]> jspc29.x-matter.uni-frankfurt.de Git - daqtools.git/commitdiff
cleaned up thresholds
authorCarsten Schwarz <M.Traxler@gsi.de>
Tue, 9 Apr 2019 12:07:36 +0000 (14:07 +0200)
committerM.Traxler <M.Traxler@gsi.de>
Tue, 9 Apr 2019 12:09:24 +0000 (14:09 +0200)
24 files changed:
thresholds/determine_noiseband_dirich.pl [new file with mode: 0755]
thresholds/trb_dirich_threshold/.gitignore [new file with mode: 0644]
thresholds/trb_dirich_threshold/HADESthreshscan_v1 [new file with mode: 0755]
thresholds/trb_dirich_threshold/HADESthreshscan_v1.C [new file with mode: 0644]
thresholds/trb_dirich_threshold/HADESthreshscan_v1.o [new file with mode: 0644]
thresholds/trb_dirich_threshold/Makefile [new file with mode: 0644]
thresholds/trb_dirich_threshold/README.md [new file with mode: 0644]
thresholds/trb_dirich_threshold/dirich_v13.C [new file with mode: 0644]
thresholds/trb_dirich_threshold/obsolete/dirich_v11.C [new file with mode: 0644]
thresholds/trb_dirich_threshold/obsolete/systemthreshscan_v11 [new file with mode: 0755]
thresholds/trb_dirich_threshold/obsolete/systemthreshscan_v11.C [new file with mode: 0644]
thresholds/trb_dirich_threshold/obsolete/test_trbnet [new file with mode: 0755]
thresholds/trb_dirich_threshold/obsolete/test_trbnet.cc [new file with mode: 0644]
thresholds/trb_dirich_threshold/setLD [new file with mode: 0644]
thresholds/trb_dirich_threshold/trbnetcom.h [new file with mode: 0644]
users/gsi_dirc/EventBuilder.xml
users/gsi_dirc/EventBuilderNew.xml
users/gsi_dirc/dirich_set_standard_thresholds.pl [new file with mode: 0755]
users/gsi_dirc/dirich_voltages.sh [new file with mode: 0755]
users/gsi_dirc/readout.pl
users/gsi_dirc/register_config_tdc.db
users/gsi_dirc/register_configgbe.db
users/gsi_dirc/register_configgbe_ip.db
users/gsi_dirc/startup.sh

diff --git a/thresholds/determine_noiseband_dirich.pl b/thresholds/determine_noiseband_dirich.pl
new file mode 100755 (executable)
index 0000000..d17e20b
--- /dev/null
@@ -0,0 +1,174 @@
+#!/usr/bin/perl
+use warnings;
+use strict;
+use HADES::TrbNet;
+use Time::HiRes qw(usleep);
+use Data::Dumper;
+
+use lib "/home/hadaq/trbsoft/daqtools/dmon/code";
+use Dmon;
+
+my $dirich = 0x1234;
+
+$dirich = $ARGV[0];
+
+unless ($ARGV[0]) {
+  print "usage: $0 <DiRICH--TrbNet-Address>\n";
+  exit;
+}
+
+$dirich = hex($dirich);
+
+my $throffset = 0xa000;
+#my $monitor = 0xdfc0;
+my $monitor = 0xc001;
+
+my $first_channel = 0;
+my $last_channel = 31;
+
+my $default_threshold = 0x6000;
+
+#my $absolute_max_threshold = 0x8000;
+my $absolute_min_threshold = 0x1000;
+
+my @res; my $res; my $rh_res;
+
+trb_init_ports() or die trb_strerror();
+
+# enable monitor counters
+$res = trb_register_write($dirich, 0xdf80 , 0xffffffff);
+if(!defined $res) {
+    $res = trb_strerror();
+    print "error output: $res\n";
+}
+
+
+my $fixed_bits = 0x00800000;
+my $shift_bits = 0;
+my $channel_shift = 24;
+my $command;
+my $chain=0;
+
+my $READ  = 0x0<<20; # bits to set for a read command
+my $WRITE = 0x8<<20; # bits to set for a write command
+my $REGNR = 24; # number of bits to shift for the register number
+
+
+for my $channel (0 .. 31) {
+  $chain = ($channel <16) ? 0 : 1;
+  #($channel<<$REGNR | $WRITE | ($data&0xffff));
+  # sendcmd($channel<<$REGNR | $WRITE | ($data&0xffff));
+  #$command = $fixed_bits | ((0x10| ($channel&0xf)) << $channel_shift) | (($default_threshold+$channel) << $shift_bits);
+  $command = ($channel&0xf)<<$REGNR | $WRITE | ($default_threshold&0xffff);
+  #print "$command\n";
+  Dmon::PadiwaSendCmd($command,$dirich, $chain);
+  usleep(10E3);
+  #trb_register_write($dirich, $throffset + $channel , $default_threshold);
+  #$rh_res = trb_register_read($dirich, $throffset + $channel);
+}
+#exit;
+usleep (1E5);
+
+my $boundaries = {};
+
+for my $channel ($first_channel .. $last_channel) {
+#for my $channel (30 .. 31) {
+
+    my $hit_zero_diff_flag = 0;
+
+    my $lower_threshold = 0x6f80;
+    my $upper_threshold = 0x9000;
+    my $reasonable_upper_threshold = 0x7800;
+    my $thresh_increment = 0x8;
+
+  THRESH_LOOP:    for (my $thresh = $lower_threshold ; $thresh <= $upper_threshold; $thresh += $thresh_increment) {
+      $chain = ($channel <16) ? 0 : 1;
+      #$command = $fixed_bits | ( (0x10|($channel&0xf)) << $channel_shift) | ($thresh << $shift_bits);
+      $command = ($channel & 0xf)<<$REGNR | $WRITE | ($thresh&0xffff);
+      #print "chain: $chain\n";
+      Dmon::PadiwaSendCmd($command,$dirich, $chain);
+      ##trb_register_write($dirich, $throffset + $channel , $thresh);
+      undef $rh_res;
+      my @hits = ();
+      foreach (1..2) {
+         $rh_res = trb_register_read($dirich, $monitor + $channel);
+         #$res = trb_strerror();
+         #print "error output: $res\n";
+         #print Dumper $rh_res;
+         push @hits ,$rh_res->{$dirich};
+          #if ($_==1) {
+            usleep(40E3);
+          #}
+        }
+
+      my $diff = $hits[1] - $hits[0];
+      #printf "channel: $channel: cur thresh: %.4x diff: $diff\n",$thresh ;
+      #sleep 0.2;
+      $hit_zero_diff_flag = 1 if($diff == 0);
+
+      if($diff != 0 && !$hit_zero_diff_flag ) {
+         print "channel: $channel, backup threshold a bit (by 0x800)..., thresh: "; printf "0x%x\n",$thresh;
+         if($thresh <= $absolute_min_threshold) {
+             print "reached abs min threshold\n";
+             $boundaries->{$channel}->{'lower'} = $thresh;
+             last THRESH_LOOP;
+         }
+         else {
+             $thresh -= 0x800;
+             $lower_threshold -= 0x800;
+             $thresh_increment *= 4 if($thresh_increment <= 0x100);
+             next THRESH_LOOP;
+         }
+      }
+
+      $thresh_increment *= 4 if($thresh_increment <= 0x100 && $thresh >= $reasonable_upper_threshold );
+
+      #my $thrstr = sprintf("0x%x", $thresh);
+      #print "channel: $channel: thresh: $thrstr : diff: $diff, a=$hits[0] b=$hits[1]\n";
+
+      my $thrstr = sprintf("0x%x", $thresh);
+      if($diff >= 50) {
+         if( ! exists $boundaries->{$channel}->{'lower'} ) {
+             print "channel: $channel, lower thresh: $thrstr\n";
+             $boundaries->{$channel}->{'lower'} = $thresh;
+         }
+      }
+      elsif ($diff == 0 && exists $boundaries->{$channel}->{'lower'} && ($thresh - $boundaries->{$channel}->{'lower'} ) > 0x40  ) {
+         print "channel: $channel, upper thresh: $thrstr\n";
+         $boundaries->{$channel}->{'upper'} = $thresh;
+         last THRESH_LOOP;
+      }
+
+    } # THRESH_LOOP
+
+    if ( ! exists $boundaries->{$channel}->{'upper'}) {
+      $boundaries->{$channel}->{'upper'} = $upper_threshold;
+      print "strange setting of upper thresh.\n";
+    }
+
+    $chain = ($channel <16) ? 0 : 1;
+    #$command = $fixed_bits | ( (0x10|($channel&0xf)) << $channel_shift) | ($default_threshold << $shift_bits);
+    $command = ($channel & 0xf)<<$REGNR | $WRITE | ($default_threshold&0xffff);
+    Dmon::PadiwaSendCmd($command,$dirich, $chain);
+    #trb_register_write($dirich, $throffset + $channel , $default_threshold);
+}
+
+
+printf "\nresult for 0x%.4x:\n",$dirich;
+#print Dumper $boundaries;
+print "channel | noiseband [mV]\n";
+print "------------------------\n";
+foreach my $cur_channel (sort {$a <=> $b} keys %$boundaries) {
+    my $diff = $boundaries->{$cur_channel}->{upper} - $boundaries->{$cur_channel}->{lower};
+    my $width = $diff * 38E-6 * 1000;
+    printf "%2d      | %02.0f\n", $cur_channel , $width;
+}
+
+printf "\nsummary for 0x%.4x:\n", $dirich;
+foreach my $cur_channel (sort {$a <=> $b} keys %$boundaries) {
+    my $diff = $boundaries->{$cur_channel}->{upper} - $boundaries->{$cur_channel}->{lower};
+    my $width = $diff * 38E-6 * 1000;
+    printf "%02.0f ", $width;
+}
+print "\n";
+
diff --git a/thresholds/trb_dirich_threshold/.gitignore b/thresholds/trb_dirich_threshold/.gitignore
new file mode 100644 (file)
index 0000000..d9eb8ea
--- /dev/null
@@ -0,0 +1,5 @@
+
+*.root
+*.thr
+*~
+
diff --git a/thresholds/trb_dirich_threshold/HADESthreshscan_v1 b/thresholds/trb_dirich_threshold/HADESthreshscan_v1
new file mode 100755 (executable)
index 0000000..2b4bbe7
Binary files /dev/null and b/thresholds/trb_dirich_threshold/HADESthreshscan_v1 differ
diff --git a/thresholds/trb_dirich_threshold/HADESthreshscan_v1.C b/thresholds/trb_dirich_threshold/HADESthreshscan_v1.C
new file mode 100644 (file)
index 0000000..d7bc18b
--- /dev/null
@@ -0,0 +1,2683 @@
+// #include "trbnetcom.h"
+// #include "dirich_sim.C"
+
+#include "TROOT.h"
+#include "TError.h"
+#include "TGraph.h"
+#include "TGraph2D.h"
+#include "TMultiGraph.h"
+#include "TCanvas.h"
+#include "TH1.h"
+#include "TH2.h"
+#include "TLegend.h"
+#include "TStyle.h"
+#include "TLine.h"
+#include "TFile.h"
+#include "TText.h"
+#include "TMath.h"
+
+#include <iostream>
+#include <thread>
+#include <mutex>
+#include <unordered_map>
+#include <map>
+#include <array>
+#include <sstream>
+#include <fstream>
+#include <ctime>
+#include <stdlib.h>
+#include <future>
+// #include <functional>
+
+#include <boost/program_options.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/range.hpp>
+// #include <iomanip>
+
+#include "dirich_v13.C"
+
+namespace po = boost::program_options;
+namespace fs = boost::filesystem;
+
+int gcheck_thresholds = 1;
+std::mutex gcheck_thresholds_mutex;
+// #define 0 0
+// #define LASTCHANNEL 31
+
+// #ifndef NCH
+//     const int NRCHANNELS = 32;                       //Nr of TDC ichannels in dirich
+//     const int CHPCHAIN = 16;                         //Nr of TDC ichannels pre dirich-chain
+//     #define NCH
+// #endif
+
+// #ifndef THC
+//     const int OFFTHRESH =   1;       //Value to switch off channel
+//     const int THRESHDELAY = 100000; //Delay [mus] for thresh change to succeed
+//     #define THC
+// #endif
+
+const uint16_t BROADCAST = 0xfe51;
+
+std::map<uint16_t,std::shared_ptr<dirich>> dirichlist ={};
+
+std::map<uint16_t,TCanvas*> canvaslist;
+
+std::vector<TCanvas*> canvasvector;
+
+TH2* get_2D_rate_histo(std::shared_ptr<dirich> dirichptr)
+{
+       TH2D* histo;
+       gStyle->SetOptStat(0);
+       if(dirichptr==NULL){
+               histo = new TH2D(
+                       "2D Rate vs. Threshold of all diriches","2D Rate vs. Threshold of all diriches",
+                       dirichlist.size()*NRCHANNELS,-.5,dirichlist.size()*NRCHANNELS-.5,
+                       (
+                               dirichlist.begin()->second->gUpperEdge.at(0)
+                               -dirichlist.begin()->second->gLowerEdge.at(0)
+                       )/dirichlist.begin()->second->gStepsize,
+                       dirichlist.begin()->second->gLowerEdge.at(0),
+                       dirichlist.begin()->second->gUpperEdge.at(0)
+               );
+               int idirich=0;
+               // std::map<uint16_t,dirich*>::iterator dirichlistiterator = dirichlist.begin();
+               TLine* dirich_line_left = new TLine(
+                       histo->GetXaxis()->GetBinLowEdge(idirich*NRCHANNELS+1),
+                       histo->GetYaxis()->GetBinLowEdge(1),
+                       histo->GetXaxis()->GetBinLowEdge(idirich*NRCHANNELS+1),
+                       histo->GetYaxis()->GetBinUpEdge(histo->GetNbinsY())
+               );
+               dirich_line_left->SetLineWidth(2);
+               dirich_line_left->SetLineColor(kRed);
+               histo->GetListOfFunctions()->Add(dirich_line_left);
+               for (auto& dirichitem : dirichlist){
+                       TLine* dirich_line_right = new TLine(
+                               histo->GetXaxis()->GetBinLowEdge((idirich+1)*NRCHANNELS+1),
+                               histo->GetYaxis()->GetBinLowEdge(1),
+                               histo->GetXaxis()->GetBinLowEdge((idirich+1)*NRCHANNELS+1),
+                               histo->GetYaxis()->GetBinUpEdge(histo->GetNbinsY())
+                       );
+                       dirich_line_right->SetLineWidth(2);
+                       dirich_line_right->SetLineColor(kRed);
+                       histo->GetListOfFunctions()->Add(dirich_line_right);
+                       TText* dirich_name = new TText(
+                               histo->GetXaxis()->GetBinCenter((idirich+1./2)*NRCHANNELS+1),
+                               histo->GetYaxis()->GetBinLowEdge(1)
+                               -(0.1*(
+                                       histo->GetYaxis()->GetBinLowEdge(1)
+                                       -histo->GetYaxis()->GetBinUpEdge(histo->GetNbinsY())
+                               )),
+                               Form("0x%x",dirichitem.first)
+                       );
+                       dirich_name->SetTextAlign(22);
+                       dirich_name->SetTextColor(kRed+2);
+                       dirich_name->SetTextFont(43);
+                       dirich_name->SetTextSize(20);
+                       histo->GetListOfFunctions()->Add(dirich_name);
+                       for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+                               for(int ipoint=0;ipoint<dirichitem.second->gRateGraphs[ichannel]->GetN();++ipoint){
+                                       histo->Fill(
+                                               idirich*NRCHANNELS+ichannel,
+                                               dirichitem.second->gRateGraphs[ichannel]->GetX()[ipoint],
+                                               dirichitem.second->gRateGraphs[ichannel]->GetY()[ipoint]
+                                       );
+                                       if(ichannel%8==0) 
+                                               histo->GetXaxis()->SetBinLabel(
+                                                       idirich*NRCHANNELS+ichannel+1,Form("%i",ichannel)
+                                               );
+                                       else histo->GetXaxis()->SetBinLabel(idirich*NRCHANNELS+ichannel+1,"");
+                               }
+                               TLine* baseline_line = new TLine(
+                                       histo->GetXaxis()->GetBinLowEdge(idirich*NRCHANNELS+ichannel+1),
+                                       dirichitem.second->GetSingleBaseline(ichannel),
+                                       histo->GetXaxis()->GetBinUpEdge(idirich*NRCHANNELS+ichannel+1),
+                                       dirichitem.second->GetSingleBaseline(ichannel)
+                               );
+                               baseline_line->SetLineColor(kRed);
+                               baseline_line->SetLineWidth(2);
+                               histo->GetListOfFunctions()->Add(baseline_line);
+                               TLine* baseline_line_old = new TLine(
+                                       histo->GetXaxis()->GetBinLowEdge(idirich*NRCHANNELS+ichannel+1),
+                                       dirichitem.second->GetSingleBaseline_old(ichannel),
+                                       histo->GetXaxis()->GetBinUpEdge(idirich*NRCHANNELS+ichannel+1),
+                                       dirichitem.second->GetSingleBaseline_old(ichannel)
+                               );
+                               baseline_line_old->SetLineColor(kBlack);
+                               baseline_line_old->SetLineWidth(2);
+                               histo->GetListOfFunctions()->Add(baseline_line_old);
+                       }
+                       // ++dirichlistiterator;
+                       ++idirich;
+               }
+       }
+       else{
+               histo = new TH2D(
+                       Form("2D Rate vs. Threshold of %x",dirichptr->GetBoardAddress()),
+                       Form("2D Rate vs. Threshold of %x",dirichptr->GetBoardAddress()),
+                       NRCHANNELS,
+                       -.5,
+                       NRCHANNELS-.5,
+                       (dirichptr->gUpperEdge.at(0)-dirichptr->gLowerEdge.at(0))/dirichptr->gStepsize,
+                       dirichptr->gLowerEdge.at(0),
+                       dirichptr->gUpperEdge.at(0)
+               );
+               for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+                       for(int ipoint=0;ipoint<dirichptr->gRateGraphs[ichannel]->GetN();++ipoint){
+                               histo->Fill(
+                                       ichannel,
+                                       dirichptr->gRateGraphs[ichannel]->GetX()[ipoint],
+                                       dirichptr->gRateGraphs[ichannel]->GetY()[ipoint]
+                               );
+                       }
+                       TLine* baseline_line = new TLine(
+                               histo->GetXaxis()->GetBinLowEdge(ichannel+1),
+                               dirichptr->GetSingleBaseline(ichannel),
+                               histo->GetXaxis()->GetBinUpEdge(ichannel+1),
+                               dirichptr->GetSingleBaseline(ichannel)
+                       );
+                       baseline_line->SetLineColor(kRed);
+                       baseline_line->SetLineWidth(2);
+                       histo->GetListOfFunctions()->Add(baseline_line);
+                       TLine* baseline_line_old = new TLine(
+                               histo->GetXaxis()->GetBinLowEdge(ichannel+1),
+                               dirichptr->GetSingleBaseline_old(ichannel),
+                               histo->GetXaxis()->GetBinUpEdge(ichannel+1),
+                               dirichptr->GetSingleBaseline_old(ichannel)
+                       );
+                       baseline_line_old->SetLineColor(kBlack);
+                       baseline_line_old->SetLineWidth(2);
+                       histo->GetListOfFunctions()->Add(baseline_line_old);
+               }
+       }
+       // std::cout << "finished histo" << std::endl;
+
+       histo->SetMinimum(0);
+       histo->GetXaxis()->SetTitle("Channel Nr");
+       // histo->GetXaxis()->SetTitleOffset();
+       histo->GetYaxis()->SetTitle("Threshold");
+       histo->GetZaxis()->SetTitle("Rate");
+       return histo;
+}
+
+TMultiGraph* get_2D_mgr_diff_over_thr_histo(std::shared_ptr<dirich>    dirichptr)
+{
+       TMultiGraph* multig = new TMultiGraph();
+       if(dirichptr==NULL){
+               multig->SetTitle(
+                       "Differentiated rate graph over baseline of all dirich;Threshold;Differentiated rate"
+               );
+               multig->SetName(
+                       "Differentiated rate graph over baseline of all dirich (Mutligraph)"
+               );
+               for (auto& dirichitem : dirichlist){
+                       for(auto& gDiffRateGraphsOverBaseIT : dirichitem.second->gDiffRateGraphsOverBase){
+                               multig->Add(gDiffRateGraphsOverBaseIT,"PL");
+                       }
+               }
+       }
+       else{
+               multig->SetTitle(Form(
+                       "Differentiated rate graph over baseline of dirich 0x%x;Threshold;Differentiated rate"
+                       ,dirichptr->GetBoardAddress()
+               ));
+               multig->SetName(Form(
+                       "Differentiated rate graph over baseline of dirich 0x%x (Multigraph)"
+                       ,dirichptr->GetBoardAddress()
+               ));
+               for(auto& gDiffRateGraphsOverBaseIT : dirichptr->gDiffRateGraphsOverBase){
+                       multig->Add(gDiffRateGraphsOverBaseIT,"PL");
+               }
+       }
+       // multig->SetMinimum(0);
+       // multig->GetHistogram()->GetYaxis()->SetRangeUser(0,100);
+       return multig;
+}
+
+TGraph2D* get_2D_gr_diff_over_thr_histo(std::shared_ptr<dirich> dirichptr)
+{
+       TGraph2D* g2d = new TGraph2D();
+       if(dirichptr==NULL){
+               g2d->SetTitle(
+                       "Differentiated rate graph over baseline of all dirich;"
+                       "Channel Nr;"
+                       "Threshold;"
+                       "Differentiated rate"
+               );
+               g2d->SetName("Differentiated rate graph over baseline of all dirich (2D_Graph)");
+               int idirich=0;
+               for (auto& dirichitem : dirichlist){
+                       int ichannel=0;
+                       for(auto& gDiffRateGraphsOverBaseIT : dirichitem.second->gDiffRateGraphsOverBase){
+                               for(int ipoint=0;ipoint<gDiffRateGraphsOverBaseIT->GetN();++ipoint){
+                                       g2d->SetPoint(
+                                               g2d->GetN(),
+                                               idirich*NRCHANNELS+ichannel,
+                                               gDiffRateGraphsOverBaseIT->GetX()[ipoint],
+                                               gDiffRateGraphsOverBaseIT->GetY()[ipoint]
+                                       );
+                               }
+                               ichannel++;
+                       }
+                       idirich++;
+               }
+       }
+       else{
+               g2d->SetTitle(Form(
+                       "Differentiated rate graph over baseline of dirich 0x%x;"
+                       "Channel Nr;"
+                       "Threshold;"
+                       "Differentiated rate"
+                       ,dirichptr->GetBoardAddress())
+               );
+               g2d->SetName(Form(
+                       "Differentiated rate graph over baseline of dirich 0x%x (2D_Graph)"
+                       ,dirichptr->GetBoardAddress())
+               );
+               int ichannel=0;
+               for(auto& gDiffRateGraphsOverBaseIT : dirichptr->gDiffRateGraphsOverBase){
+                       for(int ipoint=0;ipoint<gDiffRateGraphsOverBaseIT->GetN();++ipoint){
+                               g2d->SetPoint(
+                                       g2d->GetN(),
+                                       ichannel,
+                                       gDiffRateGraphsOverBaseIT->GetX()[ipoint],
+                                       gDiffRateGraphsOverBaseIT->GetY()[ipoint]
+                               );
+                       }
+                       ichannel++;
+               }
+       }
+       g2d->SetMinimum(0);
+       g2d->GetZaxis()->SetRangeUser(0,100);
+       return g2d;
+}
+
+TH2* get_2D_diff_over_thr_histo(std::shared_ptr<dirich>        dirichptr)
+{
+       TH2D* histo;
+       TH2D* divided_histo;
+       // divided_histo->SetDirectory(0);
+       gStyle->SetOptStat(0);
+       if(dirichptr==NULL){
+               double max_value=-9999;
+               // double min_value=9999;
+               double min_width=1000;
+               for (auto& dirichitem : dirichlist){
+                       for(auto& gDiffRateGraphsOverBaseIT : dirichitem.second->gDiffRateGraphsOverBase){
+                               if(
+                                       gDiffRateGraphsOverBaseIT->GetN()!=0 
+                                       && max_value<gDiffRateGraphsOverBaseIT->GetX()[gDiffRateGraphsOverBaseIT->GetN()-1]
+                               ) 
+                                       max_value = gDiffRateGraphsOverBaseIT->GetX()[gDiffRateGraphsOverBaseIT->GetN()-1];
+                               if(
+                                       gDiffRateGraphsOverBaseIT->GetN()!=0 
+                                       && max_value<gDiffRateGraphsOverBaseIT->GetX()[gDiffRateGraphsOverBaseIT->GetN()-1]
+                               ) 
+                                       max_value = gDiffRateGraphsOverBaseIT->GetX()[gDiffRateGraphsOverBaseIT->GetN()-1];
+                               if(
+                                       gDiffRateGraphsOverBaseIT->GetN()>=2 
+                                       && min_width>abs(gDiffRateGraphsOverBaseIT->GetX()[0]-gDiffRateGraphsOverBaseIT->GetX()[1])
+                               ) 
+                                       min_width = abs(gDiffRateGraphsOverBaseIT->GetX()[0]-gDiffRateGraphsOverBaseIT->GetX()[1]);
+                       }
+               }
+               histo = new TH2D(
+                       "2D Differentiated Rate vs. Threshold over baseline of all diriches",
+                       "2D Differentiated Rate vs. Threshold over baseline of all diriches",
+                       dirichlist.size()*NRCHANNELS,
+                       -.5,
+                       dirichlist.size()*NRCHANNELS-.5,
+                       max_value/min_width/2,0,
+                       max_value
+               );
+               divided_histo = new TH2D(
+                       "temp_diff",
+                       "temp_diff",
+                       dirichlist.size()*NRCHANNELS,
+                       -.5,dirichlist.size()*NRCHANNELS-.5,
+                       max_value/min_width/2,
+                       0,
+                       max_value
+               );
+               int idirich=0;
+               TLine* dirich_line_left = new TLine(
+                       histo->GetXaxis()->GetBinLowEdge(idirich*NRCHANNELS+1),
+                       histo->GetYaxis()->GetBinLowEdge(1),
+                       histo->GetXaxis()->GetBinLowEdge(idirich*NRCHANNELS+1),
+                       histo->GetYaxis()->GetBinUpEdge(histo->GetNbinsY())
+               );
+               dirich_line_left->SetLineWidth(2);
+               dirich_line_left->SetLineColor(kRed);
+               histo->GetListOfFunctions()->Add(dirich_line_left);
+               for (auto& dirichitem : dirichlist){
+                       TLine* dirich_line_right = new TLine(
+                               histo->GetXaxis()->GetBinLowEdge((idirich+1)*NRCHANNELS+1),
+                               histo->GetYaxis()->GetBinLowEdge(1),
+                               histo->GetXaxis()->GetBinLowEdge((idirich+1)*NRCHANNELS+1),
+                               histo->GetYaxis()->GetBinUpEdge(histo->GetNbinsY())
+                       );
+                       dirich_line_right->SetLineWidth(2);
+                       dirich_line_right->SetLineColor(kRed);
+                       histo->GetListOfFunctions()->Add(dirich_line_right);
+                       TText* dirich_name = new TText(
+                               histo->GetXaxis()->GetBinCenter((idirich+1./2)*NRCHANNELS+1),
+                                       histo->GetYaxis()->GetBinLowEdge(1)
+                                       -(
+                                               0.1*(histo->GetYaxis()->GetBinLowEdge(1)
+                                               -histo->GetYaxis()->GetBinUpEdge(histo->GetNbinsY())
+                                       )),
+                               Form("0x%x",dirichitem.first)
+                       );
+                       dirich_name->SetTextAlign(22);
+                       dirich_name->SetTextColor(kRed+2);
+                       dirich_name->SetTextFont(43);
+                       dirich_name->SetTextSize(20);
+                       histo->GetListOfFunctions()->Add(dirich_name);
+                       for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+                               for(int ipoint=0;ipoint<dirichitem.second->gDiffRateGraphsOverBase[ichannel]->GetN();++ipoint){
+                                       histo->Fill(
+                                               idirich*NRCHANNELS+ichannel,
+                                               dirichitem.second->gDiffRateGraphsOverBase[ichannel]->GetX()[ipoint],
+                                               dirichitem.second->gDiffRateGraphsOverBase[ichannel]->GetY()[ipoint]
+                                       );
+                                       divided_histo->Fill(
+                                               idirich*NRCHANNELS+ichannel,
+                                               dirichitem.second->gDiffRateGraphsOverBase[ichannel]->GetX()[ipoint]
+                                       );
+                                       // std::cout << ichannel << " " << int(dirichlist.size()*NRCHANNELS/20+1) << std::endl;
+                                       if(ichannel%8==0) histo->GetXaxis()->SetBinLabel(
+                                               idirich*NRCHANNELS+ichannel+1,Form("%i",ichannel)
+                                       );
+                                       else histo->GetXaxis()->SetBinLabel(idirich*NRCHANNELS+ichannel+1,"");
+                               }
+                               TLine* thr_line = new TLine(
+                                       histo->GetXaxis()->GetBinLowEdge(idirich*NRCHANNELS+ichannel+1),
+                                       -1*dirichitem.second->GetSingleThresholdmV(ichannel),
+                                       histo->GetXaxis()->GetBinUpEdge(idirich*NRCHANNELS+ichannel+1),
+                                       -1*dirichitem.second->GetSingleThresholdmV(ichannel)
+                               );
+                               thr_line->SetLineColor(kRed);
+                               thr_line->SetLineWidth(2);
+                               histo->GetListOfFunctions()->Add(thr_line);
+                       }
+                       ++idirich;
+               }
+               idirich=0;
+       }
+       else{
+               double max_value=0;
+               double min_width=10000;
+               for(auto& gDiffRateGraphsOverBaseIT : dirichptr->gDiffRateGraphsOverBase){
+                       if(
+                               gDiffRateGraphsOverBaseIT->GetN()!=0 
+                               && max_value<gDiffRateGraphsOverBaseIT->GetX()[gDiffRateGraphsOverBaseIT->GetN()-1]
+                       ) 
+                               max_value = gDiffRateGraphsOverBaseIT->GetX()[gDiffRateGraphsOverBaseIT->GetN()-1];
+                       if(
+                               gDiffRateGraphsOverBaseIT->GetN()>=2 
+                               && min_width>abs(gDiffRateGraphsOverBaseIT->GetX()[0]-gDiffRateGraphsOverBaseIT->GetX()[1])
+                       ) 
+                               min_width = abs(gDiffRateGraphsOverBaseIT->GetX()[0]-gDiffRateGraphsOverBaseIT->GetX()[1]);
+               }
+               histo = new TH2D(
+                       Form("2D Differentiated Rate vs. Threshold over baseline of %x",dirichptr->GetBoardAddress()),
+                       Form("2D Differentiated Rate vs. Threshold over baseline of %x",dirichptr->GetBoardAddress()),
+                       NRCHANNELS,
+                       -.5,
+                       NRCHANNELS-.5,
+                       max_value/min_width/2,0,
+                       max_value
+               );
+               divided_histo = new TH2D(
+                       "temp_diff","temp_diff",
+                       NRCHANNELS,
+                       -.5,
+                       NRCHANNELS-.5,
+                       max_value/min_width/2,0,
+                       max_value
+               );
+               for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+                       for(int ipoint=0;ipoint<dirichptr->gDiffRateGraphsOverBase[ichannel]->GetN();++ipoint){
+                               histo->Fill(
+                                       ichannel,
+                                       dirichptr->gDiffRateGraphsOverBase[ichannel]->GetX()[ipoint],
+                                       dirichptr->gDiffRateGraphsOverBase[ichannel]->GetY()[ipoint]
+                               );
+                               divided_histo->Fill(
+                                       ichannel,
+                                       dirichptr->gDiffRateGraphsOverBase[ichannel]->GetX()[ipoint]
+                               );
+                       }
+                       TLine* thr_line = new TLine(
+                               histo->GetXaxis()->GetBinLowEdge(ichannel+1),
+                               -1*dirichptr->GetSingleThresholdmV(ichannel),
+                               histo->GetXaxis()->GetBinUpEdge(ichannel+1),
+                               -1*dirichptr->GetSingleThresholdmV(ichannel)
+                       );
+                       thr_line->SetLineColor(kRed);
+                       thr_line->SetLineWidth(2);
+                       histo->GetListOfFunctions()->Add(thr_line);
+               }
+       }
+
+       histo->Divide(divided_histo);
+
+       histo->Divide(divided_histo);
+       for(int ibin=1;ibin<(histo->GetNbinsX()+2)*(histo->GetNbinsY()+2);++ibin){
+               // if(histo->GetBinContent(ibin)<-1.)histo->SetBinContent(ibin,0);
+               histo->SetBinError(ibin,0);
+       }
+       histo->SetMinimum(0.);
+       // histo->GetZaxis()->SetRangeUser(0.,30.);
+       histo->GetXaxis()->SetTitle("Channel Nr");
+       // histo->GetXaxis()->SetTitleOffset();
+       histo->GetYaxis()->SetTitle("Threshold");
+       histo->GetZaxis()->SetTitle("Differentiated rate");
+       return histo;
+}
+
+TH2* get_2D_rate_over_thr_histo(std::shared_ptr<dirich>        dirichptr)
+{
+       TH2D* histo;
+       TH2D* divided_histo;
+       // divided_histo->SetDirectory(0);
+       gStyle->SetOptStat(0);
+       if(dirichptr==NULL){
+               double max_value=-9999;
+               // double min_value=9999;
+               double min_width=1000;
+               for (auto& dirichitem : dirichlist){
+                       for(auto& gRateGraphsOverBaseIT : dirichitem.second->gRateGraphsOverBase){
+                               if(
+                                       gRateGraphsOverBaseIT->GetN()!=0 
+                                       && max_value<gRateGraphsOverBaseIT->GetX()[gRateGraphsOverBaseIT->GetN()-1]
+                               ){
+                                       max_value = gRateGraphsOverBaseIT->GetX()[gRateGraphsOverBaseIT->GetN()-1];
+                                       // min_value = gRateGraphsOverBaseIT->GetX()[0];
+                               }
+                               if(
+                                       gRateGraphsOverBaseIT->GetN()>=2 
+                                       && min_width>abs(gRateGraphsOverBaseIT->GetX()[0]-gRateGraphsOverBaseIT->GetX()[1])
+                               ) 
+                                       min_width = abs(gRateGraphsOverBaseIT->GetX()[0]-gRateGraphsOverBaseIT->GetX()[1]);
+                       }
+               }
+               histo = new TH2D(
+                       "2D Rate vs. Threshold over baseline of all diriches",
+                       "2D Rate vs. Threshold over baseline of all diriches",
+                       dirichlist.size()*NRCHANNELS,
+                       -.5,
+                       dirichlist.size()*NRCHANNELS-.5,
+                       max_value/min_width/2,0,
+                       max_value
+               );
+               divided_histo = new TH2D(
+                       "temp_diff",
+                       "temp_diff",
+                       dirichlist.size()*NRCHANNELS,
+                       -.5,
+                       dirichlist.size()*NRCHANNELS-.5,
+                       max_value/min_width/2,0,
+                       max_value
+               );
+               int idirich=0;
+               TLine* dirich_line_left = new TLine(
+                       histo->GetXaxis()->GetBinLowEdge(idirich*NRCHANNELS+1),
+                       histo->GetYaxis()->GetBinLowEdge(1),
+                       histo->GetXaxis()->GetBinLowEdge(idirich*NRCHANNELS+1),
+                       histo->GetYaxis()->GetBinUpEdge(histo->GetNbinsY())
+               );
+               dirich_line_left->SetLineWidth(2);
+               dirich_line_left->SetLineColor(kRed);
+               histo->GetListOfFunctions()->Add(dirich_line_left);
+               for (auto& dirichitem : dirichlist){
+                       TLine* dirich_line_right = new TLine(
+                               histo->GetXaxis()->GetBinLowEdge((idirich+1)*NRCHANNELS+1),
+                               histo->GetYaxis()->GetBinLowEdge(1),
+                               histo->GetXaxis()->GetBinLowEdge((idirich+1)*NRCHANNELS+1),
+                               histo->GetYaxis()->GetBinUpEdge(histo->GetNbinsY())
+                       );
+                       dirich_line_right->SetLineWidth(2);
+                       dirich_line_right->SetLineColor(kRed);
+                       histo->GetListOfFunctions()->Add(dirich_line_right);
+                       TText* dirich_name = new TText(
+                               histo->GetXaxis()->GetBinCenter((idirich+1./2)*NRCHANNELS+1),
+                               histo->GetYaxis()->GetBinLowEdge(1)
+                               -(0.1*(
+                                               histo->GetYaxis()->GetBinLowEdge(1)
+                                               -histo->GetYaxis()->GetBinUpEdge(histo->GetNbinsY())
+                               )),
+                               Form("0x%x",dirichitem.first)
+                       );
+                       dirich_name->SetTextAlign(22);
+                       dirich_name->SetTextColor(kRed+2);
+                       dirich_name->SetTextFont(43);
+                       dirich_name->SetTextSize(20);
+                       histo->GetListOfFunctions()->Add(dirich_name);
+                       for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+                               for(int ipoint=0;ipoint<dirichitem.second->gRateGraphsOverBase[ichannel]->GetN();++ipoint){
+                                       histo->Fill(
+                                               idirich*NRCHANNELS+ichannel,
+                                               dirichitem.second->gRateGraphsOverBase[ichannel]->GetX()[ipoint],
+                                               dirichitem.second->gRateGraphsOverBase[ichannel]->GetY()[ipoint]
+                                       );
+                                       divided_histo->Fill(
+                                               idirich*NRCHANNELS+ichannel,
+                                               dirichitem.second->gRateGraphsOverBase[ichannel]->GetX()[ipoint]
+                                       );
+                                       if(ichannel%8==0) 
+                                               histo->GetXaxis()->SetBinLabel(
+                                                       idirich*NRCHANNELS+ichannel+1,
+                                                       Form("%i",ichannel)
+                                               );
+                                       else 
+                                               histo->GetXaxis()->SetBinLabel(
+                                                       idirich*NRCHANNELS+ichannel+1,""
+                                               );
+                               }
+                               TLine* thr_line = new TLine(
+                                       histo->GetXaxis()->GetBinLowEdge(idirich*NRCHANNELS+ichannel+1),
+                                       -1*dirichitem.second->GetSingleThresholdmV(ichannel),
+                                       histo->GetXaxis()->GetBinUpEdge(idirich*NRCHANNELS+ichannel+1),
+                                       -1*dirichitem.second->GetSingleThresholdmV(ichannel)
+                               );
+                               thr_line->SetLineColor(kRed);
+                               thr_line->SetLineWidth(2);
+                               histo->GetListOfFunctions()->Add(thr_line);
+                       }
+                       ++idirich;
+               }
+               idirich=0;
+       }
+       else{
+               double max_value=0;
+               double min_width=1000;
+               for(auto& gRateGraphsOverBaseIT : dirichptr->gRateGraphsOverBase){
+                       if(
+                               gRateGraphsOverBaseIT->GetN()!=0 
+                               && max_value<gRateGraphsOverBaseIT->GetX()[gRateGraphsOverBaseIT->GetN()-1]
+                       ) 
+                               max_value = gRateGraphsOverBaseIT->GetX()[gRateGraphsOverBaseIT->GetN()-1];
+                       if(
+                               gRateGraphsOverBaseIT->GetN()>=2 
+                               && min_width>abs(gRateGraphsOverBaseIT->GetX()[0]-gRateGraphsOverBaseIT->GetX()[1])
+                       ) 
+                               min_width = abs(gRateGraphsOverBaseIT->GetX()[0]-gRateGraphsOverBaseIT->GetX()[1]);
+               }
+               histo = new TH2D(
+                       Form("2D Rate vs. Threshold over baseline of %x",dirichptr->GetBoardAddress()),
+                       Form("2D Rate vs. Threshold over baseline of %x",dirichptr->GetBoardAddress()),
+                       NRCHANNELS,
+                       -.5,
+                       NRCHANNELS-.5,
+                       max_value/min_width/2,0,
+                       max_value
+               );
+               divided_histo = new TH2D(
+                       "temp_diff",
+                       "temp_diff",
+                       NRCHANNELS,
+                       -.5,
+                       NRCHANNELS-.5,
+                       max_value/min_width/2,0,
+                       max_value
+               );
+               for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+                       for(int ipoint=0;ipoint<dirichptr->gRateGraphsOverBase[ichannel]->GetN();++ipoint){
+                               histo->Fill(
+                                       ichannel,
+                                       dirichptr->gRateGraphsOverBase[ichannel]->GetX()[ipoint],
+                                       dirichptr->gRateGraphsOverBase[ichannel]->GetY()[ipoint]
+                               );
+                               divided_histo->Fill(ichannel,dirichptr->gRateGraphsOverBase[ichannel]->GetX()[ipoint]);
+                       }
+                       TLine* thr_line = new TLine(
+                               histo->GetXaxis()->GetBinLowEdge(ichannel+1),
+                               -1*dirichptr->GetSingleThresholdmV(ichannel),
+                               histo->GetXaxis()->GetBinUpEdge(ichannel+1),
+                               -1*dirichptr->GetSingleThresholdmV(ichannel)
+                       );
+                       thr_line->SetLineColor(kRed);
+                       thr_line->SetLineWidth(2);
+                       histo->GetListOfFunctions()->Add(thr_line);
+               }
+       }
+
+       histo->Divide(divided_histo);
+
+       histo->SetMinimum(0);
+       histo->GetXaxis()->SetTitle("Channel Nr");
+       // histo->GetXaxis()->SetTitleOffset();
+       histo->GetYaxis()->SetTitle("Threshold");
+       histo->GetZaxis()->SetTitle("Rate");
+       return histo;
+}
+
+TH1* get_noisewidth_histo(std::shared_ptr<dirich>      dirichptr)
+{
+       TH1* histo;
+       if(dirichptr==NULL){
+               histo = new TH1D(
+                       "Noisewidthhistogram of all diriches",
+                       "Noisewidthhistogram of all diriches",
+                       dirichlist.size()*NRCHANNELS,
+                       -.5,
+                       dirichlist.size()*NRCHANNELS-.5
+               );
+               int idirich=0;
+               for (auto& dirichitem : dirichlist){
+                       TText* dirich_name = new TText(
+                               histo->GetXaxis()->GetBinCenter((idirich+1./2)*NRCHANNELS+1),
+                               histo->GetYaxis()->GetBinLowEdge(1)
+                               -(
+                                       0.1*histo->GetYaxis()->GetBinLowEdge(1)
+                                       -histo->GetYaxis()->GetBinUpEdge(histo->GetNbinsY())
+                               ),
+                               Form("0x%x",dirichitem.first)
+                       );
+                       dirich_name->SetTextAlign(22);
+                       dirich_name->SetTextColor(kRed+2);
+                       dirich_name->SetTextFont(43);
+                       dirich_name->SetTextSize(20);
+                       histo->GetListOfFunctions()->Add(dirich_name);
+                       for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+                               histo->SetBinContent(
+                                       idirich*NRCHANNELS+ichannel+1,
+                                       dirich::Thr_DtomV(dirichitem.second->GetSingleNoisewidth(ichannel))
+                               );
+                               if(ichannel%8==0) 
+                                       histo->GetXaxis()->SetBinLabel(
+                                               idirich*NRCHANNELS+ichannel+1,
+                                               Form("%i",ichannel)
+                                       );
+                               else 
+                                       histo->GetXaxis()->SetBinLabel(
+                                               idirich*NRCHANNELS+ichannel+1,
+                                               ""
+                                       );
+                       }
+               ++idirich;
+               }
+               TLine* dirich_line_left = new TLine(
+                       histo->GetXaxis()->GetBinLowEdge(1),
+                       histo->GetYaxis()->GetBinLowEdge(1),
+                       histo->GetXaxis()->GetBinLowEdge(1),
+                       histo->GetMaximum()*1.05
+               );
+               dirich_line_left->SetLineWidth(2);
+               dirich_line_left->SetLineColor(kRed);
+               histo->GetListOfFunctions()->Add(dirich_line_left);
+               for(int i=0;i<idirich;++i){
+                       TLine* dirich_line_right = new TLine(
+                               histo->GetXaxis()->GetBinLowEdge((i+1)*NRCHANNELS+1),
+                               histo->GetYaxis()->GetBinLowEdge(1),
+                               histo->GetXaxis()->GetBinLowEdge((i+1)*NRCHANNELS+1),
+                               histo->GetMaximum()*1.05
+                       );
+                       dirich_line_right->SetLineWidth(2);
+                       dirich_line_right->SetLineColor(kRed);
+                       histo->GetListOfFunctions()->Add(dirich_line_right);
+               }
+       }
+       else{
+               histo = new TH1D(
+                       Form("Noisewidthhistogram of %x",dirichptr->GetBoardAddress()),
+                       Form("Noisewidthhistogram of %x",dirichptr->GetBoardAddress()),
+                       NRCHANNELS,
+                       -.5,
+                       NRCHANNELS-.5
+               );
+               for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+                       histo->SetBinContent(
+                               ichannel+1,
+                               (dirich::Thr_DtomV(dirichptr->GetSingleNoisewidth(ichannel)))
+                       );
+               }
+       }
+
+       histo->GetYaxis()->SetTitle("NoisewidthinmV");
+       histo->SetMinimum(0);
+       histo->GetXaxis()->SetTitle("Channel Nr");
+       return histo;
+}
+
+TH1* get_diff_histo(std::shared_ptr<dirich>    dirichptr, bool baseline1_noisewidth0)
+{
+       TH1* histo;
+       if(dirichptr==NULL){
+               if(baseline1_noisewidth0==1) histo = new TH1D(
+                       "Difference in baseline of all diriches",
+                       "Difference in baseline of all diriches",
+                       dirichlist.size()*200,
+                       -300,
+                       +300
+               );
+               else 
+                       histo = new TH1D(
+                               "Difference in noisewidth of all diriches",
+                               "Difference in noisewidth of all diriches",
+                               dirichlist.size()*200,
+                               -300,
+                               +300
+                       );
+               int idirich=0;
+               for (auto& dirichitem : dirichlist){
+                       for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+                               if(baseline1_noisewidth0==1) 
+                                       histo->Fill(
+                                               dirichitem.second->GetSingleBaseline(ichannel)
+                                               -dirichitem.second->GetSingleBaseline_old(ichannel)
+                                       );
+                               else 
+                                       histo->Fill(
+                                               dirichitem.second->GetSingleNoisewidth(ichannel)
+                                               -dirichitem.second->GetSingleNoisewidth_old(ichannel)
+                                       );
+                       }
+               }
+               ++idirich;
+       }
+       else{
+               if(baseline1_noisewidth0==1) 
+                       histo = new TH1D(
+                               Form("Difference in baseline of %x",dirichptr->GetBoardAddress()),
+                               Form("Difference in baseline of %x",dirichptr->GetBoardAddress()),
+                               200,
+                               -300,
+                               +300
+                       );
+               else 
+                       histo = new TH1D(
+                               Form("Difference in noisewidth of %x",dirichptr->GetBoardAddress()),
+                               Form("Difference in noisewidth of %x",dirichptr->GetBoardAddress()),
+                               200,
+                               -300,
+                               +300
+                       );
+               for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+                       if(baseline1_noisewidth0==1) 
+                               histo->Fill(
+                                       dirichptr->GetSingleBaseline(ichannel)
+                                       -dirichptr->GetSingleBaseline_old(ichannel)
+                               );
+                       else 
+                               histo->Fill(
+                                       dirichptr->GetSingleNoisewidth(ichannel)
+                                       -dirichptr->GetSingleNoisewidth_old(ichannel)
+                               );
+               }
+       }
+
+       histo->GetYaxis()->SetTitle("Number of");
+       if(baseline1_noisewidth0==1) 
+               histo->GetXaxis()->SetTitle("Difference between old and new baseline");
+       else 
+               histo->GetXaxis()->SetTitle("Difference between old and new noisewidth");
+       return histo;
+}
+
+void clear_canvas_vector()
+{
+       while(canvasvector.size()!=0){
+               if(canvasvector.back()==NULL){
+                       std::cout <<    "1" << std::endl;
+                       canvasvector.pop_back();
+               }
+               else{
+                       std::cout <<    "2" << std::endl;
+                       canvasvector.back()->Clear();
+                       std::cout <<    "3" << std::endl;
+                       canvasvector.back()->Close();
+                       std::cout <<    "4" << std::endl;
+                       canvasvector.back()->Closed();
+                       std::cout <<    "5" << std::endl;
+                       delete canvasvector.back();
+                       std::cout <<    "6" << std::endl;
+                       canvasvector.back()=NULL;
+                       std::cout <<    "7" << std::endl;
+                       canvasvector.pop_back();
+                       std::cout <<    "8" << std::endl;
+               }
+       }
+}
+
+void draw_multigraph2D(TMultiGraph* multigraph,TCanvas* canvas)
+{
+       if(canvas==0){
+               canvasvector.emplace_back(
+                       new TCanvas(
+                               Form("Canvas%i",(int)canvasvector.size()),
+                               Form("Canvas%i",(int)canvasvector.size()),
+                               1920,
+                               1080
+                       )
+               );
+               canvasvector.back()->cd(0);
+       }
+       else{
+               canvas->cd(0);
+       }
+       multigraph->Draw("a fb l3d");
+       gPad->SetTheta(0);
+       gPad->SetPhi(-90);
+       gPad->Update();
+       if(canvas==0){
+               canvasvector.back()->Modified();
+               canvasvector.back()->Update();
+       }
+       else{
+               canvas->Modified();
+               canvas->Update();
+       }
+}
+
+void draw_multigraph(TMultiGraph* multigraph,TCanvas* canvas)
+{
+       if(canvas==0){
+               canvasvector.emplace_back(
+                       new TCanvas(
+                               Form("Canvas%i",(int)canvasvector.size()),
+                               Form("Canvas%i",(int)canvasvector.size()),
+                               1920,
+                               1080
+                       )
+               );
+               canvasvector.back()->cd(0);
+       }
+       else{
+               canvas->cd(0);
+       }
+       multigraph->Draw("alp");
+       double max_value = 0;
+       for(auto&& graph : (*multigraph->GetListOfGraphs())){
+               for(int i=10 ; i < ((TGraph*)graph)->GetN() ; ++i){
+                       max_value = 
+                       ((TGraph*)graph)->GetY()[i] > max_value ? 
+                       ((TGraph*)graph)->GetY()[i] : max_value;
+               }
+       }
+       // std::cout << "max_value" << max_value << std::endl;
+       multigraph->GetHistogram()->GetYaxis()->SetRangeUser(
+               0,
+                       max_value==0 ? 
+                       100 : max_value*1.05
+       );
+       if(canvas==0){
+               canvasvector.back()->Modified();
+               canvasvector.back()->Update();
+       }
+       else{
+               canvas->Modified();
+               canvas->Update();
+       }
+}
+
+void draw_graph2D(TGraph2D* graph2d,TCanvas* canvas)
+{
+       if(canvas==0){
+               canvasvector.emplace_back(
+                       new TCanvas(
+                               Form("Canvas%i",(int)canvasvector.size()),
+                               Form("Canvas%i",(int)canvasvector.size()),
+                               1920,
+                               1080
+                       )
+               );
+               canvasvector.back()->cd(0);
+       }
+       else{
+               canvas->cd(0);
+       }
+       graph2d->Draw("surf1");
+       gPad->SetTheta(0);
+       gPad->SetPhi(-90);
+       gPad->Update();
+       if(canvas==0){
+               canvasvector.back()->Modified();
+               canvasvector.back()->Update();
+       }
+       else{
+               canvas->Modified();
+               canvas->Update();
+       }
+}
+
+void draw_histo(TH1* histo,TCanvas* canvas)
+{
+       if(canvas==0){
+               canvasvector.emplace_back(
+                       new TCanvas(
+                               Form("Canvas%i",(int)canvasvector.size()),
+                               Form("Canvas%i",(int)canvasvector.size()),
+                               1920,
+                               1080
+                       )
+               );
+               canvasvector.back()->cd(0);
+       }
+       else{
+               canvas->cd(0);
+       }
+       histo->Draw();
+       if(canvas==0){
+               canvasvector.back()->Modified();
+               canvasvector.back()->Update();
+       }
+       else{
+               canvas->Modified();
+               canvas->Update();
+       }
+}
+
+void draw_histo(TH2* histo,TCanvas* canvas)
+{
+       if(canvas==0){
+               canvasvector.emplace_back(
+                       new TCanvas(
+                               Form("Canvas%i",(int)canvasvector.size()),
+                               Form("Canvas%i",(int)canvasvector.size()),
+                               1920,
+                               1080
+                       )
+               );
+               canvasvector.back()->cd(0);
+       }
+       else{
+               canvas->cd(0);
+       }
+       histo->Draw("COLZ");
+       if(canvas==0){
+               canvasvector.back()->Modified();
+               canvasvector.back()->Update();
+       }
+       else{
+               canvas->Modified();
+               canvas->Update();
+       }
+}
+
+void set_thresholds(std::shared_ptr<dirich> dirichptr, double thrinmV=30.)
+{
+       if(thrinmV<0.){
+               std::cerr 
+                       << "negative thresholds are not \"allowed\"!\ninverting value" 
+                       << std::endl;
+               thrinmV = -1*thrinmV;
+       }       
+       if(dirichptr==0){
+               gcheck_thresholds_mutex.lock();
+               gcheck_thresholds = 2;
+               gcheck_thresholds_mutex.unlock();               
+
+               std::vector<std::thread> threads;
+               for(auto& dirichlistitem : dirichlist)
+                       threads.push_back(
+                               std::thread(
+                                       [&dirichlistitem, &thrinmV](){
+                                               dirichlistitem.second->SetThresholdsmV(thrinmV);
+                                       }
+                               )
+                       );
+
+               for(auto& thread : threads)
+                       thread.join();
+
+               gcheck_thresholds_mutex.lock();
+               gcheck_thresholds = 1;
+               gcheck_thresholds_mutex.unlock();
+       }
+       else if(dirichlist.find(dirichptr->GetBoardAddress())!=dirichlist.end()){
+               gcheck_thresholds_mutex.lock();
+               gcheck_thresholds = 2;
+               gcheck_thresholds_mutex.unlock();               
+
+               dirichptr->SetThresholdsmV(thrinmV);
+
+               gcheck_thresholds_mutex.lock();
+               gcheck_thresholds = 1;
+               gcheck_thresholds_mutex.unlock();               
+       }
+       else{
+               std::cerr 
+                       << "No DiRICH 0x" << std::hex << dirichptr->GetBoardAddress() 
+                       << " found" 
+                       << std::endl;
+       }
+}
+
+void set_thresholds_to_noise(std::shared_ptr<dirich> dirichptr, double part_of_noisewidth=1.5)
+{
+       if(dirichptr==0){
+               gcheck_thresholds_mutex.lock();
+               gcheck_thresholds = 2;
+               gcheck_thresholds_mutex.unlock();               
+
+               std::vector<std::thread> threads;
+               for(auto& dirichlistitem : dirichlist){
+
+                       std::array<double,NRCHANNELS> thresholdvals;
+                       std::array<uint16_t,NRCHANNELS> noisevalues = dirichlistitem.second->GetNoisewidths();
+                       for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+                               thresholdvals.at(ichannel) = 
+                                       part_of_noisewidth*dirich::Thr_DtomV(.5*noisevalues.at(ichannel));
+                       }
+
+                       threads.push_back(
+                               std::thread(
+                                       [&dirichlistitem, &thresholdvals](){
+                                               dirichlistitem.second->SetThresholdsmV(thresholdvals);
+                                       }
+                               )
+                       );
+               }
+
+               for(auto& thread : threads)
+                       thread.join();
+
+               gcheck_thresholds_mutex.lock();
+               gcheck_thresholds = 1;
+               gcheck_thresholds_mutex.unlock();               
+       }
+       else if(dirichlist.find(dirichptr->GetBoardAddress())!=dirichlist.end()){
+               gcheck_thresholds_mutex.lock();
+               gcheck_thresholds = 2;
+               gcheck_thresholds_mutex.unlock();
+
+               std::array<double,NRCHANNELS> thresholdvalues;
+               std::array<uint16_t,NRCHANNELS> noisevalues = dirichptr->GetNoisewidths();
+               for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+                       thresholdvalues.at(ichannel) = 
+                               part_of_noisewidth*dirich::Thr_DtomV(.5*noisevalues.at(ichannel));
+               }
+
+               dirichptr->SetThresholdsmV(thresholdvalues);
+               gcheck_thresholds_mutex.lock();
+               gcheck_thresholds = 1;
+               gcheck_thresholds_mutex.unlock();               
+       }
+       else{
+               std::cerr 
+                       << "No DiRICH 0x" << std::hex << dirichptr->GetBoardAddress() 
+                       << " found" 
+                       << std::endl;
+       }
+}
+
+void set_pattern(std::shared_ptr<dirich> dirichptr, uint32_t pattern=4294967295)
+{
+       if(dirichptr==0){
+               gcheck_thresholds_mutex.lock();
+               gcheck_thresholds = 2;
+               gcheck_thresholds_mutex.unlock();               
+
+               std::vector<std::thread> threads;
+               for(auto& dirichlistitem : dirichlist){
+
+                       std::array<double,NRCHANNELS> thresholdvals;
+                       std::array<uint16_t,NRCHANNELS> baselines = dirichlistitem.second->GetBaselines();
+                       for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+                               thresholdvals.at(ichannel) = 
+                               (pattern >> ichannel) % 2 == 1 ? 
+                               0 : dirich::Thr_DtomV(OFFTHRESH_low-baselines.at(ichannel));
+                       }
+
+                       threads.push_back(
+                               std::thread(
+                                       [&dirichlistitem, &thresholdvals](){
+                                               dirichlistitem.second->SetThresholdsmV(thresholdvals);
+                                       }
+                               )
+                       );
+               }
+
+               for(auto& thread : threads)
+                       thread.join();
+
+               gcheck_thresholds_mutex.lock();
+               gcheck_thresholds = 1;
+               gcheck_thresholds_mutex.unlock();               
+       }
+       else if(dirichlist.find(dirichptr->GetBoardAddress())!=dirichlist.end()){
+               gcheck_thresholds_mutex.lock();
+               gcheck_thresholds = 2;
+               gcheck_thresholds_mutex.unlock();
+
+               std::array<double,NRCHANNELS> thresholdvals;
+               std::array<uint16_t,NRCHANNELS> baselines = dirichptr->GetBaselines();
+               for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+                       thresholdvals.at(ichannel) = 
+                       (pattern >> ichannel) % 2 == 1 ? 
+                       0 : dirich::Thr_DtomV(OFFTHRESH_low-baselines.at(ichannel));
+               }
+               dirichptr->SetThresholdsmV(thresholdvals);
+               
+               gcheck_thresholds_mutex.lock();
+               gcheck_thresholds = 1;
+               gcheck_thresholds_mutex.unlock();
+       }
+       else{
+               std::cerr << "No DiRICH 0x" << std::hex << dirichptr->GetBoardAddress() 
+                       << " found" 
+                       << std::endl;
+       }
+}
+
+void measure_rate(std::shared_ptr<dirich>      dirichptr, std::string filename, double measure_time)
+{
+       if(dirichptr==NULL){
+               std::ofstream file;
+               file.open(filename, std::ios_base::app);
+               if(!file) std::cerr << "File for saving (" << filename << ") could not be opened!" << std::endl;
+               
+               std::unordered_map<uint16_t,std::future<double*>> rates;
+               for(auto& dirich : dirichlist){
+                       rates.insert(std::pair<uint16_t,std::future<double*>>(
+                               dirich.first, 
+                               std::async(std::launch::async,
+                                       &dirich::GetRates, dirich.second.get(), measure_time
+                               )
+                       ));
+               }
+               for(auto& one_rates : rates){
+                       file 
+                               << "# Scan-Data\n# dirich\tchannel\trate\terror\t" 
+                               << std::endl;
+                               one_rates.second.wait();
+                       double* temp_rate_arr = one_rates.second.get();
+                       for (int ichannel=0; ichannel<NRCHANNELS; ichannel++) {
+                               file
+                                       << std::hex << one_rates.first << std::dec << "\t" 
+                                       << ichannel << "\t" 
+                                       << temp_rate_arr[ichannel] << "\t" 
+                                       << sqrt(temp_rate_arr[ichannel])/sqrt(measure_time) << "\t" 
+                                       << std::endl;
+                       }
+               }
+               if(file)
+                       file.close();
+       }
+       else{
+               std::ofstream file;
+               file.open(filename, std::ios_base::app);
+               if(!file) std::cerr << "File for saving (" << filename << ") could not be opened!" << std::endl;
+               
+               double* rates = dirichptr->GetRates(measure_time);
+
+               file 
+                       << "# Scan-Data\n# dirich\tchannel\trate\terror\t" 
+                       << std::endl;
+               for (int ichannel=0; ichannel<NRCHANNELS; ichannel++) {
+                       file
+                               << std::hex << dirichptr->GetBoardAddress() << std::dec << "\t" 
+                               << ichannel << "\t" 
+                               << rates[ichannel] << "\t" 
+                               << sqrt(rates[ichannel])/sqrt(measure_time) << "\t" 
+                               << std::endl;
+               }
+               if(file)
+                       file.close();                   
+       }
+}
+
+void save_base(std::shared_ptr<dirich> dirichptr, std::string filename, bool append)
+{
+       std::ofstream file;
+       if(append) file.open(filename+".thr", std::ios_base::app);
+       else file.open(filename+".thr");
+
+       if(!file) std::cerr << "File for saving (" << filename+".thr" << ") could not be opened!" << std::endl;
+
+       if(dirichptr==NULL){
+               std::cout << "saving minimal_data" << std::endl;
+               int counter=0;
+               for (auto& dirichlistitem: dirichlist){
+                       std::cout 
+                               << "\r" 
+                               << std::setw(10) << std::setprecision(2) << std::fixed 
+                               << 1.*((counter+1)*100)/(dirichlist.size()) 
+                               << "%" << std::flush;
+                       file 
+                               << "# Scan-Settings for 0x" 
+                               << std::hex << dirichlistitem.first 
+                               << std::dec 
+                               << "\n# gMeasureTime\tgLowerEdge(0)\tgUpperEdge(0)\tgStepsize\tgNrPasses\tgMeasureTime_over"
+                                       "\tgUpperEdge_over\tgStepsize_over\tgNrPasses_over" 
+                               << std::endl;
+                       file 
+                               << "# " 
+                               << dirichlistitem.second->gMeasureTime 
+                               << "\t" << dirichlistitem.second->gLowerEdge.at(0) 
+                               << "\t" << dirichlistitem.second->gUpperEdge.at(0) 
+                               << "\t" << dirichlistitem.second->gStepsize 
+                               << "\t" << dirichlistitem.second->gNrPasses 
+                               << "\t" << dirichlistitem.second->gMeasureTime_over 
+                               << "\t" << dirichlistitem.second->gUpperEdge_over 
+                               << "\t" << dirichlistitem.second->gStepsize_over 
+                               << "\t" << dirichlistitem.second->gNrPasses_over 
+                               << std::endl;
+                       file 
+                               << "# Scan-Data\n# dirich\tchannel\tbaseline\twidth in mV\tthreshold in mV over baseline" 
+                               << std::endl;
+                       for (int ichannel=0; ichannel<NRCHANNELS; ichannel++) {
+                               file
+                                       << std::hex << dirichlistitem.first << std::dec << "\t" 
+                                       << ichannel << "\t" 
+                                       << dirichlistitem.second->GetSingleBaseline(ichannel) << "\t" 
+                                       << dirich::Thr_DtomV(dirichlistitem.second->GetSingleNoisewidth(ichannel)) << "\t" 
+                                       << dirichlistitem.second->GetSingleThresholdmV(ichannel) 
+                                       << std::endl;
+                       }
+                       counter++;
+               }
+               std::cout << std::endl;
+       }
+       else{
+               file 
+                       << "# Scan-Settings for 0x" << std::hex << dirichptr->GetBoardAddress() 
+                       << std::dec 
+                       << "\n# gMeasureTime\tgLowerEdge(0)\tgUpperEdge(0)\tgStepsize\tgNrPasses\tgMeasureTime_over"
+                               "\tgUpperEdge_over\tgStepsize_over\tgNrPasses_over" 
+                       << std::endl;
+               file 
+                       << "# " 
+                       << dirichptr->gMeasureTime 
+                       << "\t" << dirichptr->gLowerEdge.at(0) 
+                       << "\t" << dirichptr->gUpperEdge.at(0)
+                       << "\t" << dirichptr->gStepsize 
+                       << "\t" << dirichptr->gNrPasses 
+                       << "\t" << dirichptr->gMeasureTime_over 
+                       << "\t" << dirichptr->gUpperEdge_over 
+                       << "\t" << dirichptr->gStepsize_over 
+                       << "\t" << dirichptr->gNrPasses_over 
+                       << std::endl;
+               file 
+                       << "# Scan-Data\n# dirich\tchannel\tbaseline\twidth in mV\tthreshold in mV over baseline" 
+                       << std::endl;
+               for (int ichannel=0; ichannel<NRCHANNELS; ichannel++) {
+                       file
+                       << std::hex << dirichptr->GetBoardAddress() << std::dec << "\t" 
+                       << ichannel << "\t" 
+                       << dirichptr->GetSingleBaseline(ichannel) << "\t" 
+                       << dirich::Thr_DtomV(dirichptr->GetSingleNoisewidth(ichannel)) << "\t" 
+                       << dirichptr->GetSingleThresholdmV(ichannel) 
+                       << std::endl;
+               }
+       }
+}
+
+void load_base(std::shared_ptr<dirich> dirichptr, 
+       std::string filename, 
+       bool uselast, 
+       bool set_base, 
+       bool set_thr
+       )
+{
+       std::string dirichaddress_string="";
+       uint16_t dirichaddress=0;
+       int channel=0;
+       int baseline=0;
+       double width=0;
+       double thresholdinmV=0;
+       for (auto& dirichlistitem: dirichlist){
+               if(dirichlistitem.second==NULL){
+                       std::cerr 
+                               << "dirich 0x" << std::hex << dirichlistitem.first 
+                               << std::dec << " was found uninitialized\nRun initialize_diriches(1/0) first!" 
+                               << std::endl;
+                       return;
+               }
+       }
+       std::ifstream file;
+       file.open(filename);
+       if(!file) std::cerr << "File for loading (" << filename << ") could not be opened!" << std::endl;
+       if(dirichptr==NULL){
+               std::unordered_map<uint16_t,std::array<double,32>> thresholds;
+               while(!file.eof()){
+                       std::string line;
+                       std::getline(file, line);
+                       std::istringstream iss(line);
+                       iss >> dirichaddress_string;
+                       if(dirichaddress_string=="#"){
+                               std::string dummy;
+                               std::getline(iss,dummy);
+                               continue;
+                       }
+                       // if(dirichaddress_string=="") continue;
+                       iss >> channel >> baseline >> width >> thresholdinmV;
+                       if(iss.tellg()!=-1) 
+                               std::cerr 
+                                       << "Error reading line:\n" << line 
+                                       << "\nRead in:" 
+                                       << "\ndirichaddress:0x" << dirichaddress_string 
+                                       << "\nchannel:" << channel 
+                                       << "\nbaseline:" << baseline 
+                                       << "\nwidth:" << width 
+                                       << "\nthresholdinmV:" << thresholdinmV 
+                                       << std::endl;
+                       else{
+                               dirichaddress = (uint16_t)stoi(dirichaddress_string,0,16);
+                               if(dirichlist.count(dirichaddress)!=0){
+                                       if(set_base!=0){
+                                               dirichlist.at(dirichaddress)->SetSingleBaseline_old(
+                                                       channel, 
+                                                       dirichlist.at(dirichaddress)->GetSingleBaseline(channel)
+                                               );
+                                               dirichlist.at(dirichaddress)->SetSingleBaseline(
+                                                       channel, 
+                                                       baseline
+                                               );
+
+                                               dirichlist.at(dirichaddress)->SetSingleNoisewidth_old(
+                                                       channel, 
+                                                       dirichlist.at(dirichaddress)->GetSingleNoisewidth(channel)
+                                               );
+                                               dirichlist.at(dirichaddress)->SetSingleNoisewidth(
+                                                       channel, 
+                                                       dirich::Thr_mVtoD(width)
+                                               );
+                                       }
+                                       if(set_thr!=0){
+                                               if(thresholds.find(dirichaddress)==thresholds.end()){
+                                                       std::array <double,32> temp_array;
+                                                       temp_array.fill(0);
+                                                       thresholds.insert(std::make_pair(dirichaddress,temp_array));
+                                               }
+                                               thresholds.at(dirichaddress).at(channel) = thresholdinmV;
+                                       }
+                               }
+                               else{ 
+                                       std::cerr 
+                                               << "dirich 0x" 
+                                               << std::hex << dirichaddress 
+                                               << std::dec << " was not found in list of initialized diriches" 
+                                               << std::endl;
+                                       continue;
+                               }
+                       }
+               }
+               std::vector<std::thread> threads;
+               if(set_thr!=0){
+                       gcheck_thresholds_mutex.lock();
+                       gcheck_thresholds = 2;
+                       gcheck_thresholds_mutex.unlock();
+
+                       for(auto& one_threshold : thresholds)
+                               threads.push_back(std::thread(
+                                       [&one_threshold](){
+                                               dirichlist.at(one_threshold.first)->SetThresholdsmV(
+                                                       one_threshold.second
+                                               );
+                                       }
+                               ));
+                       for(auto& one_thread : threads)
+                               one_thread.join();
+
+                       gcheck_thresholds_mutex.lock();
+                       gcheck_thresholds = 1;
+                       gcheck_thresholds_mutex.unlock();
+               }
+               for (auto& dirichlistitem: dirichlist){
+                       for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+                               if(dirichlistitem.second->GetSingleBaseline(ichannel)==0) 
+                                       std::cerr 
+                                               << "No Baseline for dirich 0x" << std::hex << dirichlistitem.first 
+                                               << std::dec << "'s channel " << ichannel 
+                                               << " found in loading-file" 
+                                               << std::endl;
+                       }
+               }
+       }
+       else if(uselast){
+               if(set_base!=0){
+                       for(int ichannel=0;ichannel<32;++ichannel){
+                               dirichptr->SetSingleBaseline_old(ichannel, dirichptr->GetSingleBaseline(ichannel));
+                               dirichptr->SetSingleNoisewidth_old(ichannel, dirichptr->GetSingleNoisewidth(ichannel));
+                       }
+               }
+               std::unordered_map<uint16_t,std::array<double,32>> thresholds;
+               while(!file.eof()){
+                       std::string line;
+                       std::getline(file, line);
+                       std::istringstream iss(line);
+                       iss >> dirichaddress_string;
+                       if(dirichaddress_string=="#"){
+                               std::string dummy;
+                               std::getline(iss,dummy);
+                               continue;
+                       }
+                       iss >> channel >> baseline >> width >> thresholdinmV;
+                       if(iss.tellg()!=-1) 
+                               std::cerr 
+                                       << "Error reading line:\n" << line 
+                                       << "\nRead in:" 
+                                       << "\ndirichaddress:0x" << dirichaddress_string 
+                                       << "\nchannel:" << channel 
+                                       << "\nbaseline:" << baseline 
+                                       << "\nwidth:" << width 
+                                       << "\nthresholdinmV:" << thresholdinmV 
+                                       << std::endl;
+                       else{
+                               if(set_base!=0){
+                                       dirichptr->SetSingleBaseline(channel, baseline);
+                                       dirichptr->SetSingleNoisewidth(channel, dirich::Thr_mVtoD(width));
+                               }
+                               if(set_thr!=0){
+                                       if(thresholds.find(dirichaddress)==thresholds.end()){
+                                               std::array <double,32> temp_array;
+                                               temp_array.fill(0);
+                                               thresholds.insert(std::make_pair(dirichaddress,temp_array));
+                                       }
+                                       thresholds.at(dirichaddress).at(channel) = thresholdinmV;
+                               }
+                       }
+               }
+               std::vector<std::thread> threads;
+               if(set_thr!=0){
+                       gcheck_thresholds_mutex.lock();
+                       gcheck_thresholds = 2;
+                       gcheck_thresholds_mutex.unlock();
+
+                       for(auto& one_threshold : thresholds)
+                               threads.push_back(std::thread(
+                                       [&one_threshold](){
+                                               dirichlist.at(one_threshold.first)->SetThresholdsmV(
+                                                       one_threshold.second
+                                               );
+                                       }
+                               ));
+                       for(auto& one_thread : threads)
+                               one_thread.join();
+               
+                       gcheck_thresholds_mutex.lock();
+                       gcheck_thresholds = 1;
+                       gcheck_thresholds_mutex.unlock();
+               }
+       }
+       else{
+               if(set_base!=0){
+                       for(int ichannel=0;ichannel<32;++ichannel){
+                               dirichptr->SetSingleBaseline_old(
+                                       ichannel, 
+                                       dirichptr->GetSingleBaseline(ichannel)
+                               );
+                               dirichptr->SetSingleNoisewidth_old(
+                                       ichannel, 
+                                       dirichptr->GetSingleNoisewidth(ichannel)
+                               );
+                       } 
+               }        
+               while(!file.eof()){
+                       std::string line;
+                       std::getline(file, line);
+                       std::istringstream iss(line);
+                       iss >> dirichaddress_string;
+                       if(dirichaddress_string=="#"){
+                               std::string dummy;
+                               std::getline(iss,dummy);
+                               continue;
+                       }
+                       iss >> channel >> baseline >> width >> thresholdinmV;
+                       dirichaddress = (uint16_t)stoi(dirichaddress_string,0,16);
+                       if(iss.tellg()!=-1) 
+                               std::cerr 
+                                       << "Error reading line:\n" << line 
+                                       << "\nRead in:" 
+                                       << "\ndirichaddress:0x" << dirichaddress_string 
+                                       << "\nchannel:" << channel 
+                                       << "\nbaseline:" << baseline 
+                                       << "\nwidth:" << width 
+                                       << "\nthresholdinmV:" << thresholdinmV 
+                                       << std::endl;
+                       else if(dirichaddress==dirichptr->GetBoardAddress()){
+                               if(set_base!=0){
+                                       dirichptr->SetSingleBaseline(channel, baseline);
+                                       dirichptr->SetSingleNoisewidth(channel, dirich::Thr_mVtoD(width));
+                               }
+                               if(set_thr!=0) dirichptr->SetSingleThresholdmV(channel, thresholdinmV);
+                       }
+               }
+       }
+}
+
+void save_graphs(std::shared_ptr<dirich>       dirichptr, std::string filename){
+       TFile* file=new TFile(Form("%s.root", filename.c_str()),"RECREATE");
+       if(dirichptr==NULL){
+               file->cd();
+               // get_noisewidth_histo(0)->Write();
+               // get_2D_rate_histo(0)->Write();
+               // get_2D_rate_over_thr_histo(0)->Write();
+               // get_2D_diff_over_thr_histo(0)->Write();
+               // get_2D_gr_diff_over_thr_histo(0)->Write();
+               // get_2D_mgr_diff_over_thr_histo(0)->Write();
+               std::cout << "saving graphs" << std::endl;
+               int counter=0;
+               for (auto& dirichlistitem: dirichlist) {
+                       std::cout 
+                               << "\r" 
+                               << std::setw(10) << std::setprecision(2) << std::fixed 
+                               << 1.*((counter+1)*100)/(dirichlist.size()) 
+                               << "%" << std::flush;
+                       TDirectory *dirich_dir = file->mkdir(Form("dirich_0x%x",dirichlistitem.first));
+                       dirich_dir->cd();
+                       get_noisewidth_histo(dirichlistitem.second)->Write();
+                       get_2D_rate_histo(dirichlistitem.second)->Write();
+                       get_2D_rate_over_thr_histo(dirichlistitem.second)->Write();
+                       get_2D_diff_over_thr_histo(dirichlistitem.second)->Write();
+                       // get_2D_gr_diff_over_thr_histo(dirichlistitem.second)->Write();
+                       // get_2D_mgr_diff_over_thr_histo(dirichlistitem.second)->Write();
+                       // TDirectory *channels = dirich_dir->mkdir("channels");
+                       // channels->cd();
+                       for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+                               // TDirectory *ch = channels->mkdir(Form("ch:%i",ichannel));
+                               // ch->cd();
+                               dirichlistitem.second->gRateGraphs[ichannel]->Write();
+                               dirichlistitem.second->gRateGraphsOverBase[ichannel]->Write();
+                               dirichlistitem.second->gDiffRateGraphsOverBase[ichannel]->Write();
+                       }
+                       counter++;
+               }
+       std::cout << std::endl;
+       }
+       else{
+               file->cd();
+               TDirectory *dirich_dir = file->mkdir(Form("dirich_0x%x",dirichptr->GetBoardAddress()));
+               dirich_dir->cd();
+               get_noisewidth_histo(dirichptr)->Write();
+               get_2D_rate_histo(dirichptr)->Write();
+               get_2D_rate_over_thr_histo(dirichptr)->Write();
+               get_2D_diff_over_thr_histo(dirichptr)->Write();
+               // get_2D_gr_diff_over_thr_histo(dirichptr)->Write();
+               // get_2D_mgr_diff_over_thr_histo(dirichptr)->Write();
+               // TDirectory *channels = dirich_dir->mkdir("channels");
+               // channels->cd();
+               for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+                       // TDirectory *ch = channels->mkdir(Form("ch:%i",ichannel));
+                       // ch->cd();
+                       dirichptr->gRateGraphs[ichannel]->Write();
+                       dirichptr->gRateGraphsOverBase[ichannel]->Write();
+                       dirichptr->gDiffRateGraphsOverBase[ichannel]->Write();
+               }
+       }
+       file->Close();
+       // gROOT->GetListOfFiles()->Remove(file); // to get a faster closing time 
+}
+
+void save()
+{
+       std::array<char, 64> buffer;
+       buffer.fill(0);
+       time_t rawtime;
+       time(&rawtime);
+       const auto timeinfo = localtime(&rawtime);
+       strftime(buffer.data(), sizeof(buffer), "%Y%m%d_%H%M%S", timeinfo);
+       std::string str = std::string(buffer.data()) + "_std_save";
+
+       save_base(NULL,str,0);
+       save_graphs(NULL,str);
+}
+
+void* scanthread_nrml(void* dirichptr) //Argument is pointer to DiRICH class instance
+{
+       if(((dirich*)dirichptr)->gdirich_reporting_level>=1) 
+               std::cout 
+                       << "Starting threshscan for Dirich at address 0x"
+                       << std::hex << ((dirich*)dirichptr)->GetBoardAddress()
+               << std::endl;
+       // std::cout << "DoThreshScan" << std::endl;
+       ((dirich*)dirichptr)->DoThreshScan();
+       // std::cout << "AnalyzeBaseline" << std::endl;
+       ((dirich*)dirichptr)->AnalyzeBaseline();
+       // std::cout << "FineScan" << std::endl;
+       ((dirich*)dirichptr)->DoFineThreshScan();
+       // std::cout << "AnalyzeBaseline" << std::endl;
+       ((dirich*)dirichptr)->AnalyzeBaseline();
+       // std::cout << "MakeGraphsOverBase" << std::endl;
+       ((dirich*)dirichptr)->MakeGraphsOverBase();
+       // std::cout << "MakeDiffGraphsOverBase" << std::endl;
+       ((dirich*)dirichptr)->MakeDiffGraphsOverBase();
+       if(((dirich*)dirichptr)->gdirich_reporting_level>=1) 
+               std::cout 
+                       << "Threshscan for Dirich at address 0x"
+                       << std::hex << ((dirich*)dirichptr)->GetBoardAddress()
+                       << " done"
+               << std::endl;
+       return 0;
+}
+
+void* scanthread_over(void* dirichptr) //Argument is pointer to DiRICH class instance
+{
+       if(((dirich*)dirichptr)->gdirich_reporting_level>=1) 
+       std::cout 
+               << "Starting threshscan_over for Dirich at address 0x"
+               << std::hex << ((dirich*)dirichptr)->GetBoardAddress()
+       << std::endl;
+       ((dirich*)dirichptr)->DoThreshScanOverBase();
+       ((dirich*)dirichptr)->MakeDiffGraphsOverBase();
+       if(((dirich*)dirichptr)->gdirich_reporting_level>=1) 
+               std::cout 
+                       << "Threshscan_over for Dirich at address 0x"
+                       << std::hex << ((dirich*)dirichptr)->GetBoardAddress()
+                       << " done"
+               << std::endl;
+       return 0;
+}
+
+void system_thr_scan(int type=0)
+{
+       if(type==0){
+               gcheck_thresholds_mutex.lock();
+               gcheck_thresholds = 1;
+               gcheck_thresholds_mutex.unlock();
+       }
+       else{
+               gcheck_thresholds_mutex.lock();
+               gcheck_thresholds = 2;
+               gcheck_thresholds_mutex.unlock();               
+       }
+       std::vector <std::thread*> threadlist;
+       // Initialize instances of dirich class for each module
+       for (auto& dirichlistitem: dirichlist){
+               if(dirichlistitem.second==NULL){
+                       std::cerr 
+                               << "DiRICH " << std::hex << dirichlistitem.first 
+                               << std::dec << " not initialized!" 
+                               << std::endl;
+                       continue;
+               }
+               switch(type){
+               case 1:
+                       threadlist.push_back(
+                               new std::thread(
+                                       scanthread_over, 
+                                       (void*) dirichlistitem.second.get()
+                               )
+                       );
+                       break;
+               case 0:
+               default:
+                       threadlist.push_back(
+                               new std::thread(
+                                       scanthread_nrml, 
+                                       (void*) dirichlistitem.second.get()
+                                       )
+                               );
+                       break;
+               }
+       }
+       usleep(1000);
+
+       for(auto& thread : threadlist){
+                       thread->join();
+                       delete thread;
+       }
+       gcheck_thresholds_mutex.lock();
+       gcheck_thresholds = 1;
+       gcheck_thresholds_mutex.unlock();
+       // threadlist.clear();
+       // printf("System scan done ! \n");
+       switch(type){
+       case 1:
+               save();
+               break;
+       case 0:
+       default:
+               save();
+               break;
+       }
+
+}
+
+void* check_thresholds(){
+       // return 0;
+       if(self_check_threshold==true) return 0;
+       int ret = 0;
+       int break_counter=0;
+       std::map<uint16_t,std::array<uint16_t,NRCHANNELS>> thresholds;
+       std::array<uint16_t,NRCHANNELS> temp_array;
+       temp_array.fill(0);
+       for(auto& dirichlistitem : dirichlist){
+               thresholds.insert(std::make_pair(dirichlistitem.first,temp_array));
+       }
+       uint32_t temp_buffer4mb[BUFFER_SIZE4mb];
+       while(true){
+               gcheck_thresholds_mutex.lock();
+               int temp_gcheck_thresholds = gcheck_thresholds;
+               gcheck_thresholds_mutex.unlock();
+               switch(temp_gcheck_thresholds){
+                       case 0:
+                       default:
+                       return 0;
+                       case 1:
+                       std::this_thread::sleep_for(std::chrono::microseconds(10*THRESHDELAY));
+                       break;
+                       case 2:
+                       for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+                               uint32_t real_ichannel = ichannel%CHPCHAIN;
+                               uint32_t c[] = {
+                                       (0x0 << 20 | real_ichannel << 24),
+                                       0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+                                       (uint32_t)ichannel/CHPCHAIN+1,
+                                       0x10001
+                               }; 
+                               ret=Ttrb_register_write_mem(BROADCAST,0xd400,0,c,CHPCHAIN+2);
+                               if(ret<0){
+                                       std::cerr << "Can't retreive Thresholds (1)!!!" << std::endl;
+                                       break_counter++;
+                                       if(break_counter>100) return 0;
+                                       else break;
+                               }
+                               std::this_thread::sleep_for(std::chrono::microseconds(SPICOMDELAY));
+                               ret=Ttrb_register_read(BROADCAST,0xd412,temp_buffer4mb,BUFFER_SIZE4mb);
+                               if(ret<0){
+                                       std::cerr << "Can't retreive Thresholds (2)!!!" << std::endl;
+                                       break_counter++;
+                                       if(break_counter>100) return 0;
+                                       else break;
+                               }
+                               for(int i=0;i<ret;i+=2){
+                                       thresholds.at(temp_buffer4mb[i]).at(ichannel) = uint16_t(temp_buffer4mb[i+1] & 0xffff);
+                               }
+                       }
+                       for(auto& threshold : thresholds){
+                               dirichlist.at(threshold.first)->Current_Thr_Mutex.lock();
+                               dirichlist.at(threshold.first)->gCurrent_Threshold = threshold.second;
+                               dirichlist.at(threshold.first)->gCurrent_Threshold_time = std::chrono::steady_clock::now();
+                               dirichlist.at(threshold.first)->Current_Thr_Mutex.unlock();
+                       }
+                       // std::cout << "done checking" << std::endl;
+                       std::this_thread::sleep_for(std::chrono::microseconds(SPICOMDELAY));
+                       break;
+               }
+       }
+       return 0;
+}
+
+dirich* make_new_dirich(uint16_t uid){
+       return new dirich(uid);
+}
+
+void initialize_diriches(bool search_dirich)
+{
+// void initialize_diriches(bool search_dirich, std::vector<int> ranges, int NrPasses, double meas_time){
+       TH1::AddDirectory(0);
+       gErrorIgnoreLevel = kError;
+       int ret=0;
+       ret=init_ports();
+
+       if(ret==-1){
+               std::cerr << "failed to initialize trb-net ports" << std::endl;
+       }
+       dirichlist.clear();
+
+       if(search_dirich){
+               int dirich_counter=0;
+               ret=Ttrb_read_uid(BROADCAST, buffer4mb, BUFFER_SIZE4mb);
+               if(ret<4){
+                       std::cerr << "No TRB3 Modules found!!!" << std::endl;
+                       return;
+               }
+               std::unordered_map<uint16_t,std::future<dirich*>> inited_diriches;
+               for(int i=0;i<ret;i+=4){
+                       // if(buffer[i+3]>0x1200 && buffer[i+3]<0x1200)
+                       inited_diriches.insert(
+                               std::make_pair(
+                                       uint16_t(buffer4mb[i+3]),
+                                       std::async(
+                                               std::launch::async,
+                                               [](uint16_t uid) ->dirich* {
+                                                       return new dirich(uid);
+                                               },
+                                               uint16_t(buffer4mb[i+3])
+                                       )
+                               )
+                       );
+               ++dirich_counter;
+               }
+               for(auto& one_dirich : inited_diriches){
+                       one_dirich.second.wait();
+                       dirich* temp_dirich_prt = one_dirich.second.get();
+                       if(temp_dirich_prt->WhichDirichVersion()!=3){ 
+                               //pls change it according to your initialization... Sure one should rather throw during init... but well I am lazy
+                               std::cerr 
+                                       << "DiRICH 0x" << std::hex << one_dirich.first 
+                                       << " not correclty initialized. Deleting!" 
+                                       << std::endl;
+                               delete one_dirich.second.get();
+                       }
+                       else
+                               dirichlist.insert(
+                                       std::make_pair(one_dirich.first,std::shared_ptr<dirich>(temp_dirich_prt))
+                               );
+               }
+               std::cout 
+                       << "Found " << std::dec << inited_diriches.size() 
+                       << " different diriches\nInitialized " << dirichlist.size() 
+                       << " out of those" 
+                       << std::endl;
+       }
+       if(dirichlist.size()==0) exit(EXIT_FAILURE);
+       // for(auto& dirichlistitem : dirichlist){
+       //      dirichlistitem.second->gdirich_reporting_level=3;       
+       // }
+       dirichlist.begin()->second->gdirich_reporting_level=1;
+       // std::cout << dirichlist.end()->first << std::endl;
+       // dirichlist.end()->second->gdirich_reporting_level=1;
+}
+
+void setup_scan_parameters(
+       std::shared_ptr<dirich> dirichptr, 
+       double gMeasureTime, 
+       int gLowerEdge, 
+       int gUpperEdge, 
+       int gStepsize, 
+       int gNrPasses
+)
+{
+       if(dirichptr==NULL){
+               for (auto& dirichlistitem: dirichlist) {
+                       if(dirichlistitem.second==NULL){
+                               std::cerr 
+                                       << "dirich 0x" << std::hex << dirichlistitem.first 
+                                       << std::dec << " not initialized" 
+                                       << std::endl;
+                               continue;
+                       }
+                       dirichlistitem.second->gMeasureTime = gMeasureTime;
+                       dirichlistitem.second->gLowerEdge.fill(gLowerEdge);
+                       dirichlistitem.second->gUpperEdge.fill(gUpperEdge);
+                       dirichlistitem.second->gStepsize = gStepsize;
+                       dirichlistitem.second->gNrPasses = gNrPasses;
+               }
+       }
+       else{
+               dirichptr->gMeasureTime = gMeasureTime;
+               dirichptr->gLowerEdge.fill(gLowerEdge);
+               dirichptr->gUpperEdge.fill(gUpperEdge);
+               dirichptr->gStepsize = gStepsize;
+               dirichptr->gNrPasses = gNrPasses;
+       }
+}
+
+void setup_scan_parameters_over_thr_mV(
+       std::shared_ptr<dirich> dirichptr, 
+       double gMeasureTime, 
+       double gUpperEdgemV, 
+       double gStepsizemV, 
+       int gNrPasses
+)
+{
+       if(dirichptr==NULL){
+               for (auto& dirichlistitem: dirichlist) {
+                       if(dirichlistitem.second==NULL){
+                               std::cerr 
+                                       << "dirich 0x" << std::hex << dirichlistitem.first 
+                                       << std::dec << " not initialized" 
+                                       << std::endl;
+                               continue;
+                       }
+                       dirichlistitem.second->gMeasureTime_over = gMeasureTime;
+                       dirichlistitem.second->gUpperEdge_over = gUpperEdgemV;
+                       dirichlistitem.second->gStepsize_over = gStepsizemV;
+                       dirichlistitem.second->gNrPasses_over = gNrPasses;
+               }
+       }
+       else{
+               dirichptr->gMeasureTime_over = gMeasureTime;
+               dirichptr->gUpperEdge_over = gUpperEdgemV;
+               dirichptr->gStepsize_over = gStepsizemV;
+               dirichptr->gNrPasses_over = gNrPasses;
+       }
+}
+
+
+int main(int argc, char* argv[]){
+       std::string loading_file = "";
+       std::string loading_file_threshold = "";
+       std::string save_file = "";
+       // Declare the supported options.
+       po::options_description desc("Allowed options");
+       desc.add_options()
+                       (
+                               "help,h",
+                               "produce help message"
+                       )
+                       (
+                               "verbosity,v", 
+                               po::value<int>(), 
+                               "Set verbosity level"
+                       )
+                       // (
+                       //      "use-dirich,u", 
+                       //      po::value<std::vector<std::string>>()->multitoken(), 
+                       //      "Add diriches to the dirichlist. If dirich does not exist it will be simulated"
+                       // )
+                       // (
+                       //      "dont-search-dirich", 
+                       //      "Dont't search for active diriches during startup."
+                       // )
+                       (
+                               "scan-baseline,b", 
+                               po::value<std::vector<std::string>>()->multitoken(), 
+                                       "Do standard baselinescan. "
+                                       "Six parameters need to be given:"
+                                       "dirich (if 0, all diriches), "
+                                       "measure-time (s), "
+                                       "threshold-start-value, "
+                                       "threshold-end-value, "
+                                       "threshold-step-width, "
+                                       "number of cycles (two refers to every second channel measured at a time). "
+                                       "Values will be set for all diriches!"
+                       )
+                       (
+                               "draw-scan-baseline,d", 
+                               po::value<std::vector<std::string>>()->multitoken(), 
+                                       "Draw the results of the baselinescan. "
+                                       "Dirich can be specified using this options parameter. "
+                                       "Obviously this function fails if no scan was done!"
+                       )
+                       (
+                               "draw-scan-above-noise", 
+                               po::value<std::vector<std::string>>()->multitoken(), 
+                                       "Draw the results of the thresholdscan above the diriches noiseband. "
+                                       "Dirich can be specified using this options parameter. "
+                                       "Obviously this function fails if no scan was done!"
+                               )
+                       (
+                               "draw-scan-above-noise-diff-gr", 
+                               po::value<std::vector<std::string>>()->multitoken(), 
+                                       "Draw the results of the baselinescan above the diriches noiseband as differential plot. "
+                                       "Dirich can be specified using this options parameter. "
+                                       "Obviously this function fails if no scan was done!"
+                       )
+                       (
+                               "draw-noisewidth,w", 
+                               po::value<std::vector<std::string>>()->multitoken(), 
+                                       "Draw the noisewidth. "
+                                       "Dirich can be specified using this options parameter. "
+                                       "Obviously this function fails if neither a scan was done nor a threshold-setting was loaded!"
+                       )
+                       (
+                               "measure-rate,r", 
+                               po::value<std::vector<std::string>>()->multitoken(), 
+                                       "measure the rate for given dirich (if 0, all diriches)"
+                       )
+                       // (
+                       //      "find-threshold,i", 
+                       //      po::value<double>(),
+                       //      "
+                       //              Find the perfect threshold for the given dirich/maptm-channel-combination. 
+                       //              The parameter specifies the method to find the perfect threshold:
+                       //              \n0: searches for the minimum in the differentiated spectrum or for the minimal gradient
+                       //              \n0<value<5: tries to find peak and sigma of the single photon distribution and 
+                       //                      sets the threshold to value*sigma (!!!!currently not implemented!!!)
+                       //              \n5<value<100: tries to find the single photon peak and 
+                       //                      sets the threshold to value% of the spp-position
+                       //      "
+                       // )
+                       (
+                               "scan-above-noise,a", 
+                               po::value<std::vector<std::string>>()->multitoken(), 
+                                       "Do scan for threshold-values greater than the diriches noiseband. "
+                                       "Five parameters need to be given:"
+                                       "dirich (if 0, all diriches), "
+                                       "measure-time (s), "
+                                       "threshold-end-value (mV), "
+                                       "threshold-step-width (mV), "
+                                       "number of cycles (two refers to every second channel measured at a time"
+                       )
+                       (
+                               "load-baseline,l", 
+                               po::value<std::vector<std::string>>()->multitoken(), 
+                                       "This option loads the baseline from the file specified in --loading-file. "
+                                       "If no file was specified, the latest produced file is choosen. "
+                                       "One can specify a certain dirich by using this options parameter. "
+                                       "Be aware that this option overwrites the baseline retreived from the baselinescan"
+                       )
+                       (
+                               "load-threshold", 
+                               po::value<std::vector<std::string>>()->multitoken(), 
+                                       "This option loads the threshold from the file specified in --loading-file-threshold. "
+                                       "If no file was specified, the latest produced file is choosen. "
+                                       "One can specify a certain dirich by using this options parameter. "
+                                       "Be aware that the thresholds are overwriten by --set-threshold"
+                       )
+                       (
+                               "loading-file,f", 
+                               po::value<std::string>(&loading_file)->default_value(""), 
+                               "File to load thresholds and/or baseline from"
+                       )
+                       (
+                               "loading-file-threshold", 
+                               po::value<std::string>(&loading_file_threshold)->default_value(""), 
+                               "File to load thresholds from. If no file is specified, the normal loading-file is used"
+                       )
+                       (
+                               "set-to-noise,n", 
+                               po::value<std::vector<std::string>>()->multitoken(), 
+                                       "Set threshold to a certain distance in terms of noisewidth for specified diriches. "
+                                       "First Parameter specifies the dirich (0 equals all DiRICHes), "
+                                       "the second the part of the half-noisebandwidth."
+                       )
+                       (
+                               "set-threshold,t", 
+                               po::value<std::vector<std::string>>()->multitoken(), 
+                                       "Set threshold for specified diriches in mV. "
+                                       "First Parameter specifies the dirich (0 equals all DiRICHes), "
+                                       "the second the threshold. "
+                                       "Only positive threshold values are accepted, as the minus-sign induces errors."
+                       )
+                       (
+                               "set-pattern,p", 
+                               po::value<std::vector<std::string>>()->multitoken(), 
+                                       "Set pattern for specified diriches. "
+                                       "First Parameter specifies the dirich (0 equals all DiRICHes), the second the pattern. "
+                                       "The pattern is derived by interpreting the second parameter "
+                                       "       as bitpattern and disabling each channel where the corresponding bit equals 0. "
+                                       "To disable one or many diriches completely you need to put the pattern 00!. "
+                                       "And... What you are searching for is 1431655765/2863311530"
+                       )
+                       (
+                               "save,s", 
+                               po::value<std::vector<std::string>>()->multitoken(), 
+                                       "Save histograms and data of specified dirich after everything else is executed! "
+                                       "Autosaves will be still produced and saved via \"DATE_std_save{.thr,.root}\". "
+                                       "Savefile can be set via --save-file"
+                       )
+                       (
+                               "save-file", 
+                               po::value<std::string>(&save_file)->default_value(""), 
+                               "Save histograms and data. If no file specified, a std. filename will be produced"
+                       )
+       ;
+// implicit_value(std::vector<std::string>{"0"},"0")
+       po::variables_map vm;
+       po::store(po::parse_command_line(argc, argv, desc), vm);
+       po::notify(vm);
+
+       if (vm.count("help")) {
+               std::cout << desc << std::endl;
+               return 0;
+       }
+       if(loading_file==""){
+               fs::path latest;
+               std::time_t latest_tm {};
+               for (auto&& entry : boost::make_iterator_range(fs::directory_iterator("."), {})) {
+                       fs::path p = entry.path();
+                       if (is_regular_file(p) && p.extension() == ".thr") 
+                       {
+                               std::time_t timestamp = fs::last_write_time(p);
+                               if (timestamp > latest_tm) {
+                                       latest = p;
+                                       latest_tm = timestamp;
+                               }
+                       }
+               }
+               loading_file = latest.filename().string();
+       }
+
+       // if(vm.count("use-diriches")){
+       //       for(auto& use_diriches_options : vm["use-diriches"].as<std::vector<std::string>>()){
+       //               dirichlist.emplace(
+       //                      std::stoi(
+       //                              use_diriches_options.substr(use_diriches_options.find("0x")!=std::string::npos ? 
+       //                              use_diriches_options.find("0x")+2 : 0),NULL,16)
+       //                      ,(dirich*)NULL
+       //              );
+       //       }
+       // }
+
+       // if(!vm.count("dont-search-dirich")) initialize_diriches(1);
+       // else initialize_diriches(0);
+
+       initialize_diriches(1);
+       std::cout << "All set and done" << std::endl;
+       std::thread* threshold_checker= new std::thread(check_thresholds);
+       gcheck_thresholds_mutex.lock();
+       gcheck_thresholds = 1;
+       gcheck_thresholds_mutex.unlock();
+
+       if(vm.count("verbosity")){
+               for(auto& dirich : dirichlist){
+                       dirich.second->gdirich_reporting_level=vm["verbosity"].as<int>();
+               }
+       }
+
+       if(vm.count("scan-baseline")){
+               if(vm["scan-baseline"].empty() || (vm["scan-baseline"].as<std::vector<std::string>>()).size() < 6){
+                       std::cout 
+                               << "no or less than six arguments were provided for option --scan-baseline:"
+                               "\nrunning scan with std. parameters" 
+                               << std::endl;
+               }
+               else{
+                       std::vector<std::vector<std::string>> each_scan_base_opt;
+                       std::vector<std::string> temp_vec;
+                       for(auto& scan_base_opt : vm["scan-baseline"].as<std::vector<std::string>>()){
+                               std::cout << scan_base_opt << std::endl;
+                               if(scan_base_opt.find("0x")!=std::string::npos || scan_base_opt=="0"){
+                                       // std::cout << "0 or 0x" <<std::endl;
+                                       if(temp_vec.size()==6){
+                                               each_scan_base_opt.push_back(temp_vec);
+                                       }
+                                       temp_vec.clear();
+                               }
+                               temp_vec.push_back(scan_base_opt);
+                       }
+                       if(temp_vec.size()==6){
+                               each_scan_base_opt.push_back(temp_vec);
+                       }
+                       for(auto& one_scan_base_opt : each_scan_base_opt){
+                               std::cout 
+                                       << std::stoi(
+                                               one_scan_base_opt.at(0).substr(one_scan_base_opt.at(0).find("0x")!=std::string::npos ? 
+                                               one_scan_base_opt.at(0).find("0x")+2 : 0),NULL,16
+                                       ) 
+                                       << "\t" << std::stod(one_scan_base_opt.at(1)) 
+                                       << "\t" << std::stoi(one_scan_base_opt.at(2)) 
+                                       << "\t" << std::stoi(one_scan_base_opt.at(3)) 
+                                       << "\t" << std::stoi(one_scan_base_opt.at(4)) 
+                                       << "\t" << std::stoi(one_scan_base_opt.at(5)) 
+                                       << std::endl;
+                               setup_scan_parameters(
+                                       one_scan_base_opt.at(0) == "0" ? 
+                                       0 : dirichlist.at(
+                                                       std::stoi(
+                                                               one_scan_base_opt.at(0).substr(one_scan_base_opt.at(0).find("0x")!=std::string::npos ?
+                                                               one_scan_base_opt.at(0).find("0x")+2 : 0),NULL,16
+                                                       )
+                                               )
+                                       , std::stod(one_scan_base_opt.at(1))
+                                       , std::stoi(one_scan_base_opt.at(2))
+                                       , std::stoi(one_scan_base_opt.at(3))
+                                       , std::stoi(one_scan_base_opt.at(4))
+                                       , std::stoi(one_scan_base_opt.at(5))
+                               );
+                       }
+               }
+               system_thr_scan(0);
+
+               if(vm.count("draw-scan-baseline")){
+                       // std::cout << "draw-scan-baseline" << std::endl;
+                       if(vm["draw-scan-baseline"].empty()){
+                               draw_histo(get_2D_rate_histo(NULL),NULL);
+                       }
+                       for(auto& draw_scan_baseline_options : vm["draw-scan-baseline"].as<std::vector<std::string>>()){
+                               // std::cout << "input for draw-scan-baseline: " << draw_scan_baseline_options << std::endl;
+                               if(draw_scan_baseline_options=="0") 
+                                       draw_histo(get_2D_rate_histo(NULL),NULL);
+                               else 
+                                       draw_histo(
+                                               get_2D_rate_histo(
+                                                       dirichlist.at(
+                                                               std::stoi(
+                                                                       draw_scan_baseline_options.substr(draw_scan_baseline_options.find("0x")!=std::string::npos ? 
+                                                                               draw_scan_baseline_options.find("0x")+2 : 0
+                                                                       ),
+                                                               NULL,
+                                                               16
+                                                               )
+                                                       )
+                                               ),
+                                               NULL
+                                       );
+                       }
+               }
+               if(vm.count("draw-noisewidth")){
+                       if(vm["draw-noisewidth"].empty()){
+                               draw_histo(get_noisewidth_histo(NULL),NULL);
+                       }
+                       for(auto& draw_noisewidth_options : vm["draw-noisewidth"].as<std::vector<std::string>>()){
+                               if(draw_noisewidth_options=="0") 
+                                       draw_histo(get_noisewidth_histo(NULL),NULL);
+                               else 
+                                       draw_histo(
+                                               get_noisewidth_histo(
+                                                       dirichlist.at(
+                                                               std::stoi(
+                                                                       draw_noisewidth_options.substr(draw_noisewidth_options.find("0x")!=std::string::npos ? 
+                                                                               draw_noisewidth_options.find("0x")+2 : 0
+                                                                       ),
+                                                                       NULL,
+                                                                       16
+                                                               )
+                                                       )
+                                               ),
+                                       NULL
+                               );
+                       }
+               }
+       }
+
+       if(vm.count("load-baseline")){
+               // std::cout << "inside load baseline" << std::endl;
+               if(loading_file==""){
+                       std::cout << "no loading-file found!\n! aborting !" << std::endl;
+               }
+               else{
+                       std::cout << "loading_file: " << loading_file << std::endl;
+                       for(auto& load_baseline_opt : vm["load-baseline"].as<std::vector<std::string>>()){
+                               if(load_baseline_opt=="0") 
+                                       load_base(NULL, loading_file, 0, 1, 0);
+                               else 
+                                       load_base(
+                                               dirichlist.at(
+                                                       std::stoi(
+                                                               load_baseline_opt.substr(load_baseline_opt.find("0x")!=std::string::npos ? 
+                                                                       load_baseline_opt.find("0x")+2 : 0),
+                                                               NULL,
+                                                               16)
+                                                       ), 
+                                               loading_file, 
+                                               0, 
+                                               1, 
+                                               0
+                                       );
+                       }
+                       if(vm.count("draw-noisewidth")){
+                               if(vm["draw-noisewidth"].empty()){
+                                       draw_histo(get_noisewidth_histo(NULL),NULL);
+                               }
+                               for(auto& draw_noisewidth_options : vm["draw-noisewidth"].as<std::vector<std::string>>()){
+                                       if(draw_noisewidth_options=="0") 
+                                               draw_histo(get_noisewidth_histo(NULL),NULL);
+                                       else 
+                                               draw_histo(
+                                                       get_noisewidth_histo(
+                                                               dirichlist.at(
+                                                                       std::stoi(draw_noisewidth_options.substr(draw_noisewidth_options.find("0x")!=std::string::npos ? 
+                                                                               draw_noisewidth_options.find("0x")+2 : 0),
+                                                                       NULL,
+                                                                       16
+                                                                       )
+                                                               )
+                                                       ),
+                                                       NULL
+                                               );
+                               }
+                       }
+               }
+       }
+
+       if(vm.count("scan-above-noise")){
+               if(vm["scan-above-noise"].empty() || (vm["scan-above-noise"].as<std::vector<std::string>>()).size() < 5){
+                       std::cout 
+                       << "no or less than five arguments were provided for option --scan-above-noise:\nrunning scan with std. parameters" 
+                       << std::endl;
+               }
+               else{
+                       std::vector<std::vector<std::string>> each_scan_above_noise_opt;
+                       std::vector<std::string> temp_vec;
+                       for(auto& scan_above_noise_opt : vm["scan-above-noise"].as<std::vector<std::string>>()){
+                               if(scan_above_noise_opt.find("0x")!=std::string::npos || scan_above_noise_opt=="0"){
+                                       if(temp_vec.size()==5){
+                                               each_scan_above_noise_opt.push_back(temp_vec);
+                                       }
+                                       temp_vec.clear();
+                               }
+                               temp_vec.push_back(scan_above_noise_opt);
+                       }
+                       if(temp_vec.size()==5){
+                               each_scan_above_noise_opt.push_back(temp_vec);
+                       }        
+                       for(auto& one_scan_above_noise_opt : each_scan_above_noise_opt){
+                               std::cout 
+                               << std::stoi(one_scan_above_noise_opt.at(0).substr(
+                                       one_scan_above_noise_opt.at(0).find("0x")!=std::string::npos ? 
+                                               one_scan_above_noise_opt.at(0).find("0x")+2 : 0),
+                                       NULL,
+                                       16
+                               ) << "\t"
+                               << std::stod(one_scan_above_noise_opt.at(1)) << "\t"
+                               << std::stod(one_scan_above_noise_opt.at(2)) << "\t"
+                               << std::stod(one_scan_above_noise_opt.at(3)) << "\t"
+                               << std::stoi(one_scan_above_noise_opt.at(4)) 
+                                       << std::endl;
+                               setup_scan_parameters_over_thr_mV(
+                                       one_scan_above_noise_opt.at(0) == "0" ? 
+                                               0 : dirichlist.at(
+                                                       std::stoi(one_scan_above_noise_opt.at(0).substr(one_scan_above_noise_opt.at(0).find("0x")!=std::string::npos ? 
+                                                               one_scan_above_noise_opt.at(0).find("0x")+2 : 0),
+                                                       NULL,
+                                                       16
+                                               )
+                                       )
+                                       , std::stod(one_scan_above_noise_opt.at(1))
+                                       , std::stod(one_scan_above_noise_opt.at(2))
+                                       , std::stod(one_scan_above_noise_opt.at(3))
+                                       , std::stoi(one_scan_above_noise_opt.at(4))
+                               );
+                       }
+               }
+               system_thr_scan(1);
+       }
+
+       if(vm.count("load-threshold")){
+               if(loading_file_threshold=="")
+                       loading_file_threshold=loading_file;
+               for(auto& load_threshold_options : vm["load-threshold"].as<std::vector<std::string>>()){
+                       std::cout << "loading_file_threshold: " << loading_file_threshold << std::endl;
+                       if(load_threshold_options=="0") 
+                               load_base(NULL, loading_file_threshold,0, 0, 1);
+                       else 
+                               load_base(
+                                       dirichlist.at(
+                                                       std::stoi(
+                                                       load_threshold_options.substr(
+                                                               load_threshold_options.find("0x")!=std::string::npos ? load_threshold_options.find("0x")+2 : 0
+                                                               ),
+                                                       NULL,
+                                                       16
+                                               )
+                                       ), 
+                                       loading_file_threshold, 
+                                       0, 
+                                       0, 
+                                       1
+                               );
+               }
+       }
+
+       if(vm.count("scan-above-noise")){
+               if(vm.count("draw-scan-above-noise")){
+                       if(vm["draw-scan-above-noise"].empty()){
+                               draw_histo(get_2D_rate_over_thr_histo(NULL),NULL);
+                       }
+                       for(auto& draw_scan_above_noise_options : vm["draw-scan-above-noise"].as<std::vector<std::string>>()){
+                               if(draw_scan_above_noise_options=="0") 
+                                       draw_histo(get_2D_rate_over_thr_histo(NULL),NULL);
+                               else 
+                                       draw_histo(
+                                               get_2D_rate_over_thr_histo(
+                                                       dirichlist.at(
+                                                               std::stoi(
+                                                                       draw_scan_above_noise_options.substr(draw_scan_above_noise_options.find("0x")!=std::string::npos ? 
+                                                                               draw_scan_above_noise_options.find("0x")+2 : 0),
+                                                                       NULL,
+                                                                       16
+                                                               )
+                                                       )
+                                               ),
+                                               NULL
+                                       );
+                       }
+               }
+               if(vm.count("draw-scan-above-noise-diff-gr")){
+                       if(vm["draw-scan-above-noise-diff-gr"].empty()){
+                               draw_multigraph(get_2D_mgr_diff_over_thr_histo(NULL),NULL);
+                       }
+                       for(auto& draw_scan_above_noise_diff_options : vm["draw-scan-above-noise-diff-gr"].as<std::vector<std::string>>()){
+                               if(draw_scan_above_noise_diff_options=="0") 
+                                       draw_multigraph(get_2D_mgr_diff_over_thr_histo(NULL),NULL);
+                               else 
+                                       draw_multigraph(
+                                               get_2D_mgr_diff_over_thr_histo(
+                                                       dirichlist.at(
+                                                               std::stoi(
+                                                                       draw_scan_above_noise_diff_options.substr(draw_scan_above_noise_diff_options.find("0x")!=std::string::npos ? 
+                                                                               draw_scan_above_noise_diff_options.find("0x")+2 : 0),
+                                                                       NULL,
+                                                                       16
+                                                               )
+                                                       )
+                                               ),
+                                               NULL
+                                       );
+                       }
+               }
+       }
+
+       if(vm.count("set-to-noise")){
+               if(vm["set-to-noise"].empty() || (vm["set-to-noise"].as<std::vector<std::string>>()).size() < 2){
+                       std::cout 
+                               << "no or less than two arguments were provided for option --set-to-noise:\nno thresholds will be set" 
+                               << std::endl;
+               }
+               else{
+                       std::vector<std::vector<std::string>> each_set_threshold_noise_opt;
+                       std::vector<std::string> temp_vec;
+                       for(auto& set_threshold_noise_opt : vm["set-to-noise"].as<std::vector<std::string>>()){
+                               if(set_threshold_noise_opt.find("0x")!=std::string::npos || set_threshold_noise_opt=="0"){
+                                       if(temp_vec.size()==2){
+                                               each_set_threshold_noise_opt.push_back(temp_vec);
+                                       }
+                                       temp_vec.clear();
+                               }
+                               temp_vec.push_back(set_threshold_noise_opt);
+                       }
+                       if(temp_vec.size()==2){
+                               each_set_threshold_noise_opt.push_back(temp_vec);
+                       }        
+                       for(auto& one_set_threshold_noise_opt : each_set_threshold_noise_opt){
+                               std::cout << "Setting Threshold of: "
+                                                                       << std::stoi(
+                                                                               one_set_threshold_noise_opt.at(0).substr(one_set_threshold_noise_opt.at(0).find("0x")!=std::string::npos ? 
+                                                                                       one_set_threshold_noise_opt.at(0).find("0x")+2 : 0),
+                                                                               NULL,
+                                                                               16
+                                                                       ) << "\t"
+                                                                       << " to: "
+                                                                       << std::stod(one_set_threshold_noise_opt.at(1))
+                                                                       << " times the noisebandwidth" << std::endl;
+                               set_thresholds_to_noise(
+                                       one_set_threshold_noise_opt.at(0) == "0" ? 
+                                       0 : dirichlist.at(
+                                               std::stoi(
+                                                       one_set_threshold_noise_opt.at(0).substr(one_set_threshold_noise_opt.at(0).find("0x")!=std::string::npos ? 
+                                                               one_set_threshold_noise_opt.at(0).find("0x")+2 : 0),
+                                                       NULL,
+                                                       16
+                                               )
+                                       ), 
+                                       std::stod(one_set_threshold_noise_opt.at(1))
+                               );
+                       }
+               }
+       }
+
+       if(vm.count("set-threshold")){
+               if(vm["set-threshold"].empty() || (vm["set-threshold"].as<std::vector<std::string>>()).size() < 2){
+                       std::cout 
+                               << "no or less than two arguments were provided for option --set-threshold:\nno thresholds will be set" 
+                               << std::endl;
+               }
+               else{
+                       std::vector<std::vector<std::string>> each_set_threshold_opt;
+                       std::vector<std::string> temp_vec;
+                       for(auto& set_threshold_opt : vm["set-threshold"].as<std::vector<std::string>>()){
+                               if(set_threshold_opt.find("0x")!=std::string::npos || set_threshold_opt=="0"){
+                                       if(temp_vec.size()==2){
+                                               each_set_threshold_opt.push_back(temp_vec);
+                                       }
+                                       temp_vec.clear();
+                               }
+                               temp_vec.push_back(set_threshold_opt);
+                       }
+                       if(temp_vec.size()==2){
+                               each_set_threshold_opt.push_back(temp_vec);
+                       }        
+                       for(auto& one_set_threshold_opt : each_set_threshold_opt){
+                               std::cout << "Setting Threshold of: "
+                                                                       << std::stoi(
+                                                                                       one_set_threshold_opt.at(0).substr(one_set_threshold_opt.at(0).find("0x")!=std::string::npos ? 
+                                                                                               one_set_threshold_opt.at(0).find("0x")+2 : 0),
+                                                                                       NULL,
+                                                                                       16
+                                                                               ) 
+                                                                       << "\t" << " to: "
+                                                                       << std::stod(one_set_threshold_opt.at(1))
+                                                                       << std::endl;
+                               set_thresholds(
+                                       one_set_threshold_opt.at(0) == "0" ? 
+                                               0 : dirichlist.at(
+                                                       std::stoi(
+                                                               one_set_threshold_opt.at(0).substr(one_set_threshold_opt.at(0).find("0x")!=std::string::npos ? 
+                                                                       one_set_threshold_opt.at(0).find("0x")+2 : 0),
+                                                               NULL,
+                                                               16
+                                                       )
+                                               ), 
+                                       std::stoi(one_set_threshold_opt.at(1))
+                               );
+                       }
+               }
+       }
+
+       if(vm.count("set-pattern")){
+               if(vm["set-pattern"].empty() || (vm["set-pattern"].as<std::vector<std::string>>()).size() < 2){
+                       std::cout 
+                               << "no or less than two arguments were provided for option --set-pattern:\nno thresholds will be set" 
+                               << std::endl;
+               }
+               else{
+                       std::vector<std::vector<std::string>> each_set_pattern_opt;
+                       std::vector<std::string> temp_vec;
+                       for(auto& set_pattern_opt : vm["set-pattern"].as<std::vector<std::string>>()){
+                               if(set_pattern_opt.find("0x")!=std::string::npos || set_pattern_opt=="0"){
+                                       if(temp_vec.size()==2){
+                                               each_set_pattern_opt.push_back(temp_vec);
+                                       }
+                                       temp_vec.clear();
+                               }
+                               temp_vec.push_back(set_pattern_opt);
+                       }
+                       if(temp_vec.size()==2){
+                               each_set_pattern_opt.push_back(temp_vec);
+                       }        
+                       for(auto& one_set_pattern_opt : each_set_pattern_opt){
+                               std::cout << "Setting Threshold of: "
+                                                                       << std::stoi(
+                                                                               one_set_pattern_opt.at(0).substr(one_set_pattern_opt.at(0).find("0x")!=std::string::npos ? 
+                                                                               one_set_pattern_opt.at(0).find("0x")+2 : 0),NULL,16) 
+                                                                       << "\t" << " to: ";
+                                                                       for(int ichannel=0;ichannel<NRCHANNELS;++ichannel) 
+                                                                               std::cout << (std::stol(one_set_pattern_opt.at(1)) >> ichannel) % 2;
+                                                                       std::cout << std::endl;
+                               set_pattern(
+                                       one_set_pattern_opt.at(0) == "0" ? 
+                                       0 : dirichlist.at(
+                                               std::stoi(
+                                                       one_set_pattern_opt.at(0).substr(one_set_pattern_opt.at(0).find("0x")!=std::string::npos ? 
+                                                               one_set_pattern_opt.at(0).find("0x")+2 : 0),
+                                                       NULL,
+                                                       16
+                                               )
+                                       ), 
+                                       std::stol(one_set_pattern_opt.at(1))
+                               );
+                       }
+               }
+       }
+
+       if(save_file==""){
+               std::array<char, 64> buffer;
+               buffer.fill(0);
+               time_t rawtime;
+               time(&rawtime);
+               const auto timeinfo = localtime(&rawtime);
+               strftime(buffer.data(), sizeof(buffer), "%Y%m%d_%H%M%S", timeinfo);
+               save_file = std::string(buffer.data()) + "_std_save";
+       }
+       else{
+               save_file=vm["save-file"].as<std::string>();
+       }
+
+       if(vm.count("save")){
+               for(auto& save_options : vm["save"].as<std::vector<std::string>>()){
+                       if(save_options=="0"){
+                               save_base(NULL,save_file,1);
+                               save_graphs(NULL,save_file);
+                       }
+                       else{
+                               save_base(
+                                       dirichlist.at(
+                                               std::stoi(
+                                                       save_options.substr(save_options.find("0x")!=std::string::npos ? 
+                                                               save_options.find("0x")+2 : 0),
+                                                       NULL,
+                                                       16
+                                               )
+                                       ),
+                                       save_file,
+                                       1
+                               );
+                               save_graphs(
+                                       dirichlist.at(
+                                               std::stoi(
+                                                       save_options.substr(save_options.find("0x")!=std::string::npos ? 
+                                                               save_options.find("0x")+2 : 0),
+                                                       NULL,
+                                                       16
+                                                       )
+                                               ),
+                                       save_file
+                               );
+                       }
+               }
+       }
+
+       std::string rate_file = save_file + "_rate.dat";
+       if(vm.count("measure-rate")){
+               if(vm["measure-rate"].empty() || (vm["measure-rate"].as<std::vector<std::string>>()).size() < 2){
+                       std::cout 
+                               << "no or less than two arguments were provided for option --measure-rate:\nno thresholds will be set" 
+                               << std::endl;
+               }
+               else{
+                       std::vector<std::vector<std::string>> each_measure_rate_options;
+                       std::vector<std::string> temp_vec;
+                       for(auto& measure_rate_options : vm["measure-rate"].as<std::vector<std::string>>()){
+                               if(measure_rate_options.find("0x")!=std::string::npos || measure_rate_options=="0"){
+                                       if(temp_vec.size()==2){
+                                               each_measure_rate_options.push_back(temp_vec);
+                                       }
+                                       temp_vec.clear();
+                               }
+                               temp_vec.push_back(measure_rate_options);
+                       }
+                       if(temp_vec.size()==2){
+                               each_measure_rate_options.push_back(temp_vec);
+                       }        
+                       for(auto& one_measure_rate_options : each_measure_rate_options){
+                               std::cout << "Measuring rate of: "
+                                                                       << std::stoi(
+                                                                               one_measure_rate_options.at(0).substr(one_measure_rate_options.at(0).find("0x")!=std::string::npos ? 
+                                                                                       one_measure_rate_options.at(0).find("0x")+2 : 0),
+                                                                               NULL,
+                                                                               16
+                                                                       ) << "\t"
+                                                                       << " over: "
+                                                                       << std::stod(one_measure_rate_options.at(1))
+                                                                       << " seconds" << std::endl;
+                               measure_rate(
+                                       one_measure_rate_options.at(0) == "0" ? 
+                                       0 : dirichlist.at(
+                                               std::stoi(
+                                                       one_measure_rate_options.at(0).substr(one_measure_rate_options.at(0).find("0x")!=std::string::npos ? 
+                                                               one_measure_rate_options.at(0).find("0x")+2 : 0),
+                                                       NULL,
+                                                       16
+                                               )
+                                       ),
+                                       rate_file,
+                                       std::stod(one_measure_rate_options.at(1))
+                               );
+                       }
+               }
+       }
+
+       std::string str = save_file + "_all_canvases.pdf";
+       uint counter=0;
+       for(auto& canvases : canvasvector){
+               if(counter==0 && canvasvector.size()>1) canvases->Print(Form("%s(",str.c_str()));
+               else if(counter==canvasvector.size()-1) canvases->Print(Form("%s)",str.c_str()));
+               else canvases->Print(str.c_str());
+               counter++;
+       }
+
+       usleep(100000);
+       gcheck_thresholds_mutex.lock();
+       gcheck_thresholds = 0;
+       gcheck_thresholds_mutex.unlock();       
+       threshold_checker->join();
+
+       return 0;
+}
diff --git a/thresholds/trb_dirich_threshold/HADESthreshscan_v1.o b/thresholds/trb_dirich_threshold/HADESthreshscan_v1.o
new file mode 100644 (file)
index 0000000..b714f38
Binary files /dev/null and b/thresholds/trb_dirich_threshold/HADESthreshscan_v1.o differ
diff --git a/thresholds/trb_dirich_threshold/Makefile b/thresholds/trb_dirich_threshold/Makefile
new file mode 100644 (file)
index 0000000..3ec61e9
--- /dev/null
@@ -0,0 +1,39 @@
+# Makefile for compiling the HADESthreshscan
+
+VERSION = v1
+TRBNETDIR = /home/hadaq/trbsoft/trbnettools/
+ROOTDIR = $(ROOTSYS)
+BOOSTDIR = /usr
+
+# Use this compiler
+CC = g++
+
+# Includes
+TRBNETINCDIR = -I$(TRBNETDIR)/include
+ROOTINCDIR = -I$(ROOTDIR)/include
+BOOSTINCDIR = -I$(BOOSTDIR)/include
+
+INCLUDEDIRS = $(TRBNETINCDIR) $(ROOTINCDIR) $(BOOSTINCDIR)
+
+# Libraries
+TRBNETLIBDIR = -L$(TRBNETDIR)/trbnetd
+TRBNETLIB = -ltrbnet
+ROOTLIBDIR = -L$(ROOTDIR)/lib
+ROOTLIB = -lCore  -lRIO -lNet -lHist -lGraf -lGraf3d -lGpad -lTree -lRint -lPostscript -lMatrix -lPhysics -lMathCore -lThread -pthread -lm -ldl -lGui
+BOOSTLIBDIR =  -L$(BOOSTDIR)/lib
+BOOSTLIB =  -lboost_program_options -lboost_filesystem -lboost_system
+
+LIBS = $(TRBNETLIB) $(ROOTLIB) $(BOOSTLIB)
+LIBDIRS = $(TRBNETLIBDIR) $(ROOTLIBDIR) $(BOOSTLIBDIR)
+
+# Options
+OPT = -c -Wall -Wextra -pedantic -O3 -std=c++11
+
+# Make rules
+HADESthreshscan_$(VERSION): HADESthreshscan_$(VERSION).o
+       $(CC) -o HADESthreshscan_$(VERSION) HADESthreshscan_$(VERSION).o $(LIBDIRS) $(LIBS)
+       $(shell echo 'export LD_LIBRARY_PATH=$(ROOTDIR)/lib:$(TRBNETDIR)/lib:$(BOOSTDIR)/lib:"$$LD_LIBRARY_PATH"' > setLD)
+clean:
+       /bin/rm -f *.o HADESthreshscan_$(VERSION) setLD
+.C.o:  $*.C
+       $(CC) $*.C $(INCLUDEDIRS) $(OPT)
diff --git a/thresholds/trb_dirich_threshold/README.md b/thresholds/trb_dirich_threshold/README.md
new file mode 100644 (file)
index 0000000..73f4c9b
--- /dev/null
@@ -0,0 +1,27 @@
+# trb_dirich_threshold
+Program to set DiRICH thresholds at the HADES RICH
+
+To compile the HADESthreshscan you need a version of ROOT (tested with >5.34), trbnet and boost-libraries.
+The ROOT, boost and trbnet libraries should be filled in the Makefile: TRBNETDIR, ROOTDIR, BOOSTDIR.
+The current setting of all of these varibles forsees a compilation on lxhadeb06 as hadaq.
+
+Before using the program you need to set the correct LD_LIBRARY_PATH via ". setLD"
+
+The usage of the program can be seen by using the --help /-h command
+Examples of standard tasks are:
+
+./HADESthreshscan_v1 -b 0 -t 0 50
+./HADESthreshscan_v1 -l 0 -t 0 50
+./HADESthreshscan_v1 -f path/to/threshold.thr -l 0 -t 0 50
+The -b/--baseline-scan performs a standard baselinescan. 
+The option-parameter specifies which DiRICHes shall be scanned.
+Here 0 specifies, that all DiRICHes shall be scanned.
+
+The -t/--set-threshold sets the thresholds to a certain mV threshold above threshold. 
+Here the first option-parameter (here 0) specifies the thresholds of which DiRICHes should be set (here 0 equals all DiRICHes). 
+The second parameter equals the threshold to set in mV above threshold.
+
+The -l/--load-baseline loads the baselines from a file which can be specified by the -f/--loading-file. 
+If no file is specified the latest produced *.thr-file in the same directory is used. 
+The option again defines which DiRICHes shall load baselines. 
+Here 0 lets all DiRIChes load baselines if they exist in the specified file.
diff --git a/thresholds/trb_dirich_threshold/dirich_v13.C b/thresholds/trb_dirich_threshold/dirich_v13.C
new file mode 100644 (file)
index 0000000..2ece5d3
--- /dev/null
@@ -0,0 +1,1433 @@
+#include "trbnetcom.h"
+#include "stdint.h"
+#include "unistd.h"
+#include <iostream>
+#include <vector>
+#include "TGraph.h"
+#include "TGraphErrors.h"
+#include <chrono>
+#include <array>
+#include <iomanip>
+#include <random>
+#include <math.h>
+#include <thread>
+#include <mutex>
+
+//**************************************
+//dirich handling routines
+//**************************************
+// Channel Numbers:
+// 0-31: TDC input ichannels (same index as for threshold setting)
+
+#ifndef MB4
+       // const size_t BUFFER_SIZE4mb = 4194304;       /* 4MByte */
+       const size_t BUFFER_SIZE4mb = 1048576;  // 1MByte holds space for 260k DiRICHes (UID-request)
+       static uint32_t buffer4mb[BUFFER_SIZE4mb];
+       #define MB4
+#endif
+
+static std::mt19937_64 rnd;
+
+#ifndef NCH
+       const int NRCHANNELS = 32;                       //Nr of TDC ichannels in dirich
+       const int CHPCHAIN = 16;                         //Nr of TDC ichannels pre dirich-chain
+       #define NCH
+#endif
+
+#ifndef THC
+       const int OFFTHRESH_high = 65535; //Value to switch off ichannel
+       const int OFFTHRESH_low = 1; //Value to switch off ichannel
+       const int THRESHDELAY = 100000; //Delay [mus] for thresh change to succeed
+       const int SPICOMDELAY = 30000; //Delay [mus] for std SPI request to be completed
+       #define THC
+#endif
+
+#ifndef REFV
+       const double REF_VOLT = 2500.;
+       #define REFV
+#endif
+
+const bool self_check_threshold = false;
+const uint16_t MAXTHROFFSET = 5; //Maximal difference between wanted and set threshold
+
+std::mutex GetRateMutex;
+
+class dirich 
+{
+
+private:
+// public:
+       uint16_t gBoardAddress; //Board gBoardAddress
+       uint64_t gBoardUID;     //UID of Board
+
+       std::array<uint16_t,NRCHANNELS> fbaseline;
+       std::array<uint16_t,NRCHANNELS> fbaseline_old;
+       std::array<uint16_t,NRCHANNELS> fnoisewidth;
+       std::array<uint16_t,NRCHANNELS> fnoisewidth_old;
+       std::array<double,NRCHANNELS> fthresholdmV;
+       std::array<int,NRCHANNELS> forientation;
+
+       inline int ReadSingleThreshold(uint8_t ichannel, uint16_t &thrvalue);
+       inline int ReadThresholds(std::array<uint16_t,NRCHANNELS>& thrarray);
+       inline int WriteSingleThreshold(uint8_t ichannel, uint16_t thrvalue, bool check, int nof_checks);
+       inline int WriteThresholds(std::array<uint16_t,NRCHANNELS> thrarray, bool check, int nof_checks);
+       inline int WriteThresholds(uint16_t thrvalue, bool check, int nof_checks);
+       inline int ReadSingleScaler(
+               uint8_t ichannel, 
+               uint32_t &scalervalue, 
+               std::chrono::system_clock::time_point& access_time
+       );
+       inline int ReadScalers(uint32_t* scalervalues, std::chrono::system_clock::time_point& access_time);
+       // int GetRates(uint32_t* ratevalues, double delay=1);
+
+       int gdirichver;
+
+public:
+       // constructor and destructor
+       dirich();
+       dirich(uint16_t gBoardAddress);
+       virtual ~dirich();
+
+
+       // converter functions
+       static double Thr_DtomV(uint32_t value) {return (double)value *REF_VOLT / 65536; }
+       static uint32_t Thr_mVtoD(double value) {return value /REF_VOLT *65536+.5; }
+
+
+       // setter functions
+       //threshold
+       void SetSingleThresholdmV(uint8_t ichannel, double thrinmV);
+       void SetThresholdsmV(std::array<double,NRCHANNELS> thrarrayinmV);
+       void SetThresholdsmV(double thrinmV);
+       //baseline
+       void SetSingleBaseline(uint8_t ichannel, uint16_t baseline) {
+               if(ichannel<NRCHANNELS) 
+                       fbaseline[ichannel] = baseline; 
+               else 
+                       std::cerr << "Channel: " << ichannel << " not specified" << std::endl;
+       }
+       void SetSingleBaseline_old(uint8_t ichannel, uint16_t baseline) {
+               if(ichannel<NRCHANNELS) 
+                       fbaseline_old[ichannel] = baseline; 
+               else 
+                       std::cerr << "Channel: " << ichannel << " not specified" << std::endl;
+       }
+       //noisewidth
+       void SetSingleNoisewidth(uint8_t ichannel, uint16_t noisewidth) {
+               if(ichannel<NRCHANNELS) 
+                       fnoisewidth[ichannel] = noisewidth; 
+               else 
+                       std::cerr << "Channel: " << ichannel << " not specified" << std::endl;
+       }
+       void SetSingleNoisewidth_old(uint8_t ichannel, uint16_t noisewidth) {
+               if(ichannel<NRCHANNELS) 
+                       fnoisewidth_old[ichannel] = noisewidth; 
+               else 
+                       std::cerr << "Channel: " << ichannel << " not specified" << std::endl;
+       }
+       inline int SetTDCSetting();
+       inline int SetTDCSetting(uint32_t setting);
+       inline int SetTDCSetting(std::array<uint32_t,NRCHANNELS/(CHPCHAIN*2)> setting);
+
+       // getter functions
+
+       uint16_t GetBoardAddress() {return gBoardAddress;} //board address
+       uint64_t GetBoardUID() {return gBoardUID;} //board address
+
+       double  GetSingleRate(double delay=1, uint8_t ichannel=0); //rates from scaler
+       double* GetRates(double delay=1); //rates from scaler
+
+
+       double GetSingleThresholdmV(uint8_t ichannel) {
+               if(ichannel<NRCHANNELS) 
+                       return fthresholdmV[ichannel]; 
+               else{
+                       std::cerr << "Channel: " << ichannel << " not specified" << std::endl; 
+                       return 0.;
+               }
+       }//threshold
+       std::array<double,NRCHANNELS> GetThresholdsmV() {return fthresholdmV;}
+
+       uint16_t GetSingleBaseline(uint8_t ichannel) {
+               if(ichannel<NRCHANNELS) 
+                       return fbaseline[ichannel]; 
+               else{
+                       std::cerr << "Channel: " << ichannel << " not specified" << std::endl; 
+                       return 0;
+               }
+       }//baseline
+       std::array<uint16_t,NRCHANNELS> GetBaselines() {return fbaseline;}
+
+       uint16_t GetSingleBaseline_old(uint8_t ichannel) {
+               if(ichannel<NRCHANNELS) 
+                       return fbaseline_old[ichannel]; 
+               else{
+                       std::cerr << "Channel: " << ichannel << " not specified" << std::endl; 
+                       return 0;
+               }
+       }//baseline
+       std::array<uint16_t,NRCHANNELS> GetBaselines_old() {return fbaseline_old;}
+
+       uint16_t GetSingleNoisewidth(uint8_t ichannel) {
+               if(ichannel<NRCHANNELS) 
+                       return fnoisewidth[ichannel]; 
+               else{
+                       std::cerr << "Channel: " << ichannel << " not specified" << std::endl; 
+                       return 0;
+               }
+       }//noisewidth
+       std::array<uint16_t,NRCHANNELS> GetNoisewidths() {return fnoisewidth;}
+
+       uint16_t GetSingleNoisewidth_old(uint8_t ichannel) {
+               if(ichannel<NRCHANNELS) return fnoisewidth_old[ichannel]; 
+               else{
+                       std::cerr << "Channel: " << ichannel << " not specified" << std::endl; 
+                       return 0;
+               }
+       }//noisewidth
+       std::array<uint16_t,NRCHANNELS> GetNoisewidths_old() {return fnoisewidth_old;}
+       int GetTDCSetting();
+
+       // threshold functions
+       void DoBaselineScan     ( );
+       void DoBaselineScan     ( 
+               uint32_t SearchedNoise, 
+               uint16_t MaxStepSize, 
+               double MeasureTime, 
+               int NrPasses
+       );
+       void AnalyzeBaseline ( );
+       void AnalyzeBaseline ( uint32_t NoiseThreshold);
+       void DoThreshScan       ( );
+       void DoThreshScan       ( 
+               uint8_t FirstChannel, 
+               uint8_t LastChannel, 
+               std::array<uint16_t,NRCHANNELS> FromThr, 
+               std::array<uint16_t,NRCHANNELS> ToThr, 
+               double MeasureTime, 
+               uint16_t StepSize, 
+               int NrPasses, 
+               int clear_graph
+       );
+       void DoFineThreshScan ( );
+       void DoThreshSearch     ( );
+       void DoThreshSearch     ( 
+               double Perc, 
+               bool SPP_SPV /*1==SPP*/, 
+               double MeasureTime, 
+               int16_t StepSize, 
+               int NrPasses
+       );
+       void DoThreshScanOverBase ( );
+       void DoThreshScanOverBase ( 
+               uint8_t FirstChannel, 
+               uint8_t LastChannel, 
+               std::array<double,NRCHANNELS> ToThrmV, 
+               double MeasureTime, 
+               double StepSize, 
+               int NrPasses
+       );
+       void MakeGraphsOverBase ( );
+       void MakeDiffGraphsOverBase ( );
+       void MakeDiffGraphsOverBase (int case_type);
+       // void MakeDiffGraphsOverBase ( uint16_t FromThr, uint16_t ToThr);
+       void FindMinThreshScanOverBase(double gThreshold_finding_method);
+
+       int WhichDirichVersion (){return gdirichver;}
+
+       // threshold visualization items
+       std::array<TGraphErrors*,NRCHANNELS> gRateGraphs;
+       std::array<TGraphErrors*,NRCHANNELS> gRateGraphsOverBase;
+       std::array<TGraph*,NRCHANNELS> gDiffRateGraphsOverBase;
+       // void ClearGraphs();
+
+
+       // settings for threshold measurement
+       double gMeasureTime;                                                                                            //Time [s] to determine rate
+       std::array<uint16_t,NRCHANNELS> gLowerEdge;                     //start of thresholdscan
+       std::array<uint16_t,NRCHANNELS> gUpperEdge;                     //end of thresholdscan
+       int gStepsize;                                                                                                                  //stepsize fr thresholdscan
+       int gNrPasses;                                                                                                                  //Nr of passes to scan all ichannels
+
+       double   gMeasureTime_over; //Time [s] to determine rate
+       int gLowerEdge_over;    //end of thresholdscan over baseline
+       int gUpperEdge_over;    //end of thresholdscan over baseline
+       int gStepsize_over;             //stepsize for thresholdscan
+       int gNrPasses_over;             //Nr of passes to scan all ichannels
+
+       double   gThreshold_finding_method; //Method to find perfect threshold: 
+                                                                                                                                                       //0: searches for the minimum in the differentiated spectrum or for the minimal gradient 
+                                                                                                                                                       //0<value<5: tries to find peak and sigma of the single photon distribution and sets the threshold to value*sigma
+                                                                                                                                                       //5<value<100: tries to find the single photon peak and sets the threshold to value% of the spp-position
+       int gdirich_reporting_level = 0;
+
+       bool gTDC_read = false;
+       std::array<uint32_t,NRCHANNELS/(CHPCHAIN*2)> gTDC_setting{{0x0}};
+
+       std::array<uint16_t,NRCHANNELS> gCurrent_Threshold;
+       std::mutex Current_Thr_Mutex;
+       std::chrono::steady_clock::time_point gCurrent_Threshold_time;
+
+};
+
+
+dirich::dirich()
+{
+       dirich(0);
+}
+
+dirich::dirich(uint16_t BoardAddress)
+       {
+
+       int ret=0;
+       for(int tries=0;tries<100;++tries){
+               ret=Ttrb_read_uid(BoardAddress, buffer4mb, BUFFER_SIZE4mb);
+               if(ret!=4) continue;
+               if(buffer4mb[0]==0 || buffer4mb[1]==0 || buffer4mb[3] ==0) continue;
+               else break;
+       }
+       if(ret<=0){
+               std::cerr 
+                       << "No DiRICH found with Address:" 
+                       << std::hex << BoardAddress 
+                       << "\nNot adding DiRICH" 
+                       << std::endl;
+               return;
+       }
+       else if(ret!=4){
+               std::cerr 
+                       << "Too many DiRICH found with Address:" 
+                       << std::hex << BoardAddress 
+                       << "(Amount: "<< ret/4 << ")\nNot adding DiRICH" 
+                       << std::endl;
+               return;
+       }
+       else{
+               gBoardAddress = buffer4mb[3];
+               uint64_t temp_store = buffer4mb[0];
+               uint64_t temp_store2 = buffer4mb[1];
+               gBoardUID = temp_store << 32 | temp_store2;
+       }
+
+       uint32_t cmd = 0x0 | 0xff << 24;
+       uint32_t c[] = {cmd,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0x10001};
+
+       std::array<uint32_t,CHPCHAIN+2> ret_c;
+       ret=0;
+       for(int failed=0;failed<100;++failed){
+               // std::cout << gBoardAddress << " " << failed << std::endl;
+               ret=Ttrb_register_write_mem(gBoardAddress,0xd400,0,c,CHPCHAIN+2);
+               if(ret<0) return;
+               std::this_thread::sleep_for(std::chrono::microseconds(SPICOMDELAY));
+               ret=Ttrb_register_read(gBoardAddress,0xd412,ret_c.data(),2);
+               if(ret<0) return;
+               if(ret==2 && (ret_c.at(1) & 0xff00) == 0x100) break;
+               //check if correct version (for dirich 0x100) is on the side FPGA
+       }
+       if(ret!=2 || (ret_c.at(1) & 0xff00) != 0x100){
+                       std::cerr 
+                       << "No DiRICH2 Threshold FPGA of newest version detected (Version:0x" 
+                       << std::hex << (ret_c.at(1) & 0xff00) 
+                       << ")\nNot adding DiRICH" << std::dec << std::endl;
+               return;
+       }
+       else{
+               gdirichver = 3;
+       }
+
+       // gBoardAddress=BoardAddress;
+       gdirich_reporting_level=0;
+       gMeasureTime=.3;
+       gLowerEdge.fill(28000);
+       gUpperEdge.fill(32000);
+       gStepsize=75;
+       // gStepsize=25;
+       gNrPasses=1;
+       gMeasureTime_over=30.;
+       gLowerEdge_over=0;
+       gUpperEdge_over=600;
+       gStepsize_over=10;
+       gNrPasses_over=1;
+       gThreshold_finding_method=0;
+       for (int ichannel=0; ichannel<NRCHANNELS; ichannel++) {
+               gRateGraphs.at(ichannel)=new TGraphErrors();
+               gRateGraphs.at(ichannel)->SetTitle(
+                       Form(
+                               "Rate graph of dirich 0x%x's ichannel %i;Threshold;Rate",
+                               gBoardAddress,
+                               ichannel
+                       )
+               );
+               gRateGraphs.at(ichannel)->SetName(
+                       Form(
+                               "Rate graph of dirich 0x%x's ichannel %i",
+                               gBoardAddress,
+                               ichannel
+                       )
+               );
+
+               gRateGraphsOverBase.at(ichannel)=new TGraphErrors();
+               gRateGraphsOverBase.at(ichannel)->SetTitle(
+                       Form(
+
+                       
+                               "Rate graph over baseline of dirich 0x%x's ichannel %i;Threshold in mV;Rate",
+                               gBoardAddress,
+                               ichannel
+                       )
+               );
+               gRateGraphsOverBase.at(ichannel)->SetName(
+                       Form(
+                               "Rate graph over baseline of dirich 0x%x's ichannel %i",
+                               gBoardAddress,
+                               ichannel
+                       )
+               );
+
+               gDiffRateGraphsOverBase.at(ichannel)=new TGraph();
+               gDiffRateGraphsOverBase.at(ichannel)->SetTitle(
+                       Form(
+                               "Differentiated rate graph over baseline of dirich 0x%x's ichannel %i;"
+                               "Threshold in mV;Differentiated rate",
+                               gBoardAddress,
+                               ichannel
+                       )
+               );
+               gDiffRateGraphsOverBase.at(ichannel)->SetName(
+                       Form(
+                               "Differentiated rate graph over baseline of dirich 0x%x's ichannel %i",
+                               gBoardAddress,
+                               ichannel
+                       )
+               );
+
+               fbaseline.at(ichannel) = 0;
+               fbaseline_old.at(ichannel) = 0;
+               fnoisewidth.at(ichannel) = 0;
+               fnoisewidth_old.at(ichannel) = 0;
+               fthresholdmV.at(ichannel) = 0.;
+               forientation.at(ichannel) = 
+               ichannel%2==0 ?
+               1 : 1; //to cope with different polarities in PADIWA
+       }
+       return;
+}
+
+dirich::~dirich()
+{
+       for (int ichannel=0; ichannel<NRCHANNELS; ichannel++) {
+               if(gRateGraphs.at(ichannel)) delete gRateGraphs.at(ichannel);
+               if(gDiffRateGraphsOverBase.at(ichannel)) delete gDiffRateGraphsOverBase.at(ichannel);
+       }
+}
+
+int dirich::ReadSingleThreshold(uint8_t ichannel, uint16_t& thrvalue)
+{
+       if(self_check_threshold){
+               if (ichannel>NRCHANNELS-1)
+                       return -1;
+               int ret;
+               int reg=0;
+               uint8_t real_ichannel=0;
+               if(gdirichver==0){
+                       reg=0xa000+31-ichannel; //old firwmare
+               }
+               if(gdirichver==1){
+                       reg=0xa000+ichannel; //new firwmare 
+               }
+               if(gdirichver==2){
+                       real_ichannel = ichannel%CHPCHAIN+CHPCHAIN;
+               }
+               if(gdirichver==3){
+                       real_ichannel = ichannel%CHPCHAIN;
+               }
+               if(gdirichver<=1){
+                       uint32_t buffer[2];
+                       ret=Ttrb_register_read(gBoardAddress,reg, buffer, 2);
+
+                       if((gBoardAddress != buffer[0]) || (ret != 2)) return -1;
+
+                       thrvalue=(buffer[1] & 0xffff); 
+                       return 0;
+               }       
+               else{
+                       uint32_t cmd = 0x0 << 20 | real_ichannel << 24 | thrvalue << 0;
+                       //evtl. sind auch mehrere Kanäle auf einmal lesbar.
+                       uint32_t c[] = {cmd,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,(uint32_t)ichannel/CHPCHAIN+1,0x10001}; 
+                       ret=Ttrb_register_write_mem(gBoardAddress,0xd400,0,c,CHPCHAIN+2);
+                       std::this_thread::sleep_for(std::chrono::microseconds(SPICOMDELAY));
+                       uint32_t ret_c[2];
+                       ret=Ttrb_register_read(gBoardAddress,0xd412,ret_c,2);
+                       if((gBoardAddress != ret_c[0]) || (ret != 2)) return -1;
+                       thrvalue=(ret_c[1] & 0xffff);
+                       if(gdirich_reporting_level>3)
+                               std::cout 
+                                       << std::hex << gBoardAddress 
+                                       << " " << std::dec << (int)ichannel 
+                                       << " " << (int)real_ichannel << std::hex 
+                                       << " " << ret_c[0] 
+                                       << " " << ret_c[1] 
+                                       << " " << thrvalue 
+                                       << std::endl;
+                       return 0;
+               }
+       }
+       else{
+               auto temp_set_time = std::chrono::steady_clock::now();
+               while(true){
+                       Current_Thr_Mutex.lock();
+                       if(gCurrent_Threshold_time>temp_set_time) 
+                               break;
+                       Current_Thr_Mutex.unlock();
+                       std::this_thread::sleep_for(std::chrono::microseconds(2*SPICOMDELAY));
+               }               
+               // std::this_thread::sleep_until(
+               //      gCurrent_Threshold_time
+               //      +std::chrono::microseconds((NRCHANNELS+1)*SPICOMDELAY)
+               // );
+               thrvalue = gCurrent_Threshold.at(ichannel);
+               Current_Thr_Mutex.unlock();
+               return 0;
+       }
+}
+
+int dirich::ReadThresholds(std::array<uint16_t,NRCHANNELS>& thrarray){
+       int ret=0;
+       if(self_check_threshold){
+               for(uint8_t ichannel=0;ichannel<NRCHANNELS;++ichannel){
+                       ret=ReadSingleThreshold(ichannel,thrarray.at(ichannel));
+                       // std::cout << std::hex << thrarray.at(ichannel) << std::endl;
+                       if(ret<0) return ret;
+               }
+               return ret;
+       }
+       else{
+               auto temp_set_time = std::chrono::steady_clock::now();
+               while(true){
+                       Current_Thr_Mutex.lock();
+                       if(gCurrent_Threshold_time>temp_set_time) 
+                               break;
+                       Current_Thr_Mutex.unlock();
+                       std::this_thread::sleep_for(std::chrono::microseconds(2*SPICOMDELAY));
+                       // std::cout << "NOPE" << std::endl;
+               }               
+               // std::this_thread::sleep_until(
+               //      gCurrent_Threshold_time
+               //      +std::chrono::microseconds((NRCHANNELS+1)*SPICOMDELAY)
+               // );           
+               thrarray = gCurrent_Threshold;
+               Current_Thr_Mutex.unlock();
+               return 0;
+       }
+}
+
+int dirich::WriteSingleThreshold(uint8_t ichannel, uint16_t thrvalue, bool check, int nof_checks)
+{
+       if (ichannel>NRCHANNELS-1)
+               return -1;
+       int ret=0;
+
+       if(gdirichver==1){
+//      int reg=0xa000+31-ichannel; old firwmare
+               int reg=0xa000+ichannel; //new firwmare 
+               ret=Ttrb_register_write(gBoardAddress, reg, (uint32_t)thrvalue);
+               return ret;
+       }
+       else{
+               uint8_t real_ichannel = ichannel%CHPCHAIN+CHPCHAIN*abs(gdirichver-3);
+               uint32_t cmd = 0x8 << 20 | real_ichannel << 24 | thrvalue <<0;
+               std::array<uint32_t,CHPCHAIN+2> c = {{
+                       cmd,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+                       (uint32_t)( 1 << ((int)ichannel/CHPCHAIN)),
+                       0x00001 | ((unsigned int)check) << 16
+               }};
+               ret=Ttrb_register_write_mem(gBoardAddress,0xd400,0,c.data(),CHPCHAIN+2);
+               if(ret==-1) return ret;
+               std::this_thread::sleep_for(std::chrono::microseconds(THRESHDELAY));            
+               if(check){
+                       uint32_t temp[18];
+                       ret=Ttrb_register_read(gBoardAddress,0xd412, temp,18);
+                       if(ret==-1) return ret;
+               }
+               int failed=0;
+               for(failed=0;failed<nof_checks;++failed){
+                       uint16_t set_threshold;
+                       ret=ReadSingleThreshold(ichannel, set_threshold);
+                       if(ret==-1) break;
+                       if(gdirich_reporting_level>3) 
+                               std::cout 
+                                       << "wanted " << thrvalue 
+                                       << " set " << set_threshold 
+                               << std::endl;
+                       if(abs(set_threshold-thrvalue) < MAXTHROFFSET) break;
+                       else{
+                               if(gdirich_reporting_level>2) 
+                               std::cout 
+                                       << "Thresholds not matching: wanted " << thrvalue 
+                                       << " set " << set_threshold 
+                               << std::endl;
+                       }
+                       ret=Ttrb_register_write_mem(gBoardAddress,0xd400,0,c.data(),CHPCHAIN+2);
+                       if(ret==-1) break;
+                       std::this_thread::sleep_for(std::chrono::microseconds(THRESHDELAY));
+                       if(check){
+                               uint32_t temp[18];
+                               ret=Ttrb_register_read(gBoardAddress,0xd412, temp,18);
+                               if(ret==-1) break;
+                       }
+               }
+               if(failed==nof_checks-1) return -1;
+               else return ret;
+       }
+}
+
+int dirich::WriteThresholds(std::array<uint16_t,NRCHANNELS> thrarray, bool check, int nof_checks)
+{
+       int ret;
+       std::array<std::array<uint32_t,CHPCHAIN+2>,NRCHANNELS/CHPCHAIN> cmd;
+       if(gdirichver==1){
+               uint16_t reg=0xa000+32-NRCHANNELS;
+               uint32_t buffer[NRCHANNELS];
+               for (int i=0;i<NRCHANNELS;i++) {
+                       buffer[i]=thrarray[NRCHANNELS-i-1];
+               }
+               ret=Ttrb_register_write_mem(gBoardAddress,reg,0,buffer,NRCHANNELS);
+               return ret;
+       }
+       else{
+               std::array<uint,NRCHANNELS/CHPCHAIN> counter;
+               counter.fill(0);
+               for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+                       if(thrarray.at(ichannel)){
+                               uint8_t real_channel = ichannel%CHPCHAIN+CHPCHAIN*abs(gdirichver-3);
+                               cmd.at(ichannel/CHPCHAIN).at(counter.at(ichannel/CHPCHAIN)) = 
+                                       0x8 << 20 | real_channel << 24 | thrarray.at(ichannel) << 0;
+                               counter.at(ichannel/CHPCHAIN)++;
+                       }
+               }
+               int failed=0;
+               for(int ichain=0;ichain<NRCHANNELS/CHPCHAIN;++ichain){
+                       cmd.at(ichain).at(CHPCHAIN)= 1 << ichain;
+                       cmd.at(ichain).at(CHPCHAIN+1)=0x00000 | counter.at(ichain) | ((int)check) << 16; 
+                       ret=Ttrb_register_write_mem(gBoardAddress,0xd400,0,cmd.at(ichain).data(),CHPCHAIN+2);
+                       if(ret==-1) break;
+                       std::this_thread::sleep_for(std::chrono::microseconds(THRESHDELAY));            
+                       if(check){
+                               uint32_t temp[18];
+                               ret=Ttrb_register_read(gBoardAddress,0xd412, temp,18);
+                               if(ret==-1) break;
+                       }
+                       for(;failed<nof_checks;++failed){
+                               std::array<uint16_t, NRCHANNELS> set_thresholds;
+                               ret=ReadThresholds(set_thresholds);
+                               if(ret==-1) break;
+                               int equal_it=0;
+                               for(int ichannel=0;ichannel<CHPCHAIN;++ichannel){
+                                       if(gdirich_reporting_level>3){
+                                               std::cout 
+                                                       << thrarray.at(ichannel+CHPCHAIN*ichain) << "/"
+                                                       << set_thresholds.at(ichannel) << "\t";
+                                       }
+                                       if(
+                                               thrarray.at(ichannel+CHPCHAIN*ichain)==0 
+                                               || abs(
+                                                       thrarray.at(ichannel+CHPCHAIN*ichain)
+                                                       -set_thresholds.at(ichannel+CHPCHAIN*ichain)
+                                                       )<MAXTHROFFSET
+                                               ){
+                                               equal_it++;
+                                       }
+                                       else if(gdirich_reporting_level>2){
+                                               std::cout 
+                                                       << "Threshold not equal at channel " 
+                                                       << ichannel << " "
+                                                       << CHPCHAIN*ichain << " "
+                                                       << thrarray.at(ichannel+CHPCHAIN*ichain) << "/"
+                                                       << set_thresholds.at(ichannel+CHPCHAIN*ichain) << std::endl;
+                                       }
+                               }
+                               if(gdirich_reporting_level>2) 
+                                       std::cout << std::endl;
+                               if(equal_it==CHPCHAIN) break;
+                               ret=Ttrb_register_write_mem(gBoardAddress,0xd400,0,cmd.at(ichain).data(),CHPCHAIN+2);
+                               if(ret==-1) break;
+                               std::this_thread::sleep_for(std::chrono::microseconds(THRESHDELAY));
+                               if(check){
+                                       uint32_t temp[18];
+                                       ret=Ttrb_register_read(gBoardAddress,0xd412, temp,18);
+                                       if(ret==-1) break;
+                               }
+                       }
+               }
+               if(failed==nof_checks-1) return -1;
+               else return ret;
+       }
+}
+
+int dirich::WriteThresholds(uint16_t thrvalue, bool check, int nof_checks)
+{
+       int ret;
+       std::array<uint16_t,NRCHANNELS> thrarray;
+       thrarray.fill(thrvalue);
+       ret=WriteThresholds(thrarray, check, nof_checks);
+       return ret;
+}
+
+void dirich::SetSingleThresholdmV(uint8_t ichannel ,double thrinmV=30.)
+{
+       if(ichannel>=NRCHANNELS){
+               std::cerr << "Channel: " << std::dec << ichannel << " not specified" << std::endl;
+               return;
+       }
+       int baseline=fbaseline[ichannel];
+       if(baseline==0){
+               std::cerr 
+                       << "dirich 0x" 
+                       << std::hex << gBoardAddress 
+                       << "'s ichannel: " << std::dec << unsigned(ichannel) 
+                       << " has no baseline! (baseline==0)" 
+                       << std::endl;
+               return;
+       } 
+       int newthreshold = thrinmV==0 ? 0 : baseline+forientation.at(ichannel)+Thr_mVtoD(thrinmV);
+
+       int ret=WriteSingleThreshold(ichannel, newthreshold, true, 100);
+       if(ret<0){
+                       std::cerr 
+                       << "dirich 0x" << std::hex << gBoardAddress 
+                       << "'s setting Thresholds failed" 
+                       << std::endl;
+       } 
+       fthresholdmV.at(ichannel) = thrinmV;
+
+}
+
+void dirich::SetThresholdsmV(std::array<double,NRCHANNELS> thrarrayinmV)
+{
+       std::array<uint16_t,NRCHANNELS> thrarrayD;
+       for(int ichannel=0; ichannel<NRCHANNELS;++ichannel){
+               if(fbaseline.at(ichannel)==0){
+                       std::cerr 
+                       << "dirich 0x" << std::hex << gBoardAddress 
+                       << "'s ichannel: " << std::dec << unsigned(ichannel) 
+                       << " has no baseline! (baseline==0)" 
+                       << std::endl;
+                       thrarrayD.at(ichannel)=0;
+               }
+               else{
+                       if(thrarrayinmV.at(ichannel)!=0)
+                               thrarrayD.at(ichannel) = 
+                                       forientation.at(ichannel)
+                                               *Thr_mVtoD(thrarrayinmV.at(ichannel))
+                                       +fbaseline.at(ichannel);
+                       else 
+                               thrarrayD.at(ichannel) = 0;
+               }
+       }
+       int ret=0;
+       ret=WriteThresholds(thrarrayD, true, 100);
+       if(ret<0){
+        std::cerr 
+               << "dirich 0x" << std::hex << gBoardAddress 
+               << "'s setting Thresholds failed" 
+               << std::endl;
+        return;
+       }       
+       fthresholdmV = thrarrayinmV;
+}
+
+
+void dirich::SetThresholdsmV(double thrinmV=30.)
+{
+       std::array<double,NRCHANNELS> thrarray;
+       thrarray.fill(thrinmV);
+       SetThresholdsmV(thrarray);
+}
+
+int dirich::SetTDCSetting(){
+       if(gTDC_read==false){
+               std::cerr << "no setting for TDC saved" << std::endl;
+               return -1;
+       }
+       else{
+               return SetTDCSetting(gTDC_setting);
+       }
+}
+int dirich::SetTDCSetting(uint32_t setting){
+       std::array<uint32_t,NRCHANNELS/(2*CHPCHAIN)> temp_arr;
+       temp_arr.fill(setting);
+       return SetTDCSetting(temp_arr);
+}
+int dirich::SetTDCSetting(std::array<uint32_t,NRCHANNELS/(2*CHPCHAIN)> setting){
+       int ret = 0;
+       for(int i=0;i<NRCHANNELS/(2*CHPCHAIN);++i){
+               ret=Ttrb_register_write(gBoardAddress, 0xc802+i, setting.at(i)); //switch off TDC
+               if(ret==-1){
+                       std::cerr 
+                               << "Setting TDCs status failed for dirich " 
+                               << std::hex << gBoardAddress << std::dec 
+                               << std::endl;
+                       return -1;
+               }
+       }
+       return ret;
+}
+
+int dirich::ReadSingleScaler(
+       uint8_t ichannel, 
+       uint32_t& scalervalue, 
+       std::chrono::system_clock::time_point& access_time
+)
+{
+       int ret=-1;
+       if (ichannel>NRCHANNELS)
+               return -1;
+       uint16_t reg=0xc000+ichannel;
+       // else reg=0xc000+ichannel;
+       uint32_t buffer[2];
+       for(int tries=0;tries<NOFCOMTRIES;++tries){
+               GetRateMutex.lock();
+               ret=Ttrb_register_read(gBoardAddress,reg, buffer, 2);
+               access_time = std::chrono::system_clock::now();
+               GetRateMutex.unlock();
+               if( ret==2 && gBoardAddress == buffer[0] ) 
+                       break;
+               std::this_thread::sleep_for(std::chrono::milliseconds(FAILDELAY));
+       }
+       if( ret==2 && gBoardAddress == buffer[0] ){
+               scalervalue=buffer[1] & 0x7fffffff;
+               return 0;
+       }
+       else
+               return -1;
+}
+
+int dirich::ReadScalers(uint32_t* scalervalues, std::chrono::system_clock::time_point& access_time)
+{
+       // std::cout << "Getting Scalers" << std::endl;
+       int ret;
+       uint16_t reg=0xc000+1;
+       uint32_t buffer[NRCHANNELS+1];
+       // for (int i=0;i<NRCHANNELS+1; i++) buffer[i]=0;
+       for(int tries=0;tries<NOFCOMTRIES;++tries){
+               // std::cout << "Getting Scalers try " << tries << std::endl;
+               GetRateMutex.lock();
+               ret=Ttrb_register_read_mem(gBoardAddress,reg,0,NRCHANNELS,buffer,NRCHANNELS+1);
+               // for(int i=0;i<ret;++i) std::cout << buffer[i] <<std::endl;
+               access_time = std::chrono::system_clock::now();
+               GetRateMutex.unlock();
+               if( ret==NRCHANNELS+1 && gBoardAddress == (buffer[0] & 0xffff) ) 
+                       break;
+               std::this_thread::sleep_for(std::chrono::milliseconds(FAILDELAY));
+       }       
+       if( (ret == NRCHANNELS+1) && gBoardAddress == (buffer[0] & 0xffff) ){
+               if(gdirich_reporting_level>=5){
+                       std::cout << "scalers:" << std::endl;
+               }
+               for (int i=0;i<NRCHANNELS;i++){
+                       scalervalues[i]=buffer[i+1] & 0x7fffffff;
+                       if(gdirich_reporting_level>=5){
+                               std::cout << std::dec <<scalervalues[i] << " ";
+                       }
+               }
+               if(gdirich_reporting_level>=5){
+                       std::cout << std::endl;
+               }
+               return 0;
+       }
+       else
+               return -1;
+}
+
+double dirich::GetSingleRate(double delay, uint8_t ichannel)
+{
+       int ret=-1;
+       uint32_t scaler1=0;
+       uint32_t scaler2=0;
+
+       std::chrono::system_clock::time_point start1;
+       ret=ReadSingleScaler(ichannel,scaler1,start1);
+       if(ret<0){
+               std::cerr << "Error reading start_scalers" << std::endl;
+               return -1;
+       }
+
+       std::this_thread::sleep_for(std::chrono::microseconds((int)(1e6*delay)));
+
+       ret=-1;
+       std::chrono::system_clock::time_point stop1;
+       ret=ReadSingleScaler(ichannel,scaler2,stop1);
+       if(ret<0){
+               std::cerr << "Error reading end_scalers" << std::endl;
+               return -2;
+       }       
+
+       double exactdelay1 =
+               1.0e-6*std::chrono::duration_cast<std::chrono::microseconds>(stop1-start1).count();
+       uint32_t scaler_diff=scaler2<scaler1?
+               (1<<31)+scaler2-scaler1 : scaler2-scaler1;
+       double rate=1.*scaler_diff/exactdelay1;
+       if(gdirich_reporting_level>=5){
+                       std::cout 
+                               << exactdelay1 << std::dec 
+                               << " " << scaler2 
+                               << " " << scaler1 
+                               << " " << scaler_diff 
+                               << " " << rate 
+                               << std::endl;
+       }       
+       return rate;
+}
+
+double* dirich::GetRates(double delay)
+{
+       // std::cout << "Getting rates" << std::endl;
+
+       int ret=-1;
+       uint32_t scaler1[NRCHANNELS];
+       uint32_t scaler2[NRCHANNELS];
+       double* ratevalues = (double*) calloc(NRCHANNELS, sizeof(double));
+
+       std::chrono::system_clock::time_point start1;
+       ret=ReadScalers(scaler1,start1);
+       if(ret<0){
+               std::cerr << "Error reading start_scalers" << std::endl;
+               for(int i=0;i<NRCHANNELS;++i)
+                       ratevalues[i] = -1;
+               return ratevalues;
+       }
+       // std::cout << "Going to sleep " << std::hex << gBoardAddress << std::endl;
+       std::this_thread::sleep_for(std::chrono::microseconds((int)(1e6*delay)));
+
+       ret=-1;
+       std::chrono::system_clock::time_point stop1;
+       ret=ReadScalers(scaler2,stop1);
+       if(ret<0){
+               std::cerr << "Error reading start_scalers" << std::endl;
+               for(int i=0;i<NRCHANNELS;++i)
+                       ratevalues[i] = -1;
+               return ratevalues;
+       }
+
+       double exactdelay1 =
+               1.0e-6*std::chrono::duration_cast<std::chrono::microseconds>(stop1-start1).count();
+       for (int i=0; i<NRCHANNELS; i++) {
+               uint64_t scaler_diff=scaler2[i]<scaler1[i]?
+                       (1<<31)+scaler2[i]-scaler1[i] : scaler2[i]-scaler1[i];
+               double rate=1.*scaler_diff/exactdelay1;
+               ratevalues[i]=rate;
+               if(gdirich_reporting_level>=4){
+                       std::cout 
+                               << exactdelay1 << std::dec 
+                               << " " << scaler2[i] 
+                               << " " << scaler1[i] 
+                               << " " << scaler_diff 
+                               << " " << rate 
+                               << std::endl;
+               }
+       }
+       // std::cout << "DONE Getting rates" << std::endl;
+       return ratevalues;
+}
+
+int dirich::GetTDCSetting(){
+       int ret = 0;
+       for(int i=0;i<NRCHANNELS/(2*CHPCHAIN);++i){
+               uint32_t temp_tdc_setting[2];
+               ret=Ttrb_register_read(gBoardAddress, 0xc802+i, temp_tdc_setting, 2); //switch off TDC
+               // std::cout << std::hex << temp_tdc_setting[0] << "\t" << temp_tdc_setting[1] << std::endl;
+               if(ret!=2 || temp_tdc_setting[0]!=gBoardAddress){
+                       std::cerr 
+                               << "Reading TDCs status failed for dirich " 
+                               << std::hex << gBoardAddress << std::dec 
+                               << " -> TDC for that dirich will be left switched off" 
+                               << std::endl;
+                       gTDC_read = false;
+                       return -1;
+               }
+               gTDC_setting.at(i) = temp_tdc_setting[1];
+               gTDC_read = true;
+       }
+       return ret;     
+       
+}
+
+void dirich::DoThreshScan(){
+       DoThreshScan(
+               0, 
+               NRCHANNELS, 
+               gLowerEdge, 
+               gUpperEdge, 
+               gMeasureTime, 
+               gStepsize, 
+               gNrPasses, 
+               1
+       );
+}
+void dirich::DoFineThreshScan(){
+       std::array<uint16_t,NRCHANNELS> gLowerEdge_array;
+       std::array<uint16_t,NRCHANNELS> gUpperEdge_array;
+       for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+               gLowerEdge_array.at(ichannel)=fbaseline.at(ichannel)-0.75*fnoisewidth.at(ichannel);
+               gUpperEdge_array.at(ichannel)=fbaseline.at(ichannel)+0.75*fnoisewidth.at(ichannel);
+       }
+       DoThreshScan(
+               0, 
+               NRCHANNELS, 
+               gLowerEdge_array, 
+               gUpperEdge_array, 
+               gMeasureTime, 
+               10, 
+               gNrPasses, 
+               0
+       );
+}
+void dirich::DoThreshScan(
+       uint8_t FirstChannel, 
+       uint8_t LastChannel, 
+       std::array<uint16_t,NRCHANNELS> FromThr, 
+       std::array<uint16_t,NRCHANNELS> ToThr, 
+       double MeasureTime, 
+       uint16_t StepSize, 
+       int NrPasses, 
+       int clear_graph
+)
+{
+       if(gdirich_reporting_level>=1){
+               std::cout 
+                       << std::dec << (int)FirstChannel 
+                       << " " << (int)LastChannel 
+                       << " " << FromThr.at(0) 
+                       << " " << ToThr.at(0) 
+                       << " " << MeasureTime 
+                       << " " << StepSize 
+                       << " " << NrPasses 
+                       << " " << clear_graph 
+                       << std::endl;
+       }
+       int ret;
+
+       if(clear_graph==1){
+               for (int ichannel=0; ichannel<NRCHANNELS; ichannel++){
+                       gRateGraphs.at(ichannel)->Set(0);
+                       gRateGraphsOverBase.at(ichannel)->Set(0);
+               }
+       }
+       
+       GetTDCSetting(); //Get TDC values
+       SetTDCSetting(0x0); //SwitchTDC off
+
+       for(int ipass=0;ipass<NrPasses;++ipass){
+               ret=WriteThresholds(OFFTHRESH_low, true, 0);
+               if(ret<0){
+                std::cerr 
+                       << "dirich 0x" 
+                       << std::hex << gBoardAddress 
+                       << "'s setting Thresholds failed" 
+                       << std::endl;
+                return;
+               }
+               int max_diff=0;
+               for(int i=0+ipass;i<NRCHANNELS;i+=NrPasses){
+                       int temp_diff = ToThr.at(i)-FromThr.at(i);
+                       max_diff = temp_diff>max_diff ? temp_diff : max_diff;
+               }
+               for (int addthresh=0; addthresh<=max_diff; addthresh+=StepSize){
+                       if(gdirich_reporting_level==1){
+                               // if((addthresh/StepSize*100)%(max_diff/StepSize)==0)
+                               std::cout 
+                               << "\r" 
+                               << std::setw(10) << std::setprecision(2) << std::fixed 
+                               << 1.*((addthresh/StepSize+ipass*max_diff/StepSize)*100)/(max_diff/StepSize*NrPasses)
+                               << "%" << std::flush;
+                       }
+                       std::array<uint16_t,NRCHANNELS> threshold_value;
+                       for (int ichannel=0; ichannel<LastChannel; ichannel++){
+                               threshold_value.at(ichannel) = 
+                               (ichannel+ipass)%NrPasses==0 ? 
+                               FromThr.at(ichannel)+addthresh : 0;
+                       }
+                       ret=WriteThresholds(threshold_value, true, 0);
+                       if(ret<0){
+                        std::cerr 
+                               << "dirich 0x" 
+                               << std::hex << gBoardAddress 
+                               << "'s setting Thresholds failed" 
+                               << std::endl;
+                        return;
+                       }
+                       double* rates;
+                       rates = GetRates(MeasureTime);
+                       for (int ichannel=0; ichannel<LastChannel; ichannel++){
+                               if(threshold_value.at(ichannel)==0) continue;
+                               gRateGraphs.at(ichannel)->SetPoint(
+                                       gRateGraphs.at(ichannel)->GetN(),
+                                       1.*threshold_value.at(ichannel),
+                                       1.*rates[ichannel]
+                               );
+                               gRateGraphs.at(ichannel)->SetPointError(
+                                       gRateGraphs.at(ichannel)->GetN()-1,
+                                       1,
+                                       sqrt(1.*rates[ichannel])/sqrt(MeasureTime)
+                               );                              
+                               if(gdirich_reporting_level>3){  
+                                       std::cout 
+                                               << 1.*threshold_value.at(ichannel) 
+                                               << " " << 1.*rates[ichannel] 
+                                               << std::endl;
+                               }
+                       }
+               }
+       }
+
+       SetTDCSetting(); //Set TDC back to original values
+
+       for (int ichannel=FirstChannel; ichannel<LastChannel; ++ichannel){
+               gRateGraphs.at(ichannel)->Sort();
+       }
+       if(gdirich_reporting_level==1){
+               std::cout << std::endl;
+       }
+}
+
+void dirich::DoThreshScanOverBase(){
+       if(std::all_of(fbaseline.cbegin(), fbaseline.cend(), [](int i){ return i==0; })){
+               std::cerr 
+                       << "dirich 0x" << std::hex << gBoardAddress 
+                       << std::dec << " has no baseline yet. Please load or scan one (load_base, system_thr_scan)" 
+                       << std::endl;
+               return;
+       }
+       std::array<double, NRCHANNELS> UpperEdge_over_array; 
+       for(auto& UpperEdge_over_array_element : UpperEdge_over_array){
+               UpperEdge_over_array_element=gUpperEdge_over;
+       }
+       DoThreshScanOverBase(
+               0, 
+               NRCHANNELS, 
+               UpperEdge_over_array, 
+               gMeasureTime_over, 
+               gStepsize_over, 
+               gNrPasses_over
+       );
+}
+void dirich::DoThreshScanOverBase(
+       uint8_t FirstChannel, 
+       uint8_t LastChannel, 
+       std::array<double,NRCHANNELS> ToThrmV, 
+       double MeasureTime, 
+       double StepSize, 
+       int NrPasses
+)
+{
+       if(gdirich_reporting_level>=1){
+               std::cout 
+                       << std::dec << (int)FirstChannel 
+                       << " " << (int)LastChannel 
+                       << " " << ToThrmV.at(0) 
+                       << " " << MeasureTime 
+                       << " " << StepSize 
+                       << " " << NrPasses 
+                       << std::endl;
+       } 
+       double gMeasureTime_over_temp=3.;
+       int gMeasures = MeasureTime/gMeasureTime_over_temp;
+       int ret;
+       
+       GetTDCSetting(); //Get TDC values
+       SetTDCSetting(0x0); //SwitchTDC off
+
+       for(int ipass=0;ipass<NrPasses;++ipass){
+               ret=WriteThresholds(OFFTHRESH_low, true, 100);
+               if(ret<0){
+                std::cerr 
+                       << "dirich 0x" << std::hex << gBoardAddress 
+                       << "'s setting Thresholds failed" 
+                       << std::endl;
+                return;
+               }
+               int max=0;
+               for(int i=0+ipass;i<NRCHANNELS;i+=NrPasses){
+                       max = ToThrmV.at(i)>max ? ToThrmV.at(i) : max;
+               }
+
+               for (int addthresh=0; addthresh<=max; addthresh+=StepSize){
+                       if(gdirich_reporting_level==1){
+                               std::cout 
+                                       << "\r" 
+                                       << std::setw(10) << std::setprecision(2) << std::fixed 
+                                       << 1.*(addthresh/StepSize*100)/(max/StepSize) 
+                                       << "%" << std::flush;
+                       }
+                       std::array<uint16_t,NRCHANNELS> threshold_value;
+                       for (int ichannel=0; ichannel<LastChannel; ichannel++){
+                               threshold_value.at(ichannel) = 
+                               (ichannel+ipass)%NrPasses==0 ? 
+                               (
+                                       fbaseline.at(ichannel)
+                                       +forientation.at(ichannel)
+                                       *(
+                                               fnoisewidth.at(ichannel)/4
+                                               +Thr_mVtoD(addthresh)
+                                       )
+                               ) : 0;
+                       }
+                       ret=WriteThresholds(threshold_value, true, 100);
+                       if(ret<0){
+                        std::cerr 
+                               << "dirich 0x" << std::hex << gBoardAddress 
+                               << "'s setting Thresholds failed" 
+                               << std::endl;
+                        return;
+                       }                       
+                       for(int measures=0;measures<gMeasures;++measures){
+                               double* rates = GetRates(gMeasureTime_over_temp);
+                               for (int ichannel=0; ichannel<LastChannel; ichannel++){
+                                       if(threshold_value.at(ichannel)==0) continue;
+                                       gRateGraphsOverBase.at(ichannel)->SetPoint(
+                                               gRateGraphsOverBase.at(ichannel)->GetN(),
+                                               1.*Thr_DtomV(threshold_value.at(ichannel)-fbaseline.at(ichannel)),
+                                               1.*rates[ichannel]
+                                       );
+                                       if(gdirich_reporting_level>2){
+                                               std::cout 
+                                                       << 1.*threshold_value.at(ichannel) 
+                                                       << " " << 1.*rates[ichannel] 
+                                                       << std::endl;
+                                       }
+                               }
+                       }
+
+                       int finish_counter=0;
+                       for (int ichannel=FirstChannel+ipass; ichannel<LastChannel; ichannel+=NrPasses){
+                               int number_of_points = gRateGraphsOverBase.at(ichannel)->GetN();
+                               if(number_of_points>3.*gMeasures){
+                                       if(
+                                               gRateGraphsOverBase.at(ichannel)->GetY()[number_of_points-1]< 3. 
+                                               && gRateGraphsOverBase.at(ichannel)->GetY()[number_of_points-2] < 3. 
+                                               && gRateGraphsOverBase.at(ichannel)->GetY()[number_of_points-3] < 3.
+                                               ) 
+                                                       finish_counter++;
+                               }
+                       }
+                       if(finish_counter==(LastChannel-(FirstChannel+ipass))/NrPasses){
+                               if(gdirich_reporting_level>=1){
+                                       std::cout 
+                                       << "Stopped Scan above Threshold at threshold of " << addthresh 
+                                       << " as no larger Rate than 3 Hz was observed in any ichannel for the last three thresholds" 
+                                       << std::endl;
+                               } 
+                               break;
+                       } 
+               }
+       }
+
+       SetTDCSetting(); //Set TDC back to original values
+
+       for (int ichannel=FirstChannel; ichannel<LastChannel; ++ichannel){
+               gRateGraphsOverBase.at(ichannel)->Sort();
+       }
+}
+
+void dirich::MakeDiffGraphsOverBase(){
+       MakeDiffGraphsOverBase(1);
+}
+void dirich::MakeDiffGraphsOverBase(int case_type){
+       auto get_med = [](std::multiset<double> input_set) {
+               return 1.*(
+                       *std::next(input_set.begin(), (int)floor(1.*input_set.size()/2))
+                       +(*std::next(input_set.begin(), (int)ceil(1.*input_set.size()/2)-1))
+                       // input_set.at((int)floor(1.*input_set.size()/2))
+                       // +input_set.at((int)ceil(1.*input_set.size()/2)-1)
+                       )/2;
+       };
+
+       for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+               gDiffRateGraphsOverBase.at(ichannel)->Set(0);
+               if(fbaseline.at(ichannel)==0) continue;
+                       
+               if(gRateGraphsOverBase.at(ichannel)->GetN()<2) continue;
+               std::map<double,std::multiset<double>> points_per_x;
+               double* x_val = gRateGraphsOverBase.at(ichannel)->GetX();
+               double* y_val = gRateGraphsOverBase.at(ichannel)->GetY();
+
+               std::vector<std::pair<double,double> > val_med;
+               for (int ipoint=0; ipoint<gRateGraphsOverBase.at(ichannel)->GetN(); ++ipoint) {
+                       // std::cout << std::dec << "\t\t" << ipoint << std::endl;
+                       if(points_per_x.count(x_val[ipoint])==0){
+                               std::multiset<double> temp;
+                               points_per_x.insert(std::pair<double,std::multiset<double>>(x_val[ipoint],temp));
+                               // std::cout << "\t\tnew" << std::endl;
+                       }
+                       points_per_x.at(x_val[ipoint]).insert(y_val[ipoint]);
+                       // std::cout << std::dec << "\t\t" << points_per_x.size() << std::endl;
+               }
+
+               switch(case_type){
+                       case 0:
+                       for (int ipoint=0;ipoint<int(points_per_x.size());++ipoint){
+                               auto iterator = std::next(points_per_x.begin(),ipoint);
+                               // std::cout << std::dec << "\t\t" << ipoint << std::endl;
+                               // std::cout << std::dec << "\t\t" << ipoint << " " << *((*std::prev(iterator,1)).second.begin()) << " " << get_med((*std::prev(iterator,1)).second) << std::endl;
+                               gDiffRateGraphsOverBase.at(ichannel)->SetPoint(
+                                       gDiffRateGraphsOverBase.at(ichannel)->GetN(),
+                                       (*iterator).first,
+                                       (
+                                               get_med((*iterator).second)
+                                       )
+                               );
+                       }
+                       break;
+                       case 1:
+                       for (int ipoint=2;ipoint<int(points_per_x.size())-2;++ipoint){
+                               auto iterator = std::next(points_per_x.begin(),ipoint);
+                               // std::cout << std::dec << "\t\t" << ipoint << std::endl;
+                               // std::cout << std::dec << "\t\t" << ipoint << " " << *((*std::prev(iterator,1)).second.begin()) << " " << get_med((*std::prev(iterator,1)).second) << std::endl;
+                               gDiffRateGraphsOverBase.at(ichannel)->SetPoint(
+                                       gDiffRateGraphsOverBase.at(ichannel)->GetN(),
+                                       ((*std::prev(iterator,1)).first+(*std::next(iterator,1)).first) * 0.5,
+                                       (
+                                               -1.*get_med((*std::prev(iterator,2)).second)
+                                               +8.*get_med((*std::prev(iterator,1)).second)
+                                               -8.*get_med((*std::next(iterator,1)).second)
+                                               +1.*get_med((*std::next(iterator,2)).second)
+                                       )/(
+                                               6*fabs((*std::prev(iterator,1)).first-(*std::next(iterator,1)).first)
+                                       )
+                               );
+                       }
+                       break;
+                       case 2:
+                       case 3:
+                       default:
+                       for (int ipoint=0;ipoint<int(points_per_x.size())-1;++ipoint){
+                               auto iterator = std::next(points_per_x.begin(),ipoint);
+                               // std::cout << std::dec << "\t\t" << ipoint << std::endl;
+                               // std::cout << std::dec << "\t\t" << ipoint << " " << *((*std::prev(iterator,1)).second.begin()) << " " << get_med((*std::prev(iterator,1)).second) << std::endl;
+                               gDiffRateGraphsOverBase.at(ichannel)->SetPoint(
+                                       gDiffRateGraphsOverBase.at(ichannel)->GetN(),
+                                       (*iterator).first,
+                                       (
+                                               -1.*get_med((*std::next(iterator,1)).second)
+                                               +get_med((*iterator).second)
+                                       )/(
+                                               fabs((*iterator).first-(*std::next(iterator,1)).first)
+                                       )
+                               );
+                       }
+                       if(case_type==3){
+                               //smoothing the graph
+                               double* x_values = gDiffRateGraphsOverBase.at(ichannel)->GetX();
+                               double* y_values = gDiffRateGraphsOverBase.at(ichannel)->GetY();
+                               int number = gDiffRateGraphsOverBase.at(ichannel)->GetN();
+                               gDiffRateGraphsOverBase.at(ichannel)->Set(0);
+                               for (int ipoint=1; ipoint<number-1; ipoint++) {
+                                       gDiffRateGraphsOverBase.at(ichannel)->SetPoint(
+                                               ipoint-1,x_values[ipoint],
+                                               1.*(y_values[ipoint-1]+y_values[ipoint]+y_values[ipoint+1])/3
+                                       );
+                               }
+                       }
+                       break;
+               }
+       }
+}
+
+void dirich::MakeGraphsOverBase(){
+       for (int ichannel=0; ichannel<NRCHANNELS; ichannel++) {
+               if(fbaseline.at(ichannel)==0) continue;
+               for(int ipoint=0; ipoint<gRateGraphs.at(ichannel)->GetN(); ++ipoint){
+                       if(gRateGraphs.at(ichannel)->GetX()[ipoint]<fbaseline.at(ichannel)) continue;
+                       gRateGraphsOverBase.at(ichannel)->SetPoint(
+                               gRateGraphsOverBase.at(ichannel)->GetN(),
+                               Thr_DtomV((gRateGraphs.at(ichannel)->GetX()[ipoint])-fbaseline.at(ichannel)),
+                               gRateGraphs.at(ichannel)->GetY()[ipoint]
+                       );
+               }
+       }
+}
+
+void dirich::AnalyzeBaseline(){
+       AnalyzeBaseline(50000);
+}
+void dirich::AnalyzeBaseline(uint32_t NoiseThreshold)
+{
+       for (int ichannel=0; ichannel<NRCHANNELS; ichannel++) {
+               int NrBins=gRateGraphs.at(ichannel)->GetN();
+               int noiseedgeleft=-1;
+               int noiseedgeright=-1;
+               double max=0;
+               double max_x=0;
+
+               for (int ibin=0; ibin<NrBins-1; ibin++) {
+                       if( 
+                               (noiseedgeleft==-1) &&
+                               (gRateGraphs.at(ichannel)->GetY()[ibin] < NoiseThreshold) &&
+                               (gRateGraphs.at(ichannel)->GetY()[ibin+1] >= NoiseThreshold)
+                       ){
+                               // linear interpolation
+                               double y1=gRateGraphs.at(ichannel)->GetY()[ibin];
+                               double y2=gRateGraphs.at(ichannel)->GetY()[ibin+1];
+                               double x1=gRateGraphs.at(ichannel)->GetX()[ibin];
+                               double x2=gRateGraphs.at(ichannel)->GetX()[ibin+1];
+                               noiseedgeleft=x1+(NoiseThreshold-y1)/(y2-y1)*(x2-x1);
+                       }
+
+                       if( 
+                               (noiseedgeright==-1) &&
+                               (gRateGraphs.at(ichannel)->GetY()[NrBins-ibin-1] < NoiseThreshold) &&
+                               (gRateGraphs.at(ichannel)->GetY()[NrBins-ibin-2] >= NoiseThreshold)
+                       ){
+                               // linear interpolation
+                               double y1=gRateGraphs.at(ichannel)->GetY()[NrBins-ibin-2];
+                               double y2=gRateGraphs.at(ichannel)->GetY()[NrBins-ibin-1];
+                               double x1=gRateGraphs.at(ichannel)->GetX()[NrBins-ibin-2];
+                               double x2=gRateGraphs.at(ichannel)->GetX()[NrBins-ibin-1];
+                               noiseedgeright=x2-(NoiseThreshold-y2)/(y1-y2)*(x2-x1);
+                       }
+                       if(gRateGraphs.at(ichannel)->GetY()[ibin]>max){
+                               max=gRateGraphs.at(ichannel)->GetY()[ibin];
+                               max_x=gRateGraphs.at(ichannel)->GetX()[ibin];
+                       }
+                       // if(gRateGraphs.at(ichannel)->GetY()[NrBins-ibin-1]>max){
+                       //      max=gRateGraphs.at(ichannel)->GetY()[NrBins-ibin-1];
+                       //      max_x=gRateGraphs.at(ichannel)->GetX()[NrBins-ibin-1];
+                       // }
+                       if(noiseedgeleft!=-1 && noiseedgeright!=-1) break;
+               }
+               if(noiseedgeleft==-1 || noiseedgeright==-1){
+                       if(max==0 || NrBins<2){
+                               fbaseline_old.at(ichannel) = fbaseline.at(ichannel);
+                               fbaseline.at(ichannel) = 0;
+                               fnoisewidth_old.at(ichannel) = fnoisewidth.at(ichannel);
+                               fnoisewidth.at(ichannel) = 0;
+                               std::cout 
+                                       << "No baseline found for ichannel " 
+                                       << ichannel << "on dirich 0x" << std::hex << gBoardAddress 
+                                       << std::dec << std::endl;
+                       }
+                       else{
+                               fbaseline_old.at(ichannel) = fbaseline.at(ichannel);
+                               fbaseline.at(ichannel) = max_x;
+                               fnoisewidth_old.at(ichannel) = fnoisewidth.at(ichannel);
+                               fnoisewidth.at(ichannel) = 
+                                       2*(
+                                               abs(gRateGraphs.at(ichannel)->GetX()[0]-gRateGraphs.at(ichannel)->GetX()[1])
+                                       );
+                       }
+               }
+               else {
+                       fbaseline_old.at(ichannel) = fbaseline.at(ichannel);
+                       fbaseline.at(ichannel)=(noiseedgeleft+noiseedgeright) / 2.;
+                       fnoisewidth_old.at(ichannel) = fnoisewidth.at(ichannel);
+                       fnoisewidth.at(ichannel)=(noiseedgeright-noiseedgeleft);
+                       TLine* baseline_line = new TLine(fbaseline.at(ichannel),
+                               gRateGraphs.at(ichannel)->GetHistogram()->GetMinimum(),
+                               fbaseline.at(ichannel),gRateGraphs.at(ichannel)->GetHistogram()->GetMaximum()
+                       );
+                       baseline_line->SetLineWidth(2);
+                       baseline_line->SetLineColor(kRed);
+                       gRateGraphs.at(ichannel)->GetListOfFunctions()->Add(baseline_line);
+               } 
+       }
+}
diff --git a/thresholds/trb_dirich_threshold/obsolete/dirich_v11.C b/thresholds/trb_dirich_threshold/obsolete/dirich_v11.C
new file mode 100644 (file)
index 0000000..f1cb2ca
--- /dev/null
@@ -0,0 +1,1378 @@
+#include "trbnet.h"
+// #include "dirich_sim.C"
+#include "stdint.h"
+#include "unistd.h"
+#include <iostream>
+#include <vector>
+#include "TGraph.h"
+#include <chrono>
+#include "TThread.h"
+#include "TMutex.h"
+#include <array>
+
+#include <random>
+#include <math.h>
+
+//**************************************
+//dirich handling routines
+//**************************************
+// Channel Numbers:
+// 0-31: TDC input channels (same index as for threshold setting)
+
+const size_t BUFFER_SIZE4mb = 4194304;  /* 4MByte */
+static uint32_t buffer4mb[4194304];
+
+
+static std::mt19937_64 rnd;
+
+#ifndef NCH
+  const int NRCHANNELS = 32;       //Nr of TDC channels in dirich
+  // const int NRCHANNELS = 4;       //Nr of TDC channels in dirich
+  #define NCH
+#endif
+// const int OFFTHRESH =  28000;   //Value to switch off channel
+const int OFFTHRESH =  1000;   //Value to switch off channel
+// const int THRESHDELAY = 1000;  //Delay [mus] for thresh change to succeed
+const int THRESHDELAY = 100000;  //Delay [mus] for thresh change to succeed
+const int MAXWIDTH = 1000; //Maximal width of Noisepeak in DAC units
+const int MINTHRESHOLD = 23000;  //Minimum Threshold to search baseline in
+const int MAXTHRESHOLD = 34000;  //Maximum Threshold to search baseline in
+
+TMutex TRBAccessMutex;
+TMutex GetRateMutex;
+
+// bool find_min_wo_zero(uint16_t i, uint16_t j) { return (i!=0 && i<j); }
+
+class dirich 
+{
+
+private:
+// public:
+  uint16_t gBoardAddress;      //Board gBoardAddress
+  uint64_t gBoardUID;          //UID of Board
+
+
+  std::array<uint16_t,NRCHANNELS> fbaseline;
+  std::array<uint16_t,NRCHANNELS> fbaseline_old;
+  std::array<uint16_t,NRCHANNELS> fnoisewidth;
+  std::array<uint16_t,NRCHANNELS> fnoisewidth_old;
+  std::array<double,NRCHANNELS>   fthresholdmV;
+      
+  std::array<uint16_t,NRCHANNELS> fsim_baseline;
+  std::array<uint16_t,NRCHANNELS> fsim_noise_sigma;
+  std::array<uint16_t,NRCHANNELS> fsim_noise_width;
+  std::array<uint16_t,NRCHANNELS> fsim_current_threshold;
+  std::array<uint16_t,NRCHANNELS> fsim_singlephotonpeakposition;
+  std::array<TH1*,NRCHANNELS> fsim_distro;
+
+  int ReadSingleThreshold(uint8_t channel, uint16_t &thrvalue);
+  int WriteSingleThreshold(uint8_t channel, uint16_t thrvalue);
+  int ReadThresholds(uint16_t* thrarray);
+  int WriteThresholds(uint16_t* thrarray);
+  int WriteThresholds(uint16_t thrvalue);
+  int ReadSingleScaler(uint8_t channel, uint32_t &scalervalue, std::chrono::high_resolution_clock::time_point& access_time);
+  int ReadScalers(uint32_t* scalervalues, std::chrono::high_resolution_clock::time_point& access_time);
+  // int GetRates(uint32_t* ratevalues, double delay=1);
+
+  bool fsimulate = true;
+  bool fjans_readout = false;
+  int  gdirichver = 3;
+
+public:
+  // constructor and destructor
+  dirich();
+  dirich(uint16_t gBoardAddress);
+  virtual ~dirich();
+  
+
+  // converter functions
+  // static double Thr_DtomV(uint16_t value) {return (double)value *2500. / 65536; }//ugly but still better than using unions
+  static double Thr_DtomV(uint32_t value) {return (double)value *2500. / 65536; }
+  static uint32_t Thr_mVtoD(double value) {return value /2500. *65536+.5; }
+
+
+  // setter functions
+  //threshold
+  void SetSingleThresholdmV(uint8_t channel, double thrinmV);
+  // void SetThresholdsmV(double* thrinmV);
+  // void SetThresholdsmV(double thrinmV);
+  //baseline
+  void SetSingleBaseline(uint8_t channel, uint16_t baseline) {if(channel<NRCHANNELS) fbaseline[channel] = baseline; else std::cerr << "Channel: " << channel << " not specified" << std::endl;}
+  void SetSingleBaseline_old(uint8_t channel, uint16_t baseline) {if(channel<NRCHANNELS) fbaseline_old[channel] = baseline; else std::cerr << "Channel: " << channel << " not specified" << std::endl;}
+  // void SetBaselines(uint16_t* baseline) {for(uint8_t channel=0;channel<NRCHANNELS;++channel){fbaseline[channel] = baseline[channel];}}
+  //noisewidth
+  void SetSingleNoisewidth(uint8_t channel, uint16_t noisewidth) {if(channel<NRCHANNELS) fnoisewidth[channel] = noisewidth; else std::cerr << "Channel: " << channel << " not specified" << std::endl;}
+  void SetSingleNoisewidth_old(uint8_t channel, uint16_t noisewidth) {if(channel<NRCHANNELS) fnoisewidth_old[channel] = noisewidth; else std::cerr << "Channel: " << channel << " not specified" << std::endl;}
+  // void Setnoisewidths(uint16_t* noisewidth) {for(uint8_t channel=0;channel<NRCHANNELS;++channel){fnoisewidth[channel] = noisewidth[channel];}}
+
+
+  // getter functions
+  
+  uint16_t GetBoardAddress() {return gBoardAddress;} //board address
+  uint64_t GetBoardUID() {return gBoardUID;} //board address
+  
+  double  GetSingleRate(double delay=1, uint8_t channel=0); //rates from scaler
+  double* GetRates(double delay=1); //rates from scaler
+  
+  uint16_t ReadSingleThreshold(uint8_t channel){if(channel>=NRCHANNELS){std::cerr << "Channel: " << channel << " not specified" << std::endl; return 0;} uint16_t thrarray[32]={0}; if(ReadThresholds(thrarray)!=-1) return thrarray[channel]; else{std::cerr << "Threshold could not be read" << std::endl; return 0;}};//read threshold from !dirich!
+  uint16_t* ReadThresholds() {uint16_t* thrarray = (uint16_t*) calloc(NRCHANNELS, sizeof(uint16_t*)); if(ReadThresholds(thrarray)!=-1) return thrarray; else{uint16_t* errthrarray = (uint16_t*) calloc(NRCHANNELS, sizeof(uint16_t*)); return errthrarray;}};
+  
+  double GetSingleThresholdmV(uint8_t channel) {if(channel<NRCHANNELS) return fthresholdmV[channel]; else{std::cerr << "Channel: " << channel << " not specified" << std::endl; return 0.;}}//threshold
+  std::array<double,NRCHANNELS> GetThresholdsmV() {return fthresholdmV;}
+  
+  uint16_t GetSingleBaseline(uint8_t channel) {if(channel<NRCHANNELS) return fbaseline[channel]; else{std::cerr << "Channel: " << channel << " not specified" << std::endl; return 0;}}//baseline
+  std::array<uint16_t,NRCHANNELS> GetBaselines() {return fbaseline;}
+
+  uint16_t GetSingleBaseline_old(uint8_t channel) {if(channel<NRCHANNELS) return fbaseline_old[channel]; else{std::cerr << "Channel: " << channel << " not specified" << std::endl; return 0;}}//baseline
+  std::array<uint16_t,NRCHANNELS> GetBaselines_old() {return fbaseline_old;}
+    
+  uint16_t GetSingleNoisewidth(uint8_t channel) {if(channel<NRCHANNELS) return fnoisewidth[channel]; else{std::cerr << "Channel: " << channel << " not specified" << std::endl; return 0;}}//noisewidth
+  std::array<uint16_t,NRCHANNELS> GetNoisewidths() {return fnoisewidth;}
+    
+  uint16_t GetSingleNoisewidth_old(uint8_t channel) {if(channel<NRCHANNELS) return fnoisewidth_old[channel]; else{std::cerr << "Channel: " << channel << " not specified" << std::endl; return 0;}}//noisewidth
+  std::array<uint16_t,NRCHANNELS> GetNoisewidths_old() {return fnoisewidth_old;}
+
+  // threshold functions
+  void DoBaselineScan         ( );
+  void DoBaselineScan         ( uint32_t SearchedNoise, uint16_t MaxStepSize, double MeasureTime, int NrPasses);
+  void AnalyzeBaseline        ( );
+  void AnalyzeBaseline        ( uint32_t NoiseThreshold);
+  void DoThreshScan           ( );
+  void DoThreshScan           ( uint8_t FirstChannel, uint8_t LastChannel, uint16_t FromThr, uint16_t ToThr, double MeasureTime, uint16_t StepSize, int NrPasses); 
+  void DoThreshSearch         ( );
+  void DoThreshSearch         ( double Perc, bool SPP_SPV /*1==SPP*/, double MeasureTime, int16_t StepSize, int NrPasses);
+  void DoThreshScanOverBase   ( );
+  void DoThreshScanOverBase   ( uint8_t FirstChannel, uint8_t LastChannel, double FromThrmV, double ToThrmV, double MeasureTime, double StepSize, int NrPasses);
+  void MakeGraphsOverBase     ( );
+  void MakeGraphsOverBase     ( uint16_t ToThr);
+  void MakeDiffGraphsOverBase ( );
+  // void MakeDiffGraphsOverBase ( uint16_t FromThr, uint16_t ToThr);
+  void FindMinThreshScanOverBase(double gThreshold_finding_method);
+  
+  bool IsSim (){return fsimulate;}
+  bool IsJansReadout (){return fjans_readout;}
+  int  WhichDirichVersion (){return gdirichver;}
+
+  // threshold visualization items
+  std::array<TGraph*,NRCHANNELS> gRateGraphs;
+  std::array<TGraph*,NRCHANNELS> gRateGraphsOverBase;
+  std::array<TGraph*,NRCHANNELS> gDiffRateGraphsOverBase;
+  // void ClearGraphs();
+
+
+  // settings for threshold measurement
+  double        gMeasureTime;   //Time [s] to determine rate
+  int           gLowerEdge;     //start of thresholdscan
+  int           gUpperEdge;     //end of thresholdscan
+  int           gStepsize;      //end of thresholdscan
+  int           gNrPasses;      //Nr of passes to scan all channels
+
+  double   gMeasureTime_over;   //Time [s] to determine rate
+  int      gLowerEdge_over;     //end of thresholdscan
+  int      gUpperEdge_over;     //end of thresholdscan
+  int      gStepsize_over;      //end of thresholdscan
+  int      gNrPasses_over;      //Nr of passes to scan all channels
+
+  double   gThreshold_finding_method; //Method to find perfect threshold: 
+                                      //0: searches for the minimum in the differentiated spectrum or for the minimal gradient 
+                                      //0<value<5: tries to find peak and sigma of the single photon distribution and sets the threshold to value*sigma
+                                      //5<value<100: tries to find the single photon peak and sets the threshold to value% of the spp-position
+
+};
+
+
+dirich::dirich()
+{
+  dirich(0);
+}
+
+dirich::dirich(uint16_t BoardAddress)
+  {
+  
+  int ret=0;
+  for(int i=0;i<100;++i){
+    TRBAccessMutex.Lock();
+    ret=trb_read_uid(BoardAddress, buffer4mb, BUFFER_SIZE4mb);
+    TRBAccessMutex.UnLock();
+    if(ret>0) break;
+  }
+  if(ret<=0){
+    std::cerr << "No DiRICH found with Address:" << BoardAddress << "\nNot adding DiRICH" << std::endl;
+    return;
+  }
+  else if(ret!=4){
+    std::cerr << "Too many DiRICH found with Address:" << BoardAddress << "(Amount: "<< ret << ")\nNot adding DiRICH" << std::endl;
+    return;
+  }
+  else{
+    gBoardAddress = buffer4mb[3];
+    uint64_t temp_store = buffer4mb[0];
+    uint64_t temp_store2 = buffer4mb[1];
+    gBoardUID = temp_store << 32 | temp_store2;
+  }
+  // std::cout << ret << " " << std::hex << buffer4mb[0] << " " << buffer4mb[1] << " " << gBoardUID << " " << gBoardAddress << std::endl;
+
+  uint32_t cmd = 0x0 << 20 | 0xff << 24;
+  uint32_t c[] = {cmd,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0x10001};
+
+  for(int failed=0;failed<100;++failed){
+    TRBAccessMutex.Lock();
+    ret=trb_register_write_mem(gBoardAddress,0xd400,0,c,18);
+    TRBAccessMutex.UnLock();
+    if(ret!=-1) break;
+    usleep(1000);
+  }
+  // std::cout << ret << std::endl;
+
+  std::array<uint32_t,18> ret_c;
+  TRBAccessMutex.Lock();
+  ret=trb_register_read(gBoardAddress,0xd412,ret_c.data(),18);
+  TRBAccessMutex.UnLock();
+  if(ret!=2 || (ret_c.at(1) & 0xff00)!=0x100){
+    std::cerr << "No DiRICH2 Threshold FPGA of newest version detected\nNot adding DiRICH" << std::endl;
+    return;
+  }
+  else{
+    gdirichver = 3;
+  }
+
+  // gBoardAddress=BoardAddress;
+  gMeasureTime=.3;
+  gLowerEdge=28000;
+  gUpperEdge=32000;
+  // gStepsize=10;
+  gStepsize=50;
+  gNrPasses=2;
+  gMeasureTime_over=30.;
+  gLowerEdge_over=0;
+  gUpperEdge_over=600;
+  gStepsize_over=10;
+  gNrPasses_over=1;
+  gThreshold_finding_method=0;
+  for (int ichannel=0; ichannel<NRCHANNELS; ichannel++) {
+    gRateGraphs[ichannel]=new TGraph();
+    gRateGraphs[ichannel]->SetTitle(Form("Rate graph of dirich 0x%x's channel %i;Threshold;Rate",gBoardAddress,ichannel));
+    gRateGraphs[ichannel]->SetName(Form("Rate graph of dirich 0x%x's channel %i",gBoardAddress,ichannel));
+
+    gRateGraphsOverBase[ichannel]=new TGraph();
+    gRateGraphsOverBase[ichannel]->SetTitle(Form("Rate graph over baseline of dirich 0x%x's channel %i;Threshold in mV;Rate",gBoardAddress,ichannel));
+    gRateGraphsOverBase[ichannel]->SetName(Form("Rate graph over baseline of dirich 0x%x's channel %i",gBoardAddress,ichannel));
+
+    gDiffRateGraphsOverBase[ichannel]=new TGraph();
+    gDiffRateGraphsOverBase[ichannel]->SetTitle(Form("Differentiated rate graph over baseline of dirich 0x%x's channel %i;Threshold in mV;Differentiated rate",gBoardAddress,ichannel));
+    gDiffRateGraphsOverBase[ichannel]->SetName(Form("Differentiated rate graph over baseline of dirich 0x%x's channel %i",gBoardAddress,ichannel));
+
+    fbaseline[ichannel]=0;
+    fbaseline_old[ichannel]=0;
+    fnoisewidth[ichannel]=0;
+    fnoisewidth_old[ichannel]=0;
+    fthresholdmV[ichannel]=0.;
+  }
+
+  fsimulate=false;
+
+  if(fsimulate==true){
+    std::cout << "dirich " << std::hex << BoardAddress << std::dec << " not found -> simulating" << std::endl;
+    rnd.seed(gBoardAddress);
+
+    for(auto& fsim_baseline_it : fsim_baseline){
+    std::uniform_int_distribution<int> dist( 29600 , 30400 );
+      fsim_baseline_it = dist(rnd);
+      std::cout << "fsim_baseline_it " << fsim_baseline_it << std::endl;
+    }
+
+    for(auto& fsim_noise_sigma_it : fsim_noise_sigma){
+    std::uniform_int_distribution<int> dist( 50 , 800 );
+      fsim_noise_sigma_it = dist(rnd);
+      std::cout << "fsim_noise_sigma_it " << fsim_noise_sigma_it << std::endl;
+    }
+    
+    for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+      std::uniform_int_distribution<int> dist( fsim_baseline.at(ichannel)+2500 , fsim_baseline.at(ichannel)+8000 );
+      fsim_singlephotonpeakposition.at(ichannel) = dist(rnd);
+      std::cout << "fsim_singlephotonpeakposition.at(ichannel) " << fsim_singlephotonpeakposition.at(ichannel) << std::endl;
+    }
+    
+    for(auto& fsim_current_threshold_it : fsim_current_threshold){
+      fsim_current_threshold_it=0;
+    }
+
+    for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+      int x_pos=65536;
+      for(double sum=0;sum<50000;x_pos--){
+        sum+=(1.0E12/(fsim_noise_sigma.at(ichannel)*sqrt(2*3.14159265359))*exp(-0.5*((x_pos-fsim_baseline.at(ichannel))/fsim_noise_sigma.at(ichannel))*((x_pos-fsim_baseline.at(ichannel))/fsim_noise_sigma.at(ichannel))));
+      }
+      fsim_noise_width.at(ichannel)=2*(x_pos-fsim_baseline.at(ichannel));
+      std::cout << "fsim_noise_width.at(ichannel) " << fsim_noise_width.at(ichannel) << std::endl;
+    }
+  }
+
+  else{
+    fjans_readout=false;
+    // if( BoardAddress == 0x1235 ||  BoardAddress == 0x1231 ||  BoardAddress == 0x1217 ||  BoardAddress == 0x1233 ||  BoardAddress == 0x1238 ||  BoardAddress == 0x1214 ||  BoardAddress == 0x1237){
+    //   fjans_readout=true;
+    // }
+    // else{
+    //   fjans_readout=false;
+    // }
+    // int ret=0;
+    // //check if TDC is implemented!
+    // uint32_t temp_tdc_setting[2];
+    // TRBAccessMutex.Lock();
+    // ret=trb_register_read(BoardAddress, 0xc802, temp_tdc_setting, 2); //get TDC-settings
+    // TRBAccessMutex.UnLock();
+    // std::cout << "jans readout check phase 1: ret=" << std::dec << ret << " temp_tdc_setting[0]=" << std::hex << temp_tdc_setting[0] << " temp_tdc_setting[2]=" << temp_tdc_setting[1] << std::endl; 
+    // if(ret!=2 || temp_tdc_setting[0]!=BoardAddress){
+    //   std::cout << "jans readout check phase 1: is true" << std::endl;
+    //   fjans_readout=true;
+    // }
+
+    // if(fjans_readout!=true){ 
+    //   TRBAccessMutex.Lock();
+    //   ret=trb_register_write(BoardAddress, 0xc802, temp_tdc_setting[1]); //reset TDC-settings
+    //   TRBAccessMutex.UnLock();
+    //   std::cout << "jans readout check phase 2: ret=" << std::dec << ret << " temp_tdc_setting[0]=" << std::hex << temp_tdc_setting[0] << " temp_tdc_setting[2]=" << temp_tdc_setting[1] << std::endl; 
+    //   if(ret==-1){
+    //     std::cout << "jans readout check phase 2: is true" << std::endl;
+    //     fjans_readout=true;
+    //   }
+    // }
+
+  //   // if(fjans_readout!=true){ 
+  //   //   ret=-1;
+  //   //   uint32_t scaler1[NRCHANNELS];
+  //   //   // std::cout << "GetSingleRate" << scaler1 << " " << scaler2 << " " << ratevalues << std::endl;
+  //   //   GetRateMutex.Lock();
+  //   //   // auto start = std::chrono::high_resolution_clock::now();
+  //   //   std::chrono::high_resolution_clock::time_point start1;
+  //   //   for(int iterator=0;iterator<100;++iterator){
+  //   //     if(ret>=0) break;
+  //   //     ret=ReadScalers(scaler1,start1);
+  //   //     // std::cout << iterator << "\t";
+  //   //     if(iterator==99)fjans_readout=true;
+  //   //   }
+  //   //   GetRateMutex.UnLock();
+  //   // }
+  //   if(fjans_readout==true){ 
+  //     std::cout << "using jans scaler implementation for dirich "  << std::hex << BoardAddress << std::dec << std::endl;
+  //   }
+
+  }
+  // std::cout << "Initialization of DiRICH " << std::hex << gBoardAddress << " complete" << std::endl;
+  return;
+}
+
+dirich::~dirich()
+{
+  for (int i=0; i<NRCHANNELS; i++) {
+    if(gRateGraphs[i]) delete gRateGraphs[i];
+    if(gDiffRateGraphsOverBase[i]) delete gDiffRateGraphsOverBase[i];
+  }
+}
+
+int dirich::ReadSingleThreshold(uint8_t channel, uint16_t &thrvalue)
+{
+  if (channel>NRCHANNELS-1)
+    return -1;
+  int ret;
+  if(gBoardAddress<=0x1210){
+//   int reg=0xa000+31-channel; old firwmare
+    int reg=0xa000+channel; //new firwmare 
+    uint32_t buffer[2];
+    TRBAccessMutex.Lock();
+    ret=trb_register_read(gBoardAddress,reg, buffer, 2);
+    TRBAccessMutex.UnLock();
+
+    if((gBoardAddress != buffer[0]) || (ret != 2)) return -1;
+    
+    thrvalue=buffer[1];  
+    return 0;
+  }
+  else{
+    // uint8_t real_channel = channel%16+16;
+    uint8_t real_channel = channel%16;
+    uint32_t cmd = 0x0 << 20 | real_channel << 24 | thrvalue << 0;
+
+    uint32_t c[] = {cmd,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,(uint32_t)channel/16+1,0x10001}; //evtl. sind auch mehrere Kanäle auf einmal lesbar.
+    for(int failed=0;failed<100;++failed){
+      TRBAccessMutex.Lock();
+      ret=trb_register_write_mem(gBoardAddress,0xd400,0,c,18);
+      TRBAccessMutex.UnLock();
+      if(ret!=-1) break;
+      usleep(1000);
+    }
+    uint32_t ret_c[18];
+    TRBAccessMutex.Lock();
+    ret=trb_register_read(gBoardAddress,0xd412,ret_c,18);
+    TRBAccessMutex.UnLock();
+    // if((gBoardAddress != ret_c[0]) || (ret != 2)) return -1;
+    
+    thrvalue=ret_c[1];  
+    return 0;
+  }
+}
+
+int dirich::WriteSingleThreshold(uint8_t channel, uint16_t thrvalue) 
+{
+  if (channel>NRCHANNELS-1)
+    return -1;
+  if(fsimulate)
+    fsim_current_threshold.at(channel) = thrvalue;
+  else{
+    int ret=0;
+
+    if(gdirichver==1){
+  //   int reg=0xa000+31-channel; old firwmare
+      int reg=0xa000+channel; //new firwmare 
+      TRBAccessMutex.Lock();
+      ret=trb_register_write(gBoardAddress, reg, (uint32_t)thrvalue);
+      TRBAccessMutex.UnLock();
+      // std::cout << ret << std::endl;
+      return ret;
+    }
+    else{
+      for(int failed=0;failed<100;++failed){
+        uint8_t real_channel = channel%16+16*abs(gdirichver-3);
+        // uint8_t real_channel = channel%16+16;
+        uint32_t cmd = 0x8 << 20 | real_channel << 24 | thrvalue <<0;
+        // uint32_t c[] = {cmd,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,(uint32_t)(channel/16+1),0x10001}; //evtl. sind auch mehrere Kanäle auf einmal setzbar.
+        std::array<uint32_t,18> c = {cmd,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,(uint32_t)(channel/16+1),0x10001}; //evtl. sind auch mehrere Kanäle auf einmal setzbar.
+    
+        TRBAccessMutex.Lock();
+        ret=trb_register_write_mem(gBoardAddress,0xd400,0,c.data(),18);
+        TRBAccessMutex.UnLock();
+        if(ret!=-1) break;
+        usleep(1000);
+      }
+      uint32_t ret_c[18];
+      TRBAccessMutex.Lock();
+      ret=trb_register_read(gBoardAddress,0xd412,ret_c,18);
+      TRBAccessMutex.UnLock();
+
+      return ret;
+    }
+  }
+}
+
+int dirich::ReadThresholds(uint16_t* thrarray)
+{
+  int ret;
+  uint16_t reg=0xa000+32-NRCHANNELS;
+  uint32_t buffer[NRCHANNELS+1];
+  
+  TRBAccessMutex.Lock();
+  ret=trb_register_read_mem(gBoardAddress,reg,0,NRCHANNELS,buffer,NRCHANNELS+1);
+  TRBAccessMutex.UnLock();
+  if (ret != NRCHANNELS+1) return -1;
+
+  for (int i=0;i<NRCHANNELS;i++) {
+    thrarray[i]=buffer[NRCHANNELS-i-1];
+  }
+  return 0;
+}
+
+int dirich::WriteThresholds(uint16_t* thrarray)
+{
+  if(fsimulate){
+    for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+      fsim_current_threshold.at(ichannel) = thrarray[ichannel];
+    }
+  }
+  else{
+    int ret;
+    std::array<uint32_t,18> c1;
+    std::array<uint32_t,18> c2;
+    if(gdirichver==1){
+         uint16_t reg=0xa000+32-NRCHANNELS;
+         uint32_t buffer[NRCHANNELS];
+         for (int i=0;i<NRCHANNELS;i++) {
+           buffer[i]=thrarray[NRCHANNELS-i-1];
+         }
+         TRBAccessMutex.Lock();
+         ret=trb_register_write_mem(gBoardAddress,reg,0,buffer,NRCHANNELS);
+         TRBAccessMutex.UnLock();
+         return ret;
+    }
+    else{
+    std::array<uint32_t,32> cmd;
+       for(int channel=0;channel<NRCHANNELS;++channel){
+        // uint8_t real_channel = channel%16+16;
+       uint8_t real_channel = channel%16+16*abs(gdirichver-3);
+       cmd.at(channel) = 0x8 << 20 | real_channel << 24 | thrarray[channel] <<0;
+        // std::cout << std::hex << thrarray[channel] << " threhsold for channel " << channel << " gives: " << cmd.at(channel) << std::endl;
+       }
+
+      c1 = {{cmd.at(0),cmd.at(1),cmd.at(2),cmd.at(3),cmd.at(4),cmd.at(5),cmd.at(6),cmd.at(7),cmd.at(8),cmd.at(9),cmd.at(10),cmd.at(11),cmd.at(12),cmd.at(13),cmd.at(14),cmd.at(15),(uint32_t)1,0x10010}};
+      for(int failed=0;failed<100;++failed){
+        TRBAccessMutex.Lock();
+        ret=trb_register_write_mem(gBoardAddress,0xd400,0,c1.data(),18);
+        TRBAccessMutex.UnLock();
+
+        if(ret!=-1) break;
+        usleep(1000);
+      }
+
+       std::array<uint32_t,18> ret_c1;
+      TRBAccessMutex.Lock();
+      if(ret!=-1) ret=trb_register_read(gBoardAddress,0xd412,ret_c1.data(),18);
+      TRBAccessMutex.UnLock();
+
+      if(ret==-1) return ret;
+
+      // std::cout << "done setting first fpga" << std::endl;
+      // for(auto& c_iterator : c1){
+      //   std::cout << c_iterator << " ";
+      // }
+      // std::cout << std::endl;
+      // for(auto& c_iterator : ret_c1){
+      //   std::cout << c_iterator << " ";
+      // }
+      // std::cout << std::endl;
+
+      c2 = {{cmd.at(16+0),cmd.at(16+1),cmd.at(16+2),cmd.at(16+3),cmd.at(16+4),cmd.at(16+5),cmd.at(16+6),cmd.at(16+7),cmd.at(16+8),cmd.at(16+9),cmd.at(16+10),cmd.at(16+11),cmd.at(16+12),cmd.at(16+13),cmd.at(16+14),cmd.at(16+15),(uint32_t)2,0x10010}};
+               for(int failed=0;failed<100;++failed){
+        TRBAccessMutex.Lock();
+        ret=trb_register_write_mem(gBoardAddress,0xd400,0,c2.data(),18);
+        TRBAccessMutex.UnLock();
+        if(ret!=-1) break;
+        usleep(1000);
+      }
+
+       std::array<uint32_t,18> ret_c2;
+      TRBAccessMutex.Lock();
+      if(ret!=-1) ret=trb_register_read(gBoardAddress,0xd412,ret_c2.data(),18);
+      TRBAccessMutex.UnLock();
+
+      // if(ret==-1) return ret;
+      // std::cout << "done setting second fpga" << std::endl;
+      // for(auto& c_iterator : c2){
+        // std::cout << c_iterator << " ";
+      // }
+      // std::cout << std::endl;    
+      // if(ret_c1!=c1 || ret_c2!=c2){
+      //   std::cout << "return values not equal!" << std::endl;
+      //   ret=-1;
+      // } 
+      return ret;
+    }
+  }
+}
+
+int dirich::WriteThresholds(uint16_t thrvalue)
+{
+  int ret;
+  uint16_t thrarray[NRCHANNELS];
+  for (int i=0; i<NRCHANNELS; i++)
+    thrarray[i]=thrvalue;
+  ret=WriteThresholds(thrarray);
+  return ret;
+}
+
+void dirich::SetSingleThresholdmV(uint8_t channel ,double thrinmV=30.)
+{
+       if(channel>=NRCHANNELS){
+               std::cerr << "Channel: " << std::dec << channel << " not specified" << std::endl;
+               return;
+       }
+  int baseline=fbaseline[channel];
+  if(baseline==0){
+    std::cerr << "dirich 0x" << std::hex << gBoardAddress << "'s channel: " << std::dec << unsigned(channel) << " has no baseline! (baseline==0)" << std::endl;
+    return;
+  } 
+  int thrinD=Thr_mVtoD(thrinmV);
+  int newthreshold=baseline+thrinD;
+
+  WriteSingleThreshold(channel,newthreshold);
+  fthresholdmV[channel]=thrinmV;
+
+  // printf("Setting threshold for channel %i \n",channel);
+  // printf("Baseline: %i \n",baseline);
+  // printf("Threshold %3.0f in digits:  %i \n",thrinmV, thrinD);
+  // printf("New threshold value %i set \n\n",newthreshold);
+  // DrawGraphs(dirichptr,cc.at(dirichptr.first),Form("Threshold: %3.0f mV",thrinmV));
+}
+
+int dirich::ReadSingleScaler(uint8_t channel, uint32_t& scalervalue, std::chrono::high_resolution_clock::time_point& access_time)
+{
+  int ret;
+  if (channel>NRCHANNELS)
+    return -1;
+  uint16_t reg=0xc000+channel;
+  if(fjans_readout) reg=0xdfc0+channel; //readout of Jans implementation!!!!
+  // else reg=0xc000+channel;
+  uint32_t buffer[2];
+  TRBAccessMutex.Lock();
+  access_time = std::chrono::high_resolution_clock::now();
+  ret=trb_register_read(gBoardAddress,reg, buffer, 2);
+  TRBAccessMutex.UnLock();
+  if ( (gBoardAddress != buffer[0]) || (ret != 2) ) 
+    return -1;
+  
+  scalervalue=buffer[1] & 0x7fffffff;
+  return 0;
+}
+
+int dirich::ReadScalers(uint32_t* scalervalues, std::chrono::high_resolution_clock::time_point& access_time)
+{
+  int ret;
+  uint16_t reg=0xc000+1;
+  if(fjans_readout) reg=0xdfc0; //readout of Jans implementation!!!!
+  // else reg=0xc000+1;
+  uint32_t buffer[NRCHANNELS+1];
+  for (int i=0;i<NRCHANNELS+1; i++) buffer[i]=0;
+  TRBAccessMutex.Lock();
+  access_time = std::chrono::high_resolution_clock::now();
+  // ret=trb_register_read(gBoardAddress,reg,buffer,NRCHANNELS);
+  ret=trb_register_read_mem(gBoardAddress,reg,0,NRCHANNELS,buffer,NRCHANNELS+1);
+  // ret=trb_register_read_mem(gBoardAddress,reg,0,NRCHANNELS,buffer,NRCHANNELS+1);
+  TRBAccessMutex.UnLock();
+  // std::cout << std::hex << buffer[0] << " " << gBoardAddress << " " << fjans_readout << std::dec << " " << ret <<  std::endl;
+  // if (ret != NRCHANNELS+1) 
+  // if ( gBoardAddress != buffer[0]) 
+  if ( (ret == NRCHANNELS+1) && (fjans_readout || gBoardAddress == (buffer[0] & 0xffff)) ){
+    for (int i=0;i<NRCHANNELS;i++){
+      scalervalues[i]=buffer[i+1] & 0x7fffffff;
+    }
+    return 0;
+  }
+  else{
+    return -1;
+  }
+}
+
+double dirich::GetSingleRate(double delay, uint8_t channel)
+{
+  if(fsimulate){
+    long long int counter = 0;
+    for(unsigned long long int itime=0;itime<delay*1000000;++itime){
+    // for(unsigned long long int itime=0;itime<delay*1000000000000;++itime){
+      // if(itime%1000000==0) std::cout << std::dec << itime << " ";
+      // GetRateMutex.Lock();
+      std::uniform_real_distribution<double> is_spp_dist(0,1);
+      std::normal_distribution<double> noise_dist(fsim_baseline.at(channel),fsim_noise_sigma.at(channel));
+      std::normal_distribution<double> spp_dist(fsim_singlephotonpeakposition.at(channel),2000);
+      if(fsim_current_threshold.at(channel)>fsim_baseline.at(channel)){
+        double spp_pulse_prob = is_spp_dist(rnd);
+        // std::cout << "spp_pulse_prob" << spp_pulse_prob << std::endl;
+        if(is_spp_dist(rnd)<=4E-9){
+          if(noise_dist(rnd)+spp_dist(rnd)>fsim_current_threshold.at(channel)){
+            counter++;
+            itime+=20000-1;
+          }
+        }
+      }
+      else{
+        double val_1 = noise_dist(rnd);
+        if((val_1>fsim_current_threshold.at(channel) && fsim_current_threshold.at(channel)>fsim_baseline.at(channel)) || (val_1<fsim_current_threshold.at(channel) && fsim_current_threshold.at(channel)<fsim_baseline.at(channel))){
+          counter++;
+          itime+=20000-1;
+          // std::cout << "yeah1" << std::endl;
+        }
+      }
+    }
+    // GetRateMutex.UnLock();
+    double counter_d = 0;
+    // std::cout << "fsim_current_threshold.at(ichannel) " << std::dec << fsim_current_threshold.at(ichannel) << std::endl;
+    // std::cout << "counter.at(ichannel) " << counter.at(ichannel) << std::endl;
+    counter_d=counter*1000000/delay;
+    // counter_d.at(ichannel)=1.*counter.at(ichannel)/delay;
+    // std::cout << "counter_d.at(ichannel) " << counter_d.at(ichannel) << std::endl;
+    // std::cout << std::endl;
+    return counter_d;
+  }
+  else{
+    int ret=-1;
+    uint32_t scaler1;
+    uint32_t scaler2;
+    GetRateMutex.Lock();
+    std::chrono::high_resolution_clock::time_point start1;
+    for(int iterator=0;iterator<100;++iterator){
+      if(ret>=0) break;
+      ret=ReadSingleScaler(channel,scaler1,start1);
+      // std::cout << iterator << "\t";
+      if(iterator==99) printf("Error reading start_scalers !\n");
+    }
+    GetRateMutex.UnLock();
+    // std::cout << scaler1 << "\n";
+
+    usleep(1e6*delay);
+    ret=-1;
+    GetRateMutex.Lock();
+    std::chrono::high_resolution_clock::time_point stop1;
+    for(int iterator=0;iterator<100;++iterator){
+      if(ret>=0) break;
+      ret=ReadSingleScaler(channel,scaler2,stop1);
+      // std::cout << iterator << "\t";
+      if(iterator==99) printf("Error reading end_scalers !\n");
+    }
+    GetRateMutex.UnLock();
+    // std::cout << scaler2 << "\n";
+
+    double exactdelay1=std::chrono::duration_cast<std::chrono::microseconds>(stop1-start1).count() * 1e-6;
+    double rate=scaler2<scaler1?
+      (2<<23)+scaler2-scaler1 : scaler2-scaler1;
+    rate=1.*rate/exactdelay1;
+    return rate;
+  }
+}
+
+double* dirich::GetRates(double delay)
+{
+  if(fsimulate){
+    std::array <long long int,NRCHANNELS> counter;
+    counter.fill(0);
+    for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+      for(unsigned long long int itime=0;itime<delay*1000000;++itime){
+      // for(unsigned long long int itime=0;itime<delay*1000000000000;++itime){
+        // if(itime%1000000==0) std::cout << std::dec << itime << " ";
+        // GetRateMutex.Lock();
+        std::uniform_real_distribution<double> is_spp_dist(0,1);
+        std::normal_distribution<double> noise_dist(fsim_baseline.at(ichannel),fsim_noise_sigma.at(ichannel));
+        std::normal_distribution<double> spp_dist(fsim_singlephotonpeakposition.at(ichannel),2000);
+        if(fsim_current_threshold.at(ichannel)>fsim_baseline.at(ichannel)){
+          double spp_pulse_prob = is_spp_dist(rnd);
+          // std::cout << "spp_pulse_prob" << spp_pulse_prob << std::endl;
+          if(is_spp_dist(rnd)<=4E-9){
+            if(noise_dist(rnd)+spp_dist(rnd)>fsim_current_threshold.at(ichannel)){
+              counter.at(ichannel)++;
+              itime+=20000-1;
+            }
+          }
+        }
+        else{
+          double val_1 = noise_dist(rnd);
+          if((val_1>fsim_current_threshold.at(ichannel) && fsim_current_threshold.at(ichannel)>fsim_baseline.at(ichannel)) || (val_1<fsim_current_threshold.at(ichannel) && fsim_current_threshold.at(ichannel)<fsim_baseline.at(ichannel))){
+            counter.at(ichannel)++;
+            itime+=20000-1;
+            // std::cout << "yeah1" << std::endl;
+          }
+        }
+      }
+      // GetRateMutex.UnLock();
+    }
+    std::array <double,NRCHANNELS> counter_d;
+    counter_d.fill(0);
+    for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+      // std::cout << "fsim_current_threshold.at(ichannel) " << std::dec << fsim_current_threshold.at(ichannel) << std::endl;
+      // std::cout << "counter.at(ichannel) " << counter.at(ichannel) << std::endl;
+      counter_d.at(ichannel)=counter.at(ichannel)*1000000/delay;
+      // counter_d.at(ichannel)=1.*counter.at(ichannel)/delay;
+      // std::cout << "counter_d.at(ichannel) " << counter_d.at(ichannel) << std::endl;
+    }
+    // std::cout << std::endl;
+    return counter_d.data();
+  }
+  else{
+    int ret=-1;
+    uint32_t scaler1[NRCHANNELS];
+    uint32_t scaler2[NRCHANNELS];
+    double* ratevalues = (double*) calloc(NRCHANNELS, sizeof(double*));
+    GetRateMutex.Lock();
+    std::chrono::high_resolution_clock::time_point start1;
+    for(int iterator=0;iterator<100;++iterator){
+      if(ret>=0) break;
+      ret=ReadScalers(scaler1,start1);
+      // std::cout << iterator << "\t";
+      if(iterator==99) printf("Error reading start_scalers !\n");
+    }
+    GetRateMutex.UnLock();
+
+    usleep(1e6*delay);
+    ret=-1;
+    GetRateMutex.Lock();
+    std::chrono::high_resolution_clock::time_point stop1;
+    for(int iterator=0;iterator<100;++iterator){
+      if(ret>=0) break;
+      ret=ReadScalers(scaler2,stop1);
+      // std::cout << iterator << "\t";
+      if(iterator==99) printf("Error reading end_scalers !\n");
+    }
+    GetRateMutex.UnLock();
+
+    double exactdelay1=std::chrono::duration_cast<std::chrono::microseconds>(stop1-start1).count() * 1e-6;
+    for (int i=0; i<NRCHANNELS; i++) {
+      double rate=scaler2[i]<scaler1[i]?
+                       (2<<23)+scaler2[i]-scaler1[i] : scaler2[i]-scaler1[i];
+      rate=1.*rate/exactdelay1;
+      ratevalues[i]=rate;
+    }
+    return ratevalues;
+  }
+}
+
+void dirich::DoBaselineScan(){
+       DoBaselineScan(50000, 250, .3, 4);
+}
+void dirich::DoBaselineScan(uint32_t SearchedNoise, uint16_t StartStepSize, double MeasureTime, int NrPasses)
+{
+  for (int ichannel=0; ichannel<NRCHANNELS; ichannel++) {
+    gRateGraphs[ichannel]->Set(0);
+  }  
+  int ret=0;
+  if(fjans_readout){
+    uint32_t scaler_switch[] = {0xffffffff};
+    TRBAccessMutex.Lock();
+    ret=trb_register_write_mem(gBoardAddress,0xdf80,0,scaler_switch,1); //switching on scaler for this dirich .... only needed when using jan's readout
+    TRBAccessMutex.UnLock();
+    if(ret<0) std::cerr << "Error switching on scalers" << std::endl;
+  }
+
+  int number_of_checks=2;
+
+  std::array<uint16_t, NRCHANNELS> low_edge;
+  low_edge.fill(0);
+  std::array<uint16_t, NRCHANNELS> high_edge;
+  high_edge.fill(0);  
+
+  for(int ipass=0;ipass<NrPasses;++ipass){
+    // std::cout  << std::dec << "Baselinescan @ " << 50/NrPasses*ipass << "\%" << std::endl;
+    int n_of_iterations=0;
+    std::array<int16_t, NRCHANNELS> step_size;
+    std::array<uint16_t, NRCHANNELS> threshold_value;
+    std::array<double, NRCHANNELS> rate;
+    std::array<double, NRCHANNELS> old_rate;
+    std::array<int, NRCHANNELS> status;
+    status.fill(0);
+    rate.fill(0);
+    old_rate.fill(0);    
+    for(int ichannel = 0; ichannel<NRCHANNELS; ++ichannel ){
+      step_size.at(ichannel)= ichannel%NrPasses==ipass ? StartStepSize : 0;
+      threshold_value.at(ichannel)= ichannel%NrPasses==ipass ? MINTHRESHOLD : OFFTHRESH;
+      status.at(ichannel)= ichannel%NrPasses==ipass ? 0 : 4*number_of_checks-2;
+    }
+    while(!std::all_of(status.cbegin(), status.cend(), [number_of_checks](int i){ return i==4*number_of_checks-2;}) 
+      && !std::all_of(step_size.cbegin(), step_size.cend(), [](int i){ return i==0;}) 
+      && n_of_iterations<500)
+    {
+    // while(!std::all_of(step_size.cbegin(), step_size.cend(), [](int i){ return i==0;}) && n_of_iterations<200){
+      std::cout << std::dec << n_of_iterations << std::endl;
+      for(auto& step_size_ch : step_size){
+        std::cout << std::dec << step_size_ch << "\t";
+      }
+      std::cout << std::dec << std::endl;
+      for(auto& threshold_value_ch : threshold_value){
+        std::cout << std::dec << threshold_value_ch << "\t";
+      }
+      std::cout << std::dec << std::endl; 
+      for(auto& rate_ch : rate){
+        std::cout << std::dec << rate_ch << "\t";
+      }
+      std::cout << std::dec << std::endl;      
+      for(auto& old_rate_ch : old_rate){
+        std::cout << std::dec << old_rate_ch << "\t";
+      }
+      std::cout << std::dec << std::endl; 
+      for(auto& status_ch : status){
+        std::cout << std::dec << status_ch << "\t";
+      }
+      std::cout << std::dec << std::endl;             
+      std::cout << std::dec << std::endl;             
+      std::cout << std::dec << std::endl;             
+
+      ++n_of_iterations;
+      ret=WriteThresholds(threshold_value.data());
+      // if(n_of_iterations==1)usleep(1000000);
+      usleep(THRESHDELAY);
+      double* temp_rate;
+      temp_rate = GetRates(MeasureTime);
+      memcpy(rate.data(),temp_rate,NRCHANNELS*sizeof(double));
+
+      for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+        gRateGraphs.at(ichannel)->SetPoint(gRateGraphs.at(ichannel)->GetN(),1.*threshold_value.at(ichannel),1.*rate.at(ichannel));
+        if(status.at(ichannel)<number_of_checks){
+          if(status.at(ichannel)%2==0 && old_rate.at(ichannel) < SearchedNoise && rate.at(ichannel) > SearchedNoise){
+            status.at(ichannel)++;
+            threshold_value.at(ichannel)-=2*step_size.at(ichannel);
+          }
+          else if(status.at(ichannel)%2==1 && old_rate.at(ichannel) > SearchedNoise && rate.at(ichannel) < SearchedNoise){
+            status.at(ichannel)++;
+            // threshold_value.at(ichannel)-=step_size.at(ichannel);
+          }
+          else{
+            status.at(ichannel)=0;
+          }
+          if(status.at(ichannel)==number_of_checks*2-1){
+            step_size.at(ichannel)/=3;
+            if(step_size.at(ichannel)!=0){
+              status.at(ichannel)=0;
+            }
+            else{
+              step_size.at(ichannel)= ichannel%NrPasses==ipass ? -StartStepSize : 0;
+              threshold_value.at(ichannel)= ichannel%NrPasses==ipass ? MAXTHRESHOLD : OFFTHRESH;
+              rate.at(ichannel)==0;
+              low_edge.at(ichannel)=threshold_value.at(ichannel);
+            }
+          }
+        }
+        if(status.at(ichannel)<4*number_of_checks-2){
+          if(status.at(ichannel)%2==0 && old_rate.at(ichannel) < SearchedNoise && rate.at(ichannel) > SearchedNoise){
+            status.at(ichannel)++;
+            threshold_value.at(ichannel)-=2*step_size.at(ichannel);
+          }
+          else if(status.at(ichannel)%2==1 && old_rate.at(ichannel) > SearchedNoise && rate.at(ichannel) < SearchedNoise){
+            status.at(ichannel)++;
+            // threshold_value.at(ichannel)-=step_size.at(ichannel);
+          }
+          else{
+            status.at(ichannel)=0;
+          }
+          if(status.at(ichannel)==number_of_checks*2-1){
+            step_size.at(ichannel)/=3;
+            if(step_size.at(ichannel)!=0){
+              status.at(ichannel)=0;
+            }
+            else{
+              high_edge.at(ichannel)=threshold_value.at(ichannel);
+            }
+          }
+        }
+        threshold_value.at(ichannel)+=step_size.at(ichannel);
+      }
+      old_rate=rate;
+    }
+  }
+
+  if(fjans_readout){
+    usleep(THRESHDELAY);
+    uint32_t scaler_switch[] = {0x0};
+    TRBAccessMutex.Lock();
+    ret=trb_register_write_mem(gBoardAddress,0xdf80,0,scaler_switch,1); //switching off scaler for this dirich .... only needed when using jan's readout
+    TRBAccessMutex.UnLock();
+    if(ret<0) std::cerr << "Error switching off scalers" << std::endl;
+  }
+  for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+    // std::cout << std::dec << "high_edge\t" << high_edge.at(ichannel) << "\tlow_edge\t" << low_edge.at(ichannel) << std::endl;
+    fnoisewidth_old.at(ichannel) = fnoisewidth.at(ichannel);
+    fnoisewidth.at(ichannel) = high_edge.at(ichannel)-low_edge.at(ichannel);
+    fbaseline_old.at(ichannel) = fbaseline.at(ichannel);
+    fbaseline.at(ichannel) = (high_edge.at(ichannel)+low_edge.at(ichannel))/2;
+    // std::cout << std::dec << "fnoisewidth_old" << "\t" << fnoisewidth_old.at(ichannel) << "\t" << "fnoisewidth" << "\t" << fnoisewidth.at(ichannel) << "\t" << "fbaseline_old" << "\t" << fbaseline_old.at(ichannel) << "\t" << "fbaseline" << "\t" << fbaseline.at(ichannel) << std::endl;
+  }
+  for (int ichannel=0; ichannel<NRCHANNELS; ++ichannel){
+    gRateGraphs.at(ichannel)->Sort();
+  }  
+}
+  
+void dirich::DoThreshScan(){
+       DoThreshScan(0, NRCHANNELS, gLowerEdge, gUpperEdge, gMeasureTime, gStepsize, gNrPasses);
+}
+void dirich::DoThreshScan(uint8_t FirstChannel, uint8_t LastChannel, uint16_t FromThr, uint16_t ToThr, double MeasureTime, uint16_t StepSize, int NrPasses)
+{
+  // std::cout << std::dec << (int)FirstChannel << " " << (int)LastChannel << " " << FromThr << " " << ToThr << " " << MeasureTime << " " << StepSize << " " << NrPasses << std::endl;
+  int ret;
+  if(fjans_readout){
+    uint32_t scaler_switch[] = {0xffffffff};
+    TRBAccessMutex.Lock();
+    ret=trb_register_write_mem(gBoardAddress,0xdf80,0,scaler_switch,1); //switching on scaler for this dirich .... only needed when using jan's readout
+    TRBAccessMutex.UnLock();
+    if(ret<0) std::cerr << "Error switching on scalers" << std::endl;
+  }
+  // std::cout << "Set0" << std::endl;
+  // TGraph* temp[NRCHANNELS];
+  for (int ichannel=0; ichannel<NRCHANNELS; ichannel++) {
+    // if(gRateGraphs[ichannel]){
+      // std::cout << "deleting gRateGraphs[" << ichannel << "]" << std::endl;
+      // delete gRateGraphs[ichannel];
+      // std::cout << "deleted" << std::endl;
+      // gRateGraphs[ichannel]=new TGraph();
+    // }
+    // gRateGraphs[ichannel]->SetTitle(Form("Rate graph of dirich 0x%x's channel %i;Threshold;Rate",gBoardAddress,ichannel));
+    // gRateGraphs[ichannel]->SetName(Form("Rate graph of dirich 0x%x's channel %i",gBoardAddress,ichannel));
+    // temp[ichannel] = new TGraph();
+    gRateGraphs[ichannel]->Set(0);
+  }
+  for(int ipass=0;ipass<NrPasses;++ipass){
+    // std::cout << "Pass Nr. " << ipass+1 << " of " << NrPasses << std::endl;
+    ret=WriteThresholds(OFFTHRESH);
+    usleep(THRESHDELAY);
+    ret=WriteThresholds(OFFTHRESH);
+    usleep(THRESHDELAY);
+    for (int thresh=FromThr; thresh<=ToThr; thresh+=StepSize){
+      // std::cout << std::dec << ((thresh-FromThr)/StepSize+1)*(ipass+1) << "\t" << ((ToThr-FromThr)/StepSize+1)*(NrPasses+1) << "\t" << int(1.*((thresh-FromThr)/StepSize+1)*(ipass+1)/(((ToThr-FromThr)/StepSize+1)*(NrPasses+1))*100) << "\t" << int(1.*((thresh-FromThr)/StepSize+1)*(ipass+1)/(((ToThr-FromThr)/StepSize+1)*(NrPasses+1))*100)%20 << std::endl;
+      // if(int(((thresh-FromThr)+(ToThr-FromThr)*(ipass))/((ToThr-FromThr)*(NrPasses))*100.)%20==0) std::cout << "Baselinescan of dirich 0x" << std::hex << gBoardAddress << std::dec <<" is @ " << int(((thresh-FromThr)+(ToThr-FromThr)*(ipass))/((ToThr-FromThr)*(NrPasses))*100.) << "%" << std::endl;
+      for (int ichannel=FirstChannel+ipass; ichannel<=LastChannel; ichannel+=NrPasses){
+        ret=WriteSingleThreshold(ichannel,thresh);
+      }
+      usleep(THRESHDELAY);
+      double* rates;
+      rates = GetRates(MeasureTime);
+      for (int ichannel=FirstChannel+ipass; ichannel<LastChannel; ichannel+=NrPasses){
+        std::cout << std::dec << "Channel " << ichannel << " PointIndex " << gRateGraphs[ichannel]->GetN() << " thr " << thresh << " rate " << rates[ichannel] << std::endl;
+        gRateGraphs[ichannel]->SetPoint(gRateGraphs[ichannel]->GetN(),1.*thresh,1.*rates[ichannel]);
+        // temp[ichannel]->SetPoint(temp[ichannel]->GetN(),1.*thresh,1.*rates[ichannel]);
+        // std::cout << std::dec << "2Channel " << ichannel << " PointIndex " << gRateGraphs[ichannel]->GetN() << " thr " << thresh << " rate " << rates[ichannel] << std::endl;
+        // gRateGraphs[ichannel]->Sort();
+      }
+      std::cout << std::endl;
+    }
+  }
+  for (int ichannel=FirstChannel; ichannel<LastChannel; ++ichannel){
+    // std::cout << ichannel << " 1" << std::endl;
+    // for (int ipoint=0; ipoint<temp[ichannel]->GetN(); ++ipoint){
+    //   gRateGraphs[ichannel]->SetPoint(ipoint,temp[ichannel]->GetX()[ipoint],temp[ichannel]->GetY()[ipoint]); 
+    // }
+    // std::cout << ichannel << " 2" << std::endl;
+    gRateGraphs[ichannel]->Sort();
+    // std::cout << ichannel << " 3" << std::endl;
+    // delete temp[ichannel];
+    // std::cout << ichannel << " 4" << std::endl;
+  }
+  if(fjans_readout){
+    usleep(THRESHDELAY);
+    uint32_t scaler_switch[] = {0x0};
+    TRBAccessMutex.Lock();
+    ret=trb_register_write_mem(gBoardAddress,0xdf80,0,scaler_switch,1); //switching off scaler for this dirich .... only needed when using jan's readout
+    TRBAccessMutex.UnLock();
+    if(ret<0) std::cerr << "Error switching off scalers" << std::endl;
+  }
+
+}
+
+void dirich::DoThreshSearch(){
+  if(std::all_of(fbaseline.cbegin(), fbaseline.cend(), [](int i){ return i==0; })){
+    std::cerr << "dirich 0x" << std::hex << gBoardAddress << std::dec << " has no baseline yet. Please load or scan one (load_base, system_thr_scan)" << std::endl;
+    return;
+  }
+  if(gThreshold_finding_method==0){
+    DoThreshSearch(1., 0, 30., 100, 1);
+  }
+  else if(gThreshold_finding_method>0 && gThreshold_finding_method<5){
+    DoThreshScanOverBase( 0, NRCHANNELS, 0., 999., 30., 10, 1);
+    MakeDiffGraphsOverBase();
+    FindMinThreshScanOverBase(gThreshold_finding_method);
+    std::cout << "currently this method is not implemented" << std::endl;
+  } 
+  else if(gThreshold_finding_method>5 && gThreshold_finding_method<100){
+    DoThreshSearch(gThreshold_finding_method, 1, 30., 400, 1);
+  }  
+}
+void dirich::DoThreshSearch(double Perc, bool SPP_SPV /*1==SPP*/, double MeasureTime, int16_t StepSize, int NrPasses){
+  int ret;
+  if(fjans_readout){
+    uint32_t scaler_switch[] = {0xffffffff};
+    TRBAccessMutex.Lock();
+    ret=trb_register_write_mem(gBoardAddress,0xdf80,0,scaler_switch,1); //switching on scaler for this dirich .... only needed when using jan's readout
+    TRBAccessMutex.UnLock();
+    if(ret<0) std::cerr << "Error switching on scalers" << std::endl;  
+  }
+    // std::cout << "Set0" << std::endl;
+  for (int ichannel=0; ichannel<NRCHANNELS; ichannel++) {
+    gRateGraphsOverBase[ichannel]->Set(0);
+    gDiffRateGraphsOverBase[ichannel]->Set(0);
+  }
+
+  std::array<double,NRCHANNELS> SPP_SPV_value;
+  for(int ipass=0;ipass<NrPasses;++ipass){
+    int n_of_iterations=0;
+    std::array<uint16_t, NRCHANNELS> step_size;
+    std::array<uint16_t, NRCHANNELS> threshold_value;
+    std::array<std::vector<double>, NRCHANNELS> rate;
+    std::array<std::vector<double>, NRCHANNELS> diff_rate;
+    for(int ichannel = 0; ichannel<NRCHANNELS; ++ichannel ){
+      step_size.at(ichannel)= ichannel%NrPasses==ipass ? StepSize : 0;
+      // step_size.at(ichannel)= ichannel==0 ? StepSize : 0;
+      // threshold_value.at(ichannel)= ichannel%NrPasses==ipass ? fbaseline.at(ichannel)+fnoisewidth.at(ichannel)/5+.5 : OFFTHRESH;
+      threshold_value.at(ichannel)= ichannel%NrPasses==ipass ? fbaseline.at(ichannel)+fnoisewidth.at(ichannel)/5+.5 : OFFTHRESH;
+      SPP_SPV_value.at(ichannel)=0;
+    }
+    while(
+        n_of_iterations==0 
+        || (
+          !std::all_of(step_size.cbegin(), step_size.cend(), [](int i){ return i==0;}) 
+          && n_of_iterations<200 
+          && !(
+            std::all_of(rate.cbegin(), rate.cend(), [](std::vector<double> i){ return i.back()< 3.;}) 
+            && std::all_of(step_size.cbegin(), step_size.cend(), [StepSize](int i){ return i==StepSize || i==0;})
+          )
+        )
+      ){
+    
+      ++n_of_iterations;
+      std::cout << "n_of_iterations " << n_of_iterations << std::endl;
+      ret=WriteThresholds(threshold_value.data());
+      if(n_of_iterations==1)usleep(1000000);
+      usleep(2*THRESHDELAY);
+      double* temp_rate;
+      temp_rate = GetRates(MeasureTime);
+      for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+        if(step_size.at(ichannel)==0) continue;
+        std::cout << "ichannel " << ichannel << std::endl;
+        std::cout << "threshold_value.at(ichannel) " << threshold_value.at(ichannel) << "\t";
+        std::cout << "temp_rate[ichannel] " << temp_rate[ichannel] << "\t";
+        rate.at(ichannel).push_back(temp_rate[ichannel]);
+        std::cout << "rate.at(ichannel) " << rate.at(ichannel).back() << std::endl;
+        gRateGraphsOverBase.at(ichannel)->SetPoint(gRateGraphsOverBase.at(ichannel)->GetN(),Thr_DtomV(threshold_value.at(ichannel)-fbaseline.at(ichannel)),rate.at(ichannel).back());
+        std::cout << "rate.at(ichannel).size() " << rate.at(ichannel).size() << std::endl;
+        if(step_size.at(ichannel)==StepSize && rate.at(ichannel).size()>5){
+          diff_rate.at(ichannel).push_back(-1.*rate.at(ichannel).at(rate.at(ichannel).size()-5)+16.*rate.at(ichannel).at(rate.at(ichannel).size()-4)+32.*rate.at(ichannel).at(rate.at(ichannel).size()-3)-16.*rate.at(ichannel).at(rate.at(ichannel).size()-2)+1.*rate.at(ichannel).at(rate.at(ichannel).size()-1));
+          diff_rate.at(ichannel).back()/=(12.*step_size.at(ichannel)*step_size.at(ichannel));
+        }
+        if(rate.at(ichannel).size()>=15){
+          double left_side_derivative=-1.*rate.at(ichannel).at(rate.at(ichannel).size()-15)+8.*rate.at(ichannel).at(rate.at(ichannel).size()-14)-8.*rate.at(ichannel).at(rate.at(ichannel).size()-12)+1.*rate.at(ichannel).at(rate.at(ichannel).size()-11);
+          double middle_derivative=-1.*rate.at(ichannel).at(rate.at(ichannel).size()-10)+8.*rate.at(ichannel).at(rate.at(ichannel).size()-9)-8.*rate.at(ichannel).at(rate.at(ichannel).size()-7)+1.*rate.at(ichannel).at(rate.at(ichannel).size()-6);
+          double right_side_derivative=-1.*rate.at(ichannel).at(rate.at(ichannel).size()-5)+8.*rate.at(ichannel).at(rate.at(ichannel).size()-4)-8.*rate.at(ichannel).at(rate.at(ichannel).size()-2)+1.*rate.at(ichannel).at(rate.at(ichannel).size()-1);
+          std::cout << "threshold_value.at(ichannel) " << threshold_value.at(ichannel) << " threshold_value.at(ichannel)-13*step_size.at(ichannel)-fbaseline.at(ichannel) " << threshold_value.at(ichannel)-13*step_size.at(ichannel)-fbaseline.at(ichannel) << std::endl;
+          gDiffRateGraphsOverBase.at(ichannel)->SetPoint(gDiffRateGraphsOverBase.at(ichannel)->GetN(),Thr_DtomV(threshold_value.at(ichannel)-13*step_size.at(ichannel)-fbaseline.at(ichannel)),left_side_derivative/(12.*step_size.at(ichannel)));
+          std::cout << "left_side_derivative " << left_side_derivative << " middle_derivative " << middle_derivative << " right_side_derivative " << right_side_derivative << std::endl;
+          if((SPP_SPV==1 && left_side_derivative<middle_derivative && right_side_derivative<middle_derivative) || (SPP_SPV==0 && left_side_derivative>middle_derivative && right_side_derivative>middle_derivative)){
+            rate.at(ichannel).clear();
+            if(step_size.at(ichannel)/10==0){
+              gDiffRateGraphsOverBase.at(ichannel)->SetPoint(gDiffRateGraphsOverBase.at(ichannel)->GetN(),Thr_DtomV(threshold_value.at(ichannel)-8*step_size.at(ichannel)-fbaseline.at(ichannel)),middle_derivative/(12.*step_size.at(ichannel)));
+              gDiffRateGraphsOverBase.at(ichannel)->SetPoint(gDiffRateGraphsOverBase.at(ichannel)->GetN(),Thr_DtomV(threshold_value.at(ichannel)-3*step_size.at(ichannel)-fbaseline.at(ichannel)),right_side_derivative/(12.*step_size.at(ichannel)));
+              // SPP_SPV_value.at(ichannel)=Perc*Thr_DtomV(threshold_value.at(ichannel)-step_size.at(ichannel)*5.5-fbaseline.at(ichannel));
+              SPP_SPV_value.at(ichannel)=Perc*Thr_DtomV(threshold_value.at(ichannel)-step_size.at(ichannel)*5.5-fbaseline.at(ichannel));
+              threshold_value.at(ichannel)=OFFTHRESH;
+            }
+            else{
+              threshold_value.at(ichannel)=threshold_value.at(ichannel)-step_size.at(ichannel)*6;
+            }
+            step_size.at(ichannel)/=10;
+          }
+        }
+        threshold_value.at(ichannel)=threshold_value.at(ichannel)+step_size.at(ichannel);
+      }
+    }
+    if(SPP_SPV==0){
+      for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+        if(step_size.at(ichannel)==StepSize){
+          double minimum=1E6;
+          for(int diff_rate_it=0;diff_rate_it<diff_rate.at(ichannel).size();++diff_rate_it){
+            if(diff_rate.at(ichannel).at(diff_rate_it)<minimum){
+              minimum=diff_rate.at(ichannel).at(diff_rate_it);
+              diff_rate_it*step_size.at(ichannel)+fbaseline.at(ichannel)+fnoisewidth.at(ichannel)/5+.5;
+            } 
+          }
+        }
+      }
+    }    
+  }
+
+  for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+    std::cout << Thr_mVtoD(SPP_SPV_value.at(ichannel))+fbaseline.at(ichannel) << "\t";
+    gDiffRateGraphsOverBase.at(ichannel)->Sort();
+    gRateGraphsOverBase.at(ichannel)->Sort();
+    SetSingleThresholdmV(ichannel,-1*SPP_SPV_value.at(ichannel));
+  }
+  std::cout << std::endl;
+  if(fjans_readout){
+    usleep(THRESHDELAY);
+    uint32_t scaler_switch[] = {0x0};
+    TRBAccessMutex.Lock();
+    ret=trb_register_write_mem(gBoardAddress,0xdf80,0,scaler_switch,1); //switching off scaler for this dirich .... only needed when using jan's readout
+    TRBAccessMutex.UnLock();  
+    if(ret<0) std::cerr << "Error switching off scalers" << std::endl;
+  }
+}
+void dirich::DoThreshScanOverBase(){
+  if(std::all_of(fbaseline.cbegin(), fbaseline.cend(), [](int i){ return i==0; })){
+    std::cerr << "dirich 0x" << std::hex << gBoardAddress << std::dec << " has no baseline yet. Please load or scan one (load_base, system_thr_scan)" << std::endl;
+    return;
+  }
+  DoThreshScanOverBase(0, NRCHANNELS, gLowerEdge_over, gUpperEdge_over, gMeasureTime_over, gStepsize_over, gNrPasses_over);
+  // DoThreshScanOverBase(0, NRCHANNELS, Thr_DtomV(gUpperEdge-*min_element(fbaseline.begin(),fbaseline.end(),find_min_wo_zero)), gMeasureTime, Thr_DtomV(gStepsize), gNrPasses);
+  // std::cout << "minimal baseline = " << *min_element(fbaseline.begin(),fbaseline.end(),find_min_wo_zero) << std::endl;
+}
+void dirich::DoThreshScanOverBase(uint8_t FirstChannel, uint8_t LastChannel, double FromThrmV, double ToThrmV, double MeasureTime, double StepSize, int NrPasses){
+  int ret;
+  if(fjans_readout){
+    uint32_t scaler_switch[] = {0xffffffff};
+    TRBAccessMutex.Lock();
+    ret=trb_register_write_mem(gBoardAddress,0xdf80,0,scaler_switch,1); //switching on scaler for this dirich .... only needed when using jan's readout
+    TRBAccessMutex.UnLock();
+    if(ret<0) std::cerr << "Error switching on scalers" << std::endl;  
+  }
+
+    // std::cout << "Set0" << std::endl;
+  for (int ichannel=0; ichannel<NRCHANNELS; ichannel++) {
+    gRateGraphsOverBase[ichannel]->Set(0);
+  }
+  for(int ipass=0;ipass<NrPasses;++ipass){
+    ret=WriteThresholds(OFFTHRESH);
+    usleep(THRESHDELAY);
+    for (double thresh=FromThrmV; fabs(thresh)<=ToThrmV; thresh+=StepSize){
+      // if(int(1.*((thresh-0)+(ToThrmV-0)*(ipass))/((ToThrmV-0)*(NrPasses))*100)%20==0) std::cout << "Thresholdscan over Noiseband of dirich 0x" << std::hex << gBoardAddress << std::dec <<" is @ " << int(1.*((thresh-0)+(ToThrmV-0)*(ipass))/((ToThrmV-0)*(NrPasses))*100) << "%" << std::endl;
+      for (int ichannel=FirstChannel+ipass; ichannel<=LastChannel; ichannel+=NrPasses){
+        if(fbaseline[ichannel]==0) continue;
+        // std::cout << thresh << " " << Thr_DtomV(fnoisewidth[ichannel]) << std::endl;
+        if(fabs(thresh)<Thr_DtomV(fnoisewidth[ichannel])/4){
+        // if(thresh<-1*fthresholdmV[ichannel]){
+          // std::cout << "skipping" << std::endl;
+          continue;
+        }
+        ret=WriteSingleThreshold(ichannel,Thr_mVtoD(thresh)+fbaseline[ichannel]);
+      }
+      usleep(THRESHDELAY);
+      double* rates;
+      rates = GetRates(MeasureTime);
+      for (int ichannel=FirstChannel+ipass; ichannel<LastChannel; ichannel+=NrPasses){
+        if(fbaseline[ichannel]==0) continue;
+        if(fabs(thresh)<Thr_DtomV(fnoisewidth[ichannel])/4) continue;
+        // if(thresh<-1*fthresholdmV[ichannel]) continue;
+        // std::cout << std::dec << "Channel " << ichannel << " thr " << thresh << " rate " << rates[ichannel] << std::endl;
+        gRateGraphsOverBase[ichannel]->SetPoint(gRateGraphsOverBase[ichannel]->GetN(),thresh,1.*rates[ichannel]);
+      }
+
+      int finish_counter=0;
+      for (int ichannel=FirstChannel+ipass; ichannel<LastChannel; ichannel+=NrPasses){
+        int number_of_points = gRateGraphsOverBase[ichannel]->GetN();
+        if(number_of_points>3){
+          if(gRateGraphsOverBase[ichannel]->GetY()[number_of_points-1]< 3. && gRateGraphsOverBase[ichannel]->GetY()[number_of_points-2] < 3. && gRateGraphsOverBase[ichannel]->GetY()[number_of_points-3] < 3.) finish_counter++;
+          // std::cout << "gRateGraphsOverBase[ichannel]->GetY()[number_of_points-1] " << gRateGraphsOverBase[ichannel]->GetY()[number_of_points-1] << " gRateGraphsOverBase[ichannel]->GetY()[number_of_points-2] " << gRateGraphsOverBase[ichannel]->GetY()[number_of_points-2] << " gRateGraphsOverBase[ichannel]->GetY()[number_of_points-3] " << gRateGraphsOverBase[ichannel]->GetY()[number_of_points-3] << std::endl;
+        }
+      }
+      std::cout << "thresh " << thresh << " finish_counter " << finish_counter << " (FirstChannel-(FirstChannel+ipass))/NrPasses " << std::dec << (LastChannel-(FirstChannel+ipass))/NrPasses << std::endl;
+      if(finish_counter==(LastChannel-(FirstChannel+ipass))/NrPasses) break;
+
+    }
+  }
+  for (int ichannel=FirstChannel; ichannel<=LastChannel; ++ichannel){
+    gRateGraphsOverBase[ichannel]->Sort();
+  }
+  if(fjans_readout){
+    usleep(THRESHDELAY);
+    uint32_t scaler_switch[] = {0x0};
+    TRBAccessMutex.Lock();
+    ret=trb_register_write_mem(gBoardAddress,0xdf80,0,scaler_switch,1); //switching off scaler for this dirich .... only needed when using jan's readout
+    TRBAccessMutex.UnLock();  
+    if(ret<0) std::cerr << "Error switching off scalers" << std::endl;
+  }  
+}
+
+void dirich::FindMinThreshScanOverBase(double gThreshold_finding_method){
+  for (int ichannel=0; ichannel<NRCHANNELS; ichannel++){
+    TGraph* temp = new TGraph("temp","temp");
+    for (int ipoint=2; ipoint<gDiffRateGraphsOverBase[ichannel]->GetN()-2; ++ipoint){
+          temp->SetPoint(temp->GetN(),
+                        (gDiffRateGraphsOverBase[ichannel]->GetX()[ipoint-1]+gDiffRateGraphsOverBase[ichannel]->GetX()[ipoint+1]) * 0.5,
+                        (-gDiffRateGraphsOverBase[ichannel]->GetY()[ipoint-2]+8*gDiffRateGraphsOverBase[ichannel]->GetY()[ipoint-1]-8*gDiffRateGraphsOverBase[ichannel]->GetY()[ipoint+1]+gDiffRateGraphsOverBase[ichannel]->GetY()[ipoint+2]) /
+                        (12*fabs(gDiffRateGraphsOverBase[ichannel]->GetX()[ipoint-1]-gDiffRateGraphsOverBase[ichannel]->GetX()[ipoint+1])));
+    }
+    double minimum_value=temp->GetY()[0];
+    double minimum=temp->GetX()[0];
+    int counter=0;
+    for (int ipoint=1; ipoint<temp->GetN(); ++ipoint){
+      if(temp->GetY()[ipoint-1]<minimum_value){
+        minimum_value = temp->GetY()[ipoint];
+        minimum = temp->GetX()[ipoint];
+      }
+      if(temp->GetY()[ipoint-1]>0 && temp->GetY()[ipoint]<0){
+        minimum_value = -9999999;
+        minimum = temp->GetX()[ipoint-1];
+        counter++;
+      }
+    }
+    std::cout << "perfect threshold for dirich 0x" << std::hex << gBoardAddress << "'s channel " << ichannel << " is at " << minimum << "lying in the" << counter << "rd valley." << std::endl;
+    SetSingleThresholdmV(ichannel,minimum);
+  }
+
+}
+
+void dirich::MakeDiffGraphsOverBase(){
+       // MakeDiffGraphsOverBase(gLowerEdge, gUpperEdge);
+// }
+// void dirich::MakeDiffGraphsOverBase(uint16_t FromThr, uint16_t ToThr){
+  for (int ichannel=0; ichannel<NRCHANNELS; ichannel++) {
+               // if(FromThr==0){
+               //      FromThr=fbaseline[ichannel]+fnoisewidth[ichannel]/2;
+               // }    
+    // std::cout << "Set0" << std::endl;
+    gDiffRateGraphsOverBase[ichannel]->Set(0);
+    // std::cout << "Set" << gDiffRateGraphsOverBase[ichannel]->GetN() << std::endl;
+    // doing the derivative (5 point stencil)
+    for (int ipoint=2; ipoint<gRateGraphsOverBase[ichannel]->GetN()-2; ++ipoint) {
+      // gDiffRateGraphsOverBase[ichannel]->SetPoint(gDiffRateGraphsOverBase[ichannel]->GetN(),
+      //                                     (gRateGraphsOverBase[ichannel]->GetX()[ipoint-1]+gRateGraphsOverBase[ichannel]->GetX()[ipoint+1]) * 0.5,
+      //                                     (gRateGraphsOverBase[ichannel]->GetY()[ipoint-1]-gRateGraphsOverBase[ichannel]->GetY()[ipoint+1]) /
+      //                                     fabs(gRateGraphsOverBase[ichannel]->GetX()[ipoint-1]-gRateGraphsOverBase[ichannel]->GetX()[ipoint+1]));
+      gDiffRateGraphsOverBase[ichannel]->SetPoint(gDiffRateGraphsOverBase[ichannel]->GetN(),
+                                          (gRateGraphsOverBase[ichannel]->GetX()[ipoint-1]+gRateGraphsOverBase[ichannel]->GetX()[ipoint+1]) * 0.5,
+                                          (-gRateGraphsOverBase[ichannel]->GetY()[ipoint-2]+8*gRateGraphsOverBase[ichannel]->GetY()[ipoint-1]-8*gRateGraphsOverBase[ichannel]->GetY()[ipoint+1]+gRateGraphsOverBase[ichannel]->GetY()[ipoint+2]) /
+                                          (12*fabs(gRateGraphsOverBase[ichannel]->GetX()[ipoint-1]-gRateGraphsOverBase[ichannel]->GetX()[ipoint+1])));
+    }
+    //smoothing the graph
+    double* x_values = gDiffRateGraphsOverBase[ichannel]->GetX();
+    double* y_values = gDiffRateGraphsOverBase[ichannel]->GetY();
+    for (int ipoint=1; ipoint<gDiffRateGraphsOverBase[ichannel]->GetN()-1; ipoint+=3) {
+      gDiffRateGraphsOverBase[ichannel]->SetPoint(ipoint-1,x_values[ipoint],1.*(y_values[ipoint-1]+y_values[ipoint]+y_values[ipoint+1])/3);
+    }
+  }
+}
+
+void dirich::MakeGraphsOverBase(){
+  MakeGraphsOverBase(gUpperEdge);
+}
+void dirich::MakeGraphsOverBase(uint16_t ToThr){
+  for (int ichannel=0; ichannel<NRCHANNELS; ichannel++) {
+    // std::cout << "Set0" << std::endl;
+    gRateGraphsOverBase[ichannel]->Set(0);
+    // std::cout << "Set" << gRateGraphsOverBase[ichannel]->GetN() << std::endl;
+    if(fbaseline[ichannel]==0) continue;
+    for(int ipoint=0; ipoint<gRateGraphs[ichannel]->GetN(); ++ipoint){
+      if(gRateGraphs[ichannel]->GetX()[ipoint]<fbaseline[ichannel]+1.*fnoisewidth[ichannel]/2) continue;
+      // std::cout << ipoint << " " << gRateGraphsOverBase[ichannel]->GetN() << " " << Thr_DtomV((gRateGraphs[ichannel]->GetX()[ipoint])-fbaseline[ichannel]) << " " << gRateGraphs[ichannel]->GetY()[ipoint] << std::endl;
+      gRateGraphsOverBase[ichannel]->SetPoint(gRateGraphsOverBase[ichannel]->GetN(),Thr_DtomV((gRateGraphs[ichannel]->GetX()[ipoint])-fbaseline[ichannel]),gRateGraphs[ichannel]->GetY()[ipoint]);
+    }
+    // std::cout << gBoardAddress << " " << ichannel << " " << gRateGraphsOverBase[ichannel]->GetN() << " " << gRateGraphs[ichannel]->GetN() << " " << fbaseline[ichannel] << " " << gRateGraphs[ichannel]->GetX()[gRateGraphs[ichannel]->GetN()-1] << std::endl;
+  }
+}
+
+void dirich::AnalyzeBaseline(){
+       AnalyzeBaseline(50000);
+}
+void dirich::AnalyzeBaseline(uint32_t NoiseThreshold)
+{
+  for (int ichannel=0; ichannel<NRCHANNELS; ichannel++) {
+    int NrBins=gRateGraphs[ichannel]->GetN();
+    int noiseedgeleft=-1;
+    int noiseedgeright=-1;
+
+    for (int ibin=0; ibin<NrBins-1; ibin++) {
+      if( 
+        (noiseedgeleft==-1) &&
+        (gRateGraphs[ichannel]->GetY()[ibin] < NoiseThreshold) &&
+        (gRateGraphs[ichannel]->GetY()[ibin+1] >= NoiseThreshold)
+      ){
+        // linear interpolation
+        double y1=gRateGraphs[ichannel]->GetY()[ibin];
+        double y2=gRateGraphs[ichannel]->GetY()[ibin+1];
+        double x1=gRateGraphs[ichannel]->GetX()[ibin];
+        double x2=gRateGraphs[ichannel]->GetX()[ibin+1];
+        noiseedgeleft=x1+(NoiseThreshold-y1)/(y2-y1)*(x2-x1);
+        // std::cout << ichannel << " LeftEdge " << ibin << " " << x1 << " " << x2 << " " << y1 << " " << y2 << " " << noiseedgeleft << std::endl;
+      }
+
+      if( 
+        (noiseedgeright==-1) &&
+        (gRateGraphs[ichannel]->GetY()[NrBins-ibin-1] < NoiseThreshold) &&
+        (gRateGraphs[ichannel]->GetY()[NrBins-ibin-2] >= NoiseThreshold)
+      ){
+        // linear interpolation
+        double y1=gRateGraphs[ichannel]->GetY()[NrBins-ibin-2];
+        double y2=gRateGraphs[ichannel]->GetY()[NrBins-ibin-1];
+        double x1=gRateGraphs[ichannel]->GetX()[NrBins-ibin-2];
+        double x2=gRateGraphs[ichannel]->GetX()[NrBins-ibin-1];
+        noiseedgeright=x2-(NoiseThreshold-y2)/(y1-y2)*(x2-x1);
+        // std::cout << ichannel << " RightEdge " << ibin << " " << x1 << " " << x2 << " " << y1 << " " << y2 << " " << noiseedgeright << std::endl;
+      }
+
+      if(noiseedgeleft!=-1 && noiseedgeright!=-1) break;
+    }
+    if(noiseedgeleft==-1 || noiseedgeright==-1){
+      fbaseline_old[ichannel] = fbaseline[ichannel];
+      fbaseline[ichannel] = 0;
+      fnoisewidth_old[ichannel] = fnoisewidth[ichannel];
+      fnoisewidth[ichannel] = 0;
+      std::cout << "No baseline found for channel " << ichannel << "on dirich 0x" << std::hex << gBoardAddress << std::dec << std::endl;
+    }
+    else {
+      fbaseline_old[ichannel] = fbaseline[ichannel];
+      fbaseline[ichannel]=(noiseedgeleft+noiseedgeright) / 2.;
+      fnoisewidth_old[ichannel] = fnoisewidth[ichannel];
+      fnoisewidth[ichannel]=(noiseedgeright-noiseedgeleft);
+      TLine* baseline_line = new TLine(fbaseline[ichannel],gRateGraphs[ichannel]->GetHistogram()->GetMinimum(),fbaseline[ichannel],gRateGraphs[ichannel]->GetHistogram()->GetMaximum());
+      baseline_line->SetLineWidth(2);
+      baseline_line->SetLineColor(kRed);
+      gRateGraphs[ichannel]->GetListOfFunctions()->Add(baseline_line);
+    }      
+  }
+}
diff --git a/thresholds/trb_dirich_threshold/obsolete/systemthreshscan_v11 b/thresholds/trb_dirich_threshold/obsolete/systemthreshscan_v11
new file mode 100755 (executable)
index 0000000..6befb83
Binary files /dev/null and b/thresholds/trb_dirich_threshold/obsolete/systemthreshscan_v11 differ
diff --git a/thresholds/trb_dirich_threshold/obsolete/systemthreshscan_v11.C b/thresholds/trb_dirich_threshold/obsolete/systemthreshscan_v11.C
new file mode 100644 (file)
index 0000000..e7fb217
--- /dev/null
@@ -0,0 +1,1478 @@
+#include "trbnet.h"
+// #include "dirich_sim.C"
+
+#include "TGraph.h"
+#include "TGraph2D.h"
+#include "TMultiGraph.h"
+#include "TCanvas.h"
+#include "TH1.h"
+#include "TH2.h"
+#include "TLegend.h"
+#include "TStyle.h"
+#include "TLine.h"
+#include "TFile.h"
+#include "TText.h"
+#include "TMath.h"
+#include "TThread.h"
+#include <map>
+#include <array>
+#include <sstream>
+#include <fstream>
+#include <ctime>
+#include <stdlib.h>
+#include <iostream>
+#include <boost/program_options.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/range.hpp>
+// #include <iomanip>
+
+#include "dirich_v11.C"
+
+namespace po = boost::program_options;
+namespace fs = boost::filesystem;
+
+// #define 0 0
+// #define LASTCHANNEL 31
+
+#ifndef NCH
+  const int NRCHANNELS = 32;       //Nr of TDC channels in dirich
+  // const int NRCHANNELS = 4;       //Nr of TDC channels in dirich
+  #define NCH
+#endif
+
+std::map<uint16_t,std::shared_ptr<dirich>> dirichlist ={};
+
+std::map<uint16_t,TCanvas*> canvaslist;
+
+std::vector<TCanvas*> canvasvector;
+
+TH2* get_2D_rate_histo(std::shared_ptr<dirich>  dirichptr){
+       TH2D* histo;
+       gStyle->SetOptStat(0);
+  if(dirichptr==NULL){
+    histo = new TH2D("2D Rate vs. Threshold of all diriches","2D Rate vs. Threshold of all diriches",dirichlist.size()*NRCHANNELS,-.5,dirichlist.size()*NRCHANNELS-.5,(dirichlist.begin()->second->gUpperEdge-dirichlist.begin()->second->gLowerEdge)/dirichlist.begin()->second->gStepsize,dirichlist.begin()->second->gLowerEdge,dirichlist.begin()->second->gUpperEdge);
+               int idirich=0;
+               // std::map<uint16_t,dirich*>::iterator dirichlistiterator = dirichlist.begin();
+               TLine* dirich_line_left = new TLine(histo->GetXaxis()->GetBinLowEdge(idirich*NRCHANNELS+1),histo->GetYaxis()->GetBinLowEdge(1),histo->GetXaxis()->GetBinLowEdge(idirich*NRCHANNELS+1),histo->GetYaxis()->GetBinUpEdge(histo->GetNbinsY()));
+               dirich_line_left->SetLineWidth(2);
+               dirich_line_left->SetLineColor(kRed);
+               histo->GetListOfFunctions()->Add(dirich_line_left);
+    for (auto& dirichitem : dirichlist){
+                       TLine* dirich_line_right = new TLine(histo->GetXaxis()->GetBinLowEdge((idirich+1)*NRCHANNELS+1),histo->GetYaxis()->GetBinLowEdge(1),histo->GetXaxis()->GetBinLowEdge((idirich+1)*NRCHANNELS+1),histo->GetYaxis()->GetBinUpEdge(histo->GetNbinsY()));
+                       dirich_line_right->SetLineWidth(2);
+      dirich_line_right->SetLineColor(kRed);
+                       histo->GetListOfFunctions()->Add(dirich_line_right);
+       TText* dirich_name = new TText(histo->GetXaxis()->GetBinCenter((idirich+1./2)*NRCHANNELS+1),histo->GetYaxis()->GetBinLowEdge(1)-(0.1*(histo->GetYaxis()->GetBinLowEdge(1)-histo->GetYaxis()->GetBinUpEdge(histo->GetNbinsY()))),Form("0x%x",dirichitem.first));
+       // TText* dirich_name = new TText(histo->GetXaxis()->GetBinCenter((idirich+1./2)*NRCHANNELS+1),histo->GetYaxis()->GetBinLowEdge(1)+500,Form("0x%x",dirichitem.first));
+                       dirich_name->SetTextAlign(22);
+                       dirich_name->SetTextColor(kRed+2);
+                       dirich_name->SetTextFont(43);
+                       dirich_name->SetTextSize(20);
+                       histo->GetListOfFunctions()->Add(dirich_name);
+      for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+                               // std::cout << (int)dirichlist.size() << std::endl;
+       // std::cout << "dirich: " << std::hex << dirichlistiterator.first << std::dec << "GetN " << dirichlistiterator->second->gRateGraphs[ichannel]->GetN() << std::endl;
+       for(int ipoint=0;ipoint<dirichitem.second->gRateGraphs[ichannel]->GetN();++ipoint){
+               // std::cout << idirich << " " << std::hex << dirichlistiterator.first << std::dec << " " <<  ichannel << " " << ipoint << " " << dirichlistiterator->second->gRateGraphs[ichannel]->GetX()[ipoint] << " " << dirichlistiterator->second->gRateGraphs[ichannel]->GetY()[ipoint] << std::endl;
+               histo->Fill(idirich*NRCHANNELS+ichannel,dirichitem.second->gRateGraphs[ichannel]->GetX()[ipoint],dirichitem.second->gRateGraphs[ichannel]->GetY()[ipoint]);
+               // std::cout << ichannel << " " << int(dirichlist.size()*NRCHANNELS/20+1) << std::endl;
+                                       if(ichannel%8==0) histo->GetXaxis()->SetBinLabel(idirich*NRCHANNELS+ichannel+1,Form("%i",ichannel));
+                                       // if(ichannel%int(dirichlist.size()*NRCHANNELS/20+1)==0) histo->GetXaxis()->SetBinLabel(idirich*NRCHANNELS+ichannel+1,Form("%i",ichannel));
+                                       else histo->GetXaxis()->SetBinLabel(idirich*NRCHANNELS+ichannel+1,"");
+       }
+                               TLine* baseline_line = new TLine(histo->GetXaxis()->GetBinLowEdge(idirich*NRCHANNELS+ichannel+1),dirichitem.second->GetSingleBaseline(ichannel),histo->GetXaxis()->GetBinUpEdge(idirich*NRCHANNELS+ichannel+1),dirichitem.second->GetSingleBaseline(ichannel));
+                               baseline_line->SetLineColor(kRed);
+                               baseline_line->SetLineWidth(2);
+                               histo->GetListOfFunctions()->Add(baseline_line);
+        TLine* baseline_line_old = new TLine(histo->GetXaxis()->GetBinLowEdge(idirich*NRCHANNELS+ichannel+1),dirichitem.second->GetSingleBaseline_old(ichannel),histo->GetXaxis()->GetBinUpEdge(idirich*NRCHANNELS+ichannel+1),dirichitem.second->GetSingleBaseline_old(ichannel));
+        baseline_line_old->SetLineColor(kBlack);
+        baseline_line_old->SetLineWidth(2);
+        histo->GetListOfFunctions()->Add(baseline_line_old);        
+      }
+       // ++dirichlistiterator;
+       ++idirich;
+    }
+  }
+  else{
+         histo = new TH2D(Form("2D Rate vs. Threshold of %x",dirichptr->GetBoardAddress()),Form("2D Rate vs. Threshold of %x",dirichptr->GetBoardAddress()),NRCHANNELS,-.5,NRCHANNELS-.5,(dirichptr->gUpperEdge-dirichptr->gLowerEdge)/dirichptr->gStepsize,dirichptr->gLowerEdge,dirichptr->gUpperEdge);
+         for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+                       for(int ipoint=0;ipoint<dirichptr->gRateGraphs[ichannel]->GetN();++ipoint){
+                               histo->Fill(ichannel,dirichptr->gRateGraphs[ichannel]->GetX()[ipoint],dirichptr->gRateGraphs[ichannel]->GetY()[ipoint]);
+                       }
+                       TLine* baseline_line = new TLine(histo->GetXaxis()->GetBinLowEdge(ichannel+1),dirichptr->GetSingleBaseline(ichannel),histo->GetXaxis()->GetBinUpEdge(ichannel+1),dirichptr->GetSingleBaseline(ichannel));
+                       baseline_line->SetLineColor(kRed);
+                       baseline_line->SetLineWidth(2);
+                       histo->GetListOfFunctions()->Add(baseline_line);
+      TLine* baseline_line_old = new TLine(histo->GetXaxis()->GetBinLowEdge(ichannel+1),dirichptr->GetSingleBaseline_old(ichannel),histo->GetXaxis()->GetBinUpEdge(ichannel+1),dirichptr->GetSingleBaseline_old(ichannel));
+      baseline_line_old->SetLineColor(kBlack);
+      baseline_line_old->SetLineWidth(2);
+      histo->GetListOfFunctions()->Add(baseline_line_old);      
+         }
+       }
+       // std::cout << "finished histo" << std::endl;
+  
+       histo->SetMinimum(0);
+       histo->GetXaxis()->SetTitle("Channel Nr");
+       // histo->GetXaxis()->SetTitleOffset();
+       histo->GetYaxis()->SetTitle("Threshold");
+       histo->GetZaxis()->SetTitle("Rate");
+  return histo;
+}
+
+TMultiGraph* get_2D_mgr_diff_over_thr_histo(std::shared_ptr<dirich>  dirichptr){
+       TMultiGraph* multig = new TMultiGraph();
+       if(dirichptr==NULL){
+    // multig->SetTitle("Differentiated rate graph over baseline of all dirich;Channel Nr;Threshold;Differentiated rate");
+               multig->SetTitle("Differentiated rate graph over baseline of all dirich;Threshold;Differentiated rate");
+               multig->SetName("Differentiated rate graph over baseline of all dirich (Mutligraph)");
+         for (auto& dirichitem : dirichlist){
+               for(auto& gDiffRateGraphsOverBaseIT : dirichitem.second->gDiffRateGraphsOverBase){
+                               multig->Add(gDiffRateGraphsOverBaseIT,"PL");
+                       }
+               }
+       }
+       else{
+    // multig->SetTitle(Form("Differentiated rate graph over baseline of dirich 0x%x;Channel Nr;Threshold;Differentiated rate",dirichptr->GetBoardAddress()));
+               multig->SetTitle(Form("Differentiated rate graph over baseline of dirich 0x%x;Threshold;Differentiated rate",dirichptr->GetBoardAddress()));
+               multig->SetName(Form("Differentiated rate graph over baseline of dirich 0x%x (Multigraph)",dirichptr->GetBoardAddress()));
+       for(auto& gDiffRateGraphsOverBaseIT : dirichptr->gDiffRateGraphsOverBase){
+                       multig->Add(gDiffRateGraphsOverBaseIT,"PL");
+               }
+       }
+  // multig->SetMinimum(0);
+  // multig->GetHistogram()->GetYaxis()->SetRangeUser(0,100);
+       return multig;
+}
+
+TGraph2D* get_2D_gr_diff_over_thr_histo(std::shared_ptr<dirich>  dirichptr){
+       TGraph2D* g2d = new TGraph2D();
+       if(dirichptr==NULL){
+               g2d->SetTitle("Differentiated rate graph over baseline of all dirich;Channel Nr;Threshold;Differentiated rate");
+               g2d->SetName("Differentiated rate graph over baseline of all dirich (2D_Graph)");
+               int idirich=0;
+         for (auto& dirichitem : dirichlist){
+               int ichannel=0;
+               for(auto& gDiffRateGraphsOverBaseIT : dirichitem.second->gDiffRateGraphsOverBase){
+                       // std::cout << " " << idirich << " " << dirichitem.first << " " << ichannel << " " << gDiffRateGraphsOverBaseIT->GetN() << std::endl;
+               for(int ipoint=0;ipoint<gDiffRateGraphsOverBaseIT->GetN();++ipoint){
+                       // std::cout << " " << idirich << " " << dirichitem.first << " " << ichannel << " " << ipoint << " " << gDiffRateGraphsOverBaseIT->GetX()[ipoint] << " " << gDiffRateGraphsOverBaseIT->GetY()[ipoint] << std::endl;
+                                       g2d->SetPoint(g2d->GetN(),idirich*NRCHANNELS+ichannel,gDiffRateGraphsOverBaseIT->GetX()[ipoint],gDiffRateGraphsOverBaseIT->GetY()[ipoint]);
+                               }
+                               ichannel++;
+                       }
+                       idirich++;
+               }
+       }
+       else{
+               g2d->SetTitle(Form("Differentiated rate graph over baseline of dirich 0x%x;Channel Nr;Threshold;Differentiated rate",dirichptr->GetBoardAddress()));
+               g2d->SetName(Form("Differentiated rate graph over baseline of dirich 0x%x (2D_Graph)",dirichptr->GetBoardAddress()));
+       int ichannel=0;
+       for(auto& gDiffRateGraphsOverBaseIT : dirichptr->gDiffRateGraphsOverBase){
+               // std::cout << " " << idirich << " " << dirichitem.first << " " << ichannel << " " << gDiffRateGraphsOverBaseIT->GetN() << std::endl;
+       for(int ipoint=0;ipoint<gDiffRateGraphsOverBaseIT->GetN();++ipoint){
+               // std::cout << " " << idirich << " " << dirichitem.first << " " << ichannel << " " << ipoint << " " << gDiffRateGraphsOverBaseIT->GetX()[ipoint] << " " << gDiffRateGraphsOverBaseIT->GetY()[ipoint] << std::endl;
+                               g2d->SetPoint(g2d->GetN(),ichannel,gDiffRateGraphsOverBaseIT->GetX()[ipoint],gDiffRateGraphsOverBaseIT->GetY()[ipoint]);
+                       }
+                       ichannel++;
+               }
+       }
+  g2d->SetMinimum(0);
+  g2d->GetZaxis()->SetRangeUser(0,100);
+       return g2d;
+}
+
+TH2* get_2D_diff_over_thr_histo(std::shared_ptr<dirich>  dirichptr){
+       TH2D* histo;
+       TH2D* divided_histo;
+  // divided_histo->SetDirectory(0);
+       gStyle->SetOptStat(0);
+  if(dirichptr==NULL){
+    double max_value=-9999;
+       double min_value=9999;
+       double min_width=1000;
+    for (auto& dirichitem : dirichlist){
+               for(auto& gDiffRateGraphsOverBaseIT : dirichitem.second->gDiffRateGraphsOverBase){
+        if(gDiffRateGraphsOverBaseIT->GetN()!=0 && max_value<gDiffRateGraphsOverBaseIT->GetX()[gDiffRateGraphsOverBaseIT->GetN()-1]) max_value = gDiffRateGraphsOverBaseIT->GetX()[gDiffRateGraphsOverBaseIT->GetN()-1];
+                       if(gDiffRateGraphsOverBaseIT->GetN()!=0 && max_value<gDiffRateGraphsOverBaseIT->GetX()[gDiffRateGraphsOverBaseIT->GetN()-1]) max_value = gDiffRateGraphsOverBaseIT->GetX()[gDiffRateGraphsOverBaseIT->GetN()-1];
+                       if(gDiffRateGraphsOverBaseIT->GetN()>=2 && min_width>abs(gDiffRateGraphsOverBaseIT->GetX()[0]-gDiffRateGraphsOverBaseIT->GetX()[1])) min_width = abs(gDiffRateGraphsOverBaseIT->GetX()[0]-gDiffRateGraphsOverBaseIT->GetX()[1]);
+               }
+         }
+    histo = new TH2D("2D Differentiated Rate vs. Threshold over baseline of all diriches","2D Differentiated Rate vs. Threshold over baseline of all diriches",dirichlist.size()*NRCHANNELS,-.5,dirichlist.size()*NRCHANNELS-.5,max_value/min_width/2,0,max_value);
+    divided_histo = new TH2D("temp_diff","temp_diff",dirichlist.size()*NRCHANNELS,-.5,dirichlist.size()*NRCHANNELS-.5,max_value/min_width/2,0,max_value);
+               int idirich=0;
+               TLine* dirich_line_left = new TLine(histo->GetXaxis()->GetBinLowEdge(idirich*NRCHANNELS+1),histo->GetYaxis()->GetBinLowEdge(1),histo->GetXaxis()->GetBinLowEdge(idirich*NRCHANNELS+1),histo->GetYaxis()->GetBinUpEdge(histo->GetNbinsY()));
+               dirich_line_left->SetLineWidth(2);
+               dirich_line_left->SetLineColor(kRed);
+               histo->GetListOfFunctions()->Add(dirich_line_left);
+    for (auto& dirichitem : dirichlist){
+                       TLine* dirich_line_right = new TLine(histo->GetXaxis()->GetBinLowEdge((idirich+1)*NRCHANNELS+1),histo->GetYaxis()->GetBinLowEdge(1),histo->GetXaxis()->GetBinLowEdge((idirich+1)*NRCHANNELS+1),histo->GetYaxis()->GetBinUpEdge(histo->GetNbinsY()));
+                       dirich_line_right->SetLineWidth(2);     
+      dirich_line_right->SetLineColor(kRed);
+                       histo->GetListOfFunctions()->Add(dirich_line_right);
+       TText* dirich_name = new TText(histo->GetXaxis()->GetBinCenter((idirich+1./2)*NRCHANNELS+1),histo->GetYaxis()->GetBinLowEdge(1)-(0.1*(histo->GetYaxis()->GetBinLowEdge(1)-histo->GetYaxis()->GetBinUpEdge(histo->GetNbinsY()))),Form("0x%x",dirichitem.first));
+                       dirich_name->SetTextAlign(22);
+                       dirich_name->SetTextColor(kRed+2);
+                       dirich_name->SetTextFont(43);
+                       dirich_name->SetTextSize(20);
+                       histo->GetListOfFunctions()->Add(dirich_name);
+      for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+                               // std::cout << (int)dirichlist.size() << std::endl;
+       // std::cout << "dirich: " << std::hex << dirichitem.first << std::dec << "GetN " << dirichitem.second->gRateGraphs[ichannel]->GetN() << std::endl;
+       for(int ipoint=0;ipoint<dirichitem.second->gDiffRateGraphsOverBase[ichannel]->GetN();++ipoint){
+               // std::cout << idirich << " dirich " << std::hex << dirichitem.first << std::dec << " C " <<  ichannel << " P " << ipoint << " X " << dirichitem.second->gDiffRateGraphsOverBase[ichannel]->GetX()[ipoint] << " Y " << dirichitem.second->gDiffRateGraphsOverBase[ichannel]->GetY()[ipoint] << std::endl;
+               histo->Fill(idirich*NRCHANNELS+ichannel,dirichitem.second->gDiffRateGraphsOverBase[ichannel]->GetX()[ipoint],dirichitem.second->gDiffRateGraphsOverBase[ichannel]->GetY()[ipoint]);
+               divided_histo->Fill(idirich*NRCHANNELS+ichannel,dirichitem.second->gDiffRateGraphsOverBase[ichannel]->GetX()[ipoint]);
+               // std::cout << ichannel << " " << int(dirichlist.size()*NRCHANNELS/20+1) << std::endl;
+                                       if(ichannel%8==0) histo->GetXaxis()->SetBinLabel(idirich*NRCHANNELS+ichannel+1,Form("%i",ichannel));
+                                       else histo->GetXaxis()->SetBinLabel(idirich*NRCHANNELS+ichannel+1,"");
+       }
+                               TLine* thr_line = new TLine(histo->GetXaxis()->GetBinLowEdge(idirich*NRCHANNELS+ichannel+1),-1*dirichitem.second->GetSingleThresholdmV(ichannel),histo->GetXaxis()->GetBinUpEdge(idirich*NRCHANNELS+ichannel+1),-1*dirichitem.second->GetSingleThresholdmV(ichannel));
+                               thr_line->SetLineColor(kRed);
+                               thr_line->SetLineWidth(2);
+                               histo->GetListOfFunctions()->Add(thr_line);
+      }
+       ++idirich;
+    }
+    idirich=0;
+    // for (auto& dirichitem : dirichlist){
+    //   for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+    //         histo->SetBinContent(idirich*NRCHANNELS+ichannel+1,int(-1*dirichitem.second->GetSingleThresholdmV(ichannel)/histo->GetYaxis()->GetBinWidth(1))+1,-1);
+    //         divided_histo->SetBinContent(idirich*NRCHANNELS+ichannel+1,int(-1*dirichitem.second->GetSingleThresholdmV(ichannel)/histo->GetYaxis()->GetBinWidth(1))+1,1);
+    //   }
+    //   idirich++;
+    // }
+  }
+  else{
+       double max_value=0;
+       double min_width=10000;
+               for(auto& gDiffRateGraphsOverBaseIT : dirichptr->gDiffRateGraphsOverBase){
+                       if(gDiffRateGraphsOverBaseIT->GetN()!=0 && max_value<gDiffRateGraphsOverBaseIT->GetX()[gDiffRateGraphsOverBaseIT->GetN()-1]) max_value = gDiffRateGraphsOverBaseIT->GetX()[gDiffRateGraphsOverBaseIT->GetN()-1];
+                       if(gDiffRateGraphsOverBaseIT->GetN()>=2 && min_width>abs(gDiffRateGraphsOverBaseIT->GetX()[0]-gDiffRateGraphsOverBaseIT->GetX()[1])) min_width = abs(gDiffRateGraphsOverBaseIT->GetX()[0]-gDiffRateGraphsOverBaseIT->GetX()[1]);
+         }
+    histo = new TH2D(Form("2D Differentiated Rate vs. Threshold over baseline of %x",dirichptr->GetBoardAddress()),Form("2D Differentiated Rate vs. Threshold over baseline of %x",dirichptr->GetBoardAddress()),NRCHANNELS,-.5,NRCHANNELS-.5,max_value/min_width/2,0,max_value);
+    divided_histo = new TH2D("temp_diff","temp_diff",NRCHANNELS,-.5,NRCHANNELS-.5,max_value/min_width/2,0,max_value);
+         for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+                       for(int ipoint=0;ipoint<dirichptr->gDiffRateGraphsOverBase[ichannel]->GetN();++ipoint){
+       histo->Fill(ichannel,dirichptr->gDiffRateGraphsOverBase[ichannel]->GetX()[ipoint],dirichptr->gDiffRateGraphsOverBase[ichannel]->GetY()[ipoint]);
+       divided_histo->Fill(ichannel,dirichptr->gDiffRateGraphsOverBase[ichannel]->GetX()[ipoint]);
+                       }
+      TLine* thr_line = new TLine(histo->GetXaxis()->GetBinLowEdge(ichannel+1),-1*dirichptr->GetSingleThresholdmV(ichannel),histo->GetXaxis()->GetBinUpEdge(ichannel+1),-1*dirichptr->GetSingleThresholdmV(ichannel));
+      thr_line->SetLineColor(kRed);
+      thr_line->SetLineWidth(2);
+      histo->GetListOfFunctions()->Add(thr_line);
+         }
+    // for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+    //         histo->SetBinContent(ichannel+1,int(-1*dirichptr->GetSingleThresholdmV(ichannel)/histo->GetYaxis()->GetBinWidth(1))+1,-1);
+    //         divided_histo->SetBinContent(ichannel+1,int(-1*dirichptr->GetSingleThresholdmV(ichannel)/histo->GetYaxis()->GetBinWidth(1))+1,1);
+    // }
+       }
+       // std::cout << "finished histo" << std::endl;
+
+  histo->Divide(divided_histo);
+  
+  histo->Divide(divided_histo);
+  for(int ibin=1;ibin<(histo->GetNbinsX()+2)*(histo->GetNbinsY()+2);++ibin){
+    // if(histo->GetBinContent(ibin)<-1.)histo->SetBinContent(ibin,0);
+    histo->SetBinError(ibin,0);
+  }
+  histo->SetMinimum(0.);
+       // histo->GetZaxis()->SetRangeUser(0.,30.);
+       histo->GetXaxis()->SetTitle("Channel Nr");
+       // histo->GetXaxis()->SetTitleOffset();
+       histo->GetYaxis()->SetTitle("Threshold");
+       histo->GetZaxis()->SetTitle("Differentiated rate");
+  return histo;
+}
+
+TH2* get_2D_rate_over_thr_histo(std::shared_ptr<dirich>  dirichptr){
+       TH2D* histo;
+       TH2D* divided_histo;
+  // divided_histo->SetDirectory(0);
+       gStyle->SetOptStat(0);
+  if(dirichptr==NULL){
+    double max_value=-9999;
+       double min_value=9999;
+       double min_width=1000;
+    for (auto& dirichitem : dirichlist){
+               for(auto& gRateGraphsOverBaseIT : dirichitem.second->gRateGraphsOverBase){
+        if(gRateGraphsOverBaseIT->GetN()!=0 && max_value<gRateGraphsOverBaseIT->GetX()[gRateGraphsOverBaseIT->GetN()-1]) max_value = gRateGraphsOverBaseIT->GetX()[gRateGraphsOverBaseIT->GetN()-1];
+                       if(gRateGraphsOverBaseIT->GetN()!=0 && max_value<gRateGraphsOverBaseIT->GetX()[gRateGraphsOverBaseIT->GetN()-1]) min_value = gRateGraphsOverBaseIT->GetX()[0];
+                       if(gRateGraphsOverBaseIT->GetN()>=2 && min_width>abs(gRateGraphsOverBaseIT->GetX()[0]-gRateGraphsOverBaseIT->GetX()[1])) min_width = abs(gRateGraphsOverBaseIT->GetX()[0]-gRateGraphsOverBaseIT->GetX()[1]);
+               }
+         }
+    histo = new TH2D("2D Rate vs. Threshold over baseline of all diriches","2D Rate vs. Threshold over baseline of all diriches",dirichlist.size()*NRCHANNELS,-.5,dirichlist.size()*NRCHANNELS-.5,max_value/min_width/2,0,max_value);
+    divided_histo = new TH2D("temp_diff","temp_diff",dirichlist.size()*NRCHANNELS,-.5,dirichlist.size()*NRCHANNELS-.5,max_value/min_width/2,0,max_value);
+               int idirich=0;
+               TLine* dirich_line_left = new TLine(histo->GetXaxis()->GetBinLowEdge(idirich*NRCHANNELS+1),histo->GetYaxis()->GetBinLowEdge(1),histo->GetXaxis()->GetBinLowEdge(idirich*NRCHANNELS+1),histo->GetYaxis()->GetBinUpEdge(histo->GetNbinsY()));
+               dirich_line_left->SetLineWidth(2);
+               dirich_line_left->SetLineColor(kRed);
+               histo->GetListOfFunctions()->Add(dirich_line_left);
+    for (auto& dirichitem : dirichlist){
+                       TLine* dirich_line_right = new TLine(histo->GetXaxis()->GetBinLowEdge((idirich+1)*NRCHANNELS+1),histo->GetYaxis()->GetBinLowEdge(1),histo->GetXaxis()->GetBinLowEdge((idirich+1)*NRCHANNELS+1),histo->GetYaxis()->GetBinUpEdge(histo->GetNbinsY()));
+                       dirich_line_right->SetLineWidth(2);     
+      dirich_line_right->SetLineColor(kRed);
+                       histo->GetListOfFunctions()->Add(dirich_line_right);
+       TText* dirich_name = new TText(histo->GetXaxis()->GetBinCenter((idirich+1./2)*NRCHANNELS+1),histo->GetYaxis()->GetBinLowEdge(1)-(0.1*(histo->GetYaxis()->GetBinLowEdge(1)-histo->GetYaxis()->GetBinUpEdge(histo->GetNbinsY()))),Form("0x%x",dirichitem.first));
+                       dirich_name->SetTextAlign(22);
+                       dirich_name->SetTextColor(kRed+2);
+                       dirich_name->SetTextFont(43);
+                       dirich_name->SetTextSize(20);
+                       histo->GetListOfFunctions()->Add(dirich_name);
+      for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+                               // std::cout << (int)dirichlist.size() << std::endl;
+       // std::cout << "dirich: " << std::hex << dirichitem.first << std::dec << "GetN " << dirichitem.second->gRateGraphs[ichannel]->GetN() << std::endl;
+       for(int ipoint=0;ipoint<dirichitem.second->gRateGraphsOverBase[ichannel]->GetN();++ipoint){
+               // std::cout << idirich << " dirich " << std::hex << dirichitem.first << std::dec << " C " <<  ichannel << " P " << ipoint << " X " << dirichitem.second->gRateGraphsOverBase[ichannel]->GetX()[ipoint] << " Y " << dirichitem.second->gRateGraphsOverBase[ichannel]->GetY()[ipoint] << std::endl;
+               histo->Fill(idirich*NRCHANNELS+ichannel,dirichitem.second->gRateGraphsOverBase[ichannel]->GetX()[ipoint],dirichitem.second->gRateGraphsOverBase[ichannel]->GetY()[ipoint]);
+               divided_histo->Fill(idirich*NRCHANNELS+ichannel,dirichitem.second->gRateGraphsOverBase[ichannel]->GetX()[ipoint]);
+               // std::cout << ichannel << " " << int(dirichlist.size()*NRCHANNELS/20+1) << std::endl;
+                                       if(ichannel%8==0) histo->GetXaxis()->SetBinLabel(idirich*NRCHANNELS+ichannel+1,Form("%i",ichannel));
+                                       else histo->GetXaxis()->SetBinLabel(idirich*NRCHANNELS+ichannel+1,"");
+       }
+                               TLine* thr_line = new TLine(histo->GetXaxis()->GetBinLowEdge(idirich*NRCHANNELS+ichannel+1),-1*dirichitem.second->GetSingleThresholdmV(ichannel),histo->GetXaxis()->GetBinUpEdge(idirich*NRCHANNELS+ichannel+1),-1*dirichitem.second->GetSingleThresholdmV(ichannel));
+                               thr_line->SetLineColor(kRed);
+                               thr_line->SetLineWidth(2);
+                               histo->GetListOfFunctions()->Add(thr_line);
+      }
+       ++idirich;
+    }
+    idirich=0;
+    // for (auto& dirichitem : dirichlist){
+    //   for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+    //         histo->SetBinContent(idirich*NRCHANNELS+ichannel+1,int(-1*dirichitem.second->GetSingleThresholdmV(ichannel)/histo->GetYaxis()->GetBinWidth(1))+1,-1);
+    //         divided_histo->SetBinContent(idirich*NRCHANNELS+ichannel+1,int(-1*dirichitem.second->GetSingleThresholdmV(ichannel)/histo->GetYaxis()->GetBinWidth(1))+1,1);
+    //   }
+    //   idirich++;
+    // }
+  }
+  else{
+       double max_value=0;
+       double min_width=1000;
+               for(auto& gRateGraphsOverBaseIT : dirichptr->gRateGraphsOverBase){
+                       if(gRateGraphsOverBaseIT->GetN()!=0 && max_value<gRateGraphsOverBaseIT->GetX()[gRateGraphsOverBaseIT->GetN()-1]) max_value = gRateGraphsOverBaseIT->GetX()[gRateGraphsOverBaseIT->GetN()-1];
+                       if(gRateGraphsOverBaseIT->GetN()>=2 && min_width>abs(gRateGraphsOverBaseIT->GetX()[0]-gRateGraphsOverBaseIT->GetX()[1])) min_width = abs(gRateGraphsOverBaseIT->GetX()[0]-gRateGraphsOverBaseIT->GetX()[1]);
+         }
+    histo = new TH2D(Form("2D Rate vs. Threshold over baseline of %x",dirichptr->GetBoardAddress()),Form("2D Rate vs. Threshold over baseline of %x",dirichptr->GetBoardAddress()),NRCHANNELS,-.5,NRCHANNELS-.5,max_value/min_width/2,0,max_value);
+    divided_histo = new TH2D("temp_diff","temp_diff",NRCHANNELS,-.5,NRCHANNELS-.5,max_value/min_width/2,0,max_value);
+         for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+                       for(int ipoint=0;ipoint<dirichptr->gRateGraphsOverBase[ichannel]->GetN();++ipoint){
+       histo->Fill(ichannel,dirichptr->gRateGraphsOverBase[ichannel]->GetX()[ipoint],dirichptr->gRateGraphsOverBase[ichannel]->GetY()[ipoint]);
+       divided_histo->Fill(ichannel,dirichptr->gRateGraphsOverBase[ichannel]->GetX()[ipoint]);
+                       }
+      TLine* thr_line = new TLine(histo->GetXaxis()->GetBinLowEdge(ichannel+1),-1*dirichptr->GetSingleThresholdmV(ichannel),histo->GetXaxis()->GetBinUpEdge(ichannel+1),-1*dirichptr->GetSingleThresholdmV(ichannel));
+      thr_line->SetLineColor(kRed);
+      thr_line->SetLineWidth(2);
+      histo->GetListOfFunctions()->Add(thr_line);
+         }
+    // for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+    //         histo->SetBinContent(ichannel+1,int(-1*dirichptr->GetSingleThresholdmV(ichannel)/histo->GetYaxis()->GetBinWidth(1))+1,-1);
+    //         divided_histo->SetBinContent(ichannel+1,int(-1*dirichptr->GetSingleThresholdmV(ichannel)/histo->GetYaxis()->GetBinWidth(1))+1,1);
+    // }
+       }
+       // std::cout << "finished histo" << std::endl;
+
+  histo->Divide(divided_histo);
+
+       histo->SetMinimum(0);
+       histo->GetXaxis()->SetTitle("Channel Nr");
+       // histo->GetXaxis()->SetTitleOffset();
+       histo->GetYaxis()->SetTitle("Threshold");
+       histo->GetZaxis()->SetTitle("Rate");
+  return histo;
+}
+
+TH1* get_noisewidth_histo(std::shared_ptr<dirich>  dirichptr){
+  TH1* histo;
+  if(dirichptr==NULL){
+    histo = new TH1D("Noisewidthhistogram of all diriches","Noisewidthhistogram of all diriches",dirichlist.size()*NRCHANNELS,-.5,dirichlist.size()*NRCHANNELS-.5);
+               int idirich=0;
+    for (auto& dirichitem : dirichlist){
+       TText* dirich_name = new TText(histo->GetXaxis()->GetBinCenter((idirich+1./2)*NRCHANNELS+1),histo->GetYaxis()->GetBinLowEdge(1)-(0.1*histo->GetYaxis()->GetBinLowEdge(1)-histo->GetYaxis()->GetBinUpEdge(histo->GetNbinsY())),Form("0x%x",dirichitem.first));
+                       dirich_name->SetTextAlign(22);
+                       dirich_name->SetTextColor(kRed+2);
+                       dirich_name->SetTextFont(43);
+                       dirich_name->SetTextSize(20);
+                       histo->GetListOfFunctions()->Add(dirich_name);
+      for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+        histo->SetBinContent(idirich*NRCHANNELS+ichannel+1,dirich::Thr_DtomV(dirichitem.second->GetSingleNoisewidth(ichannel)));
+                               if(ichannel%8==0) histo->GetXaxis()->SetBinLabel(idirich*NRCHANNELS+ichannel+1,Form("%i",ichannel));
+                               else histo->GetXaxis()->SetBinLabel(idirich*NRCHANNELS+ichannel+1,"");
+      }
+       ++idirich;
+    }
+               TLine* dirich_line_left = new TLine(histo->GetXaxis()->GetBinLowEdge(1),histo->GetYaxis()->GetBinLowEdge(1),histo->GetXaxis()->GetBinLowEdge(1),histo->GetMaximum()*1.05);
+               dirich_line_left->SetLineWidth(2);
+               dirich_line_left->SetLineColor(kRed);
+               histo->GetListOfFunctions()->Add(dirich_line_left);
+    for(int i=0;i<idirich;++i){
+                       TLine* dirich_line_right = new TLine(histo->GetXaxis()->GetBinLowEdge((i+1)*NRCHANNELS+1),histo->GetYaxis()->GetBinLowEdge(1),histo->GetXaxis()->GetBinLowEdge((i+1)*NRCHANNELS+1),histo->GetMaximum()*1.05);
+                       dirich_line_right->SetLineWidth(2);     
+      dirich_line_right->SetLineColor(kRed);
+                       histo->GetListOfFunctions()->Add(dirich_line_right);            
+    }
+  }
+  else{
+         histo = new TH1D(Form("Noisewidthhistogram of %x",dirichptr->GetBoardAddress()),Form("Noisewidthhistogram of %x",dirichptr->GetBoardAddress()),NRCHANNELS,-.5,NRCHANNELS-.5);
+         for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+           histo->SetBinContent(ichannel+1,(dirich::Thr_DtomV(dirichptr->GetSingleNoisewidth(ichannel))));
+         }
+       }
+
+  histo->GetYaxis()->SetTitle("NoisewidthinmV");
+  histo->SetMinimum(0);
+  histo->GetXaxis()->SetTitle("Channel Nr");
+  return histo;
+}
+
+TH1* get_diff_histo(std::shared_ptr<dirich>  dirichptr, bool baseline1_noisewidth0){
+       TH1* histo;
+  if(dirichptr==NULL){
+       if(baseline1_noisewidth0==1) histo = new TH1D("Difference in baseline of all diriches","Difference in baseline of all diriches",dirichlist.size()*200,-300,+300);
+       else histo = new TH1D("Difference in noisewidth of all diriches","Difference in noisewidth of all diriches",dirichlist.size()*200,-300,+300);
+               int idirich=0;
+    for (auto& dirichitem : dirichlist){
+      for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+        if(baseline1_noisewidth0==1) histo->Fill(dirichitem.second->GetSingleBaseline(ichannel)-dirichitem.second->GetSingleBaseline_old(ichannel));
+        else histo->Fill(dirichitem.second->GetSingleNoisewidth(ichannel)-dirichitem.second->GetSingleNoisewidth_old(ichannel));
+      }
+    }
+       ++idirich;
+  }
+  else{
+       if(baseline1_noisewidth0==1) histo = new TH1D(Form("Difference in baseline of %x",dirichptr->GetBoardAddress()),Form("Difference in baseline of %x",dirichptr->GetBoardAddress()),200,-300,+300);
+       else histo = new TH1D(Form("Difference in noisewidth of %x",dirichptr->GetBoardAddress()),Form("Difference in noisewidth of %x",dirichptr->GetBoardAddress()),200,-300,+300);
+         for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+      if(baseline1_noisewidth0==1) histo->Fill(dirichptr->GetSingleBaseline(ichannel)-dirichptr->GetSingleBaseline_old(ichannel));
+      else histo->Fill(dirichptr->GetSingleNoisewidth(ichannel)-dirichptr->GetSingleNoisewidth_old(ichannel));
+         }
+       }
+
+  histo->GetYaxis()->SetTitle("Number of");
+  if(baseline1_noisewidth0==1) histo->GetXaxis()->SetTitle("Difference between old and new baseline");
+  else histo->GetXaxis()->SetTitle("Difference between old and new noisewidth");
+  return histo;
+}
+
+void clear_canvas_vector(){
+       while(canvasvector.size()!=0){
+               if(canvasvector.back()==NULL){
+                       std::cout <<  "1" << std::endl;
+                       canvasvector.pop_back();
+               }
+               else{
+                       std::cout <<  "2" << std::endl;
+                       canvasvector.back()->Clear();
+                       std::cout <<  "3" << std::endl;
+                       canvasvector.back()->Close();
+                       std::cout <<  "4" << std::endl;
+                       canvasvector.back()->Closed();
+                       std::cout <<  "5" << std::endl;
+                       delete canvasvector.back();
+                       std::cout <<  "6" << std::endl;
+                       canvasvector.back()=NULL;
+                       std::cout <<  "7" << std::endl;
+                       canvasvector.pop_back();
+                       std::cout <<  "8" << std::endl;
+               }
+       }
+}
+
+void draw_multigraph2D(TMultiGraph* multigraph,TCanvas* canvas){
+       if(canvas==0){
+               canvasvector.emplace_back(new TCanvas(Form("Canvas%i",(int)canvasvector.size()),Form("Canvas%i",(int)canvasvector.size()),1920,1080));
+               canvasvector.back()->cd(0);
+       }
+       else{
+         canvas->cd(0);
+       }
+  multigraph->Draw("a fb l3d");
+  gPad->SetTheta(0);
+  gPad->SetPhi(-90);
+  gPad->Update();
+  if(canvas==0){
+    canvasvector.back()->Modified();
+    canvasvector.back()->Update();
+  }
+  else{
+    canvas->Modified();
+    canvas->Update();
+  }
+}
+
+void draw_multigraph(TMultiGraph* multigraph,TCanvas* canvas){
+  if(canvas==0){
+    canvasvector.emplace_back(new TCanvas(Form("Canvas%i",(int)canvasvector.size()),Form("Canvas%i",(int)canvasvector.size()),1920,1080));
+    canvasvector.back()->cd(0);
+  }
+  else{
+    canvas->cd(0);
+  }
+  multigraph->Draw("alp");
+  double max_value = 0;
+  for(auto&& graph : (*multigraph->GetListOfGraphs())){
+    for(int i=10 ; i < ((TGraph*)graph)->GetN() ; ++i){
+      max_value = ((TGraph*)graph)->GetY()[i] > max_value ? ((TGraph*)graph)->GetY()[i] : max_value;
+    }
+  }
+  // std::cout << "max_value" << max_value << std::endl;
+  multigraph->GetHistogram()->GetYaxis()->SetRangeUser(0,max_value==0 ? 100 : max_value*1.05);
+  if(canvas==0){
+    canvasvector.back()->Modified();
+    canvasvector.back()->Update();
+  }
+  else{
+    canvas->Modified();
+    canvas->Update();
+  }
+}
+
+void draw_graph2D(TGraph2D* graph2d,TCanvas* canvas){
+       if(canvas==0){
+               canvasvector.emplace_back(new TCanvas(Form("Canvas%i",(int)canvasvector.size()),Form("Canvas%i",(int)canvasvector.size()),1920,1080));
+               canvasvector.back()->cd(0);
+       }
+       else{
+         canvas->cd(0);
+       }
+  graph2d->Draw("surf1");
+  gPad->SetTheta(0);
+  gPad->SetPhi(-90);
+  gPad->Update();  
+  if(canvas==0){
+    canvasvector.back()->Modified();
+    canvasvector.back()->Update();
+  }
+  else{
+    canvas->Modified();
+    canvas->Update();
+  }
+}
+
+void draw_histo(TH1* histo,TCanvas* canvas){
+       if(canvas==0){
+               canvasvector.emplace_back(new TCanvas(Form("Canvas%i",(int)canvasvector.size()),Form("Canvas%i",(int)canvasvector.size()),1920,1080));
+               canvasvector.back()->cd(0);
+       }
+       else{
+         canvas->cd(0);
+       }
+  histo->Draw();
+  if(canvas==0){
+    canvasvector.back()->Modified();
+    canvasvector.back()->Update();
+  }
+  else{
+    canvas->Modified();
+    canvas->Update();
+  }
+}
+
+void draw_histo(TH2* histo,TCanvas* canvas){
+       if(canvas==0){
+               canvasvector.emplace_back(new TCanvas(Form("Canvas%i",(int)canvasvector.size()),Form("Canvas%i",(int)canvasvector.size()),1920,1080));
+               canvasvector.back()->cd(0);
+       }
+       else{
+         canvas->cd(0);
+       }
+  histo->Draw("COLZ");
+  if(canvas==0){
+    canvasvector.back()->Modified();
+    canvasvector.back()->Update();
+  }
+  else{
+    canvas->Modified();
+    canvas->Update();
+  }
+}
+
+void set_thresholds(std::shared_ptr<dirich> dirichptr, double thrinmV=30.)
+{
+  if(dirichptr==0){
+       // std::cout << "setting threshold for all diriches: " << std::endl;
+    for (auto& dirichlistitem: dirichlist){
+      set_thresholds(dirichlistitem.second, thrinmV);
+    }
+  }
+  else if(dirichlist.find(dirichptr->GetBoardAddress())!=dirichlist.end()){
+    // if(thrinmV>0.){
+      // std::cerr << "positive thresholds are not \"allowed\"!\ninverting value" << std::endl;
+      // thrinmV = -1*thrinmV;
+    // }
+       // std::cout << "setting threshold for dirich: " << std::hex << dirichptr->GetBoardAddress() << std::endl;
+    for (int ichannel=0; ichannel<NRCHANNELS; ++ichannel) {
+      dirichptr->SetSingleThresholdmV(ichannel ,thrinmV); 
+    }
+  // draw_graphs(dirichptr, canvaslist.at(dirichptr->GetBoardAddress()), makechannelvector(0,31), 1, 1, 1, 1);
+  }
+}
+
+void set_thresholds(std::shared_ptr<dirich> dirichptr, double* thrinmV)
+{
+  if(dirichptr==0){
+       std::cout << "setting threshold for all diriches: " << std::endl;
+    for (auto& dirichlistitem: dirichlist){
+      set_thresholds(dirichlistitem.second, thrinmV);
+    }
+  }
+  else if(dirichlist.find(dirichptr->GetBoardAddress())!=dirichlist.end()){
+    if (!std::all_of(thrinmV, thrinmV+32, [](double i){ return i > 0.; })) {
+      std::cerr << "positive thresholds are not \"allowed\"!\ncanceling set_thresholds" << std::endl;
+      return;
+    }
+       std::cout << "setting threshold for dirich: " << std::hex << dirichptr->GetBoardAddress() << std::endl;
+    for (int ichannel=0; ichannel<NRCHANNELS; ++ichannel) {
+               dirichptr->SetSingleThresholdmV(ichannel ,thrinmV[ichannel]); 
+       }
+    // draw_graphs(dirichptr, canvaslist.at(dirichptr->GetBoardAddress()), makechannelvector(0,31), 1, 1, 1, 1);
+  }
+}
+
+void save_base(std::shared_ptr<dirich>  dirichptr, std::string filename, bool append){
+       std::ofstream file;
+  if(append) file.open(filename+".thr", std::ios_base::app);
+       else file.open(filename+".thr");
+
+       if(!file) std::cerr << "File for saving (" << filename+".thr" << ") could not be opened!" << std::endl;
+
+       if(dirichptr==NULL){
+       for (auto& dirichlistitem: dirichlist){
+                       file << "# Scan-Settings for 0x" << std::hex << dirichlistitem.first << std::dec << "\n# gMeasureTime\tgLowerEdge\tgUpperEdge\tgStepsize\tgNrPasses\tgMeasureTime_over\tgUpperEdge_over\tgStepsize_over\tgNrPasses_over" << std::endl;
+                       file << "# " << dirichlistitem.second->gMeasureTime << "\t" << dirichlistitem.second->gLowerEdge << "\t" << dirichlistitem.second->gUpperEdge << "\t" << dirichlistitem.second->gStepsize << "\t" << dirichlistitem.second->gNrPasses << "\t" << dirichlistitem.second->gMeasureTime_over << "\t" << dirichlistitem.second->gUpperEdge_over << "\t" << dirichlistitem.second->gStepsize_over << "\t" << dirichlistitem.second->gNrPasses_over << std::endl;
+                       file << "# Scan-Data\n# dirich\tchannel\tbaseline\twidth in mV\tthreshold in mV over baseline" << std::endl;
+                 for (int ichannel=0; ichannel<NRCHANNELS; ichannel++) {
+                       file  
+                       << std::hex << dirichlistitem.first << std::dec << "\t" 
+                       << ichannel << "\t" 
+                       << dirichlistitem.second->GetSingleBaseline(ichannel) << "\t" 
+                       << dirich::Thr_DtomV(dirichlistitem.second->GetSingleNoisewidth(ichannel)) << "\t" 
+                       << dirichlistitem.second->GetSingleThresholdmV(ichannel) 
+                       << std::endl;
+               }
+       }
+       }
+       else{
+               file << "# Scan-Settings for 0x" << std::hex << dirichptr->GetBoardAddress() << std::dec << "\n# gMeasureTime\tgLowerEdge\tgUpperEdge\tgStepsize\tgNrPasses\tgMeasureTime_over\tgUpperEdge_over\tgStepsize_over\tgNrPasses_over" << std::endl;
+               file << "# " << dirichptr->gMeasureTime << "\t" << dirichptr->gLowerEdge << "\t" << dirichptr->gUpperEdge << "\t" << dirichptr->gStepsize << "\t" << dirichptr->gNrPasses << "\t" << dirichptr->gMeasureTime_over << "\t" << dirichptr->gUpperEdge_over << "\t" << dirichptr->gStepsize_over << "\t" << dirichptr->gNrPasses_over << std::endl;
+               file << "# Scan-Data\n# dirich\tchannel\tbaseline\twidth in mV\tthreshold in mV over baseline" << std::endl;
+               for (int ichannel=0; ichannel<NRCHANNELS; ichannel++) {
+                       file  
+                       << std::hex << dirichptr->GetBoardAddress() << std::dec << "\t" 
+                       << ichannel << "\t" 
+                       << dirichptr->GetSingleBaseline(ichannel) << "\t" 
+                       << dirich::Thr_DtomV(dirichptr->GetSingleNoisewidth(ichannel)) << "\t" 
+                       << dirichptr->GetSingleThresholdmV(ichannel) 
+                       << std::endl;
+               }
+       }
+}
+
+void load_base(std::shared_ptr<dirich>  dirichptr, std::string filename, bool uselast, bool set_base, bool set_thr){
+       std::string dirichaddress_string="";
+       uint16_t dirichaddress=0;
+  int channel=0;
+  int baseline=0;
+  double width=0;
+  double thresholdinmV=0;
+       for (auto& dirichlistitem: dirichlist){
+               if(dirichlistitem.second==NULL){
+                       std::cerr << "dirich 0x" << std::hex << dirichlistitem.first << std::dec << " was found uninitialized\nRun initialize_diriches(1/0) first!" << std::endl;
+                       return;
+               }
+       }
+       std::ifstream file;
+       file.open(filename);
+       if(!file) std::cerr << "File for loading (" << filename << ") could not be opened!" << std::endl;
+       if(dirichptr==NULL){
+               while(!file.eof()){
+                       std::string line;
+                       std::getline(file, line);
+                 std::istringstream iss(line);
+                 iss >> dirichaddress_string;
+                 if(dirichaddress_string=="#"){
+                       std::string dummy;
+                       std::getline(iss,dummy);
+                       continue;
+                 }
+                 iss >> channel >> baseline >> width >> thresholdinmV;
+                 if(iss.tellg()!=-1) std::cerr << "Error reading line:\n" << line << "\nRead in:" << "\ndirichaddress:0x" << dirichaddress_string << "\nchannel:" << channel << "\nbaseline:" << baseline << "\nwidth:" << width << "\nthresholdinmV:" << thresholdinmV << std::endl;
+                       else{
+       dirichaddress = (uint16_t)stoi(dirichaddress_string,0,16);
+        // std::cout << "0x" << dirichaddress_string << " " << std::hex << dirichaddress << std::dec <<  " " << channel << " " << baseline << std::endl;
+                               if(dirichlist.count(dirichaddress)!=0){
+          if(set_base!=0){
+            dirichlist.at(dirichaddress)->SetSingleBaseline_old(channel, dirichlist.at(dirichaddress)->GetSingleBaseline(channel));
+            dirichlist.at(dirichaddress)->SetSingleBaseline(channel, baseline);
+
+            dirichlist.at(dirichaddress)->SetSingleNoisewidth_old(channel, dirichlist.at(dirichaddress)->GetSingleNoisewidth(channel));
+            dirichlist.at(dirichaddress)->SetSingleNoisewidth(channel, dirich::Thr_mVtoD(width));
+          }
+          if(set_thr!=0) dirichlist.at(dirichaddress)->SetSingleThresholdmV(channel, thresholdinmV);
+        }
+                               else{ 
+                                       std::cerr << "dirich 0x" << std::hex << dirichaddress << std::dec << " was not found in list of initialized diriches" << std::endl;
+                                       continue;
+                               }
+                       }
+               }
+       for (auto& dirichlistitem: dirichlist){
+               for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+                       if(dirichlistitem.second->GetSingleBaseline(ichannel)==0) std::cerr << "No Baseline for dirich 0x" << std::hex << dirichlistitem.first << std::dec << "'s channel " << ichannel << " found in loading-file" << std::endl;
+               }
+       }
+       }
+       else if(uselast){
+    if(set_base!=0){
+      for(int ichannel=0;ichannel<32;++ichannel){
+        dirichptr->SetSingleBaseline_old(ichannel, dirichptr->GetSingleBaseline(ichannel));
+        dirichptr->SetSingleNoisewidth_old(ichannel, dirichptr->GetSingleNoisewidth(ichannel));
+      }
+    }
+               while(!file.eof()){
+                       std::string line;
+                       std::getline(file, line);
+                 std::istringstream iss(line);
+                 iss >> dirichaddress_string;
+                 if(dirichaddress_string=="#"){
+                       std::string dummy;
+                       std::getline(iss,dummy);
+                       continue;
+                 }
+                 iss >> channel >> baseline >> width >> thresholdinmV;
+                 if(iss.tellg()!=-1) std::cerr << "Error reading line:\n" << line << "\nRead in:" << "\ndirichaddress:0x" << dirichaddress_string << "\nchannel:" << channel << "\nbaseline:" << baseline << "\nwidth:" << width << "\nthresholdinmV:" << thresholdinmV << std::endl;
+                       else{
+        if(set_base!=0){
+                                 dirichptr->SetSingleBaseline(channel, baseline);
+                                 dirichptr->SetSingleNoisewidth(channel, dirich::Thr_mVtoD(width));
+        }
+        if(set_thr!=0) dirichptr->SetSingleThresholdmV(channel, thresholdinmV);
+                       }
+               }
+       }
+  else{
+    if(set_base!=0){
+      for(int ichannel=0;ichannel<32;++ichannel){
+        dirichptr->SetSingleBaseline_old(ichannel, dirichptr->GetSingleBaseline(ichannel));
+        dirichptr->SetSingleNoisewidth_old(ichannel, dirichptr->GetSingleNoisewidth(ichannel));
+      } 
+    }   
+    while(!file.eof()){
+      std::string line;
+      std::getline(file, line);
+      std::istringstream iss(line);
+                 iss >> dirichaddress_string;
+                 if(dirichaddress_string=="#"){
+                       std::string dummy;
+                       std::getline(iss,dummy);
+                       continue;
+                 }
+                 iss >> channel >> baseline >> width >> thresholdinmV;
+       dirichaddress = (uint16_t)stoi(dirichaddress_string,0,16);
+      if(iss.tellg()!=-1) std::cerr << "Error reading line:\n" << line << "\nRead in:" << "\ndirichaddress:0x" << dirichaddress_string << "\nchannel:" << channel << "\nbaseline:" << baseline << "\nwidth:" << width << "\nthresholdinmV:" << thresholdinmV << std::endl;
+      else if(dirichaddress==dirichptr->GetBoardAddress()){
+        if(set_base!=0){
+          dirichptr->SetSingleBaseline(channel, baseline);
+                                 dirichptr->SetSingleNoisewidth(channel, dirich::Thr_mVtoD(width));
+        }
+        if(set_thr!=0) dirichptr->SetSingleThresholdmV(channel, thresholdinmV);
+      }
+    }
+  }
+}
+
+void save_graphs(std::shared_ptr<dirich>  dirichptr, std::string filename){
+       TFile* file=new TFile(Form("%s.root", filename.c_str()),"RECREATE");
+  if(dirichptr==NULL){
+       file->cd();
+               get_noisewidth_histo(0)->Write();
+               get_2D_rate_histo(0)->Write();
+               get_2D_rate_over_thr_histo(0)->Write();
+               get_2D_diff_over_thr_histo(0)->Write();
+               get_2D_gr_diff_over_thr_histo(0)->Write();
+               get_2D_mgr_diff_over_thr_histo(0)->Write();
+    for (auto& dirichlistitem: dirichlist) {
+       std::cout << "saving graphs of 0x" << std::hex << dirichlistitem.first << std::dec << std::endl;
+                       TDirectory *dirich_dir = file->mkdir(Form("dirich_0x%x",dirichlistitem.first));
+                       dirich_dir->cd();
+                       get_noisewidth_histo(dirichlistitem.second)->Write();
+                       get_2D_rate_histo(dirichlistitem.second)->Write();
+                       get_2D_rate_over_thr_histo(dirichlistitem.second)->Write();                     
+                       get_2D_diff_over_thr_histo(dirichlistitem.second)->Write();
+                       get_2D_gr_diff_over_thr_histo(dirichlistitem.second)->Write();
+                       get_2D_mgr_diff_over_thr_histo(dirichlistitem.second)->Write();                 
+                       TDirectory *channels = dirich_dir->mkdir("channels");
+                       channels->cd();
+                       for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+                               TDirectory *ch = channels->mkdir(Form("ch:%i",ichannel));
+                               ch->cd();
+                               dirichlistitem.second->gRateGraphs[ichannel]->Write();
+                               dirichlistitem.second->gRateGraphsOverBase[ichannel]->Write();
+                               dirichlistitem.second->gDiffRateGraphsOverBase[ichannel]->Write();
+                       }
+               }
+       }
+  else{
+       file->cd();
+       TDirectory *dirich_dir = file->mkdir(Form("dirich_0x%x",dirichptr->GetBoardAddress()));
+               dirich_dir->cd();
+               get_noisewidth_histo(dirichptr)->Write();
+               get_2D_rate_histo(dirichptr)->Write();
+               get_2D_rate_over_thr_histo(dirichptr)->Write();                 
+               get_2D_diff_over_thr_histo(dirichptr)->Write();
+               get_2D_gr_diff_over_thr_histo(dirichptr)->Write();
+               get_2D_mgr_diff_over_thr_histo(dirichptr)->Write();                     
+               TDirectory *channels = dirich_dir->mkdir("channels");
+               channels->cd();
+               for(int ichannel=0;ichannel<NRCHANNELS;++ichannel){
+                       TDirectory *ch = channels->mkdir(Form("ch:%i",ichannel));
+                       ch->cd();
+                       dirichptr->gRateGraphs[ichannel]->Write();
+                       dirichptr->gRateGraphsOverBase[ichannel]->Write();
+                       dirichptr->gDiffRateGraphsOverBase[ichannel]->Write();
+               }
+  }
+  file->Close();
+}
+
+void save(){
+  std::array<char, 64> buffer;
+  buffer.fill(0);
+  time_t rawtime;
+  time(&rawtime);
+  const auto timeinfo = localtime(&rawtime);
+  strftime(buffer.data(), sizeof(buffer), "%Y%m%d_%H%M%S", timeinfo);
+  std::string str = std::string(buffer.data()) + "_std_save";
+  // std::string str = "./save/"+ string(buffer.data()) + "_std_save";
+
+  // auto t = std::time(nullptr);
+  // auto tm = *std::localtime(&t);
+
+  // std::ostringstream oss;
+  // oss << std::put_time(&tm, "%Y%m%d_%H%M%S") << "_std_save.dico";
+  // auto str = oss.str();
+  save_base(NULL,str,0);
+  save_graphs(NULL,str);
+}
+
+void* scanthread_baseline(void* dirichptr) //Argument is pointer to DiRICH class instance
+{
+  TThread::Printf("Starting baseline for Dirich at address 0x%x",((dirich*)dirichptr)->GetBoardAddress());
+       ((dirich*)dirichptr)->DoBaselineScan();
+  TThread::Printf("Threshold scan for Dirich at address 0x%x done ! ",((dirich*)dirichptr)->GetBoardAddress()); 
+  return 0;
+}
+
+void* scanthread_nrml(void* dirichptr) //Argument is pointer to DiRICH class instance
+{
+  TThread::Printf("Starting threshscan for Dirich at address 0x%x",((dirich*)dirichptr)->GetBoardAddress());
+       std::cout << "DoThreshScan" << std::endl;
+       ((dirich*)dirichptr)->DoThreshScan();
+       std::cout << "AnalyzeBaseline" << std::endl;
+       ((dirich*)dirichptr)->AnalyzeBaseline();
+       std::cout << "MakeGraphsOverBase" << std::endl;
+       ((dirich*)dirichptr)->MakeGraphsOverBase();
+  std::cout << "MakeDiffGraphsOverBase" << std::endl;
+  ((dirich*)dirichptr)->MakeDiffGraphsOverBase();
+  TThread::Printf("Threshold scan for Dirich at address 0x%x done ! ",((dirich*)dirichptr)->GetBoardAddress()); 
+  return 0;
+}
+
+void* scanthread_over(void* dirichptr) //Argument is pointer to DiRICH class instance
+{
+  TThread::Printf("Starting threshscan_over for Dirich at address 0x%x",((dirich*)dirichptr)->GetBoardAddress());
+       ((dirich*)dirichptr)->DoThreshScanOverBase();
+  ((dirich*)dirichptr)->MakeDiffGraphsOverBase();
+  TThread::Printf("Threshold scan for Dirich at address 0x%x done ! ",((dirich*)dirichptr)->GetBoardAddress()); 
+  return 0;
+}
+
+void* scanthread_thr(void* dirichptr) //Argument is pointer to DiRICH class instance
+{
+  TThread::Printf("Starting threshsearch for Dirich at address 0x%x",((dirich*)dirichptr)->GetBoardAddress());
+  ((dirich*)dirichptr)->DoThreshSearch();
+  TThread::Printf("Threshold search for Dirich at address 0x%x done ! ",((dirich*)dirichptr)->GetBoardAddress()); 
+  return 0;
+}
+
+// void* scanthread_std(void* dirichptr) //Argument is pointer to DiRICH class instance
+// {
+//   TThread::Printf("Starting threshscan for Dirich at address 0x%x",((dirich*)dirichptr)->GetBoardAddress());
+//     ((dirich*)dirichptr)->DoThreshScan();
+//   // ((dirich*)dirichptr)->MakeDiffGraphsOverBase();
+//   TThread::Printf("Threshold scan for Dirich at address 0x%x done ! ",((dirich*)dirichptr)->GetBoardAddress()); 
+//   return 0;
+// }
+
+// void single_thr_scan(int type=0, std::shared_ptr<dirich>  dirich_to_scan=NULL){
+//     int ret=0;
+//     if(dirich_to_scan==NULL){
+//     std::cerr << "DiRICH not initialized!" << std::endl;
+//     return;
+//   } 
+
+//   uint32_t TDC_setting[2];
+//   ret=trb_register_read(dirich_to_scan->GetBoardAddress(), 0xc802, TDC_setting, 2); //switch off TDC
+//   if(ret==-1){
+//     std::cerr << "Reading TDCs status failed for dirich " << std::hex << dirich_to_scan->GetBoardAddress() << std::dec << " -> TDC for that dirich will be left switched off" << std::endl;
+//   }
+
+//   ret=trb_register_write(dirich_to_scan->GetBoardAddress(), 0xc802, 0x00000000); //switch off TDC
+//   if(ret==-1){
+//     std::cerr << "Switching off TDCs failed for dirich " << std::hex << dirich_to_scan->GetBoardAddress() << std::dec << " -> Interupting baselinescan" << std::endl;
+//     // return;
+//   }
+
+//     TThread* thread;
+//   switch(type){
+//   case 1:
+//     thread = new TThread(Form("Thread_%i",(int)dirich_to_scan->GetBoardAddress()), scanthread_baseline, (void*) dirich_to_scan);
+//     break;
+//   case 2:
+//     thread = new TThread(Form("Thread_%i",(int)dirich_to_scan->GetBoardAddress()), scanthread_thr, (void*) dirich_to_scan);
+//     break;
+//   case 3:
+//     thread = new TThread(Form("Thread_%i",(int)dirich_to_scan->GetBoardAddress()), scanthread_over, (void*) dirich_to_scan);
+//     break;
+//   case 0:
+//   default:
+//     thread = new TThread(Form("Thread_%i",(int)dirich_to_scan->GetBoardAddress()), scanthread_nrml, (void*) dirich_to_scan);
+//     break;
+//   }
+//   usleep(1000);
+//   thread->Run(); 
+//   printf("Waiting: \n");
+//     usleep(1000);
+  
+//   thread->Join();
+//   thread->Delete();
+
+//   printf("System scan done ! \n");
+//   switch(type){
+//   case 1:
+//     save();
+//     break;
+//   case 2:
+//     save();
+//     break;
+//   case 3:
+//     save();
+//     break;          
+//   case 0:
+//   default:
+//     save();
+//     break;
+//   }
+
+//   ret=trb_register_write(dirich_to_scan->GetBoardAddress(), 0xc802, TDC_setting[1]);
+//   if(ret==-1){
+//     std::cerr << "Switching on TDCs failed for dirich: " << std::hex << dirich_to_scan->GetBoardAddress() << std::dec << std::endl;
+//   }
+
+// }
+
+void system_thr_scan(int type=0)
+{
+       int ret=0;
+
+  std::map<uint16_t,uint32_t> TDC_setting;
+  std::map<uint16_t,int> TDC_set;
+  for (auto& dirichlistitem: dirichlist) {
+    if(dirichlistitem.second==NULL){
+      std::cerr << "DiRICH " << std::hex << dirichlistitem.first << std::dec << " not initialized! Not switching off TDC" << std::endl;
+      TDC_set.insert(std::pair<uint16_t,int>(dirichlistitem.first,1));
+      continue;
+    }
+    if(dirichlistitem.second->IsJansReadout()){
+      std::cerr << "DiRICH " << std::hex << dirichlistitem.first << std::dec << " has no TDC" << std::endl;
+      TDC_set.insert(std::pair<uint16_t,int>(dirichlistitem.first,2));
+      continue;
+    } 
+    if(dirichlistitem.second->IsSim()){
+      std::cerr << "DiRICH " << std::hex << dirichlistitem.first << std::dec << " is only simulated" << std::endl;
+      TDC_set.insert(std::pair<uint16_t,int>(dirichlistitem.first,2));
+      continue;
+    }   
+    uint32_t temp_tdc_setting[2];
+       ret=trb_register_read(dirichlistitem.first, 0xc802, temp_tdc_setting, 2); //switch off TDC
+    // std::cout << std::hex << temp_tdc_setting[0] << "\t" << temp_tdc_setting[1] << std::endl;
+    if(ret!=2 || temp_tdc_setting[0]!=dirichlistitem.first){
+      std::cerr << "Reading TDCs status failed for dirich " << std::hex << dirichlistitem.first << std::dec << " -> TDC for that dirich will be left switched off" << std::endl;
+      temp_tdc_setting[1] = 0x0;
+    }
+
+       ret=trb_register_write(dirichlistitem.first, 0xc802, 0x00000000); //switch off TDC
+    if(ret==-1){
+      TDC_set.insert(std::pair<uint16_t,int>(dirichlistitem.first,3));
+      continue;
+    }
+    TDC_set.insert(std::pair<uint16_t,int>(dirichlistitem.first,4));
+    TDC_setting.insert(std::pair<uint16_t,uint32_t>(dirichlistitem.first,temp_tdc_setting[1]));
+       }
+
+  std::vector <TThread*> threadlist;  
+  // Initialize instances of dirich class for each module
+  for (auto& dirichlistitem: dirichlist){
+    if(dirichlistitem.second==NULL){
+      std::cerr << "DiRICH " << std::hex << dirichlistitem.first << std::dec << " not initialized!" << std::endl;
+      continue;
+    } 
+    if(TDC_set.at(dirichlistitem.first)==3){
+      std::cerr << "Switching off TDCs failed for dirich " << std::hex << dirichlistitem.first << std::dec << " -> Skipping" << std::endl;
+      continue;
+    }    
+    switch(type){
+    case 1:
+       threadlist.push_back(new TThread(Form("Thread_%i",(int)dirichlistitem.first), scanthread_baseline, (void*) dirichlistitem.second.get()));
+       break;
+    case 2:
+       threadlist.push_back(new TThread(Form("Thread_%i",(int)dirichlistitem.first), scanthread_thr, (void*) dirichlistitem.second.get()));
+       break;
+    case 3:
+       threadlist.push_back(new TThread(Form("Thread_%i",(int)dirichlistitem.first), scanthread_over, (void*) dirichlistitem.second.get()));
+       break;
+    case 0:
+    default:
+       threadlist.push_back(new TThread(Form("Thread_%i",(int)dirichlistitem.first), scanthread_nrml, (void*) dirichlistitem.second.get()));
+       break;
+    }
+    usleep(1000);
+    threadlist.back()->Run(); 
+  }
+  // cout << threadlist.size() << std::endl;
+  printf("Waiting: \n");
+  usleep(1000);
+
+  for(auto& thread : threadlist){
+      // cout << thread->GetState() << std::endl;
+      // thread.second->Join();
+      thread->Join();
+      thread->Delete();
+  } 
+  // threadlist.clear();
+  printf("System scan done ! \n");
+  switch(type){
+  case 1:
+    save();
+       break;
+  case 2:
+       break;
+  case 3:
+    save();
+       break;          
+  case 0:
+  default:
+       save();
+       break;
+  }
+
+       for (auto& TDC_setting_item: TDC_setting) {
+    if(TDC_set.at(TDC_setting_item.first)!=4) continue;
+               ret=trb_register_write(TDC_setting_item.first, 0xc802, TDC_setting_item.second); //switch off TDC
+               if(ret==-1){
+                       std::cerr << "Switching on TDCs failed for dirich: " << std::hex << TDC_setting_item.first << std::dec << std::endl;
+               }
+       }
+}
+
+void initialize_diriches(bool search_dirich){
+// void initialize_diriches(bool search_dirich, std::vector<int> ranges, int NrPasses, double meas_time){
+  TH1::AddDirectory(0);
+  int ret=0;
+  ret=init_ports();
+
+  if(ret==-1){
+    std::cerr << "failed to initialize trb-net ports" << std::endl;
+  }
+       dirichlist.clear();
+
+  if(search_dirich){
+    int dirich_counter=0;
+    // const size_t size4mb = 4194304;
+    const size_t size4mb = 8000; //sufficient for 2000 DiRICHes
+    uint32_t buffer[size4mb];
+    for(int i=0;i<100;++i){
+      TRBAccessMutex.Lock();
+      ret=trb_read_uid(0xfe51, buffer, size4mb);
+      TRBAccessMutex.UnLock();
+      if(ret>0) break;
+    }
+    if(ret<0){
+      std::cerr << "No TRB3 Modules found!!!" << std::endl;
+      return;
+    }
+    for(int i=0;i<ret;i+=4){
+      // if(buffer[i+3]>0x1200 && buffer[i+3]<0x1200)
+      dirichlist.insert(std::make_pair(uint16_t(buffer[i+3]),std::shared_ptr<dirich>(new dirich(uint16_t(buffer[i+3])))));
+      ++dirich_counter;
+      std::cout << "Created DiRICH-Object for DiRICH with address: 0x" << std::hex << buffer[i+3] << std::endl;
+      // std::cout << dirichlist.at(uint16_t(buffer[i+3]))->GetBoardUID() << std::endl;
+      if(dirichlist.at(uint16_t(buffer[i+3]))->gMeasureTime!=.3){ //pls change it according to your initialization... Sure one should rather throw during init... but well I am lazy
+       std::cout << "DiRICH 0x" << std::hex << uint16_t(buffer[i+3]) << " not correclty initialized. Deleting!" << std::endl;
+        // delete dirichlist.at(uint16_t(buffer[i+3]));
+        dirichlist.erase(uint16_t(buffer[i+3]));
+      }
+      // std::cout << dirichlist.at(uint16_t(buffer[i+3]))->gLowerEdge << std::endl;
+      // std::cout << dirichlist.at(uint16_t(buffer[i+3]))->gUpperEdge << std::endl;
+    }
+    std::cout << "Found " << std::dec << dirich_counter << " different diriches\nInitialized " << dirichlist.size() << " out of those" << std::endl;
+  }
+}
+
+void setup_scan_parameters(std::shared_ptr<dirich>  dirichptr, double gMeasureTime, int gLowerEdge, int gUpperEdge, int gStepsize, int gNrPasses){
+       if(dirichptr==NULL){
+               for (auto& dirichlistitem: dirichlist) {
+                       if(dirichlistitem.second==NULL){
+                               std::cerr << "dirich 0x" << std::hex << dirichlistitem.first << std::dec << " not initialized" << std::endl;
+                               continue;
+                       }
+                       dirichlistitem.second->gMeasureTime = gMeasureTime;
+                       dirichlistitem.second->gLowerEdge = gLowerEdge;
+                       dirichlistitem.second->gUpperEdge = gUpperEdge;
+                       dirichlistitem.second->gStepsize = gStepsize;
+                       dirichlistitem.second->gNrPasses = gNrPasses;
+               }
+       }
+       else{
+               dirichptr->gMeasureTime = gMeasureTime;
+               dirichptr->gLowerEdge = gLowerEdge;
+               dirichptr->gUpperEdge = gUpperEdge;
+               dirichptr->gStepsize = gStepsize;
+               dirichptr->gNrPasses = gNrPasses;
+       }
+}
+
+void setup_scan_parameters_over_thr_mV(std::shared_ptr<dirich>  dirichptr, double gMeasureTime, double gUpperEdgemV, double gStepsizemV, int gNrPasses){
+       if(dirichptr==NULL){
+               for (auto& dirichlistitem: dirichlist) {
+                       if(dirichlistitem.second==NULL){
+                               std::cerr << "dirich 0x" << std::hex << dirichlistitem.first << std::dec << " not initialized" << std::endl;
+                               continue;
+                       }
+                       dirichlistitem.second->gMeasureTime_over = gMeasureTime;
+                       dirichlistitem.second->gUpperEdge_over = gUpperEdgemV;
+                       dirichlistitem.second->gStepsize_over = gStepsizemV;
+                       dirichlistitem.second->gNrPasses_over = gNrPasses;
+               }
+       }
+       else{
+               dirichptr->gMeasureTime_over = gMeasureTime;
+               dirichptr->gUpperEdge_over = gUpperEdgemV;
+               dirichptr->gStepsize_over = gStepsizemV;
+               dirichptr->gNrPasses_over = gNrPasses;
+       }
+}
+
+
+int main(int argc, char* argv[]){
+  std::string loading_file = "";
+  std::string save_file = "";
+  // Declare the supported options.
+  po::options_description desc("Allowed options");
+  desc.add_options()
+      ("help,h", "produce help message")
+      ("info,i", "only initialize diriches")
+      // ("use-dirich,u", po::value<std::vector<std::string>>()->multitoken(), "Add diriches to the dirichlist. If dirich does not exist it will be simulated")
+      // ("dont-search-dirich", "Dont't search for active diriches during startup.")
+      // ("scan-baseline-new,n", "Do new baselinescan (Michaels method). No parameters need to be given!")
+      ("scan-baseline,b", po::value<std::vector<std::string>>()->multitoken(), "Do standard baselinescan. Six parameters need to be given:dirich (if 0, all diriches), measure-time (s), threshold-start-value, threshold-end-value, threshold-step-width, number of cycles (two refers to every second channel measured at a time. Values will be set for all diriches!")
+      ("find-threshold,r", "find the perfect threshold for the given dirich/maptm-channel-combination. No parameters need to be given.")
+      // ("find-threshold,i", po::value<double>(),"find the perfect threshold for the given dirich/maptm-channel-combination. The parameter specifies the method to find the perfect threshold:\n0: searches for the minimum in the differentiated spectrum or for the minimal gradient\n0<value<5: tries to find peak and sigma of the single photon distribution and sets the threshold to value*sigma (!!!!currently not implemented!!!)\n5<value<100: tries to find the single photon peak and sets the threshold to value% of the spp-position")
+      ("scan-above-noise,a", po::value<std::vector<std::string>>()->multitoken(), "Do scan for threshold-values greater than the diriches noiseband. Five parameters need to be given:dirich (if 0, all diriches), measure-time (s), threshold-end-value (mV), threshold-step-width (mV), number of cycles (two refers to every second channel measured at a time")
+      ("load-baseline,l", po::value<std::vector<std::string>>()->multitoken(), "This option loads the baseline from the file specified in --loading-file. If no file was specified, the latest produced file is choosen. One can specify a certain dirich by using this options parameter. Be aware that this option overwrites the baseline retreived from the baselinescan")
+      ("load-threshold", po::value<std::vector<std::string>>()->multitoken(), "This option loads the threshold from the file specified in --loading-file. If no file was specified, the latest produced file is choosen. One can specify a certain dirich by using this options parameter. Be aware that the thresholds are overwriten by --set-threshold")
+      ("loading-file,f", po::value<std::string>(&loading_file)->default_value(""), "File to load thresholds and/or baseline from")
+      ("save,s", po::value<std::vector<std::string>>()->multitoken(), "Save histograms and data of specified dirich after everything else is executed! Autosaves will be still produced and saved via \"DATE_std_save{.thr,.root}\". Savefile can be set via --save-file")
+      ("save-file", po::value<std::string>(&save_file)->default_value(""), "Save histograms and data. If no file specified, a std. filename will be produced")
+      ("draw-scan-baseline,d", po::value<std::vector<std::string>>()->multitoken(), "Draw the results of the baselinescan. Dirich can be specified using this options parameter. Obviously this function fails if no scan was done!")
+      ("draw-scan-above-noise", po::value<std::vector<std::string>>()->multitoken(), "Draw the results of the thresholdscan above the diriches noiseband. Dirich can be specified using this options parameter. Obviously this function fails if no scan was done!")
+      ("draw-scan-above-noise-diff-gr", po::value<std::vector<std::string>>()->multitoken(), "Draw the results of the baselinescan above the diriches noiseband as differential plot. Dirich can be specified using this options parameter. Obviously this function fails if no scan was done!")
+      ("draw-noisewidth,w", po::value<std::vector<std::string>>()->multitoken(), "Draw the noisewidth. Dirich can be specified using this options parameter. Obviously this function fails if neither a scan was done nor a threshold-setting was loaded!")
+      ("set-threshold,t", po::value<std::vector<std::string>>()->multitoken(), "Set threshold for specified diriches in mV. First Parameter specifies the dirich (0 equals all dirichs), the second the threshold. Only positive threshold values are accepted, as the minus-sign induces errors.")
+  ;
+// implicit_value(std::vector<std::string>{"0"},"0")
+  po::variables_map vm;
+  po::store(po::parse_command_line(argc, argv, desc), vm);
+  po::notify(vm);    
+
+  if (vm.count("help")) {
+    std::cout << desc << std::endl;
+    return 0;
+  }
+  if(loading_file==""){
+    fs::path latest;
+    std::time_t latest_tm {};
+    for (auto&& entry : boost::make_iterator_range(fs::directory_iterator("."), {})) {
+      fs::path p = entry.path();
+      if (is_regular_file(p) && p.extension() == ".thr") 
+      {
+        std::time_t timestamp = fs::last_write_time(p);
+        if (timestamp > latest_tm) {
+          latest = p;
+          latest_tm = timestamp;
+        }
+      }
+    }
+    loading_file = latest.filename().string();
+  }
+  // if(vm.count("use-diriches")){
+  //   for(auto& use_diriches_options : vm["use-diriches"].as<std::vector<std::string>>()){
+  //     dirichlist.emplace(std::stoi(use_diriches_options.substr(use_diriches_options.find("0x")!=std::string::npos ? use_diriches_options.find("0x")+2 : 0),NULL,16),(dirich*)NULL);
+  //   }
+  // }
+
+  // if(!vm.count("dont-search-dirich")) initialize_diriches(1);
+  // else initialize_diriches(0);
+  
+  initialize_diriches(1);
+  if(vm.count("info")){
+    return 0;
+  }
+  // if(vm.count("scan-baseline-new")){
+  //   system_thr_scan(1);
+
+  //   if(vm.count("draw-scan-baseline")){
+  //     // std::cout << "draw-scan-baseline" << std::endl;
+  //     if(vm["draw-scan-baseline"].empty()){
+  //       draw_histo(get_2D_rate_histo(NULL),NULL);
+  //     }
+  //     for(auto& draw_scan_baseline_options : vm["draw-scan-baseline"].as<std::vector<std::string>>()){
+  //       // std::cout << "input for draw-scan-baseline: " << draw_scan_baseline_options << std::endl;
+  //       if(draw_scan_baseline_options=="0") draw_histo(get_2D_rate_histo(NULL),NULL);
+  //       else draw_histo(get_2D_rate_histo(dirichlist.at(std::stoi(draw_scan_baseline_options.substr(draw_scan_baseline_options.find("0x")!=std::string::npos ? draw_scan_baseline_options.find("0x")+2 : 0),NULL,16))),NULL);
+  //     }
+  //   }
+  //   if(vm.count("draw-noisewidth")){
+  //     if(vm["draw-noisewidth"].empty()){
+  //       draw_histo(get_noisewidth_histo(NULL),NULL);
+  //     }
+  //     for(auto& draw_noisewidth_options : vm["draw-noisewidth"].as<std::vector<std::string>>()){
+  //       if(draw_noisewidth_options=="0") draw_histo(get_noisewidth_histo(NULL),NULL);
+  //       else draw_histo(get_noisewidth_histo(dirichlist.at(std::stoi(draw_noisewidth_options.substr(draw_noisewidth_options.find("0x")!=std::string::npos ? draw_noisewidth_options.find("0x")+2 : 0),NULL,16))),NULL);
+  //     }
+  //   }
+  // }
+
+  if(vm.count("scan-baseline")){
+    if(vm["scan-baseline"].empty() || (vm["scan-baseline"].as<std::vector<std::string>>()).size() < 6){
+      std::cout << "no or less than six arguments were provided for option --scan-baseline:\nrunning scan with std. parameters" << std::endl;    
+    }
+    else{
+      std::vector<std::vector<std::string>> each_scan_base_opt;
+      std::vector<std::string> temp_vec;
+      for(auto& scan_base_opt : vm["scan-baseline"].as<std::vector<std::string>>()){
+        std::cout << scan_base_opt << std::endl;
+        if(scan_base_opt.find("0x")!=std::string::npos || scan_base_opt=="0"){
+          // std::cout << "0 or 0x" <<std::endl;
+          if(temp_vec.size()==6){
+            each_scan_base_opt.push_back(temp_vec);
+          }
+          temp_vec.clear();
+        }
+        temp_vec.push_back(scan_base_opt);
+      }
+      if(temp_vec.size()==6){
+        each_scan_base_opt.push_back(temp_vec);
+      }      
+      for(auto& one_scan_base_opt : each_scan_base_opt){
+        std::cout << std::stoi(one_scan_base_opt.at(0).substr(one_scan_base_opt.at(0).find("0x")!=std::string::npos ? one_scan_base_opt.at(0).find("0x")+2 : 0),NULL,16) << "\t"
+                  << std::stod(one_scan_base_opt.at(1)) << "\t"
+                  << std::stoi(one_scan_base_opt.at(2)) << "\t"
+                  << std::stoi(one_scan_base_opt.at(3)) << "\t"
+                  << std::stoi(one_scan_base_opt.at(4)) << "\t"
+                  << std::stoi(one_scan_base_opt.at(5)) 
+                  << std::endl;
+        setup_scan_parameters(one_scan_base_opt.at(0) == "0" ? 0 : dirichlist.at(std::stoi(one_scan_base_opt.at(0).substr(one_scan_base_opt.at(0).find("0x")!=std::string::npos ? one_scan_base_opt.at(0).find("0x")+2 : 0),NULL,16))
+          , std::stod(one_scan_base_opt.at(1))
+          , std::stoi(one_scan_base_opt.at(2))
+          , std::stoi(one_scan_base_opt.at(3))
+          , std::stoi(one_scan_base_opt.at(4))
+          , std::stoi(one_scan_base_opt.at(5))
+        );
+      }
+    }
+    system_thr_scan(0);
+
+    if(vm.count("draw-scan-baseline")){
+      // std::cout << "draw-scan-baseline" << std::endl;
+      if(vm["draw-scan-baseline"].empty()){
+        draw_histo(get_2D_rate_histo(NULL),NULL);
+      }
+      for(auto& draw_scan_baseline_options : vm["draw-scan-baseline"].as<std::vector<std::string>>()){
+        // std::cout << "input for draw-scan-baseline: " << draw_scan_baseline_options << std::endl;
+        if(draw_scan_baseline_options=="0") draw_histo(get_2D_rate_histo(NULL),NULL);
+        else draw_histo(get_2D_rate_histo(dirichlist.at(std::stoi(draw_scan_baseline_options.substr(draw_scan_baseline_options.find("0x")!=std::string::npos ? draw_scan_baseline_options.find("0x")+2 : 0),NULL,16))),NULL);
+      }
+    }
+    if(vm.count("draw-noisewidth")){
+      if(vm["draw-noisewidth"].empty()){
+        draw_histo(get_noisewidth_histo(NULL),NULL);
+      }
+      for(auto& draw_noisewidth_options : vm["draw-noisewidth"].as<std::vector<std::string>>()){
+        if(draw_noisewidth_options=="0") draw_histo(get_noisewidth_histo(NULL),NULL);
+        else draw_histo(get_noisewidth_histo(dirichlist.at(std::stoi(draw_noisewidth_options.substr(draw_noisewidth_options.find("0x")!=std::string::npos ? draw_noisewidth_options.find("0x")+2 : 0),NULL,16))),NULL);
+      }
+    }
+  }
+
+  if(vm.count("load-baseline")){
+    // std::cout << "inside load baseline" << std::endl;
+    if(loading_file==""){
+      std::cout << "no loading-file found!\n! aborting !" << std::endl;
+    }
+    else{
+       std::cout << "loading_file: " << loading_file << std::endl;
+      for(auto& load_baseline_opt : vm["load-baseline"].as<std::vector<std::string>>()){
+        if(load_baseline_opt=="0") load_base(NULL, loading_file, 0, 1, 0);
+        else load_base(dirichlist.at(std::stoi(load_baseline_opt.substr(load_baseline_opt.find("0x")!=std::string::npos ? load_baseline_opt.find("0x")+2 : 0),NULL,16)), loading_file, 0, 1, 0);
+      }
+      if(vm.count("draw-noisewidth")){
+        if(vm["draw-noisewidth"].empty()){
+          draw_histo(get_noisewidth_histo(NULL),NULL);
+        }        
+        for(auto& draw_noisewidth_options : vm["draw-noisewidth"].as<std::vector<std::string>>()){
+          if(draw_noisewidth_options=="0") draw_histo(get_noisewidth_histo(NULL),NULL);
+          else draw_histo(get_noisewidth_histo(dirichlist.at(std::stoi(draw_noisewidth_options.substr(draw_noisewidth_options.find("0x")!=std::string::npos ? draw_noisewidth_options.find("0x")+2 : 0),NULL,16))),NULL);
+        }
+      }
+    }
+  }
+
+  if(vm.count("scan-above-noise")){
+    if(vm["scan-above-noise"].empty() || (vm["scan-above-noise"].as<std::vector<std::string>>()).size() < 5){
+      std::cout << "no or less than five arguments were provided for option --scan-above-noise:\nrunning scan with std. parameters" << std::endl;    
+    }
+    else{
+      std::vector<std::vector<std::string>> each_scan_above_noise_opt;
+      std::vector<std::string> temp_vec;
+      for(auto& scan_above_noise_opt : vm["scan-above-noise"].as<std::vector<std::string>>()){
+        if(scan_above_noise_opt.find("0x")!=std::string::npos || scan_above_noise_opt=="0"){
+          if(temp_vec.size()==5){
+            each_scan_above_noise_opt.push_back(temp_vec);
+          }
+          temp_vec.clear();
+        }
+        temp_vec.push_back(scan_above_noise_opt);
+      }
+      if(temp_vec.size()==5){
+        each_scan_above_noise_opt.push_back(temp_vec);
+      }   
+      for(auto& one_scan_above_noise_opt : each_scan_above_noise_opt){
+        std::cout << std::stoi(one_scan_above_noise_opt.at(0).substr(one_scan_above_noise_opt.at(0).find("0x")!=std::string::npos ? one_scan_above_noise_opt.at(0).find("0x")+2 : 0),NULL,16) << "\t"
+                  << std::stod(one_scan_above_noise_opt.at(1)) << "\t"
+                  << std::stod(one_scan_above_noise_opt.at(2)) << "\t"
+                  << std::stod(one_scan_above_noise_opt.at(3)) << "\t"
+                  << std::stoi(one_scan_above_noise_opt.at(4)) 
+                  << std::endl;
+        setup_scan_parameters_over_thr_mV(one_scan_above_noise_opt.at(0) == "0" ? 0 : dirichlist.at(std::stoi(one_scan_above_noise_opt.at(0).substr(one_scan_above_noise_opt.at(0).find("0x")!=std::string::npos ? one_scan_above_noise_opt.at(0).find("0x")+2 : 0),NULL,16))
+          , std::stod(one_scan_above_noise_opt.at(1))
+          , std::stod(one_scan_above_noise_opt.at(2))
+          , std::stod(one_scan_above_noise_opt.at(3))
+          , std::stoi(one_scan_above_noise_opt.at(4))
+        );
+      }
+    }
+    system_thr_scan(3);
+  }
+
+  if(vm.count("find-threshold")){
+    for(auto& dirich : dirichlist){
+      dirich.second->gThreshold_finding_method = 0;
+      // dirich.second->gThreshold_finding_method = vm["find-threshold"].as<double>();
+      std::cout << dirich.second->gThreshold_finding_method << std::endl;
+    }
+    system_thr_scan(2);
+  }
+
+  if(vm.count("load-threshold")){
+    for(auto& load_threshold_options : vm["load-threshold"].as<std::vector<std::string>>()){
+      if(load_threshold_options=="0") load_base(NULL, loading_file,0, 0, 1);
+      else load_base(dirichlist.at(std::stoi(load_threshold_options.substr(load_threshold_options.find("0x")!=std::string::npos ? load_threshold_options.find("0x")+2 : 0),NULL,16)), loading_file, 0, 0, 1);
+    }
+  }
+
+  if(vm.count("set-threshold")){
+    if(vm["set-threshold"].empty() || (vm["set-threshold"].as<std::vector<std::string>>()).size() < 2){
+      std::cout << "no or less than two arguments were provided for option --set-threshold:\nno thresholds will be set" << std::endl;    
+    }
+    else{
+      std::vector<std::vector<std::string>> each_set_threshold_opt;
+      std::vector<std::string> temp_vec;
+      for(auto& set_threshold_opt : vm["set-threshold"].as<std::vector<std::string>>()){
+        if(set_threshold_opt.find("0x")!=std::string::npos || set_threshold_opt=="0"){
+          if(temp_vec.size()==2){
+            each_set_threshold_opt.push_back(temp_vec);
+          }
+          temp_vec.clear();
+        }
+        temp_vec.push_back(set_threshold_opt);
+      }
+      if(temp_vec.size()==2){
+        each_set_threshold_opt.push_back(temp_vec);
+      }   
+      for(auto& one_set_threshold_opt : each_set_threshold_opt){
+        std::cout << std::stoi(one_set_threshold_opt.at(0).substr(one_set_threshold_opt.at(0).find("0x")!=std::string::npos ? one_set_threshold_opt.at(0).find("0x")+2 : 0),NULL,16) << "\t"
+                  << std::stod(one_set_threshold_opt.at(1))
+                  << std::endl;
+        set_thresholds(one_set_threshold_opt.at(0) == "0" ? 0 : dirichlist.at(std::stoi(one_set_threshold_opt.at(0).substr(one_set_threshold_opt.at(0).find("0x")!=std::string::npos ? one_set_threshold_opt.at(0).find("0x")+2 : 0),NULL,16)), std::stod(one_set_threshold_opt.at(1)));
+      }
+    }
+  }
+
+  if(vm.count("scan-above-noise")){
+    if(vm.count("draw-scan-above-noise")){
+      if(vm["draw-scan-above-noise"].empty()){
+        draw_histo(get_2D_rate_over_thr_histo(NULL),NULL);
+      }      
+      for(auto& draw_scan_above_noise_options : vm["draw-scan-above-noise"].as<std::vector<std::string>>()){
+        if(draw_scan_above_noise_options=="0") draw_histo(get_2D_rate_over_thr_histo(NULL),NULL);
+        else draw_histo(get_2D_rate_over_thr_histo(dirichlist.at(std::stoi(draw_scan_above_noise_options.substr(draw_scan_above_noise_options.find("0x")!=std::string::npos ? draw_scan_above_noise_options.find("0x")+2 : 0),NULL,16))),NULL);
+      }
+    }
+    if(vm.count("draw-scan-above-noise-diff-gr")){
+      if(vm["draw-scan-above-noise-diff-gr"].empty()){
+        draw_multigraph(get_2D_mgr_diff_over_thr_histo(NULL),NULL);
+      }      
+      for(auto& draw_scan_above_noise_diff_options : vm["draw-scan-above-noise-diff-gr"].as<std::vector<std::string>>()){
+        if(draw_scan_above_noise_diff_options=="0") draw_multigraph(get_2D_mgr_diff_over_thr_histo(NULL),NULL);
+        else draw_multigraph(get_2D_mgr_diff_over_thr_histo(dirichlist.at(std::stoi(draw_scan_above_noise_diff_options.substr(draw_scan_above_noise_diff_options.find("0x")!=std::string::npos ? draw_scan_above_noise_diff_options.find("0x")+2 : 0),NULL,16))),NULL);
+      }
+    }
+  }
+
+  if(save_file==""){
+    std::array<char, 64> buffer;
+    buffer.fill(0);
+    time_t rawtime;
+    time(&rawtime);
+    const auto timeinfo = localtime(&rawtime);
+    strftime(buffer.data(), sizeof(buffer), "%Y%m%d_%H%M%S", timeinfo);
+    save_file = std::string(buffer.data()) + "_std_save";      
+  }
+  else{
+    save_file=vm["save-file"].as<std::string>();
+  }
+
+  if(vm.count("save")){
+    for(auto& save_options : vm["save"].as<std::vector<std::string>>()){
+      if(save_options=="0"){
+        save_base(NULL,save_file,1);
+        save_graphs(NULL,save_file);
+      }
+      else{
+        save_base(dirichlist.at(std::stoi(save_options.substr(save_options.find("0x")!=std::string::npos ? save_options.find("0x")+2 : 0),NULL,16)),save_file,1);
+        save_graphs(dirichlist.at(std::stoi(save_options.substr(save_options.find("0x")!=std::string::npos ? save_options.find("0x")+2 : 0),NULL,16)),save_file);
+      }
+    }
+  }
+
+  std::string str = save_file + "_all_canvases.pdf";
+  uint counter=0;
+  for(auto& canvases : canvasvector){
+    if(counter==0 && canvasvector.size()>1) canvases->Print(Form("%s(",str.c_str()));
+    else if(counter==canvasvector.size()-1) canvases->Print(Form("%s)",str.c_str()));
+    else canvases->Print(str.c_str());
+    counter++;
+  }
+
+  return 0;
+}
diff --git a/thresholds/trb_dirich_threshold/obsolete/test_trbnet b/thresholds/trb_dirich_threshold/obsolete/test_trbnet
new file mode 100755 (executable)
index 0000000..4914597
Binary files /dev/null and b/thresholds/trb_dirich_threshold/obsolete/test_trbnet differ
diff --git a/thresholds/trb_dirich_threshold/obsolete/test_trbnet.cc b/thresholds/trb_dirich_threshold/obsolete/test_trbnet.cc
new file mode 100644 (file)
index 0000000..8dd1c1f
--- /dev/null
@@ -0,0 +1,7 @@
+#include "trbnet.h"
+#include "trberror.h"
+#include <iostream>
+
+int main (int arc, char** argv){
+  std::cout << init_ports() << trb_strerror()  << std::endl;
+}
diff --git a/thresholds/trb_dirich_threshold/setLD b/thresholds/trb_dirich_threshold/setLD
new file mode 100644 (file)
index 0000000..f1c3623
--- /dev/null
@@ -0,0 +1 @@
+export LD_LIBRARY_PATH=/home/hadaq/trbsoft/analysis/trb3/rootbuild/lib:/home/hadaq/trbsoft/trbnettools//lib:/usr/lib:"$LD_LIBRARY_PATH"
diff --git a/thresholds/trb_dirich_threshold/trbnetcom.h b/thresholds/trb_dirich_threshold/trbnetcom.h
new file mode 100644 (file)
index 0000000..1bbe014
--- /dev/null
@@ -0,0 +1,87 @@
+#include "trbnet.h"
+#include <thread>
+#include <mutex>
+
+const int NOFCOMTRIES = 100;
+const int FAILDELAY = 1000;
+
+std::mutex TRBAccessMutex;
+
+inline int Ttrb_read_uid(uint16_t _BoardAddress, uint32_t* _buffer, size_t _buffer_size){
+       int ret=-1;
+       for(int tries=0;
+                       tries<NOFCOMTRIES;
+                       ++tries
+               ){
+               TRBAccessMutex.lock();
+               ret=trb_read_uid(_BoardAddress, _buffer, _buffer_size);
+               TRBAccessMutex.unlock();
+               if(ret>=0) break;
+               std::cout << "FAILED COM" << std::endl;
+               std::this_thread::sleep_for(std::chrono::milliseconds(FAILDELAY));
+       }
+       return ret;
+}
+
+inline int Ttrb_register_write_mem(uint16_t _BoardAddress, uint16_t _RegisterAddress, uint8_t _option, uint32_t* _buffer, uint32_t _buffer_size){
+       int ret=-1;
+       for(int tries=0;
+                       tries<NOFCOMTRIES;
+                       ++tries
+               ){
+               TRBAccessMutex.lock();
+               ret=trb_register_write_mem(_BoardAddress, _RegisterAddress, _option, _buffer, _buffer_size);
+               TRBAccessMutex.unlock();
+               if(ret>=0) break;
+               std::cout << "FAILED COM" << std::endl;
+               std::this_thread::sleep_for(std::chrono::milliseconds(FAILDELAY));
+       }
+       return ret;
+}
+
+inline int Ttrb_register_read_mem(uint16_t _BoardAddress, uint16_t _RegisterAddress, uint8_t _option, uint16_t _size, uint32_t* _buffer, uint32_t _buffer_size){
+       int ret=-1;
+       for(int tries=0;
+                       tries<NOFCOMTRIES;
+                       ++tries
+               ){
+               TRBAccessMutex.lock();
+               ret=trb_register_read_mem(_BoardAddress, _RegisterAddress, _option, _size, _buffer, _buffer_size);
+               TRBAccessMutex.unlock();
+               if(ret>=0) break;
+               std::cout << "FAILED COM" << std::endl;
+               std::this_thread::sleep_for(std::chrono::milliseconds(FAILDELAY));
+       }
+       return ret;
+}
+       
+inline int Ttrb_register_read(uint16_t _BoardAddress, uint16_t _RegisterAddress, uint32_t* _buffer, size_t _buffer_size){
+       int ret=-1;
+       for(int tries=0;
+                       tries<NOFCOMTRIES;
+                       ++tries
+               ){
+               TRBAccessMutex.lock();
+               ret=trb_register_read(_BoardAddress, _RegisterAddress, _buffer, _buffer_size);
+               TRBAccessMutex.unlock();
+               if(ret>=0) break;
+               std::cout << "FAILED COM" << std::endl;
+               std::this_thread::sleep_for(std::chrono::milliseconds(FAILDELAY));
+       }
+       return ret;
+}
+
+inline int Ttrb_register_write(uint16_t _BoardAddress, uint16_t _RegisterAddress, uint32_t _val){
+       int ret=-1;
+       for(int tries=0;
+                       tries<NOFCOMTRIES;
+                       ++tries
+               ){
+               TRBAccessMutex.lock();
+               ret=trb_register_write(_BoardAddress, _RegisterAddress, _val);
+               TRBAccessMutex.unlock();
+               if(ret!=-1) break;
+               std::this_thread::sleep_for(std::chrono::milliseconds(FAILDELAY));
+       }
+       return ret;
+}
\ No newline at end of file
index 705e1431eec14c3d5cdf362b852a91c11c41a7f7..2d27e30b4639e17e3ce6226d120721de7ffbafa9 100644 (file)
@@ -34,7 +34,7 @@ store data in lmd files.
 
     <Module name="Combiner" class="hadaq::CombinerModule">    
         <!-- these parameters will force to create inputs/oputputs of module -->
-       <NumInputs value="7"/>
+       <NumInputs value="6"/>
        <NumOutputs value="2"/>
 
        <InputPort name="Input0"  url="hadaq://host:50000" thread="UdpThread1"/>
index 6e83f5a9c9378b13579bafc27dd8ce7d4e796dbf..1ad653cba02537424cefbac7e6441388290e335e 100644 (file)
@@ -64,7 +64,7 @@ When starting analysis from the go4 gui, one should specify stream server with p
 
     <Module name="Combiner" class="hadaq::CombinerModule">    
         <!-- these parameters will force to create inputs/oputputs of module -->
-       <NumInputs value="7"/>
+       <NumInputs value="6"/>
        <NumOutputs value="2"/>
 
        <InputPort name="Input0"  url="hadaq://host:49999" thread="UdpThread1"/>
@@ -73,7 +73,7 @@ When starting analysis from the go4 gui, one should specify stream server with p
        <InputPort name="Input3"  url="hadaq://host:50002" thread="UdpThread1"/>
        <InputPort name="Input4"  url="hadaq://host:50003" thread="UdpThread1"/>
        <InputPort name="Input5"  url="hadaq://host:50004" thread="UdpThread1"/>
-       <InputPort name="Input6"  url="hadaq://host:50005" thread="UdpThread1"/>
+                <InputPort name="Input6"  url="hadaq://host:50005" thread="UdpThread1"/> 
 
        <InputPort name="Input7"  url="hadaq://host:50006" thread="UdpThread1"/>
        <InputPort name="Input8"  url="hadaq://host:50007" thread="UdpThread1"/>
diff --git a/users/gsi_dirc/dirich_set_standard_thresholds.pl b/users/gsi_dirc/dirich_set_standard_thresholds.pl
new file mode 100755 (executable)
index 0000000..5d472fc
--- /dev/null
@@ -0,0 +1,67 @@
+#!/usr/bin/perl
+use warnings;
+use strict;
+use HADES::TrbNet;
+use Time::HiRes qw(usleep);
+use Data::Dumper;
+
+use lib "/home/hadaq/trbsoft/daqtools/dmon/code";
+use Dmon;
+
+my $dirich = 0x1234;
+my $std_thresh = 0x6800;
+
+$dirich = $ARGV[0];
+if($ARGV[1]) {
+  $std_thresh = $ARGV[1];
+  $std_thresh = hex($std_thresh);
+}
+
+unless ($ARGV[0]) {
+  print "usage: $0 <DiRICH--TrbNet-Address> [std_threshold]]\n";
+  exit;
+}
+
+$dirich = hex($dirich);
+
+my $throffset = 0xa000;
+#my $monitor = 0xdfc0;
+my $monitor = 0xc001;
+
+my $first_channel = 0;
+my $last_channel = 31;
+
+my $default_threshold = 0x6000;
+
+#my $absolute_max_threshold = 0x8000;
+my $absolute_min_threshold = 0x1000;
+
+my @res; my $res; my $rh_res;
+
+trb_init_ports() or die trb_strerror();
+
+# enable monitor counters
+$res = trb_register_write($dirich, 0xdf80 , 0xffffffff);
+if(!defined $res) {
+    $res = trb_strerror();
+    print "error output: $res\n";
+}
+
+
+my $command;
+my $chain=0;
+
+my $READ  = 0x0<<20; # bits to set for a read command
+my $WRITE = 0x8<<20; # bits to set for a write command
+my $REGNR = 24; # number of bits to shift for the register number
+
+
+for my $channel (0 .. 31) {
+  $chain = ($channel <16) ? 0 : 1;
+  $command = ($channel&0xf)<<$REGNR | $WRITE | ($std_thresh & 0xffff);
+  #print "$command\n";
+  Dmon::PadiwaSendCmd($command,$dirich, $chain);
+  usleep(10E3);
+}
+exit;
+
diff --git a/users/gsi_dirc/dirich_voltages.sh b/users/gsi_dirc/dirich_voltages.sh
new file mode 100755 (executable)
index 0000000..1dd4aa6
--- /dev/null
@@ -0,0 +1,11 @@
+echo "power voltage "
+../frankfurt_test/trb3scadc.pl 0x8005 3
+echo "power current "
+../frankfurt_test/trb3scadc.pl 0x8005 4
+echo "concentrator "
+../frankfurt_test/trb3scadc.pl 0x8005 2
+echo "drich 2014"
+../frankfurt_test/trb3scadc.pl 0x2014 1
+echo "drich 2015"
+../frankfurt_test/trb3scadc.pl 0x2015 1
+
index 7a63a369717e54c060328e3bf158efff6db1ac88..0631b0097d172390cd6a853dc3c58c94928a2178 100755 (executable)
@@ -4,10 +4,10 @@ use strict;
 use Getopt::Long;
 
 my $help = "";
-my $dataPath = "/d/sep2018/";
+my $dataPath = "/d/apr2019/";
 my $label = "cern";
 my $time = -1;
-my $name = "pilas_";
+my $name = "trb_";
 my $old;
 my $c;
 
@@ -39,7 +39,9 @@ $c=qq|pkill -f "daq_netmem -S $label"|;   qx($c); # if any, kill existing daq_ne
 
 
 if(!defined $old) {
-    $c=qq|pkill -f "dabc_exe"|;
+
+
+       $c=qq|pkill -f "dabc_exe"|;
     qx($c);
     
     my $pathandfile = "$dataPath/$name.hld";
@@ -52,10 +54,9 @@ if(!defined $old) {
 
 }
 else {
-
     #$c=qq|xterm -geometry 122x15-0+0 -e bash -c 'daq_evtbuild -S $label -m 9 -x $name --filesize 1536 -d file -o $dataPath'|;
 
-    $c=qq|xterm -geometry 122x15-0+0 -e bash -c 'daq_evtbuild -S $label -m 6 -x $name --filesize 1536 -d file -o $dataPath'|;
+    $c=qq|xterm -geometry 122x15-0+0 -e bash -c 'daq_evtbuild -S $label -m 7 -x $name --filesize 1536 -d file -o $dataPath'|;
         #2016 $c=qq|xterm -geometry 122x15-0+0 -e bash -c 'daq_evtbuild -S $label -m 10 -x $name --filesize 1536 -d file -o $dataPath'|;
     #$c=qq|xterm -geometry 122x16-0+0 -e bash -c 'daq_evtbuild -S $label -m 23 -x $name -d file -o $dataPath'|;
     print "test";
@@ -73,7 +74,7 @@ else {
         
         #$c=qq"xterm -geometry 82x45-0+210 -e bash -c 'daq_netmem -S $label -m 10 -i UDP:127.0.0.1:49999 -i UDP:127.0.0.1:50000 -i UDP:127.0.0.1:50001 -i UDP:127.0.0.1:50002 -i UDP:127.0.0.1:50003 -i UDP:127.0.0.1:50004 -i UDP:127.0.0.1:50005 -i UDP:127.0.0.1:50006 -i UDP:127.0.0.1:50007 -i UDP:127.0.0.1:50008'";
 
-    $c=qq"xterm -geometry 82x44-0+234 -e bash -c 'daq_netmem -S $label -m 6 -i UDP:127.0.0.1:49999 -i UDP:127.0.0.1:50000 -i UDP:127.0.0.1:50001 -i UDP:127.0.0.1:50002 -i UDP:127.0.0.1:50003 -i UDP:127.0.0.1:50004; sleep 2 '";
+    $c=qq"xterm -geometry 82x44-0+234 -e bash -c 'daq_netmem -S $label -m 7 -i UDP:127.0.0.1:49999 -i UDP:127.0.0.1:50000 -i UDP:127.0.0.1:50001 -i UDP:127.0.0.1:50002 -i UDP:127.0.0.1:50003 -i UDP:127.0.0.1:50004 -i UDP:127.0.0.1:50005; sleep 2 '";
 
     #$c=qq"xterm -geometry 82x44-0+234 -e bash -c 'daq_netmem -S $label -m 23 -i UDP:127.0.0.1:50000 -i UDP:127.0.0.1:50001 -i UDP:127.0.0.1:50002 -i UDP:127.0.0.1:50003 -i UDP:127.0.0.1:50004 -i UDP:127.0.0.1:50005 -i UDP:127.0.0.1:50006 -i UDP:127.0.0.1:50007 -i UDP:127.0.0.1:50008 -i UDP:127.0.0.1:50009 -i UDP:127.0.0.1:50010 -i UDP:127.0.0.1:50011 -i UDP:127.0.0.1:50012 -i UDP:127.0.0.1:50013 -i UDP:127.0.0.1:50014 -i UDP:127.0.0.1:50015 -i UDP:127.0.0.1:50016 -i UDP:127.0.0.1:50017 -i UDP:127.0.0.1:50018 -i UDP:127.0.0.1:50019 -i UDP:127.0.0.1:50020 -i UDP:127.0.0.1:50021 -i UDP:127.0.0.1:50022; sleep 2'";
 
index 994186f2c9237931ef762fda23df089803384db3..dd78ea59a8ee89a508173747ebd6206b139de0cc 100644 (file)
@@ -37,8 +37,8 @@
 #  0x201f   0         0x00000000           0x00000000
 
 # AUX
-  0x2000   0         0xffffffff           0x0000ffff
-  0x2001   0         0x0000ffff           0x00000000
+  0x2000   0         0x00000000           0x00000000
+  0x2001   0         0x00000000           0x00000000
   0x2002   0         0x00000000           0x00000000
   0x2003   0         0x00000000           0x00000000
   0x2004   0         0x00000000           0x00000000
index d7921a54689fe14ce057821dd02dc9373e90042d..3e7146927af33f0482f99ba849c9d9daf56bbaef 100755 (executable)
@@ -17,7 +17,7 @@
  0x8002     0     0x8002    0x00020001   0x00030064     0x1DE8       0x578         1          1           1            1                0x0 
  0x8003     0     0x8003    0x00020001   0x00030064     0x1DE8       0x578         1          1           1            1                0x0 
  0x8004     0     0x8004    0x00020001   0x00030064     0x1DE8       0x578         1          1           1            1                0x0 
- 0x8005     0     0x8005    0x00020001   0x00030064     0x1DE8       0x578         1          1           1            1                0x0 
+ 0x8005     0     0x8005    0x00020001   0x00030064     0x1DE8       0x578         0          1           1            1                0x0 
 # 0x8006     0     0x8006    0x00020001   0x00030064     0x1DE8       0x578         1          1           1            1                0x0 
 # 0x8007     0     0x8007    0x00020001   0x00030064     0x1DE8       0x578         1          1           1            1                0x0 
 # 0x8008     0     0x8008    0x00020001   0x00030064     0x1DE8       0x578         1          1           1            1                0x0 
index a30d0c03e95c04ab8650237b050480b48528bb9d..5a08c342add15600fd713d30f28638311bd10be9 100755 (executable)
@@ -36,7 +36,7 @@
  0x8002        0   0x1e04f334    0x000e      0xc0a80003      0xc352     0xdead8002     0x001b   0xc0a80003      0xc353     0x0578
  0x8003        0   0x1e04f334    0x000e      0xc0a80003      0xc353     0xdead8003     0x001b   0xc0a80004      0xc354     0x0578
  0x8004        0   0x1e04f334    0x000e      0xc0a80003      0xc354     0xdead8004     0x001b   0xc0a80005      0xc355     0x0578
- 0x8005        0   0x1e04f330    0x000e      0xc0a80003      0xc355     0xdead8005     0x001b   0xc0a80006      0xc350     0x0578
+ 0x8005        0   0x1e04f334    0x000e      0xc0a80003      0xc355     0xdead8005     0x001b   0xc0a80006      0xc356     0x0578
 # 0x8006        0   0x1e04f330    0x000e      0xc0a80003      0xc356     0xdead8006     0x001b   0xc0a80007      0xc357     0x0578
 # 0x8007        0   0x1e04f330    0x000e      0xc0a80003      0xc357     0xdead8007     0x001b   0xc0a80008      0xc358     0x0578
 # 0x8008        0   0x1e04f330    0x000e      0xc0a80003      0xc358     0xdead8008     0x001b   0xc0a80009      0xc359     0x0578
index 9786d493af2628d152e654ac44bf51d52ddce5c8..fa1c79830166737e45a106fb3732ee194df6ac38 100755 (executable)
@@ -55,6 +55,9 @@ echo "registers configgbe_ip"
 # standard TDCs
 trbcmd clearbit 0xfe4c 0xc800 0x2000 ## clear bit to reset the epoch and coarse counters
 trbcmd w 0xfe4c 0xc800 0x00002000 ## TDC-Control-Register, RTniceM
+#
+trbcmd clearbit 0xfe51 0xc800 0x2000 ## clear bit to reset the epoch and coarse counters
+trbcmd w 0xfe51 0xc800 0x00002000 ## TDC-Control-Register, RTniceM
 #trbcmd w 0xfe4c 0xc800 0x00003000 ## Triggerless   mode
 #trbcmd w 0xfe4c 0xc801 0x000f0005 ## trigger window enable & trigger window width
 #trbcmd w 0xfe4c 0xc800 0x00000001 ## logic analyser control register
@@ -62,12 +65,17 @@ trbcmd w 0xfe4c 0xc800 0x00002000 ## TDC-Control-Register, RTniceM
 
 #trbcmd w 0xfe4c 0xc801 0x801e0046 ##  triggerwindow -350...+150ns ;5ns granularity (Experiment cern2015)
 trbcmd w 0xfe4c 0xc801 0x80c600c6 ##  triggerwindow +/-990ns ;5ns granularity
+trbcmd w 0xfe51 0xc801 0x80c600c6 ##  triggerwindow +/-990ns ;5ns granularity
 #trbcmd w 0xfe4c 0xc801 0x8000001e ##  triggerwindow +/-150ns ;5ns granularity
 
 # Default TDC-channel enable for all channels
 trbcmd w 0xfe4c 0xc802 0xffffffff ## channel 01-32 enable
 trbcmd w 0xfe4c 0xc803 0x0000ffff ## channel 33-64 enable
 trbcmd w 0xfe4c 0xc804 0x0000007c ## data transfer limit
+#
+trbcmd w 0xfe51 0xc802 0xffffffff ## channel 01-32 enable
+trbcmd w 0xfe51 0xc803 0x0000ffff ## channel 33-64 enable
+trbcmd w 0xfe51 0xc804 0x0000007c ## data transfer limit
 
 # TOFs time windows
 #trbcmd w 0x2014 0xc801 0x8000008c
@@ -105,6 +113,14 @@ trbcmd w 0xfe4a 0xc803 0x00000000 ## channel 33-64 enable
 trbcmd w 0xfe4a 0xc804 0x0000007c ## data transfer limit
 
 
+
+
+#Dirich-Concentrator: enable reference time from RJ45
+trbcmd loadbit 0x8300 0xd580 0x6 0x6
+
+
+
+
 echo -n "register_config_tdc"
 ~/trbsoft/daqtools/tools/loadregisterdb.pl register_config_tdc.db
 
@@ -141,12 +157,12 @@ trbcmd i 0xffff | wc -l
 #20170822 prepare_padiwas_invert_leds.pl --endpoints=0x2000..0x2003 --chains=0..2 --invert=0xffff 
 
 
-prepare_padiwas_invert_leds.pl --endpoints=0x2000..0x200f --chains=0..2 --invert=0xffff 
+#prepare_padiwas_invert_leds.pl --endpoints=0x2000..0x200f --chains=0..2 --invert=0xffff 
 
 #Invert erlangen
-prepare_padiwas_invert_leds.pl --endpoints=0x2014..0x201d --chains=0..1 --invert=0xffff 
+#prepare_padiwas_invert_leds.pl --endpoints=0x2014..0x201d --chains=0..1 --invert=0xffff 
 
-padiwa_led_off.pl
+#padiwa_led_off.pl
 
 #invert Erlangen Padiwas
 #~/trbsoft/daqtools/users/gsi_dirc/setup_erlangen.sh
@@ -189,7 +205,8 @@ trbcmd w 0xfffe 0xc5 0x800050ff
 #trbcmd setbit 0x8000 0xa1d4 0x10000 ## ???
 
 
-cd ~/trbsoft/daqtools/thresholds/
+cd ~/trbsoft/daqtools/thresholds/trb_dirich_threshold
+
 # july ./load_thresh_orig.sh  # 1mV
 # switch 8/27 ./load_thresh_aug2014.sh  # 4mV for first few days
 ## ./load_thresh_sep2014-2mV.sh  # 2mV starting evening Sep 8
@@ -269,14 +286,14 @@ echo "padiwa_threshold_results loading"
 #./write_thresholds.pl mcp04.log -o 600
 #./write_thresholds.pl mcp05.log -o 600
 #./write_thresholds.pl mcp06.log -o 600
-./write_thresholds.pl padiwa_threshold_results.log -o 600
+#                  ./write_thresholds.pl padiwa_threshold_results.log -o 600
 
 #./write_thresholds.pl mcp08.log -o 900 #20170911
 #./write_thresholds.pl mcp09.log -o 600 #20170912
 #./write_thresholds.pl mcp10.log -o 600
 #./write_thresholds.pl mcp11.log -o 600
 
-
+./HADESthreshscan_v1 -f 20190403_141628_std_save.thr -l 0 -t 0 2300
 # 10/26 quick fix to set special threshold for 0x2006/0 = +1mV
 #grep '0x2006' padiwa_threshold_results_latest.log | grep 'chain: 00' >! padiwa_thresholds_current_0x2006-0.txt
 #./write_thresholds.pl padiwa_thresholds_current_0x2006-0.txt -o 1000
@@ -317,5 +334,13 @@ trbcmd w 0xc000 0xa155 0x05f5e100  #1Hz pulser
 # js 20170909 ttrbcmd loadbit 0xc000 0xa159 0x00000f00 0x00000d00  #Pulser 1 is calibration
 
 
+
+trbcmd w 0xfe51 0xdf80 0xffffffff # enable monitor counters
+
+
+
+
+
+
 # disable all triggers
 #trbcmd setbit 0xc000 0xa00c 0x80000000