pxar
 All Classes Namespaces Functions Variables Typedefs Friends
PixTestPhOptimization.cc
1 #include <stdlib.h> // atof, atoi
2 #include <algorithm> // std::find
3 #include <sstream> // parsing
4 
5 #include <TStopwatch.h>
6 
7 #include "PixTestPhOptimization.hh"
8 #include "log.h"
9 
10 using namespace std;
11 using namespace pxar;
12 
13 ClassImp(PixTestPhOptimization)
14 
16 
17 PixTestPhOptimization::PixTestPhOptimization( PixSetup *a, std::string name ) : PixTest(a, name), fParNtrig(-1), fParDAC("nada"), fParDacVal(100), fFlagSinglePix(true), fSafetyMarginUp(10), fSafetyMarginLow(15) {
18  PixTest::init();
19  init();
20 }
21 
22 bool PixTestPhOptimization::setParameter(string parName, string sval) {
23  bool found(false);
24  string str1, str2;
25  string::size_type s1;
26  int pixc, pixr;
27  std::transform(parName.begin(), parName.end(), parName.begin(), ::tolower);
28  for (unsigned int i = 0; i < fParameters.size(); ++i) {
29  if (!fParameters[i].first.compare(parName)) {
30  found = true;
31  sval.erase(remove(sval.begin(), sval.end(), ' '), sval.end());
32  if (!parName.compare("ntrig")) {
33  setTestParameter("ntrig", sval);
34  fParNtrig = atoi( sval.c_str() );
35  LOG(logDEBUG) << " setting fParNtrig ->" << fParNtrig
36  << "<- from sval = " << sval;
37  }
38  if (!parName.compare("safetymarginup")) {
39  fSafetyMarginUp = atoi( sval.c_str() );
40  LOG(logDEBUG) << " setting fSafetyMarginUp ->" << fSafetyMarginUp
41  << "<- from sval = " << sval;
42  }
43  if (!parName.compare("safetymarginlow")) {
44  fSafetyMarginLow = atoi( sval.c_str() );
45  LOG(logDEBUG) << " setting fSafetyMarginLow ->" << fSafetyMarginLow
46  << "<- from sval = " << sval;
47  }
48  if (!parName.compare("singlepix")) {
49  fFlagSinglePix = atoi( sval.c_str() );
50  LOG(logDEBUG) << " setting fFlagSinglePix ->" << fFlagSinglePix
51  << "<- from sval = " << sval;
52  }
53  if (!parName.compare("dac")) {
54  setTestParameter("dac", sval);
55  fParDAC = sval;
56  LOG(logDEBUG) << " setting fParDAC ->" << fParDAC
57  << "<- from sval = " << sval;
58  }
59 
60  if (!parName.compare("dacval")) {
61  setTestParameter("dacval", sval);
62  fParDacVal = atoi(sval.c_str());
63  LOG(logDEBUG) << " setting fParDacVal ->" << fParDacVal
64  << "<- from sval = " << sval;
65  }
66 
67  if (!parName.compare("pix")) {
68  s1 = sval.find(",");
69  if (string::npos != s1) {
70  str1 = sval.substr(0, s1);
71  pixc = atoi(str1.c_str());
72  str2 = sval.substr(s1+1);
73  pixr = atoi(str2.c_str());
74  fPIX.push_back(make_pair(pixc, pixr));
75  addSelectedPixels(sval);
76  LOG(logDEBUG) << " adding to FPIX ->" << pixc << "/" << pixr << " fPIX.size() = " << fPIX.size() ;
77  } else {
79  LOG(logDEBUG) << " clear fPIX: " << fPIX.size();
80  }
81  }
82  break;
83  }
84  }
85  return found;
86 }
87 
88 void PixTestPhOptimization::init() {
89  fDirectory = gFile->GetDirectory(fName.c_str());
90  if(!fDirectory) {
91  fDirectory = gFile->mkdir(fName.c_str());
92  }
93  fDirectory->cd();
94 }
95 
96 void PixTestPhOptimization::bookHist(string /*name*/) {}
97 
98 PixTestPhOptimization::~PixTestPhOptimization() {}
99 
101 
102  TStopwatch t;
103 
104  cacheDacs();
105  bigBanner(Form("PixTestPhOptimization::doTest() Ntrig = %d, singlePix = %d", fParNtrig, (fFlagSinglePix?1:0)));
106  fDirectory->cd();
107  PixTest::update();
108 
109  TH1D *h1(0);
110  vector<uint8_t> rocIds = fApi->_dut->getEnabledRocIDs();
111 // LOG(logDEBUG)<<"Enabled ROCs vector has size: "<<rocIds.size();
112 // LOG(logDEBUG)<<"ROC "<<(int)rocIds[0]<<" is enabled";
113 // for(unsigned int iroc=0; iroc < rocIds.size(); iroc++){
114 // LOG(logDEBUG)<<"ROC "<<(int)rocIds[iroc]<<" is enabled";
115 // }
116  string name, title;
117 
118  //looking for inefficient pixels, so that they can be avoided
119  std::vector<std::pair<uint8_t, pair<int,int> > > badPixels;
120  BlacklistPixels(badPixels, 10);
121 
122  //Set from trim file minimum vcal where PH is sampled for minphpix search
123  SetMinThr();
124 
125  //flag allows to choose between PhOpt on single pixel (1) or on the whole roc (0)
126  pair<int, pxar::pixel> maxpixel;
127  pair<int, pxar::pixel> minpixel;
128  map<int, pxar::pixel> maxpixels;
129  map<int, pxar::pixel> minpixels;
130  map<int, int> minVcal;
131 
132  if(fFlagSinglePix){
133  for (unsigned int iroc = 0; iroc < rocIds.size(); ++iroc){
134  LOG(logDEBUG)<<"**********Ph range will be optimised on a single random pixel***********";
135  pxar::pixel randomPix;
136  randomPix= *(RandomPixel(badPixels, rocIds[iroc]));
137  LOG(logDEBUG)<<"In doTest(), randomCol "<<(int)randomPix.column()<<", randomRow "<<(int)randomPix.row()<<", pixel "<<randomPix;
138  maxpixel.first = rocIds[iroc];
139  maxpixel.second.setRoc(rocIds[iroc]);
140  maxpixel.second.setColumn(randomPix.column());
141  maxpixel.second.setRow(randomPix.row());
142  minpixel.first = iroc;
143  minpixel.second.setRoc(rocIds[iroc]);
144  minpixel.second.setColumn(randomPix.column());
145  minpixel.second.setRow(randomPix.row());
146  LOG(logDEBUG)<<"random pixel: "<<maxpixel.second<<", "<<minpixel.second<<"is not on the blacklist";
147  maxpixels.insert(maxpixel);
148  minpixels.insert(minpixel);
149  }
150  }
151  else{
152  LOG(logDEBUG)<<"**********Ph range will be optimised on the whole ROC***********";
153  //getting highest ph pixel
154  GetMaxPhPixel(maxpixels, badPixels);
155  //getting min ph pixel and finding its vcal threshold
156  GetMinPhPixel(minpixels, minVcal, badPixels);
157  }
158 
159  for(unsigned int roc_it = 0; roc_it < rocIds.size(); roc_it++){
160  LOG(logDEBUG)<<"vcal min "<<minVcal[roc_it]<<" on ROC"<<(int)rocIds[roc_it];
161  }
162 
163  //scan phoffset and phscale for max and min ph pixels
164  std::vector< std::pair<uint8_t, std::pair<uint8_t, std::vector<pxar::pixel> > > > dacdac_max;
165  std::vector< std::pair<uint8_t, std::pair<uint8_t, std::vector<pxar::pixel> > > > dacdac_min;
166  MaxPhVsDacDac(dacdac_max, maxpixels);
167  MinPhVsDacDac(dacdac_min, minpixels, minVcal);
168 
169  //search for optimal dac values in 3 steps
170  //1. shrinking the PH to be completely inside the ADC range, adjusting phscale
171  map<uint8_t, int> ps_opt, po_opt;
172  for(unsigned int roc_it = 0; roc_it < rocIds.size(); roc_it++){
173  po_opt[rocIds[roc_it]] = 120;
174  }
175  ps_opt = InsideRangePH(po_opt, dacdac_max, dacdac_min);
176  //check for opt failure
177  for(unsigned int roc_it = 0; roc_it < rocIds.size(); roc_it++){
178  if(ps_opt[rocIds[roc_it]]==999){
179  LOG(logDEBUG)<<"PH optimization failed on ROC "<<(int)rocIds[roc_it]<<endl<<"Please run PreTest or try PhOptimization on a random pixel";
180  }
181  }
182  //2. centring PH curve adjusting phoffset
183  po_opt = CentrePhRange(po_opt, ps_opt, dacdac_max, dacdac_min);
184 
185  //3. stretching curve adjusting phscale
186  ps_opt = StretchPH(po_opt, ps_opt, dacdac_max, dacdac_min);
187 
188  //set optimized dacs and save
189  restoreDacs();
190  for(unsigned int roc_it = 0; roc_it < rocIds.size(); roc_it++){
191  fApi->setDAC("phscale",ps_opt[rocIds[roc_it]], rocIds[roc_it] );
192  fApi->setDAC("phoffset",po_opt[rocIds[roc_it]], rocIds[roc_it]);
193  }
194  saveDacs();
195 
196  cacheDacs();
197  //draw figures of merit of optimization
198  DrawPhMaps(minVcal, badPixels);
199  DrawPhCurves(maxpixels, minpixels, po_opt, ps_opt);
200  restoreDacs();
201 
202  for (list<TH1*>::iterator il = fHistList.begin(); il != fHistList.end(); ++il) {
203  (*il)->Draw(getHistOption(*il).c_str());
204  PixTest::update();
205  }
206  fDisplayedHist = find(fHistList.begin(), fHistList.end(), h1);
207 
208  // -- print summary information
209  string psString(""), poString("");
210  for (unsigned int i = 0; i < rocIds.size(); ++i) {
211  psString += Form(" %3d", fApi->_dut->getDAC(rocIds[i], "phscale"));
212  poString += Form(" %3d", fApi->_dut->getDAC(rocIds[i], "phoffset"));
213  }
214 
215  int seconds = t.RealTime();
216  LOG(logINFO) << "PixTestPhOptimization::doTest() done, duration: " << seconds << " seconds";
217  LOG(logINFO) << "PH scale (per ROC): " << psString;
218  LOG(logINFO) << "PH offset (per ROC): " << poString;
219 
220  }
221 
222 void PixTestPhOptimization::BlacklistPixels(std::vector<std::pair<uint8_t, pair<int, int> > > &badPixels, int aliveTrig){
223  //makes a list of inefficient pixels, to be avoided during optimization
224  fApi->_dut->testAllPixels(true);
225  fApi->_dut->maskAllPixels(false);
226 
227  vector<uint8_t> vVcal = getDacs("vcal");
228  vector<uint8_t> vCreg = getDacs("ctrlreg");
229 
230  vector<TH2D*> testEff = efficiencyMaps("PixelAlive", aliveTrig);
231  vector<uint8_t> rocIds = fApi->_dut->getEnabledRocIDs();
232  std::pair<uint8_t, pair<int, int> > badPix;
233  Double_t eff=0.;
234  for(uint8_t rocid = 0; rocid<rocIds.size(); rocid++){
235  for(int r=0; r<80; r++){
236  for(int c=0; c<52; c++){
237  eff = testEff[rocid]->GetBinContent( testEff[rocid]->FindFixBin((double)c + 0.5, (double)r+0.5) );
238  if(eff<aliveTrig){
239  LOG(logDEBUG)<<"Pixel ["<<(int)rocIds[rocid]<<", "<<(int)c<<", "<<(int)r<<"] has eff "<<eff<<"/"<<aliveTrig;
240  badPix.first = rocIds[rocid];
241  badPix.second.first = c;
242  badPix.second.second = r;
243  LOG(logDEBUG)<<"bad Pixel found and blacklisted: ["<<(int)badPix.first<<", "<<(int)badPix.second.first<<", "<<(int)badPix.second.second<<"]";
244  (badPixels).push_back(badPix);
245  }
246  }
247  }
248  }
249  setDacs("vcal", vVcal);
250  setDacs("ctrlreg", vCreg);
251  LOG(logDEBUG)<<"Number of bad pixels found: "<<badPixels.size();
252 }
253 
254 
255 pxar::pixel* PixTestPhOptimization::RandomPixel(std::vector<std::pair<uint8_t, pair<int, int> > > &badPixels, uint8_t iroc){
256  //Returns a random pixel, taking care it is not on the blacklist
257  fApi->setDAC("ctrlreg",4);
258  bool isPixGood=true;
259  pxar::pixel *randPixel= new pixel();
260  srand(int(time(NULL)));
261  int random_col=-1, random_row=-1;
262  do{
263  random_col = rand() % 52;
264  random_row = rand() % 80;
265  LOG(logDEBUG)<<"random pixel: ["<<iroc<<", "<<random_col<<", "<<random_row<<"]";
266  isPixGood=true;
267  for(std::vector<std::pair<uint8_t, pair<int, int> > >::iterator bad_it = badPixels.begin(); bad_it != badPixels.end(); bad_it++){
268  if(bad_it->first == iroc && bad_it->second.first == random_col && bad_it->second.second == random_row){
269  isPixGood=false;
270  }
271  }
272  LOG(logDEBUG)<<"is the random pixel good? "<<isPixGood;
273  }while(!isPixGood);
274  randPixel->setRoc(iroc);
275  randPixel->setColumn(random_col);
276  randPixel->setRow(random_row);
277  LOG(logDEBUG)<<"In RandomPixel(), rocId "<<iroc<<", randomCol "<<(int)randPixel->column()<<", randomRow "<<(int)randPixel->row()<<", pixel "<<randPixel;
278  return randPixel;
279 }
280 
281 void PixTestPhOptimization::GetMaxPhPixel(map<int, pxar::pixel > &maxpixels, std::vector<std::pair<uint8_t, pair<int,int> > > &badPixels){
282  //looks for the pixel with the highest Ph at vcal = 255, taking care the pixels are not already saturating (ph=255)
283  fApi->_dut->testAllPixels(true);
284  fApi->_dut->maskAllPixels(false);
285  vector<uint8_t> rocIds = fApi->_dut->getEnabledRocIDs();
286  bool isPixGood=true;
287  int maxph = 255;
288  fApi->setDAC("phoffset", 200);
289  int init_phScale =200;
290  int flag_maxPh=0;
291  pair<int, pxar::pixel> maxpixel;
292  maxpixel.second.setValue(0);
293  std::vector<pxar::pixel> result;
294  while((maxph>254 || maxph==0) && flag_maxPh<52){
295  result.clear();
296  fApi->setDAC("phscale", init_phScale);
297  fApi->setDAC("vcal",255);
298  fApi->setDAC("ctrlreg",4);
299  fApi->setDAC("phoffset",200);
300  int cnt(0);
301  bool done(false);
302  while (!done) {
303  try {
304  result = fApi->getPulseheightMap(0, 10);
305  done = true;
306  } catch(pxarException &e) {
307  LOG(logCRITICAL) << "pXar execption: "<< e.what();
308  ++cnt;
309  }
310  done = (cnt>5) || done;
311  }
312 
313  maxph=0;
314  LOG(logDEBUG) << "result size "<<result.size()<<endl;
315  //check that the pixel showing highest PH on the module is not reaching 255
316  for(std::vector<pxar::pixel>::iterator px = result.begin(); px != result.end(); px++) {
317  isPixGood=true;
318  for(std::vector<std::pair<uint8_t, pair<int, int> > >::iterator bad_it = badPixels.begin(); bad_it != badPixels.end(); bad_it++){
319  if(bad_it->second.first == px->column() && bad_it->second.second == px->row() && bad_it->first == px->roc()){
320  isPixGood=false;
321  }
322  }
323  if(isPixGood && px->value() > maxph){
324  maxph = px->value();
325  }
326  }
327  //should have flag for v2 or v2.1
328  init_phScale+=5;
329  flag_maxPh++;
330  }
331  // Look for pixel with max. pulse height on every ROC:
332  for(unsigned int iroc=0; iroc< rocIds.size(); iroc++){
333  maxph=0;
334  for(std::vector<pxar::pixel>::iterator px = result.begin(); px != result.end(); px++) {
335  isPixGood=true;
336  if(px->value() > maxph && px->roc() == rocIds[iroc]){
337  for(std::vector<std::pair<uint8_t, pair<int, int> > >::iterator bad_it = badPixels.begin(); bad_it != badPixels.end(); bad_it++){
338  if(bad_it->second.first == px->column() && bad_it->second.second == px->row() && bad_it->first == px->roc()){
339  isPixGood=false;
340  break;
341  }
342  }
343  if(isPixGood){
344  maxpixel = make_pair(iroc,*px);
345  maxph = px->value();
346  }
347  }
348  }
349  maxpixels.insert(maxpixel);
350  LOG(logDEBUG) << "maxPh " << maxph <<" for ROC "<<maxpixel.first<<" on pixel "<<maxpixel.second << endl ;
351  }
352 }
353 
354 void PixTestPhOptimization::GetMinPhPixel(map<int, pxar::pixel > &minpixels, map<int, int> &minVcal, std::vector<std::pair<uint8_t, pair<int,int> > > &badPixels){
355  //looks for the pixel with the lowest Ph at vcal = 1.2*trimValue, taking care the pixels are correclty responding (ph>0)
356  //finds the min vcal at which the minphpixel can be sampled
357  fApi->_dut->testAllPixels(true);
358  fApi->_dut->maskAllPixels(false);
359  vector<uint8_t> rocIds = fApi->_dut->getEnabledRocIDs();
360  bool isPixGood=true;
361  int minph = 0;
362  int init_phScale = 100;
363  int flag_minPh=0;
364  pair<int, pxar::pixel> minpixel;
365  minpixel.second.setValue(0);
366  std::vector<pxar::pixel> result;
367  while(minph<1 && flag_minPh<52){
368  result.clear();
369  fApi->setDAC("phscale", init_phScale);
370  fApi->setDAC("ctrlreg",0);
371  // fApi->setDAC("vcal",fMinThr*1.2);
372  fApi->setDAC("vcal",130);
373  fApi->setDAC("phoffset",150);
374  int cnt(0);
375  bool done(false);
376  int size = 0;
377  while (!(done && size !=0)) {
378  try {
379  result = fApi->getPulseheightMap(0, 10);
380  size = result.size();
381  ++cnt;
382  done = true;
383  } catch(pxarException &e) {
384  LOG(logCRITICAL) << "pXar execption: "<< e.what();
385  ++cnt;
386  }
387  done = (cnt>5) || done;
388  }
389  minph=255;
390  LOG(logDEBUG) << "result size "<<result.size()<<endl;
391  //check that the pixel showing lowest PH above 0 on the module
392  for(std::vector<pxar::pixel>::iterator px = result.begin(); px != result.end(); px++) {
393  isPixGood=true;
394  for(std::vector<std::pair<uint8_t, pair<int, int> > >::iterator bad_it = badPixels.begin(); bad_it != badPixels.end(); bad_it++){
395  if(bad_it->second.first == px->column() && bad_it->second.second == px->row() && bad_it->first == px->roc()){
396  isPixGood=false;
397  break;
398  }
399  }
400  if(isPixGood && px->value() < minph){
401  minph = px->value();
402  }
403  }
404  //should have flag for v2 or v2.1
405  init_phScale+=5;
406  flag_minPh++;
407  }
408  // Look for pixel with min pulse height on every ROC:
409  for(unsigned int iroc=0; iroc< rocIds.size(); iroc++){
410  minph=255;
411  for(std::vector<pxar::pixel>::iterator px = result.begin(); px != result.end(); px++) {
412  isPixGood=true;
413  if(px->value() < minph && px->roc() == rocIds[iroc]){
414  for(std::vector<std::pair<uint8_t, pair<int, int> > >::iterator bad_it = badPixels.begin(); bad_it != badPixels.end(); bad_it++){
415  if(bad_it->second.first == px->column() && bad_it->second.second == px->row() && bad_it->first == px->roc()){
416  isPixGood=false;
417  break;
418  }
419  }
420  if(isPixGood){
421  minpixel = make_pair(iroc,*px);
422  minph = px->value();
423  }
424  }
425  }
426  minpixels.insert(minpixel);
427  LOG(logDEBUG) << "minPh " << minph <<" for ROC "<<minpixel.first<<" on pixel "<<minpixel.second << endl ;
428  }
429 
430  //finds min vcal
431  int cnt(0);
432  bool done(false);
433  TH1D *h1(0);
434  vector<pair<uint8_t, vector<pixel> > > results;
435  pair<int, int> vcalmin;
436  int vcalthr = 0;
437  h1 = bookTH1D("h1", "h1", 256, 0., 256.);
438  unsigned int NRocs = rocIds.size();
439  for(unsigned int roc_it = 0; roc_it < NRocs; roc_it++){
440  for(unsigned int roc_kt = 0; roc_kt < NRocs; roc_kt++){
441  fApi->_dut->setROCEnable(roc_kt, true);
442  }
443  fApi->_dut->testAllPixels(false);
444  fApi->_dut->maskAllPixels(true);
445  // fApi->_dut->setROCEnable(roc_it, true);
446  // fApi->_dut->testPixel(minpixels[rocIds[roc_it]].column(), minpixels[rocIds[roc_it]].row(), true, rocIds[roc_it]);
447  // fApi->_dut->maskPixel(minpixels[rocIds[roc_it]].column(), minpixels[rocIds[roc_it]].row(), false, rocIds[roc_it]);
448  fApi->_dut->testPixel(minpixels[rocIds[roc_it]].column(), minpixels[rocIds[roc_it]].row(), true);
449  fApi->_dut->maskPixel(minpixels[rocIds[roc_it]].column(), minpixels[rocIds[roc_it]].row(), false);
450  LOG(logDEBUG)<<"enabling pixels "<<(int)minpixels[roc_it].column()<<", "<<(int)minpixels[roc_it].row()<<", "<<(int)minpixels[roc_it].roc()<<" "<<(int)roc_it;
451  for(unsigned int roc_jt = 0; roc_jt < NRocs; roc_jt++){
452  if(roc_jt!= roc_it){
453  fApi->_dut->setROCEnable(roc_jt, false);
454  }
455  }
456  // fApi->_dut->testPixel(minpixels[roc_it].column(), minpixels[roc_it].row(), true, getIdFromIdx((int)roc_it));
457  //fApi->_dut->maskPixel(minpixels[roc_it].column(), minpixels[roc_it].row(), false, getIdFromIdx((int)roc_it));
458  fApi->_dut->info();
459  cnt = 0;
460  done = false;
461  while (!done) {
462  try {
463  // LOG(logDEBUG)<<"trying phVsDAC for roc "<<(int)roc_it<<" "<<(int)rocIds[roc_it];
464  results = fApi->getPulseheightVsDAC("vcal", 0, 255, FLAG_FORCE_MASKED, 10);
465  //LOG(logDEBUG)<<"worked? phVsDAC for roc "<<(int)roc_it<<" "<<(int)rocIds[roc_it];
466  done = true;
467  } catch(pxarException &e) {
468  LOG(logCRITICAL) << "pXar execption: "<< e.what();
469  ++cnt;
470  }
471  done = (cnt>5) || done;
472  }
473 
474  LOG(logDEBUG)<<"size of results "<<results.size();
475  for (unsigned int i = 0; i < results.size(); ++i) {
476  // LOG(logDEBUG)<<"analyzing postion "<<int(i)<<" of results";
477  pair<uint8_t, vector<pixel> > v = results[i];
478  int idac = v.first;
479  // LOG(logDEBUG)<<"idac is "<<(int)idac;
480  vector<pixel> vpix = v.second;
481  //LOG(logDEBUG)<<"vpix size is "<<vpix.size();
482  for (unsigned int ipix = 0; ipix < vpix.size(); ++ipix) {
483  // LOG(logDEBUG)<<"vcalmin loop: ipix = "<<ipix<<", dac = "<<idac<<", ph = "<<vpix[ipix].value();
484  h1->Fill(idac, vpix[ipix].value());
485  }
486  }
487  vcalthr = static_cast<int>( h1->GetBinCenter( h1->FindFirstBinAbove(1.) ) );
488  vcalmin = make_pair(roc_it, vcalthr);
489  minVcal.insert(vcalmin);
490  h1->Reset();
491  }
492  for(unsigned int roc_kt = 0; roc_kt < NRocs; roc_kt++){
493  fApi->_dut->setROCEnable(roc_kt, false);
494  }
495  for(unsigned int roc_kt = 0; roc_kt < NRocs; roc_kt++){
496  fApi->_dut->setROCEnable(roc_kt, true);
497  }
498 }
499 
500 map<uint8_t, int> PixTestPhOptimization::InsideRangePH(map<uint8_t,int> &po_opt, std::vector< std::pair<uint8_t, std::pair<uint8_t, std::vector<pxar::pixel> > > > &dacdac_max, std::vector< std::pair<uint8_t, std::pair<uint8_t, std::vector<pxar::pixel> > > > &dacdac_min){
501  //adjusting phscale so that the PH curve is fully inside the ADC range
502  map<uint8_t, int> ps_opt;
503  int maxPh(0);
504  int minPh(0);
505  bool lowEd=false, upEd=false;
506  int upEd_dist=255, lowEd_dist=255;
507  int safetyMargin = 40;
508  int dist = 255;
509  map<uint8_t, int> bestDist;
510  LOG(logDEBUG) << "dacdac at max vcal has size "<<dacdac_max.size()<<endl;
511  LOG(logDEBUG) << "dacdac at min vcal has size "<<dacdac_min.size()<<endl;
512  vector<uint8_t> rocIds = fApi->_dut->getEnabledRocIDs();
513  for(unsigned int roc_it = 0; roc_it < rocIds.size(); roc_it++){
514  bestDist[rocIds[roc_it]] = 255;
515  LOG(logDEBUG)<<"Bestdist at roc_it "<<roc_it<<" initialized with "<<bestDist[roc_it]<<" "<<bestDist[rocIds[roc_it]];
516  ps_opt[rocIds[roc_it]] = 999;
517  }
518  std::vector< std::pair<uint8_t, std::pair<uint8_t, std::vector<pxar::pixel> > > >::iterator dacit_max = dacdac_max.begin();
519  std::vector< std::pair<uint8_t, std::pair<uint8_t, std::vector<pxar::pixel> > > >::iterator dacit_min = dacdac_min.begin();
520 // for(dacit_max = dacdac_max.begin(); dacit_max != dacdac_max.end(); dacit_max++){
521 // for(int pixit = 0; pixit < dacit_max->second.second.size(); pixit++){
522 // LOG(logDEBUG)<<"dacit_max: pixel "<<(int)dacit_max->second.second[pixit].roc()<<", "<<(int)dacit_max->second.second[pixit].column()<<", "<<(int)dacit_max->second.second[pixit].row()<<", ph offset "<<(int)dacit_max->first<<", ph scale "<<(int)dacit_max->second.first<<", max ph "<<(int)dacit_max->second.second[pixit].value();
523 // LOG(logDEBUG)<<"dacit_min: pixel "<<(int)dacit_min->second.second[pixit].roc()<<", "<<(int)dacit_min->second.second[pixit].column()<<", "<<(int)dacit_min->second.second[pixit].row()<<", ph offset "<<(int)dacit_min->first<<", ph scale "<<(int)dacit_min->second.first<<", min ph "<<(int)dacit_min->second.second[pixit].value();
524 // }
525 // dacit_min++;
526 // }
527  int pixsize_max=0;
528  int pixsize_min=0;
529  LOG(logDEBUG)<<"InsideRange() subtest";
530  for(unsigned int roc_it = 0; roc_it < rocIds.size(); roc_it++){
531  for(dacit_max = dacdac_max.begin(); dacit_max != dacdac_max.end(); dacit_max++){
532  if(dacit_max->first == po_opt[rocIds[roc_it]]){
533  for(dacit_min = dacdac_min.begin(); dacit_min != dacdac_min.end(); dacit_min++)
534  if(dacit_min->first == po_opt[rocIds[roc_it]] && dacit_min->second.first == dacit_max->second.first){
535  pixsize_max = dacit_max->second.second.size();
536  pixsize_min = dacit_min->second.second.size();
537  for(int pix=0; pix < pixsize_max; pix++){
538  if((dacit_max->second.second[pix].roc()!=rocIds[roc_it] || dacit_min->second.second[pix].roc()!=rocIds[roc_it]) && dacit_max->second.second[pix].roc() != dacit_min->second.second[pix].roc()){
539  // LOG(logDEBUG)<<"####//// this time roc ids DO NOT match "<<(int)dacit_min->second.second[pix].roc()<<" "<<(int)dacit_max->second.second[pix].roc()<<" "<<(int)rocIds[roc_it]<<" "<<(int)roc_it<<" ////####";
540  continue;
541  }
542  //LOG(logDEBUG)<<"####//// this time roc ids match "<<(int)rocIds[roc_it]<<" "<<(int)roc_it<<" ////####";
543  maxPh=dacit_max->second.second[pix].value();
544  minPh=dacit_min->second.second[pix].value();
545  if(dacit_max->second.second[pix].roc() != dacit_min->second.second[pix].roc()){
546  LOG(logDEBUG) << "InsideRangePH: ROC ids do not correspond";
547  }
548  lowEd = (minPh > safetyMargin);
549  upEd = (maxPh < 255 - safetyMargin);
550  lowEd_dist = abs(minPh - safetyMargin);
551  upEd_dist = abs(maxPh - (255 - safetyMargin));
552  dist = (upEd_dist > lowEd_dist ) ? (upEd_dist) : (lowEd_dist);
553  if(dist < bestDist[dacit_max->second.second[pix].roc()] && upEd && lowEd){
554  LOG(logDEBUG)<<"New distance "<<dist<<" is smaller than previous bestDist "<<bestDist[dacit_max->second.second[pix].roc()]<<" and edges are ok, so... ";
555  ps_opt[dacit_max->second.second[pix].roc()] = dacit_max->second.first;
556  bestDist[dacit_max->second.second[pix].roc()]=dist;
557  LOG(logDEBUG)<<"... new bestDist is "<<bestDist[dacit_max->second.second[pix].roc()]<<" for ps_opt = "<<ps_opt[dacit_max->second.second[pix].roc()];
558  }
559  }
560  }
561  }
562  }
563  }
564 
565  for(unsigned int roc_it = 0; roc_it < rocIds.size(); roc_it++){
566  LOG(logDEBUG)<<"opt step 1: po fixed to"<<po_opt[rocIds[roc_it]]<<" and scale adjusted to "<<ps_opt[rocIds[roc_it]]<<" for ROC "<<(int)rocIds[roc_it]<<", with distance "<<bestDist[rocIds[roc_it]];
567  }
568  return ps_opt;
569 }
570 
571 map<uint8_t, int> PixTestPhOptimization::CentrePhRange(map<uint8_t, int> &po_opt, map<uint8_t, int> &ps_opt, std::vector< std::pair<uint8_t, std::pair<uint8_t, std::vector<pxar::pixel> > > > &dacdac_max, std::vector< std::pair<uint8_t, std::pair<uint8_t, std::vector<pxar::pixel> > > > &dacdac_min){
572  //centring PH curve adjusting phoffset
573  LOG(logDEBUG)<<"Welcome to CentrePhRange()";
574  int maxPh(0);
575  int minPh(0);
576  int dist = 255;
577  map<uint8_t, int> bestDist;
578  vector<uint8_t> rocIds = fApi->_dut->getEnabledRocIDs();
579  for(unsigned int roc_it = 0; roc_it < rocIds.size(); roc_it++){
580  bestDist[rocIds[roc_it]] = 255;
581  }
582  std::vector< std::pair<uint8_t, std::pair<uint8_t, std::vector<pxar::pixel> > > >::iterator dacit_max = dacdac_max.begin();
583  std::vector< std::pair<uint8_t, std::pair<uint8_t, std::vector<pxar::pixel> > > >::iterator dacit_min = dacdac_min.begin();
584  int pixsize_max=0;
585  int pixsize_min=0;
586  for(unsigned int roc_it = 0; roc_it < rocIds.size(); roc_it++){
587  dist = 255;
588  for(dacit_max = dacdac_max.begin(); dacit_max != dacdac_max.end(); dacit_max++){
589  if(dacit_max->second.first != ps_opt[rocIds[roc_it]])continue;
590  for(dacit_min = dacdac_min.begin(); dacit_min != dacdac_min.end(); dacit_min++){
591  if(dacit_min->second.first == ps_opt[rocIds[roc_it]] && dacit_min->first == dacit_max->first){
592  pixsize_max = dacit_max->second.second.size();
593  pixsize_min = dacit_min->second.second.size();
594  for(int pix=0; pix < pixsize_max; pix++){
595  if(dacit_max->second.second[pix].roc()!=rocIds[roc_it] || dacit_min->second.second[pix].roc()!=rocIds[roc_it]) continue;
596  maxPh=dacit_max->second.second[pix].value();
597  minPh=dacit_min->second.second[pix].value();
598  if(dacit_max->second.second[pix].roc() != dacit_min->second.second[pix].roc()){
599  LOG(logDEBUG) << "CentrePhRange: ROC ids do not correspond";
600  }
601  dist = abs(minPh - (255 - maxPh));
602  if (dist < bestDist[dacit_max->second.second[pix].roc()]){
603  po_opt[dacit_max->second.second[pix].roc()] = dacit_max->first;
604  bestDist[dacit_max->second.second[pix].roc()] = dist;
605  }
606  }
607  }
608  }
609  }
610  }
611  for(unsigned int roc_it = 0; roc_it < rocIds.size(); roc_it++){
612  LOG(logDEBUG)<<"opt centring step: po "<<po_opt[rocIds[roc_it]]<<" and scale "<<ps_opt[rocIds[roc_it]]<<", with distance "<<bestDist[rocIds[roc_it]]<<" on ROC "<<(int)rocIds[roc_it];
613  }
614  return po_opt;
615 }
616 
617 map<uint8_t, int> PixTestPhOptimization::StretchPH(map<uint8_t, int> &po_opt, map<uint8_t, int> &ps_opt, std::vector< std::pair<uint8_t, std::pair<uint8_t, std::vector<pxar::pixel> > > > &dacdac_max, std::vector< std::pair<uint8_t, std::pair<uint8_t, std::vector<pxar::pixel> > > > &dacdac_min){
618  //stretching PH curve to exploit the full ADC range, adjusting phscale
619  int maxPh(0);
620  int minPh(0);
621  bool lowEd=false, upEd=false;
622  int upEd_dist=255, lowEd_dist=255;
623  int safetyMarginUp = fSafetyMarginUp;
624  int safetyMarginLow = fSafetyMarginLow;
625  LOG(logDEBUG)<<"safety margin for stretching set to "<<fSafetyMarginLow<<" (lower edge) and "<<fSafetyMarginUp<<"(upper edge)";
626  int dist = 255;
627  map<uint8_t, int> bestDist;
628  vector<uint8_t> rocIds = fApi->_dut->getEnabledRocIDs();
629  for(unsigned int roc_it = 0; roc_it < rocIds.size(); roc_it++){
630  bestDist[rocIds[roc_it]] = 255;
631  }
632  std::vector< std::pair<uint8_t, std::pair<uint8_t, std::vector<pxar::pixel> > > >::iterator dacit_max = dacdac_max.begin();
633  std::vector< std::pair<uint8_t, std::pair<uint8_t, std::vector<pxar::pixel> > > >::iterator dacit_min = dacdac_min.begin();
634  while(dacit_max != dacdac_max.end() || dacit_min != dacdac_min.end()){
635  for(unsigned int pix=0; pix < dacit_min->second.second.size() && pix < dacit_max->second.second.size(); pix++){
636  if(dacit_max->first == po_opt[dacit_max->second.second[pix].roc()] && dacit_min->first == po_opt[dacit_min->second.second[pix].roc()]){
637  maxPh=dacit_max->second.second[pix].value();
638  minPh=dacit_min->second.second[pix].value();
639  if(dacit_max->second.second[pix].roc() != dacit_min->second.second[pix].roc()){
640  LOG(logDEBUG) << "CentrePhRange: ROC ids do not correspond";
641  }
642  lowEd = (minPh > safetyMarginLow);
643  upEd = (maxPh < 255 - safetyMarginUp);
644  upEd_dist = abs(maxPh - (255 - safetyMarginUp));
645  lowEd_dist = abs(minPh - safetyMarginLow);
646  dist = (upEd_dist < lowEd_dist ) ? (upEd_dist) : (lowEd_dist);
647  if(dist < bestDist[dacit_max->second.second[pix].roc()] && lowEd && upEd){
648  ps_opt[dacit_max->second.second[pix].roc()] = dacit_max->second.first;
649  bestDist[dacit_max->second.second[pix].roc()]=dist;
650  }
651  }
652  }
653  dacit_max++;
654  dacit_min++;
655  }
656  for(unsigned int roc_it = 0; roc_it < rocIds.size(); roc_it++){
657  LOG(logDEBUG)<<"opt final step: po fixed to"<<po_opt[rocIds[roc_it]]<<" and scale adjusted to "<<ps_opt[rocIds[roc_it]]<<", with distance "<<bestDist[rocIds[roc_it]]<<" on ROC "<<(int)rocIds[roc_it];
658  }
659  return ps_opt;
660 }
661 
662 void PixTestPhOptimization::DrawPhMaps(std::map<int, int> &minVcal, std::vector<std::pair<uint8_t, std::pair<int, int> > > &badPixels){
663  vector<uint8_t> rocIds = fApi->_dut->getEnabledRocIDs();
664  string name, title;
665  //draw PH maps and extract validation distributions from them
666  fApi->_dut->testAllPixels(true);
667  fApi->_dut->maskAllPixels(false);
668 
669  std::vector<pxar::pixel> result_map;
670  map<int, TH2D* > h2_PhMaps;
671  map<int, TH1D* > h1_PhMaps;
672  TH2D* h2_PhMap(0);
673  TH1D* h1_PhMap(0);
674  fApi->setDAC("ctrlreg",4);
675  fApi->setDAC("vcal",255);
676  //pulseheight map at vcal=255
677  result_map = fApi->getPulseheightMap(0,10);
678  //unpacking data from map and filling one histo per ROC
679  for(unsigned int roc_it = 0; roc_it < rocIds.size(); roc_it++){
680  name = Form("PH_mapHiVcal_C%d", rocIds[roc_it]);
681  title = Form("PH_mapHiVcal_C%d", rocIds[roc_it]);
682  h2_PhMap = bookTH2D(name, name, 52, 0., 52., 80, 0., 80.);
683  h2_PhMaps.insert(make_pair(rocIds[roc_it], h2_PhMap));
684  fHistList.push_back(h2_PhMaps[rocIds[roc_it]]);
685  fHistOptions.insert( make_pair(h2_PhMaps[rocIds[roc_it]], "colz") );
686  }
687  for (unsigned int i = 0; i < result_map.size(); ++i) {
688  h2_PhMaps[ (int) result_map[i].roc() ]->Fill( result_map[i].column(), result_map[i].row(), result_map[i].value());
689  }
690  //adjust z axis range and extract ph distribution
691  for(unsigned int roc_it = 0; roc_it < rocIds.size(); roc_it++){
692  h2_PhMaps[ (int) rocIds[roc_it] ]->GetZaxis()->SetRangeUser(h2_PhMaps[ (int) rocIds[roc_it] ]->GetMinimum(), 255. );
693  h1_PhMap = distribution( h2_PhMaps[ (int) rocIds[roc_it] ], 255, 0., 255.);
694  h1_PhMaps.insert( make_pair(rocIds[roc_it], h1_PhMap) );
695  fHistList.push_back(h1_PhMaps[rocIds[roc_it]]);
696  }
697 
698  //PH map for lower vcal sampling point
699  for(unsigned int roc_it = 0; roc_it < rocIds.size(); roc_it++){
700  fApi->setDAC("ctrlreg",0);
701  fApi->setDAC("vcal",minVcal[roc_it]+10, rocIds[roc_it] );
702  }
703  map<int, TH2D* > h2_PhMapsMin;
704  map<int, TH1D* > h1_PhMapsMin;
705  //phmap
706  result_map = fApi->getPulseheightMap(0,10);
707  //unpacking data from map and filling one histo per ROC
708  for(unsigned int roc_it = 0; roc_it < rocIds.size(); roc_it++){
709  name = Form("PH_mapLowVcal_C%d", rocIds[roc_it]);
710  title = Form("PH_mapLowVcal_C%d", rocIds[roc_it]);
711  h2_PhMap = bookTH2D(name, name, 52, 0., 52., 80, 0., 80.);
712  h2_PhMapsMin.insert(make_pair(rocIds[roc_it], h2_PhMap));
713  fHistList.push_back(h2_PhMapsMin[rocIds[roc_it]]);
714  fHistOptions.insert( make_pair(h2_PhMapsMin[rocIds[roc_it]], "colz") );
715  }
716  for (unsigned int i = 0; i < result_map.size(); ++i) {
717  h2_PhMapsMin[ (int) result_map[i].roc() ]->Fill( result_map[i].column(), result_map[i].row(), result_map[i].value());
718  }
719  //removing blacklisted pixels (bincontent = 0) from histos
720  for(std::vector<std::pair<uint8_t, pair<int, int> > >::iterator bad_it = badPixels.begin(); bad_it != badPixels.end(); bad_it++){
721  h2_PhMaps[ bad_it->first] ->SetBinContent( h2_PhMaps[ bad_it->first] ->FindFixBin(bad_it->second.first, bad_it->second.second), 0);
722  h2_PhMapsMin[ bad_it->first] ->SetBinContent( h2_PhMapsMin[ bad_it->first] ->FindFixBin(bad_it->second.first, bad_it->second.second), 0);
723  }
724  //adjust z axis range and extract ph distribution
725  for(unsigned int roc_it = 0; roc_it < rocIds.size(); roc_it++){
726  name = Form("PH_distr_LowVcal_C%d", rocIds[roc_it]);
727  title = Form("PH_distr_LowVcal_C%d", rocIds[roc_it]);
728  h2_PhMapsMin[ (int) rocIds[roc_it] ]->GetZaxis()->SetRangeUser(0., h2_PhMapsMin[ (int) rocIds[roc_it] ]->GetMaximum() );
729  h1_PhMap = distribution( h2_PhMapsMin[ (int) rocIds[roc_it] ], 255, 0., 255.);
730  h1_PhMapsMin.insert( make_pair(rocIds[roc_it], h1_PhMap) );
731  fHistList.push_back(h1_PhMapsMin[rocIds[roc_it]]);
732  }
733 }
734 
735 void PixTestPhOptimization::DrawPhCurves(map<int, pxar::pixel > &maxpixels, map<int, pxar::pixel > &minpixels, std::map<uint8_t, int> &po_opt, std::map<uint8_t, int> &ps_opt){
736  vector<uint8_t> rocIds = fApi->_dut->getEnabledRocIDs();
737  string name, title;
738  TH1D *h1(0);
739  for(unsigned int roc_it = 0; roc_it < rocIds.size(); roc_it++){
740  fApi->setDAC("ctrlreg",4);
741  }
742  vector<pair<uint8_t, vector<pixel> > > results;
743  for(unsigned int roc_it = 0; roc_it < rocIds.size(); roc_it++){
744  //draw PH curve for max and min pixel on every ROC
745  results.clear();
746  name = Form("PH_c%d_r%d_C%d", maxpixels[roc_it].column(), maxpixels[roc_it].row(), rocIds[roc_it]);
747  title = Form("PH_c%d_r%d_C%d, phscale = %d, phoffset = %d, maxpixel", maxpixels[roc_it].column(), maxpixels[roc_it].row(), rocIds[roc_it], ps_opt[rocIds[roc_it]], po_opt[rocIds[roc_it]]);
748  h1 = bookTH1D(name, name, 256, 0., 256.);
749  fApi->_dut->testAllPixels(false);
750  fApi->_dut->maskAllPixels(true);
751  fApi->_dut->testPixel(maxpixels[roc_it].column(), maxpixels[roc_it].row(), true, roc_it);
752  fApi->_dut->maskPixel(maxpixels[roc_it].column(), maxpixels[roc_it].row(), false, roc_it);
753  int cnt = 0;
754  bool done = false;
755  while (!done) {
756  try {
757  results = fApi->getPulseheightVsDAC("vcal", 0, 255, FLAG_FORCE_MASKED, 10);
758  done = true;
759  } catch(pxarException &e) {
760  LOG(logCRITICAL) << "pXar execption: "<< e.what();
761  ++cnt;
762  }
763  done = (cnt>5) || done;
764  }
765 
766  for (unsigned int i = 0; i < results.size(); ++i) {
767  pair<uint8_t, vector<pixel> > v = results[i];
768  int idac = v.first;
769  vector<pixel> vpix = v.second;
770  for (unsigned int ipix = 0; ipix < vpix.size(); ++ipix) {
771  h1->Fill(idac, vpix[ipix].value());
772  }
773  }
774  h1->SetMinimum(0);
775  setTitles(h1, title.c_str(), "average PH");
776  fHistList.push_back(h1);
777 
778  results.clear();
779 
780  name = Form("PH_c%d_r%d_C%d", minpixels[roc_it].column(), minpixels[roc_it].row(), rocIds[roc_it]);
781  title = Form("PH_c%d_r%d_C%d, phscale = %d, phoffset = %d, minpixel", minpixels[roc_it].column(), minpixels[roc_it].row(), rocIds[roc_it], ps_opt[rocIds[roc_it]], po_opt[rocIds[roc_it]]);
782  h1 = bookTH1D(name, name, 256, 0., 256.);
783  fApi->_dut->testAllPixels(false);
784  fApi->_dut->maskAllPixels(true);
785  fApi->_dut->testPixel(minpixels[roc_it].column(), minpixels[roc_it].row(), true, roc_it);
786  fApi->_dut->maskPixel(minpixels[roc_it].column(), minpixels[roc_it].row(), false, roc_it);
787  cnt = 0;
788  done = false;
789  while (!done) {
790  try {
791  results = fApi->getPulseheightVsDAC("vcal", 0, 255, FLAG_FORCE_MASKED, 10);
792  done = true;
793  } catch(pxarException &e) {
794  LOG(logCRITICAL) << "pXar execption: "<< e.what();
795  ++cnt;
796  }
797  done = (cnt>5) || done;
798  }
799 
800  for (unsigned int i = 0; i < results.size(); ++i) {
801  pair<uint8_t, vector<pixel> > v = results[i];
802  int idac = v.first;
803  vector<pixel> vpix = v.second;
804  for (unsigned int ipix = 0; ipix < vpix.size(); ++ipix) {
805  h1->Fill(idac, vpix[ipix].value());
806  }
807  }
808  h1->SetMinimum(0);
809  setTitles(h1, title.c_str(), "average PH");
810  fHistList.push_back(h1);
811  }
812 }
813 
814 void PixTestPhOptimization::MaxPhVsDacDac(std::vector< std::pair<uint8_t, std::pair<uint8_t, std::vector<pxar::pixel> > > > &dacdac_max, map<int, pxar::pixel> maxpixels){
815 
816  fApi->_dut->testAllPixels(false);
817  fApi->_dut->maskAllPixels(true);
818  for(std::map<int, pxar::pixel>::iterator maxp_it = maxpixels.begin(); maxp_it != maxpixels.end(); maxp_it++){
819  fApi->_dut->testPixel(maxp_it->second.column(),maxp_it->second.row(),true, getIdxFromId(maxp_it->second.roc()));
820  fApi->_dut->maskPixel(maxp_it->second.column(),maxp_it->second.row(),false, getIdxFromId(maxp_it->second.roc()));
821  }
822  fApi->setDAC("vcal",255);
823  fApi->setDAC("ctrlreg",4);
824 
825  //scanning through offset and scale for max pixel (or randpixel)
826  int cnt = 0;
827  bool done = false;
828  while (!done) {
829  try {
830  dacdac_max = fApi->getPulseheightVsDACDAC("phoffset",0,255,"phscale",0,255,0,10);
831  done = true;
832  } catch(pxarException &e) {
833  LOG(logCRITICAL) << "pXar execption: "<< e.what();
834  ++cnt;
835  }
836  done = (cnt>5) || done;
837  }
838  //std::map<uint8_t, std::map<std::pair<uint8_t, uint8_t>, pxar::pixel > > dacdacmax_map;
839  //std::map<std::pair<uint8_t ,uint8_t >, pxar::pixel > tempMap;
840  for( std::vector< std::pair<uint8_t, std::pair<uint8_t, std::vector<pxar::pixel> > > >::iterator dacit_max = dacdac_max.begin(); dacit_max < dacdac_max.end(); dacit_max+=10){
841  LOG(logDEBUG)<<"size "<<(int)(dacdac_max.end() - dacdac_max.begin())<<"pos "<<(int)(dacdac_max.end() - dacit_max)<<" sizepix "<<(int)dacit_max->second.second.size();
842  // for(int ipix=0; ipix < dacit_max->second.second.size(); ipix++ ){
843  // LOG(logDEBUG)<<"roc "<< (int)dacit_max->second.second[ipix].roc() <<" col "<<(int)dacit_max->second.second[ipix].column() << " row "<<(int)dacit_max->second.second[ipix].row();
844  // }
845  // for(int ipix=0; ipix < dacit_max->second.second.size(); ipix++ ){
846  // tempMap[ make_pair(dacit_max->first, dacit_max->second.first) ] = dacit_max->second.second.at(ipix);
847  // dacdacmax_map[dacit_max->second.second[ipix].roc()] = tempMap;
848  // tempMap.clear();
849  // }
850  }
851 
852 
853 }
854 
855 void PixTestPhOptimization::MinPhVsDacDac(std::vector< std::pair<uint8_t, std::pair<uint8_t, std::vector<pxar::pixel> > > > &dacdac_min, map<int, pxar::pixel> minpixels, std::map<int, int> &minVcal){
856 
857 
858  fApi->_dut->testAllPixels(false);
859  fApi->_dut->maskAllPixels(true);
860  for(std::map<int, pxar::pixel>::iterator minp_it = minpixels.begin(); minp_it != minpixels.end(); minp_it++){
861  fApi->_dut->testPixel(minp_it->second.column(),minp_it->second.row(),true, getIdxFromId(minp_it->second.roc()));
862  fApi->_dut->maskPixel(minp_it->second.column(),minp_it->second.row(),false, getIdxFromId(minp_it->second.roc()));
863  }
864 
865  fApi->setDAC("ctrlreg",0);
866  for(std::map<int, int>::iterator ivcal = minVcal.begin(); ivcal != minVcal.end(); ivcal++){
867  fApi->setDAC("vcal",minVcal[ivcal->first]+10, getIdxFromId(ivcal->first));
868  }
869 
870  //scanning through offset and scale for min pixel (or same randpixel)
871  int cnt = 0;
872  bool done = false;
873  while (!done) {
874  try {
875  dacdac_min = fApi->getPulseheightVsDACDAC("phoffset",0,255,"phscale",0,255,0,10);
876  done = true;
877  } catch(pxarException &e) {
878  LOG(logCRITICAL) << "pXar execption: "<< e.what();
879  ++cnt;
880  }
881  done = (cnt>5) || done;
882  }
883 
884  // std::map<uint8_t, std::map<std::pair<uint8_t, uint8_t>, pxar::pixel > > dacdacmin_map;
885  //std::map<std::pair<uint8_t ,uint8_t >, pxar::pixel > tempMap;
886 // for( std::vector< std::pair<uint8_t, std::pair<uint8_t, std::vector<pxar::pixel> > > >::iterator dacit_min = dacdac_min.begin(); dacit_min < dacdac_min.end(); dacit_min+=1000){
887 // LOG(logDEBUG)<<"dacdac_min: size "<<(int)(dacdac_min.end() - dacdac_min.begin())<<"pos "<<(int)(dacdac_min.end() - dacit_min)<<" sizepix "<<(int)dacit_min->second.second.size();
888 // for(int ipix=0; ipix < dacit_min->second.second.size(); ipix++ ){
889 // LOG(logDEBUG)<<"roc "<< (int)dacit_min->second.second[ipix].roc() <<" col "<<(int)dacit_min->second.second[ipix].column() << " row "<<(int)dacit_min->second.second[ipix].row();
890 // }
891 // for(int ipix=0; ipix < dacit_min->second.second.size(); ipix++ ){
892 // tempMap[ make_pair(dacit_min->first, dacit_min->second.first) ] = dacit_min->second.second.at(ipix);
893 // dacdacmin_map[dacit_min->second.second[ipix].roc()] = tempMap;
894 // tempMap.clear();
895 // }
896  }
897 
898 
899 
900 void PixTestPhOptimization::SetMinThr(){
901  fMinThr=0;
902  string trimfile = fPixSetup->getConfigParameters()->getTrimParameterFileName() + fPixSetup->getConfigParameters()->getTrimVcalSufix();
903  trimfile.erase(0,14); //erases 'trimParamerers' from the name of the file
904  if(0!=(trimfile.compare(""))){
905  fMinThr = atoi(trimfile.c_str());
906  }
907  else{
908  LOG(logINFO)<<"***::: The test requires a TRIMMED module, but no TrimParameterFile is loaded :::***";
909  LOG(logINFO)<<"Vcal lower sample point will be set to 40";
910  fMinThr=40;
911  }
912 }
913 
914 
915 /*map<uint8_t, int> PixTestPhOptimization::InsideRangePH_new(map<uint8_t,int> &po_opt, std::map<uint8_t, std::map<std::pair<uint8_t, uint8_t>, pxar::pixel > > dacdacmax_map, std::map<uint8_t, std::map<std::pair<uint8_t, uint8_t>, pxar::pixel > > dacdacmin_map){
916  //adjusting phscale so that the PH curve is fully inside the ADC range
917  map<uint8_t, int> ps_opt;
918  int maxPh(0);
919  int minPh(0);
920  bool lowEd=false, upEd=false;
921  int upEd_dist=255, lowEd_dist=255;
922  int safetyMargin = 50;
923  int dist = 255;
924  map<uint8_t, int> bestDist;
925  LOG(logDEBUG) << "dacdac at max vcal has size "<<dacdac_max.size()<<endl;
926  LOG(logDEBUG) << "dacdac at min vcal has size "<<dacdac_min.size()<<endl;
927  vector<uint8_t> rocIds = fApi->_dut->getEnabledRocIDs();
928  for(unsigned int roc_it = 0; roc_it < rocIds.size(); roc_it++){
929  bestDist[rocIds[roc_it]] = 255;
930  LOG(logDEBUG)<<"Bestdist at roc_it "<<roc_it<<" initialized with "<<bestDist[roc_it]<<" "<<bestDist[rocIds[roc_it]];
931  ps_opt[rocIds[roc_it]] = 999;
932  }
933  std::vector< std::pair<uint8_t, std::pair<uint8_t, std::vector<pxar::pixel> > > >::iterator dacit_max = dacdac_max.begin();
934  std::vector< std::pair<uint8_t, std::pair<uint8_t, std::vector<pxar::pixel> > > >::iterator dacit_min = dacdac_min.begin();
935 // for(dacit_max = dacdac_max.begin(); dacit_max != dacdac_max.end(); dacit_max++){
936 // for(int pixit = 0; pixit < dacit_max->second.second.size(); pixit++){
937 // LOG(logDEBUG)<<"dacit_max: pixel "<<(int)dacit_max->second.second[pixit].roc()<<", "<<(int)dacit_max->second.second[pixit].column()<<", "<<(int)dacit_max->second.second[pixit].row()<<", ph offset "<<(int)dacit_max->first<<", ph scale "<<(int)dacit_max->second.first<<", max ph "<<(int)dacit_max->second.second[pixit].value();
938 // LOG(logDEBUG)<<"dacit_min: pixel "<<(int)dacit_min->second.second[pixit].roc()<<", "<<(int)dacit_min->second.second[pixit].column()<<", "<<(int)dacit_min->second.second[pixit].row()<<", ph offset "<<(int)dacit_min->first<<", ph scale "<<(int)dacit_min->second.first<<", min ph "<<(int)dacit_min->second.second[pixit].value();
939 // }
940 // dacit_min++;
941 // }
942  int pixsize_max=0;
943  int pixsize_min=0;
944  LOG(logDEBUG)<<"InsideRange() subtest";
945  for(unsigned int roc_it = 0; roc_it < rocIds.size(); roc_it++){
946  for(dacit_max = dacdac_max.begin(); dacit_max != dacdac_max.end(); dacit_max++){
947  if(dacit_max->first == po_opt[rocIds[roc_it]]){
948  for(dacit_min = dacdac_min.begin(); dacit_min != dacdac_min.end(); dacit_min++)
949  if(dacit_min->first == po_opt[rocIds[roc_it]] && dacit_min->second.first == dacit_max->second.first){
950  pixsize_max = dacit_max->second.second.size();
951  pixsize_min = dacit_min->second.second.size();
952  for(int pix=0; pix < pixsize_max; pix++){
953  if(dacit_max->second.second[pix].roc()!=rocIds[roc_it] || dacit_min->second.second[pix].roc()!=rocIds[roc_it]){
954  LOG(logDEBUG)<<"####//// this time roc ids DO NOT match "<<(int)dacit_min->second.second[pix].roc()<<" "<<(int)dacit_max->second.second[pix].roc()<<" "<<(int)rocIds[roc_it]<<" "<<(int)roc_it<<" ////####";
955  continue;
956  }
957  LOG(logDEBUG)<<"####//// this time roc ids match "<<(int)rocIds[roc_it]<<" "<<(int)roc_it<<" ////####";
958  maxPh=dacit_max->second.second[pix].value();
959  minPh=dacit_min->second.second[pix].value();
960  if(dacit_max->second.second[pix].roc() != dacit_min->second.second[pix].roc()){
961  LOG(logDEBUG) << "InsideRangePH: ROC ids do not correspond";
962  }
963  lowEd = (minPh > safetyMargin);
964  upEd = (maxPh < 255 - safetyMargin);
965  lowEd_dist = abs(minPh - safetyMargin);
966  upEd_dist = abs(maxPh - (255 - safetyMargin));
967  dist = (upEd_dist > lowEd_dist ) ? (upEd_dist) : (lowEd_dist);
968  if(dist < bestDist[dacit_max->second.second[pix].roc()] && upEd && lowEd){
969  LOG(logDEBUG)<<"New distance "<<dist<<" is smaller than previous bestDist "<<bestDist[dacit_max->second.second[pix].roc()]<<" and edges are ok, so... ";
970  ps_opt[dacit_max->second.second[pix].roc()] = dacit_max->second.first;
971  bestDist[dacit_max->second.second[pix].roc()]=dist;
972  LOG(logDEBUG)<<"... new bestDist is "<<bestDist[dacit_max->second.second[pix].roc()]<<" for ps_opt = "<<ps_opt[dacit_max->second.second[pix].roc()];
973  }
974  }
975  }
976  }
977  }
978  }
979 
980  for(unsigned int roc_it = 0; roc_it < rocIds.size(); roc_it++){
981  LOG(logDEBUG)<<"opt step 1: po fixed to"<<po_opt[rocIds[roc_it]]<<" and scale adjusted to "<<ps_opt[rocIds[roc_it]]<<" for ROC "<<(int)rocIds[roc_it]<<", with distance "<<bestDist[rocIds[roc_it]];
982  }
983  return ps_opt;
984 }*/
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
std::vector< pixel > getPulseheightMap(uint16_t flags, uint16_t nTriggers)
Definition: api.cc:1024
std::map< TH1 *, std::string > fHistOptions
options can be stored with each histogram
Definition: PixTest.hh:308
void setDacs(std::string dacName, std::vector< uint8_t > dacVector)
set on all ROCs the DAC dacName
Definition: PixTest.cc:1627
std::vector< std::pair< uint8_t, std::vector< pixel > > > getPulseheightVsDAC(std::string dacName, uint8_t dacMin, uint8_t dacMax, uint16_t flags, uint16_t nTriggers)
Definition: api.cc:675
bool setDAC(std::string dacName, uint8_t dacValue, uint8_t rocI2C)
Definition: api.cc:546
PixSetup * fPixSetup
all necessary stuff in one place
Definition: PixTest.hh:290
void doTest()
function connected to "DoTest" button of PixTab
std::vector< std::pair< int, int > > fPIX
range of enabled pixels for time-consuming tests
Definition: PixTest.hh:311
void setRow(uint8_t row)
Definition: datatypes.h:67
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
int getIdxFromId(int id)
provide the mapping between ROC index and ID
Definition: PixTest.cc:1124
void info()
Definition: dut.cc:16
void maskAllPixels(bool mask, uint8_t rocid)
Definition: dut.cc:481
void clearSelectedPixels()
clear selected pixel list
Definition: PixTest.cc:498
TDirectory * fDirectory
where the root histograms will end up
Definition: PixTest.hh:306
void setROCEnable(size_t rocId, bool enable)
Definition: dut.cc:381
void restoreDacs(bool verbose=false)
restore all DACs
Definition: PixTest.cc:771
dut * _dut
Definition: api.h:728
void addSelectedPixels(std::string sval)
add a selected pixel to the internal parameter list
Definition: PixTest.cc:480
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
std::vector< std::pair< uint8_t, std::pair< uint8_t, std::vector< pixel > > > > getPulseheightVsDACDAC(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:878
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
void setColumn(uint8_t column)
Definition: datatypes.h:59
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
virtual bool setParameter(std::string parName, std::string sval)
set the string value of a parameter
std::vector< uint8_t > getDacs(std::string dacName)
return from all ROCs the DAC dacName
Definition: PixTest.cc:1604
void saveDacs()
save DACs to file
Definition: PixTest.cc:1511
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
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
uint8_t column() const
Definition: datatypes.h:55
pxar::pxarCore * fApi
pointer to the API
Definition: PixTest.hh:289
void init()
sets all test parameters
Definition: PixTest.cc:62
void setRoc(uint8_t roc)
Definition: datatypes.h:51
uint8_t row() const
Definition: datatypes.h:63