CMS 3D CMS Logo

EcalLaserAnalyzer2.cc
Go to the documentation of this file.
1 /*
2  * \class EcalLaserAnalyzer2
3  * primary author: Julie Malcles - CEA/Saclay
4  * author: Gautier Hamel De Monchenault - CEA/Saclay
5  */
6 
7 #include <TAxis.h>
8 #include <TH1.h>
9 #include <TProfile.h>
10 #include <TTree.h>
11 #include <TChain.h>
12 #include <TFile.h>
13 #include <TMath.h>
14 
16 
17 #include <sstream>
18 #include <iostream>
19 #include <iomanip>
20 #include <fstream>
21 
24 
27 
30 
38 
39 #include <vector>
40 
52 
53 using namespace std;
54 
55 //========================================================================
57  //========================================================================
58  : iEvent(0),
59 
60  // framework parameters with default values
61  _nsamples(iConfig.getUntrackedParameter<unsigned int>("nSamples", 10)),
62  _presample(iConfig.getUntrackedParameter<unsigned int>("nPresamples", 2)),
63  _firstsample(iConfig.getUntrackedParameter<unsigned int>("firstSample", 1)),
64  _lastsample(iConfig.getUntrackedParameter<unsigned int>("lastSample", 2)),
65  _nsamplesPN(iConfig.getUntrackedParameter<unsigned int>("nSamplesPN", 50)),
66  _presamplePN(iConfig.getUntrackedParameter<unsigned int>("nPresamplesPN", 6)),
67  _firstsamplePN(iConfig.getUntrackedParameter<unsigned int>("firstSamplePN", 7)),
68  _lastsamplePN(iConfig.getUntrackedParameter<unsigned int>("lastSamplePN", 8)),
69  _timingcutlow(iConfig.getUntrackedParameter<unsigned int>("timingCutLow", 2)),
70  _timingcuthigh(iConfig.getUntrackedParameter<unsigned int>("timingCutHigh", 9)),
71  _timingquallow(iConfig.getUntrackedParameter<unsigned int>("timingQualLow", 3)),
72  _timingqualhigh(iConfig.getUntrackedParameter<unsigned int>("timingQualHigh", 8)),
73  _ratiomincutlow(iConfig.getUntrackedParameter<double>("ratioMinCutLow", 0.4)),
74  _ratiomincuthigh(iConfig.getUntrackedParameter<double>("ratioMinCutHigh", 0.95)),
75  _ratiomaxcutlow(iConfig.getUntrackedParameter<double>("ratioMaxCutLow", 0.8)),
76  _presamplecut(iConfig.getUntrackedParameter<double>("presampleCut", 5.0)),
77  _niter(iConfig.getUntrackedParameter<unsigned int>("nIter", 5)),
78  _noise(iConfig.getUntrackedParameter<double>("noise", 2.0)),
79  _ecalPart(iConfig.getUntrackedParameter<std::string>("ecalPart", "EB")),
80  _saveshapes(iConfig.getUntrackedParameter<bool>("saveShapes", true)),
81  _docorpn(iConfig.getUntrackedParameter<bool>("doCorPN", false)),
82  _fedid(iConfig.getUntrackedParameter<int>("fedID", -999)),
83  _saveallevents(iConfig.getUntrackedParameter<bool>("saveAllEvents", false)),
84  _qualpercent(iConfig.getUntrackedParameter<double>("qualPercent", 0.2)),
85  _debug(iConfig.getUntrackedParameter<int>("debug", 0)),
86  nCrys(NCRYSEB),
87  nPNPerMod(NPNPERMOD),
88  nMod(NMODEB),
89  nSides(NSIDES),
90  nSamplesShapes(NSAMPSHAPES),
91  IsMatacqOK(false),
92  runType(-1),
93  runNum(0),
94  towerID(-1),
95  channelID(-1),
96  fedID(-1),
97  dccID(-1),
98  side(2),
99  lightside(2),
100  iZ(1),
101  phi(-1),
102  eta(-1),
103  event(0),
104  color(0),
105  pn0(0),
106  pn1(0),
107  apdAmpl(0),
108  apdTime(0),
109  pnAmpl(0),
110  pnID(-1),
111  moduleID(-1),
112  flag(0),
113  channelIteratorEE(0),
114  ShapeCor(0)
115 
116 //========================================================================
117 
118 {
119  // Initialization from cfg file
120 
121  resdir_ = iConfig.getUntrackedParameter<std::string>("resDir");
122  elecfile_ = iConfig.getUntrackedParameter<std::string>("elecFile");
123  pncorfile_ = iConfig.getUntrackedParameter<std::string>("pnCorFile");
124 
125  digiCollection_ = iConfig.getParameter<std::string>("digiCollection");
126  digiPNCollection_ = iConfig.getParameter<std::string>("digiPNCollection");
127  digiProducer_ = iConfig.getParameter<std::string>("digiProducer");
128 
129  eventHeaderCollection_ = iConfig.getParameter<std::string>("eventHeaderCollection");
130  eventHeaderProducer_ = iConfig.getParameter<std::string>("eventHeaderProducer");
131 
132  // Geometrical constants initialization
133  if (_ecalPart == "EB") {
134  nCrys = NCRYSEB;
135  } else {
136  nCrys = NCRYSEE;
137  }
138  iZ = 1;
139  if (_fedid <= 609)
140  iZ = -1;
142  nMod = modules.size();
143  nRefChan = NREFCHAN;
144 
145  for (unsigned int j = 0; j < nCrys; j++) {
146  iEta[j] = -1;
147  iPhi[j] = -1;
148  iModule[j] = 10;
149  iTowerID[j] = -1;
150  iChannelID[j] = -1;
151  idccID[j] = -1;
152  iside[j] = -1;
153  wasTimingOK[j] = true;
154  wasGainOK[j] = true;
155  }
156 
157  for (unsigned int j = 0; j < nMod; j++) {
158  int ii = modules[j];
159  firstChanMod[ii - 1] = 0;
160  isFirstChanModFilled[ii - 1] = 0;
161  }
162 
163  // Quality check flags
164 
165  isGainOK = true;
166  isTimingOK = true;
167 
168  // PN linearity corrector
169 
170  pnCorrector = new TPNCor(pncorfile_);
171 
172  // Objects dealing with pulses
173 
175  _presample,
176  _firstsample,
177  _lastsample,
186 
187  // Object dealing with MEM numbering
188 
189  Mem = new TMem(_fedid);
190 
191  // Objects needed for npresample calculation
192 
193  Delta01 = new TMom();
194  Delta12 = new TMom();
195 }
196 
197 //========================================================================
199  //========================================================================
200 
201  // do anything here that needs to be done at desctruction time
202  // (e.g. close files, deallocate resources etc.)
203 }
204 
205 //========================================================================
207  //========================================================================
208 
209  // Create temporary files and trees to save adc samples
210  //======================================================
211 
212  ADCfile = resdir_;
213  ADCfile += "/APDSamplesLaser.root";
214 
215  APDfile = resdir_;
216  APDfile += "/APDPNLaserAllEvents.root";
217 
218  ADCFile = new TFile(ADCfile.c_str(), "RECREATE");
219 
220  for (unsigned int i = 0; i < nCrys; i++) {
221  stringstream name;
222  name << "ADCTree" << i + 1;
223  ADCtrees[i] = new TTree(name.str().c_str(), name.str().c_str());
224 
225  ADCtrees[i]->Branch("iphi", &phi, "phi/I");
226  ADCtrees[i]->Branch("ieta", &eta, "eta/I");
227  ADCtrees[i]->Branch("towerID", &towerID, "towerID/I");
228  ADCtrees[i]->Branch("channelID", &channelID, "channelID/I");
229  ADCtrees[i]->Branch("dccID", &dccID, "dccID/I");
230  ADCtrees[i]->Branch("side", &side, "side/I");
231  ADCtrees[i]->Branch("event", &event, "event/I");
232  ADCtrees[i]->Branch("color", &color, "color/I");
233  ADCtrees[i]->Branch("adc", &adc, "adc[10]/D");
234  ADCtrees[i]->Branch("pn0", &pn0, "pn0/D");
235  ADCtrees[i]->Branch("pn1", &pn1, "pn1/D");
236 
237  ADCtrees[i]->SetBranchAddress("ieta", &eta);
238  ADCtrees[i]->SetBranchAddress("iphi", &phi);
239  ADCtrees[i]->SetBranchAddress("towerID", &towerID);
240  ADCtrees[i]->SetBranchAddress("channelID", &channelID);
241  ADCtrees[i]->SetBranchAddress("dccID", &dccID);
242  ADCtrees[i]->SetBranchAddress("side", &side);
243  ADCtrees[i]->SetBranchAddress("event", &event);
244  ADCtrees[i]->SetBranchAddress("color", &color);
245  ADCtrees[i]->SetBranchAddress("adc", adc);
246  ADCtrees[i]->SetBranchAddress("pn0", &pn0);
247  ADCtrees[i]->SetBranchAddress("pn1", &pn1);
248  }
249 
250  // Define output results filenames
251  //==================================
252  stringstream namefile1;
253  namefile1 << resdir_ << "/SHAPE_LASER.root";
254  shapefile = namefile1.str();
255 
256  stringstream namefile2;
257  namefile2 << resdir_ << "/APDPN_LASER.root";
258  resfile = namefile2.str();
259 
260  stringstream namefile3;
261  namefile3 << resdir_ << "/MATACQ.root";
262 
263  matfile = namefile3.str();
264 
265  // Get Pulse Shapes
266  //==================
267 
268  IsMatacqOK = getShapes();
269  if (!IsMatacqOK) {
270  cout << " ERROR! No matacq shape available: analysis aborted !" << endl;
271  return;
272  }
273 
274  // Laser events counter
275 
276  laserEvents = 0;
277 }
278 
279 //========================================================================
281  //========================================================================
282 
283  ++iEvent;
284 
285  // retrieving DCC header
287  const EcalRawDataCollection* DCCHeader = nullptr;
288  try {
290  DCCHeader = pDCCHeader.product();
291  } catch (std::exception& ex) {
292  std::cerr << "Error! can't get the product retrieving DCC header" << eventHeaderCollection_.c_str() << std::endl;
293  }
294 
295  //retrieving crystal data from Event
297  const EBDigiCollection* EBDigi = nullptr;
299  const EEDigiCollection* EEDigi = nullptr;
300 
301  if (_ecalPart == "EB") {
302  try {
304  EBDigi = pEBDigi.product();
305  } catch (std::exception& ex) {
306  std::cerr << "Error! can't get the product retrieving EB crystal data " << digiCollection_.c_str() << std::endl;
307  }
308  } else if (_ecalPart == "EE") {
309  try {
311  EEDigi = pEEDigi.product();
312  } catch (std::exception& ex) {
313  std::cerr << "Error! can't get the product retrieving EE crystal data " << digiCollection_.c_str() << std::endl;
314  }
315  } else {
316  cout << " Wrong ecalPart in cfg file " << endl;
317  return;
318  }
319 
320  // retrieving crystal PN diodes from Event
321 
323  const EcalPnDiodeDigiCollection* PNDigi = nullptr;
324  try {
326  PNDigi = pPNDigi.product();
327  } catch (std::exception& ex) {
328  std::cerr << "Error! can't get the product " << digiPNCollection_.c_str() << std::endl;
329  }
330 
331  // retrieving electronics mapping
333  const EcalElectronicsMapping* TheMapping = nullptr;
334  try {
335  c.get<EcalMappingRcd>().get(ecalmapping);
336  TheMapping = ecalmapping.product();
337  } catch (std::exception& ex) {
338  std::cerr << "Error! can't get the product EcalMappingRcd" << std::endl;
339  }
340 
341  // ====================================
342  // Decode Basic DCCHeader Information
343  // ====================================
344 
345  for (EcalRawDataCollection::const_iterator headerItr = DCCHeader->begin(); headerItr != DCCHeader->end();
346  ++headerItr) {
347  // Get run type and run number
348 
349  int fed = headerItr->fedId();
350  if (fed != _fedid && _fedid != -999)
351  continue;
352 
353  runType = headerItr->getRunType();
354  runNum = headerItr->getRunNumber();
355  event = headerItr->getLV1();
356 
357  dccID = headerItr->getDccInTCCCommand();
358  fedID = headerItr->fedId();
359  lightside = headerItr->getRtHalf();
360 
361  // Check fed corresponds to the DCC in TCC
362 
363  if (600 + dccID != fedID)
364  continue;
365 
366  // Cut on runType
367 
370  return;
371 
372  // Retrieve laser color and event number
373 
374  EcalDCCHeaderBlock::EcalDCCEventSettings settings = headerItr->getEventSettings();
375  color = settings.wavelength;
376  if (color < 0)
377  return;
378 
379  vector<int>::iterator iter = find(colors.begin(), colors.end(), color);
380  if (iter == colors.end()) {
381  colors.push_back(color);
382  cout << " new color found " << color << " " << colors.size() << endl;
383  }
384  }
385 
386  // Check Matacq shape exists
387 
388  if (!IsMatacqOK)
389  return;
390 
391  // Cut on fedID
392 
393  if (fedID != _fedid && _fedid != -999)
394  return;
395 
396  // Count laser events
397 
398  laserEvents++;
399 
400  // ======================
401  // Decode PN Information
402  // ======================
403 
404  TPNFit* pnfit = new TPNFit();
406 
407  double chi2pn = 0;
408  unsigned int samplemax = 0;
409  int pnGain = 0;
410 
411  map<int, vector<double> > allPNAmpl;
412  map<int, vector<double> > allPNGain;
413 
414  // Loop on PNs digis
415 
416  for (EcalPnDiodeDigiCollection::const_iterator pnItr = PNDigi->begin(); pnItr != PNDigi->end(); ++pnItr) {
417  EcalPnDiodeDetId pnDetId = EcalPnDiodeDetId((*pnItr).id());
418 
419  if (_debug == 1)
420  cout << "-- debug test -- Inside PNDigi - pnID=" << pnDetId.iPnId() << ", dccID=" << pnDetId.iDCCId() << endl;
421 
422  // Skip MEM DCC without relevant data
423 
424  bool isMemRelevant = Mem->isMemRelevant(pnDetId.iDCCId());
425  if (!isMemRelevant)
426  continue;
427 
428  // Loop on PN samples
429 
430  for (int samId = 0; samId < (*pnItr).size(); samId++) {
431  pn[samId] = (*pnItr).sample(samId).adc();
432  pnG[samId] = (*pnItr).sample(samId).gainId();
433  if (samId == 0)
434  pnGain = pnG[samId];
435  if (samId > 0)
436  pnGain = int(TMath::Max(pnG[samId], pnGain));
437  }
438 
439  if (pnGain != 1)
440  cout << "PN gain different from 1" << endl;
441 
442  // Calculate amplitude from pulse
443 
444  PNPulse->setPulse(pn);
446  samplemax = PNPulse->getMaxSample();
447  chi2pn = pnfit->doFit(samplemax, &pnNoPed[0]);
448  if (chi2pn == 101 || chi2pn == 102 || chi2pn == 103)
449  pnAmpl = 0.;
450  else
451  pnAmpl = pnfit->getAmpl();
452 
453  // Apply linearity correction
454 
455  double corr = 1.0;
456  if (_docorpn)
457  corr = pnCorrector->getPNCorrectionFactor(pnAmpl, pnGain);
458  pnAmpl *= corr;
459 
460  // Fill PN ampl vector
461 
462  allPNAmpl[pnDetId.iDCCId()].push_back(pnAmpl);
463 
464  if (_debug == 1)
465  cout << "-- debug -- Inside PNDigi - PNampl=" << pnAmpl << ", PNgain=" << pnGain << endl;
466  }
467 
468  // ===========================
469  // Decode EBDigis Information
470  // ===========================
471 
472  int adcGain = 0;
473 
474  if (EBDigi) {
475  // Loop on crystals
476  //===================
477 
478  for (EBDigiCollection::const_iterator digiItr = EBDigi->begin(); digiItr != EBDigi->end();
479  ++digiItr) { // Loop on crystals
480 
481  // Retrieve geometry
482  //===================
483 
484  EBDetId id_crystal(digiItr->id());
485  EBDataFrame df(*digiItr);
486  EcalElectronicsId elecid_crystal = TheMapping->getElectronicsId(id_crystal);
487 
488  int etaG = id_crystal.ieta(); // global
489  int phiG = id_crystal.iphi(); // global
490 
491  std::pair<int, int> LocalCoord = MEEBGeom::localCoord(etaG, phiG);
492 
493  int etaL = LocalCoord.first; // local
494  int phiL = LocalCoord.second; // local
495 
496  int strip = elecid_crystal.stripId();
497  int xtal = elecid_crystal.xtalId();
498 
499  int module = MEEBGeom::lmmod(etaG, phiG);
500  int tower = elecid_crystal.towerId();
501 
502  int apdRefTT = MEEBGeom::apdRefTower(module);
503 
504  std::pair<int, int> pnpair = MEEBGeom::pn(module);
505  unsigned int MyPn0 = pnpair.first;
506  unsigned int MyPn1 = pnpair.second;
507 
508  int lmr = MEEBGeom::lmr(etaG, phiG);
509  unsigned int channel = MEEBGeom::electronic_channel(etaL, phiL);
510  assert(channel < nCrys);
511 
512  setGeomEB(etaG, phiG, module, tower, strip, xtal, apdRefTT, channel, lmr);
513 
514  if (_debug == 1)
515  cout << "-- debug -- Inside EBDigi - towerID:" << towerID << " channelID:" << channelID << " module:" << module
516  << " modules:" << modules.size() << endl;
517 
518  // APD Pulse
519  //===========
520 
521  // Loop on adc samples
522 
523  for (unsigned int i = 0; i < (*digiItr).size(); ++i) {
524  EcalMGPASample samp_crystal(df.sample(i));
525  adc[i] = samp_crystal.adc();
526  adcG[i] = samp_crystal.gainId();
527  adc[i] *= adcG[i];
528  if (i == 0)
529  adcGain = adcG[i];
530  if (i > 0)
531  adcGain = TMath::Max(adcG[i], adcGain);
532  }
533 
535 
536  // Quality checks
537  //================
538 
539  if (adcGain != 1)
540  nEvtBadGain[channel]++;
541  if (!APDPulse->isTimingQualOK())
542  nEvtBadTiming[channel]++;
543  nEvtTot[channel]++;
544 
545  // Associate PN ampl
546  //===================
547 
548  int mem0 = Mem->Mem(lmr, 0);
549  int mem1 = Mem->Mem(lmr, 1);
550 
551  if (allPNAmpl[mem0].size() > MyPn0)
552  pn0 = allPNAmpl[mem0][MyPn0];
553  else
554  pn0 = 0;
555  if (allPNAmpl[mem1].size() > MyPn1)
556  pn1 = allPNAmpl[mem1][MyPn1];
557  else
558  pn1 = 0;
559 
560  // Fill if Pulse is fine
561  //=======================
562 
563  if (APDPulse->isPulseOK() && lightside == side) {
564  ADCtrees[channel]->Fill();
565 
568  }
569  }
570  } else if (EEDigi) {
571  // Loop on crystals
572  //===================
573 
574  for (EEDigiCollection::const_iterator digiItr = EEDigi->begin(); digiItr != EEDigi->end(); ++digiItr) {
575  // Retrieve geometry
576  //===================
577 
578  EEDetId id_crystal(digiItr->id());
579  EEDataFrame df(*digiItr);
580  EcalElectronicsId elecid_crystal = TheMapping->getElectronicsId(id_crystal);
581 
582  int etaG = id_crystal.iy();
583  int phiG = id_crystal.ix();
584 
585  int iX = (phiG - 1) / 5 + 1;
586  int iY = (etaG - 1) / 5 + 1;
587 
588  int tower = elecid_crystal.towerId();
589  int ch = elecid_crystal.channelId() - 1;
590 
591  int module = MEEEGeom::lmmod(iX, iY);
592  if (module >= 18 && side == 1)
593  module += 2;
594  int lmr = MEEEGeom::lmr(iX, iY, iZ);
595  int dee = MEEEGeom::dee(lmr);
596  int apdRefTT = MEEEGeom::apdRefTower(lmr, module);
597 
598  std::pair<int, int> pnpair = MEEEGeom::pn(dee, module);
599  unsigned int MyPn0 = pnpair.first;
600  unsigned int MyPn1 = pnpair.second;
601 
602  int hashedIndex = 100000 * eta + phi;
603  if (channelMapEE.count(hashedIndex) == 0) {
606  }
607  unsigned int channel = channelMapEE[hashedIndex];
608  assert(channel < nCrys);
609 
610  setGeomEE(etaG, phiG, iX, iY, iZ, module, tower, ch, apdRefTT, channel, lmr);
611 
612  if (_debug == 1)
613  cout << "-- debug -- Inside EEDigi - towerID:" << towerID << " channelID:" << channelID << " module:" << module
614  << " modules:" << modules.size() << endl;
615 
616  // APD Pulse
617  //===========
618 
619  if ((*digiItr).size() > 10)
620  cout << "SAMPLES SIZE > 10!" << (*digiItr).size() << endl;
621 
622  // Loop on adc samples
623 
624  for (unsigned int i = 0; i < (*digiItr).size(); ++i) {
625  EcalMGPASample samp_crystal(df.sample(i));
626  adc[i] = samp_crystal.adc();
627  adcG[i] = samp_crystal.gainId();
628  adc[i] *= adcG[i];
629 
630  if (i == 0)
631  adcGain = adcG[i];
632  if (i > 0)
633  adcGain = TMath::Max(adcG[i], adcGain);
634  }
635 
637 
638  // Quality checks
639  //================
640 
641  if (adcGain != 1)
642  nEvtBadGain[channel]++;
643  if (!APDPulse->isTimingQualOK())
644  nEvtBadTiming[channel]++;
645  nEvtTot[channel]++;
646 
647  // Associate PN ampl
648  //===================
649 
650  int mem0 = Mem->Mem(lmr, 0);
651  int mem1 = Mem->Mem(lmr, 1);
652 
653  if (allPNAmpl[mem0].size() > MyPn0)
654  pn0 = allPNAmpl[mem0][MyPn0];
655  else
656  pn0 = 0;
657  if (allPNAmpl[mem1].size() > MyPn1)
658  pn1 = allPNAmpl[mem1][MyPn1];
659  else
660  pn1 = 0;
661 
662  // Fill if Pulse is fine
663  //=======================
664 
665  if (APDPulse->isPulseOK() && lightside == side) {
666  ADCtrees[channel]->Fill();
667 
670  }
671  }
672  }
673 }
674 // analyze
675 
676 //========================================================================
678  //========================================================================
679 
680  if (!IsMatacqOK) {
681  cout << "\n\t+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+" << endl;
682  cout << "\t+=+ WARNING! NO MATACQ +=+" << endl;
683  cout << "\t+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+" << endl;
684  return;
685  }
686 
687  // Adjust channel numbers for EE
688  //===============================
689 
690  if (_ecalPart == "EE") {
691  nCrys = channelMapEE.size();
692  }
693 
694  // Set presamples number
695  //======================
696 
697  double delta01 = Delta01->getMean();
698  double delta12 = Delta12->getMean();
699  if (delta12 > _presamplecut) {
700  _presample = 2;
701  if (delta01 > _presamplecut)
702  _presample = 1;
703  }
704 
706 
707  // Don't do anything if there is no events
708  //=========================================
709 
710  if (laserEvents == 0) {
711  ADCFile->Close();
712  stringstream del;
713  del << "rm " << ADCfile;
714  system(del.str().c_str());
715  cout << " No Laser Events " << endl;
716  return;
717  }
718 
719  // Set quality flags for gains and timing
720  //=========================================
721 
722  double BadGainEvtPercentage = 0.0;
723  double BadTimingEvtPercentage = 0.0;
724 
725  int nChanBadGain = 0;
726  int nChanBadTiming = 0;
727 
728  for (unsigned int i = 0; i < nCrys; i++) {
729  if (nEvtTot[i] != 0) {
730  BadGainEvtPercentage = double(nEvtBadGain[i]) / double(nEvtTot[i]);
731  BadTimingEvtPercentage = double(nEvtBadTiming[i]) / double(nEvtTot[i]);
732  }
733  if (BadGainEvtPercentage > _qualpercent) {
734  wasGainOK[i] = false;
735  nChanBadGain++;
736  }
737  if (BadTimingEvtPercentage > _qualpercent) {
738  wasTimingOK[i] = false;
739  nChanBadTiming++;
740  }
741  }
742 
743  double BadGainChanPercentage = double(nChanBadGain) / double(nCrys);
744  double BadTimingChanPercentage = double(nChanBadTiming) / double(nCrys);
745 
746  if (BadGainChanPercentage > _qualpercent)
747  isGainOK = false;
748  if (BadTimingChanPercentage > _qualpercent)
749  isTimingOK = false;
750 
751  // Analyze adc samples to get amplitudes
752  //=======================================
753 
754  cout << "\n\t+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+" << endl;
755  cout << "\t+=+ Analyzing laser data: getting APD, PN, APD/PN, PN/PN +=+" << endl;
756 
757  if (!isGainOK)
758  cout << "\t+=+ ............................ WARNING! APD GAIN WAS NOT 1 +=+" << endl;
759  if (!isTimingOK)
760  cout << "\t+=+ ............................ WARNING! TIMING WAS BAD +=+" << endl;
761 
762  APDFile = new TFile(APDfile.c_str(), "RECREATE");
763 
764  int ieta, iphi;
765 
766  int flagfit;
767  for (unsigned int i = 0; i < nCrys; i++) {
768  stringstream name;
769  name << "APDTree" << i + 1;
770 
771  APDtrees[i] = new TTree(name.str().c_str(), name.str().c_str());
772 
773  //List of branches
774 
775  APDtrees[i]->Branch("event", &event, "event/I");
776  APDtrees[i]->Branch("color", &color, "color/I");
777  APDtrees[i]->Branch("iphi", &iphi, "iphi/I");
778  APDtrees[i]->Branch("ieta", &ieta, "ieta/I");
779  APDtrees[i]->Branch("side", &side, "side/I");
780  APDtrees[i]->Branch("dccID", &dccID, "dccID/I");
781  APDtrees[i]->Branch("towerID", &towerID, "towerID/I");
782  APDtrees[i]->Branch("channelID", &channelID, "channelID/I");
783  APDtrees[i]->Branch("apdAmpl", &apdAmpl, "apdAmpl/D");
784  APDtrees[i]->Branch("apdTime", &apdTime, "apdTime/D");
785  if (_saveallevents)
786  APDtrees[i]->Branch("adc", &adc, "adc[10]/D");
787  APDtrees[i]->Branch("flagfit", &flagfit, "flagfit/I");
788  APDtrees[i]->Branch("pn0", &pn0, "pn0/D");
789  APDtrees[i]->Branch("pn1", &pn1, "pn1/D");
790 
791  APDtrees[i]->SetBranchAddress("event", &event);
792  APDtrees[i]->SetBranchAddress("color", &color);
793  APDtrees[i]->SetBranchAddress("iphi", &iphi);
794  APDtrees[i]->SetBranchAddress("ieta", &ieta);
795  APDtrees[i]->SetBranchAddress("side", &side);
796  APDtrees[i]->SetBranchAddress("dccID", &dccID);
797  APDtrees[i]->SetBranchAddress("towerID", &towerID);
798  APDtrees[i]->SetBranchAddress("channelID", &channelID);
799  APDtrees[i]->SetBranchAddress("apdAmpl", &apdAmpl);
800  APDtrees[i]->SetBranchAddress("apdTime", &apdTime);
801  if (_saveallevents)
802  APDtrees[i]->SetBranchAddress("adc", adc);
803  APDtrees[i]->SetBranchAddress("flagfit", &flagfit);
804  APDtrees[i]->SetBranchAddress("pn0", &pn0);
805  APDtrees[i]->SetBranchAddress("pn1", &pn1);
806  }
807 
808  for (unsigned int iref = 0; iref < nRefChan; iref++) {
809  for (unsigned int imod = 0; imod < nMod; imod++) {
810  int jmod = modules[imod];
811 
812  stringstream nameref;
813  nameref << "refAPDTree" << imod << "_" << iref;
814 
815  RefAPDtrees[iref][jmod] = new TTree(nameref.str().c_str(), nameref.str().c_str());
816 
817  RefAPDtrees[iref][jmod]->Branch("eventref", &eventref, "eventref/I");
818  RefAPDtrees[iref][jmod]->Branch("colorref", &colorref, "colorref/I");
819  if (iref == 0)
820  RefAPDtrees[iref][jmod]->Branch("apdAmplA", &apdAmplA, "apdAmplA/D");
821  if (iref == 1)
822  RefAPDtrees[iref][jmod]->Branch("apdAmplB", &apdAmplB, "apdAmplB/D");
823 
824  RefAPDtrees[iref][jmod]->SetBranchAddress("eventref", &eventref);
825  RefAPDtrees[iref][jmod]->SetBranchAddress("colorref", &colorref);
826  if (iref == 0)
827  RefAPDtrees[iref][jmod]->SetBranchAddress("apdAmplA", &apdAmplA);
828  if (iref == 1)
829  RefAPDtrees[iref][jmod]->SetBranchAddress("apdAmplB", &apdAmplB);
830  }
831  }
832 
833  assert(colors.size() <= nColor);
834  unsigned int nCol = colors.size();
835 
836  // Declare PN stuff
837  //===================
838 
839  for (unsigned int iM = 0; iM < nMod; iM++) {
840  unsigned int iMod = modules[iM] - 1;
841  for (unsigned int ich = 0; ich < nPNPerMod; ich++) {
842  for (unsigned int icol = 0; icol < nCol; icol++) {
843  PNFirstAnal[iMod][ich][icol] = new TPN(ich);
844  PNAnal[iMod][ich][icol] = new TPN(ich);
845  }
846  }
847  }
848 
849  // Declare function for APD ampl fit
850  //===================================
851 
852  PulseFitWithShape* psfit = new PulseFitWithShape();
853 
854  for (unsigned int iCry = 0; iCry < nCrys; iCry++) {
855  for (unsigned int icol = 0; icol < nCol; icol++) {
856  // Declare APD stuff
857  //===================
858 
859  APDFirstAnal[iCry][icol] = new TAPD();
860  IsThereDataADC[iCry][icol] = 1;
861  stringstream cut;
862  cut << "color==" << colors.at(icol);
863  if (ADCtrees[iCry]->GetEntries(cut.str().c_str()) < 10)
864  IsThereDataADC[iCry][icol] = 0;
865  }
866 
867  unsigned int iMod = iModule[iCry] - 1;
868  assert(iMod <= nMod);
869 
870  if (isSPRFine)
872 
873  // Loop on events
874  //================
875 
876  Long64_t nbytes = 0, nb = 0;
877  for (Long64_t jentry = 0; jentry < ADCtrees[iCry]->GetEntriesFast(); jentry++) { // Loop on events
878  nb = ADCtrees[iCry]->GetEntry(jentry);
879  nbytes += nb;
880 
881  flagfit = 1;
882  apdAmpl = 0.0;
883  apdTime = 0.0;
884  ieta = eta;
885  iphi = phi;
886 
887  // Get back color
888 
889  unsigned int iCol = 0;
890  for (unsigned int i = 0; i < nCol; i++) {
891  if (color == colors[i]) {
892  iCol = i;
893  i = colors.size();
894  }
895  }
896 
897  // Amplitude calculation
898 
901 
902  if (isSPRFine && APDPulse->isPulseOK()) {
903  psfit->doFit(&adcNoPed[0]);
904  apdAmpl = psfit->getAmpl();
905  apdTime = psfit->getTime();
906 
907  } else {
908  apdAmpl = 0;
909  apdTime = 0;
910  flagfit = 0;
911  }
912 
913  if (_debug >= 1)
914  cout << "-- debug test -- endJob -- apdAmpl:" << apdAmpl << " apdTime:" << apdTime << endl;
915 
916  double pnmean;
917  if (pn0 < 10 && pn1 > 10) {
918  pnmean = pn1;
919  } else if (pn1 < 10 && pn0 > 10) {
920  pnmean = pn0;
921  } else
922  pnmean = 0.5 * (pn0 + pn1);
923 
924  if (_debug >= 1)
925  cout << "-- debug test -- endJob -- pnMean:" << pnmean << endl;
926 
927  // Fill PN stuff
928  //===============
929 
930  if (firstChanMod[iMod] == iCry && IsThereDataADC[iCry][iCol] == 1) {
931  for (unsigned int ichan = 0; ichan < nPNPerMod; ichan++) {
932  PNFirstAnal[iMod][ichan][iCol]->addEntry(pnmean, pn0, pn1);
933  }
934  }
935 
936  // Fill APD stuff
937  //================
938 
939  if (apdAmpl != 0.0)
940  APDFirstAnal[iCry][iCol]->addEntry(apdAmpl, pnmean, pn0, pn1, apdTime);
941  if (_debug >= 1)
942  cout << "-- debug test -- endJob -- filling APDTree" << endl;
943 
944  APDtrees[iCry]->Fill();
945 
946  // Fill reference trees
947  //=====================
948 
949  if (apdRefMap[0][iMod + 1] == iCry || apdRefMap[1][iMod + 1] == iCry) {
950  apdAmplA = 0.0;
951  apdAmplB = 0.0;
952  eventref = event;
953  colorref = color;
954 
955  for (unsigned int ir = 0; ir < nRefChan; ir++) {
956  if (_debug >= 1)
957  cout << "-- debug test -- ir:" << ir << " tt:" << towerID << " refmap:" << apdRefMap[ir][iMod + 1]
958  << " iCry:" << iCry << endl;
959 
960  if (apdRefMap[ir][iMod + 1] == iCry) {
961  if (_debug >= 1)
962  cout << "-- debug test -- cut passed " << endl;
963  if (ir == 0)
964  apdAmplA = apdAmpl;
965  else if (ir == 1)
966  apdAmplB = apdAmpl;
967  if (_debug >= 1)
968  cout << "-- debug test -- apdAmplA=" << apdAmplA << endl;
969  if (_debug >= 1)
970  cout << "-- debug test -- apdAmplB=" << apdAmplB << endl;
971  if (_debug >= 1)
972  cout << "-- debug test -- color=" << color << ", event:" << event << ", ir:" << ir
973  << " tt-1:" << towerID - 1 << endl;
974 
975  RefAPDtrees[ir][iMod + 1]->Fill();
976 
977  if (_debug >= 1)
978  cout << "-- debug test -- tree filled" << event << endl;
979  }
980  }
981  }
982  }
983  }
984 
985  delete psfit;
986 
987  ADCFile->Close();
988 
989  if (_debug == 1)
990  cout << "-- debug test -- endJob -- after apdAmpl Loop" << endl;
991 
992  // Remove temporary file
993  //=======================
994 
995  stringstream del;
996  del << "rm " << ADCfile;
997  system(del.str().c_str());
998 
999  // Create output trees
1000  //=====================
1001 
1002  resFile = new TFile(resfile.c_str(), "RECREATE");
1003 
1004  for (unsigned int iColor = 0; iColor < nCol; iColor++) {
1005  stringstream nametree;
1006  nametree << "APDCol" << colors.at(iColor);
1007  stringstream nametree2;
1008  nametree2 << "PNCol" << colors.at(iColor);
1009 
1010  restrees[iColor] = new TTree(nametree.str().c_str(), nametree.str().c_str());
1011  respntrees[iColor] = new TTree(nametree2.str().c_str(), nametree2.str().c_str());
1012 
1013  restrees[iColor]->Branch("iphi", &iphi, "iphi/I");
1014  restrees[iColor]->Branch("ieta", &ieta, "ieta/I");
1015  restrees[iColor]->Branch("side", &side, "side/I");
1016  restrees[iColor]->Branch("dccID", &dccID, "dccID/I");
1017  restrees[iColor]->Branch("moduleID", &moduleID, "moduleID/I");
1018  restrees[iColor]->Branch("towerID", &towerID, "towerID/I");
1019  restrees[iColor]->Branch("channelID", &channelID, "channelID/I");
1020  restrees[iColor]->Branch("APD", &APD, "APD[6]/D");
1021  restrees[iColor]->Branch("Time", &Time, "Time[6]/D");
1022  restrees[iColor]->Branch("APDoPN", &APDoPN, "APDoPN[6]/D");
1023  restrees[iColor]->Branch("APDoPNA", &APDoPNA, "APDoPNA[6]/D");
1024  restrees[iColor]->Branch("APDoPNB", &APDoPNB, "APDoPNB[6]/D");
1025  restrees[iColor]->Branch("APDoAPDA", &APDoAPDA, "APDoAPDA[6]/D");
1026  restrees[iColor]->Branch("APDoAPDB", &APDoAPDB, "APDoAPDB[6]/D");
1027  restrees[iColor]->Branch("ShapeCor", &ShapeCor, "ShapeCor/D");
1028  restrees[iColor]->Branch("flag", &flag, "flag/I");
1029 
1030  respntrees[iColor]->Branch("moduleID", &moduleID, "moduleID/I");
1031  respntrees[iColor]->Branch("pnID", &pnID, "pnID/I");
1032  respntrees[iColor]->Branch("PN", &PN, "PN[6]/D");
1033  respntrees[iColor]->Branch("PNoPN", &PNoPN, "PNoPN[6]/D");
1034  respntrees[iColor]->Branch("PNoPNA", &PNoPNA, "PNoPNA[6]/D");
1035  respntrees[iColor]->Branch("PNoPNB", &PNoPNB, "PNoPNB[6]/D");
1036 
1037  restrees[iColor]->SetBranchAddress("iphi", &iphi);
1038  restrees[iColor]->SetBranchAddress("ieta", &ieta);
1039  restrees[iColor]->SetBranchAddress("dccID", &dccID);
1040  restrees[iColor]->SetBranchAddress("moduleID", &moduleID);
1041  restrees[iColor]->SetBranchAddress("towerID", &towerID);
1042  restrees[iColor]->SetBranchAddress("channelID", &channelID);
1043  restrees[iColor]->SetBranchAddress("APD", APD);
1044  restrees[iColor]->SetBranchAddress("Time", Time);
1045  restrees[iColor]->SetBranchAddress("APDoPN", APDoPN);
1046  restrees[iColor]->SetBranchAddress("APDoPNA", APDoPNA);
1047  restrees[iColor]->SetBranchAddress("APDoPNB", APDoPNB);
1048  restrees[iColor]->SetBranchAddress("APDoAPDA", APDoAPDA);
1049  restrees[iColor]->SetBranchAddress("APDoAPDB", APDoAPDB);
1050  restrees[iColor]->SetBranchAddress("ShapeCor", &ShapeCor);
1051  restrees[iColor]->SetBranchAddress("flag", &flag);
1052 
1053  respntrees[iColor]->SetBranchAddress("moduleID", &moduleID);
1054  respntrees[iColor]->SetBranchAddress("pnID", &pnID);
1055  respntrees[iColor]->SetBranchAddress("PN", PN);
1056  respntrees[iColor]->SetBranchAddress("PNoPN", PNoPN);
1057  respntrees[iColor]->SetBranchAddress("PNoPNA", PNoPNA);
1058  respntrees[iColor]->SetBranchAddress("PNoPNB", PNoPNB);
1059  }
1060 
1061  // Set Cuts for PN stuff
1062  //=======================
1063 
1064  for (unsigned int iM = 0; iM < nMod; iM++) {
1065  unsigned int iMod = modules[iM] - 1;
1066 
1067  for (unsigned int ich = 0; ich < nPNPerMod; ich++) {
1068  for (unsigned int icol = 0; icol < nCol; icol++) {
1069  PNAnal[iMod][ich][icol]->setPNCut(PNFirstAnal[iMod][ich][icol]->getPN().at(0),
1070  PNFirstAnal[iMod][ich][icol]->getPN().at(1));
1071  }
1072  }
1073  }
1074 
1075  // Build ref trees indexes
1076  //========================
1077 
1078  for (unsigned int imod = 0; imod < nMod; imod++) {
1079  int jmod = modules[imod];
1080  if (RefAPDtrees[0][jmod]->GetEntries() != 0 && RefAPDtrees[1][jmod]->GetEntries() != 0) {
1081  RefAPDtrees[0][jmod]->BuildIndex("eventref");
1082  RefAPDtrees[1][jmod]->BuildIndex("eventref");
1083  }
1084  }
1085 
1086  // Final loop on crystals
1087  //=======================
1088 
1089  for (unsigned int iCry = 0; iCry < nCrys; iCry++) {
1090  unsigned int iMod = iModule[iCry] - 1;
1091 
1092  // Set cuts on APD stuff
1093  //=======================
1094 
1095  for (unsigned int iCol = 0; iCol < nCol; iCol++) {
1096  std::vector<double> lowcut;
1097  std::vector<double> highcut;
1098  double cutMin;
1099  double cutMax;
1100 
1101  cutMin = APDFirstAnal[iCry][iCol]->getAPD().at(0) - 2.0 * APDFirstAnal[iCry][iCol]->getAPD().at(1);
1102  if (cutMin < 0)
1103  cutMin = 0;
1104  cutMax = APDFirstAnal[iCry][iCol]->getAPD().at(0) + 2.0 * APDFirstAnal[iCry][iCol]->getAPD().at(1);
1105 
1106  lowcut.push_back(cutMin);
1107  highcut.push_back(cutMax);
1108 
1109  cutMin = APDFirstAnal[iCry][iCol]->getTime().at(0) - 2.0 * APDFirstAnal[iCry][iCol]->getTime().at(1);
1110  cutMax = APDFirstAnal[iCry][iCol]->getTime().at(0) + 2.0 * APDFirstAnal[iCry][iCol]->getTime().at(1);
1111  lowcut.push_back(cutMin);
1112  highcut.push_back(cutMax);
1113 
1114  APDAnal[iCry][iCol] = new TAPD();
1115  APDAnal[iCry][iCol]->setAPDCut(APDFirstAnal[iCry][iCol]->getAPD().at(0),
1116  APDFirstAnal[iCry][iCol]->getAPD().at(1));
1117  APDAnal[iCry][iCol]->setAPDoPNCut(APDFirstAnal[iCry][iCol]->getAPDoPN().at(0),
1118  APDFirstAnal[iCry][iCol]->getAPDoPN().at(1));
1119  APDAnal[iCry][iCol]->setAPDoPN0Cut(APDFirstAnal[iCry][iCol]->getAPDoPN0().at(0),
1120  APDFirstAnal[iCry][iCol]->getAPDoPN0().at(1));
1121  APDAnal[iCry][iCol]->setAPDoPN1Cut(APDFirstAnal[iCry][iCol]->getAPDoPN1().at(0),
1122  APDFirstAnal[iCry][iCol]->getAPDoPN1().at(1));
1123  APDAnal[iCry][iCol]->setTimeCut(APDFirstAnal[iCry][iCol]->getTime().at(0),
1124  APDFirstAnal[iCry][iCol]->getTime().at(1));
1125 
1126  APDAnal[iCry][iCol]->set2DAPDoAPD0Cut(lowcut, highcut);
1127  APDAnal[iCry][iCol]->set2DAPDoAPD1Cut(lowcut, highcut);
1128  }
1129 
1130  // Final loop on events
1131  //=======================
1132 
1133  Long64_t nbytes = 0, nb = 0;
1134  for (Long64_t jentry = 0; jentry < APDtrees[iCry]->GetEntriesFast(); jentry++) {
1135  nb = APDtrees[iCry]->GetEntry(jentry);
1136  nbytes += nb;
1137 
1138  double pnmean;
1139  if (pn0 < 10 && pn1 > 10) {
1140  pnmean = pn1;
1141  } else if (pn1 < 10 && pn0 > 10) {
1142  pnmean = pn0;
1143  } else
1144  pnmean = 0.5 * (pn0 + pn1);
1145 
1146  // Get back color
1147  //===============
1148 
1149  unsigned int iCol = 0;
1150  for (unsigned int i = 0; i < nCol; i++) {
1151  if (color == colors[i]) {
1152  iCol = i;
1153  i = colors.size();
1154  }
1155  }
1156 
1157  // Fill PN stuff
1158  //===============
1159 
1160  if (firstChanMod[iMod] == iCry && IsThereDataADC[iCry][iCol] == 1) {
1161  for (unsigned int ichan = 0; ichan < nPNPerMod; ichan++) {
1162  PNAnal[iMod][ichan][iCol]->addEntry(pnmean, pn0, pn1);
1163  }
1164  }
1165 
1166  // Get ref amplitudes
1167  //===================
1168 
1169  if (_debug >= 1)
1170  cout << "-- debug test -- LastLoop event:" << event << " apdAmpl:" << apdAmpl << endl;
1171  apdAmplA = 0.0;
1172  apdAmplB = 0.0;
1173 
1174  for (unsigned int iRef = 0; iRef < nRefChan; iRef++) {
1175  RefAPDtrees[iRef][iMod + 1]->GetEntryWithIndex(event);
1176  }
1177 
1178  if (_debug == 1)
1179  cout << "-- debug test -- LastLoop apdAmplA:" << apdAmplA << " apdAmplB:" << apdAmplB << ", event:" << event
1180  << ", eventref:" << eventref << endl;
1181 
1182  // Fill APD stuff
1183  //===============
1184 
1185  APDAnal[iCry][iCol]->addEntry(apdAmpl, pnmean, pn0, pn1, apdTime, apdAmplA, apdAmplB);
1186  }
1187 
1188  moduleID = iMod + 1;
1189 
1190  if (moduleID >= 20)
1191  moduleID -= 2; // Trick to fix endcap specificity
1192 
1193  // Get final results for APD
1194  //===========================
1195 
1196  for (unsigned int iColor = 0; iColor < nCol; iColor++) {
1197  std::vector<double> apdvec = APDAnal[iCry][iColor]->getAPD();
1198  std::vector<double> apdpnvec = APDAnal[iCry][iColor]->getAPDoPN();
1199  std::vector<double> apdpn0vec = APDAnal[iCry][iColor]->getAPDoPN0();
1200  std::vector<double> apdpn1vec = APDAnal[iCry][iColor]->getAPDoPN1();
1201  std::vector<double> timevec = APDAnal[iCry][iColor]->getTime();
1202  std::vector<double> apdapd0vec = APDAnal[iCry][iColor]->getAPDoAPD0();
1203  std::vector<double> apdapd1vec = APDAnal[iCry][iColor]->getAPDoAPD1();
1204 
1205  for (unsigned int i = 0; i < apdvec.size(); i++) {
1206  APD[i] = apdvec.at(i);
1207  APDoPN[i] = apdpnvec.at(i);
1208  APDoPNA[i] = apdpn0vec.at(i);
1209  APDoPNB[i] = apdpn1vec.at(i);
1210  APDoAPDA[i] = apdapd0vec.at(i);
1211  APDoAPDB[i] = apdapd1vec.at(i);
1212  Time[i] = timevec.at(i);
1214  }
1215 
1216  // Fill APD results trees
1217  //========================
1218 
1219  iphi = iPhi[iCry];
1220  ieta = iEta[iCry];
1221  dccID = idccID[iCry];
1222  towerID = iTowerID[iCry];
1223  side = iside[iCry];
1224  channelID = iChannelID[iCry];
1225 
1226  if (!wasGainOK[iCry] || !wasTimingOK[iCry] || IsThereDataADC[iCry][iColor] == 0)
1227  flag = 1;
1228  else
1229  flag = 0;
1230 
1231  if (_debug >= 1)
1232  cout << "-- debug test -- endJob -- APD[0]" << APD[0] << " APDoPN[0] " << APDoPN[0] << " APDoAPDA[0] "
1233  << APDoAPDA[0] << " flag " << flag << endl;
1234  restrees[iColor]->Fill();
1235  }
1236  }
1237 
1238  // Get final results for PN
1239  //==========================
1240 
1241  for (unsigned int iM = 0; iM < nMod; iM++) {
1242  unsigned int iMod = modules[iM] - 1;
1243 
1244  side = iside[firstChanMod[iMod]];
1245 
1246  for (unsigned int ch = 0; ch < nPNPerMod; ch++) {
1247  pnID = ch;
1248  moduleID = iMod + 1;
1249 
1250  if (moduleID >= 20)
1251  moduleID -= 2; // Trick to fix endcap specificity
1252 
1253  for (unsigned int iColor = 0; iColor < nCol; iColor++) {
1254  std::vector<double> pnvec = PNAnal[iMod][ch][iColor]->getPN();
1255  std::vector<double> pnopnvec = PNAnal[iMod][ch][iColor]->getPNoPN();
1256  std::vector<double> pnopn0vec = PNAnal[iMod][ch][iColor]->getPNoPN0();
1257  std::vector<double> pnopn1vec = PNAnal[iMod][ch][iColor]->getPNoPN1();
1258 
1259  for (unsigned int i = 0; i < pnvec.size(); i++) {
1260  PN[i] = pnvec.at(i);
1261  PNoPN[i] = pnopnvec.at(i);
1262  PNoPNA[i] = pnopn0vec.at(i);
1263  PNoPNB[i] = pnopn1vec.at(i);
1264  }
1265 
1266  if (_debug >= 1)
1267  cout << "-- debug test -- endJob -- filling pn results'tree: PN[0]:" << PN[0] << " iModule:" << iMod
1268  << " iColor:" << iColor << " ch:" << ch << endl;
1269 
1270  // Fill PN results trees
1271  //========================
1272 
1273  respntrees[iColor]->Fill();
1274  }
1275  }
1276  }
1277 
1278  // Remove temporary files
1279  //========================
1280 
1281  if (!_saveallevents) {
1282  APDFile->Close();
1283  stringstream del2;
1284  del2 << "rm " << APDfile;
1285  system(del2.str().c_str());
1286 
1287  } else {
1288  APDFile->cd();
1289  APDtrees[0]->Write();
1290  APDFile->Close();
1291  resFile->cd();
1292  }
1293 
1294  // Save results
1295  //===============
1296 
1297  for (unsigned int i = 0; i < nCol; i++) {
1298  restrees[i]->Write();
1299  respntrees[i]->Write();
1300  }
1301 
1302  resFile->Close();
1303 
1304  cout << "\t+=+ .................................................. done +=+" << endl;
1305  cout << "\t+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+" << endl;
1306 }
1307 
1308 //========================================================================
1310  //========================================================================
1311 
1312  // Get Pulse From Matacq Analysis:
1313  //================================
1314 
1315  bool IsMatacqOK = false;
1316 
1317  int doesMatFileExist = 0;
1318  int doesMatShapeExist = 0;
1319  FILE* test2;
1320  TProfile* laserShape = nullptr;
1321  test2 = fopen(matfile.c_str(), "r");
1322  if (test2)
1323  doesMatFileExist = 1;
1324 
1325  TFile* MatShapeFile;
1326  if (doesMatFileExist == 1) {
1327  MatShapeFile = new TFile(matfile.c_str());
1328  laserShape = (TProfile*)MatShapeFile->Get("shapeLaser");
1329  if (laserShape) {
1330  doesMatShapeExist = 1;
1331  double y = laserShape->Integral("w");
1332  if (y != 0)
1333  laserShape->Scale(1.0 / y);
1334  }
1335  } else {
1336  cout << " ERROR! Matacq shape file not found !" << endl;
1337  }
1338  if (doesMatShapeExist)
1339  IsMatacqOK = true;
1340 
1341  // Get SPR from the average elec shape in SM6:
1342  //============================================
1343 
1344  int doesElecFileExist = 0;
1345  FILE* test;
1346  test = fopen(elecfile_.c_str(), "r");
1347  if (test)
1348  doesElecFileExist = 1;
1349 
1350  TFile* ElecShapesFile;
1351  TH1D* elecShape = nullptr;
1352 
1353  if (doesElecFileExist == 1) {
1354  ElecShapesFile = new TFile(elecfile_.c_str());
1355  stringstream name;
1356  name << "MeanElecShape";
1357  elecShape = (TH1D*)ElecShapesFile->Get(name.str().c_str());
1358  if (elecShape && doesMatShapeExist == 1) {
1359  double x = elecShape->GetMaximum();
1360  if (x != 0)
1361  elecShape->Scale(1.0 / x);
1362  isSPRFine = true;
1363  } else {
1364  isSPRFine = false;
1365  }
1366 
1367  } else {
1368  cout << " ERROR! Elec shape file not found !" << endl;
1369  }
1370 
1371  if (IsMatacqOK) {
1372  ShapeFile = new TFile(shapefile.c_str(), "RECREATE");
1373 
1374  unsigned int nBins = int(laserShape->GetEntries());
1375  assert(nSamplesShapes == nBins);
1376  double elec_jj, laser_iiMinusjj;
1377  double sum_jj;
1378 
1379  if (isSPRFine == true) {
1380  unsigned int nBins2 = int(elecShape->GetNbinsX());
1381 
1382  if (nBins2 < nBins) {
1383  cout << "EcalLaserAnalyzer2::getShapes: wrong configuration of the shapes' number of bins" << std::endl;
1384  isSPRFine = false;
1385  }
1386  assert(nSamplesShapes == nBins2);
1387 
1388  stringstream name;
1389  name << "PulseShape";
1390 
1391  PulseShape = new TProfile(name.str().c_str(), name.str().c_str(), nBins, -0.5, double(nBins) - 0.5);
1392 
1393  // shift shapes to have max close to the real APD max
1394 
1395  for (int ii = 0; ii < 50; ii++) {
1396  shapes[ii] = 0.0;
1397  PulseShape->Fill(ii, 0.0);
1398  }
1399 
1400  for (unsigned int ii = 0; ii < nBins - 50; ii++) {
1401  sum_jj = 0.0;
1402  for (unsigned int jj = 0; jj < ii; jj++) {
1403  elec_jj = elecShape->GetBinContent(jj + 1);
1404  laser_iiMinusjj = laserShape->GetBinContent(ii - jj + 1);
1405  sum_jj += elec_jj * laser_iiMinusjj;
1406  }
1407  PulseShape->Fill(ii + 50, sum_jj);
1408  shapes[ii + 50] = sum_jj;
1409  }
1410 
1411  double scale = PulseShape->GetMaximum();
1413 
1414  if (scale != 0) {
1415  PulseShape->Scale(1.0 / scale);
1416  for (unsigned int ii = 0; ii < nBins; ii++) {
1417  shapesVec.push_back(shapes[ii] / scale);
1418  }
1419  }
1420 
1421  if (_saveshapes)
1422  PulseShape->Write();
1423  }
1424  }
1425  ShapeFile->Close();
1426 
1427  if (!_saveshapes) {
1428  stringstream del;
1429  del << "rm " << shapefile;
1430  system(del.str().c_str());
1431  }
1432 
1433  return IsMatacqOK;
1434 }
1435 
1437  int etaG, int phiG, int module, int tower, int strip, int xtal, int apdRefTT, int channel, int lmr) {
1438  side = MEEBGeom::side(etaG, phiG);
1439 
1440  assert(module >= *min_element(modules.begin(), modules.end()) &&
1441  module <= *max_element(modules.begin(), modules.end()));
1442 
1443  eta = etaG;
1444  phi = phiG;
1445  channelID = 5 * (strip - 1) + xtal - 1;
1446  towerID = tower;
1447 
1448  vector<int> apdRefChan = ME::apdRefChannels(module, lmr);
1449  for (unsigned int iref = 0; iref < nRefChan; iref++) {
1450  if (channelID == apdRefChan[iref] && towerID == apdRefTT && apdRefMap[iref].count(module) == 0) {
1451  apdRefMap[iref][module] = channel;
1452  }
1453  }
1454 
1455  if (isFirstChanModFilled[module - 1] == 0) {
1456  firstChanMod[module - 1] = channel;
1457  isFirstChanModFilled[module - 1] = 1;
1458  }
1459 
1460  iEta[channel] = eta;
1461  iPhi[channel] = phi;
1462  iModule[channel] = module;
1463  iTowerID[channel] = towerID;
1464  iChannelID[channel] = channelID;
1465  idccID[channel] = dccID;
1466  iside[channel] = side;
1467 }
1468 
1470  int etaG, int phiG, int iX, int iY, int iZ, int module, int tower, int ch, int apdRefTT, int channel, int lmr) {
1471  side = MEEEGeom::side(iX, iY, iZ);
1472 
1473  assert(module >= *min_element(modules.begin(), modules.end()) &&
1474  module <= *max_element(modules.begin(), modules.end()));
1475 
1476  eta = etaG;
1477  phi = phiG;
1478  channelID = ch;
1479  towerID = tower;
1480 
1481  vector<int> apdRefChan = ME::apdRefChannels(module, lmr);
1482  for (unsigned int iref = 0; iref < nRefChan; iref++) {
1483  if (channelID == apdRefChan[iref] && towerID == apdRefTT && apdRefMap[iref].count(module) == 0) {
1484  apdRefMap[iref][module] = channel;
1485  }
1486  }
1487 
1488  if (isFirstChanModFilled[module - 1] == 0) {
1489  firstChanMod[module - 1] = channel;
1490  isFirstChanModFilled[module - 1] = 1;
1491  }
1492 
1493  iEta[channel] = eta;
1494  iPhi[channel] = phi;
1495  iModule[channel] = module;
1496  iTowerID[channel] = towerID;
1497  iChannelID[channel] = channelID;
1498  idccID[channel] = dccID;
1499  iside[channel] = side;
1500 }
size
Write out results.
void addEntry(double val)
Definition: TMom.cc:88
static XYCoord localCoord(int icr)
Definition: MEEBGeom.cc:142
T getParameter(std::string const &) const
TPN * PNAnal[9][2][nColor]
T getUntrackedParameter(std::string const &, T const &) const
static int lmmod(SuperCrysCoord iX, SuperCrysCoord iY)
Definition: MEEEGeom.cc:112
void analyze(const edm::Event &e, const edm::EventSetup &c) override
Definition: TPN.h:8
void setAPDCut(double, double)
Definition: TAPD.cc:141
std::map< int, int > channelMapEE
int xtalId() const
get the channel id
std::vector< double > getPN()
Definition: TPN.cc:90
#define NSIDES
Definition: TAPD.h:8
static int apdRefTower(int ilmr, int ilmmod)
Definition: MEEEGeom.cc:1208
void addEntry(double, double, double)
Definition: TPN.cc:33
void beginJob() override
int stripId() const
get the tower id
double getDelta(int, int)
Definition: TAPDPulse.cc:116
TAPD * APDAnal[1700][nColor]
std::vector< double > getPNoPN1()
Definition: TPN.cc:102
Ecal readout channel identification [32:20] Unused (so far) [19:13] DCC id [12:6] tower [5:3] strip [...
#define NCRYSEE
bool setPulse(double *)
Definition: TAPDPulse.cc:86
TAPD * APDFirstAnal[1700][nColor]
static int side(SuperCrysCoord iX, SuperCrysCoord iY, int iz)
Definition: MEEEGeom.cc:1155
TPN * PNFirstAnal[9][2][nColor]
void setPNCut(double, double)
Definition: TPN.cc:70
void addEntry(double, double, double, double, double, double, double)
Definition: TAPD.cc:42
unsigned int _timingcuthigh
double getPNCorrectionFactor(double val0, int gain)
Definition: TPNCor.cc:64
std::vector< T >::const_iterator const_iterator
void init(int, int, int)
Definition: TPNFit.cc:24
int towerId() const
get the tower id
double * getAdcWithoutPedestal()
Definition: TPNPulse.cc:89
const_iterator begin() const
unsigned int isFirstChanModFilled[21]
void setGeomEE(int etaG, int phiG, int iX, int iY, int iZ, int module, int tower, int ch, int apdRefTT, int channel, int lmr)
static int lmr(EBGlobalCoord ieta, EBGlobalCoord iphi)
Definition: MEEBGeom.cc:110
Definition: TMom.h:7
unsigned int _timingquallow
std::string digiPNCollection_
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
bool setPulse(double *)
Definition: TPNPulse.cc:45
std::vector< double > getAPDoPN0()
Definition: TAPD.cc:224
void setTimeCut(double, double)
Definition: TAPD.cc:145
unsigned int _presamplePN
std::vector< double > shapesVec
static std::pair< int, int > pn(int ilmmod)
Definition: MEEBGeom.cc:447
void set2DAPDoAPD1Cut(const std::vector< double > &, const std::vector< double > &)
Definition: TAPD.cc:181
void setAPDoPN0Cut(double, double)
Definition: TAPD.cc:143
virtual double doFit(double *, double *cova=nullptr)
std::vector< double > getPNoPN0()
Definition: TPN.cc:98
std::vector< double > getAPDoPN1()
Definition: TAPD.cc:228
int iPnId() const
get the PnId
Definition: TMem.h:7
int hashedIndex(int ieta, int iphi)
Definition: EcalPyUtils.cc:38
EcalElectronicsId getElectronicsId(const DetId &id) const
Get the electronics id for this det id.
static std::pair< int, int > pn(int dee, int ilmod)
Definition: MEEEGeom.cc:574
int Mem(int, int)
Definition: TMem.cc:41
int iEvent
Definition: GenABIO.cc:224
std::vector< double > getAPDoAPD0()
Definition: TAPD.cc:236
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
void set2DAPDoAPD0Cut(const std::vector< double > &, const std::vector< double > &)
Definition: TAPD.cc:173
static int electronic_channel(EBLocalCoord ix, EBLocalCoord iy)
Definition: MEEBGeom.cc:326
virtual void init(int, int, int, int, int, const std::vector< double > &, double)
#define NCRYSEB
double getAmpl()
Definition: TPNFit.h:31
std::string eventHeaderCollection_
unsigned int _nsamplesPN
#define NMODEB
double * getAdcWithoutPedestal()
Definition: TAPDPulse.cc:237
EcalLaserAnalyzer2(const edm::ParameterSet &iConfig)
static int apdRefTower(int ilmmod)
Definition: MEEBGeom.cc:490
#define NREFCHAN
unsigned int _lastsample
int iDCCId() const
get the DCCId
static int lmmod(EBGlobalCoord ieta, EBGlobalCoord iphi)
Definition: MEEBGeom.cc:90
std::vector< double > getAPDoAPD1()
Definition: TAPD.cc:241
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:488
JetCorrectorParameters corr
Definition: classes.h:5
std::vector< double > getAPD()
Definition: TAPD.cc:216
ii
Definition: cuy.py:590
const_iterator end() const
T Max(T a, T b)
Definition: MathUtil.h:44
unsigned int firstChanMod[21]
#define NSAMPSHAPES
void setGeomEB(int etaG, int phiG, int module, int tower, int strip, int xtal, int apdRefTT, int channel, int lmr)
static int side(EBGlobalCoord ieta, EBGlobalCoord iphi)
Definition: MEEBGeom.cc:105
bool isTimingQualOK()
Definition: TAPDPulse.cc:145
T const * product() const
Definition: Handle.h:69
unsigned int nSamplesShapes
int IsThereDataADC[1700][nColor]
std::string digiCollection_
void endJob() override
TTree * respntrees[nColor]
TTree * RefAPDtrees[2][21]
#define NPNPERMOD
boost::transform_iterator< IterHelp, boost::counting_iterator< int > > const_iterator
unsigned int _firstsamplePN
const_iterator end() const
void setPresamples(int)
Definition: TAPDPulse.cc:251
bool isPulseOK()
Definition: TAPDPulse.cc:162
Definition: colors.py:1
TTree * restrees[nColor]
std::vector< double > getPNoPN()
Definition: TPN.cc:94
T get() const
Definition: EventSetup.h:73
Definition: TPNFit.h:8
static int dee(SuperCrysCoord iX, SuperCrysCoord iY, int iz)
Definition: MEEEGeom.cc:292
bool isMemRelevant(int)
Definition: TMem.cc:30
unsigned int _firstsample
int getMaxSample()
Definition: TPNPulse.cc:70
unsigned int _timingcutlow
unsigned int iModule[1700]
double doFit(int, double *)
Definition: TPNFit.cc:39
EcalLogicID towerID(EcalElectronicsId const &)
std::string eventHeaderProducer_
std::vector< double > getAPDoPN()
Definition: TAPD.cc:220
Definition: TPNCor.h:7
std::map< int, unsigned int > apdRefMap[2]
std::vector< double > getTime()
Definition: TAPD.cc:232
T const * product() const
Definition: ESHandle.h:86
Definition: vlib.h:198
unsigned int _timingqualhigh
static std::vector< int > apdRefChannels(ME::LMMid ilmmod, ME::LMRid ilmr)
Definition: ME.cc:545
unsigned int _lastsamplePN
static std::vector< ME::LMMid > lmmodFromDcc(ME::DCCid idcc)
Definition: ME.cc:574
double getMean()
Definition: TMom.cc:121
static int lmr(SuperCrysCoord iX, SuperCrysCoord iY, int iz)
Definition: MEEEGeom.cc:254
int channelId() const
so far for EndCap only :
const_iterator begin() const
void setAPDoPNCut(double, double)
Definition: TAPD.cc:142
Definition: event.py:1
void setAPDoPN1Cut(double, double)
Definition: TAPD.cc:144