pxar
 All Classes Namespaces Functions Variables Typedefs Friends
PixTestScurves.cc
1 #include <stdlib.h> /* atof, atoi */
2 #include <algorithm> // std::find
3 #include <iostream>
4 #include <fstream>
5 
6 #include <TH1.h>
7 #include <TRandom.h>
8 #include <TMath.h>
9 #include <TStopwatch.h>
10 
11 #include "PixTestScurves.hh"
12 #include "PixUtil.hh"
13 #include "log.h"
14 #include "rsstools.hh"
15 
16 using namespace std;
17 using namespace pxar;
18 
19 ClassImp(PixTestScurves)
20 
21 // ----------------------------------------------------------------------
22 PixTestScurves::PixTestScurves(PixSetup *a, std::string name) : PixTest(a, name),
23  fParDac(""), fParNtrig(-1), fParNpix(-1), fParDacLo(-1), fParDacHi(-1), fParDacsPerStep(-1), fAdjustVcal(1), fDumpAll(-1), fDumpProblematic(-1) {
24  PixTest::init();
25  init();
26 }
27 
28 
29 //----------------------------------------------------------
30 PixTestScurves::PixTestScurves() : PixTest() {
31  // LOG(logDEBUG) << "PixTestScurves ctor()";
32 }
33 
34 // ----------------------------------------------------------------------
35 bool PixTestScurves::setParameter(string parName, string sval) {
36  bool found(false);
37  std::transform(parName.begin(), parName.end(), parName.begin(), ::tolower);
38  for (unsigned int i = 0; i < fParameters.size(); ++i) {
39  if (fParameters[i].first == parName) {
40  found = true;
41  sval.erase(remove(sval.begin(), sval.end(), ' '), sval.end());
42  if (!parName.compare("ntrig")) {
43  fParNtrig = atoi(sval.c_str());
44  }
45  if (!parName.compare("npix")) {
46  fParNpix = atoi(sval.c_str());
47  }
48  if (!parName.compare("dac")) {
49  fParDac = sval;
50  }
51  if (!parName.compare("daclo")) {
52  fParDacLo = atoi(sval.c_str());
53  }
54  if (!parName.compare("dachi")) {
55  fParDacHi = atoi(sval.c_str());
56  }
57  if (!parName.compare("dacs/step")) {
58  fParDacsPerStep = atoi(sval.c_str());
59  }
60 
61  if (!parName.compare("adjustvcal")) {
62  PixUtil::replaceAll(sval, "checkbox(", "");
63  PixUtil::replaceAll(sval, ")", "");
64  fAdjustVcal = atoi(sval.c_str());
65  setToolTips();
66  }
67 
68  if (!parName.compare("dumpall")) {
69  PixUtil::replaceAll(sval, "checkbox(", "");
70  PixUtil::replaceAll(sval, ")", "");
71  fDumpAll = atoi(sval.c_str());
72  setToolTips();
73  }
74 
75  if (!parName.compare("dumpallproblematic")) {
76  PixUtil::replaceAll(sval, "checkbox(", "");
77  PixUtil::replaceAll(sval, ")", "");
78  fDumpProblematic = atoi(sval.c_str());
79  setToolTips();
80  }
81 
82  setToolTips();
83  break;
84  }
85  }
86 
87  return found;
88 }
89 
90 
91 // ----------------------------------------------------------------------
93  fTestTip = string(Form("measure and fit s-curves for DAC %s\n", fParDac.c_str()));
94  fSummaryTip = string("all ROCs are displayed side-by-side. Note the orientation:")
95  + string("\nthe canvas bottom corresponds to the narrow module side with the cable")
96  + string("\nexplanations for all plots: ")
97  + string("thr_* shows the map of the s-curve thresholds")
98  + string("\nsig_* shows the map of the s-curve widths")
99  + string("\ndist_* shows the distribution/projections of the threshold and width maps")
100  ;
101 }
102 
103 // ----------------------------------------------------------------------
104 void PixTestScurves::init() {
105 
106  setToolTips();
107 
108  fDirectory = gFile->GetDirectory(fName.c_str());
109  if (!fDirectory) {
110  fDirectory = gFile->mkdir(fName.c_str());
111  }
112  fDirectory->cd();
113 
114 }
115 
116 // ----------------------------------------------------------------------
117 void PixTestScurves::bookHist(string name) {
118  fDirectory->cd();
119 
120  LOG(logDEBUG) << "nothing done with " << name;
121 
122 }
123 
124 
125 //----------------------------------------------------------
126 PixTestScurves::~PixTestScurves() {
127  LOG(logDEBUG) << "PixTestScurves dtor";
128 }
129 
130 
131 // ----------------------------------------------------------------------
133 
134  fDirectory->cd();
135  PixTest::update();
136 
137  bigBanner(Form("PixTestScurves::doTest() ntrig = %d", fParNtrig));
138  scurves();
139 
140  /*
141  fParNtrig = 20;
142  bigBanner(Form("PixTestScurves::doTest() ntrig = %d (warning: this overrides the GUI values!)", fParNtrig));
143 
144  fParDac = "VthrComp";
145  fParDacLo = 0;
146  fParDacHi = 139;
147  scurves();
148 
149  fParDac = "Vcal";
150  fParDacLo = 0;
151  fParDacHi = 169;
152  scurves();
153  */
154 
155 }
156 
157 
158 // ----------------------------------------------------------------------
160 
161  TStopwatch t;
162 
163  fDirectory->cd();
164  PixTest::update();
165  fParNtrig = 20;
166  bigBanner(Form("PixTestScurves::fullTest() ntrig = %d", fParNtrig));
167 
168  fParDac = "VthrComp";
169  fParDacLo = 0;
170  fParDacHi = 119;
171  fParDacsPerStep = 40;
172  scurves();
173 
174  fParDac = "Vcal";
175  fParDacLo = 0;
176  fParDacHi = 159;
177  fParDacsPerStep = 40;
178  scurves();
179 
180  int seconds = t.RealTime();
181  LOG(logINFO) << "PixTestScurves::fullTest() done, duration: " << seconds << " seconds";
182 
183 
184 }
185 
186 
187 // ----------------------------------------------------------------------
188 void PixTestScurves::runCommand(string command) {
189  std::transform(command.begin(), command.end(), command.begin(), ::tolower);
190  LOG(logDEBUG) << "running command: " << command;
191  if (!command.compare("thrmap")) {
192  thrMap();
193  return;
194  }
195  if (!command.compare("fits")) {
196  fitS();
197  return;
198  }
199  if (!command.compare("scurves")) {
200  scurves();
201  return;
202  }
203  return;
204 }
205 
206 
207 // ----------------------------------------------------------------------
208 void PixTestScurves::scurves() {
209  fDirectory->cd();
210  cacheDacs();
211 
212  string command(fParDac);
213  std::transform(command.begin(), command.end(), command.begin(), ::tolower);
214  if (!command.compare("vthrcomp") && fAdjustVcal) {
215  LOG(logINFO) << "adjusting VCAL to have VthrComp average threshold at default VthrComp";
216  adjustVcal();
217  }
218 
219 
220  fApi->_dut->testAllPixels(true);
221  fApi->_dut->maskAllPixels(false);
222 
223  int results(0xf);
224  if (fDumpAll) results |= 0x20;
225  if (fDumpProblematic) results |= 0x10;
226 
227  int FLAG = FLAG_FORCE_MASKED;
228  vector<TH1*> thr0 = scurveMaps(fParDac, "scurve"+fParDac, fParNtrig, fParDacLo, fParDacHi, fParDacsPerStep, results, 1, FLAG);
229  if (thr0.size() < 1) {
230  LOG(logERROR) << "no scurve result histograms received?!";
231  return;
232 
233  }
234  TH1 *h1 = (*fDisplayedHist);
235  if (h1) h1->Draw(getHistOption(h1).c_str());
236  PixTest::update();
237  restoreDacs();
238 
239  string hname(""), scurvesMeanString(""), scurvesRmsString("");
240  for (unsigned int i = 0; i < thr0.size(); ++i) {
241  hname = thr0[i]->GetName();
242  if (!thr0[i]) continue;
243  // -- skip sig_ and thn_ histograms
244  if (string::npos == hname.find("dist_thr_")) continue;
245  scurvesMeanString += Form("%6.2f ", thr0[i]->GetMean());
246  scurvesRmsString += Form("%6.2f ", thr0[i]->GetRMS());
247  }
248 
249  LOG(logINFO) << "PixTestScurves::scurves() done ";
250  LOG(logINFO) << Form("%s mean: ", fParDac.c_str()) << scurvesMeanString;
251  LOG(logINFO) << Form("%s RMS: ", fParDac.c_str()) << scurvesRmsString;
252 
253 }
254 
255 
256 // ----------------------------------------------------------------------
257 void PixTestScurves::thrMap() {
258  cacheDacs();
259  PixTest::update();
260  fDirectory->cd();
261 
262  fApi->_dut->testAllPixels(true);
263  fApi->_dut->maskAllPixels(false);
264  LOG(logINFO) << "PixTestScurves::thrMap() start: "
265  << fParDac << ": " << fParDacLo << " .. " << fParDacHi
266  << " ntrig = " << fParNtrig;
267  vector<TH1*> thr1 = thrMaps(fParDac, "thr"+fParDac, fParDacLo, fParDacHi, fParNtrig);
268 
269  PixTest::update();
270  restoreDacs();
271  LOG(logINFO) << "PixTestScurves::thrMap() done ";
272 
273 }
274 
275 
276 // ----------------------------------------------------------------------
277 void PixTestScurves::fitS() {
278  PixTest::update();
279  fDirectory->cd();
280 
281  if (!fParDac.compare("Vcal")) {
282  TH1D *h = (TH1D*)fDirectory->Get("scurveVcal_Vcal_c51_r62_C0");
283 
284  fPIF->fLo = fParDacLo+1;
285  fPIF->fHi = fParDacHi;
286  TF1 *f = fPIF->errScurve(h);
287  f->SetLineColor(kBlue);
288 
289  for (int iroc = 0; iroc < 1; ++iroc) {
290  for (int ic = 0; ic < 2; ++ic) {
291  for (int ir = 0; ir < 10; ++ir) {
292 
293  h = (TH1D*)fDirectory->Get(Form("scurveVcal_Vcal_c%d_r%d_C%d", ic, ir, iroc));
294  if (0 == h) continue;
295 
296  h->Fit(f, "qr", "", fPIF->fLo, fPIF->fHi);
297 
298  double Threshold = f->GetParameter(0);
299  double ThresholdE = f->GetParError(0);
300  cout << Threshold << " +/- " << ThresholdE << endl;
301  PixTest::update();
302  }
303  }
304  }
305  }
306 
307  string dacname(fParDac);
308  std::transform(dacname.begin(), dacname.end(), dacname.begin(), ::tolower);
309  if (!dacname.compare("vthrcomp")) {
310  TH1D *h = (TH1D*)fDirectory->Get("scurveVthrComp_VthrComp_c51_r62_C0");
311 
312 
313  for (int iroc = 0; iroc < 1; ++iroc) {
314  for (int ic = 0; ic < 10; ++ic) {
315  for (int ir = 0; ir < 20; ++ir) {
316  h = (TH1D*)fDirectory->Get(Form("scurveVthrComp_VthrComp_c%d_r%d_C%d", ic, ir, iroc));
317  if (0 == h) continue;
318  fPIF->fLo = fParDacLo+1;
319  fPIF->fHi = h->FindLastBinAbove(0.5*h->GetMaximum());
320  TF1 *f = fPIF->errScurve(h);
321  f->SetLineColor(kBlue);
322  if (fPIF->doNotFit()) {
323  } else {
324  h->Fit(f, "qr", "", fPIF->fLo, fPIF->fHi);
325  }
326  double Threshold = f->GetParameter(0);
327  double ThresholdE = f->GetParError(0);
328  cout << Threshold << " +/- " << ThresholdE << endl;
329  PixTest::update();
330  fHistList.push_back(h);
331  }
332  }
333  }
334  fDisplayedHist = find(fHistList.begin(), fHistList.end(), h);
335  }
336 
337 }
338 
339 // ----------------------------------------------------------------------
340 void PixTestScurves::adjustVcal() {
341 
342  vector<int> vcal;
343  uint16_t FLAGS = FLAG_FORCE_MASKED;
344 
345  vector<uint8_t> rocIds = fApi->_dut->getEnabledRocIDs();
346  unsigned nrocs = rocIds.size();
347 
348  vector<vector<pair<int, int> > > dead = deadPixels(5);
349  // FIXME: do something with 'dead'!!!
350 
351  fApi->_dut->testAllPixels(false);
352  fApi->_dut->maskAllPixels(true);
353 
354  fApi->_dut->testPixel(11, 20, true);
355  fApi->_dut->maskPixel(11, 20, false);
356 
357  vector<TH2D *> hv;
358  TH2D *h(0);
359  for (unsigned int iroc = 0; iroc < nrocs; ++iroc){
360  h = bookTH2D(Form("adjustVcal_C%d", rocIds[iroc]), Form("adjustVcal_C%d", rocIds[iroc]), 256, 0., 256., 256, 0., 256.);
361  fHistOptions.insert(make_pair(h, "colz"));
362  hv.push_back(h);
363  }
364 
365  int ntrig(5);
366 
367  try{
368 
369  vector<pair<uint8_t, pair<uint8_t, vector<pixel> > > > results =
370  fApi->getEfficiencyVsDACDAC("vthrcomp", 0, 255, "vcal", 0, 255, FLAGS, ntrig);
371 
372  int idx(-1);
373  for (unsigned int i = 0; i < results.size(); ++i) {
374  pair<uint8_t, pair<uint8_t, vector<pixel> > > v = results[i];
375  int idac1 = v.first;
376  pair<uint8_t, vector<pixel> > w = v.second;
377  int idac2 = w.first;
378  vector<pixel> wpix = w.second;
379 
380  for (unsigned ipix = 0; ipix < wpix.size(); ++ipix) {
381  idx = getIdxFromId(wpix[ipix].roc());
382  hv[idx]->Fill(idac1, idac2, wpix[ipix].value());
383  }
384  }
385 
386  for (unsigned int iroc = 0; iroc < nrocs; ++iroc){
387  hv[iroc]->Draw("colz");
388  fHistList.push_back(hv[iroc]);
389  PixTest::update();
390 
391  int vcthr = fApi->_dut->getDAC(rocIds[iroc], "vthrcomp");
392  TH1D *h0 = hv[iroc]->ProjectionY("h0_px", vcthr, vcthr+1);
393  int vcalthr = h0->FindFirstBinAbove(0.5*ntrig);
394  delete h0;
395 
396  LOG(logDEBUG) << "ROC " << static_cast<int>(rocIds[iroc]) << " vthrcomp = " << vcthr << " -> vcal = " << vcalthr;
397  vcal.push_back(vcalthr);
398  }
399 
400  } catch(pxarException &e){
401  LOG(logCRITICAL) << "problem with readout: "<< e.what() << " setting vcal = 100";
402  for (unsigned int iroc = 0; iroc < nrocs; ++iroc){
403  vcal.push_back(100);
404  }
405  }
406 
407  for (unsigned int i = 0; i < nrocs; ++i) {
408  fApi->setDAC("vcal", vcal[i], rocIds[i]);
409  }
410  fApi->_dut->testAllPixels(true);
411  fApi->_dut->maskAllPixels(false);
412 
413 }
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
std::vector< std::vector< std::pair< int, int > > > deadPixels(int ntrig, bool scanCalDel=false)
create vector (per ROC) of vector of dead pixels
Definition: PixTest.cc:1528
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
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
virtual bool setParameter(std::string parName, std::string sval)
set the string value of a parameter
void maskAllPixels(bool mask, uint8_t rocid)
Definition: dut.cc:481
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
dut * _dut
Definition: api.h:728
void setToolTips()
implement this to provide updated tool tips if the user changes test parameters
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
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
std::vector< std::pair< uint8_t, std::pair< uint8_t, std::vector< pixel > > > > getEfficiencyVsDACDAC(std::string dac1name, uint8_t dac1min, uint8_t dac1max, std::string dac2name, uint8_t dac2min, uint8_t dac2max, uint16_t flags, uint16_t nTriggers)
Definition: api.cc:951
void fullTest()
function called when FullTest is running; most often this is simply calling doTest() ...
PixInitFunc * fPIF
function instantiation and automatic initialization
Definition: PixTest.hh:292
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 doTest()
function connected to "DoTest" button of PixTab
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
pxar::pxarCore * fApi
pointer to the API
Definition: PixTest.hh:289
std::vector< TH1 * > scurveMaps(std::string dac, std::string name, int ntrig=10, int daclo=0, int dachi=255, int dacsperstep=-1, int result=15, int ihit=1, int flag=FLAG_FORCE_MASKED)
Definition: PixTest.cc:177
void init()
sets all test parameters
Definition: PixTest.cc:62
void runCommand(std::string command)
allow execution of any button in the test
std::vector< TH1 * > thrMaps(std::string dac, std::string name, uint8_t dacmin, uint8_t dachi, int ntrig, uint16_t flag=0)
returns TH2D's for the threshold, the user flag argument is intended for selecting calS and will be O...