pxar
 All Classes Namespaces Functions Variables Typedefs Friends
PixTestDaq.cc
1 
2 #include <stdlib.h> /* atof, atoi */
3 #include <algorithm> // std::find
4 #include <iostream>
5 #include "PixTestDaq.hh"
6 #include "log.h"
7 #include "helper.h"
8 #include "timer.h"
9 
10 #include "PixUtil.hh"
11 
12 using namespace std;
13 using namespace pxar;
14 
15 ClassImp(PixTestDaq)
16 
17 // ----------------------------------------------------------------------
18 PixTestDaq::PixTestDaq(PixSetup *a, std::string name) : PixTest(a, name), fParDelayTBM(0), fParFillTree(0), fParStretch(0), fParTriggerFrequency(0), fParNtrig(0), fParIter(0), fRunDaqTrigger(0), fParSeconds(0) {
19  PixTest::init();
20  init();
21  LOG(logDEBUG) << "PixTestDaq ctor(PixSetup &a, string, TGTab *)";
22 
23  fTree = 0;
24  fPhCal.setPHParameters(fPixSetup->getConfigParameters()->getGainPedestalParameters());
25  fPhCalOK = fPhCal.initialized();
26 }
27 
28 //----------------------------------------------------------
29 PixTestDaq::PixTestDaq() : PixTest() {
30  LOG(logDEBUG) << "PixTestDaq ctor()";
31  fTree = 0;
32 }
33 
34 //----------------------------------------------------------
35 PixTestDaq::~PixTestDaq() {
36  LOG(logDEBUG) << "PixTestDaq dtor";
37  fDirectory->cd();
38  if (fTree && fParFillTree) fTree->Write();
39 }
40 
41 // ----------------------------------------------------------------------
42 void PixTestDaq::init() {
43  LOG(logDEBUG) << "PixTestDaq::init()";
44  setToolTips();
45  fDirectory = gFile->GetDirectory(fName.c_str());
46  if (!fDirectory) {
47  fDirectory = gFile->mkdir(fName.c_str());
48  }
49  fDirectory->cd();
50 }
51 
52 // ----------------------------------------------------------------------
54  fTestTip = string("Run DAQ seconds - data from each run will be added to the same histogram.") ;
55  fSummaryTip = string("to be implemented") ;
56  fStopTip = string("Stop DAQ and save data.");
57 }
58 
59 // ----------------------------------------------------------------------
60 bool PixTestDaq::setParameter(string parName, string sval) {
61  bool found(false);
62  fParOutOfRange = false;
63  std::transform(parName.begin(), parName.end(), parName.begin(), ::tolower);
64  for (unsigned int i = 0; i < fParameters.size(); ++i) {
65  if (fParameters[i].first == parName) {
66  found = true;
67  if (!parName.compare("delaytbm")) {
68  PixUtil::replaceAll(sval, "checkbox(", "");
69  PixUtil::replaceAll(sval, ")", "");
70  fParDelayTBM = !(atoi(sval.c_str()) == 0);
71  setToolTips();
72  }
73  if (!parName.compare("filltree")) {
74  PixUtil::replaceAll(sval, "checkbox(", "");
75  PixUtil::replaceAll(sval, ")", "");
76  fParFillTree = !(atoi(sval.c_str()) == 0);
77  setToolTips();
78  }
79  if (!parName.compare("clockstretch")) { //debug - useful?
80  fParStretch = atoi(sval.c_str());
81  setToolTips();
82  }
83  if (!parName.compare("trgfrequency(khz)")){ // trigger frequency in kHz.
84  fParTriggerFrequency = atoi(sval.c_str());
85  if (fParTriggerFrequency == 0) {
86  LOG(logWARNING) << "PixTestDaq::setParameter() trgfrequency must be different from zero";
87  found = false; fParOutOfRange = true;
88  }
89  }
90  if (!parName.compare("trgnumber")) {
91  fParNtrig = atoi(sval.c_str());
92  setToolTips();
93  }
94  if (!parName.compare("iterations")) {
95  fParIter = atoi(sval.c_str());
96  setToolTips();
97  }
98  if (!parName.compare("daqseconds")){
99  fParSeconds = atoi(sval.c_str());
100  }
101  }
102  }
103  return found;
104 }
105 
106 // ----------------------------------------------------------------------
107 void PixTestDaq::doStop(){
108  // Interrupt the test
109  fDaq_loop = false;
110  LOG(logINFO) << "Stop pressed. Ending test.";
111 }
112 
113 // ----------------------------------------------------------------------
114 void PixTestDaq::doRunMaskHotPixels() {
115  PixTest::update();
116  vector<TH2D*> v = mapsWithString(fHitMap, "hotpixels");
117  if (0 == v.size()) {
118  bookHist("hotpixels");
119  v = mapsWithString(fHitMap, "hotpixels");
120  }
121  for (unsigned int i = 0; i < v.size(); ++i) v[i]->Reset();
122  maskHotPixels(v);
123  // -- display
124  fDisplayedHist = find(fHistList.begin(), fHistList.end(), v[0]);
125  v[0]->Draw("colz");
126  PixTest::update();
127  return;
128 }
129 
130 // ----------------------------------------------------------------------
131 void PixTestDaq::runCommand(std::string command) {
132 
133  if (command == "stop")
134  doStop();
135  else if (!command.compare("maskhotpixels")) {
136  doRunMaskHotPixels();
137  return;
138  }
139  else if (!command.compare("rundaqtrg")) {
140  fRunDaqTrigger = true;
141  doDaqRun();
142  }
143  else if (!command.compare("rundaqseconds")) {
144  fRunDaqTrigger = false;
145  doDaqRun();
146  }
147  else
148  LOG(logINFO) << "Command " << command << " not implemented.";
149 }
150 
151 // ----------------------------------------------------------------------
152 void PixTestDaq::bookHist(string /*name*/) {
153 
154  if (fParFillTree) bookTree();
155  fHitMap.clear(); fPhmap.clear(); fPh.clear(); fQmap.clear(); fQ.clear();
156 
157  std::vector<uint8_t> rocIds = fApi->_dut->getEnabledRocIDs();
158  TH1D *h1(0);
159  TH2D *h2(0);
160  TProfile2D *p2(0);
161  for (unsigned int iroc = 0; iroc < rocIds.size(); ++iroc){
162  h2 = bookTH2D(Form("hits_C%d", rocIds[iroc]), Form("hits_C%d", rocIds[iroc]), 52, 0., 52., 80, 0., 80.);
163  h2->SetMinimum(0.);
164  h2->SetDirectory(fDirectory);
165  setTitles(h2, "col", "row");
166  fHistOptions.insert(make_pair(h2, "colz"));
167  fHitMap.push_back(h2);
168 
169  p2 = bookTProfile2D(Form("phMap_C%d", rocIds[iroc]), Form("phMap_C%d", rocIds[iroc]), 52, 0., 52., 80, 0., 80.);
170  p2->SetMinimum(0.);
171  p2->SetDirectory(fDirectory);
172  setTitles(p2, "col", "row");
173  fHistOptions.insert(make_pair(p2, "colz"));
174  fPhmap.push_back(p2);
175 
176  h1 = bookTH1D(Form("ph_C%d", rocIds[iroc]), Form("ph_C%d", rocIds[iroc]), 256, 0., 256.);
177  h1->SetMinimum(0.);
178  h1->SetDirectory(fDirectory);
179  setTitles(h1, "ADC", "Entries/bin");
180  fPh.push_back(h1);
181 
182  p2 = bookTProfile2D(Form("qMap_C%d", rocIds[iroc]), Form("qMap_C%d", rocIds[iroc]), 52, 0., 52., 80, 0., 80.);
183  p2->SetMinimum(0.);
184  p2->SetDirectory(fDirectory);
185  setTitles(p2, "col", "row");
186  fHistOptions.insert(make_pair(p2, "colz"));
187  fQmap.push_back(p2);
188 
189  h1 = bookTH1D(Form("q_C%d", rocIds[iroc]), Form("q_C%d", rocIds[iroc]), 200, 0., 1000.);
190  h1->SetMinimum(0.);
191  h1->SetDirectory(fDirectory);
192  setTitles(h1, "Q [Vcal]", "Entries/bin");
193  fQ.push_back(h1);
194  }
195 }
196 
197 // ----------------------------------------------------------------------
198 void PixTestDaq::ProcessData(uint16_t numevents){
199 
200  LOG(logDEBUG) << "Getting Event Buffer";
201  std::vector<pxar::Event> daqdat;
202 
203  if (numevents > 0) {
204  for (unsigned int i = 0; i < numevents; i++) {
205  pxar::Event evt = fApi->daqGetEvent();
206  //Check if event is empty?
207  if (evt.pixels.size() > 0)
208  daqdat.push_back(evt);
209  }
210  }
211  else
212  daqdat = fApi->daqGetEventBuffer();
213 
214  LOG(logDEBUG) << "Processing Data: " << daqdat.size() << " events.";
215 
216  int pixCnt(0);
217  int idx(-1);
218  uint16_t q;
219  vector<uint8_t> rocIds = fApi->_dut->getEnabledRocIDs();
220  for (std::vector<pxar::Event>::iterator it = daqdat.begin(); it != daqdat.end(); ++it) {
221  pixCnt += it->pixels.size();
222 
223  if (fParFillTree) {
224  bookTree();
225  fTreeEvent.header = it->header;
226  fTreeEvent.dac = 0;
227  fTreeEvent.trailer = it->trailer;
228  }
229 
230  for (unsigned int ipix = 0; ipix < it->pixels.size(); ++ipix) {
231  idx = getIdxFromId(it->pixels[ipix].roc());
232  if(idx == -1) {
233  LOG(logWARNING) << "PixTestDaq::ProcessData() wrong 'idx' value --> return";
234  return;
235  }
236  fHitMap[idx]->Fill(it->pixels[ipix].column(), it->pixels[ipix].row());
237  fPhmap[idx]->Fill(it->pixels[ipix].column(), it->pixels[ipix].row(), it->pixels[ipix].value());
238  fPh[idx]->Fill(it->pixels[ipix].value());
239 
240  if (fPhCalOK) {
241  q = static_cast<uint16_t>(fPhCal.vcal(it->pixels[ipix].roc(), it->pixels[ipix].column(),
242  it->pixels[ipix].row(), it->pixels[ipix].value()));
243  }
244  else {
245  q = 0;
246  }
247  fQ[idx]->Fill(q);
248  fQmap[idx]->Fill(it->pixels[ipix].column(), it->pixels[ipix].row(), q);
249  if (fParFillTree && ipix < 20000) {
250  ++fTreeEvent.npix;
251  fTreeEvent.proc[ipix] = it->pixels[ipix].roc();
252  fTreeEvent.pcol[ipix] = it->pixels[ipix].column();
253  fTreeEvent.prow[ipix] = it->pixels[ipix].row();
254  fTreeEvent.pval[ipix] = it->pixels[ipix].value();
255  fTreeEvent.pq[ipix] = q;
256  }
257  }
258  if (fParFillTree) fTree->Fill();
259  }
260 
261  //to draw the hitsmap as 'online' check.
262  TH2D* h2 = (TH2D*)(fHitMap.back());
263  h2->Draw(getHistOption(h2).c_str());
264  fDisplayedHist = find(fHistList.begin(), fHistList.end(), h2);
265  PixTest::update();
266 
267  LOG(logINFO) << Form("events read:%5ld, pixels seen:%3d, hist entries: %4d",
268  daqdat.size(), pixCnt, static_cast<int>(fHitMap[0]->GetEntries()));
269 }
270 
271 // ----------------------------------------------------------------------
272 void PixTestDaq::doDaqRun() {
273 
274  PixTest::update();
275  fDirectory->cd();
276 
277  //Immediately stop if parameters not in range
278  if (fParOutOfRange) return;
279 
280  banner(Form("PixTestDaq::doDaqRun() start.") );
281 
282  //Set the ClockStretch
283  fApi->setClockStretch(0, 0, fParStretch); //Stretch after trigger, 0 delay //debug - needed?
284 
285  //Set the histograms:
286  if(fHistList.size() == 0) bookHist("daq"); //to book histo only for the first 'doTest' (or after Clear).
287 
288  // -- unmask entire chip and then mask hot pixels
289  fApi->_dut->testAllPixels(false);
290  fApi->_dut->maskAllPixels(false);
291  for (unsigned int i = 0; i < fHotPixels.size(); ++i) {
292  vector<pair<int, int> > hot = fHotPixels[i];
293  for (unsigned int ipix = 0; ipix < hot.size(); ++ipix) {
294  LOG(logINFO) << "ROC " << getIdFromIdx(i) << " masking hot pixel " << hot[ipix].first << "/" << hot[ipix].second;
295  fApi->_dut->maskPixel(hot[ipix].first, hot[ipix].second, true, getIdFromIdx(i));
296  }
297  }
298  maskPixels();
299 
300  //To print summary of the number of masked pixels per ROC:
301  vector<uint8_t> rocIds = fApi->_dut->getEnabledRocIDs();
302  LOG(logINFO) << "PixTestDaq:: Number of masked pixels:";
303  for (unsigned int iroc = 0; iroc < rocIds.size(); ++iroc) {
304  LOG(logINFO) << "PixTestDaq:: " << fApi->_dut->getNMaskedPixels(static_cast<int>(iroc)) << " - ROC " << static_cast<int>(iroc);
305  }
306 
307  // Start the DAQ:
308  //::::::::::::::::::::::::::::::::
309 
310  int totalPeriod = prepareDaq(fParTriggerFrequency, 50); //new common function defined in PixTest.cc
311 
312  //Set the pattern wrt the trigger frequency:
313  LOG(logINFO) << "PG set to have trigger frequency = " << fParTriggerFrequency << " kHz";
314 
315  if (fParDelayTBM) {
316  LOG(logINFO) << "set TBM register delays = 0x40";
317  fApi->setTbmReg("delays", 0x40);
318  }
319 
320  //Start the DAQ:
321  fDaq_loop = true;
322  fApi->daqStart();
323 
324  //Using number of triggers
325  if (fRunDaqTrigger) {
326  LOG(logINFO) << "Sending " << fParNtrig << " triggers for " << fParIter << " iterations.";
327  for (int i = 0; i < fParIter && fDaq_loop; i++) { //Send fParNtrig for fParIter
328  fApi->daqTrigger(fParNtrig, totalPeriod);
329  gSystem->ProcessEvents();
330  ProcessData(0);
331  }
332  fApi->daqStop();
333 
334  } else { //Use seconds
335 
336  //Start trigger loop + buffer fill management:
337  int finalPeriod = fApi->daqTriggerLoop(totalPeriod);
338  LOG(logINFO) << "PixTestDaq:: start TriggerLoop with period " << finalPeriod << " and duration " << fParSeconds << " seconds";
339 
340  //To control the buffer filling
341  uint8_t perFull;
342  uint64_t diff = 0, timepaused = 0, timeff = 0;
343  timer t;
344  bool TotalTime = false;
345 
346  while (fDaq_loop){ //Check every n seconds if buffer is full less then 80%
347  while (fApi->daqStatus(perFull) && perFull < 80 && fDaq_loop) { //Pause and drain the buffer if almost full.
348  timeff = t.get() - timepaused;
349  if (timeff / 1000 >= fParSeconds) {
350  fDaq_loop = false;
351  TotalTime = true;
352  break;
353  }
354  LOG(logDEBUG) << "buffer not full, at " << (int)perFull << "%";
355  gSystem->ProcessEvents();
356  }
357  if (fDaq_loop){
358  LOG(logINFO) << "Elapsed time: " << timeff / 1000 << " seconds.";
359  LOG(logINFO) << "Buffer almost full, pausing triggers.";
361  diff = t.get();
362  ProcessData(0);
363  diff = t.get() - diff;
364  timepaused += diff;
365  LOG(logDEBUG) << "Readout time: " << timepaused / 1000 << " seconds.";
366  LOG(logINFO) << "Resuming triggers for " << fParSeconds - (timeff/1000) << " seconds.";
367  fApi->daqTriggerLoop(finalPeriod);
368  }
369  else {
370  if (TotalTime) { LOG(logINFO) << "PixTestDaq:: total time reached - DAQ stopped."; }
371  fApi->daqStop();
372  ProcessData(0);
373  }
374  }
375  }
376  //::::::::::::::::::::::::::::::
377  //DAQ - THE END.
378 
379  //to draw and save histograms //debug - needed all?
380  TH1D *h1(0);
381  TH2D *h2(0);
382  TProfile2D *p2(0);
383  copy(fQ.begin(), fQ.end(), back_inserter(fHistList));
384  copy(fQmap.begin(), fQmap.end(), back_inserter(fHistList));
385  copy(fPh.begin(), fPh.end(), back_inserter(fHistList));
386  copy(fPhmap.begin(), fPhmap.end(), back_inserter(fHistList));
387  copy(fHitMap.begin(), fHitMap.end(), back_inserter(fHistList));
388  for (list<TH1*>::iterator il = fHistList.begin(); il != fHistList.end(); ++il) {
389  (*il)->Draw((getHistOption(*il)).c_str());
390  }
391  fDisplayedHist = find(fHistList.begin(), fHistList.end(), h1);
392  fDisplayedHist = find(fHistList.begin(), fHistList.end(), p2);
393  fDisplayedHist = find(fHistList.begin(), fHistList.end(), h1);
394  fDisplayedHist = find(fHistList.begin(), fHistList.end(), p2);
395  fDisplayedHist = find(fHistList.begin(), fHistList.end(), h2);
396  PixTest::update();
397 
398  finalCleanup();
399  fApi->setClockStretch(0, 0, 0); //No Stretch after trigger, 0 delay
400  LOG(logINFO) << "PixTestDaq::doDaqRun() done";
401 }
402 
403 // ----------------------------------------------------------------------
405  LOG(logINFO) << "PixTestDaq::doTest() start.";
406  fRunDaqTrigger = false; //use daqTriggerLoop() as default for doTest
407  doDaqRun();
408  LOG(logINFO) << "PixTestDaq::doTest() done";
409 }
uint16_t prepareDaq(int triggerFreq, uint8_t trgTkDel)
set up DAQ (including call to setTriggerFrequency)
Definition: PixTest.cc:1799
static void replaceAll(std::string &str, const std::string &from, const std::string &to)
in str, replace all occurences of from to to
Definition: PixUtil.cc:24
size_t getNMaskedPixels(uint8_t rocid)
Definition: dut.cc:59
bool daqStart()
Definition: api.cc:1139
std::map< TH1 *, std::string > fHistOptions
options can be stored with each histogram
Definition: PixTest.hh:308
void daqTriggerLoopHalt()
Definition: api.cc:1257
void setToolTips()
implement this to provide updated tool tips if the user changes test parameters
Definition: PixTestDaq.cc:53
std::string fStopTip
information for this test
Definition: PixTest.hh:300
void doTest()
function connected to "DoTest" button of PixTab
Definition: PixTestDaq.cc:404
void runCommand(std::string command)
allow execution of any button in the test
Definition: PixTestDaq.cc:131
std::vector< TH1 * > mapsWithString(std::vector< TH1 * >, std::string name)
return a list of TH* that have 'name' as part to their histogram name
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 maskAllPixels(bool mask, uint8_t rocid)
Definition: dut.cc:481
void maskHotPixels(std::vector< TH2D * >)
determine hot pixels with high occupancy
Definition: PixTest.cc:1837
TDirectory * fDirectory
where the root histograms will end up
Definition: PixTest.hh:306
uint16_t daqTriggerLoop(uint16_t period=1000)
Definition: api.cc:1239
void bookTree()
book a minimal tree with pixel events
Definition: PixTest.cc:99
dut * _dut
Definition: api.h:728
Event daqGetEvent()
Definition: api.cc:1300
std::vector< uint8_t > getEnabledRocIDs()
Definition: dut.cc:214
void finalCleanup()
functions for DAQ
Definition: PixTest.cc:1765
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
bool setTbmReg(std::string regName, uint8_t regValue, uint8_t tbmid)
Definition: api.cc:633
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
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
virtual bool setParameter(std::string parName, std::string sval)
set the string value of a parameter
Definition: PixTestDaq.cc:60
void setClockStretch(uint8_t src, uint16_t delay, uint16_t width)
Definition: api.cc:2215
pxar::pxarCore * fApi
pointer to the API
Definition: PixTest.hh:289
std::vector< Event > daqGetEventBuffer()
Definition: api.cc:1285
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 maskPixels()
mask all pixels mentioned in the mask file
Definition: PixTest.cc:1741
bool daqStatus()
Definition: api.cc:1191
int getIdFromIdx(int idx)
provide the mapping between ROC ID and index
Definition: PixTest.cc:1114