--- /dev/null
+#!/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";
+
--- /dev/null
+
+*.root
+*.thr
+*~
+
--- /dev/null
+// #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;
+}
--- /dev/null
+# 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)
--- /dev/null
+# 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.
--- /dev/null
+#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);
+ }
+ }
+}
--- /dev/null
+#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);
+ }
+ }
+}
--- /dev/null
+#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;
+}
--- /dev/null
+#include "trbnet.h"
+#include "trberror.h"
+#include <iostream>
+
+int main (int arc, char** argv){
+ std::cout << init_ports() << trb_strerror() << std::endl;
+}
--- /dev/null
+export LD_LIBRARY_PATH=/home/hadaq/trbsoft/analysis/trb3/rootbuild/lib:/home/hadaq/trbsoft/trbnettools//lib:/usr/lib:"$LD_LIBRARY_PATH"
--- /dev/null
+#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
<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"/>
<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"/>
<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"/>
--- /dev/null
+#!/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;
+
--- /dev/null
+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
+
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;
if(!defined $old) {
- $c=qq|pkill -f "dabc_exe"|;
+
+
+ $c=qq|pkill -f "dabc_exe"|;
qx($c);
my $pathandfile = "$dataPath/$name.hld";
}
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";
#$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'";
# 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
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
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
# 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
#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
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
#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
#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
#./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
# 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