pxar
 All Classes Namespaces Functions Variables Typedefs Friends
PixTestReadback.cc
1 #include <stdlib.h> /* atof, atoi */
2 #include <algorithm> // std::find
3 #include <iostream>
4 #include <TStopwatch.h>
5 #include <TStyle.h>
6 #include "PixTestReadback.hh"
7 #include "log.h"
8 #include "helper.h"
9 #include "timer.h"
10 #include <fstream>
11 #include "PixUtil.hh"
12 
13 using namespace std;
14 using namespace pxar;
15 
16 ClassImp(PixTestReadback)
17 
18 // ----------------------------------------------------------------------
19 PixTestReadback::PixTestReadback(PixSetup *a, std::string name) : PixTest(a, name), fParStretch(0), fParTriggerFrequency(100), fParResetROC(0), fCalwVd(true), fCalwVa(false) {
20  PixTest::init();
21  init();
22  LOG(logDEBUG) << "PixTestReadback ctor(PixSetup &a, string, TGTab *)";
23  fTree = 0;
24 
25  vector<vector<pair<string, double> > > iniCal;
26  vector<pair<string, double> > prova1;
27  fRbCal = fPixSetup->getConfigParameters()->getReadbackCal();
28 
29  //initialize all calibration factors to 1
30  vector<uint8_t> rocIds = fApi->_dut->getEnabledRocIDs();
31  for(unsigned int iroc=0; iroc < rocIds.size(); iroc++){
32  fPar0VdCal.push_back(1.);
33  fPar1VdCal.push_back(1.);
34  fPar0VaCal.push_back(1.);
35  fPar1VaCal.push_back(1.);
36  fPar0RbIaCal.push_back(1.);
37  fPar1RbIaCal.push_back(1.);
38  fPar0TbIaCal.push_back(1.);
39  fPar1TbIaCal.push_back(1.);
40  fPar2TbIaCal.push_back(1.);
41  fRbVbg.push_back(0.);
42  }
43 
44  for(unsigned int iroc=0; iroc < rocIds.size(); iroc++){
45  for(std::vector<std::pair<std::string, double> >::iterator ical = fRbCal[iroc].begin(); ical != fRbCal[iroc].end(); ical++){
46  if(!(ical->first.compare("par0vd"))){
47  fPar0VdCal[iroc] = ical->second;
48  }
49  else if(!(ical->first.compare("par1vd"))){
50  fPar1VdCal[iroc] = ical->second;
51  }
52  else if(!(ical->first.compare("par0va"))){
53  fPar0VaCal[iroc] = ical->second;
54  }
55  else if(!(ical->first.compare("par1va"))){
56  fPar1VaCal[iroc] = ical->second;
57  }
58  else if(!(ical->first.compare("par0rbia"))){
59  fPar0RbIaCal[iroc] = ical->second;
60  }
61  else if(!(ical->first.compare("par1rbia"))){
62  fPar1RbIaCal[iroc] = ical->second;
63  }
64  else if(!(ical->first.compare("par0tbia"))){
65  fPar0TbIaCal[iroc] = ical->second;
66  }
67  else if(!(ical->first.compare("par1tbia"))){
68  fPar1TbIaCal[iroc] = ical->second;
69  }
70  else if(!(ical->first.compare("par2tbia"))){
71  fPar2TbIaCal[iroc] = ical->second;
72  }
73  }
74  }
75 
76  fPhCal.setPHParameters(fPixSetup->getConfigParameters()->getGainPedestalParameters());
77  fPhCalOK = fPhCal.initialized();
78 }
79 
80 
81 //----------------------------------------------------------
82 PixTestReadback::PixTestReadback() : PixTest() {
83  LOG(logDEBUG) << "PixTestReadback ctor()";
84  fTree = 0;
85 }
86 
87 //----------------------------------------------------------
88 PixTestReadback::~PixTestReadback() {
89  LOG(logDEBUG) << "PixTestReadback dtor, saving tree ... ";
90  fDirectory->cd();
91  if (fTree && fParFillTree) fTree->Write();
92 }
93 
94 // ----------------------------------------------------------------------
95 void PixTestReadback::init() {
96  LOG(logDEBUG) << "PixTestReadback::init()";
97 
98  setToolTips();
99  fDirectory = gFile->GetDirectory(fName.c_str());
100  if (!fDirectory) {
101  fDirectory = gFile->mkdir(fName.c_str());
102  }
103  fDirectory->cd();
104 }
105 
106 // ----------------------------------------------------------------------
108  fTestTip = string("Run DAQ - data from each run will be added to the same histogram.") ;
109  fSummaryTip = string("to be implemented") ;
110  fStopTip = string("Stop DAQ and save data.");
111 }
112 
113 // ----------------------------------------------------------------------
114 void PixTestReadback::bookHist(string name) {
115  fDirectory->cd();
116  LOG(logDEBUG) << "nothing done with " << name;
117 }
118 
119 // ----------------------------------------------------------------------
120 void PixTestReadback::stop(){
121  // Interrupt the test
122  fDaq_loop = false;
123  LOG(logINFO) << "Stop pressed. Ending test.";
124 }
125 
126 // ----------------------------------------------------------------------
127 void PixTestReadback::runCommand(std::string command) {
128  std::transform(command.begin(), command.end(), command.begin(), ::tolower);
129  LOG(logDEBUG) << "running command: " << command;
130  if(!command.compare("stop")){
131  stop();
132  return;
133  }
134  if(!command.compare("calibratevd")){
135  CalibrateVd();
136  return;
137  }
138  if(!command.compare("calibrateva")){
139  CalibrateVa();
140  return;
141  }
142  if(!command.compare("calibrateia")){
143  CalibrateIa();
144  return;
145  }
146  if(!command.compare("readbackvbg")){
147  readbackVbg();
148  getCalibratedVbg();
149  return;
150  }
151  if(!command.compare("getcalibratedvbg")){
152  getCalibratedVbg();
153  return;
154  }
155  if(!command.compare("getcalibratedia")){
156  getCalibratedIa();
157  return;
158  }
159  if(!command.compare("setvana")){
160  setVana();
161  return;
162  }
163  else{
164  LOG(logINFO) << "Command " << command << " not implemented.";
165  }
166 }
167 
168 // ----------------------------------------------------------------------
169 bool PixTestReadback::setParameter(string parName, string sval) {
170  bool found(false);
171  fParOutOfRange = false;
172  std::transform(parName.begin(), parName.end(), parName.begin(), ::tolower);
173  for (unsigned int i = 0; i < fParameters.size(); ++i) {
174  if (fParameters[i].first == parName) {
175  found = true;
176  if (!parName.compare("readback")) {
177  fParReadback = atoi(sval.c_str());
178  setToolTips();
179  }
180  if (!parName.compare("usecalvd")) {
181  PixUtil::replaceAll(sval, "checkbox(", "");
182  PixUtil::replaceAll(sval, ")", "");
183  fCalwVd = atoi(sval.c_str());
184  LOG(logDEBUG)<<"fCalwVd set to "<<fCalwVd;
185  setToolTips();
186  }
187  if (!parName.compare("usecalva")) {
188  PixUtil::replaceAll(sval, "checkbox(", "");
189  PixUtil::replaceAll(sval, ")", "");
190  fCalwVa = atoi(sval.c_str());
191  setToolTips();
192  }
193  if (!parName.compare("clockstretch")) {
194  fParStretch = atoi(sval.c_str());
195  setToolTips();
196  }
197  if (!parName.compare("filltree")) {
198  fParFillTree = !(atoi(sval.c_str()) == 0);
199  setToolTips();
200  }
201  if (!parName.compare("trgfrequency(khz)")){ // trigger frequency in kHz.
202  fParTriggerFrequency = atoi(sval.c_str());
203  if (fParTriggerFrequency == 0) {
204  LOG(logWARNING) << "PixTestReadback::setParameter() trgfrequency must be different from zero";
205  found = false; fParOutOfRange = true;
206  }
207  }
208  }
209  }
210  return found;
211 }
212 
213 //----------------------------------------------------------
214 bool PixTestReadback::setTrgFrequency(uint8_t TrgTkDel){
215  int nDel = 0;
216  uint8_t trgtkdel= TrgTkDel;
217  double period_ns = 1 / (double)fParTriggerFrequency * 1000000; // trigger frequency in kHz.
218  fParPeriod = (uint16_t)period_ns / 25;
219  uint16_t ClkDelays = fParPeriod - trgtkdel;
220 
221  //add right delay between triggers:
222  if (fParResetROC) { //by default not reset (already done before daqstart)
223  fPg_setup.push_back(make_pair("resetroc", 15));
224  ClkDelays -= 15;
225  nDel++;
226  }
227  while (ClkDelays>255){
228  fPg_setup.push_back(make_pair("delay", 255));
229  ClkDelays = ClkDelays - 255;
230  nDel ++;
231  }
232  fPg_setup.push_back(make_pair("delay", ClkDelays));
233 
234  //then send trigger and token:
235  fPg_setup.push_back(make_pair("trg", trgtkdel));
236  fPg_setup.push_back(make_pair("tok", 0));
237 
238  fParPeriod = fParPeriod + 4 + nDel; //to align to the new pg minimum (1 additional clk cycle per PG call);
239 
240  return true;
241 }
242 
243 // ----------------------------------------------------------------------
244 void PixTestReadback::pgToDefault() {
245  fPg_setup.clear();
246  LOG(logDEBUG) << "PixTestPattern::PG_Setup clean";
247 
248  fPg_setup = fPixSetup->getConfigParameters()->getTbPgSettings();
249  fApi->setPatternGenerator(fPg_setup);
250  LOG(logINFO) << "PixTestPattern:: pg_setup set to default.";
251 }
252 
253 // ----------------------------------------------------------------------
254 void PixTestReadback::setHistos(){
255  if (fParFillTree) bookTree();
256  fHits.clear(); fPhmap.clear(); fPh.clear(); fQmap.clear(); fQ.clear();
257 
258  std::vector<uint8_t> rocIds = fApi->_dut->getEnabledRocIDs();
259  TH1D *h1(0);
260  TH2D *h2(0);
261  TProfile2D *p2(0);
262  for (unsigned int iroc = 0; iroc < rocIds.size(); ++iroc){
263  h2 = bookTH2D(Form("hits_C%d", rocIds[iroc]), Form("hits_C%d", rocIds[iroc]), 52, 0., 52., 80, 0., 80.);
264  h2->SetMinimum(0.);
265  h2->SetDirectory(fDirectory);
266  setTitles(h2, "col", "row");
267  fHistOptions.insert(make_pair(h2, "colz"));
268  fHits.push_back(h2);
269 
270  p2 = bookTProfile2D(Form("phMap_C%d", rocIds[iroc]), Form("phMap_C%d", rocIds[iroc]), 52, 0., 52., 80, 0., 80.);
271  p2->SetMinimum(0.);
272  p2->SetDirectory(fDirectory);
273  setTitles(p2, "col", "row");
274  fHistOptions.insert(make_pair(p2, "colz"));
275  fPhmap.push_back(p2);
276 
277  h1 = bookTH1D(Form("ph_C%d", rocIds[iroc]), Form("ph_C%d", rocIds[iroc]), 256, 0., 256.);
278  h1->SetMinimum(0.);
279  h1->SetDirectory(fDirectory);
280  setTitles(h1, "ADC", "Entries/bin");
281  fPh.push_back(h1);
282 
283  p2 = bookTProfile2D(Form("qMap_C%d", rocIds[iroc]), Form("qMap_C%d", rocIds[iroc]), 52, 0., 52., 80, 0., 80.);
284  p2->SetMinimum(0.);
285  p2->SetDirectory(fDirectory);
286  setTitles(p2, "col", "row");
287  fHistOptions.insert(make_pair(p2, "colz"));
288  fQmap.push_back(p2);
289 
290  h1 = bookTH1D(Form("q_C%d", rocIds[iroc]), Form("q_C%d", rocIds[iroc]), 200, 0., 1000.);
291  h1->SetMinimum(0.);
292  h1->SetDirectory(fDirectory);
293  setTitles(h1, "Q [Vcal]", "Entries/bin");
294  fQ.push_back(h1);
295  }
296 }
297 
298 
299 // ----------------------------------------------------------------------
300 void PixTestReadback::ProcessData(uint16_t numevents){
301 
302  LOG(logDEBUG) << "Getting Event Buffer";
303  std::vector<pxar::Event> daqdat;
304 
305  if (numevents > 0) {
306  for (unsigned int i = 0; i < numevents; i++) {
307  pxar::Event evt = fApi->daqGetEvent();
308  //Check if event is empty?
309  if (evt.pixels.size() > 0)
310  daqdat.push_back(evt);
311  }
312  }
313  else
314  daqdat = fApi->daqGetEventBuffer();
315 
316  LOG(logDEBUG) << "Processing Data: " << daqdat.size() << " events.";
317 
318  int pixCnt(0);
319  int idx(-1);
320  uint16_t q;
321  vector<uint8_t> rocIds = fApi->_dut->getEnabledRocIDs();
322  for (std::vector<pxar::Event>::iterator it = daqdat.begin(); it != daqdat.end(); ++it) {
323  pixCnt += it->pixels.size();
324 
325  if (fParFillTree) {
326  fTreeEvent.header = it->header;
327  fTreeEvent.dac = 0;
328  fTreeEvent.trailer = it->trailer;
329  fTreeEvent.npix = it->pixels.size();
330  }
331 
332  for (unsigned int ipix = 0; ipix < it->pixels.size(); ++ipix) {
333  idx = getIdxFromId(it->pixels[ipix].roc());
334  if(idx == -1) {
335  LOG(logWARNING) << "PixTestReadback::ProcessData() wrong 'idx' value --> return";
336  return;
337  }
338  fHits[idx]->Fill(it->pixels[ipix].column(), it->pixels[ipix].row());
339  fPhmap[idx]->Fill(it->pixels[ipix].column(), it->pixels[ipix].row(), it->pixels[ipix].value());
340  fPh[idx]->Fill(it->pixels[ipix].value());
341 
342  if (fPhCalOK) {
343  q = static_cast<uint16_t>(fPhCal.vcal(it->pixels[ipix].roc(), it->pixels[ipix].column(),
344  it->pixels[ipix].row(), it->pixels[ipix].value()));
345  }
346  else {
347  q = 0;
348  }
349  fQ[idx]->Fill(q);
350  fQmap[idx]->Fill(it->pixels[ipix].column(), it->pixels[ipix].row(), q);
351  if (fParFillTree) {
352  fTreeEvent.proc[ipix] = it->pixels[ipix].roc();
353  fTreeEvent.pcol[ipix] = it->pixels[ipix].column();
354  fTreeEvent.prow[ipix] = it->pixels[ipix].row();
355  fTreeEvent.pval[ipix] = it->pixels[ipix].value();
356  fTreeEvent.pq[ipix] = q;
357  }
358  }
359  if (fParFillTree) fTree->Fill();
360  }
361 
362  //to draw the hitsmap as 'online' check.
363  TH2D* h2 = (TH2D*)(fHits.back());
364  h2->Draw(getHistOption(h2).c_str());
365  fDisplayedHist = find(fHistList.begin(), fHistList.end(), h2);
366  PixTest::update();
367 
368  LOG(logINFO) << Form("events read: %6ld, pixels seen: %3d, hist entries: %4d",
369  daqdat.size(), pixCnt, static_cast<int>(fHits[0]->GetEntries()));
370 }
371 
372 // ----------------------------------------------------------------------
373 void PixTestReadback::FinalCleaning() {
374 
375  // Reset the pg_setup to default value.
376  pgToDefault();
377  //clean local variables:
378  fPg_setup.clear();
379 }
380 
381 // ----------------------------------------------------------------------
383  LOG(logINFO) << "PixTestReadback::doTest() start.";
384 
385  CalibrateVd();
386  CalibrateVa();
387  readbackVbg();
388  vector<double> VBG = getCalibratedVbg();
389  CalibrateIa();
390  for (list<TH1*>::iterator il = fHistList.begin(); il != fHistList.end(); ++il) {
391  (*il)->Draw((getHistOption(*il)).c_str());
392  }
393 
394  LOG(logINFO) << "PixTestReadback::doTest() done";
395 
396 }
397 
398 
399 void PixTestReadback::CalibrateIa(){
400  cacheDacs();
401  //readback DAC set to 12 (i.e. Ia)
402  fParReadback=12;
403 
404  vector<uint8_t> readback;
405 
406  string name, title;
407  TH1D* hrb(0);
408  vector<TH1D*> hs_rbIa, hs_tbIa;
409  double tbIa = 0.;
410  map<uint8_t, vector<uint8_t > > rbIa;
411  while(readback.size()<1){
412  readback=daqReadback("vana", (uint8_t)80, fParReadback);
413  }
414  for(unsigned int iroc=0; iroc < readback.size(); iroc++){
415  name = Form("rbIa_C%d", iroc);
416  title=name;
417  hrb = bookTH1D(name, title, 256, 0., 256);
418  hs_rbIa.push_back(hrb);
419  name = Form("tbIa_C%d", iroc);
420  title=name;
421  hrb = bookTH1D(name, title, 256, 0., 256);
422  hs_tbIa.push_back(hrb);
423  }
424 
425  uint8_t vana=0;
426  //measuring average current offset from other ROCs
427  // vector<uint8_t> readback_offset;
428  double ioff16=0.;
429  fApi->setDAC("vana", 0);
430  ioff16 = fApi->getTBia()*1E3;
431  double avIoff=0;
432  avIoff = ioff16*(readback.size()-1)/(readback.size());
433 
434  for(unsigned int iroc=0; iroc < readback.size(); iroc++){
435  fApi->setDAC("vana", 0);
436  for(int ivana=0; ivana<52; ivana++){
437  vana = (uint8_t)ivana*5;
438  do{readback=daqReadback("vana", vana, iroc, fParReadback);
439  } while(readback.size()<1);
440  rbIa.insert(make_pair(vana, readback));
441  fApi->setDAC("vana", vana, iroc);
442  tbIa = fApi->getTBia()*1E3;
443  hs_rbIa[iroc]->Fill(vana, readback[iroc]);//should this be corrected as well?
444  hs_tbIa[iroc]->Fill(vana, tbIa-avIoff);//tbIa corrected for offset
445  }
446  }
447 
448  for(unsigned int iroc=0; iroc < readback.size(); iroc++){
449  hs_rbIa[iroc]->GetXaxis()->SetTitle("Vana [DAC]");
450  hs_rbIa[iroc]->GetYaxis()->SetTitle("Ia_rb [ADC]");
451  hs_tbIa[iroc]->GetXaxis()->SetTitle("Vana [DAC]");
452  hs_tbIa[iroc]->GetYaxis()->SetTitle("Ia_TB [mA]");
453  }
454  gStyle->SetOptFit(1111);
455 
456  vector<double> rb_vanaMax(readback.size(), 0.);
457  vector<double> tb_vanaMax(readback.size(), 0.);
458 
459  //protection to exclude plateu from fit
460  for(unsigned int iroc=0; iroc < readback.size(); iroc++){
461  rb_vanaMax[iroc] = hs_rbIa[iroc]->GetBinCenter(hs_rbIa[iroc]->FindFirstBinAbove(254));
462 
463  LOG(logDEBUG)<<"Vana max for fit:"<<endl<<"rb: "<<rb_vanaMax[iroc]<<endl<<"tb :"<<tb_vanaMax[iroc];
464  }
465 
466 
467  TF1* frb;
468  TF1* ftb;
469  vector<TF1*> v_frb, v_ftb;
470  for(unsigned int iroc=0; iroc < readback.size(); iroc++){
471  name = Form("lin_rb_C%d", iroc);
472  frb = new TF1(name.c_str(), "[0] + x*[1]", 0, rb_vanaMax[iroc]);
473  v_frb.push_back(frb);
474  name = Form("pol2_ftb_C%d", iroc);
475  ftb = new TF1(name.c_str(), "[0] + x*[1] + x*x*[2] ", 0, 255);
476  v_ftb.push_back(ftb);
477  }
478 
479  for(unsigned int iroc=0; iroc < readback.size(); iroc++){
480  hs_rbIa[iroc]->Fit(v_frb[iroc], "W", "", 0., rb_vanaMax[iroc]);
481  hs_tbIa[iroc]->Fit(v_ftb[iroc]);
482 
483  // LOG(logDEBUG)<<"Number of points for rb fit "<<frb->GetNumberFitPoints();
484 
485  fPar0RbIaCal[iroc]=v_frb[iroc]->GetParameter(0);
486  fPar1RbIaCal[iroc]=v_frb[iroc]->GetParameter(1);
487  fPar0TbIaCal[iroc]=v_ftb[iroc]->GetParameter(0);
488  fPar1TbIaCal[iroc]=v_ftb[iroc]->GetParameter(1);
489  fPar2TbIaCal[iroc]=v_ftb[iroc]->GetParameter(2);
490  }
491 
492 
493  for(unsigned int iroc=0; iroc < readback.size(); iroc++){
494  for(std::vector<std::pair<std::string, double> >::iterator ical = fRbCal[iroc].begin(); ical != fRbCal[iroc].end(); ical++){
495  if(!(ical->first.compare("par0rbia"))){
496  ical->second = fPar0RbIaCal[iroc];
497  }
498  else if(!(ical->first.compare("par1rbia"))){
499  ical->second = fPar1RbIaCal[iroc];
500  }
501  else if(!(ical->first.compare("par0tbia"))){
502  ical->second = fPar0TbIaCal[iroc];
503  }
504  else if(!(ical->first.compare("par1tbia"))){
505  ical->second = fPar1TbIaCal[iroc];
506  }
507  else if(!(ical->first.compare("par2tbia"))){
508  ical->second = fPar2TbIaCal[iroc];
509  }
510  }
511  }
512 
513  for(unsigned int iroc=0; iroc < readback.size(); iroc++){
514  for(std::vector<std::pair<std::string, double> >::iterator ical = fRbCal[iroc].begin(); ical != fRbCal[iroc].end(); ical++){
515  LOG(logDEBUG)<<"debug: "<<ical->first<<" "<<ical->second;
516  }
517  }
518 
519  TH1D* h_rbIaCal (0);
520  vector<TH1D*> hs_rbIaCal;
521  for(unsigned int iroc=0; iroc < readback.size(); iroc++){
522  name = Form("rbIaCal_C%d", iroc);
523  title = name;
524  h_rbIaCal = bookTH1D(name,title, 256, 0., 256.);
525  hs_rbIaCal.push_back(h_rbIaCal);
526  }
527 
528  for(int ivana=0; ivana<52; ivana++){
529  vana = (uint8_t)ivana*5;
530  for(unsigned int iroc=0; iroc < rbIa[vana].size(); iroc++){
531  LOG(logDEBUG)<<"step ivana = "<<ivana;
532  // h_rbIaCal->Fill(vana, ((tbpar1/rbpar1)*(rbIa[vana]-rbpar0)+tbpar0));
533  hs_rbIaCal[iroc]->Fill(vana, (rbIa[vana][iroc]*rbIa[vana][iroc]*fPar2TbIaCal[iroc]/fPar1RbIaCal[iroc]/fPar1RbIaCal[iroc] + rbIa[vana][iroc]/fPar1RbIaCal[iroc]/fPar1RbIaCal[iroc]*(fPar1RbIaCal[iroc]*fPar1TbIaCal[iroc]-2*fPar0RbIaCal[iroc]*fPar2TbIaCal[iroc]) + (fPar0RbIaCal[iroc]*fPar0RbIaCal[iroc]*fPar2TbIaCal[iroc] - fPar0RbIaCal[iroc]*fPar1TbIaCal[iroc])/fPar1RbIaCal[iroc] + fPar0TbIaCal[iroc]));
534  }
535  }
536 
537  for(unsigned int iroc=0; iroc < readback.size(); iroc++){
538  hs_rbIaCal[iroc]->GetXaxis()->SetTitle("Vana [DAC]");
539  hs_rbIaCal[iroc]->GetYaxis()->SetTitle("Ia_rb_cal [mA]");
540  hs_rbIaCal[iroc]->SetLineColor(kBlue);
541  fHistList.push_back(hs_rbIa[iroc]);
542  fHistList.push_back(hs_rbIaCal[iroc]);
543  fHistList.push_back(hs_tbIa[iroc]);
544  }
545  for(unsigned int iroc=0; iroc < readback.size(); iroc++){
546  fPixSetup->getConfigParameters()->writeReadbackFile(iroc, fRbCal[iroc]);
547  }
548 
549  restoreDacs();
550 }
551 
552 std::vector<double> PixTestReadback::getCalibratedIa(){
553  //readback DAC set to 12 (i.e. Ia)
554  fParReadback=12;
555 
556  vector<uint8_t> readback;
557 
558  while(readback.size()<1){
559  readback=daqReadbackIa();
560  }
561  vector<double> calIa(readback.size(), 0.);
562  for(unsigned int iroc=0; iroc < readback.size(); iroc++){
563  // calIa = ((fPar1TbIaCal/fPar1RbIaCal)*((double)readback-fPar0RbIaCal)+fPar0TbIaCal);
564  calIa[iroc] = (((double)readback[iroc])*((double)readback[iroc])*fPar2TbIaCal[iroc]/fPar1RbIaCal[iroc]/fPar1RbIaCal[iroc] + ((double)readback[iroc])/fPar1RbIaCal[iroc]/fPar1RbIaCal[iroc]*(fPar1RbIaCal[iroc]*fPar1TbIaCal[iroc]-2*fPar0RbIaCal[iroc]*fPar2TbIaCal[iroc]) + (fPar0RbIaCal[iroc]*fPar0RbIaCal[iroc]*fPar2TbIaCal[iroc] - fPar0RbIaCal[iroc]*fPar1TbIaCal[iroc])/fPar1RbIaCal[iroc] + fPar0TbIaCal[iroc]);
565  LOG(logDEBUG)<<"Calibrated analog current is "<<calIa[iroc];
566  }
567  return calIa;
568 }
569 
570 double PixTestReadback::getCalibratedIa(unsigned int iroc){
571  //readback DAC set to 12 (i.e. Ia)
572  fParReadback=12;
573 
574  vector<uint8_t> readback;
575 
576  while(readback.size()<1){
577  readback=daqReadbackIa();
578  }
579  double calIa;
580  calIa = (((double)readback[iroc])*((double)readback[iroc])*fPar2TbIaCal[iroc]/fPar1RbIaCal[iroc]/fPar1RbIaCal[iroc] + ((double)readback[iroc])/fPar1RbIaCal[iroc]/fPar1RbIaCal[iroc]*(fPar1RbIaCal[iroc]*fPar1TbIaCal[iroc]-2*fPar0RbIaCal[iroc]*fPar2TbIaCal[iroc]) + (fPar0RbIaCal[iroc]*fPar0RbIaCal[iroc]*fPar2TbIaCal[iroc] - fPar0RbIaCal[iroc]*fPar1TbIaCal[iroc])/fPar1RbIaCal[iroc] + fPar0TbIaCal[iroc]);
581  LOG(logDEBUG)<<"Calibrated analog current is "<<calIa;
582 
583  return calIa;
584 }
585 
586 void PixTestReadback::CalibrateVana(){
587 // cacheDacs();
588 // //readback DAC set to 11 (i.e. Vana)
589 // fParReadback=12;
590 //
591 // int readback=0;
592 //
593 // TH1D* h_rbVana = new TH1D("rbVana","rbVana", 256, 0., 256.);
594 // TH1D* h_dacVana = new TH1D("dacVana","dacVana", 256, 0., 256.);
595 // vector<double > rbVana;
596 //
597 // for(uint8_t vana=0; vana<255; vana++){
598 // readback=daqReadback("vana", vana, fParReadback);
599 // rbVana.push_back(readback);
600 // h_rbVana->Fill(vana, readback);
601 // h_dacVana->Fill(vana, vana);
602 // }
603 //
604 // double rb_vanaMax=0.;
605 //
606 // rb_vanaMax = h_rbVana->GetBinCenter(h_rbVana->FindFirstBinAbove(254));
607 //
608 // LOG(logDEBUG)<<"Vana max for fit:"<<endl<<"rb: "<<rb_vanaMax;
609 //
610 // TF1* frb = new TF1("lin_rb", "[0] + x*[1]", 0, rb_vanaMax);
611 // TF1* fdac = new TF1("lin_fdac", "[0] + x*[1]", 0, 255);
612 //
613 // h_rbVana->Fit(frb, "W", "", 0., rb_vanaMax);
614 // h_dacVana->Fit(fdac);
615 //
616 // LOG(logDEBUG)<<"Number of points for rb fit "<<frb->GetNumberFitPoints();
617 //
618 // double rbpar0=0., rbpar1=0., dacpar0=0., dacpar1=0.;
619 // rbpar0=frb->GetParameter(0);
620 // rbpar1=frb->GetParameter(1);
621 // dacpar0=fdac->GetParameter(0);
622 // dacpar1=fdac->GetParameter(1);
623 //
624 // TH1D* h_rbVanaCal = new TH1D("rbVana","rbVana", 256, 0., 256.);
625 // for(int vana=0; vana<256; vana++){
626 // h_rbVanaCal->Fill(vana, ((dacpar1/rbpar1)*(rbVana[vana]-rbpar0)+dacpar0));
627 // }
628 //
629 // h_rbVanaCal->SetLineColor(kBlue);
630 // fHistOptions.insert(make_pair(h_rbVanaCal,"same"));
631 //
632 // fHistList.push_back(h_rbVana);
633 // fHistList.push_back(h_rbVanaCal);
634 // fHistList.push_back(h_dacVana);
635 // restoreDacs();
636 }
637 
638 void PixTestReadback::CalibrateVd(){
639  cacheDacs();
640 
641  //readback DAC set to 8 (i.e. Vd)
642  fParReadback=8;
643 
644  vector<uint8_t> readback;
645 
646  string name, title;
647  TH1D* hrb(0);
648  vector<TH1D*> hs_rbVd, hs_dacVd;
649  vector<double > rbVd;
650  double Vd;
651 
652  //dry run to avoid spikes
653  while(readback.size()<1){
654  readback=daqReadback("vd", 2.1, fParReadback);
655  }
656  //book histos
657  for(unsigned int iroc=0; iroc < readback.size(); iroc++){
658  name = Form("rbVd_C%d", iroc);
659  title = name;
660  hrb = bookTH1D(name, title, 500, 0., 5.);
661  hs_rbVd.push_back(hrb);
662  name = Form("dacVd_C%d", iroc);
663  title = name;
664  hrb = bookTH1D(name, title, 500, 0., 5.);
665  hs_dacVd.push_back(hrb);
666  }
667  readback.clear();
668 
669  for(int iVd=0; iVd<18; iVd++){
670  LOG(logDEBUG)<<"/****:::::: CALIBRATE VD :::::****/";
671  Vd = 2.1 + iVd*0.05;
672  LOG(logDEBUG)<<"Digital voltage will be set to: "<<Vd;
673  do{
674  readback=daqReadback("vd", Vd, fParReadback);
675  } while(readback.size()<1);
676  for(unsigned int iroc=0; iroc < readback.size(); iroc++){
677  LOG(logDEBUG)<<"Voltage "<<Vd<<", readback "<<(int)readback[iroc];
678  // rbVd.push_back(readback);
679  hs_rbVd[iroc]->Fill(Vd, readback[iroc]);
680  hs_dacVd[iroc]->Fill(Vd, fApi->getTBvd());
681  }
682  }
683 
684  for(unsigned int iroc=0; iroc < readback.size(); iroc++){
685  hs_rbVd[iroc]->GetXaxis()->SetTitle("Vd [V]");
686  hs_rbVd[iroc]->GetYaxis()->SetTitle("Vd_rb [ADC]");
687  hs_dacVd[iroc]->GetXaxis()->SetTitle("Vd set [V]");
688  hs_dacVd[iroc]->GetYaxis()->SetTitle("Vd TB [V]");
689  }
690 
691  gStyle->SetOptFit(1111);
692 
693  TF1* frb (0);
694  vector<TF1*> v_frb;
695  for(unsigned int iroc=0; iroc < readback.size(); iroc++){
696  name = Form("lin_vd_C%d", iroc);
697  frb = new TF1(name.c_str(), "[0] + x*[1]");
698  v_frb.push_back(frb);
699  }
700 
701  for(unsigned int iroc=0; iroc < readback.size(); iroc++){
702  hs_rbVd[iroc]->Fit(v_frb[iroc], "W", "");
703 
704  fPar0VdCal[iroc]=v_frb[iroc]->GetParameter(0);
705  fPar1VdCal[iroc]=v_frb[iroc]->GetParameter(1);
706 
707  fHistList.push_back(hs_rbVd[iroc]);
708  fHistList.push_back(hs_dacVd[iroc]);
709  }
710 
711 
712  for(unsigned int iroc=0; iroc < readback.size(); iroc++){
713  for(std::vector<std::pair<std::string, double> >::iterator ical = fRbCal[iroc].begin(); ical != fRbCal[iroc].end(); ical++){
714  if(!(ical->first.compare("par0vd"))){
715  ical->second = fPar0VdCal[iroc];
716  }
717  else if(!(ical->first.compare("par1vd"))){
718  ical->second = fPar1VdCal[iroc];
719  }
720  }
721  }
722 
723  for(unsigned int iroc=0; iroc < readback.size(); iroc++){
724  fPixSetup->getConfigParameters()->writeReadbackFile(iroc, fRbCal[iroc]);
725  }
726 
727  restoreDacs();
728 }
729 
730 
731 void PixTestReadback::readbackVbg(){
732  cacheDacs();
733  //readback DAC set to 11 (i.e. Vbg)
734  fParReadback=11;
735 
736  vector<uint8_t> readback;
737 
738  while(readback.size()<1){
739  readback = daqReadback("vd", 2.5, fParReadback);
740  }
741  vector<double> avReadback(readback.size(), 0.);
742 
743  double Vd;
744 
745  int n_meas=0;
746  bool okRb=true;
747 
748  for(int i=0; i<10; i++){
749  LOG(logDEBUG)<<"/****:::::: READBACK VBG :::::****/";
750  Vd = 2.5;
751  LOG(logDEBUG)<<"Digital voltage will be set to: "<<Vd;
752 
753  do{ readback = daqReadback("vd", Vd, fParReadback);
754  } while(readback.size()<1);
755  for(unsigned int iroc=0; iroc < readback.size(); iroc++){
756  if(0==readback[iroc]){
757  okRb=false;
758  break;
759  }
760  }
761  for(unsigned int iroc=0; iroc < readback.size(); iroc++){
762  if (okRb){
763  avReadback[iroc]+=(double)readback[iroc];
764  n_meas++;
765  }
766  LOG(logDEBUG)<<"Voltage "<<Vd<<", average readback "<<(double)readback[iroc]/(i+1);
767  }
768  }
769  for(unsigned int iroc=0; iroc < readback.size(); iroc++){
770  fRbVbg[iroc] = avReadback[iroc]/n_meas;
771  }
772 
773  restoreDacs();
774 }
775 
776 vector<double> PixTestReadback::getCalibratedVbg(){
777  vector<double> calVbg(fRbVbg.size(), 0.);
778  //0.5 needed because Vbg rb has twice the sensitivity Vd and Va have
779  if(fCalwVd){
780  LOG(logINFO)<<"Vbg will be calibrated using Vd calibration";
781  for(unsigned int iroc=0; iroc < calVbg.size(); iroc++){
782  calVbg[iroc]=0.5*(fRbVbg[iroc]-fPar0VdCal[iroc])/fPar1VdCal[iroc];
783  }
784  }
785  else if(fCalwVa){
786  LOG(logINFO)<<"Vbg will be calibrated using Va calibration";
787  for(unsigned int iroc=0; iroc < calVbg.size(); iroc++){
788  calVbg[iroc]=0.5*(fRbVbg[iroc]-fPar0VaCal[iroc])/fPar1VaCal[iroc];
789  }
790  }
791  else{
792  LOG(logDEBUG)<<"No calibration option specified. Please select one and retry.";
793  return calVbg;
794  }
795  for(unsigned int iroc=0; iroc < calVbg.size(); iroc++){
796  LOG(logINFO)<<"/*/*/*/*::: ROC "<<iroc<<": calibrated Vbg = "<<calVbg[iroc]<<" :::*/*/*/*/";
797  }
798  return calVbg;
799 }
800 
801 void PixTestReadback::CalibrateVa(){
802  cacheDacs();
803 
804  //readback DAC set to 9 (i.e. Va)
805  fParReadback=9;
806 
807  vector<uint8_t> readback;
808 
809  string name, title;
810  TH1D* hrb(0);
811  vector<TH1D*> hs_rbVa, hs_dacVa;
812  vector<double > rbVa;
813  double Va;
814 
815  //dry run to avoid spikes
816  while(readback.size()<1){
817  readback=daqReadback("va", 1.5, fParReadback);
818  }
819  //book histos
820  for(unsigned int iroc=0; iroc < readback.size(); iroc++){
821  name = Form("rbVa_C%d", iroc);
822  title = name;
823  hrb = bookTH1D(name, title, 500, 0., 5.);
824  hs_rbVa.push_back(hrb);
825  name = Form("dacVa_C%d", iroc);
826  title = name;
827  hrb = bookTH1D(name, title, 500, 0., 5.);
828  hs_dacVa.push_back(hrb);
829  }
830  readback.clear();
831 
832  for(int iVa=0; iVa<18; iVa++){
833  LOG(logDEBUG)<<"/****:::::: CALIBRATE VA FUNCTION :::::****/";
834  Va = 1.5 + iVa*0.05;
835  LOG(logDEBUG)<<"Analog voltage will be set to: "<<Va;
836  do{readback=daqReadback("va", Va, fParReadback);
837  } while(readback.size()<1);
838  for(unsigned int iroc=0; iroc < readback.size(); iroc++){
839  hs_rbVa[iroc]->Fill(Va, readback[iroc]);
840  hs_dacVa[iroc]->Fill(Va, fApi->getTBva());
841  }
842  }
843 
844  for(unsigned int iroc=0; iroc < readback.size(); iroc++){
845  hs_rbVa[iroc]->GetXaxis()->SetTitle("Va [V]");
846  hs_rbVa[iroc]->GetYaxis()->SetTitle("Va_rb [ADC]");
847  hs_dacVa[iroc]->GetXaxis()->SetTitle("Va set [V]");
848  hs_dacVa[iroc]->GetYaxis()->SetTitle("Va TB [V]");
849  }
850 
851  gStyle->SetOptFit(1111);
852 
853  vector<double> rb_VaMax(readback.size(), 0.);
854  for(unsigned int iroc=0; iroc < readback.size(); iroc++){
855  rb_VaMax[iroc] = hs_rbVa[iroc]->GetBinCenter(hs_rbVa[iroc]->FindFirstBinAbove(254));
856 
857  LOG(logDEBUG)<<"Va max for fit on ROC "<<iroc<<" : "<<rb_VaMax[iroc];
858  }
859 
860  TF1* frb (0);
861  vector<TF1*> v_frb;
862  for(unsigned int iroc=0; iroc < readback.size(); iroc++){
863  name = Form("lin_va_C%d", iroc);
864  frb = new TF1(name.c_str(), "[0] + x*[1]", 0, rb_VaMax[iroc]);
865  v_frb.push_back(frb);
866  }
867 
868  for(unsigned int iroc=0; iroc < readback.size(); iroc++){
869  hs_rbVa[iroc]->Fit(v_frb[iroc], "W", "", 0., rb_VaMax[iroc]);
870 
871  // LOG(logDEBUG)<<"Number of points for rb fit "<<frb->GetNumberFitPoints();
872 
873  fPar0VaCal[iroc]=v_frb[iroc]->GetParameter(0);
874  fPar1VaCal[iroc]=v_frb[iroc]->GetParameter(1);
875 
876  fHistList.push_back(hs_rbVa[iroc]);
877  fHistList.push_back(hs_dacVa[iroc]);
878  }
879 
880  for(unsigned int iroc=0; iroc < readback.size(); iroc++){
881  for(std::vector<std::pair<std::string, double> >::iterator ical = fRbCal[iroc].begin(); ical != fRbCal[iroc].end(); ical++){
882  if(!(ical->first.compare("par0va"))){
883  ical->second = fPar0VaCal[iroc];
884  }
885  else if(!(ical->first.compare("par1va"))){
886  ical->second = fPar1VaCal[iroc];
887  }
888  }
889  }
890 
891  for(unsigned int iroc=0; iroc < readback.size(); iroc++){
892  fPixSetup->getConfigParameters()->writeReadbackFile(iroc, fRbCal[iroc]);
893  }
894 
895  restoreDacs();
896 }
897 
898 vector<uint8_t> PixTestReadback::daqReadback(string dac, double vana, int8_t parReadback){
899 
900  PixTest::update();
901  fDirectory->cd();
902  fPg_setup.clear();
903 
904  if (!dac.compare("vana")){
905  LOG(logDEBUG)<<"Wrong daqReadback function called!!!";
906  }
907  else if (!dac.compare("vd")){
908  vector<pair<string,double > > powerset = fPixSetup->getConfigParameters()->getTbPowerSettings();
909  for(std::vector<std::pair<std::string,double> >::iterator pow_it=powerset.begin(); pow_it!=powerset.end(); pow_it++){
910  if( pow_it->first.compare("vd") == 0){
911  pow_it->second = vana;
912  }
913  }
914  fApi->setTestboardPower(powerset);
915  }
916  else if (!dac.compare("va")){
917  vector<pair<string,double > > powerset = fPixSetup->getConfigParameters()->getTbPowerSettings();
918  for(std::vector<std::pair<std::string,double> >::iterator pow_it=powerset.begin(); pow_it!=powerset.end(); pow_it++){
919  if( pow_it->first.compare("va") == 0){
920  pow_it->second = vana;
921  }
922  }
923  fApi->setTestboardPower(powerset);
924  }
925 
926  fApi->setDAC("readback", parReadback);
927 
928  doDAQ();
929 
930  std::vector<std::vector<uint16_t> > rb;
931  rb = fApi->daqGetReadback();
932  std::vector<uint8_t> rb_val;
933 
934  for(uint8_t i=0; i<rb.size(); i++){
935  rb_val.push_back( rb[i][ rb[i].size()-1 ]&0xff ); // read the last (size-1) readback word read out for ROC i
936  }
937 
938  //::::::::::::::::::::::::::::::
939  //DAQ - THE END.
940 
941  FinalCleaning();
942  fApi->setClockStretch(0, 0, 0); //No Stretch after trigger, 0 delay
943  return rb_val;
944  }
945 
946 
947 std::vector<uint8_t> PixTestReadback::daqReadback(string dac, uint8_t vana, int8_t parReadback){
948 
949  PixTest::update();
950  fDirectory->cd();
951  fPg_setup.clear();
952 
953  if (!dac.compare("vana")){
954  fApi->setDAC(dac.c_str(), vana);
955  }
956  else {
957  LOG(logDEBUG)<<"Wrong daqReadback function called!!!";
958  //fApi->_hal->setTBvd(vana);
959  }
960 
961  fApi->setDAC("readback", parReadback);
962  doDAQ();
963 
964  std::vector<std::vector<uint16_t> > rb;
965  rb = fApi->daqGetReadback();
966  std::vector<uint8_t> rb_val;
967 
968  for(uint8_t i=0; i<rb.size(); i++){
969  rb_val.push_back( rb[i][ rb[i].size()-1 ]&0xff ); // read the last (size-1) readback word read out for ROC i
970  }
971 
972  //::::::::::::::::::::::::::::::
973  //DAQ - THE END.
974 
975  FinalCleaning();
976  fApi->setClockStretch(0, 0, 0); //No Stretch after trigger, 0 delay
977  return rb_val;
978  }
979 
980 std::vector<uint8_t> PixTestReadback::daqReadback(string dac, uint8_t vana, unsigned int roc, int8_t parReadback){
981 
982  PixTest::update();
983  fDirectory->cd();
984  fPg_setup.clear();
985 
986  if (!dac.compare("vana")){
987  fApi->setDAC(dac.c_str(), vana, roc);
988  }
989  else {
990  LOG(logDEBUG)<<"Wrong daqReadback function called!!!";
991  //fApi->_hal->setTBvd(vana);
992  }
993 
994  fApi->setDAC("readback", parReadback);
995  doDAQ();
996 
997  std::vector<std::vector<uint16_t> > rb;
998  rb = fApi->daqGetReadback();
999  std::vector<uint8_t> rb_val;
1000 
1001  for(uint8_t i=0; i<rb.size(); i++){
1002  rb_val.push_back( rb[i][ rb[i].size()-1 ]&0xff ); // read the last (size-1) readback word read out for ROC i
1003  }
1004 
1005  //::::::::::::::::::::::::::::::
1006  //DAQ - THE END.
1007 
1008  FinalCleaning();
1009  fApi->setClockStretch(0, 0, 0); //No Stretch after trigger, 0 delay
1010  return rb_val;
1011  }
1012 
1013 
1014 
1015 std::vector<uint8_t> PixTestReadback::daqReadbackIa(){
1016 
1017  PixTest::update();
1018  fDirectory->cd();
1019  fPg_setup.clear();
1020 
1021  fApi->setDAC("readback", 12);
1022 
1023  //Immediately stop if parameters not in range
1024  // if (fParOutOfRange) return 255;
1025 
1026  //Set the ClockStretch
1027  fApi->setClockStretch(0, 0, fParStretch); //Stretch after trigger, 0 delay
1028 
1029  //Set the histograms:
1030  if(fHistList.size() == 0) setHistos(); //to book histo only for the first 'doTest' (or after Clear).
1031 
1032  //To print on shell the number of masked pixels per ROC:
1033  vector<uint8_t> rocIds = fApi->_dut->getEnabledRocIDs();
1034  LOG(logINFO) << "PixTestReadback::Number of masked pixels:";
1035  for (unsigned int iroc = 0; iroc < rocIds.size(); ++iroc) {
1036  LOG(logINFO) << "PixTestReadback:: ROC " << static_cast<int>(iroc) << ": " << fApi->_dut->getNMaskedPixels(static_cast<int>(iroc));
1037  }
1038 
1039  // Start the DAQ:
1040  //::::::::::::::::::::::::::::::::
1041 
1042  //:::Setting register to read back a given quantity::::://
1043 
1044  //First send only a RES:
1045  fPg_setup.push_back(make_pair("resetroc", 0)); // PG_RESR b001000
1046  uint16_t period = 28;
1047 
1048  //Set the pattern generator:
1049  fApi->setPatternGenerator(fPg_setup);
1050 
1051  fApi->daqStart();
1052 
1053  //Send only one trigger to reset:
1054  fApi->daqTrigger(1, period);
1055  LOG(logINFO) << "PixTestReadback::RES sent once ";
1056 
1057  fApi->daqStop();
1058 
1059  fPg_setup.clear();
1060  LOG(logINFO) << "PixTestReadback::PG_Setup clean";
1061 
1062  //Set the pattern wrt the trigger frequency:
1063  LOG(logINFO) << "PG set to have trigger frequency = " << fParTriggerFrequency << " kHz";
1064  if (!setTrgFrequency(20)){
1065  FinalCleaning();
1066  // return 255;
1067  }
1068 
1069  //Set pattern generator:
1070  fApi->setPatternGenerator(fPg_setup);
1071 
1072  fDaq_loop = true;
1073 
1074  //Start the DAQ:
1075  fApi->daqStart();
1076 
1077  int Ntrig=32;
1078  //Send the triggers:
1079  fApi->daqTrigger(Ntrig, fParPeriod);
1080  gSystem->ProcessEvents();
1081  ProcessData(0);
1082 
1083  fApi->daqStop();
1084 
1085  std::vector<std::vector<uint16_t> > rb;
1086  rb = fApi->daqGetReadback();
1087  std::vector<uint8_t> rb_val;
1088 
1089  for(uint8_t i=0; i<rb.size(); i++){
1090  rb_val.push_back( rb[i][ rb[i].size()-1 ]&0xff ); // read the last (size-1) readback word read out for ROC i
1091  }
1092 
1093 
1094  //::::::::::::::::::::::::::::::
1095  //DAQ - THE END.
1096 
1097  FinalCleaning();
1098  fApi->setClockStretch(0, 0, 0); //No Stretch after trigger, 0 delay
1099  return rb_val;
1100  }
1101 
1102 void PixTestReadback::setVana() {
1103  cacheDacs();
1104  fDirectory->cd();
1105  PixTest::update();
1106 
1107  int fTargetIa=24;
1108 
1109  banner(Form("PixTestPretest::setVana() target Ia = %d mA/ROC", fTargetIa));
1110 
1111  fApi->_dut->testAllPixels(false);
1112 
1113  vector<uint8_t> vanaStart;
1114  vector<double> rocIana;
1115 
1116  // -- cache setting and switch off all(!) ROCs
1117  int nRocs = fApi->_dut->getNRocs();
1118  for (int iroc = 0; iroc < nRocs; ++iroc) {
1119  vanaStart.push_back(fApi->_dut->getDAC(iroc, "vana"));
1120  rocIana.push_back(0.);
1121  fApi->setDAC("vana", 0, iroc);
1122  }
1123 
1124 // double i016 = getCalibratedIa();
1125 //
1126 // // FIXME this should not be a stopwatch, but a delay
1127  TStopwatch sw;
1128  sw.Start(kTRUE); // reset
1129 // do {
1130 // sw.Start(kFALSE); // continue
1131 // i016 = getCalibratedIa();
1132 // } while (sw.RealTime() < 0.1);
1133 //
1134 // // subtract one ROC to get the offset from the other Rocs (on average):
1135 // double i015 = (nRocs-1) * i016 / nRocs; // = 0 for single chip tests
1136 // LOG(logDEBUG) << "offset current from other " << nRocs-1 << " ROCs is " << i015 << " mA";
1137 
1138  double i015=0.;
1139 
1140  // tune per ROC:
1141 
1142  const double extra = 0.1; // [mA] besser zu viel als zu wenig
1143  const double eps = 0.25; // [mA] convergence
1144  const double slope = 6; // 255 DACs / 40 mA
1145 
1146  for (int roc = 0; roc < nRocs; ++roc) {
1147  if (!selectedRoc(roc)) {
1148  LOG(logDEBUG) << "skipping ROC idx = " << roc << " (not selected) for Vana tuning";
1149  continue;
1150  }
1151  int vana = vanaStart[roc];
1152  fApi->setDAC("vana", vana, roc); // start value
1153 
1154  double ia = getCalibratedIa(roc); // [mA], just to be sure to flush usb
1155  sw.Start(kTRUE); // reset
1156  do {
1157  sw.Start(kFALSE); // continue
1158  ia = getCalibratedIa(roc); // [mA]
1159  } while (sw.RealTime() < 0.1);
1160 
1161  double diff = fTargetIa + extra - (ia - i015);
1162 
1163  int iter = 0;
1164  LOG(logDEBUG) << "ROC " << roc << " iter " << iter
1165  << " Vana " << vana
1166  << " Ia " << ia-i015 << " mA";
1167 
1168  while (TMath::Abs(diff) > eps && iter < 11 && vana > 0 && vana < 255) {
1169 
1170  int stp = static_cast<int>(TMath::Abs(slope*diff));
1171  if (stp == 0) stp = 1;
1172  if (diff < 0) stp = -stp;
1173 
1174  vana += stp;
1175 
1176  if (vana < 0) {
1177  vana = 0;
1178  } else {
1179  if (vana > 255) {
1180  vana = 255;
1181  }
1182  }
1183 
1184  fApi->setDAC("vana", vana, roc);
1185  iter++;
1186 
1187  sw.Start(kTRUE); // reset
1188  do {
1189  sw.Start(kFALSE); // continue
1190  ia = getCalibratedIa(roc); // [mA]
1191  }
1192  while( sw.RealTime() < 0.1 );
1193 
1194  diff = fTargetIa + extra - (ia - i015);
1195 
1196  LOG(logDEBUG) << "ROC " << setw(2) << roc
1197  << " iter " << setw(2) << iter
1198  << " Vana " << setw(3) << vana
1199  << " Ia " << ia-i015 << " mA";
1200  } // iter
1201 
1202  rocIana[roc] = ia-i015; // more or less identical for all ROCS?!
1203  vanaStart[roc] = vana; // remember best
1204  fApi->setDAC( "vana", 0, roc ); // switch off for next ROC
1205 
1206  } // rocs
1207 
1208  TH1D *hsum = bookTH1D("VanaSettings", "Vana per ROC", nRocs, 0., nRocs);
1209  setTitles(hsum, "ROC", "Vana [DAC]");
1210  hsum->SetStats(0);
1211  hsum->SetMinimum(0);
1212  hsum->SetMaximum(256);
1213  fHistList.push_back(hsum);
1214 
1215  TH1D *hcurr = bookTH1D("Iana", "Iana per ROC", nRocs, 0., nRocs);
1216  setTitles(hcurr, "ROC", "Vana [DAC]");
1217  hcurr->SetStats(0); // no stats
1218  hcurr->SetMinimum(0);
1219  hcurr->SetMaximum(30.0);
1220  fHistList.push_back(hcurr);
1221 
1222 
1223  restoreDacs();
1224  for (int roc = 0; roc < nRocs; ++roc) {
1225  // -- reset all ROCs to optimum or cached value
1226  fApi->setDAC( "vana", vanaStart[roc], roc );
1227  LOG(logDEBUG) << "ROC " << setw(2) << roc << " Vana " << setw(3) << int(vanaStart[roc]);
1228  // -- histogramming only for those ROCs that were selected
1229  if (!selectedRoc(roc)) continue;
1230  hsum->Fill(roc, vanaStart[roc] );
1231  hcurr->Fill(roc, rocIana[roc]);
1232  }
1233 
1234  vector<double> v_ia16 = getCalibratedIa(); // [mA]
1235 
1236  sw.Start(kTRUE); // reset
1237  do {
1238  sw.Start(kFALSE); // continue
1239  v_ia16 = getCalibratedIa(); // [mA]
1240  }
1241  while( sw.RealTime() < 0.1 );
1242 
1243  double ia16=0.;
1244  for(unsigned int iroc = 0; iroc<v_ia16.size(); iroc++){
1245  ia16 += v_ia16[iroc];
1246  }
1247 
1248  hsum->Draw();
1249  fDisplayedHist = find(fHistList.begin(), fHistList.end(), hsum);
1250  PixTest::update();
1251 
1252  LOG(logINFO) << "PixTestPretest::setVana() done, Module Ia " << ia16 << " mA = " << ia16/nRocs << " mA/ROC";
1253 
1254 }
1255 
1256 
1257 void PixTestReadback::doDAQ(){
1258  //Immediately stop if parameters not in range
1259  if (fParOutOfRange) return;
1260 
1261  //Set the ClockStretch
1262  fApi->setClockStretch(0, 0, fParStretch); //Stretch after trigger, 0 delay
1263 
1264  //Set the histograms:
1265  if(fHistList.size() == 0) setHistos(); //to book histo only for the first 'doTest' (or after Clear).
1266 
1267  //To print on shell the number of masked pixels per ROC:
1268  vector<uint8_t> rocIds = fApi->_dut->getEnabledRocIDs();
1269  LOG(logINFO) << "PixTestReadback::Number of masked pixels:";
1270  for (unsigned int iroc = 0; iroc < rocIds.size(); ++iroc) {
1271  LOG(logINFO) << "PixTestReadback:: ROC " << static_cast<int>(iroc) << ": " << fApi->_dut->getNMaskedPixels(static_cast<int>(iroc));
1272  }
1273 
1274  // Start the DAQ:
1275  //::::::::::::::::::::::::::::::::
1276 
1277  //:::Setting register to read back a given quantity::::://
1278 
1279  //First send only a RES:
1280  fPg_setup.push_back(make_pair("resetroc", 0)); // PG_RESR b001000
1281  uint16_t period = 28;
1282 
1283  //Set the pattern generator:
1284  fApi->setPatternGenerator(fPg_setup);
1285 
1286  fApi->daqStart();
1287 
1288  //Send only one trigger to reset:
1289  fApi->daqTrigger(1, period);
1290  LOG(logINFO) << "PixTestReadback::RES sent once ";
1291 
1292  fApi->daqStop();
1293 
1294  fPg_setup.clear();
1295  LOG(logINFO) << "PixTestReadback::PG_Setup clean";
1296 
1297  //Set the pattern wrt the trigger frequency:
1298  LOG(logINFO) << "PG set to have trigger frequency = " << fParTriggerFrequency << " kHz";
1299  if (!setTrgFrequency(20)){
1300  FinalCleaning();
1301  return;
1302  }
1303 
1304  //Set pattern generator:
1305  fApi->setPatternGenerator(fPg_setup);
1306 
1307  fDaq_loop = true;
1308 
1309  //Start the DAQ:
1310  fApi->daqStart();
1311 
1312  int Ntrig=32;
1313  //Send the triggers:
1314  fApi->daqTrigger(Ntrig, fParPeriod);
1315  gSystem->ProcessEvents();
1316  ProcessData(0);
1317 
1318  fApi->daqStop();
1319 }
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
size_t getNMaskedPixels(uint8_t rocid)
Definition: dut.cc:59
void setPatternGenerator(std::vector< std::pair< std::string, uint8_t > > pg_setup)
Definition: api.cc:78
bool daqStart()
Definition: api.cc:1139
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 getTBva()
Definition: api.cc:429
std::string fStopTip
information for this test
Definition: PixTest.hh:300
PixSetup * fPixSetup
all necessary stuff in one place
Definition: PixTest.hh:290
std::vector< std::vector< uint16_t > > daqGetReadback()
Definition: api.cc:1126
std::vector< std::pair< std::string, std::string > > fParameters
the parameters of this test
Definition: PixTest.hh:302
int getIdxFromId(int id)
provide the mapping between ROC index and ID
Definition: PixTest.cc:1124
TDirectory * fDirectory
where the root histograms will end up
Definition: PixTest.hh:306
void restoreDacs(bool verbose=false)
restore all DACs
Definition: PixTest.cc:771
void bookTree()
book a minimal tree with pixel events
Definition: PixTest.cc:99
dut * _dut
Definition: api.h:728
void setTestboardPower(std::vector< std::pair< std::string, double > > power_settings)
Definition: api.cc:88
Event daqGetEvent()
Definition: api.cc:1300
std::vector< uint8_t > getEnabledRocIDs()
Definition: dut.cc:214
void testAllPixels(bool enable)
Definition: dut.cc:503
bool daqStop()
Definition: api.cc:1324
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
bool selectedRoc(int id)
is ROC ID selected?
Definition: PixTest.cc:879
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 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
void setClockStretch(uint8_t src, uint16_t delay, uint16_t width)
Definition: api.cc:2215
size_t getNRocs()
Definition: dut.cc:84
void setToolTips()
implement this to provide updated tool tips if the user changes test parameters
pxar::pxarCore * fApi
pointer to the API
Definition: PixTest.hh:289
std::vector< Event > daqGetEventBuffer()
Definition: api.cc:1285
double getTBvd()
Definition: api.cc:439
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
uint16_t daqTrigger(uint32_t nTrig=1, uint16_t period=0)
Definition: api.cc:1222
void init()
sets all test parameters
Definition: PixTest.cc:62
void runCommand(std::string command)
allow execution of any button in the test
void doTest()
function connected to "DoTest" button of PixTab