8 #include <TStopwatch.h>
10 #include "PixTestTrim.hh"
30 PixTestTrim::PixTestTrim() :
PixTest() {
37 std::transform(parName.begin(), parName.end(), parName.begin(), ::tolower);
38 for (
unsigned int i = 0; i <
fParameters.size(); ++i) {
41 sval.erase(
remove(sval.begin(), sval.end(),
' '), sval.end());
42 if (!parName.compare(
"ntrig")) {
43 fParNtrig = atoi(sval.c_str());
45 if (!parName.compare(
"vcal")) {
46 fParVcal = atoi(sval.c_str());
57 void PixTestTrim::init() {
59 fDirectory = gFile->GetDirectory(fName.c_str());
70 std::transform(command.begin(), command.end(), command.begin(), ::tolower);
71 LOG(logDEBUG) <<
"running command: " << command;
72 if (!command.compare(
"trimbits")) {
76 if (!command.compare(
"trim")) {
80 LOG(logDEBUG) <<
"did not find command ->" << command <<
"<-";
86 fTestTip = string(Form(
"trimming results in a uniform in-time threshold\n")
87 +
string(
"TO BE FINISHED!!"))
89 fSummaryTip = string(
"summary plot to be implemented")
94 void PixTestTrim::bookHist(
string name) {
97 LOG(logDEBUG) <<
"nothing done with " << name;
102 PixTestTrim::~PixTestTrim() {
103 LOG(logDEBUG) <<
"PixTestTrim dtor";
114 bigBanner(Form(
"PixTestTrim::doTest()"));
119 LOG(logINFO) <<
"PixTestTrim::doTest() aborted because of problem ";
122 TH1 *h1 = (*fDisplayedHist);
129 LOG(logINFO) <<
"PixTestTrim::doTest() aborted because of problem ";
132 h1 = (*fDisplayedHist);
136 int seconds = t.RealTime();
137 LOG(logINFO) <<
"PixTestTrim::doTest() done, duration: " << seconds <<
" seconds";
141 void PixTestTrim::trimTest() {
147 banner(Form(
"PixTestTrim::trimTest() ntrig = %d, vcal = %d", fParNtrig, fParVcal));
162 map<int, int> rocVthrComp;
163 print(
"VthrComp thr map (minimal VthrComp)");
164 vector<TH1*> thr0 =
scurveMaps(
"vthrcomp",
"TrimThr0", NTRIG, 0, 159, 40, 7);
166 if (thr0.size()/3 != rocIds.size()) {
167 LOG(logERROR) <<
"scurve map size " << thr0.size() <<
" does not agree with number of enabled ROCs " << rocIds.size();
174 for (
unsigned int iroc = 0; iroc < rocIds.size(); ++iroc) {
175 LOG(logINFO) <<
"ROC " <<
static_cast<int>(rocIds[iroc]) <<
" VthrComp = " << minVthrComp[iroc];
176 fApi->
setDAC(
"VthrComp", static_cast<uint8_t>(minVthrComp[iroc]), rocIds[iroc]);
177 rocVthrComp.insert(make_pair(rocIds[iroc], minVthrComp[iroc]));
181 print(
"Vcal thr map (pixel with maximum Vcal thr)");
182 vector<TH1*> thr1 =
scurveMaps(
"vcal",
"TrimThr1", NTRIG, 0, 159, -1, 1);
184 if (thr1.size() != rocIds.size()) {
185 LOG(logERROR) <<
"scurve map size " << thr1.size() <<
" does not agree with number of enabled ROCs " << rocIds.size() << endl;
193 double vcalMean(-1), vcalMin(999.), vcalMax(-1.);
195 string::size_type s1, s2;
198 map<string, TH2D*> maps;
199 for (
unsigned int i = 0; i < thr1.size(); ++i) {
201 hname = h2->GetName();
204 vcalMean = d1->GetMean();
205 vcalMin = d1->GetMean() - NSIGMA*d1->GetRMS();
206 if (vcalMin < 0) vcalMin = 0;
207 vcalMax = d1->GetMean() + NSIGMA*d1->GetRMS();
208 if (vcalMax > 255) vcalMin = 255;
211 s1 = hname.rfind(
"_C");
212 s2 = hname.rfind(
"_V");
213 rocid = atoi(hname.substr(s1+2, s2-s1-2).c_str());
214 double maxVcal(-1.), vcal(0.);
216 for (
int ic = 0; ic < h2->GetNbinsX(); ++ic) {
217 for (
int ir = 0; ir < h2->GetNbinsY(); ++ir) {
218 vcal = h2->GetBinContent(ic+1, ir+1);
219 if (vcal > vcalMin && vcal > maxVcal && vcal < vcalMax) {
227 LOG(logINFO) <<
" roc " <<
getIdxFromId(rocid) <<
" with ID = " << rocid
228 <<
" has maximal Vcal " << maxVcal <<
" for pixel " << ix <<
"/" << iy
229 <<
" mean/min/max = " << vcalMean <<
"/" << vcalMin <<
"/" <<vcalMax;
230 Vcal.push_back(static_cast<int>(maxVcal));
238 h2 =
bookTH2D(Form(
"trim_VCAL_VTRIM_C%d", rocid),
239 Form(
"trim_VCAL_VTRIM_c%d_r%d_C%d", ix, iy, rocid),
240 256, 0., 256., 256, 0., 256.);
245 maps.insert(make_pair(Form(
"trim_VCAL_VTRIM_C%d", rocid), h2));
252 vector<pair<uint8_t, pair<uint8_t, vector<pixel> > > > results;
258 LOG(logCRITICAL) <<
"pXar execption: "<< e.what();
259 fNDaqErrors = 666667;
262 done = (cnt>2) || done;
266 for (
unsigned int i = 0; i < results.size(); ++i) {
267 pair<uint8_t, pair<uint8_t, vector<pixel> > > v = results[i];
269 pair<uint8_t, vector<pixel> > w = v.second;
271 vector<pixel> wpix = w.second;
273 for (
unsigned ipix = 0; ipix < wpix.size(); ++ipix) {
274 h2 = maps[Form(
"trim_VCAL_VTRIM_C%d", wpix[ipix].roc())];
276 h2->Fill(idac1, idac2, wpix[ipix].value());
278 LOG(logDEBUG) <<
"wrong pixel decoded";
283 map<int, int> rocTrim;
285 for (
unsigned int iroc = 0; iroc < rocIds.size(); ++iroc){
286 h2 = maps[Form(
"trim_VCAL_VTRIM_C%d", rocIds[iroc])];
287 TH1D *hy = h2->ProjectionY(
"_py", 150, 150);
288 double thresh = hy->FindLastBinAbove(0.5*NTRIG);
290 vtrim =
static_cast<int>(thresh);
292 for (
int itrim = vtrim-20; itrim > 0; --itrim) {
293 TH1D *hx = h2->ProjectionX(
"_px", itrim, itrim);
296 if (fThreshold > fParVcal) {
297 if (TMath::Abs(fParVcal - fThreshold) < TMath::Abs(fParVcal - oldThr)) {
298 rocTrim.insert(make_pair(rocIds[iroc], itrim));
300 LOG(logDEBUG) <<
" vtrim: vcal = " << fThreshold <<
" < " << fParVcal <<
" for itrim = " << itrim <<
"; old thr = " << oldThr
303 rocTrim.insert(make_pair(rocIds[iroc], itrim+1));
305 LOG(logDEBUG) <<
"vtrim: vcal = " << fThreshold <<
" < " << fParVcal <<
" for itrim+1 = " << itrim+1 <<
"; old thr = " << oldThr
318 for (
unsigned int iroc = 0; iroc < rocIds.size(); ++iroc) {
319 for (
int ix = 0; ix < 52; ++ix) {
320 for (
int iy = 0; iy < 80; ++iy) {
321 fTrimBits[iroc][ix][iy] = 7;
330 vector<TH1*> thr2 =
scurveMaps(
"vcal",
"TrimThr2", fParNtrig, 0, 199, -1, 1);
331 if (thr2.size() != rocIds.size()) {
332 LOG(logERROR) <<
"scurve map thr2 size " << thr2.size() <<
" does not agree with number of enabled ROCs " << rocIds.size();
338 print(Form(
"TrimStepCorr4 extremal thresholds: %f .. %f", minthr, maxthr));
339 if (maxthr < 245) maxthr += 10;
340 if (minthr > 10) minthr -= 10;
341 vector<TH1*> thr2a = trimStep(
"trimStepCorr4", correction, thr2, static_cast<int>(minthr), static_cast<int>(maxthr));
343 if (thr2a.size() != rocIds.size()) {
344 LOG(logERROR) <<
"scurve map thr2a size " << thr2a.size() <<
" does not agree with number of enabled ROCs " << rocIds.size();
353 print(Form(
"TrimStepCorr2 extremal thresholds: %f .. %f", minthr, maxthr));
354 if (maxthr < 245) maxthr += 10;
355 if (minthr > 10) minthr -= 10;
356 vector<TH1*> thr3a = trimStep(
"trimStepCorr2", correction, thr2a, static_cast<int>(minthr), static_cast<int>(maxthr));
358 if (thr3a.size() != rocIds.size()) {
359 LOG(logERROR) <<
"scurve map thr3a size " << thr3a.size() <<
" does not agree with number of enabled ROCs " << rocIds.size();
367 print(Form(
"TrimStepCorr1a extremal thresholds: %f .. %f", minthr, maxthr));
368 if (maxthr < 245) maxthr += 10;
369 if (minthr > 10) minthr -= 10;
370 vector<TH1*> thr4a = trimStep(
"trimStepCorr1a", correction, thr3a, static_cast<int>(minthr), static_cast<int>(maxthr));
372 if (thr4a.size() != rocIds.size()) {
373 LOG(logERROR) <<
"scurve map thr4a size " << thr4a.size() <<
" does not agree with number of enabled ROCs " << rocIds.size();
381 print(Form(
"TrimStepCorr1b extremal thresholds: %f .. %f", minthr, maxthr));
382 if (maxthr < 245) maxthr += 10;
383 if (minthr > 10) minthr -= 10;
384 vector<TH1*> thr5a = trimStep(
"trimStepCorr1b", correction, thr4a, static_cast<int>(minthr), static_cast<int>(maxthr));
386 if (thr5a.size() != rocIds.size()) {
387 LOG(logERROR) <<
"scurve map thr5a size " << thr5a.size() <<
" does not agree with number of enabled ROCs " << rocIds.size();
393 string trimbitsMeanString(
""), trimbitsRmsString(
"");
394 for (
unsigned int i = 0; i < thr5a.size(); ++i) {
395 h2 =
bookTH2D(Form(
"TrimMap_C%d", i),
396 Form(
"TrimMap_C%d", i),
397 52, 0., 52., 80, 0., 80.);
398 for (
int ix = 0; ix < 52; ++ix) {
399 for (
int iy = 0; iy < 80; ++iy) {
400 h2->SetBinContent(ix+1, iy+1, fTrimBits[i][ix][iy]);
409 trimbitsMeanString += Form(
"%6.2f ", d1->GetMean());
410 trimbitsRmsString += Form(
"%6.2f ", d1->GetRMS());
415 print(Form(
"TrimThrFinal extremal thresholds: %d .. %d", fParVcal-20, fParVcal+20));
416 vector<TH1*> thrF =
scurveMaps(
"vcal",
"TrimThrFinal", fParNtrig, fParVcal-20, fParVcal+20, -1, 9);
418 string trimMeanString, trimRmsString;
419 for (
unsigned int i = 0; i < thrF.size(); ++i) {
420 hname = thrF[i]->GetName();
422 if (string::npos == hname.find(
"dist_thr_"))
continue;
423 trimMeanString += Form(
"%6.2f ", thrF[i]->GetMean());
424 trimRmsString += Form(
"%6.2f ", thrF[i]->GetRMS());
428 TH1 *h1 = (*fDisplayedHist);
432 string vtrimString, vthrcompString;
433 for (
unsigned int iroc = 0; iroc < rocIds.size(); ++iroc) {
434 fApi->
setDAC(
"vtrim", rocTrim[rocIds[iroc]], rocIds[iroc]);
435 vtrimString += Form(
"%3d ", rocTrim[rocIds[iroc]]);
436 fApi->
setDAC(
"vthrcomp", rocVthrComp[rocIds[iroc]], rocIds[iroc]);
437 vthrcompString += Form(
"%3d ", rocVthrComp[rocIds[iroc]]);
441 fPixSetup->getConfigParameters()->setTrimVcalSuffix(Form(
"%d", fParVcal),
true);
446 LOG(logINFO) <<
"PixTestTrim::trimTest() done";
447 LOG(logINFO) <<
"vtrim: " << vtrimString;
448 LOG(logINFO) <<
"vthrcomp: " << vthrcompString;
449 LOG(logINFO) <<
"vcal mean: " << trimMeanString;
450 LOG(logINFO) <<
"vcal RMS: " << trimRmsString;
451 LOG(logINFO) <<
"bits mean: " << trimbitsMeanString;
452 LOG(logINFO) <<
"bits RMS: " << trimbitsRmsString;
457 void PixTestTrim::trimBitTest() {
462 unsigned int nrocs = rocIds.size();
465 for (
unsigned int i = 0; i < nrocs; ++i) {
468 for (
unsigned int ipix = 0; ipix < pix.size(); ++ipix) {
469 ix = pix[ipix].column();
470 iy = pix[ipix].row();
471 fTrimBits[i][ix][iy] = pix[ipix].trim();
476 vtrim.push_back(255);
477 vtrim.push_back(240);
478 vtrim.push_back(150);
479 vtrim.push_back(100);
489 banner(Form(
"PixTestTrim::trimBitTest() ntrig = %d, vtrims = %d %d %d %d",
490 fParNtrig, vtrim[0], vtrim[1], vtrim[2], vtrim[3]));
495 vector<vector<TH1*> > steps;
499 bool ok = cp->setTrimBits(15);
501 LOG(logWARNING) <<
"could not set trim bits to " << 15;
507 LOG(logDEBUG) <<
"trimBitTest determine threshold map without trims ";
513 if (maxThr > 245.) maxThr = 245.;
514 for (
unsigned int iv = 0; iv < vtrim.size(); ++iv) {
516 ok = cp->setTrimBits(btrim[iv]);
518 LOG(logWARNING) <<
"could not set trim bits to " << btrim[iv];
522 LOG(logDEBUG) <<
"trimBitTest initDUT with trim bits = " << btrim[iv];
523 for (vector<uint8_t>::size_type iroc = 0; iroc < rocIds.size(); ++iroc) {
528 LOG(logDEBUG) <<
"trimBitTest threshold map with trim = " << btrim[iv];
529 thr =
mapsWithString(
scurveMaps(
"Vcal", Form(
"TrimThr_trim%d", btrim[iv]), fParNtrig, 0, static_cast<int>(maxThr)+10, -1, 7),
"thr");
531 if (maxThr > 245.) maxThr = 245.;
532 steps.push_back(thr);
538 for (
unsigned int i = 0; i < steps.size(); ++i) {
540 for (
unsigned int iroc = 0; iroc < thr.size(); ++iroc) {
541 h1 =
bookTH1D(Form(
"TrimBit%d_C%d", btrim[i], rocIds[iroc]), Form(
"TrimBit%d_C%d", btrim[i], rocIds[iroc]), 256, 0., 256);
542 for (
int ix = 0; ix < 52; ++ix) {
543 for (
int iy = 0; iy < 80; ++iy) {
544 dthr = thr0[iroc]->GetBinContent(ix+1, iy+1) - thr[iroc]->GetBinContent(ix+1, iy+1);
558 LOG(logINFO) <<
"PixTestTrim::trimBitTest() done ";
565 int PixTestTrim::adjustVtrim() {
567 int thr(255), thrOld(255);
574 LOG(logDEBUG) << vtrim <<
" thr " << thr;
576 while (((thr > fParVcal) || (thrOld > fParVcal) || (thr < 10)) && (vtrim < 200));
579 LOG(logINFO) <<
"Vtrim set to " << vtrim;
585 vector<TH1*> PixTestTrim::trimStep(
string name,
int correction, vector<TH1*> calOld,
int vcalMin,
int vcalMax) {
589 if (vcalMin < 0) vcalMin = 0;
590 if (vcalMin > 255) vcalMax = 255;
593 int trimBitsOld[16][52][80];
594 for (
unsigned int i = 0; i < calOld.size(); ++i) {
595 for (
int ix = 0; ix < 52; ++ix) {
596 for (
int iy = 0; iy < 80; ++iy) {
597 trimBitsOld[i][ix][iy] = fTrimBits[i][ix][iy];
598 if (calOld[i]->GetBinContent(ix+1, iy+1) > fParVcal) {
599 trim = fTrimBits[i][ix][iy] - correction;
601 trim = fTrimBits[i][ix][iy] + correction;
603 if (trim < 1) trim = 1;
604 if (trim > 15) trim = 15;
605 fTrimBits[i][ix][iy] = trim;
611 vector<TH1*> calNew =
scurveMaps(
"vcal", name, NTRIG, vcalMin, vcalMax, -1, 1);
612 if (calNew.size() != calOld.size()) {
613 LOG(logERROR) <<
"scurve map size " << calNew.size() <<
" does not agree with previous number " << calOld.size();
619 for (
unsigned int i = 0; i < calOld.size(); ++i) {
620 for (
int ix = 0; ix < 52; ++ix) {
621 for (
int iy = 0; iy < 80; ++iy) {
622 if (TMath::Abs(calOld[i]->GetBinContent(ix+1, iy+1) - fParVcal) < TMath::Abs(calNew[i]->GetBinContent(ix+1, iy+1) - fParVcal)) {
623 trim = trimBitsOld[i][ix][iy];
624 calNew[i]->SetBinContent(ix+1, iy+1, calOld[i]->GetBinContent(ix+1, iy+1));
626 trim = fTrimBits[i][ix][iy];
628 fTrimBits[i][ix][iy] = trim;
639 void PixTestTrim::setTrimBits(
int itrim) {
641 for (
unsigned int ir = 0; ir < rocIds.size(); ++ir){
643 for (
unsigned int ipix = 0; ipix < pix.size(); ++ipix) {
645 fTrimBits[ir][pix[ipix].column()][pix[ipix].row()] = itrim;
647 fApi->
_dut->
updateTrimBits(pix[ipix].column(), pix[ipix].row(), fTrimBits[ir][pix[ipix].column()][pix[ipix].row()], rocIds[ir]);
std::map< TH1 *, std::string > fHistOptions
options can be stored with each histogram
bool setDAC(std::string dacName, uint8_t dacValue, uint8_t rocI2C)
PixSetup * fPixSetup
all necessary stuff in one place
void setToolTips()
implement this to provide updated tool tips if the user changes test parameters
void doTest()
function connected to "DoTest" button of PixTab
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)
std::vector< int > getMinimumVthrComp(std::vector< TH1 * >, int reserve=10, double nsigma=3.)
minimum allowable VthrComp; reserve indicate the separation from the minimum VthrComp where noise set...
bool updateTrimBits(std::vector< pixelConfig > trimming, uint8_t rocid)
TDirectory * fDirectory
where the root histograms will end up
void restoreDacs(bool verbose=false)
restore all DACs
TH1D * distribution(TH2D *, int nbins, double xmin, double xmax)
creates a 1D distribution of a map
std::vector< uint8_t > getEnabledRocIDs()
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
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
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
std::vector< std::pair< uint8_t, std::pair< uint8_t, std::vector< pixel > > > > getEfficiencyVsDACDAC(std::string dac1name, uint8_t dac1min, uint8_t dac1max, std::string dac2name, uint8_t dac2min, uint8_t dac2max, uint16_t flags, uint16_t nTriggers)
void print(std::string, pxar::TLogLevel log=pxar::logINFO)
produce eye-catching printouts
std::vector< pixelConfig > getEnabledPixels(size_t rocid)
double getMinimumThreshold(std::vector< TH1 * >)
return minimum threshold in a set of maps
void saveDacs()
save DACs to file
void saveTrimBits()
save trim bits to file
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
int pixelThreshold(std::string dac, int ntrig, int dacmin, int dacmax)
work-around to cope with suboptimal pxar/core
pxar::pxarCore * fApi
pointer to the API
bool threshold(TH1 *)
fit an s-curve to a distribution. Fills fThreshold, fThresholdE, fSigma, fSigmaE
std::vector< TH1 * > scurveMaps(std::string dac, std::string name, int ntrig=10, int daclo=0, int dachi=255, int dacsperstep=-1, int result=15, int ihit=1, int flag=FLAG_FORCE_MASKED)
void init()
sets all test parameters
double getMaximumThreshold(std::vector< TH1 * >)
return maximum threshold in a set of maps
void runCommand(std::string)
allow execution of any button in the test