pxar
 All Classes Namespaces Functions Variables Typedefs Friends
PixTestBarePretest.cc
1 #include <iostream>
2 #include <stdlib.h>
3 #include <algorithm>
4 
5 #include <TStopwatch.h>
6 #include <TMarker.h>
7 #include <TStyle.h>
8 
9 #include "PixTestBarePretest.hh"
10 #include "log.h"
11 #include "helper.h"
12 
13 using namespace std;
14 using namespace pxar;
15 
16 ClassImp(PixTestBarePretest)
17 
18 // ----------------------------------------------------------------------
19 PixTestBarePretest::PixTestBarePretest( PixSetup *a, std::string name) : PixTest(a, name), fTargetIa(-1), fNoiseWidth(22), fNoiseMargin(10), fParNtrig(-1), fProblem(false) {
20  PixTest::init();
21  init();
22 }
23 
24 // ----------------------------------------------------------------------
25 PixTestBarePretest::PixTestBarePretest() : PixTest() {
26  // LOG(logINFO) << "PixTestBarePretest ctor()";
27 }
28 
29 
30 // ----------------------------------------------------------------------
31 bool PixTestBarePretest::setParameter(string parName, string sval) {
32  bool found(false);
33  string str1, str2;
34  string::size_type s1;
35  int pixc, pixr;
36  std::transform(parName.begin(), parName.end(), parName.begin(), ::tolower);
37  for (unsigned int i = 0; i < fParameters.size(); ++i) {
38  if (fParameters[i].first == parName) {
39  found = true;
40  sval.erase(remove(sval.begin(), sval.end(), ' '), sval.end());
41 
42  if (!parName.compare("targetia")) {
43  fTargetIa = atoi(sval.c_str()); // [mA/ROC]
44  LOG(logDEBUG) << "setting fTargetIa = " << fTargetIa << " mA/ROC";
45  }
46 
47  if (!parName.compare("noisewidth")) {
48  fNoiseWidth = atoi(sval.c_str());
49  LOG(logDEBUG) << "setting fNoiseWidth = " << fNoiseWidth << " DAC units";
50  }
51 
52  if (!parName.compare("noisemargin")) {
53  fNoiseMargin = atoi(sval.c_str()); // safety margin below noise
54  LOG(logDEBUG) << "setting fNoiseMargin = " << fNoiseMargin << " DAC units";
55  }
56 
57  if (!parName.compare("ntrig") ) {
58  fParNtrig = atoi(sval.c_str() );
59  LOG(logDEBUG) << "setting fParNtrig = " << fParNtrig;
60  }
61 
62  if (!parName.compare("vcal") ) {
63  fParVcal = atoi(sval.c_str() );
64  LOG(logDEBUG) << "setting fParVcal = " << fParVcal;
65  }
66 
67  if (!parName.compare("deltavthrcomp") ) {
68  fParDeltaVthrComp = atoi(sval.c_str() );
69  LOG(logDEBUG) << "setting fParDeltaVthrComp = " << fParDeltaVthrComp;
70  }
71 
72  if (!parName.compare("pix") || !parName.compare("pix1") ) {
73  s1 = sval.find(",");
74  if (string::npos != s1) {
75  str1 = sval.substr(0, s1);
76  pixc = atoi(str1.c_str());
77  str2 = sval.substr(s1+1);
78  pixr = atoi(str2.c_str());
79  fPIX.push_back( make_pair(pixc, pixr) );
80  }
81  }
82  // FIXME: remove/update from fPIX if the user removes via the GUI!
83  break;
84  }
85  }
86  return found;
87 }
88 
89 // ----------------------------------------------------------------------
90 void PixTestBarePretest::init() {
91  setToolTips();
92  fDirectory = gFile->GetDirectory(fName.c_str());
93  if( !fDirectory ) {
94  fDirectory = gFile->mkdir(fName.c_str());
95  }
96  fDirectory->cd();
97 }
98 
99 
100 // ----------------------------------------------------------------------
102  fTestTip = string( "Pretest: set Vana, VthrComp, and CalDel")
103  + string("\ntune PH into ADC range using VOffsetRO and VIref_ADC")
104  ;
105  fSummaryTip = string("summary plot to be implemented");
106 }
107 
108 // ----------------------------------------------------------------------
109 void PixTestBarePretest::bookHist(string name) {
110  fDirectory->cd();
111 
112  LOG(logDEBUG) << "nothing done with " << name;
113 }
114 
115 // ----------------------------------------------------------------------
116 PixTestBarePretest::~PixTestBarePretest() {
117  LOG(logDEBUG) << "PixTestBarePretest dtor";
118 }
119 
120 // ----------------------------------------------------------------------
122 
123  fDirectory->cd();
124  PixTest::update();
125  bigBanner(Form("PixTestBarePretest::doTest()"));
126 
127  programROC();
128  TH1 *h1 = (*fDisplayedHist);
129  h1->Draw(getHistOption(h1).c_str());
130  PixTest::update();
131 
132  if (fProblem) {
133  bigBanner("ERROR: some ROCs are not programmable; stop");
134  return;
135  }
136 
137  setVana();
138  h1 = (*fDisplayedHist);
139  h1->Draw(getHistOption(h1).c_str());
140  PixTest::update();
141 
142  setVthrCompCalDel();
143  h1 = (*fDisplayedHist);
144  h1->Draw(getHistOption(h1).c_str());
145  PixTest::update();
146 
147  // -- save DACs!
148  saveDacs();
149  LOG(logINFO) << "PixTestBarePretest::doTest() done";
150 }
151 
152 // ----------------------------------------------------------------------
153 void PixTestBarePretest::runCommand(std::string command) {
154  std::transform(command.begin(), command.end(), command.begin(), ::tolower);
155  LOG(logDEBUG) << "running command: " << command;
156  if (!command.compare("programroc")) {
157  programROC();
158  return;
159  }
160  if (!command.compare("setcaldel")) {
161  setCalDel();
162  return;
163  }
164  if (!command.compare("savedacs")) {
165  saveDacs();
166  return;
167  }
168  if (!command.compare("setvana")) {
169  setVana();
170  return;
171  }
172  if (!command.compare("setvthrcompcaldel")) {
173  setVthrCompCalDel();
174  return;
175  }
176  if (!command.compare("setvthrcompid")) {
177  setVthrCompId();
178  return;
179  }
180 
181  LOG(logDEBUG) << "did not find command ->" << command << "<-";
182 }
183 
184 
185 // ----------------------------------------------------------------------
186 void PixTestBarePretest::setVana() {
187  cacheDacs();
188  fDirectory->cd();
189  PixTest::update();
190  banner(Form("PixTestBarePretest::setVana() target Ia = %d mA/ROC", fTargetIa));
191 
192  fApi->_dut->testAllPixels(false);
193 
194  vector<uint8_t> vanaStart;
195  vector<double> rocIana;
196 
197  // -- cache setting and switch off all(!) ROCs
198  int nRocs = fApi->_dut->getNRocs();
199  for (int iroc = 0; iroc < nRocs; ++iroc) {
200  vanaStart.push_back(fApi->_dut->getDAC(iroc, "vana"));
201  rocIana.push_back(0.);
202  fApi->setDAC("vana", 0, iroc);
203  }
204 
205  double i016 = fApi->getTBia()*1E3;
206 
207  // FIXME this should not be a stopwatch, but a delay
208  TStopwatch sw;
209  sw.Start(kTRUE); // reset
210  do {
211  sw.Start(kFALSE); // continue
212  i016 = fApi->getTBia()*1E3;
213  } while (sw.RealTime() < 0.1);
214 
215  // subtract one ROC to get the offset from the other Rocs (on average):
216  double i015 = (nRocs-1) * i016 / nRocs; // = 0 for single chip tests
217  LOG(logDEBUG) << "offset current from other " << nRocs-1 << " ROCs is " << i015 << " mA";
218 
219  // tune per ROC:
220 
221  const double extra = 0.1; // [mA] besser zu viel als zu wenig
222  const double eps = 0.25; // [mA] convergence
223  const double slope = 6; // 255 DACs / 40 mA
224 
225  for (int roc = 0; roc < nRocs; ++roc) {
226  if (!selectedRoc(roc)) {
227  LOG(logDEBUG) << "skipping ROC idx = " << roc << " (not selected) for Vana tuning";
228  continue;
229  }
230  int vana = vanaStart[roc];
231  fApi->setDAC("vana", vana, roc); // start value
232 
233  double ia = fApi->getTBia()*1E3; // [mA], just to be sure to flush usb
234  sw.Start(kTRUE); // reset
235  do {
236  sw.Start(kFALSE); // continue
237  ia = fApi->getTBia()*1E3; // [mA]
238  } while (sw.RealTime() < 0.1);
239 
240  double diff = fTargetIa + extra - (ia - i015);
241 
242  int iter = 0;
243  LOG(logDEBUG) << "ROC " << roc << " iter " << iter
244  << " Vana " << vana
245  << " Ia " << ia-i015 << " mA";
246 
247  while (TMath::Abs(diff) > eps && iter < 11 && vana > 0 && vana < 255) {
248 
249  int stp = static_cast<int>(TMath::Abs(slope*diff));
250  if (stp == 0) stp = 1;
251  if (diff < 0) stp = -stp;
252 
253  vana += stp;
254 
255  if (vana < 0) {
256  vana = 0;
257  } else {
258  if (vana > 255) {
259  vana = 255;
260  }
261  }
262 
263  fApi->setDAC("vana", vana, roc);
264  iter++;
265 
266  sw.Start(kTRUE); // reset
267  do {
268  sw.Start(kFALSE); // continue
269  ia = fApi->getTBia()*1E3; // [mA]
270  }
271  while( sw.RealTime() < 0.1 );
272 
273  diff = fTargetIa + extra - (ia - i015);
274 
275  LOG(logDEBUG) << "ROC " << setw(2) << roc
276  << " iter " << setw(2) << iter
277  << " Vana " << setw(3) << vana
278  << " Ia " << ia-i015 << " mA";
279  } // iter
280 
281  rocIana[roc] = ia-i015; // more or less identical for all ROCS?!
282  vanaStart[roc] = vana; // remember best
283  fApi->setDAC( "vana", 0, roc ); // switch off for next ROC
284 
285  } // rocs
286 
287  TH1D *hsum = bookTH1D("VanaSettings", "Vana per ROC", nRocs, 0., nRocs);
288  setTitles(hsum, "ROC", "Vana [DAC]");
289  hsum->SetStats(0);
290  hsum->SetMinimum(0);
291  hsum->SetMaximum(256);
292  fHistList.push_back(hsum);
293 
294  TH1D *hcurr = bookTH1D("Iana", "Iana per ROC", nRocs, 0., nRocs);
295  setTitles(hcurr, "ROC", "Vana [DAC]");
296  hcurr->SetStats(0); // no stats
297  hcurr->SetMinimum(0);
298  hcurr->SetMaximum(30.0);
299  fHistList.push_back(hcurr);
300 
301 
302  restoreDacs();
303  for (int roc = 0; roc < nRocs; ++roc) {
304  // -- reset all ROCs to optimum or cached value
305  fApi->setDAC( "vana", vanaStart[roc], roc );
306  LOG(logDEBUG) << "ROC " << setw(2) << roc << " Vana " << setw(3) << int(vanaStart[roc]);
307  // -- histogramming only for those ROCs that were selected
308  if (!selectedRoc(roc)) continue;
309  hsum->Fill(roc, vanaStart[roc] );
310  hcurr->Fill(roc, rocIana[roc]);
311  }
312 
313  double ia16 = fApi->getTBia()*1E3; // [mA]
314 
315  sw.Start(kTRUE); // reset
316  do {
317  sw.Start(kFALSE); // continue
318  ia16 = fApi->getTBia()*1E3; // [mA]
319  }
320  while( sw.RealTime() < 0.1 );
321 
322 
323  hsum->Draw();
324  fDisplayedHist = find(fHistList.begin(), fHistList.end(), hsum);
325  PixTest::update();
326 
327  LOG(logINFO) << "PixTestBarePretest::setVana() done, Module Ia " << ia16 << " mA = " << ia16/nRocs << " mA/ROC";
328 
329 }
330 
331 
332 // ----------------------------------------------------------------------
333 void PixTestBarePretest::setVthrCompCalDel() {
334  uint16_t FLAGS = FLAG_FORCE_SERIAL | FLAG_FORCE_MASKED | FLAG_CALS; // required for manual loop over ROCs
335 
336  cacheDacs();
337  fDirectory->cd();
338  PixTest::update();
339  banner(Form("PixTestBarePretest::setVthrCompCalDel()"));
340 
341  string name("pretestVthrCompCalDel");
342  // commented out A.V
343  //fApi->setDAC("CtrlReg", 0);
344  //fApi->setDAC("Vcal", 250);
345  fApi->setDAC("CtrlReg", 4);
346  fApi->setDAC("Vcal", 222);
347 
348  fApi->_dut->testAllPixels(false);
349  fApi->_dut->maskAllPixels(true);
350 
351  std::cout << "at the beginning the trigger: " << fParNtrig << std::endl;
352 
353  vector<uint8_t> rocIds = fApi->_dut->getEnabledRocIDs();
354  vector<pair<uint8_t, pair<uint8_t, vector<pixel> > > > rresults;
355 
356  TH1D *h1(0);
357  h1 = bookTH1D(Form("pretestCalDel"), Form("pretestCalDel"), rocIds.size(), 0., rocIds.size());
358  h1->SetMinimum(0.);
359  h1->SetDirectory(fDirectory);
360  setTitles(h1, "ROC", "CalDel DAC");
361 
362  TH2D *h2(0);
363 
364  TH1D *h_optimize(0);
365 
366  vector<int> calDel(rocIds.size(), -1);
367  vector<int> vthrComp(rocIds.size(), -1);
368  vector<int> calDelE(rocIds.size(), -1);
369 
370  for (unsigned int iroc = 0; iroc < rocIds.size(); ++iroc){
371 
372  int ip = 0;
373 
374  fApi->_dut->testPixel(fPIX[ip].first, fPIX[ip].second, true, rocIds[iroc]);
375  fApi->_dut->maskPixel(fPIX[ip].first, fPIX[ip].second, false, rocIds[iroc]);
376 
377  h2 = bookTH2D(Form("%s_c%d_r%d_C%d", name.c_str(), fPIX[ip].first, fPIX[ip].second, rocIds[iroc]),
378  Form("%s_c%d_r%d_C%d", name.c_str(), fPIX[ip].first, fPIX[ip].second, rocIds[iroc]),
379  255, 0., 255., 255, 0., 255.);
380  fHistOptions.insert(make_pair(h2, "colz"));
381  h2->SetMinimum(0.);
382  h2->SetDirectory(fDirectory);
383 
384  h_optimize = bookTH1D(Form("VthrComp-Optimized"), Form("VthrComp-Optimized"),255, 0., 255);
385 
386  setTitles(h2, "CalDel", "VthrComp");
387 
388  bool done = false;
389  while (!done) {
390  rresults.clear();
391 
392  LOG(logDEBUG) << " looking at roc = " << static_cast<unsigned int>(rocIds[iroc])
393  << " pixel col = " << fPIX[ip].first << ", row = " << fPIX[ip].second
394  << " getNEnabledRocs() = " << fApi->_dut->getNEnabledRocs()
395  << " getNEnabledPixels() = " << fApi->_dut->getNEnabledPixels(rocIds[iroc]);
396  int cnt(0);
397  try{
398  //rresults = fApi->getEfficiencyVsDACDAC("caldel", 0, 255, "vthrcomp", 0, 150, FLAGS, fParNtrig);
399  rresults = fApi->getEfficiencyVsDACDAC("caldel", 0, 255, "vthrcomp", 0, 255, FLAGS, fParNtrig);
400  done = true;
401  } catch(DataMissingEvent &e){
402  LOG(logCRITICAL) << "problem with readout: "<< e.what() << " missing " << e.numberMissing << " events";
403  ++cnt;
404  if (e.numberMissing > 10) done = true;
405  } catch(pxarException &e) {
406  LOG(logCRITICAL) << "pXar execption: "<< e.what();
407  ++cnt;
408  }
409  done = (cnt>5) || done;
410  }
411 
412  fApi->_dut->testPixel(fPIX[ip].first, fPIX[ip].second, false, rocIds[iroc]);
413  fApi->_dut->maskPixel(fPIX[ip].first, fPIX[ip].second, true, rocIds[iroc]);
414 
415  for (unsigned i = 0; i < rresults.size(); ++i) {
416  pair<uint8_t, pair<uint8_t, vector<pixel> > > v = rresults[i];
417  int idac1 = v.first;
418  pair<uint8_t, vector<pixel> > w = v.second;
419  int idac2 = w.first;
420  vector<pixel> wpix = w.second;
421  for (unsigned ipix = 0; ipix < wpix.size(); ++ipix) {
422  if (wpix[ipix].roc() == rocIds[iroc]) {
423  if (wpix[ipix].value() >= fParNtrig/2){
424  h2->Fill(idac1, idac2, wpix[ipix].value());
425  }
426  } else {
427  LOG(logDEBUG) << "ghost ROC " << static_cast<unsigned int>(wpix[ipix].roc()) << " seen with pixel "
428  << static_cast<unsigned int>(wpix[ipix].column()) << " " << static_cast<unsigned int>(wpix[ipix].row());
429  }
430  }
431  }
432 
433  TH1D *h0 = h2->ProjectionX("_px", fParDeltaVthrComp+1, fParDeltaVthrComp+2);
434  h0->Draw();
435  PixTest::update();
436 
437  pxar::mDelay(1000);
438 
439  // commenting out
440  //calDelE[iroc] = static_cast<int>(h0->GetRMS());
441  //calDel[iroc] = static_cast<int>(h0->GetMean()+0.25*calDelE[iroc]);
442  delete h0;
443 
444  TH1D *hy = h2->ProjectionY("_py", 5, h2->GetNbinsX());
445  int top = hy->FindLastBinAbove(1.);
446  hy->Draw();
447  PixTest::update();
448  pxar::mDelay(1000);
449 
450  int itop(top);
451  for (itop = top; itop > 0; --itop) {
452  h0 = h2->ProjectionX("_px", itop, itop);
453  int cnt(0);
454  for (int i = 0; i < h0->GetNbinsX(); ++i) {
455  if (fParNtrig == h0->GetBinContent(i)) cnt++;
456  }
457  if (cnt > 40) break;
458  }
459 
460  // modification for vthrcomp:
461  // now find best value for caldel
462  // find efficiency plateau of dac2 at dac1Mean:
463 
464  int nm = 0;
465  int i0 = 0;
466  int i9 = 0;
467 
468  //double dac1Mean = h2->GetMean( 1 );
469  int dac1Mean = int ( h2->GetMean( 1 ) );
470  int i1 = h2->GetXaxis()->FindBin( dac1Mean);
471 
472  cout << "Mean ist at Bin: " << i1 << endl;
473 
474  // int n
475 
476  for( int j = 0; j < 255; ++j ) {
477 
478  int cnt = h2->GetBinContent( i1, j+1 ); // ROOT bins start at 1
479 
480  // Fill histogram
481  h_optimize->Fill(j, cnt);
482 
483  //cout << "j " << j << " cnt " << cnt << endl;
484  if( cnt > nm ) {
485  nm = cnt;
486  i0 = j; // begin of plateau
487  }
488  if( cnt >= nm ) {
489  i9 = j; // end of plateau
490  }
491 
492  }
493 
494  std::cout << "Number of bins x- "
495  << h2->GetXaxis()->GetNbins()
496  << " mean: "
497  << h2->GetMean(1)
498  << " at bin: " << i1 << endl;
499  std::cout << "Number of bins y- "
500  << h2->GetYaxis()->GetNbins()
501  << "mean: "
502  << h2->GetMean(2) << endl;
503 
504  cout << " plateau from " << i0 << " to " << i9 << endl;
505 
506  int dac2Best = i0 + ( i9 - i0 ) / 4;
507 
508  // use the result of our test
509 
510  calDelE[iroc] = static_cast<int>(0.);
511  calDel[iroc] = static_cast<int>(h2->GetMean( 1 ));
512 
513  vthrComp[iroc] = dac2Best;
514  //vthrComp[iroc] = (fParDeltaVthrComp>0?fParDeltaVthrComp:itop+fParDeltaVthrComp);
515 
516  h1->SetBinContent(rocIds[iroc]+1, calDel[iroc]);
517  h1->SetBinError(rocIds[iroc]+1, calDelE[iroc]);
518  LOG(logDEBUG) << "CalDel: " << calDel[iroc] << " +/- " << calDelE[iroc];
519 
520  h2->Draw(getHistOption(h2).c_str());
521  TMarker *tm = new TMarker();
522  tm->SetMarkerSize(1);
523  tm->SetMarkerStyle(21);
524  tm->DrawMarker(calDel[iroc], vthrComp[iroc]);
525  PixTest::update();
526 
527  fHistList.push_back(h2);
528  }
529 
530  fHistList.push_back(h1);
531  fHistList.push_back(h_optimize);
532 
533  fDisplayedHist = find(fHistList.begin(), fHistList.end(), h2);
534  PixTest::update();
535 
536  restoreDacs();
537  string caldelString(""), vthrcompString("");
538  /*
539  for (unsigned int iroc = 0; iroc < rocIds.size(); ++iroc){
540  fApi->setDAC("CalDel", calDel[iroc], rocIds[iroc]);
541  caldelString += Form(" %4d", calDel[iroc]);
542  fApi->setDAC("VthrComp", vthrComp[iroc], rocIds[iroc]);
543  vthrcompString += Form(" %4d", vthrComp[iroc]);
544  }
545  */
546  for (unsigned int iroc = 0; iroc < rocIds.size(); ++iroc){
547  fApi->setDAC("CalDel", calDel[iroc], rocIds[iroc]);
548  caldelString += Form(" %4d", calDel[iroc]);
549  fApi->setDAC("VthrComp", vthrComp[iroc], rocIds[iroc]);
550  vthrcompString += Form(" %4d", vthrComp[iroc]);
551  }
552 
553 
554  // -- summary printout
555  LOG(logINFO) << "PixTestBarePretest::setVthrCompCalDel() done";
556  LOG(logINFO) << "CalDel: " << caldelString;
557  LOG(logINFO) << "VthrComp: " << vthrcompString;
558 
559  // setting back the Flag to small pulses
560 
561  FLAGS = FLAG_FORCE_SERIAL | FLAG_FORCE_MASKED;
562 
563 
564 }
565 
566 
567 // ----------------------------------------------------------------------
568 void PixTestBarePretest::setVthrCompId() {
569 
570  cacheDacs();
571  fDirectory->cd();
572  PixTest::update();
573  banner(Form("PixTestBarePretest::setVthrCompId()"));
574 
575  vector<TH1D*> hsts;
576  TH1D *h1(0);
577 
578  int nRocs = fApi->_dut->getNRocs();
579 
580  for (int roc = 0; roc < nRocs; ++roc) {
581  if (!selectedRoc(roc)) continue;
582  h1 = bookTH1D(Form("Id_vs_VthrComp_C%d", int(roc)),
583  Form("Id vs VthrComp C%d", int(roc)),
584  256, 0., 256.);
585  h1->SetMinimum(0);
586  h1->SetStats(0);
587  setTitles( h1, "VthrComp [DAC]", "ROC digital current [mA]" );
588  hsts.push_back(h1);
589  fHistList.push_back(h1);
590  }
591 
592  fApi->_dut->testAllPixels(true); // enable all pix: more noise
593 
594  for (int roc = 0; roc < nRocs; ++roc) {
595  fApi->setDAC("Vsf", 33, roc); // small
596  fApi->setDAC("VthrComp", 0, roc); // off
597  }
598 
599  double i016 = fApi->getTBid()*1E3;
600  TStopwatch sw;
601  sw.Start(kTRUE); // reset
602  do {
603  sw.Start(kFALSE); // continue
604  i016 = fApi->getTBid()*1E3;
605  }
606  while( sw.RealTime() < 0.1 ); // discharge time
607 
608  double i015 = (nRocs-1) * i016 / nRocs; // = 0 for single chip tests
609 
610  LOG(logINFO) << "offset current from other " << nRocs-1 << " ROCs is "
611  << i015 << " mA";
612 
613  TH1D *hid(0);
614 
615  // loope over ROCs:
616 
617  vector<int> rocVthrComp(nRocs, -1);
618  for (int roc = 0; roc < nRocs; ++roc) {
619  if (!selectedRoc(roc)) continue;
620 
621  LOG(logDEBUG) << "ROC " << setw(2) << roc;
622 
623  hid = hsts[roc];
624 
625  for (size_t idac = 0; idac < 256; ++idac) {
626  fApi->setDAC("VthrComp", idac, roc);
627  // delay?
628  hid->Fill(idac, fApi->getTBid()*1E3 - i015);
629  }
630 
631  fApi->setDAC("VthrComp", 0, roc); // switch off
632 
633  if (hid) hid->Draw();
634  PixTest::update();
635 
636  // analyze:
637 
638  LOG(logDEBUG) << "current peak " << hid->GetMaximum()
639  << " mA at DAC " << hid->GetMaximumBin();
640 
641  double maxd = 0;
642  int maxi = 0;
643  for (int i = 1; i <= 256-fNoiseWidth; ++i) { // histo bin counting starts at 1
644  double ni = hid->GetBinContent(i);
645  double d = hid->GetBinContent(i+fNoiseWidth) - ni;
646  if (d > maxd) {
647  maxd = d;
648  maxi = i-1;
649  }
650  }
651  LOG(logDEBUG) << "[SetComp] max d" << fNoiseWidth
652  << maxd << " at " << maxi;
653 
654  int32_t val = maxi - fNoiseMargin; // safety
655  if (val < 0) val = 0;
656  rocVthrComp[roc] = val;
657  LOG(logDEBUG) << "set VthrComp to " << val;
658 
659  } // rocs
660 
661  TH1D *hsum = bookTH1D("VthrCompSettings", "VthrComp per ROC", nRocs, 0., nRocs);
662  setTitles(hsum, "ROC", "VthrComp [DAC]");
663  hsum->SetStats(0); // no stats
664  hsum->SetMinimum(0);
665  hsum->SetMaximum(256);
666  fHistList.push_back(hsum);
667 
668 
669  restoreDacs();
670  for (int roc = 0; roc < nRocs; ++roc) {
671  // -- (re)set all
672  fApi->setDAC("VthrComp", rocVthrComp[roc], roc);
673  // -- report on/histogram only selected ROCs
674  LOG(logINFO) << "ROC " << setw(2) << roc
675  << " VthrComp " << setw(3) << rocVthrComp[roc];
676  hsum->Fill(roc, rocVthrComp[roc]);
677  }
678 
679  hsum->Draw();
680  fDisplayedHist = find(fHistList.begin(), fHistList.end(), hsum);
681  PixTest::update();
682 
683  LOG(logINFO) << "PixTestBarePretest::setVthrCompId() done";
684 
685 }
686 
687 
688 // ----------------------------------------------------------------------
689 void PixTestBarePretest::setCalDel() {
690  uint16_t FLAGS = FLAG_FORCE_SERIAL | FLAG_FORCE_MASKED; // required for manual loop over ROCs
691 
692  cacheDacs();
693  fDirectory->cd();
694  PixTest::update();
695  banner(Form("PixTestBarePretest::setCalDel()"));
696 
697  fApi->_dut->testAllPixels(false);
698  fApi->_dut->maskAllPixels(true);
699 
700  if (fPIX[0].first > -1) {
701  fApi->_dut->testPixel(fPIX[0].first, fPIX[0].second, true);
702  fApi->_dut->maskPixel(fPIX[0].first, fPIX[0].second, false);
703  } else {
704  LOG(logWARNING) << "PreTest: no pixel defined, return";
705  return;
706  }
707 
708  // set maximum pulse (minimal time walk):
709 
710  fApi->setDAC("Vcal", 250);
711  fApi->setDAC("CtrlReg", 4);
712 
713  string DacName = "caldel";
714 
715  // measure:
716  bool done = false;
717  vector<pair<uint8_t, vector<pixel> > > results;
718  int cnt(0);
719  while (!done) {
720  try{
721  results = fApi->getEfficiencyVsDAC(DacName, 0, 250, FLAGS, fParNtrig);
722  done = true;
723  } catch(DataMissingEvent &e){
724  LOG(logCRITICAL) << "problem with readout: "<< e.what() << " missing " << e.numberMissing << " events";
725  ++cnt;
726  if (e.numberMissing > 10) done = true;
727  } catch(pxarException &e) {
728  LOG(logCRITICAL) << "pXar execption: "<< e.what();
729  ++cnt;
730  }
731  done = (cnt>5) || done;
732  }
733 
734  // histos:
735  vector<TH1D*> hsts;
736  TH1D *h1(0);
737  int nRocs = fApi->_dut->getNEnabledRocs();
738  for (int iroc = 0; iroc < nRocs; ++iroc) {
739  if (!selectedRoc(iroc)) continue;
740  h1 = bookTH1D(Form("NhitsVs%s_c%d_r%d_C%d", DacName.c_str(), fPIX[0].first, fPIX[0].second, fId2Idx[iroc]),
741  Form("NhitsVs%s_c%d_r%d_C%d", DacName.c_str(), fPIX[0].first, fPIX[0].second, fId2Idx[iroc]),
742  256, 0., 256.);
743  h1->SetMinimum(0);
744  setTitles(h1, Form( "%s [DAC]", DacName.c_str() ), "readouts");
745  fHistList.push_back(h1);
746  hsts.push_back(h1);
747  }
748 
749  TH1D *hsum = bookTH1D( "CalDelSettings", "CalDel per ROC;ROC;CalDel [DAC]", 16, 0., 16.);
750  hsum->SetStats(0); // no stats
751  hsum->SetMinimum(0);
752  hsum->SetMaximum(256);
753  fHistList.push_back(hsum);
754 
755  // FIXME this is so bad
756  int i0[35] = {0};
757  int i9[35] = {0};
758  int nm[35] = {0};
759 
760  for (size_t i = 0; i < results.size(); ++i) {
761  int caldel = results[i].first;
762  vector<pixel> vpix = results[i].second;
763 
764  for (size_t ipx = 0; ipx < vpix.size(); ++ipx) {
765  uint32_t roc = vpix.at(ipx).roc();
766 
767  if (fId2Idx[roc] < nRocs
768  && vpix[ipx].column() == fPIX[0].first
769  && vpix[ipx].row() == fPIX[0].second
770  ) {
771 
772  int nn = vpix.at(ipx).value();
773 
774  if (nn > nm[fId2Idx[roc]]) {
775  nm[fId2Idx[roc]] = nn;
776  i0[fId2Idx[roc]] = caldel; // begin of plateau
777  }
778  if (nn == nm[fId2Idx[roc]] )
779  i9[fId2Idx[roc]] = caldel; // end of plateau
780 
781  h1 = hsts.at(fId2Idx[roc]);
782  h1->Fill(caldel, nn);
783 
784  } // valid
785 
786  } // pixels and rocs
787 
788  } // caldel vals
789 
790  for (int roc = 0; roc < nRocs; ++roc) {
791  hsts[fId2Idx[roc]]->Draw();
792  PixTest::update();
793  }
794 
795  // set CalDel:
796  restoreDacs();
797  for (int roc = 0; roc < nRocs; ++roc) {
798  if (i9[fId2Idx[roc]] > 0 ) {
799 
800  int i2 = i0[fId2Idx[roc]] + (i9[fId2Idx[roc]]-i0[fId2Idx[roc]])/4;
801  fApi->setDAC(DacName, i2, getIdFromIdx(roc));
802 
803  LOG(logINFO) << "ROC " << setw(2) << getIdFromIdx(roc)
804  << ": eff plateau from " << setw(3) << i0[fId2Idx[roc]]
805  << " to " << setw(3) << i9[fId2Idx[roc]]
806  << ": set CalDel to " << i2;
807 
808  hsum->Fill(roc, i2);
809  }
810  } // rocs
811 
812  hsum->Draw();
813  PixTest::update();
814  fDisplayedHist = find(fHistList.begin(), fHistList.end(), hsum);
815 }
816 
817 // ----------------------------------------------------------------------
818 void PixTestBarePretest::programROC() {
819  cacheDacs();
820  fDirectory->cd();
821  PixTest::update();
822  banner(Form("PixTestBarePretest::programROC() "));
823 
824  vector<uint8_t> rocIds = fApi->_dut->getEnabledRocIDs();
825  unsigned int nRocs = rocIds.size();
826  TH1D *h1 = bookTH1D("programROC", "#Delta(Iana) vs ROC", nRocs, 0., nRocs);
827  fHistList.push_back(h1);
828 
829  vector<int> vanaStart;
830  for (unsigned int iroc = 0; iroc < nRocs; ++iroc) {
831  vanaStart.push_back(fApi->_dut->getDAC(rocIds[iroc], "vana"));
832  fApi->setDAC("vana", 0, rocIds[iroc]);
833  }
834 
835  pxar::mDelay(2000);
836  double iA0 = fApi->getTBia()*1E3;
837  // cout << "iA0 = " << iA0 << endl;
838 
839  double iA, dA;
840  string result("ROCs");
841  bool problem(false);
842  for (unsigned int iroc = 0; iroc < rocIds.size(); ++iroc){
843  fApi->setDAC("vana", vanaStart[iroc], rocIds[iroc]);
844  pxar::mDelay(1000);
845  iA = fApi->getTBia()*1E3;
846  dA = iA - iA0;
847  if (dA < 5) {
848  result += Form(" %d", rocIds[iroc]);
849  problem = true;
850  }
851  h1->SetBinContent(iroc+1, dA);
852  fApi->setDAC("vana", 0, rocIds[iroc]);
853  }
854 
855  if (problem) {
856  result += " cannot be programmed! Error!";
857  fProblem = true;
858  } else {
859  result += " are all programmable";
860  }
861 
862  // -- summary printout
863  string dIaString("");
864  for (unsigned int i = 0; i < nRocs; ++i) {
865  dIaString += Form(" %3.1f", h1->GetBinContent(i+1));
866  }
867 
868  LOG(logINFO) << "PixTestBarePretest::programROC() done: " << result;
869  LOG(logINFO) << "IA differences per ROC: " << dIaString;
870 
871  h1 = (TH1D*)(fHistList.back());
872  h1->Draw(getHistOption(h1).c_str());
873  fDisplayedHist = find(fHistList.begin(), fHistList.end(), h1);
874  PixTest::update();
875 
876  restoreDacs();
877 }
size_t getNEnabledPixels(uint8_t rocid)
Definition: dut.cc:44
void setToolTips()
implement this to provide updated tool tips if the user changes test parameters
std::map< TH1 *, std::string > fHistOptions
options can be stored with each histogram
Definition: PixTest.hh:308
bool setDAC(std::string dacName, uint8_t dacValue, uint8_t rocI2C)
Definition: api.cc:546
double getTBid()
Definition: api.cc:434
std::vector< std::pair< int, int > > fPIX
range of enabled pixels for time-consuming tests
Definition: PixTest.hh:311
void testPixel(uint8_t column, uint8_t row, bool enable)
Definition: dut.cc:432
std::vector< std::pair< std::string, std::string > > fParameters
the parameters of this test
Definition: PixTest.hh:302
void doTest()
function connected to "DoTest" button of PixTab
void maskAllPixels(bool mask, uint8_t rocid)
Definition: dut.cc:481
void runCommand(std::string)
allow execution of any button in the test
TDirectory * fDirectory
where the root histograms will end up
Definition: PixTest.hh:306
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)
Definition: api.cc:733
void restoreDacs(bool verbose=false)
restore all DACs
Definition: PixTest.cc:771
dut * _dut
Definition: api.h:728
std::vector< uint8_t > getEnabledRocIDs()
Definition: dut.cc:214
void testAllPixels(bool enable)
Definition: dut.cc:503
std::list< TH1 * >::iterator fDisplayedHist
pointer to the histogram currently displayed
Definition: PixTest.hh:309
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::list< TH1 * > fHistList
list of histograms available in PixTab::next and PixTab::previous
Definition: PixTest.hh:307
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
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)
Definition: api.cc:951
bool selectedRoc(int id)
is ROC ID selected?
Definition: PixTest.cc:879
size_t getNEnabledRocs()
Definition: dut.cc:74
void saveDacs()
save DACs to file
Definition: PixTest.cc:1511
virtual bool setParameter(std::string parName, std::string sval)
set the string value of a parameter
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
double getTBia()
Definition: api.cc:424
void maskPixel(uint8_t column, uint8_t row, bool mask)
Definition: dut.cc:397
void update()
signal to PixTab to update the canvas
Definition: PixTest.cc:569
uint8_t getDAC(size_t rocId, std::string dacName)
Definition: dut.cc:314
size_t getNRocs()
Definition: dut.cc:84
pxar::pxarCore * fApi
pointer to the API
Definition: PixTest.hh:289
std::map< int, int > fId2Idx
map the ROC ID onto the (results vector) index of the ROC
Definition: PixTest.hh:312
void init()
sets all test parameters
Definition: PixTest.cc:62
int getIdFromIdx(int idx)
provide the mapping between ROC ID and index
Definition: PixTest.cc:1114
void mDelay(uint32_t ms)
Definition: helper.h:40