7 #include "PixTestSetPh.hh"
18 :
PixTest(a, name), fParNtrig(-1)
25 PixTestSetPh::PixTestSetPh() :
PixTest()
34 for( uint32_t i = 0; i <
fParameters.size(); ++i ) {
40 if( !parName.compare(
"ntrig" ) )
41 fParNtrig = atoi( sval.c_str() );
43 if( !parName.compare(
"pix1" ) ) {
44 string::size_type s1 = sval.find(
"," );
45 if( string::npos != s1 ) {
46 string str1 = sval.substr(0, s1);
47 uint16_t pixc = atoi( str1.c_str() );
48 string str2 = sval.substr(s1+1);
49 uint16_t pixr = atoi( str2.c_str() );
50 fPIX.push_back( make_pair( pixc, pixr ) );
53 fPIX.push_back( make_pair( -1, -1 ) );
63 void PixTestSetPh::init()
65 LOG(logINFO) <<
"PixTestSetPh::init()";
67 fDirectory = gFile->GetDirectory( fName.c_str() );
76 fTestTip = string(
"tune PH into ADC range using VOffsetRO and VIref_ADC");
77 fSummaryTip = string(
"summary plot to be implemented");
81 void PixTestSetPh::bookHist(
string name)
83 LOG(logDEBUG) <<
"nothing done with " << name;
87 PixTestSetPh::~PixTestSetPh()
89 LOG(logDEBUG) <<
"PixTestSetPh dtor";
90 std::list<TH1*>::iterator il;
93 LOG(logINFO) <<
"Write out " << (*il)->GetName();
102 LOG(logINFO) <<
"PixTestSetPh::doTest() ntrig = " << fParNtrig;
108 if(
fPIX.size() < 1 ) {
109 LOG(logWARNING) <<
"PixTestSetCalDel: no pixel defined, return";
113 if(
fPIX[
fPIX.size()-1].first < 0 ) {
114 LOG(logWARNING) <<
"PixTestSetCalDel: no valid pixel defined, return";
124 LOG(logINFO) <<
"CtrlReg 4 (large Vcal)";
131 const int max_vcal = 255;
139 int32_t col =
fPIX[
fPIX.size()-1].first;
140 int32_t row =
fPIX[
fPIX.size()-1].second;
145 size_t nRocs =
fPixSetup->getConfigParameters()->getNrocs();
152 for(
size_t i = 0; i < 16; ++i ) {
161 for(
size_t roc = 0; roc < nRocs; ++roc )
166 std::vector<pixel> vpix =
169 LOG(logINFO) <<
"vpix size " << vpix.size();
173 for(
size_t ipx = 0; ipx < vpix.size(); ++ipx ) {
174 uint8_t roc = vpix[ipx].roc();
176 pix_ph[roc] = vpix[ipx].value();
177 LOG(logINFO) <<
"ipx " << setw(2) << ipx
178 <<
": ROC " << setw(2) << (int) vpix[ipx].roc()
179 <<
" col " << setw(2) << (int) vpix[ipx].column()
180 <<
" row " << setw(2) << (int) vpix[ipx].row()
181 <<
" val " << setw(3) << (int) vpix[ipx].value();
187 for(
size_t roc = 0; roc < nRocs; ++roc ) {
188 if( pix_ph[roc] <= 0 ) {
192 if( min_vcal[roc] > 120 ) too_much = 1;
195 while( not_enough && !too_much );
199 <<
"[SetPh] Cannot find working Vcal for pixel "
201 <<
". Please use other pixel or re-trim to lower threshold";
205 for(
size_t roc = 0; roc < nRocs; ++roc ) {
208 LOG(logINFO) <<
"ROC " << setw(2) << roc
209 <<
" min Vcal " << setw(2) << min_vcal[roc]
210 <<
" has Ph " << setw(3) << pix_ph[roc];
216 for(
size_t roc = 0; roc < nRocs; ++roc )
219 string dacName =
"VOffsetRO";
220 vector<pair<uint8_t, vector<pixel> > >
228 for(
size_t roc = 0; roc < nRocs; ++roc ) {
230 h1 =
new TH1D( Form(
"PH_vs_%s_at_Vcal_%2d_c%02d_r%02d_C%02d",
231 dacName.c_str(), min_vcal[roc],
232 col, row, int(roc) ),
233 Form(
"PH vs %s at Vcal %2d c%02d r%02d C%02d",
234 dacName.c_str(), min_vcal[roc],
235 col, row, int(roc) ),
239 setTitles( h1, Form(
"%s [DAC]", dacName.c_str() ),
240 Form(
"Vcal %2d <PH> [ADC]", min_vcal[roc] ) );
248 for(
size_t i = 0; i < result.size(); ++i ) {
250 int idac = result[i].first;
252 vector<pixel> vpix = result[i].second;
254 for(
size_t ipx = 0; ipx < vpix.size(); ++ipx ) {
256 uint8_t roc = vpix[ipx].roc();
259 vpix[ipx].column() == col &&
260 vpix[ipx].row() == row ) {
262 h1->Fill( idac, vpix[ipx].value());
269 for(
size_t roc = 0; roc < nRocs; ++roc ) {
286 for(
size_t roc = 0; roc < nRocs; ++roc ) {
288 h1 =
new TH1D( Form(
"PH_vs_%s_at_Vcal_%2d_c%02d_r%02d_C%02d",
289 dacName.c_str(), max_vcal,
290 col, row, int(roc) ),
291 Form(
"PH vs %s at Vcal %2d c%02d r%02d C%02d",
292 dacName.c_str(), max_vcal,
293 col, row, int(roc) ),
297 setTitles( h1, Form(
"%s [DAC]", dacName.c_str() ),
298 Form(
"Vcal %2d <PH> [ADC]", max_vcal ) );
306 for(
size_t i = 0; i < result.size(); ++i ) {
308 int idac = result[i].first;
310 vector<pixel> vpix = result[i].second;
312 for(
size_t ipx = 0; ipx < vpix.size(); ++ipx ) {
314 uint8_t roc = vpix[ipx].roc();
317 vpix[ipx].column() == col &&
318 vpix[ipx].row() == row ) {
320 h1->Fill( idac, vpix[ipx].value());
327 for(
size_t roc = 0; roc < nRocs; ++roc ) {
338 for(
size_t i = 0; i < 16; ++i )
341 for(
size_t roc = 0; roc < nRocs; ++roc ) {
343 for(
int i = 0; i < 256; ++i ) {
344 int ph0 =
static_cast<int>(hmin[roc]->GetBinContent(i+1));
345 if( ph0 <= 0 )
continue;
346 int ph4 =
static_cast<int>(hmax[roc]->GetBinContent(i+1));
347 if( ph4 <= 0 )
continue;
349 LOG(logINFO) <<
"VOffsetRO " << setw(3) << i
350 <<
": min " << setw(3) << ph0
351 <<
", max " << setw(3) << ph4
352 <<
", mid " << setw(3) << (ph0+ph4)/2;
354 if( ( ph0 + ph4 ) / 2 < 133 ) {
355 voffset_opt[roc] = i;
363 for(
size_t roc = 0; roc < nRocs; ++roc ) {
365 if( voffset_opt[roc] == -1 ) {
367 <<
"[SetPh] Warning: Cannot find VoffsetOp midpoint!";
372 <<
"[SetPh] Found VOffsetRO value: "
375 fApi->
setDAC(
"VOffsetRO", voffset_opt[roc], roc );
383 <<
"[SetPh] Finding mid VIref_ADC value ...";
389 dacName =
"VIref_ADC";
397 for(
size_t roc = 0; roc < nRocs; ++roc ) {
399 h1 =
new TH1D( Form(
"PH_vs_%s_at_Vcal_%2d_c%02d_r%02d_C%02d",
400 dacName.c_str(), max_vcal,
401 col, row, int(roc) ),
402 Form(
"PH vs %s at Vcal %2d c%02d r%02d C%02d",
403 dacName.c_str(), max_vcal,
404 col, row, int(roc) ),
408 setTitles( h1, Form(
"%s [DAC]", dacName.c_str() ),
409 Form(
"Vcal %2d <PH> [ADC]", max_vcal ) );
417 for(
size_t i = 0; i < result.size(); ++i ) {
419 int idac = result[i].first;
421 vector<pixel> vpix = result[i].second;
423 for(
size_t ipx = 0; ipx < vpix.size(); ++ipx ) {
425 uint8_t roc = vpix[ipx].roc();
428 vpix[ipx].column() == col &&
429 vpix[ipx].row() == row ) {
431 h1->Fill( idac, vpix[ipx].value());
438 for(
size_t roc = 0; roc < nRocs; ++roc ) {
446 int viref_adc_opt[16];
447 for(
size_t i = 0; i < 16; ++i )
448 viref_adc_opt[i] = -1;
450 for(
size_t roc = 0; roc < nRocs; ++roc ) {
451 for(
int i = 0; i < 256; ++i ) {
452 int ph =
static_cast<int>(href[roc]->GetBinContent(i+1));
453 if( ph <= 0 )
continue;
455 viref_adc_opt[roc] = i;
462 if( viref_adc_opt[roc] == -1 ) {
464 <<
"[SetPh] Warning: Cannot adjust pulse height range!";
468 <<
"[SetPh] Found VIref_ADC value: "
469 << viref_adc_opt[roc];
470 fApi->
setDAC( dacName, viref_adc_opt[roc], roc );
486 for(
size_t roc = 0; roc < nRocs; ++roc ) {
488 h2 =
new TH2D( Form(
"maxPhMap_C%d",
int(roc) ),
489 Form(
"max PH map ROC %d",
int(roc) ),
490 52, -0.5, 51.5, 80, -0.5, 79.5 );
494 h2->GetZaxis()->SetTitle(
"<PH> [ADC]" );
499 h1 =
new TH1D( Form(
"maxPhDistribution_C%d",
int(roc) ),
500 Form(
"max Pulse height distribution ROC %d",
int(roc) ),
517 LOG(logINFO) <<
"vpix.size() " << vpix.size();
521 for(
size_t ipx = 0; ipx < vpix.size(); ++ipx ) {
522 h2 = maps9.at( vpix[ipx].roc() );
523 if( h2 ) h2->SetBinContent( vpix[ipx].column() + 1, vpix[ipx].row() + 1,
525 h1 = hsts9.at( vpix[ipx].roc() );
526 if( h1 ) h1->Fill( vpix[ipx].value());
529 for(
size_t roc = 0; roc < nRocs; ++roc ) {
540 for(
size_t roc = 0; roc < nRocs; ++roc ) {
542 LOG(logINFO) <<
"max Ph map for ROC " << roc;
544 Int_t locmaxx,locmaxy,locmaxz;
546 h2->GetMaximumBin( locmaxx, locmaxy,locmaxz );
547 double phmax = h2->GetBinContent( locmaxx, locmaxy );
549 <<
"Ph max " << setw(3) << phmax
550 <<
" at " << setw(2) << locmaxx-1
551 <<
"," << setw(2) << locmaxy-1;
552 if( phmax > 254.5 ) {
553 voffset_opt[roc] += 5;
554 viref_adc_opt[roc] += 3;
555 fApi->
setDAC(
"VOffsetRO", voffset_opt[roc], roc );
556 fApi->
setDAC(
"VIref_ADC", viref_adc_opt[roc], roc );
559 <<
" VoffsetOp " << setw(3) << voffset_opt[roc]
560 <<
" VIref_ADC " << setw(3) << viref_adc_opt[roc];
561 if( voffset_opt[roc] < 251 && viref_adc_opt[roc] < 253 ) {
579 for(
size_t roc = 0; roc < nRocs; ++roc ) {
581 h2 =
new TH2D( Form(
"minPhMap_C%d",
int(roc) ),
582 Form(
"min PH map ROC %d",
int(roc) ),
583 52, -0.5, 51.5, 80, -0.5, 79.5 );
587 h2->GetZaxis()->SetTitle(
"<PH> [ADC]" );
592 h1 =
new TH1D( Form(
"minPhDistribution_C%d",
int(roc) ),
593 Form(
"min Pulse height distribution ROC %d",
int(roc) ),
603 for(
size_t roc = 0; roc < nRocs; ++roc )
606 LOG(logINFO) <<
"check against underflow...";
612 LOG(logINFO) <<
"vpix.size() " << vpix.size();
617 for(
size_t roc = 0; roc < nRocs; ++roc ) {
619 for(
int ix = 0; ix < h2->GetNbinsX(); ++ix )
620 for(
int iy = 0; iy < h2->GetNbinsY(); ++iy )
621 h2->SetBinContent( ix + 1, iy + 1, 256 );
626 for(
size_t ipx = 0; ipx < vpix.size(); ++ipx ) {
627 if( vpix[ipx].roc() == 0 &&
628 vpix[ipx].column() == 0 &&
629 vpix[ipx].row() == 0 &&
630 vpix[ipx].value() == 0 ) {
631 LOG(logINFO) <<
"vpix[" << ipx <<
"] all zero, skipped";
634 h2 = maps0.at( vpix[ipx].roc() );
635 if( h2 ) h2->SetBinContent( vpix[ipx].column() + 1, vpix[ipx].row() + 1,
637 h1 = hsts0.at( vpix[ipx].roc() );
638 if( h1 ) h1->Fill( vpix[ipx].value());
641 for(
size_t roc = 0; roc < nRocs; ++roc ) {
652 for(
size_t roc = 0; roc < nRocs; ++roc ) {
654 LOG(logINFO) <<
"min Ph map for ROC " << roc;
656 Int_t locminx,locminy,locminz;
658 h2->GetMinimumBin( locminx, locminy,locminz );
659 double phmin = h2->GetBinContent( locminx, locminy );
661 <<
"Ph min " << setw(3) << phmin
662 <<
" at " << setw(2) << locminx-1
663 <<
"," << setw(2) << locminy-1;
665 voffset_opt[roc] -= 5;
666 viref_adc_opt[roc] += 3;
667 fApi->
setDAC(
"VOffsetRO", voffset_opt[roc], roc );
668 fApi->
setDAC(
"VIref_ADC", viref_adc_opt[roc], roc );
670 <<
"Found underflow "
671 <<
" VoffsetOp " << setw(3) << voffset_opt[roc]
672 <<
" VIref_ADC " << setw(3) << viref_adc_opt[roc];
673 if( voffset_opt[roc] > 4 && viref_adc_opt[roc] < 253 ) {
699 for(
size_t roc = 0; roc < nRocs; ++roc ) {
701 LOG(logINFO) <<
"Ph range fine tuning for ROC " << roc;
703 Int_t locminx,locminy,locminz;
705 h2->GetMinimumBin( locminx, locminy,locminz );
706 double min_ph = h2->GetBinContent( locminx, locminy );
707 uint32_t min_col = locminx - 1;
708 uint32_t min_row = locminy - 1;
710 <<
"Ph min " << setw(3) << min_ph
711 <<
" at " << setw(2) << min_col
712 <<
"," << setw(2) << min_row;
714 Int_t locmaxx,locmaxy,locmaxz;
716 h2->GetMaximumBin( locmaxx, locmaxy,locmaxz );
717 double max_ph = h2->GetBinContent( locmaxx, locmaxy );
718 uint32_t max_col = locmaxx - 1;
719 uint32_t max_row = locmaxy - 1;
721 <<
"Ph max " << setw(3) << max_ph
722 <<
" at " << setw(2) << max_col
723 <<
"," << setw(2) << max_row;
725 int range =
static_cast<int>(max_ph - min_ph);
726 int mid =
static_cast<int>(max_ph + min_ph)/2;
731 while( ( abs(range-200) > 5 || abs(mid-133) > 5 ) &&
732 voffset_opt[roc] < 255 &&
733 voffset_opt[roc] > 0 &&
734 viref_adc_opt[roc] < 255 &&
735 viref_adc_opt[roc] > 0 ) {
739 <<
". gain_dac " << setw(3) << viref_adc_opt[roc]
740 <<
", offset_dac " << setw(3) << voffset_opt[roc]
741 <<
": min_ph " << setw(3) << min_ph
742 <<
", max_ph " << setw(3) << max_ph
743 <<
": range " << setw(3) << range
744 <<
", mid " << setw(3) << mid
750 if( abs(dmid) > 5 ) {
751 voffset_opt[roc] -= dmid/2;
752 if( voffset_opt[roc] < 0 )
753 voffset_opt[roc] = 0;
754 else if( voffset_opt[roc] > 255 )
755 voffset_opt[roc] = 255;
756 fApi->
setDAC(
"VOffsetRO", voffset_opt[roc] );
760 fApi->
setDAC(
"VIref_ADC", ++viref_adc_opt[roc], roc );
761 else if( range < 195 )
762 fApi->
setDAC(
"VIref_ADC", --viref_adc_opt[roc], roc );
768 for(
size_t ipx = 0; ipx < vpix0.size(); ++ipx )
769 if( vpix0[ipx].roc() == roc &&
770 vpix0[ipx].column() == min_col &&
771 vpix0[ipx].row() == min_row )
772 min_ph = vpix0[ipx].value();
778 for(
size_t ipx = 0; ipx < vpix9.size(); ++ipx )
779 if( vpix9[ipx].roc() == roc &&
780 vpix9[ipx].column() == max_col &&
781 vpix9[ipx].row() == max_row )
782 max_ph = vpix9[ipx].value();
785 range =
static_cast<int>(max_ph - min_ph);
786 mid =
static_cast<int>(max_ph + min_ph)/2;
792 <<
". gain_dac " << setw(3) << viref_adc_opt[roc]
793 <<
", offset_dac " << setw(3) << voffset_opt[roc]
794 <<
", min_ph " << setw(3) << min_ph
795 <<
", max_ph " << setw(3) << max_ph
796 <<
", range " << setw(3) << range
797 <<
", mid " << setw(3) << mid
800 LOG(logINFO) <<
"SetPh Final for ROC " << setw(2) << roc;
801 LOG(logINFO) <<
" 17 VOffsetRO "
803 LOG(logINFO) <<
" 20 VIref_ADC "
810 LOG(logINFO) <<
"back to CtrlReg " << int(ctl);
812 LOG(logINFO) <<
"PixTestSetPh::doTest() done for " << nRocs <<
" ROCs";
std::vector< pixel > getPulseheightMap(uint16_t flags, uint16_t nTriggers)
std::vector< std::pair< uint8_t, std::vector< pixel > > > getPulseheightVsDAC(std::string dacName, uint8_t dacMin, uint8_t dacMax, uint16_t flags, uint16_t nTriggers)
bool setDAC(std::string dacName, uint8_t dacValue, uint8_t rocI2C)
PixSetup * fPixSetup
all necessary stuff in one place
std::vector< std::pair< int, int > > fPIX
range of enabled pixels for time-consuming tests
void testPixel(uint8_t column, uint8_t row, bool enable)
std::vector< std::pair< std::string, std::string > > fParameters
the parameters of this test
TDirectory * fDirectory
where the root histograms will end up
void testAllPixels(bool enable)
std::list< TH1 * >::iterator fDisplayedHist
pointer to the histogram currently displayed
virtual bool setParameter(std::string parName, std::string sval)
set the string value of a parameter
std::list< TH1 * > fHistList
list of histograms available in PixTab::next and PixTab::previous
void setTitles(TH1 *h, const char *sx, const char *sy, float size=0.05, float xoff=1.1, float yoff=1.1, float lsize=0.05, int font=42)
utility to set histogram titles
void update()
signal to PixTab to update the canvas
uint8_t getDAC(size_t rocId, std::string dacName)
void setToolTips()
implement this to provide updated tool tips if the user changes test parameters
void doTest()
function connected to "DoTest" button of PixTab
pxar::pxarCore * fApi
pointer to the API
void init()
sets all test parameters