7 #include "PixTestHighRate.hh"
9 #include "TStopwatch.h"
24 fParTriggerFrequency(0), fParRunSeconds(0), fParTriggerDelay(20),
25 fParFillTree(false), fParDelayTBM(false), fParNtrig(5), fParVcal(200),
26 fParMaskFileName("default"), fParSaveMaskedPixels(0) {
29 LOG(logDEBUG) <<
"PixTestHighRate ctor(PixSetup &a, string, TGTab *)";
32 fPhCal.setPHParameters(fPixSetup->getConfigParameters()->getGainPedestalParameters());
33 fPhCalOK = fPhCal.initialized();
38 PixTestHighRate::PixTestHighRate() :
PixTest() {
39 LOG(logDEBUG) <<
"PixTestHighRate ctor()";
50 std::transform(parName.begin(), parName.end(), parName.begin(), ::tolower);
51 for (
unsigned int i = 0; i <
fParameters.size(); ++i) {
54 if (!parName.compare(
"savemaskfile")) {
57 fParSaveMaskedPixels = !(atoi(sval.c_str())==0);
60 if (!parName.compare(
"maskfilename")) {
61 fParMaskFileName = sval;
64 if (!parName.compare(
"trgfrequency(khz)")) {
65 fParTriggerFrequency = atoi(sval.c_str());
66 LOG(logDEBUG) <<
" setting fParTriggerFrequency -> " << fParTriggerFrequency;
69 if (!parName.compare(
"runseconds")) {
70 fParRunSeconds = atoi(sval.c_str());
73 if (!parName.compare(
"triggerdelay")) {
74 fParTriggerDelay = atoi(sval.c_str());
77 if (!parName.compare(
"delaytbm")) {
80 fParDelayTBM = !(atoi(sval.c_str())==0);
83 if (!parName.compare(
"filltree")) {
86 fParFillTree = !(atoi(sval.c_str())==0);
89 if (!parName.compare(
"ntrig")) {
90 fParNtrig =
static_cast<uint16_t
>(atoi(sval.c_str()));
93 if (!parName.compare(
"vcal")) {
94 fParVcal = atoi(sval.c_str());
97 if (!parName.compare(
"pix") || !parName.compare(
"pix1") ) {
99 if (string::npos != s1) {
100 str1 = sval.substr(0, s1);
101 pixc = atoi(str1.c_str());
102 str2 = sval.substr(s1+1);
103 pixr = atoi(str2.c_str());
105 fPIX.push_back( make_pair(pixc, pixr) );
110 LOG(logDEBUG) <<
" clear fPIX: " <<
fPIX.size();
124 std::transform(command.begin(), command.end(), command.begin(), ::tolower);
125 LOG(logDEBUG) <<
"running command: " << command;
127 if (!command.compare(
"stop")){
131 if (!command.compare(
"maskhotpixels")) {
132 doRunMaskHotPixels();
136 if (!command.compare(
"rundaq")) {
141 if (!command.compare(
"xpixelalive")) {
146 if (!command.compare(
"caldelscan")) {
151 LOG(logDEBUG) <<
"did not find command ->" << command <<
"<-";
155 void PixTestHighRate::init() {
156 LOG(logDEBUG) <<
"PixTestHighRate::init()";
158 fDirectory = gFile->GetDirectory(fName.c_str());
168 fTestTip = string(
"Xray vcal calibration test")
170 fSummaryTip = string(
"to be implemented")
172 fStopTip = string(
"Stop 'rundaq' and save data.")
178 void PixTestHighRate::bookHist(
string name) {
183 unsigned nrocs = rocIds.size();
187 for (
unsigned int iroc = 0; iroc < nrocs; ++iroc){
188 h2 =
bookTH2D(Form(
"hitMap_%s_C%d", name.c_str(), rocIds[iroc]), Form(
"hitMap_%s_C%d", name.c_str(), rocIds[iroc]),
189 52, 0., 52., 80, 0., 80.);
193 fHitMap.push_back(h2);
196 copy(fHitMap.begin(), fHitMap.end(), back_inserter(
fHistList));
202 PixTestHighRate::~PixTestHighRate() {
203 LOG(logDEBUG) <<
"PixTestHighRate dtor";
205 if (fTree && fParFillTree) fTree->Write();
211 bigBanner(Form(
"PixTestHighRate::doTest()"));
212 doRunMaskHotPixels();
216 LOG(logINFO) <<
"PixTestHighRate::doTest() done ";
220 void PixTestHighRate::doCalDelScan() {
222 uint16_t FLAGS = FLAG_FORCE_MASKED;
225 banner(Form(
"PixTestHighRate::calDelScan() ntrig = %d, vcal = %d", ntrig, fParVcal));
242 vector<pair<uint8_t, vector<pixel> > > results;
250 LOG(logCRITICAL) <<
"problem with readout: "<< e.what() <<
" missing " << e.numberMissing <<
" events";
252 if (e.numberMissing > 10) done =
true;
254 LOG(logCRITICAL) <<
"pXar execption: "<< e.what();
257 done = (cnt>5) || done;
268 for (
unsigned int iroc = 0; iroc < rocIds.size(); ++iroc){
269 h1 =
bookTH1D(Form(
"hrCalDelScan_C%d", rocIds[iroc]), Form(
"hrCalDelScan_C%d", rocIds[iroc]), 256, 0., 256.);
277 for (
unsigned int i = 0; i < results.size(); ++i) {
278 int caldel = results[i].first;
279 vector<pixel> pixels = results[i].second;
280 for (
unsigned int ipix = 0; ipix < pixels.size(); ++ipix) {
284 h1->Fill(caldel, pixels[ipix].value());
286 LOG(logDEBUG) <<
"no histogram found for ROC " << pixels[ipix].roc() <<
" with index " << idx;
291 vector<int> calDelLo(rocIds.size(), -1);
292 vector<int> calDelHi(rocIds.size(), -1);
293 int DeltaCalDelMax(-1), reserve(1);
294 for (
unsigned int iroc = 0; iroc < rocIds.size(); ++iroc){
295 double cdMax = maps[iroc]->GetMaximum();
296 calDelLo[iroc] =
static_cast<int>(maps[iroc]->GetBinLowEdge(maps[iroc]->FindFirstBinAbove(0.8*cdMax) + reserve));
297 calDelHi[iroc] =
static_cast<int>(maps[iroc]->GetBinLowEdge(maps[iroc]->FindLastBinAbove(0.8*cdMax) - reserve));
298 if (calDelHi[iroc] - calDelLo[iroc] > DeltaCalDelMax) {
299 DeltaCalDelMax = calDelHi[iroc] - calDelLo[iroc];
306 for (
unsigned int i = 0; i < fHotPixels.size(); ++i) {
307 vector<pair<int, int> > hot = fHotPixels[i];
308 for (
unsigned int ipix = 0; ipix < hot.size(); ++ipix) {
309 LOG(logINFO) <<
"ROC " <<
getIdFromIdx(i) <<
" masking hot pixel " << hot[ipix].first <<
"/" << hot[ipix].second;
318 vector<pair<string, uint8_t> > pgtmp =
fPixSetup->getConfigParameters()->getTbPgSettings();
319 for (
unsigned i = 0; i < pgtmp.size(); ++i) {
320 if (string::npos != pgtmp[i].first.find(
"resetroc"))
continue;
321 if (string::npos != pgtmp[i].first.find(
"resettbm"))
continue;
322 fPg_setup.push_back(pgtmp[i]);
324 if (0)
for (
unsigned int i = 0; i < fPg_setup.size(); ++i) cout << fPg_setup[i].first <<
": " << (
int)fPg_setup[i].second << endl;
329 vector<pair<int, double> > calDelMax(rocIds.size(), make_pair(-1, -1));
330 vector<TH1D*> calDelEffHist;
331 for (
unsigned int iroc = 0; iroc < rocIds.size(); ++iroc){
333 Form(
"HR_CalDelScan_eff_C%d",
getIdFromIdx(iroc)), 256, 0., 256);
334 calDelEffHist.push_back(h1);
338 for (
int istep = 0; istep < nsteps; ++istep) {
340 for (
unsigned int iroc = 0; iroc < rocIds.size(); ++iroc){
341 int caldel = calDelLo[iroc] + istep*(calDelHi[iroc]-calDelLo[iroc])/(nsteps-1);
346 pair<vector<TH2D*>,vector<TH2D*> > tests =
xEfficiencyMaps(Form(
"HR_xeff_CalDelScan_step%d", istep),
347 ntrig, FLAG_CHECK_ORDER | FLAG_FORCE_UNMASKED);
348 vector<TH2D*> test2 = tests.first;
349 for (
unsigned int iroc = 0; iroc < test2.size(); ++iroc) {
352 Form(
"HR_CalDelScan_step%d_C%d", istep,
getIdFromIdx(iroc)), 201, 0., 1.005);
354 for (
int ix = 0; ix < test2[iroc]->GetNbinsX(); ++ix) {
355 for (
int iy = 0; iy < test2[iroc]->GetNbinsY(); ++iy) {
356 h1->Fill(test2[iroc]->GetBinContent(ix+1, iy+1)/ntrig);
360 calDelEffHist[iroc]->SetBinContent(caldel, h1->GetMean());
362 if (h1->GetMean() > calDelMax[iroc].second) {
363 calDelMax[iroc].first = caldel;
364 calDelMax[iroc].second = h1->GetMean();
368 for (
unsigned int i = 0; i < tests.first.size(); ++i) {
369 delete tests.first[i];
370 delete tests.second[i];
373 tests.second.clear();
377 for (
unsigned int i = 0; i < calDelMax.size(); ++i) {
378 LOG(logDEBUG) <<
"roc " << Form(
"%2d", i) <<
": caldel = " << calDelMax[i].first <<
" eff = " << calDelMax[i].second;
379 fApi->
setDAC(
"CalDel", calDelMax[i].first, rocIds[i]);
382 copy(calDelEffHist.begin(), calDelEffHist.end(), back_inserter(
fHistList));
384 calDelEffHist[0]->Draw();
393 void PixTestHighRate::doXPixelAlive() {
395 banner(Form(
"PixTestHighRate::xPixelAlive() ntrig = %d, vcal = %d", fParNtrig, fParVcal));
400 vector<pair<string, uint8_t> > oldDelays =
fPixSetup->getConfigParameters()->getTbSigDelays();
402 for (
unsigned int i = 0; i < oldDelays.size(); ++i) {
403 if (oldDelays[i].first ==
"triggerdelay") {
406 LOG(logDEBUG) <<
" old set: " << oldDelays[i].first <<
": " << (int)oldDelays[i].second;
409 vector<pair<string, uint8_t> > delays =
fPixSetup->getConfigParameters()->getTbSigDelays();
411 delays.push_back(make_pair(
"triggerdelay", fParTriggerDelay));
412 oldDelays.push_back(make_pair(
"triggerdelay", 0));
414 for (
unsigned int i = 0; i < delays.size(); ++i) {
415 if (delays[i].first ==
"triggerdelay") {
416 delays[i].second = fParTriggerDelay;
421 for (
unsigned int i = 0; i < delays.size(); ++i) {
422 LOG(logDEBUG) <<
" setting: " << delays[i].first <<
": " << (int)delays[i].second;
434 for (
unsigned int i = 0; i < fHotPixels.size(); ++i) {
435 vector<pair<int, int> > hot = fHotPixels[i];
436 for (
unsigned int ipix = 0; ipix < hot.size(); ++ipix) {
437 LOG(logINFO) <<
"ROC " <<
getIdFromIdx(i) <<
" masking hot pixel " << hot[ipix].first <<
"/" << hot[ipix].second;
446 vector<pair<string, uint8_t> > pgtmp =
fPixSetup->getConfigParameters()->getTbPgSettings();
447 for (
unsigned i = 0; i < pgtmp.size(); ++i) {
448 if (string::npos != pgtmp[i].first.find(
"resetroc"))
continue;
449 if (string::npos != pgtmp[i].first.find(
"resettbm"))
continue;
450 fPg_setup.push_back(pgtmp[i]);
452 if (0)
for (
unsigned int i = 0; i < fPg_setup.size(); ++i) cout << fPg_setup[i].first <<
": " << (
int)fPg_setup[i].second << endl;
458 pair<vector<TH2D*>,vector<TH2D*> > tests =
xEfficiencyMaps(
"highRate", fParNtrig, FLAG_CHECK_ORDER | FLAG_FORCE_UNMASKED);
459 vector<TH2D*> test2 = tests.first;
460 vector<TH2D*> test3 = tests.second;
461 vector<int> deadPixel(test2.size(), 0);
462 vector<int> probPixel(test2.size(), 0);
463 vector<int> xHits(test3.size(),0);
464 vector<int> fidHits(test2.size(),0);
465 vector<int> allHits(test2.size(),0);
466 vector<int> fidPixels(test2.size(),0);
468 for (
unsigned int i = 0; i < test2.size(); ++i) {
476 for (
int ix = 0; ix < test2[i]->GetNbinsX(); ++ix) {
477 for (
int iy = 0; iy < test2[i]->GetNbinsY(); ++iy) {
478 allHits[i] +=
static_cast<int>(test2[i]->GetBinContent(ix+1, iy+1));
479 h1->Fill(test2[i]->GetBinContent(ix+1, iy+1)/fParNtrig);
480 if ((ix > 0) && (ix < 51) && (iy < 79) && (test2[i]->GetBinContent(ix+1, iy+1) > 0)) {
481 fidHits[i] +=
static_cast<int>(test2[i]->GetBinContent(ix+1, iy+1));
483 h2->Fill(test2[i]->GetBinContent(ix+1, iy+1)/fParNtrig);
486 if (test2[i]->GetBinContent(ix+1, iy+1) < fParNtrig) {
488 if (test2[i]->GetBinContent(ix+1, iy+1) < 1) {
493 if (test3[i]->GetBinContent(ix+1,iy+1)>0){
494 xHits[i] +=
static_cast<int> (test3[i]->GetBinContent(ix+1,iy+1));
500 copy(test2.begin(), test2.end(), back_inserter(
fHistList));
501 copy(test3.begin(), test3.end(), back_inserter(
fHistList));
509 double sensorArea = 0.015 * 0.010 * 54 * 81;
510 string deadPixelString, probPixelString, xHitsString, numTrigsString,
511 fidCalHitsString, allCalHitsString,
512 fidCalEfficiencyString, allCalEfficiencyString,
514 for (
unsigned int i = 0; i < probPixel.size(); ++i) {
515 probPixelString += Form(
" %4d", probPixel[i]);
516 deadPixelString += Form(
" %4d", deadPixel[i]);
517 xHitsString += Form(
" %4d", xHits[i]);
518 allCalHitsString += Form(
" %4d", allHits[i]);
519 fidCalHitsString += Form(
" %4d", fidHits[i]);
520 int numTrigs = fParNtrig * 4160;
521 numTrigsString += Form(
" %4d", numTrigs );
522 fidCalEfficiencyString += Form(
" %.1f", fidHits[i]/static_cast<double>(fidPixels[i]*fParNtrig)*100);
523 allCalEfficiencyString += Form(
" %.1f", allHits[i]/static_cast<double>(numTrigs)*100);
524 xRayRateString += Form(
" %.1f", xHits[i]/static_cast<double>(numTrigs)/25./sensorArea*1000.);
527 LOG(logINFO) <<
"number of dead pixels (per ROC): " << deadPixelString;
528 LOG(logINFO) <<
"number of red-efficiency pixels: " << probPixelString;
529 LOG(logINFO) <<
"number of X-ray hits detected: " << xHitsString;
530 LOG(logINFO) <<
"number of triggers sent (total per ROC): " << numTrigsString;
531 LOG(logINFO) <<
"number of Vcal hits detected: " << allCalHitsString;
532 LOG(logINFO) <<
"Vcal hit fiducial efficiency (%): " << fidCalEfficiencyString;
533 LOG(logINFO) <<
"Vcal hit overall efficiency (%): " << allCalEfficiencyString;
534 LOG(logINFO) <<
"X-ray hit rate [MHz/cm2]: " << xRayRateString;
535 LOG(logINFO) <<
"PixTestHighRate::doXPixelAlive() done";
540 for (
unsigned int i = 0; i < oldDelays.size(); ++i) {
541 LOG(logDEBUG) <<
" resetting: " << oldDelays[i].first <<
": " << (int)oldDelays[i].second;
549 void PixTestHighRate::doRunDaq() {
554 bookHist(
"daqbbtest");
558 banner(Form(
"PixTestHighRate::runDaq() running for %d seconds", fParRunSeconds));
567 for (
unsigned int i = 0; i < fHotPixels.size(); ++i) {
568 vector<pair<int, int> > hot = fHotPixels[i];
569 for (
unsigned int ipix = 0; ipix < hot.size(); ++ipix) {
570 LOG(logINFO) <<
"ROC " <<
getIdFromIdx(i) <<
" masking hot pixel " << hot[ipix].first <<
"/" << hot[ipix].second;
577 vector<pair<string, uint8_t> > oldDelays =
fPixSetup->getConfigParameters()->getTbSigDelays();
579 for (
unsigned int i = 0; i < oldDelays.size(); ++i) {
580 if (oldDelays[i].first ==
"triggerdelay") {
583 LOG(logDEBUG) <<
" old set: " << oldDelays[i].first <<
": " << (int)oldDelays[i].second;
586 vector<pair<string, uint8_t> > delays =
fPixSetup->getConfigParameters()->getTbSigDelays();
588 delays.push_back(make_pair(
"triggerdelay", fParTriggerDelay));
589 oldDelays.push_back(make_pair(
"triggerdelay", 0));
591 for (
unsigned int i = 0; i < delays.size(); ++i) {
592 if (delays[i].first ==
"triggerdelay") {
593 delays[i].second = fParTriggerDelay;
598 for (
unsigned int i = 0; i < delays.size(); ++i) {
599 LOG(logDEBUG) <<
" setting: " << delays[i].first <<
": " << (int)delays[i].second;
605 doHitMap(fParRunSeconds, v);
614 string zPixelString(
"");
615 for (
unsigned int i = 0; i < v.size(); ++i) {
617 LOG(logDEBUG) <<
"analyzing " << v[i]->GetName();
618 for (
int ix = 0; ix < v[i]->GetNbinsX(); ++ix) {
619 for (
int iy = 0; iy < v[i]->GetNbinsY(); ++iy) {
620 if (0 == v[i]->GetBinContent(ix+1, iy+1)) ++cnt;
623 zPixelString += Form(
" %4d ", cnt);
628 for (
unsigned int i = 0; i < oldDelays.size(); ++i) {
629 LOG(logDEBUG) <<
" resetting: " << oldDelays[i].first <<
": " << (int)oldDelays[i].second;
634 LOG(logINFO) <<
"Pixels without X-ray hits (per ROC): " << zPixelString;
635 LOG(logINFO) <<
"PixTestHighRate::doRunDaq() done";
642 void PixTestHighRate::doHitMap(
int nseconds, vector<TH2D*> h) {
644 int totalPeriod =
prepareDaq(fParTriggerFrequency, 50);
648 LOG(logINFO) <<
"PixTestHighRate::doHitMap start TriggerLoop with trigger frequency " << fParTriggerFrequency
649 <<
" kHz, period " << finalPeriod
650 <<
" and duration " << nseconds <<
" seconds";
657 gSystem->ProcessEvents();
659 seconds = t.RealTime();
660 LOG(logINFO) <<
"run duration " << seconds <<
" seconds, buffer almost full ("
661 << (int)perFull <<
"%), pausing triggers.";
664 LOG(logINFO) <<
"Resuming triggers.";
669 seconds = t.RealTime();
671 if (static_cast<int>(seconds) >= nseconds) {
672 LOG(logINFO) <<
"data taking finished, elapsed time: " << seconds <<
" seconds.";
687 void PixTestHighRate::fillMap(vector<TH2D*> hist) {
692 for(std::vector<pxar::Event>::iterator it = daqdat.begin(); it != daqdat.end(); ++it) {
693 pixCnt += it->pixels.size();
695 for (
unsigned int ipix = 0; ipix < it->pixels.size(); ++ipix) {
696 hist[
getIdxFromId(it->pixels[ipix].roc())]->Fill(it->pixels[ipix].column(), it->pixels[ipix].row());
699 LOG(logDEBUG) <<
"Processing Data: " << daqdat.size() <<
" events with " << pixCnt <<
" pixels";
704 void PixTestHighRate::doRunMaskHotPixels() {
708 bookHist(
"hotpixels");
711 for (
unsigned int i = 0; i < v.size(); ++i) v[i]->Reset();
714 if (fParSaveMaskedPixels) {
715 if (fParMaskFileName ==
"default") {
716 fPixSetup->getConfigParameters()->writeMaskFile(fHotPixels);
718 fPixSetup->getConfigParameters()->writeMaskFile(fHotPixels, fParMaskFileName);
730 void PixTestHighRate::doStop(){
733 LOG(logINFO) <<
"Stop pressed. Ending test.";
uint16_t prepareDaq(int triggerFreq, uint8_t trgTkDel)
set up DAQ (including call to setTriggerFrequency)
static void replaceAll(std::string &str, const std::string &from, const std::string &to)
in str, replace all occurences of from to to
void resetROC()
send reset to ROC(s)
void doTest()
function connected to "DoTest" button of PixTab
void setPatternGenerator(std::vector< std::pair< std::string, uint8_t > > pg_setup)
std::map< TH1 *, std::string > fHistOptions
options can be stored with each histogram
void daqTriggerLoopHalt()
bool setDAC(std::string dacName, uint8_t dacValue, uint8_t rocI2C)
std::string fStopTip
information for this test
PixSetup * fPixSetup
all necessary stuff in one place
std::vector< std::pair< int, int > > fPIX
range of enabled pixels for time-consuming tests
virtual bool setParameter(std::string parName, std::string sval)
set the string value of a parameter
std::vector< TH1 * > mapsWithString(std::vector< TH1 * >, std::string name)
return a list of TH* that have 'name' as part to their histogram name
void testPixel(uint8_t column, uint8_t row, bool enable)
std::vector< std::pair< std::string, std::string > > fParameters
the parameters of this test
int getIdxFromId(int id)
provide the mapping between ROC index and ID
void maskAllPixels(bool mask, uint8_t rocid)
void maskHotPixels(std::vector< TH2D * >)
determine hot pixels with high occupancy
void setTestboardDelays(std::vector< std::pair< std::string, uint8_t > > sig_delays)
void clearSelectedPixels()
clear selected pixel list
TDirectory * fDirectory
where the root histograms will end up
uint16_t daqTriggerLoop(uint16_t period=1000)
std::vector< std::pair< uint8_t, std::vector< pixel > > > getEfficiencyVsDAC(std::string dacName, uint8_t dacMin, uint8_t dacMax, uint16_t flags, uint16_t nTriggers)
void restoreDacs(bool verbose=false)
restore all DACs
void bookTree()
book a minimal tree with pixel events
void addSelectedPixels(std::string sval)
add a selected pixel to the internal parameter list
std::vector< uint8_t > getEnabledRocIDs()
void finalCleanup()
functions for DAQ
void testAllPixels(bool enable)
std::list< TH1 * >::iterator fDisplayedHist
pointer to the histogram currently displayed
void setToolTips()
implement this to provide updated tool tips if the user changes test parameters
TH1D * bookTH1D(std::string sname, std::string title, int nbins, double xmin, double xmax)
book a TH1D, adding version information to the name and title
virtual std::string getHistOption(TH1 *)
get the hist display options (if stored in fHistOptions)
void cacheDacs(bool verbose=false)
cache all DACs
std::list< TH1 * > fHistList
list of histograms available in PixTab::next and PixTab::previous
std::pair< std::vector< TH2D * >, std::vector< TH2D * > > xEfficiencyMaps(std::string name, uint16_t ntrig, uint16_t FLAGS=FLAG_CHECK_ORDER|FLAG_FORCE_UNMASKED)
Return pixelAlive map and additional hit map when running with external source.
TH2D * bookTH2D(std::string sname, std::string title, int nbinsx, double xmin, double xmax, int nbinsy, double ymin, double max)
book a TH2D, adding version information to the name and title
void maskPixel(uint8_t column, uint8_t row, bool mask)
void update()
signal to PixTab to update the canvas
uint8_t getDAC(size_t rocId, std::string dacName)
pxar::pxarCore * fApi
pointer to the API
std::vector< Event > daqGetEventBuffer()
void runCommand(std::string command)
allow execution of any button in the test
void init()
sets all test parameters
void maskPixels()
mask all pixels mentioned in the mask file
int getIdFromIdx(int idx)
provide the mapping between ROC ID and index