pxar
 All Classes Namespaces Functions Variables Typedefs Friends
PixTest.cc
1 #include <iostream>
2 #include <fstream>
3 #include <stdlib.h> /* atof, atoi */
4 
5 #include <TKey.h>
6 #include <TClass.h>
7 #include <TMinuit.h>
8 #include <TMath.h>
9 #include <TStyle.h>
10 #include <TGMsgBox.h>
11 #include "TVirtualFitter.h"
12 
13 #include "PixTest.hh"
14 #include "PixUtil.hh"
15 #include "timer.h"
16 #include "log.h"
17 #include "helper.h"
18 #include "rsstools.hh"
19 
20 using namespace std;
21 using namespace pxar;
22 
23 ClassImp(PixTest)
24 
25 // ----------------------------------------------------------------------
26 PixTest::PixTest(PixSetup *a, string name) {
27  // LOG(logINFO) << "PixTest ctor(PixSetup, string)";
28  fPIF = new PixInitFunc();
29  fPixSetup = a;
30  fApi = a->getApi();
31  fTestParameters = a->getPixTestParameters();
32  fTimeStamp = new TTimeStamp();
33 
34  fProblem = false;
35 
36  fName = name;
37  setToolTips();
38  fParameters = a->getPixTestParameters()->getTestParameters(name);
39  fTree = 0;
40 
41  // TVirtualFitter::SetDefaultFitter("Minuit2");
42 
43  // -- provide default map when all ROCs are selected
44  map<int, int> id2idx;
45  vector<uint8_t> rocIds = fApi->_dut->getEnabledRocIDs();
46  for (unsigned i = 0; i < rocIds.size(); ++i) {
47  id2idx.insert(make_pair(rocIds[i], i));
48  }
49  setId2Idx(id2idx);
50 
51 }
52 
53 // ----------------------------------------------------------------------
55  // LOG(logINFO) << "PixTest ctor()";
56  fTree = 0;
57 
58 }
59 
60 
61 // ----------------------------------------------------------------------
62 void PixTest::init() {
63  int verbose(0);
64 
65  if (verbose) {
66  cout << "test: " << getName() << endl;
67  }
68 
69  for (unsigned int i = 0; i < fParameters.size(); ++i) {
70  if (verbose) cout << "fParameters[" << i << "].first = " << fParameters[i].first
71  << " fParameters[" << i << "].second = " << fParameters[i].second
72  << endl;
73  setParameter(fParameters[i].first, fParameters[i].second);
74  }
75 }
76 
77 // ----------------------------------------------------------------------
78 string PixTest::stripPos(string name) {
79  string::size_type m1 = name.find("::");
80  name = name.substr(m1+2);
81  return name;
82 }
83 
84 // ----------------------------------------------------------------------
86  fTestTip = "generic tool tip for a test";
87  fSummaryTip = "generic tool tip for a the summary plot";
88 }
89 
90 
91 
92 // ----------------------------------------------------------------------
93 void PixTest::bookHist(string name) {
94  LOG(logDEBUG) << "Nothing done with " << name;
95 }
96 
97 
98 // ----------------------------------------------------------------------
100  fTreeEvent.npix = 0;
101  fTreeEvent.header = 0;
102  fTreeEvent.trailer = 0;
103  fTreeEvent.numDecoderErrors = 0;
104  fTreeEvent.dac = 0;
105  for (int ipix = 0; ipix < 20000; ++ipix) {
106  fTreeEvent.proc[ipix] = 0;
107  fTreeEvent.pcol[ipix] = 0;
108  fTreeEvent.prow[ipix] = 0;
109  fTreeEvent.pval[ipix] = 0.;
110  fTreeEvent.pq[ipix] = 0.;
111  }
112 
113  if (0 == fTree) {
114  fTree = new TTree("events", "events");
115  fTree->SetDirectory(fDirectory);
116  fTree->Branch("header", &fTreeEvent.header, "header/s");
117  fTree->Branch("trailer", &fTreeEvent.trailer, "trailer/s");
118  fTree->Branch("npix", &fTreeEvent.npix, "npix/s");
119  fTree->Branch("proc", fTreeEvent.proc, "proc[npix]/b");
120  fTree->Branch("pcol", fTreeEvent.pcol, "pcol[npix]/b");
121  fTree->Branch("prow", fTreeEvent.prow, "prow[npix]/b");
122  fTree->Branch("pval", fTreeEvent.pval, "pval[npix]/D");
123  fTree->Branch("pq", fTreeEvent.pq, "pq[npix]/D");
124  }
125 }
126 
127 
128 // ----------------------------------------------------------------------
129 void PixTest::runCommand(std::string command) {
130  std::transform(command.begin(), command.end(), command.begin(), ::tolower);
131  LOG(logDEBUG) << "Nothing done with " << command;
132 }
133 
134 
135 // ----------------------------------------------------------------------
137  fDirectory = gFile->GetDirectory(fName.c_str());
138 }
139 
140 
141 // ----------------------------------------------------------------------
142 int PixTest::pixelThreshold(string dac, int ntrig, int dacmin, int dacmax) {
143  // uint16_t FLAGS = FLAG_FORCE_MASKED | FLAG_FORCE_SERIAL;
144  uint16_t FLAGS = FLAG_FORCE_MASKED;
145  TH1D *h = new TH1D("h1", "h1", 256, 0., 256.);
146 
147  vector<pair<uint8_t, vector<pixel> > > results;
148  int cnt(0);
149  bool done(false);
150  while (!done) {
151  LOG(logDEBUG) << " attempt #" << cnt;
152  try {
153  results = fApi->getEfficiencyVsDAC(dac, dacmin, dacmax, FLAGS, ntrig);
154  fNDaqErrors = fApi->getStatistics().errors_pixel();
155  done = true;
156  } catch(pxarException &/*e*/) {
157  ++cnt;
158  }
159  done = (cnt>2) || done;
160  }
161 
162  int val(0);
163  for (unsigned int idac = 0; idac < results.size(); ++idac) {
164  int dacval = results[idac].first;
165  for (unsigned int ipix = 0; ipix < results[idac].second.size(); ++ipix) {
166  val = results[idac].second[ipix].value();
167  h->Fill(dacval, val);
168  }
169  }
170  int thr = simpleThreshold(h);
171  delete h;
172  return thr;
173 
174 }
175 
176 // ----------------------------------------------------------------------
177 vector<TH1*> PixTest::scurveMaps(string dac, string name, int ntrig, int dacmin, int dacmax, int dacsperstep,
178  int result, int ihit, int flag) {
179 
180  vector<uint8_t> rocIds = fApi->_dut->getEnabledRocIDs();
181  string type("hits");
182  if (2 == ihit) type = string("pulseheight");
183  print(Form("dac: %s name: %s ntrig: %d dacrange: %d .. %d %s flags = %d (plus default)",
184  dac.c_str(), name.c_str(), ntrig, dacmin, dacmax, type.c_str(), flag));
185 
186  vector<shist256*> maps;
187  vector<TH1*> resultMaps;
188  resultMaps.clear();
189 
190  shist256 *pshistBlock = new (fPixSetup->fPxarMemory) shist256[16*52*80];
191  shist256 *ph;
192  rsstools rss;
193 
194  int idx(0);
195  for (unsigned int iroc = 0; iroc < rocIds.size(); ++iroc) {
196  for (unsigned int ic = 0; ic < 52; ++ic) {
197  for (unsigned int ir = 0; ir < 80; ++ir) {
198  idx = PixUtil::rcr2idx(iroc, ic, ir);
199  ph = pshistBlock + idx;
200  maps.push_back(ph);
201  }
202  }
203  }
204 
205  if (dacsperstep > 0) {
206  int stepsize(dacsperstep);
207  int dacminAdj = dacmin;
208  int dacmaxAdj = dacmin + stepsize - 1;
209  bool finalRun(false);
210  while (dacmaxAdj <= dacmax) {
211  LOG(logINFO) << " dacScan step from " << dacminAdj << " .. " << dacmaxAdj;
212  dacScan(dac, ntrig, dacminAdj, dacmaxAdj, maps, ihit, flag);
213  if (finalRun) break;
214  dacminAdj = dacminAdj + stepsize;
215  dacmaxAdj = dacminAdj + stepsize - 1;
216  if (dacmaxAdj >= dacmax) {
217  dacmaxAdj = dacmax;
218  finalRun = true;
219  }
220  }
221  } else {
222  dacScan(dac, ntrig, dacmin, dacmax, maps, ihit, flag);
223  }
224 
225 
226  if (fNDaqErrors > 666000) return resultMaps;
227  if (1 == ihit) {
228  scurveAna(dac, name, maps, resultMaps, result);
229  }
230 
231  LOG(logDEBUG) << "PixTest::scurveMaps end: getCurrentRSS() = " << rss.getCurrentRSS();
232 
233  return resultMaps;
234 }
235 
236 
237 
238 // ----------------------------------------------------------------------
239 vector<TH2D*> PixTest::phMaps(string name, uint16_t ntrig, uint16_t FLAGS) {
240 
241  vector<pixel> results;
242 
243  int cnt(0);
244  bool done = false;
245  while (!done){
246  LOG(logDEBUG) << " attempt #" << cnt;
247  try {
248  results = fApi->getPulseheightMap(FLAGS, ntrig);
249  fNDaqErrors = fApi->getStatistics().errors_pixel();
250  done = true;
251  } catch(pxarException &/*e*/) {
252  fNDaqErrors = 666667;
253  ++cnt;
254  }
255  done = (cnt>2) || done;
256  }
257  LOG(logDEBUG) << " eff result size = " << results.size();
258 
259  fDirectory->cd();
260  vector<TH2D*> maps;
261  TH2D *h2(0);
262 
263  vector<uint8_t> rocIds = fApi->_dut->getEnabledRocIDs();
264  for (unsigned int iroc = 0; iroc < rocIds.size(); ++iroc){
265  LOG(logDEBUG) << "Create hist " << Form("%s_C%d", name.c_str(), rocIds[iroc]);
266  h2 = bookTH2D(Form("%s_C%d", name.c_str(), rocIds[iroc]), Form("%s_C%d", name.c_str(), rocIds[iroc]), 52, 0., 52., 80, 0., 80.);
267  h2->SetMinimum(0.);
268  h2->SetDirectory(fDirectory);
269  fHistOptions.insert(make_pair(h2, "colz"));
270  setTitles(h2, "col", "row");
271  maps.push_back(h2);
272  }
273 
274  int idx(-1);
275  for (unsigned int i = 0; i < results.size(); ++i) {
276  idx = getIdxFromId(results[i].roc());
277  if (rocIds.end() != find(rocIds.begin(), rocIds.end(), results[i].roc())) {
278  h2 = maps[idx];
279  if (h2->GetBinContent(results[i].column()+1, results[i].row()+1) > 0) {
280  LOG(logDEBUG) << "ROC/col/row = " << int(results[i].roc()) << "/" << int(results[i].column()) << "/" << int(results[i].row())
281  << " with = " << h2->GetBinContent(results[i].column()+1, results[i].row()+1)
282  << " now adding " << static_cast<float>(results[i].value());
283  }
284  h2->Fill(results[i].column(), results[i].row(), static_cast<float>(results[i].value()));
285  } else {
286  LOG(logDEBUG) << "histogram for ROC " << (int)results[i].roc() << " not found";
287  }
288  }
289 
290  return maps;
291 }
292 
293 
294 // ----------------------------------------------------------------------
295 vector<TH2D*> PixTest::efficiencyMaps(string name, uint16_t ntrig, uint16_t FLAGS) {
296 
297  vector<pixel> results;
298 
299  int cnt(0);
300  bool done = false;
301  while (!done){
302  LOG(logDEBUG) << " attempt #" << cnt;
303  try {
304  results = fApi->getEfficiencyMap(FLAGS, ntrig);
305  fNDaqErrors = fApi->getStatistics().errors_pixel();
306  done = true;
307  } catch(pxarException &/*e*/) {
308  fNDaqErrors = 666667;
309  ++cnt;
310  }
311  done = (cnt>5) || done;
312  }
313  LOG(logDEBUG) << " eff result size = " << results.size();
314 
315  fDirectory->cd();
316  vector<TH2D*> maps;
317  TH2D *h2(0);
318 
319  vector<uint8_t> rocIds = fApi->_dut->getEnabledRocIDs();
320  for (unsigned int iroc = 0; iroc < rocIds.size(); ++iroc){
321  LOG(logDEBUG) << "Create hist " << Form("%s_C%d", name.c_str(), rocIds[iroc]);
322  h2 = bookTH2D(Form("%s_C%d", name.c_str(), rocIds[iroc]), Form("%s_C%d", name.c_str(), rocIds[iroc]), 52, 0., 52., 80, 0., 80.);
323  h2->SetMinimum(0.);
324  h2->SetDirectory(fDirectory);
325  fHistOptions.insert(make_pair(h2, "colz"));
326  setTitles(h2, "col", "row");
327  maps.push_back(h2);
328  }
329 
330  int idx(-1);
331  for (unsigned int i = 0; i < results.size(); ++i) {
332  idx = getIdxFromId(results[i].roc());
333  // if (rocIds.end() != find(rocIds.begin(), rocIds.end(), idx)) {
334  if (rocIds.end() != find(rocIds.begin(), rocIds.end(), results[i].roc())) {
335  h2 = maps[idx];
336  if (h2->GetBinContent(results[i].column()+1, results[i].row()+1) > 0) {
337  LOG(logDEBUG) << "ROC/col/row = " << int(results[i].roc()) << "/" << int(results[i].column()) << "/" << int(results[i].row())
338  << " with = " << h2->GetBinContent(results[i].column()+1, results[i].row()+1)
339  << " now adding " << static_cast<float>(results[i].value());
340  }
341  h2->Fill(results[i].column(), results[i].row(), static_cast<float>(results[i].value()));
342  } else {
343  LOG(logDEBUG) << "histogram for ROC " << (int)results[i].roc() << " not found";
344  }
345  }
346 
347  return maps;
348 }
349 
350 
351 
352 // ----------------------------------------------------------------------
353 vector<TH1*> PixTest::thrMaps(string dac, string name, int ntrig, uint16_t flag) {
354  return thrMaps(dac, name, 1, 0, ntrig, flag);
355 }
356 
357 
358 
359 // ----------------------------------------------------------------------
360 vector<TH1*> PixTest::thrMaps(string dac, string name, uint8_t daclo, uint8_t dachi, int ntrig, uint16_t flag) {
361  // use at your own risk; pxarCore::getThresholdMap may or may not work as intended
362  vector<TH1*> resultMaps;
363 
364  if (daclo > dachi) {
365  LOG(logWARNING) << "thrMaps called with dacLo = " << daclo << " > dacHi = " << dachi;
366  return resultMaps;
367  }
368 
369  uint16_t FLAGS = flag | FLAG_RISING_EDGE;
370  TH1* h1(0);
371  fDirectory->cd();
372 
373  vector<uint8_t> rocIds = fApi->_dut->getEnabledRocIDs();
374  for (unsigned int iroc = 0; iroc < rocIds.size(); ++iroc){
375  h1 = bookTH2D(Form("thr_%s_%s_C%d", name.c_str(), dac.c_str(), iroc),
376  Form("thr_%s_%s_C%d", name.c_str(), dac.c_str(), iroc),
377  52, 0., 52., 80, 0., 80.);
378  resultMaps.push_back(h1);
379  fHistOptions.insert(make_pair(h1, "colz"));
380  }
381 
382  int ic, ir, iroc, val;
383  LOG(logDEBUG) << "start threshold map for dac = " << dac;
384 
385  std::vector<pixel> results;
386 
387  int cnt(0);
388  bool done = false;
389  while (!done){
390  LOG(logDEBUG) << " attempt #" << cnt;
391  try {
392  results = fApi->getThresholdMap(dac, 1, daclo, dachi, FLAGS, ntrig);
393  fNDaqErrors = fApi->getStatistics().errors_pixel();
394  done = true;
395  } catch(pxarException &/*e*/) {
396  fNDaqErrors = 666667;
397  ++cnt;
398  }
399  done = (cnt>2) || done;
400  }
401 
402  LOG(logDEBUG) << "finished threshold map for dac = " << dac << " results size = " << results.size();
403  for (unsigned int ipix = 0; ipix < results.size(); ++ipix) {
404  ic = results[ipix].column();
405  ir = results[ipix].row();
406  iroc = getIdxFromId(results[ipix].roc());
407  val = results[ipix].value();
408  if (rocIds.end() != find(rocIds.begin(), rocIds.end(), results[ipix].roc())) {
409  ((TH2D*)resultMaps[iroc])->Fill(ic, ir, val);
410  } else {
411  LOG(logDEBUG) << "histogram for ROC " << static_cast<int>(results[ipix].roc()) << " not found";
412  }
413  }
414 
415  for (unsigned int i = 0; i < rocIds.size(); ++i){
416  TH2D *h2 = (TH2D*)resultMaps[i];
417  TH1* d1 = distribution(h2, 256, 0., 256.);
418  resultMaps.push_back(d1);
419  }
420 
421  copy(resultMaps.begin(), resultMaps.end(), back_inserter(fHistList));
422  fDisplayedHist = find(fHistList.begin(), fHistList.end(), h1);
423  if (h1) h1->Draw(getHistOption(h1).c_str());
424  PixTest::update();
425 
426  return resultMaps;
427 
428 }
429 
430 
431 
432 // ----------------------------------------------------------------------
433 bool PixTest::setParameter(string parName, string value) {
434  LOG(logDEBUG) << " PixTest::setParameter wrong function" << parName << " " << value;
435  return false;
436 }
437 
438 
439 // ----------------------------------------------------------------------
440 string PixTest::getParameter(std::string parName) {
441  for (unsigned int i = 0; i < fParameters.size(); ++i) {
442  if (0 == fParameters[i].first.compare(parName)) {
443  return fParameters[i].second;
444  }
445  }
446  return string(Form("parameter %s not found", parName.c_str()));
447 }
448 
449 // ----------------------------------------------------------------------
450 bool PixTest::getParameter(std::string parName, int &ival) {
451  bool found(false);
452  // FIXME This is likely not the intended behavior
453  for (unsigned int i = 0; i < fParameters.size(); ++i) {
454  if (0 == fParameters[i].first.compare(parName)) {
455  found = true;
456  ival = atoi(fParameters[i].first.c_str());
457  break;
458  }
459  }
460  return found;
461 }
462 
463 
464  // ----------------------------------------------------------------------
465 bool PixTest::getParameter(std::string parName, float &fval) {
466  bool found(false);
467  // FIXME This is likely not the intended behavior
468  for (unsigned int i = 0; i < fParameters.size(); ++i) {
469  if (0 == fParameters[i].first.compare(parName)) {
470  found = true;
471  fval = static_cast<float>(atof(fParameters[i].first.c_str()));
472  break;
473  }
474  }
475  return found;
476 }
477 
478 
479 // ----------------------------------------------------------------------
480 void PixTest::addSelectedPixels(string sval) {
481  bool reset(false), alreadyIn(false);
482  for (unsigned int i = 0; i < fParameters.size(); ++i) {
483  if (!fParameters[i].first.compare("pix") && !fParameters[i].second.compare("reset")) {
484  fParameters[i].second = sval;
485  reset = true;
486  break;
487  }
488  if (!fParameters[i].first.compare("pix") && !fParameters[i].second.compare(sval)) {
489  alreadyIn = true;
490  break;
491  }
492  }
493  if (!reset && !alreadyIn) fParameters.push_back(make_pair("pix", sval));
494 }
495 
496 
497 // ----------------------------------------------------------------------
499  fPIX.clear();
500  std::vector<std::pair<std::string, std::string> > pnew;
501  for (unsigned int i = 0; i < fParameters.size(); ++i) {
502  if (0 == fParameters[i].first.compare("pix")) {
503  pnew.push_back(make_pair("pix", "reset"));
504  } else {
505  pnew.push_back(make_pair(fParameters[i].first, fParameters[i].second));
506  }
507  }
508  fParameters.clear();
509  fParameters = pnew;
510 }
511 
512 
513 // ----------------------------------------------------------------------
514 bool PixTest::setTestParameter(string parname, string value) {
515 
516  for (unsigned int i = 0; i < fParameters.size(); ++i) {
517  if (!fParameters[i].first.compare(parname)) {
518  fParameters[i].second = value;
519  LOG(logDEBUG) << " setting " << fParameters[i].first << " to new value " << fParameters[i].second;
520  }
521  return true;
522  }
523 
524  return false;
525 }
526 
527 
528 // ----------------------------------------------------------------------
530  LOG(logINFO) << "Parameters for test " << getName() << ", number of parameters = " << fParameters.size();
531  // FIXME This is likely not the intended behavior
532  for (unsigned int i = 0; i < fParameters.size(); ++i) {
533  LOG(logINFO) << fParameters[i].first << ": " << fParameters[i].second;
534  }
535 }
536 
537 
538 // ----------------------------------------------------------------------
539 PixTest::~PixTest() {
540  // LOG(logDEBUG) << "PixTestBase dtor(), writing out histograms";
541  std::list<TH1*>::iterator il;
542  fDirectory->cd();
543  for (il = fHistList.begin(); il != fHistList.end(); ++il) {
544  // LOG(logINFO) << "Write out " << (*il)->GetName();
545  (*il)->SetDirectory(fDirectory);
546  (*il)->Write();
547  }
548 
549  TH1D *h = (TH1D*)gDirectory->Get("ha");
550  if (h) {
551  h->SetDirectory(fDirectory);
552  h->Write();
553  }
554 
555  h = (TH1D*)gDirectory->Get("hd");
556  if (h) {
557  h->SetDirectory(fDirectory);
558  h->Write();
559  }
560 }
561 
562 // ----------------------------------------------------------------------
564  // LOG(logINFO) << "PixTest::testDone()";
565  Emit("testDone()");
566 }
567 
568 // ----------------------------------------------------------------------
570  // cout << "PixTest::update()" << endl;
571  Emit("update()");
572  fPixSetup->getPixMonitor()->update();
573 
574 }
575 
576 // ----------------------------------------------------------------------
578  // cout << "PixTest::hvOn()" << endl;
579  Emit("hvOn()");
580 }
581 
582 // ----------------------------------------------------------------------
584  // cout << "PixTest::hvOff()" << endl;
585  Emit("hvOff()");
586 }
587 
588 // ----------------------------------------------------------------------
590  // cout << "PixTest::powerOn()" << endl;
591  Emit("powerOn()");
592 }
593 
594 // ----------------------------------------------------------------------
596  // cout << "PixTest::powerOff()" << endl;
597  Emit("powerOff()");
598 }
599 
600 
601 // ----------------------------------------------------------------------
603  // LOG(logINFO) << "PixTest::doTest()";
604 }
605 
606 // ----------------------------------------------------------------------
608  doTest();
609 }
610 
611 
612 // ----------------------------------------------------------------------
614  // LOG(logINFO) << "PixTest::doAnalysis()";
615 }
616 
617 
618 // ----------------------------------------------------------------------
620  if (fHistList.size() == 0) return 0;
621  std::list<TH1*>::iterator itmp = fDisplayedHist;
622  ++itmp;
623  if (itmp == fHistList.end()) {
624  // -- wrap around and point to first histogram in list
625  fDisplayedHist = fHistList.begin();
626  return (*fDisplayedHist);
627  } else {
628  ++fDisplayedHist;
629  return (*fDisplayedHist);
630  }
631 }
632 
633 // ----------------------------------------------------------------------
635  if (fHistList.size() == 0) return 0;
636  if (fDisplayedHist == fHistList.begin()) {
637  // -- wrap around and point to last histogram in list
638  fDisplayedHist = fHistList.end();
639  --fDisplayedHist;
640  return (*fDisplayedHist);
641  } else {
642  --fDisplayedHist;
643  return (*fDisplayedHist);
644  }
645 
646 }
647 
648 // ----------------------------------------------------------------------
649 void PixTest::setTitles(TH1 *h, const char *sx, const char *sy, float size,
650  float xoff, float yoff, float lsize, int font) {
651  if (h == 0) {
652  LOG(logDEBUG) << " Histogram not defined";
653  } else {
654  h->SetXTitle(sx); h->SetYTitle(sy);
655  if (fPixSetup->useRootLogon()) {
656  h->SetTitleOffset(gStyle->GetTitleOffset("X"), "x"); h->SetTitleOffset(gStyle->GetTitleOffset("Y"), "y");
657  h->SetTitleSize(gStyle->GetTitleSize("X"), "x"); h->SetTitleSize(gStyle->GetTitleSize("Y"), "y");
658  h->SetLabelSize(gStyle->GetLabelSize("X"), "x"); h->SetLabelSize(gStyle->GetLabelSize("Y"), "y");
659  h->SetLabelFont(gStyle->GetLabelFont()); h->SetLabelFont(gStyle->GetLabelFont(), "y");
660  h->GetXaxis()->SetTitleFont(gStyle->GetTitleFont("X")); h->GetYaxis()->SetTitleFont(gStyle->GetTitleFont("Y"));
661  h->SetNdivisions(gStyle->GetNdivisions("X"), "X");
662  } else {
663  h->SetTitleOffset(xoff, "x"); h->SetTitleOffset(yoff, "y");
664  h->SetTitleSize(size, "x"); h->SetTitleSize(size, "y");
665  h->SetLabelSize(lsize, "x"); h->SetLabelSize(lsize, "y");
666  h->SetLabelFont(font, "x"); h->SetLabelFont(font, "y");
667  h->GetXaxis()->SetTitleFont(font); h->GetYaxis()->SetTitleFont(font);
668  h->SetNdivisions(508, "X");
669  }
670  }
671 }
672 
673 // ----------------------------------------------------------------------
675  for (list<TH1*>::iterator il = fHistList.begin(); il != fHistList.end(); ++il) {
676  // (*il)->Reset();
677  delete (*il);
678  }
679  fHistList.clear();
680 }
681 
682 
683 // ----------------------------------------------------------------------
685 
686  double plaVal = h->GetMaximum();
687  double thrVal = 0.5*plaVal;
688  for (int ibin = 1; ibin < h->GetNbinsX(); ++ibin) {
689  if (h->GetBinContent(ibin) >= thrVal) {
690  if (h->GetBinContent(ibin+1) < thrVal) continue;
691  return static_cast<int>(h->GetBinCenter(ibin));
692  }
693  }
694  return -1;
695 }
696 
697 
698 // ----------------------------------------------------------------------
699 bool PixTest::threshold(TH1 *h) {
700 
701  TF1 *f = fPIF->errScurve(h);
702 
703  double lo, hi;
704  f->GetRange(lo, hi);
705 
706  fThresholdN = h->FindLastBinAbove(0.5*h->GetMaximum());
707 
708  if (fPIF->doNotFit()) {
709  fThreshold = f->GetParameter(0);
710  fThresholdE = 0.3;
711  fSigma = 0.;
712  fSigmaE = 0.;
713  return false;
714  } else {
715  h->Fit(f, "qr", "", lo, hi);
716  fThreshold = f->GetParameter(0);
717  fThresholdE = f->GetParError(0);
718  fSigma = 1./(TMath::Sqrt(2.)/f->GetParameter(1));
719  fSigmaE = fSigma * f->GetParError(1) / f->GetParameter(1);
720  }
721 
722  // cout << "fit status: " << gMinuit->GetStatus() << endl;
723 
724 
725  if (fThreshold < h->GetBinLowEdge(1)) {
726  fThreshold = -2.;
727  fThresholdE = -2.;
728  fSigma = -2.;
729  fSigmaE = -2.;
730  fThresholdN = -2.;
731  return false;
732  }
733 
734  if (fThreshold > h->GetBinLowEdge(h->GetNbinsX())) {
735  fThreshold = h->GetBinLowEdge(h->GetNbinsX());
736  fThresholdE = -1.;
737  fSigma = -1.;
738  fSigmaE = -1.;
739  fThresholdN = fThreshold;
740  return false;
741  }
742 
743  return true;
744 }
745 
746 
747 // ----------------------------------------------------------------------
748 TH1D* PixTest::distribution(TH2D* h2, int nbins, double xmin, double xmax) {
749  TH1D *h1 = new TH1D(Form("dist_%s", h2->GetName()), Form("dist_%s", h2->GetName()), nbins, xmin, xmax);
750  for (int ix = 0; ix < h2->GetNbinsX(); ++ix) {
751  for (int iy = 0; iy < h2->GetNbinsY(); ++iy) {
752  h1->Fill(h2->GetBinContent(ix+1, iy+1));
753  }
754  }
755  return h1;
756 }
757 
758 
759 // ----------------------------------------------------------------------
760 void PixTest::cacheDacs(bool verbose) {
761  fDacCache.clear();
762  vector<uint8_t> rocIds = fApi->_dut->getEnabledRocIDs();
763  for (unsigned i = 0; i < rocIds.size(); ++i) {
764  fDacCache.push_back(fApi->_dut->getDACs(rocIds[i]));
765  if (verbose) fApi->_dut->printDACs(i);
766  }
767 }
768 
769 
770 // ----------------------------------------------------------------------
771 void PixTest::restoreDacs(bool verbose) {
772 
773  vector<uint8_t> rocIds = fApi->_dut->getEnabledRocIDs();
774  for (unsigned int iroc = 0; iroc < rocIds.size(); ++iroc) {
775  vector<pair<string, uint8_t> > rocDacs = fDacCache[iroc];
776  for (unsigned int idac = 0; idac < rocDacs.size(); ++idac) {
777  fApi->setDAC(rocDacs[idac].first, rocDacs[idac].second, rocIds[iroc]);
778  }
779  if (verbose) fApi->_dut->printDACs(rocIds[iroc]);
780  }
781  fDacCache.clear();
782 }
783 
784 
785 // ----------------------------------------------------------------------
786 TH1* PixTest::moduleMap(string histname) {
787  // FIXME? Loop over fHistList instead of using Directory->Get()?
788  LOG(logDEBUG) << "moduleMap histname: " << histname;
789  TH1* h0 = (*fDisplayedHist);
790  if (!h0->InheritsFrom(TH2::Class())) {
791  return 0;
792  }
793  TH2D *h1 = (TH2D*)h0;
794  string h1name = h1->GetName();
795  string::size_type s1 = h1name.rfind("_C");
796  string barename = h1name.substr(0, s1);
797  string h2name = barename + string("_mod");
798  LOG(logDEBUG) << "h1->GetName() = " << h1name << " -> " << h2name;
799  TH2D *h2 = bookTH2D(h2name.c_str(), h2name.c_str(), 2*80, 0., 2*80., 8*52, 0., 8*52);
800  fHistOptions.insert(make_pair(h2, "colz"));
801  int cycle(-1);
802  vector<uint8_t> rocIds = fApi->_dut->getEnabledRocIDs();
803  for (unsigned int iroc = 0; iroc < rocIds.size(); ++iroc){
804  if (0 == iroc) cycle = -1 + histCycle(Form("%s_C%d", barename.c_str(), rocIds[iroc]));
805  TH2D *hroc = (TH2D*)fDirectory->Get(Form("%s_C%d_V%d", barename.c_str(), rocIds[iroc], cycle));
806  if (hroc) fillMap(h2, hroc, rocIds[iroc]);
807  }
808 
809  fHistList.push_back(h2);
810  fDisplayedHist = find(fHistList.begin(), fHistList.end(), h2);
811 
812  if (h2) h2->Draw(getHistOption(h2).c_str());
813  update();
814  return h2;
815 }
816 
817 // ----------------------------------------------------------------------
818 void PixTest::fillMap(TH2D *hmod, TH2D *hroc, int iroc) {
819  int mxOffset(iroc<8?159:0), mxDirection(iroc<8?-1:+1);
820  int myOffset(iroc<8?52*(iroc%8):52*(16-iroc)-1), myDirection(iroc<8?1:-1);
821 
822  int mx, my;
823  for (int rx = 0; rx < hroc->GetNbinsX(); ++rx) {
824  for (int ry = 0; ry < hroc->GetNbinsY(); ++ry) {
825  mx = mxOffset + mxDirection*ry;
826  my = myOffset + myDirection*rx;
827  // if (0) cout << "mod x: " << mx
828  // << " mod y: " << my
829  // << endl;
830  hmod->Fill(mx, my, hroc->GetBinContent(rx+1, ry+1));
831  }
832  }
833 
834 }
835 
836 
837 
838 // ----------------------------------------------------------------------
839 void PixTest::sparseRoc(int npix) {
840 
841  if (!fApi) return;
842 
843  int cnt(0);
844  if (npix < 11) {
845  for (int i = 0; i < npix; ++i) {
846  fApi->_dut->testPixel(5*i, 5*i, true);
847  fApi->_dut->maskPixel(5*i, 5*i, false);
848  }
849  return;
850  } else if (npix < 101) {
851  for (int i = 0; i < 50; ++i) {
852  fApi->_dut->testPixel(i, 5 + i/2, true);
853  fApi->_dut->maskPixel(i, 5 + i/2, false);
854  ++cnt;
855  fApi->_dut->testPixel(i, 15 + i/2, true);
856  fApi->_dut->maskPixel(i, 15 + i/2, false);
857  ++cnt;
858  if (cnt == npix) return;
859  }
860  } else if (npix < 1001) {
861  for (int i = 0; i < 50; ++i) {
862  for (int j = 0; j < 10; ++j) {
863  fApi->_dut->testPixel(i, i + 2*j, true);
864  fApi->_dut->maskPixel(i, i + 2*j, false);
865  fApi->_dut->testPixel(i, i + 5*j, true);
866  fApi->_dut->maskPixel(i, i + 5*j, false);
867  ++cnt;
868  if (cnt == npix) return;
869  }
870  }
871  } else{
872  fApi->_dut->testAllPixels(true);
873  fApi->_dut->maskAllPixels(false);
874  }
875 }
876 
877 
878 // ----------------------------------------------------------------------
879 bool PixTest::selectedRoc(int iroc) {
880  vector<uint8_t> v = fApi->_dut->getEnabledRocIDs();
881  if (v.end() == find(v.begin(), v.end(), iroc)) {
882  return false;
883  }
884  return true;
885 }
886 
887 
888 // ----------------------------------------------------------------------
889 void PixTest::setId2Idx(std::map<int, int> a) {
890  fId2Idx = a;
891 }
892 
893 
894 // ----------------------------------------------------------------------
895 TH1D* PixTest::bookTH1D(std::string sname, std::string title, int nbins, double xmin, double xmax) {
896  int cnt = histCycle(sname);
897  // LOG(logDEBUG) << "bookTH1D " << Form("%s_V%d", sname.c_str(), cnt);
898  return new TH1D(Form("%s_V%d", sname.c_str(), cnt), Form("%s (V%d)", title.c_str(), cnt), nbins, xmin, xmax);
899 }
900 
901 
902 // ----------------------------------------------------------------------
903 TH2D* PixTest::bookTH2D(std::string sname, std::string title, int nbinsx, double xmin, double xmax,
904  int nbinsy, double ymin, double ymax) {
905  int cnt = histCycle(sname);
906  // LOG(logDEBUG) << "bookTH2D " << Form("%s_V%d", sname.c_str(), cnt);
907  return new TH2D(Form("%s_V%d", sname.c_str(), cnt), Form("%s (V%d)", title.c_str(), cnt), nbinsx, xmin, xmax, nbinsy, ymin, ymax);
908 }
909 
910 // ----------------------------------------------------------------------
911 TProfile2D* PixTest::bookTProfile2D(std::string sname, std::string title, int nbinsx, double xmin, double xmax,
912  int nbinsy, double ymin, double ymax, string option) {
913  int cnt = histCycle(sname);
914  // LOG(logDEBUG) << "bookTH2D " << Form("%s_V%d", sname.c_str(), cnt);
915  return new TProfile2D(Form("%s_V%d", sname.c_str(), cnt), Form("%s (V%d)", title.c_str(), cnt),
916  nbinsx, xmin, xmax, nbinsy, ymin, ymax, option.c_str());
917 }
918 
919 
920 // ----------------------------------------------------------------------
921 int PixTest::histCycle(string hname) {
922  TH1* h(0);
923  int cnt(0);
924  if (fPixSetup->doRootFileUpdate()) fDirectory->ReadAll();
925  h = (TH1*)fDirectory->FindObject(Form("%s_V%d", hname.c_str(), cnt));
926  // TKey *k(0);
927  // k = (TKey*)fDirectory->FindKey(Form("%s_V%d", hname.c_str(), cnt));
928  // cout << k << endl;
929  // if (k) h = (TH1*)k->ReadObj();
930  while (h) {
931  ++cnt;
932  h = (TH1*)fDirectory->FindObject(Form("%s_V%d", hname.c_str(), cnt));
933  // k = (TKey*)fDirectory->FindKey(Form("%s_V%d", hname.c_str(), cnt));
934  // cout << k << endl;
935  // if (k) h = (TH1*)k->ReadObj();
936  }
937  return cnt;
938 }
939 
940 // ----------------------------------------------------------------------
941 string PixTest::getHistOption(TH1* h) {
942  map<TH1*, string>::iterator end = fHistOptions.end();
943  for (map<TH1*, string>::iterator pos = fHistOptions.begin();
944  pos != end; ++pos) {
945  if (h == pos->first) return pos->second;
946  }
947  return string("");
948 }
949 
950 
951 // ----------------------------------------------------------------------
952 vector<int> PixTest::getMaximumVthrComp(int ntrig, double frac, int reserve) {
953 
954  vector<int> results;
955  results.clear();
956 
957  // uint16_t FLAGS = FLAG_FORCE_MASKED | FLAG_FORCE_SERIAL;
958  uint16_t FLAGS = FLAG_FORCE_MASKED;
959 
960  vector<pair<uint8_t, vector<pixel> > > scans;
961  int cnt(0);
962  bool done = false;
963  while (!done){
964  LOG(logDEBUG) << " attempt #" << cnt;
965  try {
966  scans = fApi->getEfficiencyVsDAC("vthrcomp", 0, 255, FLAGS, ntrig);
967  fNDaqErrors = fApi->getStatistics().errors_pixel();
968  done = true;
969  } catch(pxarException &/*e*/) {
970  fNDaqErrors = 666667;
971  ++cnt;
972  }
973  done = (cnt>2) || done;
974  }
975 
976 
977  LOG(logDEBUG) << " getMaximumVthrComp.size(): " << scans.size();
978 
979  vector<uint8_t> rocIds = fApi->_dut->getEnabledRocIDs();
980  vector<TH1*> scanHists;
981  vector<int> npixels;
982  TH1* h1;
983  for (unsigned int iroc = 0; iroc < rocIds.size(); ++iroc){
984  h1 = bookTH1D(Form("maxVthrComp_C%d", rocIds[iroc]), Form("maxVthrComp_C%d", rocIds[iroc]), 255, 0., 255.);
985  scanHists.push_back(h1);
986  npixels.push_back(fApi->_dut->getNEnabledPixels(rocIds[iroc]));
987  }
988 
989  int idx(-1);
990  for (unsigned int i = 0; i < scans.size(); ++i) {
991  pair<uint8_t, vector<pixel> > v = scans[i];
992  int idac = v.first;
993 
994  vector<pixel> vpix = v.second;
995  for (unsigned int ipix = 0; ipix < vpix.size(); ++ipix) {
996  idx = getIdxFromId(vpix[ipix].roc());
997  if (scanHists[idx]) {
998  scanHists[idx]->Fill(idac, vpix[ipix].value());
999  } else {
1000  LOG(logDEBUG) << "histogram for ROC " << vpix[ipix].roc() << " not found" << endl;
1001  }
1002  }
1003  }
1004 
1005  for (unsigned int i = 0; i < scanHists.size(); ++i) {
1006  scanHists[i]->Draw();
1007  update();
1008  bool onPlateau(false);
1009  int idac(1);
1010  int plateau = ntrig*npixels[i];
1011  for (idac = 1; idac < 255; ++idac) {
1012  if (scanHists[i]->GetBinContent(idac) > frac*plateau
1013  && scanHists[i]->GetBinContent(idac+1) > frac*plateau
1014  && scanHists[i]->GetBinContent(idac+2) > frac*plateau
1015  && scanHists[i]->GetBinContent(idac+3) > frac*plateau
1016  ) {
1017  onPlateau = true;
1018  } else {
1019  if (onPlateau) {
1020  break;
1021  }
1022  }
1023  }
1024  idac -= reserve;
1025  fHistList.push_back(scanHists[i]);
1026  results.push_back(idac);
1027  }
1028  return results;
1029 }
1030 
1031 
1032 // ----------------------------------------------------------------------
1033 vector<int> PixTest::getMinimumVthrComp(vector<TH1*>maps, int reserve, double nsigma) {
1034  vector<int> results;
1035  results.clear();
1036 
1037  TH2D *h2(0), *hn(0);
1038  string hname("");
1039  for (unsigned int i = 0; i < maps.size(); ++i) {
1040  double minThr(999.), thr(0.), minThrN(999.), result(-1.);
1041  h2 = (TH2D*)maps[i];
1042  hname = h2->GetName();
1043  if (string::npos == hname.find("thr_")) continue;
1044  hn = (TH2D*)maps[i+2];
1045  PixUtil::replaceAll(hname, "thr_", "thn_");
1046  if (strcmp(hname.c_str(), hn->GetName())) {
1047  LOG(logDEBUG) << "XXX problem in the ordering of the scurveMaps results ThrN map has name " << hn->GetName();
1048  continue;
1049  }
1050  TH1* d1 = distribution(h2, 256, 0., 256.);
1051  TH1* dn = distribution(hn, 256, 0., 256.);
1052  double minThrLimit = TMath::Max(1., d1->GetMean() - nsigma*d1->GetRMS());
1053  double minThrNLimit = TMath::Max(1., dn->GetMean() - nsigma*dn->GetRMS());
1054  delete d1;
1055  delete dn;
1056  for (int ic = 0; ic < 52; ++ic) {
1057  for (int ir = 0; ir < 80; ++ir) {
1058  thr = h2->GetBinContent(ic+1, ir+1);
1059  if (thr < minThr && thr > minThrLimit) {
1060  minThr = thr;
1061  }
1062 
1063  thr = hn->GetBinContent(ic+1, ir+1);
1064  if (thr < minThrN && thr > minThrNLimit) {
1065  minThrN = thr;
1066  }
1067  }
1068  }
1069  if (minThrN - reserve < minThr) {
1070  result = minThrN - 10;
1071  LOG(logDEBUG) << "minThr = " << minThr << " minThrN = " << minThrN << " -> result = " << result;
1072  } else {
1073  result = minThr;
1074  LOG(logDEBUG) << "minThr = " << minThr << " minThrLimit = " << minThrLimit << " minThrNLimit = " << minThrNLimit
1075  << " -> result = " << result << " -> " << static_cast<int>(result);
1076  }
1077  results.push_back(static_cast<int>(result));
1078  }
1079  return results;
1080 }
1081 
1082 
1083 // ----------------------------------------------------------------------
1084 double PixTest::getMinimumThreshold(vector<TH1*>maps) {
1085  double val(0.), result(999.);
1086  TH2D *h2(0);
1087  for (unsigned int i = 0; i < maps.size(); ++i) {
1088  h2 = (TH2D*)maps[i];
1089  for (int ic = 0; ic < h2->GetNbinsX(); ++ic) {
1090  for (int ir = 0; ir < h2->GetNbinsY(); ++ir) {
1091  val = h2->GetBinContent(ic+1, ir+1);
1092  if (val > 0 && val < result) result = val;
1093  }
1094  }
1095  }
1096  if (result < 0.) result = 0.;
1097  return result;
1098 }
1099 
1100 // ----------------------------------------------------------------------
1101 double PixTest::getMaximumThreshold(vector<TH1*>maps) {
1102  double result(-999.);
1103  TH2D *h2(0);
1104  for (unsigned int i = 0; i < maps.size(); ++i) {
1105  h2 = (TH2D*)maps[i];
1106  double maxi = h2->GetMaximum();
1107  if (maxi > result) result = maxi;
1108  }
1109  if (result > 255.) result = 255.;
1110  return result;
1111 }
1112 
1113 // ----------------------------------------------------------------------
1115  map<int, int>::iterator end = fId2Idx.end();
1116  for (map<int, int>::iterator il = fId2Idx.begin(); il != end; ++il) {
1117  if (il->second == idx) return il->first;
1118  }
1119  return -1;
1120 }
1121 
1122 
1123 // ----------------------------------------------------------------------
1125  if (fId2Idx.count(id) > 0) {
1126  return fId2Idx[id];
1127  }
1128  return -1;
1129 }
1130 
1131 
1132 
1133 // ----------------------------------------------------------------------
1134 vector<TH1*> PixTest::mapsWithString(vector<TH1*>maps, string name) {
1135  vector<TH1*> results;
1136  string hname("");
1137  for (unsigned i = 0; i < maps.size(); ++i) {
1138  hname = maps[i]->GetName();
1139  if (string::npos != hname.find(name)) results.push_back(maps[i]);
1140  }
1141  return results;
1142 }
1143 
1144 // ----------------------------------------------------------------------
1145 vector<TH2D*> PixTest::mapsWithString(vector<TH2D*>maps, string name) {
1146  vector<TH2D*> results;
1147  string hname("");
1148  for (unsigned i = 0; i < maps.size(); ++i) {
1149  hname = maps[i]->GetName();
1150  if (string::npos != hname.find(name)) results.push_back(maps[i]);
1151  }
1152  return results;
1153 }
1154 
1155 // ----------------------------------------------------------------------
1156 void PixTest::fillDacHist(vector<pair<uint8_t, vector<pixel> > > &results, TH1D *h, int icol, int irow, int iroc) {
1157  h->Reset();
1158  int ri(-1), ic(-1), ir(-1);
1159  for (unsigned int idac = 0; idac < results.size(); ++idac) {
1160  int dac = results[idac].first;
1161  for (unsigned int ipix = 0; ipix < results[idac].second.size(); ++ipix) {
1162  ri = results[idac].second[ipix].roc();
1163  ic = results[idac].second[ipix].column();
1164  ir = results[idac].second[ipix].row();
1165  if (iroc > -1 && ri != iroc) continue;
1166  if (icol > -1 && ic != icol) continue;
1167  if (irow > -1 && ir != irow) continue;
1168  if (ic > 51 || ir > 79) continue;
1169 
1170  h->Fill(dac, results[idac].second[ipix].value());
1171  }
1172  }
1173 
1174 }
1175 
1176 // ----------------------------------------------------------------------
1177 void PixTest::bigBanner(string what, TLogLevel log) {
1178  LOG(log) << "######################################################################";
1179  LOG(log) << what;
1180  LOG(log) << "######################################################################";
1181 }
1182 
1183 // ----------------------------------------------------------------------
1184 void PixTest::banner(string what, TLogLevel log) {
1185  LOG(log) << " ----------------------------------------------------------------------";
1186  LOG(log) << " " << what;
1187  LOG(log) << " ----------------------------------------------------------------------";
1188 }
1189 
1190 // ----------------------------------------------------------------------
1191 void PixTest::print(string what, TLogLevel log) {
1192  LOG(log) << "---> " << what;
1193 }
1194 
1195 
1196 // ----------------------------------------------------------------------
1197 void PixTest::preScan(string dac, std::vector<shist256*> maps, int &dacmin, int &dacmax) {
1198  PixTest::update();
1199  uint16_t FLAGS = FLAG_FORCE_MASKED;
1200 
1201  vector<uint8_t> rocIds = fApi->_dut->getEnabledRocIDs();
1202 
1203  bool done(false);
1204  int ntrig(3), cnt(0);
1205  vector<pair<uint8_t, vector<pixel> > > results;
1206 
1207  while (!done){
1208  LOG(logDEBUG) << " attempt #" << cnt;
1209  try{
1210  results = fApi->getEfficiencyVsDAC(dac, 1, 200, FLAGS, ntrig);
1211  fNDaqErrors = fApi->getStatistics().errors_pixel();
1212  done = true;
1213  } catch(pxarException &/*e*/) {
1214  fNDaqErrors = 666667;
1215  ++cnt;
1216  }
1217  done = (cnt>2) || done;
1218  }
1219 
1220  if (666667 == fNDaqErrors) {
1221  LOG(logDEBUG) << "fNDaqErrors = " << fNDaqErrors;
1222  return;
1223  }
1224 
1225  int idx(0), roc(0), ic(0), ir(0);
1226  double val(0.);
1227  for (unsigned int idac = 0; idac < results.size(); ++idac) {
1228  int dac = results[idac].first;
1229  for (unsigned int ipix = 0; ipix < results[idac].second.size(); ++ipix) {
1230  ic = results[idac].second[ipix].column();
1231  ir = results[idac].second[ipix].row();
1232  roc = results[idac].second[ipix].roc();
1233  if (ic > 51 || ir > 79) {
1234  LOG(logDEBUG) << "bad pixel address encountered: ROC/col/row = " << roc << "/" << ic << "/" << ir;
1235  continue;
1236  }
1237  val = results[idac].second[ipix].value();
1238  idx = PixUtil::rcr2idx(getIdxFromId(roc), ic, ir);
1239  if (idx > -1) maps[idx]->fill(dac, val);
1240  }
1241  }
1242 
1243 
1244  // -- analyze results
1245  bool ok(false);
1246  TH1D *hT = new TH1D("hT", "hT", 256, 0., 256.); hT->Sumw2();
1247  TH1D *h1 = new TH1D("h1", "h1", 256, 0., 256.); h1->Sumw2();
1248  for (unsigned int iroc = 0; iroc < rocIds.size(); ++iroc) {
1249  LOG(logDEBUG) << "analyzing ROC " << static_cast<int>(rocIds[iroc]);
1250  for (unsigned int i = iroc*4160; i < (iroc+1)*4160; ++i) {
1251  if (maps[i]->getSumOfWeights() < 1) continue;
1252 
1253  h1->Reset();
1254  for (int ib = 1; ib <= 256; ++ib) {
1255  h1->SetBinContent(ib, maps[i]->get(ib));
1256  h1->SetBinError(ib, ntrig*PixUtil::dBinomial(static_cast<int>(maps[i]->get(ib)), ntrig));
1257  }
1258 
1259  ok = threshold(h1);
1260  if (fThreshold > 0) {
1261  hT->Fill(fThreshold);
1262 // TH1D *h = (TH1D*)h1->Clone(Form("h1_%d", i));
1263 // h->SetTitle(Form("OK i = %d, thr = %4.3f, thrn = %4.3f", i, fThreshold, fThresholdN));
1264 // fHistList.push_back(h);
1265  } else {
1266  hT->Fill(0.);
1267 // TH1D *h = (TH1D*)h1->Clone(Form("h1_%d", i));
1268 // h->SetTitle(Form("i = %d, thr = %4.3f, thrn = %4.3f", i, fThreshold, fThresholdN));
1269 // fHistList.push_back(h);
1270  }
1271 
1272 // if (fThreshold > 80.) {
1273 // TH1D *h = (TH1D*)h1->Clone(Form("h1_%d", i));
1274 // h->SetTitle(Form("i = %d, thr = %4.3f, thrn = %4.3f", i, fThreshold, fThresholdN));
1275 // fHistList.push_back(h);
1276 // }
1277  }
1278  }
1279 
1280  int lo(-1), hi(-1);
1281  for (int i = 1; i < 256; ++i) {
1282  if (hT->Integral(i, i+5) > 5) {
1283  lo = i;
1284  break;
1285  }
1286  }
1287 
1288  for (int i = lo; i < 255; ++i) {
1289  if (0 == hT->Integral(i, i+5)) {
1290  hi = i;
1291  break;
1292  }
1293  }
1294 
1295  if (lo > hi) {
1296  lo = 1;
1297  hi = 255;
1298  }
1299 
1300  dacmin = lo;
1301  dacmax = hi;
1302 
1303  fHistList.push_back(hT);
1304  fDisplayedHist = find(fHistList.begin(), fHistList.end(), hT);
1305  hT->Draw();
1306  PixTest::update();
1307 
1308 }
1309 
1310 
1311 // ----------------------------------------------------------------------
1312 void PixTest::dacScan(string dac, int ntrig, int dacmin, int dacmax, std::vector<shist256*> maps, int ihit, int flag) {
1313  uint16_t FLAGS = flag | FLAG_FORCE_MASKED;
1314 
1315  fNtrig = ntrig;
1316 
1317  vector<uint8_t> rocIds = fApi->_dut->getEnabledRocIDs();
1318 
1319  int ic, ir, iroc;
1320  double val;
1321  bool done = false;
1322  int cnt(0);
1323  vector<pair<uint8_t, vector<pixel> > > results;
1324 
1325  if (2 == ihit) {
1326  LOG(logDEBUG) << "determine PH error: " << dacmin << " .. " << dacmax;
1327  getPhError(dac, dacmin, dacmax, FLAGS, fNtrig);
1328  }
1329 
1330  while (!done){
1331  LOG(logDEBUG) << " attempt #" << cnt;
1332  try{
1333  if (1 == ihit) {
1334  results = fApi->getEfficiencyVsDAC(dac, dacmin, dacmax, FLAGS, fNtrig);
1335  fNDaqErrors = fApi->getStatistics().errors_pixel();
1336  } else {
1337  results = fApi->getPulseheightVsDAC(dac, dacmin, dacmax, FLAGS, fNtrig);
1338  fNDaqErrors = fApi->getStatistics().errors_pixel();
1339  }
1340  done = true;
1341  } catch(pxarException &/*e*/) {
1342  fNDaqErrors = 666667;
1343  ++cnt;
1344  }
1345  done = (cnt>2) || done;
1346  }
1347 
1348  int idx(0);
1349  for (unsigned int idac = 0; idac < results.size(); ++idac) {
1350  int dac = results[idac].first;
1351  for (unsigned int ipix = 0; ipix < results[idac].second.size(); ++ipix) {
1352  ic = results[idac].second[ipix].column();
1353  ir = results[idac].second[ipix].row();
1354  iroc = results[idac].second[ipix].roc();
1355  if (ic > 51 || ir > 79) {
1356  LOG(logDEBUG) << "bad pixel address encountered: ROC/col/row = " << iroc << "/" << ic << "/" << ir;
1357  continue;
1358  }
1359  val = results[idac].second[ipix].value();
1360  idx = PixUtil::rcr2idx(getIdxFromId(iroc), ic, ir);
1361  if (idx > -1) maps[idx]->fill(dac, val);
1362  }
1363  }
1364 
1365 }
1366 
1367 
1368 // ----------------------------------------------------------------------
1369 void PixTest::scurveAna(string dac, string name, vector<shist256*> maps, vector<TH1*> &resultMaps, int result) {
1370  fDirectory->cd();
1371  TH1* h2(0), *h3(0), *h4(0);
1372  string fname("SCurveData");
1373  ofstream OutputFile;
1374  string line;
1375  string empty("32 93 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ");
1376  bool dumpFile(false);
1377  vector<uint8_t> rocIds = fApi->_dut->getEnabledRocIDs();
1378  int roc(0), ic(0), ir(0);
1379  TH1D *h1 = new TH1D("h1", "h1", 256, 0., 256.); h1->Sumw2();
1380 
1381  for (unsigned int iroc = 0; iroc < rocIds.size(); ++iroc) {
1382  LOG(logDEBUG) << "analyzing ROC " << static_cast<int>(rocIds[iroc]);
1383  h2 = bookTH2D(Form("thr_%s_%s_C%d", name.c_str(), dac.c_str(), rocIds[iroc]),
1384  Form("thr_%s_%s_C%d", name.c_str(), dac.c_str(), rocIds[iroc]),
1385  52, 0., 52., 80, 0., 80.);
1386  fHistOptions.insert(make_pair(h2, "colz"));
1387 
1388  h3 = bookTH2D(Form("sig_%s_%s_C%d", name.c_str(), dac.c_str(), rocIds[iroc]),
1389  Form("sig_%s_%s_C%d", name.c_str(), dac.c_str(), rocIds[iroc]),
1390  52, 0., 52., 80, 0., 80.);
1391  fHistOptions.insert(make_pair(h3, "colz"));
1392 
1393  h4 = bookTH2D(Form("thn_%s_%s_C%d", name.c_str(), dac.c_str(), rocIds[iroc]),
1394  Form("thn_%s_%s_C%d", name.c_str(), dac.c_str(), rocIds[iroc]),
1395  52, 0., 52., 80, 0., 80.);
1396  fHistOptions.insert(make_pair(h4, "colz"));
1397 
1398  string lname(name);
1399  std::transform(lname.begin(), lname.end(), lname.begin(), ::tolower);
1400  if (!name.compare("scurveVcal") || !lname.compare("scurvevcal")) {
1401  dumpFile = true;
1402  OutputFile.open(Form("%s/%s_C%d.dat", fPixSetup->getConfigParameters()->getDirectory().c_str(), fname.c_str(), iroc));
1403  OutputFile << "Mode 1 " << "Ntrig " << fNtrig << endl;
1404  }
1405 
1406 
1407  for (unsigned int i = iroc*4160; i < (iroc+1)*4160; ++i) {
1408  PixUtil::idx2rcr(i, roc, ic, ir);
1409  if (maps[i]->getSumOfWeights() < 1) {
1410  if (dumpFile) OutputFile << empty << endl;
1411  continue;
1412  }
1413 
1414  // -- calculated "proper" errors
1415  h1->Reset();
1416  for (int ib = 1; ib <= 256; ++ib) {
1417  h1->SetBinContent(ib, maps[i]->get(ib));
1418  h1->SetBinError(ib, fNtrig*PixUtil::dBinomial(static_cast<int>(maps[i]->get(ib)), fNtrig));
1419  }
1420 
1421  bool ok = threshold(h1);
1422  if (((result & 0x10) && !ok) || (result & 0x20)) {
1423  TH1D *h1c = (TH1D*)h1->Clone(Form("scurve_%s_c%d_r%d_C%d", dac.c_str(), ic, ir, rocIds[iroc]));
1424  if (!ok) {
1425  h1c->SetTitle(Form("problematic %s scurve (c%d_r%d_C%d), thr = %4.3f", dac.c_str(), ic, ir, rocIds[iroc], fThreshold));
1426  } else {
1427  h1c->SetTitle(Form("%s scurve (c%d_r%d_C%d), thr = %4.3f", dac.c_str(), ic, ir, rocIds[iroc], fThreshold));
1428  }
1429  fHistList.push_back(h1c);
1430  }
1431  h2->SetBinContent(ic+1, ir+1, fThreshold);
1432  h2->SetBinError(ic+1, ir+1, fThresholdE);
1433 
1434  h3->SetBinContent(ic+1, ir+1, fSigma);
1435  h3->SetBinError(ic+1, ir+1, fSigmaE);
1436 
1437  h4->SetBinContent(ic+1, ir+1, fThresholdN);
1438 
1439  // -- write file
1440  if (dumpFile) {
1441  int NSAMPLES(32);
1442  int ibin = h1->FindBin(fThreshold);
1443  int bmin = ibin - 15;
1444  line = Form("%2d %3d", NSAMPLES, bmin);
1445  for (int ix = bmin; ix < bmin + NSAMPLES; ++ix) {
1446  line += string(Form(" %3d", static_cast<int>(h1->GetBinContent(ix+1))));
1447  }
1448  OutputFile << line << endl;
1449  }
1450  }
1451  if (dumpFile) OutputFile.close();
1452 
1453  if (result & 0x1) {
1454  resultMaps.push_back(h2);
1455  fHistList.push_back(h2);
1456  }
1457  if (result & 0x2) {
1458  resultMaps.push_back(h3);
1459  fHistList.push_back(h3);
1460  }
1461  if (result & 0x4) {
1462  resultMaps.push_back(h4);
1463  fHistList.push_back(h4);
1464  }
1465 
1466  if (result & 0x8) {
1467  if (result & 0x1) {
1468  TH1* d1 = distribution((TH2D*)h2, 256, 0., 256.);
1469  resultMaps.push_back(d1);
1470  fHistList.push_back(d1);
1471  }
1472  if (result & 0x2) {
1473  TH1* d2 = distribution((TH2D*)h3, 100, 0., 6.);
1474  resultMaps.push_back(d2);
1475  fHistList.push_back(d2);
1476  }
1477  if (result & 0x4) {
1478  TH1* d3 = distribution((TH2D*)h4, 256, 0., 256.);
1479  resultMaps.push_back(d3);
1480  fHistList.push_back(d3);
1481  }
1482  }
1483 
1484  }
1485 
1486  fDisplayedHist = find(fHistList.begin(), fHistList.end(), h2);
1487 
1488  delete h1;
1489 
1490  if (h2) h2->Draw("colz");
1491  PixTest::update();
1492 
1493 }
1494 
1495 // ----------------------------------------------------------------------
1496 void PixTest::getPhError(std::string /*dac*/, int /*dacmin*/, int /*dacmax*/, int /*FLAGS*/, int /*ntrig*/) {
1497 
1498  // -- initialize to 5% constant error
1499  vector<uint8_t> rocIds = fApi->_dut->getEnabledRocIDs();
1500  for (unsigned int iroc = 0; iroc < rocIds.size(); ++iroc){
1501  fPhErrP0.push_back(0.05);
1502  fPhErrP1.push_back(0.0);
1503  // h0 = new TH1D(Form("phErr_C%d", rocIds[iroc]), Form("phErr_C%d", rocIds[iroc]), 256, 0., 256.);
1504  // maps.push_back(h0);
1505  }
1506 
1507  return;
1508 }
1509 
1510 // ----------------------------------------------------------------------
1512  fPixSetup->writeDacParameterFiles();
1513 }
1514 
1515 // ----------------------------------------------------------------------
1517  fPixSetup->writeTrimFiles();
1518 
1519 }
1520 
1521 // ----------------------------------------------------------------------
1523  LOG(logDEBUG) << "save Tb parameters";
1524  fPixSetup->getConfigParameters()->writeTbParameterFile();
1525 }
1526 
1527 // ----------------------------------------------------------------------
1528 vector<vector<pair<int, int> > > PixTest::deadPixels(int ntrig, bool scanCalDel) {
1529  vector<vector<pair<int, int> > > deadPixels;
1530  vector<pair<int, int> > deadPixelsRoc;
1531 
1532  // -- local DAC caches
1533  vector<uint8_t> vVcal = getDacs("vcal");
1534  vector<uint8_t> vVthrComp = getDacs("vthrcomp");
1535  vector<uint8_t> vCreg = getDacs("ctrlreg");
1536  vector<uint8_t> vCalDel = getDacs("caldel");
1537 
1538  fApi->setDAC("vcal", 200);
1539  fApi->setDAC("ctrlreg", 4);
1540  fApi->setDAC("vthrcomp", 50);
1541 
1542  fApi->_dut->testAllPixels(true);
1543  fApi->_dut->maskAllPixels(false);
1544  vector<TH2D*> testEff;
1545 
1546  if (scanCalDel) {
1547  // -- initialize testEff with zero-contents TH2D
1548  vector<uint8_t> rocIds = fApi->_dut->getEnabledRocIDs();
1549  for (unsigned int iroc = 0; iroc < rocIds.size(); ++iroc){
1550  TH2D *h2 = bookTH2D(Form("dp0_C%d", rocIds[iroc]), Form("dp0_C%d", rocIds[iroc]), 52, 0., 52., 80, 0., 80.);
1551  testEff.push_back(h2);
1552  }
1553 
1554  // -- scan CalDel
1555  vector<TH2D*> tEff;
1556  for (int icaldel = 10; icaldel < 250; icaldel += 30) {
1557  fApi->setDAC("caldel", icaldel);
1558  tEff = efficiencyMaps(Form("dp_caldel%d", icaldel), ntrig);
1559  for (int i = 0; i < static_cast<int>(tEff.size()); ++i) {
1560  if (tEff[i]->Integral() > testEff[i]->Integral()) {
1561  // cout << " tEff->Integral: " << tEff[i]->Integral() << " > testEff[i]->Integral(): " << testEff[i]->Integral() << endl;
1562  delete testEff[i];
1563  testEff[i] = tEff[i];
1564  } else {
1565  // cout << " tEff->Integral: " << tEff[i]->Integral() << " < testEff[i]->Integral(): " << testEff[i]->Integral() << endl;
1566  delete tEff[i];
1567  }
1568  }
1569  tEff.clear();
1570  }
1571  } else {
1572  testEff = efficiencyMaps("deadPixels", ntrig);
1573  }
1574 
1575  std::pair<int, int> badPix;
1576  Double_t eff(0.);
1577 
1578  for (unsigned int i = 0; i < testEff.size(); ++i) {
1579  deadPixelsRoc.clear();
1580  for(int r=0; r<80; r++){
1581  for(int c=0; c<52; c++){
1582  eff = testEff[i]->GetBinContent( testEff[i]->FindFixBin((double)c + 0.5, (double)r+0.5) );
1583  if (eff<ntrig){
1584  LOG(logDEBUG) << Form("ROC %2d", i) << " col/row = " << c << "/" << r << " with eff " << eff << "/" << ntrig << "; blacklisting";
1585  badPix.first = c;
1586  badPix.second = r;
1587  deadPixelsRoc.push_back(badPix);
1588  }
1589  }
1590  }
1591  deadPixels.push_back(deadPixelsRoc);
1592  }
1593 
1594  setDacs("vcal", vVcal);
1595  setDacs("ctrlreg", vCreg);
1596  setDacs("caldel", vCalDel);
1597  setDacs("vthrcomp", vVthrComp);
1598 
1599  return deadPixels;
1600 }
1601 
1602 
1603 // ----------------------------------------------------------------------
1604 vector<uint8_t> PixTest::getDacs(string dacName) {
1605  vector<uint8_t> result;
1606  vector<uint8_t> rocIds = fApi->_dut->getEnabledRocIDs();
1607  for (unsigned int i = 0; i < rocIds.size(); ++i) {
1608  result.push_back(fApi->_dut->getDAC(rocIds[i], dacName));
1609  }
1610  return result;
1611 }
1612 
1613 // ----------------------------------------------------------------------
1614 string PixTest::getDacsString(std::string dacName) {
1615  vector<uint8_t> v = getDacs(dacName);
1616  stringstream s;
1617  unsigned int vsize = v.size();
1618  for (unsigned int i = 0; i < vsize; ++i) {
1619  s << static_cast<int>(v[i]);
1620  if (i < vsize-1) s << " ";
1621  }
1622  return s.str();
1623 }
1624 
1625 
1626 // ----------------------------------------------------------------------
1627 void PixTest::setDacs(string dacName, vector<uint8_t> v) {
1628  vector<uint8_t> rocIds = fApi->_dut->getEnabledRocIDs();
1629  for (unsigned int i = 0; i < rocIds.size(); ++i) {
1630  fApi->setDAC(dacName, v[i], rocIds[i]);
1631  }
1632 }
1633 
1634 
1635 // ----------------------------------------------------------------------
1636 vector<pair<int,int> > PixTest::checkHotPixels(TH2D* h) {
1637  vector<pair<int,int> > hotPixels(0);
1638  double mean(0.);
1639  for (int ix = 0; ix < h->GetNbinsX(); ++ix) {
1640  for (int iy = 0; iy < h->GetNbinsY(); ++iy) {
1641  mean += h->GetBinContent(ix+1, iy+1);
1642  }
1643  }
1644  mean /= h->GetNbinsX()*h->GetNbinsY();
1645 
1646  double fos = 6.0;
1647  double bc(0.);
1648  double hitThr = (mean < 10.?10.:3.*mean);
1649  LOG(logDEBUG) << "average number of unexpected hits per pixel: "
1650  << mean
1651  << " hit threshold: " << hitThr;
1652  for (int ix = 0; ix < h->GetNbinsX(); ++ix) {
1653  for (int iy = 0; iy < h->GetNbinsY(); ++iy) {
1654  bc = h->GetBinContent(ix+1, iy+1);
1655  if (bc > hitThr && bc > fos*mean) {
1656  hotPixels.push_back(make_pair(ix,iy));
1657  LOG(logDEBUG) << "Found a hot pixel with " << bc << " hits "
1658  << " and masking Pixel (" << ix << ',' << iy << ')';
1659  }
1660  }
1661  }
1662  return hotPixels;
1663 }
1664 
1665 
1666 // ----------------------------------------------------------------------
1667 pair<vector<TH2D*>,vector<TH2D*> > PixTest::xEfficiencyMaps(string name, uint16_t ntrig, uint16_t FLAGS) {
1668 
1669  vector<pixel> results;
1670  vector<uint8_t> rocIds = fApi->_dut->getEnabledRocIDs();
1671  int cnt(0);
1672  bool done = false;
1673  while (!done){
1674  LOG(logDEBUG) << " attempt #" << cnt;
1675  try {
1676  results = fApi->getEfficiencyMap(FLAGS, ntrig);
1677  fNDaqErrors = fApi->getStatistics().errors_pixel();
1678  done = true;
1679  } catch(pxarException &/*e*/) {
1680  fNDaqErrors = 666667;
1681  ++cnt;
1682  }
1683  done = (cnt>2) || done;
1684  }
1685 
1686  fDirectory->cd();
1687  vector<TH2D*> maps;
1688  vector<TH2D*> xMaps;
1689  TH2D *h2(0),*h3(0);
1690  for (unsigned int iroc = 0; iroc < rocIds.size(); ++iroc){
1691  h2 = bookTH2D(Form("%s_calmap_C%d", name.c_str(), rocIds[iroc]),
1692  Form("%s_calmap_C%d", name.c_str(), rocIds[iroc]),
1693  52, 0., 52., 80, 0., 80.);
1694  fHistOptions.insert(make_pair(h2,"colz"));
1695  h3 = bookTH2D(Form("%s_xraymap_C%d", name.c_str(), rocIds[iroc]),
1696  Form("%s_xraymap_C%d", name.c_str(), rocIds[iroc]),
1697  52, 0., 52., 80, 0., 80.);
1698  fHistOptions.insert(make_pair(h3,"colz"));
1699  h2->SetMinimum(0.);
1700  h3->SetMinimum(0.);
1701 
1702  h2->SetDirectory(fDirectory);
1703  h3->SetDirectory(fDirectory);
1704 
1705  setTitles(h2, "col", "row");
1706  setTitles(h3, "col", "row");
1707 
1708  maps.push_back(h2);
1709  xMaps.push_back(h3);
1710  }
1711 
1712  int idx(-1);
1713  for (unsigned int i = 0; i < results.size(); ++i) {
1714  idx = getIdxFromId(results[i].roc());
1715  if (rocIds.end() != find(rocIds.begin(), rocIds.end(), idx)) {
1716  h2 = maps[idx];
1717  h3 = xMaps[idx];
1718  if (FLAGS | FLAG_CHECK_ORDER) {
1719  if (results[i].value() > 0) {
1720  h2->Fill(results[i].column(), results[i].row(), static_cast<float>(results[i].value()));
1721  }
1722  else {
1723  //add a hit to the X-ray counter if a hit comes in out of order
1724  h3->Fill(results[i].column(), results[i].row(), 1);
1725  }
1726  }
1727  else {
1728  h2->Fill(results[i].column(), results[i].row(), static_cast<float>(results[i].value()));
1729  }
1730  }
1731  else {
1732  LOG(logDEBUG) << "histogram for ROC " << (int)results[i].roc() << " not found";
1733  }
1734  }
1735  LOG(logDEBUG) << "Size of results from : PixTestHighRate::xEfficiencyMaps: " << results.size();
1736  return make_pair(maps, xMaps);
1737 }
1738 
1739 
1740 // ----------------------------------------------------------------------
1742  string mfile = fPixSetup->getConfigParameters()->getDirectory() + "/" + fPixSetup->getConfigParameters()->getMaskFileName();
1743  vector<vector<pair<int, int> > > vmask = fPixSetup->getConfigParameters()->readMaskFile(mfile);
1744 
1745  for (unsigned int i = 0; i < vmask.size(); ++i) {
1746  vector<pair<int, int> > mask = vmask[i];
1747  for (unsigned int ipix = 0; ipix < mask.size(); ++ipix) {
1748  LOG(logINFO) << "ROC " << getIdFromIdx(i) << " masking pixel " << mask[ipix].first << "/" << mask[ipix].second;
1749  fApi->_dut->maskPixel(mask[ipix].first, mask[ipix].second, true, getIdFromIdx(i));
1750  }
1751  }
1752 
1753 }
1754 
1755 
1756 // ----------------------------------------------------------------------
1757 void PixTest::pgToDefault() {
1758  fPg_setup.clear();
1759  fPg_setup = fPixSetup->getConfigParameters()->getTbPgSettings();
1760  fApi->setPatternGenerator(fPg_setup);
1761  LOG(logINFO) << "PixTest:: pg_setup set to default.";
1762 }
1763 
1764 // ----------------------------------------------------------------------
1766  pgToDefault();
1767  fPg_setup.clear();
1768 }
1769 
1770 // ----------------------------------------------------------------------
1772  // -- setup DAQ for data taking
1773  fPg_setup.clear();
1774  fPg_setup.push_back(make_pair("resetroc", 0)); // PG_RESR b001000
1775  uint16_t period = 28;
1776  fApi->setPatternGenerator(fPg_setup);
1777  fApi->daqStart();
1778  fApi->daqTrigger(1, period);
1779  LOG(logINFO) << "IGNORE THE WARNING ABOVE (resetROC sent)!";
1780  fApi->daqStop();
1781  fPg_setup.clear();
1782 }
1783 
1784 // ----------------------------------------------------------------------
1786  // -- setup DAQ for data taking
1787  fPg_setup.clear();
1788  fPg_setup.push_back(make_pair("resettbm", 0)); // PG_RESR b001000
1789  uint16_t period = 28;
1790  fApi->setPatternGenerator(fPg_setup);
1791  fApi->daqStart();
1792  fApi->daqTrigger(1, period);
1793  LOG(logINFO) << "IGNORE THE WARNING ABOVE (resetTBM sent)!";
1794  fApi->daqStop();
1795  fPg_setup.clear();
1796 }
1797 
1798 // ----------------------------------------------------------------------
1799 uint16_t PixTest::prepareDaq(int triggerFreq, uint8_t trgTkDel) {
1800  resetROC();
1801  uint16_t totalPeriod = setTriggerFrequency(triggerFreq, trgTkDel);
1802  fApi->setPatternGenerator(fPg_setup);
1803  return totalPeriod;
1804 }
1805 
1806 // ----------------------------------------------------------------------
1807 uint16_t PixTest::setTriggerFrequency(int triggerFreq, uint8_t trgTkDel) {
1808 
1809  uint16_t nDel = 0;
1810  uint16_t totalPeriod = 0;
1811 
1812  double period_ns = 1 / (double)triggerFreq * 1000000; // trigger frequency in kHz.
1813  double clkDelays = period_ns / 25 - trgTkDel;
1814  uint16_t ClkDelays = (uint16_t)clkDelays; // aproximate to defect
1815 
1816  fPg_setup.clear();
1817 
1818  // -- add right delay between triggers:
1819  uint16_t i = ClkDelays;
1820  while (i>255){
1821  fPg_setup.push_back(make_pair("delay", 255));
1822  i = i - 255;
1823  nDel++;
1824  }
1825  fPg_setup.push_back(make_pair("delay", i));
1826 
1827  // -- then send trigger and token:
1828  fPg_setup.push_back(make_pair("trg", trgTkDel)); // PG_TRG b000010
1829  fPg_setup.push_back(make_pair("tok", 0)); // PG_TOK
1830  if (0) for (unsigned int i = 0; i < fPg_setup.size(); ++i) cout << fPg_setup[i].first << ": " << (int)fPg_setup[i].second << endl;
1831 
1832  totalPeriod = ((uint16_t)period_ns / 25) + 4 + nDel; //+4 to align to the new pg minimum (1 additional clk cycle per PG call);
1833  return totalPeriod;
1834 }
1835 
1836 // ----------------------------------------------------------------------
1837 void PixTest::maskHotPixels(std::vector<TH2D*> v) {
1838 
1839  int NSECONDS(10);
1840  int TRGFREQ(100); // in kiloHertz
1841 
1842  banner(Form("PixTest::maskHotPixels() running for %d seconds with %d kHz trigger rate", NSECONDS, TRGFREQ));
1843 
1844  fHotPixels.clear();
1845 
1846  fApi->_dut->testAllPixels(false);
1847  fApi->_dut->maskAllPixels(false);
1848 
1849  int totalPeriod = prepareDaq(TRGFREQ, (uint8_t)500);
1850 
1851  timer t;
1852  uint8_t perFull;
1853  bool daq_loop = true;
1854 
1855  fApi->daqStart();
1856 
1857  int finalPeriod = fApi->daqTriggerLoop(totalPeriod);
1858  LOG(logINFO) << "PixTestHighRate::maskHotPixels start TriggerLoop with period " << finalPeriod
1859  << " and duration " << NSECONDS << " seconds and trigger rate " << TRGFREQ << " kHz";
1860 
1861  while (fApi->daqStatus(perFull) && daq_loop) {
1862  if (perFull > 80) {
1863  LOG(logINFO) << "Buffer almost full, pausing triggers.";
1864  fApi->daqTriggerLoopHalt();
1865 
1866  // fillMap(v):
1867  vector<pxar::Event> daqdat = fApi->daqGetEventBuffer();
1868  for(std::vector<pxar::Event>::iterator it = daqdat.begin(); it != daqdat.end(); ++it) {
1869  for (unsigned int ipix = 0; ipix < it->pixels.size(); ++ipix) {
1870  v[getIdxFromId(it->pixels[ipix].roc())]->Fill(it->pixels[ipix].column(), it->pixels[ipix].row());
1871  }
1872  }
1873 
1874  LOG(logINFO) << "Resuming triggers.";
1875  fApi->daqTriggerLoop(finalPeriod);
1876  }
1877 
1878  if (static_cast<int>(t.get()/1000) >= NSECONDS) {
1879  LOG(logINFO) << "Done with hot pixel readout";
1880  daq_loop = false;
1881  break;
1882  }
1883  }
1884 
1885  fApi->daqTriggerLoopHalt();
1886  fApi->daqStop();
1887 
1888  // fillMap(v):
1889  vector<pxar::Event> daqdat = fApi->daqGetEventBuffer();
1890  for(std::vector<pxar::Event>::iterator it = daqdat.begin(); it != daqdat.end(); ++it) {
1891  for (unsigned int ipix = 0; ipix < it->pixels.size(); ++ipix) {
1892  v[getIdxFromId(it->pixels[ipix].roc())]->Fill(it->pixels[ipix].column(), it->pixels[ipix].row());
1893  }
1894  }
1895 
1896  finalCleanup();
1897 
1898 
1899  // -- analysis of hit map
1900  double THR = 1.e-4*NSECONDS*TRGFREQ*1000;
1901  LOG(logDEBUG) << "hot pixel determination with THR = " << THR;
1902  int cntHot(0);
1903  TH2D *h(0);
1904  for (unsigned int i = 0; i < v.size(); ++i) {
1905  h = v[i];
1906  vector<pair<int, int> > hot;
1907  for (int ix = 0; ix < h->GetNbinsX(); ++ix) {
1908  for (int iy = 0; iy < h->GetNbinsY(); ++iy) {
1909  if (h->GetBinContent(ix+1, iy+1) > THR) {
1910  ++cntHot;
1911  LOG(logDEBUG) << "ROC " << i << " with hot pixel " << ix << "/" << iy << ", hits = " << h->GetBinContent(ix+1, iy+1);
1912  hot.push_back(make_pair(ix, iy));
1913  }
1914  }
1915  }
1916  fHotPixels.push_back(hot);
1917  }
1918  if (0 == cntHot) {
1919  LOG(logDEBUG) << "no hot pixel found!";
1920  }
1921  LOG(logINFO) << "PixTest::maskHotPixels() done";
1922 
1923 }
uint16_t prepareDaq(int triggerFreq, uint8_t trgTkDel)
set up DAQ (including call to setTriggerFrequency)
Definition: PixTest.cc:1799
static void replaceAll(std::string &str, const std::string &from, const std::string &to)
in str, replace all occurences of from to to
Definition: PixUtil.cc:24
void getPhError(std::string dac, int dacmin, int dacmax, int FLAGS, int ntrig)
determine PH error interpolation
Definition: PixTest.cc:1496
void fillMap(TH2D *hmod, TH2D *hroc, int iroc)
provides the coordinate transformation to module map
Definition: PixTest.cc:818
std::vector< TH2D * > efficiencyMaps(std::string name, uint16_t ntrig=10, uint16_t FLAGS=FLAG_FORCE_MASKED)
returns TH2D's with hit maps
Definition: PixTest.cc:295
void resetROC()
send reset to ROC(s)
Definition: PixTest.cc:1771
virtual void runCommand(std::string command)
allow execution of any button in the test
Definition: PixTest.cc:129
static std::string stripPos(std::string)
decrepit, do not use
Definition: PixTest.cc:78
void hvOff()
turn HV off
Definition: PixTest.cc:583
static int rcr2idx(int iroc, int icol, int irow)
convert ROC/COL/ROW into idx
Definition: PixUtil.cc:51
virtual void doTest()
function connected to "DoTest" button of PixTab
Definition: PixTest.cc:602
void preScan(std::string dac, std::vector< shist256 * > maps, int &dacmin, int &dacmax)
kind of another work-around (splitting the range, adjusting ntrig, etc)
Definition: PixTest.cc:1197
std::vector< std::vector< std::pair< int, int > > > deadPixels(int ntrig, bool scanCalDel=false)
create vector (per ROC) of vector of dead pixels
Definition: PixTest.cc:1528
void setDacs(std::string dacName, std::vector< uint8_t > dacVector)
set on all ROCs the DAC dacName
Definition: PixTest.cc:1627
TH1 * nextHist()
allow forward iteration through list of histograms
Definition: PixTest.cc:619
void hvOn()
turn HV on
Definition: PixTest.cc:577
int histCycle(std::string hname)
determine histogram cycle
Definition: PixTest.cc:921
void powerOff()
turn DTB power off
Definition: PixTest.cc:595
virtual void fullTest()
function called when FullTest is running; most often this is simply calling doTest() ...
Definition: PixTest.cc:607
void dumpParameters()
print all parameters and values
Definition: PixTest.cc:529
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 resetTBM()
send reset to TBM(s)
Definition: PixTest.cc:1785
int getIdxFromId(int id)
provide the mapping between ROC index and ID
Definition: PixTest.cc:1124
int simpleThreshold(TH1 *)
find first bin above 50% level. Fills fThreshold, fThresholdE, fSigma, fSigmaE
Definition: PixTest.cc:684
virtual void sparseRoc(int npix=8)
select some pattern of pixels if not enabling the complete ROC. Enables the complete ROC if npix > 99...
Definition: PixTest.cc:839
std::vector< std::pair< int, int > > checkHotPixels(TH2D *h)
Definition: PixTest.cc:1636
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...
Definition: PixTest.cc:1033
void maskHotPixels(std::vector< TH2D * >)
determine hot pixels with high occupancy
Definition: PixTest.cc:1837
void bookHist(std::string name)
use if you want, or define the histograms in the specific member functions
Definition: PixTest.cc:93
void dacScan(std::string dac, int ntrig, int dacmin, int dacmax, std::vector< shist256 * > maps, int ihit, int flag=0)
scan a dac range. Will call preScan to protect against r/o problems.
Definition: PixTest.cc:1312
void clearSelectedPixels()
clear selected pixel list
Definition: PixTest.cc:498
void fillDacHist(std::vector< std::pair< uint8_t, std::vector< pxar::pixel > > > &results, TH1D *h, int icol=-1, int irow=-1, int iroc=-1)
fill the results of a api::getEfficiencyVsDAC into a TH1D; if icol/irow/iroc are > -1, then fill only 'correct' pixels
Definition: PixTest.cc:1156
std::vector< int > getMaximumVthrComp(int ntrig, double frac=0.8, int reserve=10)
maximum allowable VthrComp
Definition: PixTest.cc:952
void restoreDacs(bool verbose=false)
restore all DACs
Definition: PixTest.cc:771
void testDone()
signal to PixTab that the test is done (and to update the canvas)
Definition: PixTest.cc:563
void bookTree()
book a minimal tree with pixel events
Definition: PixTest.cc:99
void scurveAna(std::string dac, std::string name, std::vector< shist256 * > maps, std::vector< TH1 * > &resultMaps, int result)
do the scurve analysis
Definition: PixTest.cc:1369
void resetDirectory()
???
Definition: PixTest.cc:136
void addSelectedPixels(std::string sval)
add a selected pixel to the internal parameter list
Definition: PixTest.cc:480
virtual void doAnalysis()
to be filled per test
Definition: PixTest.cc:613
bool getParameter(std::string parName, int &)
return by reference the INT value of a parameter
Definition: PixTest.cc:450
virtual TH1 * moduleMap(std::string histname)
combine all available ROC maps into a module map
Definition: PixTest.cc:786
TH1D * distribution(TH2D *, int nbins, double xmin, double xmax)
creates a 1D distribution of a map
Definition: PixTest.cc:748
bool setTestParameter(std::string parname, std::string value)
change the local parameter
Definition: PixTest.cc:514
TH1 * previousHist()
allow backward iteration through list of histograms
Definition: PixTest.cc:634
void finalCleanup()
functions for DAQ
Definition: PixTest.cc:1765
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
Definition: PixTest.cc:895
virtual std::string getHistOption(TH1 *)
get the hist display options (if stored in fHistOptions)
Definition: PixTest.cc:941
void cacheDacs(bool verbose=false)
cache all DACs
Definition: PixTest.cc:760
std::string getDacsString(std::string dacName)
return from all ROCs the DAC dacName as a string
Definition: PixTest.cc:1614
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
Definition: PixTest.cc:649
static void idx2rcr(int idx, int &iroc, int &icol, int &irow)
and back again
Definition: PixUtil.cc:59
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.
Definition: PixTest.cc:1667
std::vector< uint8_t > getDacs(std::string dacName)
return from all ROCs the DAC dacName
Definition: PixTest.cc:1604
void print(std::string, pxar::TLogLevel log=pxar::logINFO)
produce eye-catching printouts
Definition: PixTest.cc:1191
bool selectedRoc(int id)
is ROC ID selected?
Definition: PixTest.cc:879
double getMinimumThreshold(std::vector< TH1 * >)
return minimum threshold in a set of maps
Definition: PixTest.cc:1084
void saveDacs()
save DACs to file
Definition: PixTest.cc:1511
virtual void setToolTips()
implement this to provide updated tool tips if the user changes test parameters
Definition: PixTest.cc:85
void clearHistList()
delete histogams from HistList
Definition: PixTest.cc:674
void saveTbParameters()
save TB parameters to file
Definition: PixTest.cc:1522
size_t getCurrentRSS()
Definition: rsstools.cc:59
void saveTrimBits()
save trim bits to file
Definition: PixTest.cc:1516
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
Definition: PixTest.cc:903
uint16_t setTriggerFrequency(int triggerFreq, uint8_t TrgTkDel)
set trigger frequence [kHz] and trigger token delay
Definition: PixTest.cc:1807
void update()
signal to PixTab to update the canvas
Definition: PixTest.cc:569
virtual bool setParameter(std::string parName, std::string sval)
set the string value of a parameter
Definition: PixTest.cc:433
int pixelThreshold(std::string dac, int ntrig, int dacmin, int dacmax)
work-around to cope with suboptimal pxar/core
Definition: PixTest.cc:142
void powerOn()
turn DTB power on
Definition: PixTest.cc:589
PixTest(PixSetup *a, std::string name)
constructor requires PixSet to get test parameters and config parameters
void setId2Idx(std::map< int, int > a)
set the mapping between ROC ID and index
Definition: PixTest.cc:889
TProfile2D * bookTProfile2D(std::string sname, std::string title, int nbinsx, double xmin, double xmax, int nbinsy, double ymin, double max, std::string option="")
book a TProfile2D, adding version information to the name and title
Definition: PixTest.cc:911
bool threshold(TH1 *)
fit an s-curve to a distribution. Fills fThreshold, fThresholdE, fSigma, fSigmaE
Definition: PixTest.cc:699
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)
Definition: PixTest.cc:177
void init()
sets all test parameters
Definition: PixTest.cc:62
void maskPixels()
mask all pixels mentioned in the mask file
Definition: PixTest.cc:1741
std::vector< TH2D * > phMaps(std::string name, uint16_t ntrig=10, uint16_t FLAGS=FLAG_FORCE_MASKED)
returns TH2D's with pulseheight maps
Definition: PixTest.cc:239
double getMaximumThreshold(std::vector< TH1 * >)
return maximum threshold in a set of maps
Definition: PixTest.cc:1101
int getIdFromIdx(int idx)
provide the mapping between ROC ID and index
Definition: PixTest.cc:1114
std::vector< TH1 * > thrMaps(std::string dac, std::string name, uint8_t dacmin, uint8_t dachi, int ntrig, uint16_t flag=0)
returns TH2D's for the threshold, the user flag argument is intended for selecting calS and will be O...