CMS 3D CMS Logo

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