ATLAS Offline Software
TileLaserTimingTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 // Athena includes
7 #include "CoralBase/Blob.h"
8 #include "CoralBase/AttributeListSpecification.h"
11 #include "StoreGate/ReadHandle.h"
12 
13 // Tile includes
14 #include "TileLaserTimingTool.h"
20 
21 #include "TFile.h"
22 #include "TTree.h"
23 #include "TF1.h"
24 #include "TObjArray.h"
25 #include <TROOT.h>
26 
27 #include <cmath>
28 
29 //const unsigned NPmts = 48;
30 
31 template<class _T> inline _T sqr(const _T &data) { return data * data; }
32 
33 inline int imax(int i, int j) { return i < j ? j : i; }
34 
36  : TimeDiffHisto(("pmt_dtime"+id).c_str(),("pmt_dtime"+id).c_str(),1200,-60,60)
37  , TimeDiffNoCFCorrHisto(("dtimeNoCorr"+id).c_str(),("dtimeNoCorr"+id).c_str(),1200,-60,60)
38 
39 #ifdef TileLaserTimingMon
40  , timeHisto(("time" + id).c_str(), ("time" + id).c_str(), 200, -100, 100)
41  , eneHisto(("energy" + id).c_str(), ("energy" + id).c_str(), 300, 0., 300.)
42  , gainHisto(("gain" + id).c_str(), ("gain" + id).c_str(), 2, 0, 2)
43 #endif
44 
45 #ifdef TileLaserTimingPMT0Mon
46  , TimeDiffHistoHigh(("dtime" + id + "hi").c_str(), ("dtime" + id + "hi").c_str(), 200, -40, 40)
47  , TimeDiffHistoLow(("dtime" + id + "lo").c_str(), ("dtime" + id + "lo").c_str(), 200, -60, 60)
48 #endif
49 
50 #ifdef TileLaserTimingMonPulse
51  , pulseShapeHigh(("pulseShape_" + id + "hi").c_str(), ("pulseShape_" + id + "hi").c_str(), 400, -200., 300., 0, 100000.)
52  , pulseShapeLow(("pulseShape_" + id + "lo").c_str(), ("pulseShape_" + id + "lo").c_str(), 400, -200., 300., 0, 100000.)
53 #endif
54 
55  , TimeDiffResHis(("dtimeRes"+id).c_str(),("dtimeRes"+id).c_str(),1000,-40.,40.)
56  , time(0.0)
57 
58 #ifdef TileLaserTimingPMT0
59  , dtime(0.0)
60  , dtimeNoCFCorr(0.0)
61 #endif
62 
63  , energy(0.0)
64 {
65 }
66 
68  : m_N_active(0)
69  , m_mean_time(0.)
70  , m_mean_rms(0.)
71 {
72  memset(m_ch_time, 0, sizeof(m_ch_time));
73 }
74 
76  m_ch_time[m_N_active] = time;
77  ++m_N_active;
78 }
79 
81  m_mean_time = 0;
82  m_mean_rms = 0;
83 
84  for (int i = 0; i < m_N_active; ++i) m_mean_time += m_ch_time[i];
85 
86  m_mean_time = m_mean_time / ((float) m_N_active);
87 
88  for (int i = 0; i < m_N_active; ++i) m_mean_rms += sqr(m_ch_time[i] - m_mean_time);
89 
90  m_mean_rms = m_mean_rms / ((float) m_N_active);
91  m_mean_rms = sqrt(m_mean_rms);
92 }
93 
95  : Digi0TimeDiffHisto(("TimeDiff" + id).c_str(), ("TimeDiff" + id).c_str(), 2000, -100., 100.)
96  , Digi0Time(("Digi0Time" + id).c_str(), ("Digi0Time" + id).c_str(), 2000, -100., 100.)
97  , FarDigitizerMeanTime(0.0)
98 {
99 
100  for (int i = 0; i < 48; ++i) {
101  std::ostringstream sout;
102  sout << id << '_' << i;
103  pmtd[i] = new PMTData(sout.str());
104  }
105 }
106 
107 
108 // LBA | LBC
109 // EBA | EBC
110 float const TileLaserTimingTool::s_fiberLength[2][48] = {{167.1,167.1,178.7,178.7,190.3,190.3,201.9,201.9,213.5,213.5,
111  225.1,225.1,236.7,236.7,248.3,248.3,259.9,259.9,271.5,271.5,
112  283.1,283.1,294.7,294.7,201.9,201.9,213.5,213.5,225.1,225.1,
113  236.7,236.7,248.3,248.3,259.9,259.9,271.5,271.5,283.1,283.1,
114  294.7,294.7,306.3,306.3,317.9,317.9,329.6,329.6},
115 
116  { 51.1, 51.1, 62.7, 62.7, 74.3, 74.3, 85.9, 85.9, 97.5, 97.5,
117  109.1,109.1,120.7,120.7,132.3,132.3,143.9,143.9,143.9,143.9,
118  167.1,167.1,178.1,178.1,178.1,178.1,178.1,178.1,213.5,213.5,
119  213.5,213.5,236.7,236.7,236.7,236.7,259.9,259.9,259.9,259.9,
120  283.1,283.1,294.7,294.7,294.7,294.7,294.7,294.7}};
121 
122 TileLaserTimingTool::TileLaserTimingTool(const std::string& type, const std::string& name, const IInterface* pParent)
123  : AthAlgTool(type, name, pParent)
124  , m_tileHWID(nullptr)
125  , m_cabling(nullptr)
126  , m_nevts(0)
127  , m_gaussf(nullptr)
128 {
129 
130  declareInterface<ITileCalibTool>( this );
131 
132  declareProperty("NtupleID", m_ntupleID = "h3000");
133  declareProperty("FiberLightSpeed", m_fiberLightSpeed);
134  declareProperty("NSamples", m_nSamples = 9);
135  declareProperty("EneLowLimitPulseShape", m_eneLowLimitPulseShape = 0.000001);
136  declareProperty("ReferenceDrawer", m_refDrawer = 39);
137 
138  declareProperty("UseMeanChannelOffset", m_useMeanChannelOffset = true);
139  declareProperty("MaxTimeDiff", m_maxTimeDiff = 10000.);
140  declareProperty("UsePMT0AsDskewRef", m_usePMT0AsDskewRef = true);
141 
142 #ifdef TileLaserTimingMonPulse
143  // create mon histos
144  m_h1_time_check = new TH1F("h1_time_check", "Time(Tfit based) - Time(cispar based)", 1000, -200., 200.);
145  m_h2_time_check = new TH2F("h2_time_check", "Time(Tfit based) vs Time(cispar based)", 1000, -200., 200., 1000, -200., 200.);
146 
147  m_PulseShapeHigh = new TProfile("pulse_shape_HG", "pulse shape HG", 400, -200., 300., 0, 100000.);
148  m_PulseShapeLow = new TProfile("pulse_shape_LG", "pulse shape LG", 400, -200., 300., 0, 100000.);
149 #endif
150 
151  // creating multi-dim arrays on the heap and initialize all elements to zeros
153 
154  m_DrawerOffset = new float[NROS][NDRAWERS]();
155  m_DrawerOffsetError = new float[NROS][NDRAWERS]();
156 
157  m_ChannelOffset = new float[NROS][NDRAWERS][NCHANNELS]();
158  m_ChannelOffsetError = new float[NROS][NDRAWERS][NCHANNELS]();
159 
160  m_ADCAmplitude = new float[NROS][NDRAWERS][NCHANNELS]();
161 
162  m_PedestalMean = new float[NROS][NDRAWERS][NCHANNELS]();
163  m_PedestalSigma = new float[NROS][NDRAWERS][NCHANNELS]();
164 
165  m_TimeDiffMean = new float[NROS][NDRAWERS][NCHANNELS]();
166  m_TimeDiffMeanError = new float[NROS][NDRAWERS][NCHANNELS]();
167  m_TimeDiffSigma = new float[NROS][NDRAWERS][NCHANNELS]();
168 
169  m_MeanOddPmtTdiffPMT0 = new float[NROS][NDRAWERS]();
170  m_OddPmtCounterPMT0 = new int[NROS][NDRAWERS]();
171  m_MeanEvenPmtTdiffPMT0 = new float[NROS][NDRAWERS]();
172  m_EvenPmtCounterPMT0 = new int[NROS][NDRAWERS]();
173  m_EvenOddTimeDiffPMT0 = new float[NROS][NDRAWERS]();
174 
175 #ifdef TileLaserTimingPMT0Mon
176  m_TimeDiffHighMean = new float[NROS][NDRAWERS][NCHANNELS]();
177  m_TimeDiffHighMeanError = new float[NROS][NDRAWERS][NCHANNELS]();
178  m_TimeDiffHighSigma = new float[NROS][NDRAWERS][NCHANNELS]();
179 
180  m_TimeDiffLowMean = new float[NROS][NDRAWERS][NCHANNELS]();
181  m_TimeDiffLowMeanError = new float[NROS][NDRAWERS][NCHANNELS]();
182  m_TimeDiffLowSigma = new float[NROS][NDRAWERS][NCHANNELS]();
183 
184  m_TimeDiffNoCFCorrMean = new float[NROS][NDRAWERS][NCHANNELS]();
185  m_TimeDiffNoCFCorrMeanError = new float[NROS][NDRAWERS][NCHANNELS]();
186  m_TimeDiffNoCFCorrSigma = new float[NROS][NDRAWERS][NCHANNELS]();
187 #endif
188 
189  m_FiberLength = new float[NROS][NDRAWERS][NCHANNELS]();
190 
191 #ifdef TileLaserTimingMon
192  m_TimeDiffPMTDigi0 = new float[NROS][NDRAWERS][NCHANNELS]();
193  m_FiberCorrection = new float[NROS][NDRAWERS][NCHANNELS]();
194  m_IsConnected = new int[NROS][NDRAWERS][NCHANNELS]();
195 
196  m_MeanOddPmtTdiff = new float[NROS][NDRAWERS]();
197  m_OddPmtCounter = new int[NROS][NDRAWERS]();
198  m_MeanEvenPmtTdiff = new float[NROS][NDRAWERS]();
199  m_EvenPmtCounter = new int[NROS][NDRAWERS]();
200 
201  m_EvenOddTimeDiff = new float[NROS][NDRAWERS]();
202 #endif
203 
204  m_DSkewSet = new float[NROS][NDRAWERS][NDIGI]();
205  m_DigiMean = new float[NROS][NDRAWERS][NDIGI]();
206 }
207 
209 
210  delete[] m_drawerData;
211  delete[] m_DrawerOffset;
212  delete[] m_DrawerOffsetError;
213  delete[] m_ChannelOffset;
214  delete[] m_ChannelOffsetError;
215  delete[] m_ADCAmplitude;
216  delete[] m_PedestalMean;
217  delete[] m_PedestalSigma;
218  delete[] m_TimeDiffMean;
219  delete[] m_TimeDiffMeanError;
220  delete[] m_TimeDiffSigma;
221  delete[] m_MeanOddPmtTdiffPMT0;
222  delete[] m_OddPmtCounterPMT0;
223  delete[] m_MeanEvenPmtTdiffPMT0;
224  delete[] m_EvenPmtCounterPMT0;
225  delete[] m_EvenOddTimeDiffPMT0;
226 #ifdef TileLaserTimingPMT0Mon
227  delete[] m_TimeDiffHighMean;
228  delete[] m_TimeDiffHighMeanError;
229  delete[] m_TimeDiffHighSigma;
230  delete[] m_TimeDiffLowMean;
231  delete[] m_TimeDiffLowMeanError;
232  delete[] m_TimeDiffLowSigma;
233  delete[] m_TimeDiffNoCFCorrMean;
234  delete[] m_TimeDiffNoCFCorrMeanError;
235  delete[] m_TimeDiffNoCFCorrSigma;
236 #endif
237 
238  delete[] m_FiberLength;
239 
240 #ifdef TileLaserTimingMon
241  delete[] m_TimeDiffPMTDigi0;
242  delete[] m_FiberCorrection;
243  delete[] m_IsConnected;
244  delete[] m_MeanOddPmtTdiff;
245  delete[] m_OddPmtCounter;
246  delete[] m_MeanEvenPmtTdiff;
247  delete[] m_EvenPmtCounter;
248  delete[] m_EvenOddTimeDiff;
249 #endif
250  delete[] m_DSkewSet;
251  delete[] m_DigiMean;
252 }
253 
254 
255 
257 
258  ATH_MSG_INFO( "initialize()" );
259 
260  // get TileHWID helper
262 
263  // get the timing tool
264  CHECK( m_tileToolTiming.retrieve() );
265 
266  // get TileCabling Service
268 
269  m_nevts = 0;
270 
274 
275  // gauss fit function
276  m_gaussf = new TF1("GainGauss", "[0]*exp(- (x-[1])*(x-[1])/(2*[2]*[2]))", -60, 60);
277 
278  ATH_MSG_DEBUG( "initialize() ready " );
279 
291  return StatusCode::SUCCESS;
292 }
293 
295 
296  ATH_MSG_INFO( "initNtuple(" << runNumber << "," << runType << "," << rootFile << ")" );
297 
298  return StatusCode::SUCCESS;
299 }
300 
301 // conv factor from low gain to high gain
302 //const float LG2HG = 64.;
303 
308 
309  ATH_MSG_DEBUG( "execute()" );
310 
311  gROOT->cd();
312 
313  // Get event's CIS parameters
314  // QQQ: const uint32_t *cispar = m_beamInfo->cispar();
315  // QQQ: const uint32_t dac = cispar[6];
316  // QQQ: const uint32_t phase = cispar[5];
317  // QQQ: const uint32_t cap = cispar[7];
318 
319  // Get EventInfo
321  ATH_CHECK( eventInfo.isValid() );
322 
323 
324  // QQQ: const unsigned runNumber = eventInfo->runNumber();
325  // QQQ: const unsigned eventNumber = eventInfo->eventNumber();
326 
327  // Check if event should be used in calibration
328  bool pass = true;
329 
330  // Get TileRawChannelContainer
332  ATH_CHECK( container.isValid() );
333 
334  // Get TileDigitsContainer
336  ATH_CHECK( digitsCnt.isValid() );
337 
338  // Create iterator over RawChannelContainer
339  TileRawChannelContainer::const_iterator itColl = (*container).begin();
340  TileRawChannelContainer::const_iterator itCollEnd = (*container).end();
342 
343  // tmp vars
344  const TileDigitsCollection *digiColl = nullptr;
345  const TileDigits* digits;
346  const TileRawChannel *rawch = nullptr;
347  float dtime, dtimeNoCFCorr;
348 
349 #ifdef TileLaserTimingMonPulse
350  float f_SampleTime, f_phase1, f_phase2, f_time, f_tfittime;
351 #endif
352 
353  size_t colls;
354  int Nconnected;
355  float ChannelOffset;
356 
357  DrawerData *ddata = nullptr;
358 
359  unsigned frag;
360  if (pass) {
361  m_nevts++;
362 
363  // Go through all TileRawChannelCollections
364  for (; itColl != itCollEnd; ++itColl) {
365  // Get the digits collection for the drawer corresponding to the raw channel
366  frag = (*itColl)->identify();
367  const auto *digiCollIt = digitsCnt->indexFindPtr(digitsCnt->hashFunc()(frag));
368  if (digiCollIt == nullptr) {
369  ATH_MSG_ERROR( " unable to get TileDigitsCollection for drawer:" << drawerIdStr(frag) );
370 
371  } else {
372  digiColl = digiCollIt;
373  colls = (*itColl)->size();
374  ATH_MSG_VERBOSE( "execute() colls:" << colls
375  << " digiColl->size:" << digiColl->size()
376  << " drawer:" << drawerIdStr((*itColl)->identify()) );
377 
378  if (digiColl->size() != colls) {
379  ATH_MSG_ERROR( " size of TileDigitsCollection and TileRawChannelCollection differ for drawer:" << drawerIdStr((*itColl)->identify()) );
380 
381  } else {
382  // ZZZ: Assume the first RawChannel in the collection corresponds to PMT 0
383  // ZZZ: if this is not the case (for some reason) there will be a nasty segflt
384 
385  // get drawer HWID
386  HWIdentifier dhwid = drawerId((*itColl)->identify());
387  // LBA=1 LBC=2 EBA=3 EBC=4
388  int ros = m_tileHWID->ros(dhwid);
389  // 0 to 63
390  int drawer = m_tileHWID->drawer(dhwid);
391  // get and create DrawerData if needed, cannot be null
392  ddata = drawerData(ros, drawer);
393  // store ref to first PMT
394  PMTData &pmt0data = *ddata->pmtd[0];
395 
396  for (size_t i = 0; i < colls; ++i) {
397  digits = digiColl->at(i);
398  rawch = (*itColl)->at(i);
399 
400  // require both digits and raw channels with equal ids
401  if (!digits || !rawch || (digits->identify() != rawch->identify())) {
402  if (!digits) {
403  ATH_MSG_ERROR( " no TileDigits for drawer:" << drawerIdStr((*itColl)->identify()) );
404  }
405 
406  if (!rawch) {
407  ATH_MSG_ERROR( " no TileRawChannel for drawer:" << drawerIdStr((*itColl)->identify()) );
408  }
409 
410  if (rawch && digits) {
411  ATH_MSG_ERROR( " no id mismatch for drawer:" << drawerIdStr((*itColl)->identify()) );
412  }
413 
414  } else {
415  // get hardware id to identify adc
416  HWIdentifier hwid = rawch->adc_HWID();
417  // int ros = m_tileHWID->ros(hwid); // LBA=1 LBC=2 EBA=3 EBC=4
418  // int drawer = m_tileHWID->drawer(hwid); // 0 to 63
419  const int chan = m_tileHWID->channel(hwid); // 0 to 47 channel not PMT
420  const int gain = m_tileHWID->adc(hwid); // low=0 high=1
421  const int ipmt = channel2PMT(ros, chan);
422 
423  // store Fit data
424  PMTData &pmtdata = *ddata->pmtd[ipmt];
425  pmtdata.time = rawch->time();
426  pmtdata.energy = rawch->amplitude();
427  pmtdata.pedestal.add(rawch->pedestal());
428 
429  // in case of the first PMT (i.e. 0) this will be 0 as per definition
430  dtimeNoCFCorr = pmtdata.time - pmt0data.time;
431  dtime = dtimeNoCFCorr - fiberCorrection(ros, ipmt);
432  pmtdata.TimeDiffHisto.Fill(dtime);
433 
434 #ifdef TileLaserTimingPMT0
435  pmtdata.TimeDiffNoCFCorrHisto.Fill(dtimeNoCFCorr);
436 
437  if(gain == 0) pmtdata.TimeDiffHistoLow.Fill(dtime);
438  else pmtdata.TimeDiffHistoHigh.Fill(dtime);
439 #endif
440 
441 #ifdef TileLaserTimingMon
442  pmtdata.timeHisto.Fill(pmtdata.time);
443  pmtdata.eneHisto.Fill(pmtdata.energy);
444  pmtdata.gainHisto.Fill(gain);
445 #endif
446 
447  // pulse data-->
448 #ifdef TileLaserTimingMonPulse
449  if(isConnectedChan(ros, chan)) {
450  std::vector<float> sample = digits->samples();
451  if(sample.size() != m_nSamples) {
452  ATH_MSG_ERROR( " sample size mismatch for drawer:" << drawerIdStr(frag)
453  <<" in:" << sample.size() << " expected:" << m_nSamples );
454  } else {
455  for (unsigned jsample = 0; jsample < m_nSamples; ++jsample) {
456  f_SampleTime = ((float) jsample) * 25.;
457  f_phase1 = (25. * ((float) phase)) / (30. * 8);
458  f_phase2 = -pmtdata.time;
459  f_time = f_SampleTime + f_phase1 - 100;
460  f_tfittime = f_SampleTime + f_phase2 - 100;
461  if (phase >= 160) {
462  f_time -= 25;
463  f_phase1 -= 25;
464  }
465 
466  if (phase < 140 || phase > 160) {
467  // if Low gain convert to the HG scale
468  if (gain == 0) {
469  m_h1_time_check->Fill(f_phase1 - f_phase2);
470  m_h2_time_check->Fill(f_phase1, f_phase2);
471 
472  if (fabs(pmtdata.energy) > m_eneLowLimitPulseShape) {
473  pmtdata.pulseShapeLow.Fill(f_tfittime, (LG2HG * (sample[jsample] - rawch->pedestal())));
474  }
475  }
476  //HG
477  else if (fabs(pmtdata.energy) > m_eneLowLimitPulseShape) {
478  pmtdata.pulseShapeHigh.Fill(f_tfittime, (sample[jsample] - rawch->pedestal()));
479  }
480  } // if Cispar not in 140->160 (range with time jitter,
481  //difficult to handle for smooth pulse shape
482  }
483  } // end loop over jsample
484  } // end if PMT is connected
485 #endif
486  // <--pulse data
487 
488  } // else: ok digits and raw channels
489  } // end collection loop
490 
491  //=====================================================================================
492  //=== Compute mean Tfit (corrected for laser fiber length) over the first digitizer ===
493  //=====================================================================================
494  Nconnected = 0;
495  ddata->FarDigitizerMeanTime = 0.;
496  for (int ipmt = 0; ipmt < 6; ++ipmt) {
497  if (isConnectedPMT(ros, ipmt)) {
498  ddata->FarDigitizerMeanTime += (ddata->pmtd[ipmt]->time - fiberCorrection(ros, ipmt));
499  Nconnected++;
500  }
501  }
502  if (Nconnected)
503  ddata->FarDigitizerMeanTime /= (float) Nconnected;
504 
505 #ifdef TileLaserTimingMon
506  ddata->Digi0Time.Fill(ddata->FarDigitizerMeanTime);
507 #endif
508 
509  if (msgLvl(MSG::VERBOSE) && (ros == 1) && (drawer == 1)) {
510  ATH_MSG_VERBOSE( " ddata->FarDigitizerMeanTime:" << ddata->FarDigitizerMeanTime );
511  }
512 
513  //============================================================================
514  //=== Calculate residuals. Fill histos with time diff b/w PMT i and digi 1 ===
515  //============================================================================
516  for (int ipmt = 0; ipmt < NCHANNELS; ipmt++) {
517  if (isConnectedPMT(ros, ipmt)) {
518  ChannelOffset = -(ddata->pmtd[ipmt]->time - fiberCorrection(ros, ipmt) - ddata->FarDigitizerMeanTime);
519  ddata->pmtd[ipmt]->TimeDiffResHis.Fill(ChannelOffset);
520  if (msgLvl(MSG::VERBOSE) && (ros == 1) && (drawer == 1)) {
521  ATH_MSG_VERBOSE( " ipmt:" << ipmt << " ChannelOffset:" << ChannelOffset );
522  }
523  }
524  }
525 
526  } // else: matching digits and raw channel collections
527  }
528  } // end container loop
529 
530  //=====================================================================================
531  //=== this histogram contains the difference between first digitizer of drawer 1 and drawer 2: drawer offset
532  //=====================================================================================
533  for (unsigned int ros = 1; ros < TileCalibUtils::MAX_ROS; ++ros) {
534  if (drawerData(ros, m_refDrawer)) {
535  DrawerData &drawer0data = *drawerData(ros, m_refDrawer);
536  for (unsigned int drawer = 0; drawer < TileCalibUtils::MAX_DRAWER; ++drawer) {
537  if ((drawer != m_refDrawer) && drawerData(ros, drawer)) {
538  DrawerData &ddata = *drawerData(ros, drawer);
539  ddata.Digi0TimeDiffHisto.Fill( ddata.FarDigitizerMeanTime - drawer0data.FarDigitizerMeanTime);
540 
541  if (msgLvl(MSG::VERBOSE) && (ros == 1) && (drawer == 1)) {
542  ATH_MSG_VERBOSE( " drawerdiff:" << ddata.FarDigitizerMeanTime - drawer0data.FarDigitizerMeanTime );
543  }
544  }
545  }
546  }
547  }
548  }
549 
550  return StatusCode::SUCCESS;
551 }
552 
554 
555  ATH_MSG_INFO( "finalizeCalculations()" );
556 
557  gROOT->cd();
558 
559  float fmean, fdummy, fchi2, fmeanerr;
560 
561  for (unsigned int ros = 1; ros < TileCalibUtils::MAX_ROS; ++ros) {
562  for (unsigned int drawer = 0; drawer < TileCalibUtils::MAX_DRAWER; ++drawer) {
563  DrawerData &drawerd = *drawerData(ros, drawer);
564 
565  for (int ipmt = 0; ipmt < NCHANNELS; ++ipmt) {
566  PMTData &pmtd = *drawerd.pmtd[ipmt];
567  // to simplify the root analysis, store the fiber length, not really neccessary
568  m_FiberLength[ros][drawer][ipmt] = fiberLength(ros, ipmt);
569 #ifdef TileLaserTimingMon
571  m_IsConnected[ros][drawer][ipmt] = isConnectedPMT(ros, ipmt);
572 #endif
573  //==========================================================================================
574  //==== Pulse shapes ====
575 
576  // use the number of entries in the histos as the number of passed events for high/low
577 
578 #ifdef TileLaserTimingMonPulse
579  if(pmtd.TimeDiffHistoLow.GetEntries() > 0.99 * m_nevts) {
580  m_PulseShapeLow->Add(&pmtd.pulseShapeLow);
581  }
582 
583  if(pmtd.TimeDiffHistoHigh.GetEntries() > 0.99 * m_nevts) {
584  m_PulseShapeHigh->Add(&pmtd.pulseShapeHigh);
585  }
586 #endif
587 
588  if (ipmt > 0) {
589  //==================================================================
590  // Fit time difference regardless of gain, to derive standard Dskews
591  //==================================================================
592  if (isConnectedPMT(ros, ipmt)) {
594  }
595 
596 #ifdef TileLaserTimingPMT0
597  //===========================================================
598  //=== Fit time difference without clear fiber corrections ===
599  //===========================================================
600  if(isConnectedPMT(ros, ipmt)) {
601  fitGauss(pmtd.TimeDiffNoCFCorrHisto, m_TimeDiffNoCFCorrMean[ros][drawer][ipmt], m_TimeDiffNoCFCorrSigma[ros][drawer][ipmt], m_TimeDiffNoCFCorrMeanError[ros][drawer][ipmt]);
602  }
603 
604  //================================================================================
605  //==== Fit gauss to time differences in all gains/ low gain/ high gain in all PMTs
606  //================================================================================
607 
608  fitGauss(pmtd.TimeDiffHistoLow, m_TimeDiffLowMean[ros][drawer][ipmt], m_TimeDiffLowSigma[ros][drawer][ipmt], m_TimeDiffLowMeanError[ros][drawer][ipmt]);
609 
610  //------------------------------------- For high gain --------------------------------------
611 
612  fitGauss(pmtd.TimeDiffHistoHigh, m_TimeDiffHighMean[ros][drawer][ipmt], m_TimeDiffHighSigma[ros][drawer][ipmt], m_TimeDiffHighMeanError[ros][drawer][ipmt]);
613 #endif
614  }
615 
616  //==================================================================================
617  //=== Fit mean value of time difference b/w drawer_i(pmt_j) and drawer_i(digi_1) ===
618  //==================================================================================
619 
620  // TODO: previous values on error
621  if (isConnectedPMT(ros, ipmt)) {
623  m_TimeDiffPMTDigi0[ros][drawer][ipmt] = m_ChannelOffset[ros][drawer][ipmt] = pmtd.TimeDiffResHis.GetMean();
624  m_ChannelOffsetError[ros][drawer][ipmt] = pmtd.TimeDiffResHis.GetMeanError();
625  } else {
626  fitGauss2(pmtd.TimeDiffResHis, fmean, fdummy, fchi2, fmeanerr, 1.0, 3.0);
627 
628  if (fchi2 > 500) {
629  ATH_MSG_WARNING( "pmt # " << ipmt + 1
630  << " has chi2 value " << fchi2
631  << " force timing residual same as PMT-1 " );
632 
633  // FittedMean=PreviousFittedMean;
634  fchi2 = -fchi2; // just to make Coverity happt
635  fmean = -4711;
636  fmeanerr = 0.0;
637  }
638  if (fabs(fmean) > 100) {
639  ATH_MSG_WARNING( " pmt # " << ipmt + 1
640  << " has ChannelOffset " << fmean
641  << " force timing residual same as PMT-1" );
642 
643  // FittedMean=PreviousFittedMean;
644  fmean = -4711;
645  fmeanerr = 0.0;
646  }
647  m_ChannelOffset[ros][drawer][ipmt] = fmean;
648  m_ChannelOffsetError[ros][drawer][ipmt] = fmeanerr;
649  }
650  } else {
651  m_ChannelOffset[ros][drawer][ipmt] = 0.0;
652  m_ChannelOffsetError[ros][drawer][ipmt] = 0.0;
653  }
654 
655 #ifdef TileLaserTimingMonPulse
656  //===========================================================
657  //=== Pedestal and ADC Amplitudes ===
658  //===========================================================
660  if (isConnectedPMT(ros, ipmt))
661  m_ADCAmplitude[ros][drawer][ipmt] = fmax(pmtd.pulseShapeHigh.GetMaximum(), pmtd.pulseShapeLow.GetMaximum());
662  else
663  m_ADCAmplitude[ros][drawer][ipmt] = 0.;
664 
665  if (msgLvl(MSG::VERBOSE) && (ros == 1) && (drawer == 1)) {
666  msg(MSG::VERBOSE) << "ipmt: " << ipmt
667  << " TimeDiffLow: " << m_TimeDiffLowMean[ros][drawer][ipmt] << "(" << m_TimeDiffLowSigma[ros][drawer][ipmt] << ") +-" << m_TimeDiffLowMeanError[ros][drawer][ipmt]
668  << " TimeDiffHigh:" << m_TimeDiffHighMean[ros][drawer][ipmt] << "(" << m_TimeDiffHighSigma[ros][drawer][ipmt] << ") +-" << m_TimeDiffHighMeanError[ros][drawer][ipmt] << endmsg;
669 
670  msg(MSG::VERBOSE) << " TimeDiff:" << m_TimeDiffMean[ros][drawer][ipmt] << "(" << m_TimeDiffSigma[ros][drawer][ipmt] << ") +-" << m_TimeDiffMeanError[ros][drawer][ipmt]
671  << " TomeDiffNoCF:" << m_TimeDiffNoCFCorrMean[ros][drawer][ipmt] << "(" << m_TimeDiffNoCFCorrSigma[ros][drawer][ipmt] << ") +-" << m_TimeDiffNoCFCorrMeanError[ros][drawer][ipmt] << endmsg;
672 
673  msg(MSG::VERBOSE) << " ped:" << m_PedestalMean[ros][drawer][ipmt] << "(" << m_PedestalSigma[ros][drawer][ipmt]
674  << ") amp:" << m_ADCAmplitude[ros][drawer][ipmt] << endmsg;
675  }
676 #endif
677 
678  } // end PMT loop
679 
680  //============================================
681  //========= Fit mean DrawerOffset ============
682  //============================================
683 
684  fitGauss2(drawerd.Digi0TimeDiffHisto, m_DrawerOffset[ros][drawer], fdummy, fdummy, m_DrawerOffsetError[ros][drawer], 0.5, 1.0);
685 
686  ATH_MSG_DEBUG( "finalizeCalculations()"
687  << " ros: " << ros
688  << " drawer:" << drawer
689  << " DrawerOffset:" << m_DrawerOffset[ros][drawer] << "("
690  << m_DrawerOffsetError[ros][drawer] << ")" );
691 
692  //==============================================================
693  //=== correct for overall offset between odd and even fibers ===
694  //
695  // Better would be to meassure the laser fiber lengths and
696  // implement this as a correction. Meanwhile, use this as
697  // a compromise.
698  //==============================================================
699  // CCC: MeanEvenPmtTdiff= 0;
700  // CCC: MeanOddPmtTdiff = 0;
701  // CCC: DeltaParity = 0;
702  // CCC: OddPmtCounter =0;
703  // CCC: EvenPmtCounter =0;
704 
706 
708 
710 
711  //==================================================================
712  //=== Calculate Dskews ===
713  //==================================================================
714  for (int ipmt = 0; ipmt < NCHANNELS; ++ipmt) {
715  // LBA and LBC
716  if (isBarrel(ros)) {
717  if (isConnectedPMT(ros, ipmt) && (timeDiffs[ros][drawer][ipmt] < 300)) {
718  drawerd.digid[ipmt / 6].Add(timeDiffs[ros][drawer][ipmt]);
719  }
720  if (ipmt % 6 == 5) {
721  drawerd.digid[ipmt / 6].Freeze();
722  }
723  } // end isBarrel
724  // EBA and EBC%
725  else if (isExtBarrel(ros)) {
726  if (isConnectedPMT(ros, ipmt) && (timeDiffs[ros][drawer][ipmt] < 300)) {
727  if (ipmt < 6) drawerd.digid[0].Add(timeDiffs[ros][drawer][ipmt]);
728  else if (ipmt > 5 && ipmt < 12) drawerd.digid[1].Add(timeDiffs[ros][drawer][ipmt]);
729  else if (ipmt > 11 && ipmt < 18) drawerd.digid[2].Add(timeDiffs[ros][drawer][ipmt]);
730  else if (ipmt > 17 && ipmt < 24) drawerd.digid[3].Add(timeDiffs[ros][drawer][ipmt]);
731  else if (ipmt > 27 && ipmt < 34) {
732  drawerd.digid[4].Add(timeDiffs[ros][drawer][ipmt]);
733  drawerd.digid[5].Add(timeDiffs[ros][drawer][ipmt]);
734  } else if (ipmt > 35) {
735  drawerd.digid[6].Add(timeDiffs[ros][drawer][ipmt]);
736  drawerd.digid[7].Add(timeDiffs[ros][drawer][ipmt]);
737  }
738  }
739 
740  if (ipmt == 5) drawerd.digid[0].Freeze();
741  else if (ipmt == 11) drawerd.digid[1].Freeze();
742  else if (ipmt == 17) drawerd.digid[2].Freeze();
743  else if (ipmt == 23) drawerd.digid[3].Freeze();
744  else if (ipmt == 33) {
745  drawerd.digid[4].Freeze();
746  drawerd.digid[5].Freeze();
747  } else if (ipmt == 47) {
748  drawerd.digid[6].Freeze();
749  drawerd.digid[7].Freeze();
750  }
751  } // end isExtBarrel
752  } // end PMT loop
753 
754  for (int digi = 0; digi < NDIGI; ++digi) {
755  m_DigiMean[ros][drawer][digi] = drawerd.digid[digi].GetDigiTime();
756  m_DSkewSet[ros][drawer][digi] = (m_DigiMean[ros][drawer][digi] - m_DigiMean[ros][drawer][0]) * 240. / 25.;
757 
758  ATH_MSG_DEBUG( "finalizeCalculations()"
759  << " ros: " << ros
760  << " drawer: " << drawer
761  << " digi: " << digi
762  << " digi_time: " << drawerd.digid[digi].GetDigiTime()
763  << " #active: " << drawerd.digid[digi].GetTotActive()
764  << " DSkewSet: " << m_DSkewSet[ros][drawer][digi] );
765 
766  }
767  } // end drawer loop
768  } // end ros loop
769 
770  return StatusCode::SUCCESS;
771 }
772 
774 
775  ATH_MSG_INFO( "writeNtuple(" << runNumber << "," << runType << "," << rootFile << ")" );
776 
777  // Write a tree with all arrays
778  TTree *t = new TTree(m_ntupleID.c_str(), "TileLaserTimingNtuple");
779  t->Branch("DrawerOffset", m_DrawerOffset, "DrawerOffset[5][64]/F"); // float m_DrawerOffset[s_NRos][64];
780  t->Branch("DrawerOffsetError", m_DrawerOffsetError, "DrawerOffsetError[5][64]/F"); // float m_DrawerOffsetError[NROS][64];
781 
782  t->Branch("ChannelOffset", m_ChannelOffset, "ChannelOffset[5][64][48]/F"); // float m_ChannelOffset[NROS][64][48];
783  t->Branch("ChannelOffsetError", m_ChannelOffsetError, "ChannelOffsetError[5][64][48]/F"); // float m_ChannelOffsetError[NROS][64][48];
784 
785  t->Branch("ADCAmplitude", m_ADCAmplitude, "ADCAmplitude[5][64][48]/F"); // float m_ADCAmplitude[NROS][64][48];
786 
787  t->Branch("PedestalMean", m_PedestalMean, "PedestalMean[5][64][48]/F"); // float m_PedestalMean[NROS][64][48];
788  t->Branch("PedestalSigma", m_PedestalSigma, "PedestalSigma[5][64][48]/F"); // float m_PedestalSigma[NROS][64][48];
789 
790  t->Branch("TimeDiffMean", m_TimeDiffMean, "TimeDiffMean[5][64][48]/F"); // float m_TimeDiffMean[NROS][64][48];
791  t->Branch("TimeDiffMeanError", m_TimeDiffMeanError, "TimeDiffMeanError[5][64][48]/F"); // float m_TimeDiffMeanError[NROS][64][48];
792  t->Branch("TimeDiffSigma", m_TimeDiffSigma, "TimeDiffSigma[5][64][48]/F"); // float m_TimeDiffSigma[NROS][64][48];
793 
794 #ifdef TileLaserTimingPMT0Mon
795  t->Branch("TimeDiffHighMean", m_TimeDiffHighMean, "TimeDiffHighMean[5][64][48]/F"); // float m_TimeDiffHighMean[NROS][64][48];
796  t->Branch("TimeDiffHighMeanError", m_TimeDiffHighMeanError, "TimeDiffHighMeanError[5][64][48]/F"); // float m_TimeDiffHighMeanError[NROS][64][48];
797  t->Branch("TimeDiffHighSigma", m_TimeDiffHighSigma, "TimeDiffHighSigma[5][64][48]/F"); // float m_TimeDiffHighSigma[NROS][64][48];
798  t->Branch("TimeDiffLowMean", m_TimeDiffLowMean, "TimeDiffLowMean[5][64][48]/F"); // float m_TimeDiffLowMean[NROS][64][48];
799  t->Branch("TimeDiffLowMeanError", m_TimeDiffLowMeanError, "TimeDiffLowMeanError[5][64][48]/F"); // float m_TimeDiffLowMeanError[NROS][64][48];
800  t->Branch("TimeDiffLowSigma", m_TimeDiffLowSigma, "TimeDiffLowSigma[5][64][48]/F"); // float m_TimeDiffLowSigma[NROS][64][48];
801  t->Branch("TimeDiffNoCFCorrMean", m_TimeDiffNoCFCorrMean, "TimeDiffNoCFCorrMean[5][64][48]/F"); // float m_TimeDiffNoCFCorrMean[NROS][64][48];
802  t->Branch("TimeDiffNoCFCorrMeanError", m_TimeDiffNoCFCorrMeanError, "TimeDiffNoCFCorrMeanError[5][64][48]/F"); // float m_TimeDiffNoCFCorrMeanError[NROS][64][48];
803  t->Branch("TimeDiffNoCFCorrSigma", m_TimeDiffNoCFCorrSigma, "TimeDiffNoCFCorrSigma[5][64][48]/F"); // float m_TimeDiffNoCFCorrSigma[NROS][64][48];
804 #endif
805  t->Branch("FiberLength", m_FiberLength, "FiberLength[5][64][48]/F"); // float m_FiberLength[NROS][64][48];
806 
807 #ifdef TileLaserTimingMon
808  t->Branch("EvenOddTimeDiff", m_EvenOddTimeDiff, "EvenOddTimeDiff[5][64]/F"); // float m_EvenOddTimeDiff[NROS][64];
809 
810  t->Branch("FiberCorrection", m_FiberCorrection, "FiberCorrection[5][64][48]/F"); // float m_FiberCorrection[NROS][64][48];
811  t->Branch("IsConnected", m_IsConnected, "IsConnected[5][64][48]/F"); // float m_FiberCorrection[NROS][64][48];
812 
813  t->Branch("MeanOddPmtTdiff", m_MeanOddPmtTdiff, "MeanOddPmtTdiff[5][64]/F");
814  t->Branch("OddPmtCounter", m_OddPmtCounter, "OddPmtCounter[5][64]/I");
815  t->Branch("MeanEvenPmtTdiff", m_MeanEvenPmtTdiff, "MeanEvenPmtTdiff[5][64]/F");
816  t->Branch("EvenPmtCounter", m_EvenPmtCounter, "EvenPmtCounter[5][64]/I");
817 
818  t->Branch("TimeDiffPMTDigi0", m_TimeDiffPMTDigi0, "TimeDiffPMTDigi0[5][64][48]/F");
819 #endif
820 
821  // mon pmt0-->
822  t->Branch("EvenOddTimeDiffPMT0", m_EvenOddTimeDiffPMT0, "EvenOddTimeDiffPMT0[5][64]/F");
823  t->Branch("MeanOddPmtTdiffPMT0", m_MeanOddPmtTdiffPMT0, "MeanOddPmtTdiffPMT0[5][64]/F");
824  t->Branch("OddPmtCounterPMT0", m_OddPmtCounterPMT0, "OddPmtCounterPMT0[5][64]/I");
825  t->Branch("MeanEvenPmtTdiffPMT0", m_MeanEvenPmtTdiffPMT0, "MeanEvenPmtTdiffPMT0[5][64]/F");
826  t->Branch("EvenPmtCounterPMT0", m_EvenPmtCounterPMT0, "EvenPmtCounterPMT0[5][64]/I");
827  // <-- mon pmt0
828 
829  t->Branch("DSkewSet", m_DSkewSet, "DSkewSet[5][64][8]/F"); // float m_DSkewSet[NROS][64][8];
830  t->Branch("DigiMean", m_DigiMean, "DigiMean[5][64][8]/F"); // float m_DigiMean[NROS][64][8];
831  t->Fill();
832  rootFile->cd();
833  t->Write();
834 
835  ATH_MSG_INFO( "writeNtuple(" << runNumber << "," << runType << "," << rootFile << ") data written" );
836 
837  rootFile->ls();
838 
839  // store histos
840  for (unsigned int ros = 1; ros < TileCalibUtils::MAX_ROS; ++ros) {
841  for (unsigned int drawer = 0; drawer < TileCalibUtils::MAX_DRAWER; ++drawer) {
842  ATH_MSG_VERBOSE( "writeNtuple() ros:" << ros << " drawer:" << drawer );
843 
845  if (dd) {
846  dd->Digi0TimeDiffHisto.Write();
847 #ifdef TileLaserTimingMon
848  dd->Digi0Time.Write();
849 #endif
850  for (int ipmt = 0; ipmt < NCHANNELS; ++ipmt) {
851  if (isConnectedPMT(ros, ipmt)) {
852  /*dd->pmtd[ipmt]->TimeDiffHisto.Write();
853  dd->pmtd[ipmt]->TimeDiffNoCFCorrHisto.Write();*/
854 #ifdef TileLaserTimingMon
855  dd->pmtd[ipmt]->timeHisto.Write();
856  dd->pmtd[ipmt]->eneHisto.Write();
857  dd->pmtd[ipmt]->gainHisto.Write();
858 #endif
859  /*dd->pmtd[ipmt]->TimeDiffHistoHigh.Write();
860  dd->pmtd[ipmt]->pulseShapeHigh.Write();
861  dd->pmtd[ipmt]->TimeDiffHistoLow.Write();
862  dd->pmtd[ipmt]->pulseShapeLow.Write();*/
863  dd->pmtd[ipmt]->TimeDiffResHis.Write();
864  }
865  }
866  }
867  }
868  }
869 
870  return StatusCode::SUCCESS;
871 }
872 
874 
875  ATH_MSG_INFO( "finalize()" );
876 
877  return StatusCode::SUCCESS;
878 }
879 
880 
881 
883  if (isBarrel(ros)) {
884  return !(ipmt == 31 || ipmt == 32 || ipmt == 43);
885  } else if (isExtBarrel(ros)) {
886  return !( ipmt == 18 || ipmt == 19 || ipmt == 24 || ipmt == 25
887  || ipmt == 26 || ipmt == 27 || ipmt == 30 || ipmt == 31
888  || ipmt == 34 || ipmt == 35 || ipmt == 38 || ipmt == 39
889  || ipmt == 44 || ipmt == 45 || ipmt == 46 || ipmt == 47);
890  }
891 
892  return false;
893 }
894 
895 
896 void TileLaserTimingTool::fitGauss(TH1F &hi, float &p1, float &p2, float &p1_err) {
897 
898  if (hi.GetEntries() == 0) {
899  p1 = p2 = p1_err = 0.0;
900  return;
901  }
902  double MaxAmplitude = hi.GetMaximum();
903  double MeanTimeDiff = hi.GetMean();
904  double RMSTimeDiff = hi.GetRMS();
905  m_gaussf->SetParameter(0, MaxAmplitude);
906  m_gaussf->SetParameter(1, MeanTimeDiff);
907  m_gaussf->SetParameter(2, RMSTimeDiff);
908  m_gaussf->SetRange(MeanTimeDiff - 2.0 * RMSTimeDiff, MeanTimeDiff + 2.0 * RMSTimeDiff);
909 
910  hi.Fit(m_gaussf, "QR");
911 
912  p1 = m_gaussf->GetParameter(1);
913  p1_err = m_gaussf->GetParError(1);
914  p2 = m_gaussf->GetParameter(2);
915 }
916 
917 void TileLaserTimingTool::fitGauss2(TH1F &hi, float &p1, float &p2, float &chi2, float &p1_err, float w1, float w2) {
918 
919  if (hi.GetEntries() == 0) {
920  p1 = p2 = chi2 = p1_err = w1 = w2 = 0.0;
921  return;
922  }
923 
924  double MaxAmplitude = hi.GetMaximum();
925  double MeanTimeDiff = hi.GetMean();
926  double RMSTimeDiff = hi.GetRMS();
927 
928  m_gaussf->SetParameter(0, MaxAmplitude);
929  m_gaussf->SetParameter(1, MeanTimeDiff);
930  m_gaussf->SetParameter(2, RMSTimeDiff);
931  m_gaussf->SetRange(MeanTimeDiff - w1 * RMSTimeDiff, MeanTimeDiff + w1 * RMSTimeDiff);
932 
933  hi.Fit(m_gaussf, "QR");
934  double FittedAmplitude = m_gaussf->GetParameter(0);
935  double FittedMean = m_gaussf->GetParameter(1);
936  double FittedSigma = m_gaussf->GetParameter(2);
937 
938  //=== Iterate once ===
939 
940  m_gaussf->SetParameter(0, FittedAmplitude);
941  m_gaussf->SetParameter(1, FittedMean);
942  m_gaussf->SetParameter(2, FittedSigma);
943  m_gaussf->SetRange(FittedMean - w2 * FittedSigma, FittedMean + w2 * FittedSigma);
944 
945  hi.Fit(m_gaussf, "QR");
946  p1 = m_gaussf->GetParameter(1);
947  p2 = m_gaussf->GetParameter(2);
948  p1_err = m_gaussf->GetParError(1);
949  chi2 = m_gaussf->GetChisquare();
950 }
951 
952 void TileLaserTimingTool::correctEvenOddPMT(int ros, int drawer, TPMTArray& ChannelOffset
953  , TDrawerArrayF& MeanOddPmtTdiff, TDrawerArrayI& OddPmtCounter
954  , TDrawerArrayF& MeanEvenPmtTdiff, TDrawerArrayI& EvenPmtCounter
955  , TDrawerArrayF& EvenOddTimeDiff) {
956 
957 
958  float DeltaParity = 0;
959 
960  //=== determine overall shift between odd and even fibers ===
961  //=== for this take only into account channels with connected PMT
962  //=== don't take into the mean the value of tdiff when it is too far from zero
963  for (int ipmt = 0; ipmt < NCHANNELS; ++ipmt) {
964  if (isConnectedPMT(ros, ipmt)) {
965  if (ipmt % 2 == 1) {
966  // odd PMTs
967  if (fabs(ChannelOffset[ros][drawer][ipmt]) < m_maxTimeDiff) {
968  MeanOddPmtTdiff[ros][drawer] += ChannelOffset[ros][drawer][ipmt];
969  ++OddPmtCounter[ros][drawer];
970  } else {
971  ATH_MSG_WARNING( "correctEvenOddPMT()"
972  << " time overflow (" << ChannelOffset[ros][drawer][ipmt]
973  << ") ros:" << ros
974  << " dr:" << drawer
975  << " pmt:" << ipmt );
976 
977  }
978  } else if (ipmt % 2 == 0) {
979  // even PMTs
980  if (fabs(ChannelOffset[ros][drawer][ipmt]) < m_maxTimeDiff) {
981  MeanEvenPmtTdiff[ros][drawer] += ChannelOffset[ros][drawer][ipmt];
982  ++EvenPmtCounter[ros][drawer];
983  } else {
984  ATH_MSG_WARNING( "correctEvenOddPMT()"
985  << " time overflow (" << ChannelOffset[ros][drawer][ipmt]
986  << ") ros:" << ros
987  << " dr:" << drawer
988  << " pmt:" << ipmt );
989  }
990  }
991  }
992  }
993 
994  // Save Time difference b/w odd/even pmt's
995  MeanOddPmtTdiff[ros][drawer] /= (float) OddPmtCounter[ros][drawer];
996  MeanEvenPmtTdiff[ros][drawer] /= (float) EvenPmtCounter[ros][drawer];
997  DeltaParity = 0.5 * (MeanOddPmtTdiff[ros][drawer] - MeanEvenPmtTdiff[ros][drawer]);
998 
999  EvenOddTimeDiff[ros][drawer] = 2 * DeltaParity;
1000 
1001  ATH_MSG_DEBUG( "correctEvenOddPMT()"
1002  << " ros: " << ros
1003  << " drawer:" << drawer
1004  << " EvenOddTimeDiff:" << EvenOddTimeDiff[ros][drawer]
1005  << " | MeanOddPmtTdiff:" << MeanOddPmtTdiff[ros][drawer]
1006  << " MeanEvenPmtTdiff:" << MeanEvenPmtTdiff[ros][drawer]
1007  << " DeltaParity:" << DeltaParity );
1008 
1009  //==================================================================
1010  //=== Correct for overall shift b/w odd and even fibers ===
1011  //==================================================================
1012  for (int ipmt = 0; ipmt < NCHANNELS; ++ipmt) {
1013  if (isConnectedPMT(ros, ipmt)) {
1014  if (ipmt % 2 == 1)
1015  ChannelOffset[ros][drawer][ipmt] -= DeltaParity;
1016  else if (ipmt % 2 == 0) ChannelOffset[ros][drawer][ipmt] += DeltaParity;
1017  }
1018  } // end pmt loop
1019 }
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
TileLaserTimingTool::initNtuple
virtual StatusCode initNtuple(int runNumber, int runType, TFile *rootfile) override
Definition: TileLaserTimingTool.cxx:294
TileLaserTimingTool::m_TimeDiffSigma
float(* m_TimeDiffSigma)[NDRAWERS][NCHANNELS]
Definition: TileLaserTimingTool.h:196
TileLaserTimingTool::isConnectedChan
bool isConnectedChan(int ros, int chan)
Definition: TileLaserTimingTool.h:303
data
char data[hepevt_bytes_allocation_ATLAS]
Definition: HepEvt.cxx:11
TileLaserTimingTool::m_MeanOddPmtTdiffPMT0
float(* m_MeanOddPmtTdiffPMT0)[NDRAWERS]
Definition: TileLaserTimingTool.h:199
TileLaserTimingTool::~TileLaserTimingTool
virtual ~TileLaserTimingTool()
Definition: TileLaserTimingTool.cxx:208
ReadOfcFromCool.phase
phase
Definition: ReadOfcFromCool.py:127
TileLaserTimingTool::m_tileToolTiming
ToolHandle< TileCondToolTiming > m_tileToolTiming
Definition: TileLaserTimingTool.h:259
DataModel_detail::const_iterator
Const iterator class for DataVector/DataList.
Definition: DVLIterator.h:82
TileCalibDrawerFlt.h
TileLaserTimingTool::fiberCorrection
double fiberCorrection(int ros, int pmt)
Definition: TileLaserTimingTool.h:323
TileLaserTimingTool::isExtBarrel
static bool isExtBarrel(int ros)
Definition: TileLaserTimingTool.h:319
TileLaserTimingTool::DigitizerData::m_ch_time
float m_ch_time[6]
Definition: TileLaserTimingTool.h:149
TileLaserTimingTool::isConnectedPMT
static bool isConnectedPMT(int ros, int chan)
Definition: TileLaserTimingTool.cxx:882
TileLaserTimingTool::DrawerData::FarDigitizerMeanTime
float FarDigitizerMeanTime
Definition: TileLaserTimingTool.h:171
CondAttrListCollection.h
This file defines the class for a collection of AttributeLists where each one is associated with a ch...
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
TileCablingService::getInstance
static const TileCablingService * getInstance()
get pointer to service instance
Definition: TileCablingService.cxx:24
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
TileLaserTimingTool::DrawerData::pmtd
PMTData * pmtd[NCHANNELS]
Definition: TileLaserTimingTool.h:157
TileLaserTimingTool::DigitizerData::Freeze
void Freeze()
Definition: TileLaserTimingTool.cxx:80
sqr
_T sqr(const _T &data)
Definition: TileLaserTimingTool.cxx:31
TileLaserTimingTool::PMTData::PMTData
PMTData(const std::string &id)
Definition: TileLaserTimingTool.cxx:35
TileLaserTimingTool::m_DigiMean
float(* m_DigiMean)[NDRAWERS][NDIGI]
Definition: TileLaserTimingTool.h:236
TileRawChannel::pedestal
float pedestal(void) const
Definition: TileRawChannel.h:106
TileLaserTimingTool::finalizeCalculations
virtual StatusCode finalizeCalculations() override
Definition: TileLaserTimingTool.cxx:553
CaloCondBlobAlgs_fillNoiseFromASCII.gain
gain
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:110
TileLaserTimingTool::m_eneLowLimitPulseShape
double m_eneLowLimitPulseShape
Definition: TileLaserTimingTool.h:269
TileLaserTimingTool::DrawerData::DrawerData
DrawerData(const std::string &id)
Definition: TileLaserTimingTool.cxx:94
TRTCalib_cfilter.p1
p1
Definition: TRTCalib_cfilter.py:130
TileLaserTimingTool::writeNtuple
virtual StatusCode writeNtuple(int runNumber, int runType, TFile *rootfile) override
Definition: TileLaserTimingTool.cxx:773
TileLaserTimingTool::m_PedestalMean
float(* m_PedestalMean)[NDRAWERS][NCHANNELS]
Definition: TileLaserTimingTool.h:190
skel.it
it
Definition: skel.GENtoEVGEN.py:396
TileLaserTimingTool::PMTData::TimeDiffHisto
TH1F TimeDiffHisto
Definition: TileLaserTimingTool.h:103
TileLaserTimingTool::DigitizerData::GetTotActive
int GetTotActive() const
Definition: TileLaserTimingTool.h:143
TileLaserTimingTool::DigitizerData::GetDigiTime
float GetDigiTime() const
Definition: TileLaserTimingTool.h:144
TileLaserTimingTool::m_refDrawer
unsigned int m_refDrawer
Definition: TileLaserTimingTool.h:271
AthCommonMsg< AlgTool >::msgLvl
bool msgLvl(const MSG::Level lvl) const
Definition: AthCommonMsg.h:30
TileLaserTimingTool::drawerId
HWIdentifier drawerId(int frag)
Definition: TileLaserTimingTool.h:331
TileLaserTimingTool::m_PedestalSigma
float(* m_PedestalSigma)[NDRAWERS][NCHANNELS]
Definition: TileLaserTimingTool.h:191
TileCalibUtils.h
TileLaserTimingTool::DrawerData::Digi0TimeDiffHisto
TH1F Digi0TimeDiffHisto
Definition: TileLaserTimingTool.h:163
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
TileLaserTimingTool::m_nevts
int m_nevts
number of laser events
Definition: TileLaserTimingTool.h:284
TileLaserTimingTool::m_tileHWID
const TileHWID * m_tileHWID
Definition: TileLaserTimingTool.h:257
TileLaserTimingTool::DigitizerData::Add
void Add(float time)
Definition: TileLaserTimingTool.cxx:75
TileLaserTimingTool::m_TimeDiffPMTDigi0
float(* m_TimeDiffPMTDigi0)[NDRAWERS][NCHANNELS]
Definition: TileLaserTimingTool.h:223
TileRawData::adc_HWID
HWIdentifier adc_HWID(void) const
Definition: TileRawData.h:53
HWIdentifier
Definition: HWIdentifier.h:13
python.TrigEgammaMonitorHelper.TH2F
def TH2F(name, title, nxbins, bins_par2, bins_par3, bins_par4, bins_par5=None, bins_par6=None, path='', **kwargs)
Definition: TrigEgammaMonitorHelper.py:45
TileLaserTimingTool::PMTData::TimeDiffNoCFCorrHisto
TH1F TimeDiffNoCFCorrHisto
Definition: TileLaserTimingTool.h:104
TileLaserTimingTool::m_EvenPmtCounterPMT0
int(* m_EvenPmtCounterPMT0)[NDRAWERS]
Definition: TileLaserTimingTool.h:202
TileRawChannel::time
float time(int ind=0) const
Definition: TileRawChannel.h:103
Example_ReadSampleNoise.drawer
drawer
Definition: Example_ReadSampleNoise.py:39
TileLaserTimingTool::m_fiberLightSpeed
double m_fiberLightSpeed
Definition: TileLaserTimingTool.h:266
TileLaserTimingTool::PMTData::pedestal
TileSimpleStat pedestal
Definition: TileLaserTimingTool.h:137
TileHWID::channel
int channel(const HWIdentifier &id) const
extract channel field from HW identifier
Definition: TileHWID.h:189
TileSimpleStat::getStat
void getStat(double &mean, double &sigma)
Definition: TileSimpleStat.h:21
AthCommonDataStore< AthCommonMsg< AlgTool > >::detStore
const ServiceHandle< StoreGateSvc > & detStore() const
The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:95
TileCalibUtils::MAX_DRAWER
static const unsigned int MAX_DRAWER
Number of drawers in ROS 1-4.
Definition: TileCalibUtils.h:139
TileHWID::ros
int ros(const HWIdentifier &id) const
extract ros field from HW identifier
Definition: TileHWID.h:167
TileLaserTimingMon
#define TileLaserTimingMon
Definition: TileLaserTimingTool.h:75
TileLaserTimingTool::execute
virtual StatusCode execute() override
TODO: determine event type, select laser?
Definition: TileLaserTimingTool.cxx:307
TileLaserTimingTool::m_nSamples
unsigned m_nSamples
Definition: TileLaserTimingTool.h:267
TileRawChannelContainer.h
TileLaserTimingTool::PMTData
Definition: TileLaserTimingTool.h:99
TileLaserTimingTool::m_MeanEvenPmtTdiffPMT0
float(* m_MeanEvenPmtTdiffPMT0)[NDRAWERS]
Definition: TileLaserTimingTool.h:201
NPARTITIONS
#define NPARTITIONS
Definition: TileLaserDefaultCalibTool.h:35
TRTCalib_cfilter.p2
p2
Definition: TRTCalib_cfilter.py:131
TileHWID::adc
int adc(const HWIdentifier &id) const
extract adc field from HW identifier
Definition: TileHWID.h:193
TileLaserTimingTool::m_IsConnected
int(* m_IsConnected)[NDRAWERS][NCHANNELS]
Definition: TileLaserTimingTool.h:225
TileLaserTimingTool::m_usePMT0AsDskewRef
bool m_usePMT0AsDskewRef
Definition: TileLaserTimingTool.h:276
TileLaserTimingTool::NROS
static const int NROS
Definition: TileLaserTimingTool.h:176
TileRawChannel::amplitude
float amplitude(int ind=0) const
Definition: TileRawChannel.h:101
TileHWID.h
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
TileLaserTimingTool::m_ntupleID
std::string m_ntupleID
Definition: TileLaserTimingTool.h:265
ParticleGun_FastCalo_ChargeFlip_Config.energy
energy
Definition: ParticleGun_FastCalo_ChargeFlip_Config.py:78
FullCPAlgorithmsTest_eljob.sample
sample
Definition: FullCPAlgorithmsTest_eljob.py:113
TileLaserTimingTool::m_maxTimeDiff
float m_maxTimeDiff
Definition: TileLaserTimingTool.h:274
lumiFormat.i
int i
Definition: lumiFormat.py:85
python.TrigEgammaMonitorHelper.TProfile
def TProfile(*args, **kwargs)
Definition: TrigEgammaMonitorHelper.py:81
ReadCellNoiseFromCool.chan
chan
Definition: ReadCellNoiseFromCool.py:52
TileDigitsContainer.h
TileLaserTimingTool::s_fiberLength
static const float s_fiberLength[2][48]
Definition: TileLaserTimingTool.h:300
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
TileLaserTimingTool::PMTData::timeHisto
TH1F timeHisto
Definition: TileLaserTimingTool.h:107
TileLaserTimingTool::m_ChannelOffset
float(* m_ChannelOffset)[NDRAWERS][NCHANNELS]
Definition: TileLaserTimingTool.h:185
TileLaserTimingTool::m_EvenOddTimeDiffPMT0
float(* m_EvenOddTimeDiffPMT0)[NDRAWERS]
Definition: TileLaserTimingTool.h:203
TileLaserTimingTool::PMTData::time
double time
Definition: TileLaserTimingTool.h:129
TileLaserTimingTool::initialize
virtual StatusCode initialize() override
Definition: TileLaserTimingTool.cxx:256
chi2
double chi2(TH1 *h0, TH1 *h1)
Definition: comparitor.cxx:523
TileRawChannel
Definition: TileRawChannel.h:35
TileLaserTimingTool::m_ADCAmplitude
float(* m_ADCAmplitude)[NDRAWERS][NCHANNELS]
Definition: TileLaserTimingTool.h:188
NCHANNELS
#define NCHANNELS
Definition: TileLaserDefaultCalibTool.h:38
TileLaserTimingTool::m_rawChannelContainerKey
SG::ReadHandleKey< TileRawChannelContainer > m_rawChannelContainerKey
Definition: TileLaserTimingTool.h:251
NDIGI
#define NDIGI
Definition: TileLaserTimingTool.h:67
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
makeComparison.rootFile
rootFile
Definition: makeComparison.py:27
TileLaserTimingTool::m_OddPmtCounter
int(* m_OddPmtCounter)[NDRAWERS]
Definition: TileLaserTimingTool.h:228
CHECK
#define CHECK(...)
Evaluate an expression and check for errors.
Definition: Control/AthenaKernel/AthenaKernel/errorcheck.h:422
NDRAWERS
#define NDRAWERS
Definition: TileLaserDefaultCalibTool.h:36
IdentifiableContainerMT::const_iterator
Definition: IdentifiableContainerMT.h:79
SG::VarHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:103
TileLaserTimingTool::channel2PMT
int channel2PMT(int ros, int chan)
Definition: TileLaserTimingTool.h:311
TileCalibUtils::MAX_ROS
static const unsigned int MAX_ROS
Number of ROSs
Definition: TileCalibUtils.h:138
maskDeadModules.ros
ros
Definition: maskDeadModules.py:35
imax
int imax(int i, int j)
Definition: TileLaserTimingTool.cxx:33
TileLaserTimingTool::PMTData::gainHisto
TH1F gainHisto
Definition: TileLaserTimingTool.h:109
TileDigits::samples
const std::vector< float > & samples() const
Definition: TileDigits.h:58
python.OnlineISConfiguration.runType
def runType
Definition: OnlineISConfiguration.py:112
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
TileLaserTimingTool::m_TimeDiffMeanError
float(* m_TimeDiffMeanError)[NDRAWERS][NCHANNELS]
Definition: TileLaserTimingTool.h:195
TileLaserTimingTool::correctEvenOddPMT
void correctEvenOddPMT(int ros, int drawer, TPMTArray &ChannelOffset, TDrawerArrayF &MeanOddPmtTdiff, TDrawerArrayI &OddPmtCounter, TDrawerArrayF &MeanEvenPmtTdiff, TDrawerArrayI &EvenPmtCounter, TDrawerArrayF &EvenOddTimeDiff)
Correct for differences between even and odd PMTs.
Definition: TileLaserTimingTool.cxx:952
TileLaserTimingTool::m_FiberCorrection
float(* m_FiberCorrection)[NDRAWERS][NCHANNELS]
Definition: TileLaserTimingTool.h:224
TileDigitsCollection
Definition: TileDigitsCollection.h:18
TileLaserTimingTool::m_DrawerOffset
float(* m_DrawerOffset)[NDRAWERS]
Definition: TileLaserTimingTool.h:181
TileLaserTimingTool::fitGauss2
void fitGauss2(TH1F &hi, float &p1, float &p2, float &chi2, float &p1_err, float w1, float w2)
Fit a Gaussian function with two iterations mean range = hi.mean +- w1|w2 * hi.rms.
Definition: TileLaserTimingTool.cxx:917
TileLaserTimingTool::m_gaussf
TF1 * m_gaussf
Definition: TileLaserTimingTool.h:286
id
SG::auxid_t id
Definition: Control/AthContainers/Root/debug.cxx:227
TileLaserTimingTool::isBarrel
static bool isBarrel(int ros)
Definition: TileLaserTimingTool.h:315
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
TileLaserTimingTool::m_TimeDiffMean
float(* m_TimeDiffMean)[NDRAWERS][NCHANNELS]
Definition: TileLaserTimingTool.h:194
TileDigits
Definition: TileDigits.h:30
errorcheck.h
Helpers for checking error return status codes and reporting errors.
TileLaserTimingTool::m_DrawerOffsetError
float(* m_DrawerOffsetError)[NDRAWERS]
Definition: TileLaserTimingTool.h:182
TileRawDataContainer::hashFunc
const TileFragHash & hashFunc() const
Definition: TileRawDataContainer.h:66
TileLaserTimingTool::PMTData::energy
double energy
Definition: TileLaserTimingTool.h:134
TileSimpleStat::add
void add(double val)
Definition: TileSimpleStat.h:15
TileRawData::identify
Identifier identify(void) const
Definition: TileRawData.h:52
TileLaserTimingTool::finalize
virtual StatusCode finalize() override
Definition: TileLaserTimingTool.cxx:873
TileLaserTimingTool::DrawerData::digid
DigitizerData digid[8]
Definition: TileLaserTimingTool.h:158
library_scraper.dd
list dd
Definition: library_scraper.py:46
EventInfo.h
IdentifiableContainerMT::indexFindPtr
virtual const T * indexFindPtr(IdentifierHash hashId) const override final
return pointer on the found entry or null if out of range using hashed index - fast version,...
Definition: IdentifiableContainerMT.h:289
DeMoAtlasDataLoss.runNumber
string runNumber
Definition: DeMoAtlasDataLoss.py:64
TileLaserTimingTool::fitGauss
void fitGauss(TH1F &hi, float &p1, float &p2, float &p1_err)
Fit a Gaussian function (m_gaussf) to the given histogram, store mean, rms and mean error.
Definition: TileLaserTimingTool.cxx:896
TileLaserTimingTool::DigitizerData::DigitizerData
DigitizerData()
Definition: TileLaserTimingTool.cxx:67
TileHWID::drawer
int drawer(const HWIdentifier &id) const
extract drawer field from HW identifier
Definition: TileHWID.h:171
CaloSwCorrections.time
def time(flags, cells_name, *args, **kw)
Definition: CaloSwCorrections.py:242
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
TileLaserTimingTool::m_MeanEvenPmtTdiff
float(* m_MeanEvenPmtTdiff)[NDRAWERS]
Definition: TileLaserTimingTool.h:229
TileLaserTimingTool::PMTData::eneHisto
TH1F eneHisto
Definition: TileLaserTimingTool.h:108
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
TileLaserTimingTool::TPMTArray
float(* TPMTArray)[NDRAWERS][NCHANNELS]
Definition: TileLaserTimingTool.h:354
AthCommonMsg< AlgTool >::msg
MsgStream & msg() const
Definition: AthCommonMsg.h:24
TileLaserTimingTool::m_digitsContainerKey
SG::ReadHandleKey< TileDigitsContainer > m_digitsContainerKey
Definition: TileLaserTimingTool.h:253
TileLaserTimingTool::m_ChannelOffsetError
float(* m_ChannelOffsetError)[NDRAWERS][NCHANNELS]
Definition: TileLaserTimingTool.h:186
TileLaserTimingTool::TileLaserTimingTool
TileLaserTimingTool(const std::string &type, const std::string &name, const IInterface *pParent)
Definition: TileLaserTimingTool.cxx:122
TileLaserTimingTool::fiberLength
static float fiberLength(int ros, int pmt)
Definition: TileLaserTimingTool.h:327
TileLaserTimingTool::m_useMeanChannelOffset
bool m_useMeanChannelOffset
Definition: TileLaserTimingTool.h:272
TileLaserTimingTool::drawerData
DrawerData * drawerData(int ros, int drawer)
Definition: TileLaserTimingTool.h:239
TileLaserTimingTool::m_DSkewSet
float(* m_DSkewSet)[NDRAWERS][NDIGI]
Definition: TileLaserTimingTool.h:235
python.TrigEgammaMonitorHelper.TH1F
def TH1F(name, title, nxbins, bins_par2, bins_par3=None, path='', **kwargs)
Definition: TrigEgammaMonitorHelper.py:24
python.Constants.VERBOSE
int VERBOSE
Definition: Control/AthenaCommon/python/Constants.py:14
DataVector::at
const T * at(size_type n) const
Access an element, as an rvalue.
TileLaserTimingTool::m_EvenOddTimeDiff
float(* m_EvenOddTimeDiff)[NDRAWERS]
Definition: TileLaserTimingTool.h:232
TileLaserTimingTool::m_FiberLength
float(* m_FiberLength)[NDRAWERS][NCHANNELS]
Definition: TileLaserTimingTool.h:220
ReadHandle.h
Handle class for reading from StoreGate.
AthAlgTool
Definition: AthAlgTool.h:26
TileLaserTimingTool.h
TileLaserTimingTool::DrawerData
Definition: TileLaserTimingTool.h:155
TileLaserTimingTool::DrawerData::Digi0Time
TH1F Digi0Time
Definition: TileLaserTimingTool.h:167
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
TileLaserTimingTool::m_eventInfoKey
SG::ReadHandleKey< xAOD::EventInfo > m_eventInfoKey
Definition: TileLaserTimingTool.h:249
TileLaserTimingTool::m_EvenPmtCounter
int(* m_EvenPmtCounter)[NDRAWERS]
Definition: TileLaserTimingTool.h:230
readCCLHist.float
float
Definition: readCCLHist.py:83
TileLaserTimingTool::m_OddPmtCounterPMT0
int(* m_OddPmtCounterPMT0)[NDRAWERS]
Definition: TileLaserTimingTool.h:200
TileLaserTimingTool::drawerIdStr
std::string drawerIdStr(int frag)
Definition: TileLaserTimingTool.h:335
TileLaserTimingTool::m_MeanOddPmtTdiff
float(* m_MeanOddPmtTdiff)[NDRAWERS]
Definition: TileLaserTimingTool.h:227
TileLaserTimingTool::PMTData::TimeDiffResHis
TH1F TimeDiffResHis
Definition: TileLaserTimingTool.h:126
TileLaserTimingTool::m_drawerData
DrawerData *(* m_drawerData)[NDRAWERS]
Definition: TileLaserTimingTool.h:174
TileLaserTimingTool::m_cabling
const TileCablingService * m_cabling
Definition: TileLaserTimingTool.h:258