CMS 3D CMS Logo

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