ATLAS Offline Software
TileDigitsMaker.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 //****************************************************************************
6 // Filename : TileDigitsMaker.cxx
7 // Author : Zhifang
8 // Created : Feb 2006 from TileHitToDigits
9 //
10 // DESCRIPTION:
11 // Created to simulate the digits information (amplitudes of N time-slices,
12 // with N about 9) received by the ROD's.)
13 //
14 // HISTORY:
15 //
16 // BUGS:
17 //
18 //*****************************************************************************
19 
20 // Tile includes
29 
30 // Calo includes
31 #include "CaloIdentifier/TileID.h"
33 
34 // Atlas include
36 // For the Athena-based random numbers.
39 
40 #include "AthenaKernel/Units.h"
41 #include "StoreGate/ReadHandle.h"
42 #include "StoreGate/WriteHandle.h"
44 #include "GaudiKernel/ThreadLocalContext.h"
45 // Pile up
47 
48 // Gaudi includes
49 
50 //CLHEP includes
51 #include <CLHEP/Random/Randomize.h>
52 
53 
54 #include "TMatrixF.h"
55 #include "TDecompChol.h"
56 #include "cmath"
57 
58 #include <algorithm>
59 
60 using CLHEP::RandGaussQ;
61 using CLHEP::RandFlat;
62 using Athena::Units::MeV;
63 
64 
65 //
66 // Alg standard initialize function
67 //
69  // retrieve TileID helper and TileInfo from det store
70 
72 
74 
76 
78 
79  //=== intialize TileEMScale condtion object
81 
82  //=== initialize TileSampleNoise condition object
84 
85  ATH_CHECK( m_cablingSvc.retrieve() );
86  m_cabling = m_cablingSvc->cablingService();
87 
88  /* Get needed parameters from tileInfo. */
89  m_nSamples = m_tileInfo->NdigitSamples(); // number of time slices for each chan
90  m_iTrig = m_tileInfo->ItrigSample(); // index of the triggering time slice
91  m_i_ADCmax = m_tileInfo->ADCmax(); // adc saturation value used in assignment
92  m_f_ADCmax = m_i_ADCmax; // adc saturation value used in assignment
93  m_f_ADCmaxHG = m_f_ADCmax - 0.5; // value of switch from high to low gain
95  m_ADCmaxPlusEps = m_f_ADCmax + 0.01;
96  m_f_ADCmaskValue = m_tileInfo->ADCmaskValue(); // indicates channels which were masked in background dataset
97  m_tileNoise = m_tileInfo->TileNoise(); // (true => generate noise in TileDigits)
98  m_tileCoherNoise = m_tileInfo->TileCoherNoise(); // (true => generate coherent noise in TileDigits)
99  m_tileThresh = m_tileInfo->TileZeroSuppress(); // (true => apply threshold to Digits)
102 
104  ATH_CHECK( m_rndmSvc.retrieve());
105  }
106 
107  ATH_MSG_DEBUG( "Event Overlay: " << ((m_rndmEvtOverlay)?"true":"false"));
108  ATH_MSG_DEBUG( "Masking Channels: " << ((m_maskBadChannels)?"true":"false"));
109  ATH_MSG_DEBUG( "Using pulse shapes from COOL: " << ((m_useCoolPulseShapes)?"true":"false"));
110 
113 
114  if (m_useCoolPulseShapes) {
115  ATH_MSG_DEBUG( "Initializing pulse shape conditions object");
116  } else {
117  /* Get fine-grained shaping profile (0.5-ns bins) for both gains*/
119  m_digitShapeHi.push_back(0.0);
121  m_digitShapeLo.push_back(0.0);
122  }
123 
124  //=== Initialize bad channels key
126 
130  m_timeStepHi = 25.0 / m_nBinsPerXHi;
131 
135  m_timeStepLo = 25.0 / m_nBinsPerXLo;
136 
139 
140  if (m_rndmEvtOverlay) {
141  m_tileNoise = false;
142  m_tileCoherNoise = false;
143  m_tileThresh = false;
144  m_calibRun = false;
145  if (m_allChannels<0) m_allChannels = 2; // create all channels with noise in overlay by default
146 
147  ATH_MSG_INFO( "Pileup and/or noise added by overlaying digits of random events");
148 
149  // locate the PileUpMergeSvc and initialize our local ptr
151  ATH_CHECK( service("PileUpMergeSvc", m_mergeSvc) );
152 
153  ATH_MSG_INFO( "PileUpMergeSvc successfully initialized");
154  }
155 
157 
158  } else {
160 
161  if (m_allChannels<0) m_allChannels = 0; // do not create all channels by default
162  if (m_tileNoise || m_tileCoherNoise) m_allChannels = 2; // unless noise is set to True
163  if (msgLvl(MSG::INFO)) {
164  msg(MSG::INFO) << "Obtained info from TileInfo" << endmsg;
165  msg(MSG::INFO) << "tileNoise=" << ((m_tileNoise) ? "true" : "false")
166  << ", tileCoherNoise=" << ((m_tileCoherNoise) ? "true" : "false")
167  << ", tileThresh=" << ((m_tileThresh) ? "true" : "false");
168  if (m_tileThresh)
169  msg(MSG::INFO) << ", thresh(hi,lo)=" << m_tileThreshHi << "," << m_tileThreshLo << endmsg;
170  else
171  msg(MSG::INFO) << endmsg;
172  }
173  }
174 
175  if (m_allChannels>1)
176  ATH_MSG_INFO( "Create all channels with noise: true");
177  else if (m_allChannels>0)
178  ATH_MSG_INFO( "Create all channels without noise: true");
179  else
180  ATH_MSG_INFO( "Create all channels: false");
181 
182  if (m_calibRun) {
184  }
185 
186  if (!m_filteredDigitsContainerKey.key().empty()) {
187  ATH_MSG_INFO( "Keep digits with hit energy above " << m_filterThreshold / MeV
188  << " MeV in " << m_filteredDigitsContainerKey.key() << " container");
189  ATH_MSG_INFO( "Keep digits from MBTS with original G4 hit energy above "
190  << m_filterThresholdMBTS / MeV << " MeV ");
191 
193 
194  } else {
195  m_filterThreshold = HUGE_VALL;
196  m_filterThresholdMBTS = HUGE_VALL;
197  }
198 
199  ATH_MSG_DEBUG( "nShapeHi=" << m_nShapeHi
200  << " nBinsPerXHi=" << m_nBinsPerXHi
201  << " timeStepHi=" << m_timeStepHi
202  << " binTime0Hi=" << m_binTime0Hi);
203 
204  ATH_MSG_DEBUG( "nShapeLo=" << m_nShapeLo
205  << " nBinsPerXLo=" << m_nBinsPerXLo
206  << " timeStepLo=" << m_timeStepLo
207  << " binTime0Lo=" << m_binTime0Lo);
208 
209  // decrease by 1, now they are indexes of last element in a vector
210  --m_nShapeHi;
211  --m_nShapeLo;
212 
213  /* ==================================*/
214  // Store HWID's for all 12288 channels (48 channels in each of 64 drawers).
215  IdContext drawer_context = m_tileHWID->drawer_context();
216  int ndrawers = m_tileHWID->drawer_hash_max();
217  const int nchMax = 48; // number of channels per drawer
218 
219  ATH_MSG_DEBUG( "ndrawers=" << ndrawers
220  << " nchMax=" << nchMax
221  << " HIGAIN=" << TileID::HIGHGAIN
222  << " LOWGAIN=" << TileID::LOWGAIN);
223 
224  /* Store all (12288) Identifiers for the calorimeter adc's for HIGHAIN */
225  m_all_ids.reserve(ndrawers);
226  for (int dr = 0; dr < ndrawers; ++dr) {
227  HWIdentifier drawer_id;
228  m_tileHWID->get_id(dr, drawer_id, &drawer_context);
229 
230  m_all_ids.push_back(std::make_unique<HWIdentifier[]>(nchMax));
231  std::unique_ptr<HWIdentifier[]>& adc_ids = m_all_ids.back();
232 
233  int ros = m_tileHWID->ros(drawer_id);
234  if (ros > 0) {
235  int drawer = m_tileHWID->drawer(drawer_id);
236  IdentifierHash idhash;
237  m_tileHWID->get_hash(drawer_id, idhash, &drawer_context);
238  int drawerIdx = TileCalibUtils::getDrawerIdx(ros, drawer);
239  if (drawerIdx != (int)idhash) {
240  ATH_MSG_ERROR("drawer " << m_tileHWID->to_string(drawer_id, -2)
241  << " hash " << idhash << " NOT EQUAL to idx " << drawerIdx);
242  } else if (msgLvl(MSG::VERBOSE) && m_cabling->connected(ros, drawer)) {
243  msg(MSG::VERBOSE) << "drawer " << m_tileHWID->to_string(drawer_id, -2)
244  << " hash " << idhash << endmsg;
245  }
246 
247  for (int ch = 0; ch < nchMax; ++ch) {
248  adc_ids[ch] = m_tileHWID->adc_id(drawer_id, ch, TileID::HIGHGAIN);
249  }
250  }
251  }
252 
255 
258 
259  ATH_MSG_INFO( "TileDigitsMaker initialization completed");
260 
261  return StatusCode::SUCCESS;
262 }
263 
264 
265 StatusCode TileDigitsMaker::execute(const EventContext &ctx) const {
266  ATH_MSG_DEBUG( "Executing TileDigitsMaker");
267 
268  // Prepare RNG service
269  ATHRNG::RNGWrapper* rngWrapper = nullptr;
270  CLHEP::HepRandomEngine* rngEngine = nullptr;
272  rngWrapper = m_rndmSvc->getEngine(this, m_randomStreamName);
273  rngWrapper->setSeed( m_randomStreamName, ctx );
274  rngEngine = rngWrapper->getEngine(ctx);
275  }
276 
278  ATH_CHECK( sampleNoise.isValid() );
279 
280  bool first = (msgLvl(MSG::VERBOSE) && ctx.evt() == 0 && !m_rndmEvtOverlay );
281  if (first) {
282  ATH_MSG_VERBOSE( "Dumping 2G noise parameters");
283  first = false;
284  IdContext drawer_context = m_tileHWID->drawer_context();
285  int ndrawers = m_tileHWID->drawer_hash_max();
286  const int nchMax = 48; // number of channels per drawer
287  for (int dr = 0; dr < ndrawers; ++dr) {
288  HWIdentifier drawer_id;
289  m_tileHWID->get_id(dr, drawer_id, &drawer_context);
290  int ros = m_tileHWID->ros(drawer_id);
291  int drawer = m_tileHWID->drawer(drawer_id);
292  if (m_cabling->connected(ros, drawer)) {
293  IdentifierHash idhash;
294  m_tileHWID->get_hash(drawer_id, idhash, &drawer_context);
295  for (int ch = 0; ch < nchMax; ++ch) {
296  double pedSimHi = sampleNoise->getPed(idhash, ch, TileID::HIGHGAIN);
297  double sigmaHi_Hfn1 = sampleNoise->getHfn1(idhash, ch, TileID::HIGHGAIN);
298  double sigmaHi_Hfn2 = sampleNoise->getHfn2(idhash, ch, TileID::HIGHGAIN);
299  double sigmaHi_Norm = sampleNoise->getHfnNorm(idhash, ch, TileID::HIGHGAIN);
300  double pedSimLo = sampleNoise->getPed(idhash, ch, TileID::LOWGAIN);
301  double sigmaLo_Hfn1 = sampleNoise->getHfn1(idhash, ch, TileID::LOWGAIN);
302  double sigmaLo_Hfn2 = sampleNoise->getHfn2(idhash, ch, TileID::LOWGAIN);
303  double sigmaLo_Norm = sampleNoise->getHfnNorm(idhash, ch, TileID::LOWGAIN);
304  ATH_MSG_VERBOSE( "Channel " << m_tileHWID->to_string(drawer_id,-2) << "/" << ch
305  << " pedHi="<< pedSimHi
306  << " pedLo="<< pedSimLo
307  << " rmsHi="<< sigmaHi_Hfn1 << "," << sigmaHi_Hfn2 << "," << sigmaHi_Norm
308  << " rmsLo="<< sigmaLo_Hfn1 << "," << sigmaLo_Hfn2 << "," << sigmaLo_Norm);
309 
310  }
311  }
312  }
313  }
314 
315  // declare array for random number generation
316  double Rndm[16]; // Can't use variable size array,
317  double RndmLo[16]; // Can't use variable size array,
318  double Rndm_dG[1]; // uniform random number for the double gaussian
319  double RndmLo_dG[1]; // uniform random number for the double gaussian
320 
321  // step1: Get hit container from TES
323  ATH_CHECK( hitContainer.isValid() );
324 
325  SG::ReadHandle<TileHitContainer> hitContainer_DigiHSTruth;
326  if(m_doDigiTruth){
327  hitContainer_DigiHSTruth = SG::ReadHandle<TileHitContainer> (m_hitContainer_DigiHSTruthKey, ctx);
328  ATH_CHECK( hitContainer_DigiHSTruth.isValid() );
329  }
330 
331  // Zero sums for monitoring.
332  int nChSum = 0;
333  int nChHiSum = 0;
334  int nChLoSum = 0;
335  int nChHiAcc = 0;
336  int nChLoAcc = 0;
337  int nChHiFlt = 0;
338  int nChLoFlt = 0;
339  int nChHiCut = 0;
340  int nChLoCut = 0;
341  double echtot_Acc = 0.;
342  double echint_Acc = 0.;
343  double echtot_Cut = 0.;
344  double echint_Cut = 0.;
345  double HitSum = 0.;
346  double EneSum = 0.;
347  double RChSum = 0.;
348 
349  /* step2: Set up Digits container */
350 
351  auto digitsContainer = std::make_unique<TileMutableDigitsContainer>(true,
354  ATH_CHECK( digitsContainer->status() );
355 
356  std::unique_ptr<TileMutableDigitsContainer> digitsContainer_DigiHSTruth;
357  if(m_doDigiTruth){
358  digitsContainer_DigiHSTruth = std::make_unique<TileMutableDigitsContainer>(true,
361  ATH_CHECK( digitsContainer_DigiHSTruth->status() );
362  }
363 
364  std::unique_ptr<TileMutableDigitsContainer> filteredContainer;
365  if (!m_filteredDigitsContainerKey.key().empty()) {
366  filteredContainer = std::make_unique<TileMutableDigitsContainer>(true,
370  ATH_CHECK( filteredContainer->status() );
371  }
372 
373  /* Set up buffers for handling information in a single collection. */
374  IdentifierHash idhash;
375  IdContext drawer_context = m_tileHWID->drawer_context();
376  const int nchMax = 48; // number of channels per drawer
377  std::vector<int> igain(nchMax, -1);
378  std::vector<int> ntot_ch(nchMax, 0);
379  std::vector<double> ech_tot(nchMax, 0.0);
380  std::vector<double> ech_int(nchMax, 0);
381  std::vector<double> ech_int_DigiHSTruth(nchMax, 0);
382  std::vector<int> over_gain(nchMax, -1);
383 
384  /* Make a vector of digits (to be filled at the end from m_drawerBuffer arrays) */
385  std::vector<float> digitsBuffer(m_nSamples);
386  std::vector<float> digitsBufferLo(m_nSamples); // for calib runs
387  std::vector<float> digitsBuffer_DigiHSTruth(m_nSamples);
388  std::vector<float> digitsBufferLo_DigiHSTruth(m_nSamples); // for calib runs
389 
390  std::vector<double> emptyBuffer;
391  std::vector<std::vector<double>> drawerBufferHi(nchMax, std::vector<double>(m_nSamples));
392  std::vector<std::vector<double>> drawerBufferLo(nchMax, std::vector<double>(m_nSamples));
393 
394  std::vector<std::vector<double>> drawerBufferHi_DigiHSTruth;
395  std::vector<std::vector<double>> drawerBufferLo_DigiHSTruth;
396  if (m_doDigiTruth) {
397  drawerBufferHi_DigiHSTruth.resize(nchMax, std::vector<double>(m_nSamples));
398  drawerBufferLo_DigiHSTruth.resize(nchMax, std::vector<double>(m_nSamples));
399  }
400 
401 
402  /* everything for calculation of coherent noise */
403  // booleans for coherent noise
404  Bool_t coherNoiseHi = false;
405  Bool_t coherNoiseLo = false;
406  TMatrixD CorrWeightHi;
407  TMatrixD CorrWeightLo;
408  std::vector<std::unique_ptr<double[]>> CorrRndmVec;
409  std::vector<std::unique_ptr<double[]>> CorrRndmVecLo;
410  if (m_tileCoherNoise) {
411  for (int k = 0; k < m_nSamples; ++k) {
412  CorrRndmVec.push_back(std::make_unique<double[]>(nchMax));
413  }
414  if (m_calibRun) {
415  for (int k = 0; k < m_nSamples; ++k) {
416  CorrRndmVecLo.push_back(std::make_unique<double[]>(nchMax));
417  }
418  }
419  }
420 
421  TileMutableDigitsContainer::const_iterator collItrRndm;
422  TileMutableDigitsContainer::const_iterator lastCollRndm;
423  std::unique_ptr<TileMutableDigitsContainer> backgroundDigitContainer{};
424  if (m_rndmEvtOverlay) {
425  backgroundDigitContainer = std::make_unique<TileMutableDigitsContainer>(true,
428  ATH_CHECK( backgroundDigitContainer->status() );
429 
431  typedef PileUpMergeSvc::TimedList<TileDigitsContainer>::type TimedDigitContList;
432  TimedDigitContList digitContList;
434  ATH_MSG_DEBUG( "TileDigitsCnt successfully retrieved ");
435 
436 
437  if (digitContList.size() == 0) {
438  ATH_MSG_WARNING( "No overlay done ... ");
439  return StatusCode::SUCCESS;
440  }
441 
442  TimedDigitContList::iterator iTzeroDigitCont(digitContList.begin());
443  for (const auto* digitCollection : *(iTzeroDigitCont->second)) {
444  for (const auto* digit : *digitCollection) {
445  auto pDigits = std::make_unique<TileDigits>(*digit);
446  ATH_CHECK(backgroundDigitContainer->push_back(std::move(pDigits)));
447  }
448  }
449  }
450  else {
451  SG::ReadHandle<TileDigitsContainer> tileDigitsContainerHandle(m_inputDigitContainerKey, ctx);
452  if (tileDigitsContainerHandle.isValid()) {
453  for (const auto* digitCollection : *tileDigitsContainerHandle) {
454  for (const auto* digit : *digitCollection) {
455  auto pDigits = std::make_unique<TileDigits>(*digit);
456  ATH_CHECK(backgroundDigitContainer->push_back(std::move(pDigits)));
457  }
458  }
459  }
460  else {
461  ATH_MSG_ERROR("ReadHandle to Background Digits is invalid.");
462  return StatusCode::FAILURE;
463  }
464  }
465 
466  collItrRndm = backgroundDigitContainer->begin();
467  lastCollRndm = backgroundDigitContainer->end();
468  }
469 
471  ATH_CHECK( emScale.isValid() );
472 
473  const TilePulse* pulse = nullptr;
474  if (m_useCoolPulseShapes) {
476  ATH_CHECK( pulseShape.isValid() );
477  pulse = pulseShape.retrieve();
478  }
479 
481  ATH_CHECK( samplingFraction.isValid() );
482 
483  const TileDQstatus* dqStatus = nullptr;
484  if (m_rndmEvtOverlay) {
485  SG::ReadHandle<TileDQstatus> DQstatusHandle(m_DQstatusKey, ctx);
486  ATH_CHECK( DQstatusHandle.isValid() );
487  dqStatus = DQstatusHandle.get();
488  }
489 
490  const TileBadChannels* badChannels = nullptr;
493  ATH_CHECK( badChannelsHandle.isValid() );
494  badChannels = badChannelsHandle.retrieve();
495  }
496 
497  // iterate over all collections in a container
498  // Hit Container and signal hit container are the same size (1 entry per channel)
499  TileHitContainer::const_iterator collItr_DigiHSTruth;
500  if(m_doDigiTruth) collItr_DigiHSTruth = hitContainer_DigiHSTruth->begin();
501 
502  /* ----------------------------------------------------------------- */
503  /* Begin loop over the Hit collections. All collections are defined */
504  /* (even if they have no hits), and all the digit information */
505  /* including pileup events are contained in the collection. */
506  /*-------------------------------------------------------------------*/
507  for (const TileHitCollection* hitCollection : *hitContainer) {
508  /* Get array of HWID's for this drawer (stored locally). */
509  HWIdentifier drawer_id = m_tileHWID->drawer_id(hitCollection->identify());
510  int ros = m_tileHWID->ros(drawer_id);
511  int drawer = m_tileHWID->drawer(drawer_id);
512  int drawerIdx = TileCalibUtils::getDrawerIdx(ros, drawer);
513  if (m_cabling->connected(ros, drawer)) {
514  ATH_MSG_VERBOSE( "ROS "<< ros << " drawer " << drawer << " is connected");
515  } else {
516  if (m_rndmEvtOverlay && collItrRndm != lastCollRndm) {
517  ++collItrRndm; // skip also one drawer in digi overlay container
518  }
519  if (m_doDigiTruth) {
520  ++collItr_DigiHSTruth;
521  } // End DigiHSTruth stuff
522  continue;
523  }
524 
525  m_tileHWID->get_hash(drawer_id, idhash, &drawer_context);
526  const std::unique_ptr<HWIdentifier[]>& adc_ids = m_all_ids[idhash];
527 
528  /* Initialize gain settings. If noise is requested, all channels are */
529  /* set to be active. If not, set them all to be inactive (gain=-1). */
530  /* Only those which contain actual hits will be set active when the */
531  /* hits are read in. */
532  int igainch = (m_allChannels) ? TileID::HIGHGAIN : -1;
533  if (m_rndmEvtOverlay) {
534  std::fill(over_gain.begin(), over_gain.end(), -1);
535  } else if (m_tileNoise || m_tileCoherNoise) {
536  igainch = TileID::HIGHGAIN;
537  }
538 
539  std::fill(ech_tot.begin(), ech_tot.end(), 0.0);
540  std::fill(ech_int.begin(), ech_int.end(), 0.0);
541  std::fill(ntot_ch.begin(), ntot_ch.end(), 0);
542  std::fill(igain.begin(), igain.end(), igainch);
543 
544  std::vector<std::reference_wrapper<std::vector<std::vector<double>>>> drawerBuffers{drawerBufferHi, drawerBufferLo};
545  if (m_doDigiTruth) {
546  drawerBuffers.push_back(drawerBufferHi_DigiHSTruth);
547  drawerBuffers.push_back(drawerBufferLo_DigiHSTruth);
548  }
549  for (std::vector<std::vector<double>>& drawerBuffer : drawerBuffers) {
550  for (std::vector<double>& digitsBuffer : drawerBuffer) {
551  std::fill(digitsBuffer.begin(), digitsBuffer.end(), 0);
552  }
553  }
554 
555  if (m_rndmEvtOverlay && collItrRndm != lastCollRndm) {
556  const TileDigitsCollection *bkgDigitCollection(*collItrRndm);
557  ATH_CHECK(overlayBackgroundDigits(bkgDigitCollection, hitCollection, drawerBufferLo, drawerBufferHi,
558  igain, ros, drawer, drawerIdx, over_gain, *emScale, *sampleNoise, dqStatus, badChannels));
559  ++collItrRndm; // skip to next digi collection
560  }
561 
562  std::vector<bool> signal_in_channel(nchMax, false);
563  std::vector<bool> signal_in_channel_DigiHSTruth(nchMax, false);
564  ATH_CHECK(fillDigitCollection( hitCollection, drawerBufferLo, drawerBufferHi,
565  igain, over_gain, ech_int, signal_in_channel, *emScale, *samplingFraction, pulse));
566  if(m_doDigiTruth){
567  ATH_CHECK(fillDigitCollection( *collItr_DigiHSTruth, drawerBufferLo_DigiHSTruth, drawerBufferHi_DigiHSTruth,
568  igain, over_gain, ech_int_DigiHSTruth, signal_in_channel_DigiHSTruth, *emScale, *samplingFraction, pulse));
569  } // End DigiHSTruth stuff
570 
571  /* Now all signals for this collection are stored in m_drawerBuffer,
572  accessed with digitSamplesHi and digitSampleLo. */
573  if (msgLvl(MSG::VERBOSE)) {
574  for (int ich = 0; ich < nchMax; ++ich) {
575  if (igain[ich] > -1) {
576  std::vector<double>& digitSamplesHi = drawerBufferHi[ich];
577  std::vector<double>& digitSamplesLo = drawerBufferLo[ich];
578  msg(MSG::VERBOSE) << "total: ADC " << m_tileHWID->to_string(adc_ids[ich],-1) << "/" << igain[ich]
579  << " nhit=" << ntot_ch[ich]
580  << " e_ch=" << ech_tot[ich]
581  << " AinTHi=" << digitSamplesHi[m_iTrig]
582  << " AinTLo=" << digitSamplesLo[m_iTrig] << endmsg;
583  }
584  }
585  }
586 
587  /* --------------------------------------------------------------- */
588  /* Now all signals for this drawer are stored in m_drawerBuffer arrays, */
589  /* and we are finished with TileHits for this collection. Loop over */
590  /* channels to add noise and pedestal. Check for saturation for */
591  /* each channel, and in case of saturation convert to low gain. */
592  /* -------------------------------------------------------------- */
593 
594  // =============CORRELATION MODIFICATION (F Spano)==============
595  //
596  // Define CoVariance Matrix corresponding to noise.
597  // TO UPDATE:: Such Matrix will have to be loaded from database in the future; 1 matrix per drawer.
598  // NOW:
599  // a) define one covariance matrix
600  // b) find Cholesky decomposition use for corrlation building
601  // if this is set load the matrix
602  if (m_tileCoherNoise) {
603  ATH_MSG_VERBOSE( "Coherent noise for ROS " << ros
604  << " drawer " << drawer
605  << " with " << nchMax << " channels and "
606  << m_nSamples << "samples ");
607 
608  // get decomposed covariance matrix for hi gain
609  coherNoiseHi = 1;
610  if (coherNoiseHi) {
611  CorrWeightHi.ResizeTo(*(m_tileInfo->DecoCovariance(ros, drawer, TileID::HIGHGAIN)));
612  CorrWeightHi = *(m_tileInfo->DecoCovariance(ros, drawer, TileID::HIGHGAIN));
613  }
614 
615  // get decomposed covariance matrix for low gain
616  coherNoiseLo = 1;
617  if (coherNoiseLo) {
618  CorrWeightLo.ResizeTo(*(m_tileInfo->DecoCovariance(ros, drawer, TileID::LOWGAIN)));
619  CorrWeightLo = *(m_tileInfo->DecoCovariance(ros, drawer, TileID::LOWGAIN));
620  }
621 
622  //NOTE: ShootArray's inputs are : the engine, the size, the vector, the mean, the standard dev
623  for (int k = 0; k < m_nSamples; ++k) {
624  double* RndmVec = CorrRndmVec[k].get();
625  RandGaussQ::shootArray(rngEngine, nchMax, RndmVec, 0.0, 1.0);
626  }
627 
628  if (m_calibRun) {
629  for (int k = 0; k < m_nSamples; ++k) {
630  double * RndmVecLo = CorrRndmVecLo[k].get();
631  RandGaussQ::shootArray(rngEngine, nchMax, RndmVecLo, 0.0, 1.0);
632  }
633  }
634  }
635  // =============CORRELATION MODIFICATION (F Spano)============== end
636 
637  // looping over channels
638  for (int ich = 0; ich < nchMax; ++ich) {
639  /* If igain<0, channel is inactive => skip it. */
640  if (igain[ich] < 0)
641  continue;
642 
643  /* Generate the nSamp Digits for high gain. Check each for saturation. */
644  ++nChHiSum;
645  HWIdentifier adc_id = adc_ids[ich];
646  HWIdentifier adc_id_lo; // for calib runs
647  Identifier pmt_id = m_cabling->h2s_pmt_id(adc_id);
648  ATH_MSG_DEBUG( "Ch " << m_tileHWID->to_string(adc_id,-1)
649  << " PMT " << (pmt_id.is_valid() ? m_tileID->to_string(pmt_id,-1) : (signal_in_channel[ich] ? "fake gap" : "not connected"))
650  << " gain=" << igain[ich]);
651 
652  if (m_calibRun || m_maskBadChannels) {
653  adc_id_lo = m_tileHWID->adc_id(drawer_id, ich, TileID::LOWGAIN);
654  if (m_calibRun) {
655  ++nChLoSum;
656  }
657  }
658 
659  bool chanLoIsBad = false;
660  bool chanHiIsBad = false;
661  if (m_maskBadChannels) {
662  TileBchStatus statusLo = badChannels->getAdcStatus(adc_id_lo);
663  TileBchStatus statusHi = badChannels->getAdcStatus(adc_id);
664  chanLoIsBad = statusLo.isBad();
665  chanHiIsBad = statusHi.isBad();
666  }
667 
668  /* Get pedestal and noise values */
669  double pedSimHi(0.), sigmaHi_Hfn1(0.), sigmaHi_Hfn2(0.), sigmaHi_Norm(0.), pedSimLo(0.),
670  sigmaLo_Hfn1(0.), sigmaLo_Hfn2(0.), sigmaLo_Norm(0.);
671  bool good_ch = (over_gain[ich]<9);
672  bool overNoiseHG(over_gain[ich]!=TileID::HIGHGAIN && good_ch); // it's always true if no overlay
673  bool overNoiseLG(over_gain[ich]!=TileID::LOWGAIN && good_ch); // it's always true if no overlay
674  bool tileNoiseHG(false),tileNoiseLG(false);
675 
676  if (overNoiseHG) {
677  overNoiseHG &= (m_rndmEvtOverlay && m_allChannels>1); // set it to true only for overlay
678  tileNoiseHG = m_tileNoise || overNoiseHG;
679 
680  pedSimHi = sampleNoise->getPed(idhash, ich, TileID::HIGHGAIN);
681  // bug fix for wrong ped value in DB
682  if (pedSimHi == 0.0 && (signal_in_channel[ich] || pmt_id.is_valid()))
683  pedSimHi = 50.;
684 
685  sigmaHi_Hfn1 = sampleNoise->getHfn1(idhash, ich, TileID::HIGHGAIN);
686  sigmaHi_Hfn2 = sampleNoise->getHfn2(idhash, ich, TileID::HIGHGAIN);
687  if (sigmaHi_Hfn1>0 || sigmaHi_Hfn2) {
688  sigmaHi_Norm = sigmaHi_Hfn1 / (sigmaHi_Hfn1
689  + sigmaHi_Hfn2 * sampleNoise->getHfnNorm(idhash, ich, TileID::HIGHGAIN));
690  } else {
691  sigmaHi_Hfn1 = sampleNoise->getHfn(idhash, ich, TileID::HIGHGAIN);
692  sigmaHi_Norm = 1.;
693  }
694  }
695 
696  if (overNoiseLG) {
697  overNoiseLG &= (m_rndmEvtOverlay && m_allChannels>1); // set it to true only for overlay
698  tileNoiseLG = m_tileNoise || overNoiseLG;
699 
700  pedSimLo = sampleNoise->getPed(idhash, ich, TileID::LOWGAIN);
701  // bug fix for wrong ped value in DB
702  if (pedSimLo == 0.0 && (signal_in_channel[ich] || pmt_id.is_valid()))
703  pedSimLo = 30.;
704 
705  sigmaLo_Hfn1 = sampleNoise->getHfn1(idhash, ich, TileID::LOWGAIN);
706  sigmaLo_Hfn2 = sampleNoise->getHfn2(idhash, ich, TileID::LOWGAIN);
707  if (sigmaLo_Hfn1 > 0 || sigmaLo_Hfn2) {
708  sigmaLo_Norm = sigmaLo_Hfn1 / (sigmaLo_Hfn1
709  + sigmaLo_Hfn2 * sampleNoise->getHfnNorm(idhash, ich, TileID::LOWGAIN));
710  } else {
711  sigmaLo_Hfn1 = sampleNoise->getHfn(idhash, ich, TileID::LOWGAIN);
712  sigmaLo_Norm = 1.;
713  }
714  }
715 
716  /* If tileNoise is requested, generate array of random numbers. */
717  if (tileNoiseLG) { // true if tileNoise is set or noise is needed for low gain in overlay
718  RandGaussQ::shootArray(rngEngine, m_nSamples, Rndm, 0.0, 1.0);
719  RandFlat::shootArray(rngEngine, 1, Rndm_dG, 0.0, 1.0);
720  if (m_calibRun) {
721  RandGaussQ::shootArray(rngEngine, m_nSamples, RndmLo, 0.0, 1.0);
722  RandFlat::shootArray(rngEngine, 1, RndmLo_dG, 0.0, 1.0);
723  }
724  }
725 
726  std::vector<double>& digitSamplesHi = drawerBufferHi[ich];
727  std::vector<double>& digitSamplesLo = drawerBufferLo[ich];
728  std::vector<double>& digitSamplesHi_DigiHSTruth = (m_doDigiTruth) ? drawerBufferHi_DigiHSTruth[ich] : emptyBuffer;
729  std::vector<double>& digitSamplesLo_DigiHSTruth = (m_doDigiTruth) ? drawerBufferLo_DigiHSTruth[ich] : emptyBuffer;
730 
731  ATH_MSG_DEBUG(" Channel " << ros << '/' << drawer << '/' << ich
732  << " sampHi=" << digitSamplesHi[m_iTrig]
733  << " pedHi=" << pedSimHi
734  << " sampLo=" << digitSamplesLo[m_iTrig]
735  << " pedLo=" << pedSimLo);
736 
737  // looping over samples
738  for (int js = 0; js < m_nSamples; ++js) {
739 
740  digitsBuffer[js] = digitSamplesHi[js] + pedSimHi;
741  if(m_doDigiTruth) {
742  digitsBuffer_DigiHSTruth[js] = digitSamplesHi_DigiHSTruth[js] + pedSimHi;
743  }
744 
745  double noiseHi(0.0);
746  // Full noise pattern, including coherent noise has priority over normal noise //F Spano'
747  if (coherNoiseHi) {
748  // get the js-th correct random vector of 48 elements for the jsth sample k //F Spano'
749  std::unique_ptr<double[]>& CorVec = CorrRndmVec[js];
750  // apply Y=C*Z where Z is the random vector of 48 normal indep variables, and C is the Cholesky decomposition //F Spano'
751  for (int i = 0; i < nchMax; ++i) noiseHi += CorrWeightHi(i, ich) * CorVec[i];
752  } else if (tileNoiseHG) {
753  //using the same gaussian(sigma) for all samples in one channel in one event
754  if (Rndm_dG[0] < sigmaHi_Norm) noiseHi = sigmaHi_Hfn1 * Rndm[js];
755  else noiseHi = sigmaHi_Hfn2 * Rndm[js];
756  }
757 
758  if (digitsBuffer[js] + noiseHi >= 0.0) {
759  digitsBuffer[js] += noiseHi;
760  if(m_doDigiTruth) digitsBuffer_DigiHSTruth[js] += noiseHi;
761  } else {
762  digitsBuffer[js] -= noiseHi;
763  if(m_doDigiTruth) digitsBuffer_DigiHSTruth[js] -= noiseHi;
764  }
765 
766 
767  if (m_integerDigits) {
768  digitsBuffer[js] = round(digitsBuffer[js]);
769  if(m_doDigiTruth) digitsBuffer_DigiHSTruth[js] = round(digitsBuffer_DigiHSTruth[js]);
770  }
771 
772  if (m_calibRun) { //Calculate also low gain
773  digitsBufferLo[js] = digitSamplesLo[js] + pedSimLo;
774  if(m_doDigiTruth) digitsBufferLo_DigiHSTruth[js] = digitSamplesLo_DigiHSTruth[js] + pedSimLo;
775  double noiseLo(0.0);
776  // Full noise pattern, including coherent noise has priority over normal noise //F Spano'
777  if (coherNoiseLo) {
778  // get the js-th correct random vector of 48 elements for the jsth sample // F Spano'
779  std::unique_ptr<double[]>& CorVecLo = CorrRndmVecLo[js];
780  // apply Y=C*Z where Z is the random vector of 48 normal indep variables, and C is the Cholesky decomposition // F Spano'
781  for (int i = 0; i < nchMax; ++i) noiseLo += CorrWeightLo(i, ich) * CorVecLo[i];
782  } else if (tileNoiseLG) {
783  //using the same gaussian (sigma) for all samples in one channel in one event
784  if (RndmLo_dG[0] < sigmaLo_Norm) noiseLo = sigmaLo_Hfn1 * RndmLo[js];
785  else noiseLo = sigmaLo_Hfn2 * RndmLo[js];
786  }
787 
788  if (digitsBufferLo[js] + noiseLo >= 0.0) {
789  digitsBufferLo[js] += noiseLo;
790  if(m_doDigiTruth) digitsBufferLo_DigiHSTruth[js] += noiseLo;
791  } else {
792  digitsBufferLo[js] -= noiseLo;
793  if(m_doDigiTruth) digitsBufferLo_DigiHSTruth[js] -= noiseLo;
794  }
795 
796  if (m_integerDigits) {
797  digitsBufferLo[js] = round(digitsBufferLo[js]);
798  if(m_doDigiTruth) digitsBufferLo_DigiHSTruth[js] = round(digitsBufferLo_DigiHSTruth[js]);
799  }
800 
801 
802  } else if ((digitsBuffer[js] >= m_f_ADCmaxHG && good_ch) || igain[ich] == TileID::LOWGAIN) { // saturation of high gain in non-calib run
803  // or low gain in digi overlay
804  --nChHiSum;
805  ++nChLoSum;
806  igain[ich] = TileID::LOWGAIN;
807  adc_id = m_tileHWID->adc_id(drawer_id, ich, TileID::LOWGAIN);
808 
809  // reset all samples in digitsBuffer[] to Low Gain values
810  for (js = 0; js < m_nSamples; ++js) {
811  digitsBuffer[js] = digitSamplesLo[js] + pedSimLo;
812  if(m_doDigiTruth) digitsBuffer_DigiHSTruth[js] = digitSamplesLo_DigiHSTruth[js] + pedSimLo;
813  double noiseLo(0.0);
814  // Full noise pattern, including coherent noise has priority over normal noise //F Spano'
815  if (coherNoiseLo) {
816  // get the js-th correct random vector of 48 elements for the jsth sample // F Spano'
817  double* CorVec = CorrRndmVec[js].get(); // reuse the same rndm as for high gain
818  // apply Y=C*Z where Z is the random vector of 48 normal indep variables, and C is the Cholesky decomposition // F Spano'
819  for (int i = 0; i < nchMax; ++i) noiseLo += CorrWeightLo(i, ich) * CorVec[i];
820  } else if (tileNoiseLG) {
821  //using the same gaussian (sigma) for all samples in one channel in one event
822  // reuse the same rndm as for high gain
823  if (Rndm_dG[0] < sigmaLo_Norm) noiseLo = sigmaLo_Hfn1 * Rndm[js];
824  else noiseLo = sigmaLo_Hfn2 * Rndm[js];
825  }
826 
827  if (digitsBuffer[js] + noiseLo >= 0.0) {
828  digitsBuffer[js] += noiseLo;
829  if(m_doDigiTruth) digitsBuffer_DigiHSTruth[js] += noiseLo;
830  } else {
831  digitsBuffer[js] -= noiseLo;
832  if(m_doDigiTruth) digitsBuffer_DigiHSTruth[js] -= noiseLo;
833  }
834 
835  if (digitsBuffer[js] > m_f_ADCmax && good_ch) {
836  digitsBuffer[js] = m_f_ADCmax;
837  if(m_doDigiTruth) digitsBuffer_DigiHSTruth[js] = m_f_ADCmax;
838  }
839  if (m_integerDigits) {
840  digitsBuffer[js] = round(digitsBuffer[js]);
841  if(m_doDigiTruth) digitsBuffer_DigiHSTruth[js] = round(digitsBuffer_DigiHSTruth[js]);
842  }
843  }
844 
845  overNoiseHG = false;
846 
847  if (msgLvl(MSG::VERBOSE)) {
848  msg(MSG::VERBOSE) << "Channel " << ros << '/' << drawer << '/' << ich << "/" << igain[ich]
849  << " Switch to low gain Amp(lo)=" << digitsBuffer[m_iTrig] << endmsg;
850  if (overNoiseLG) {
851  if (sigmaLo_Norm<1.0) {
852  msg(MSG::VERBOSE) << "LG Ped & noise from DB "
853  << pedSimLo << " " << sigmaLo_Hfn1 << " " << sigmaLo_Hfn2 << " " << sigmaLo_Norm
854  << ((Rndm_dG[0] < sigmaLo_Norm)?(" sig1 used"):(" sig2 used")) << endmsg;
855  } else {
856  msg(MSG::VERBOSE) << "LG Ped & noise from DB "
857  << pedSimLo << " " << sigmaLo_Hfn1 << endmsg;
858  }
859  }
860  }
861  break;
862  }
863  }
864  if (msgLvl(MSG::VERBOSE)) {
865  if (overNoiseHG) {
866  if (sigmaHi_Norm<1.0) {
867  msg(MSG::VERBOSE) << "HG Ped & noise from DB "
868  << pedSimHi << " " << sigmaHi_Hfn1 << " " << sigmaHi_Hfn2 << " " << sigmaHi_Norm
869  << ((Rndm_dG[0] < sigmaHi_Norm)?(" sig1 used"):(" sig2 used")) << endmsg;
870  } else {
871  msg(MSG::VERBOSE) << "HG Ped & noise from DB "
872  << pedSimHi << " " << sigmaHi_Hfn1 << endmsg;
873  }
874  }
875  if (m_calibRun && overNoiseLG) {
876  if (sigmaLo_Norm<1.0) {
877  msg(MSG::VERBOSE) << "LG Ped & noise from DB "
878  << pedSimLo << " " << sigmaLo_Hfn1 << " " << sigmaLo_Hfn2 << " " << sigmaLo_Norm
879  << ((RndmLo_dG[0] < sigmaLo_Norm)?(" sig1 used"):(" sig2 used")) << endmsg;
880  } else {
881  msg(MSG::VERBOSE) << "LG Ped & noise from DB "
882  << pedSimLo << " " << sigmaLo_Hfn1 << endmsg;
883  }
884  }
885  }
886 
887  if (m_calibRun) { // calib run - keep both low and high gain
888 
889  if (chanHiIsBad) {
890  std::fill(digitsBuffer.begin(), digitsBuffer.end(), m_f_ADCmaskValue);
891  if (m_doDigiTruth) {
892  std::fill(digitsBuffer_DigiHSTruth.begin(), digitsBuffer_DigiHSTruth.end(), m_f_ADCmaskValue);
893  }
894  ATH_MSG_DEBUG( "Masking Channel " << ros << '/' << drawer << '/' << ich << "/1 HG" );
895  }
896 
897  auto pDigits = std::make_unique<TileDigits>(adc_id, digitsBuffer);
898  ATH_CHECK( digitsContainer->push_back(std::move(pDigits)) );
899 
900  if(m_doDigiTruth && digitsContainer_DigiHSTruth){
901  auto digits_DigiHSTruth = std::make_unique<TileDigits>(adc_id, digitsBuffer_DigiHSTruth);
902  ATH_CHECK( digitsContainer_DigiHSTruth->push_back(std::move(digits_DigiHSTruth)) );
903  }
904 
905  if (chanLoIsBad) {
906  std::fill(digitsBufferLo.begin(), digitsBufferLo.end(), m_f_ADCmaskValue);
907  if(m_doDigiTruth) {
908  std::fill(digitsBufferLo_DigiHSTruth.begin(), digitsBufferLo_DigiHSTruth.end(), m_f_ADCmaskValue);
909  }
910 
911  ATH_MSG_DEBUG( "Masking Channel " << ros << '/' << drawer << '/' << ich << "/0 LG");
912  }
913 
914  auto pDigitsLo = std::make_unique<TileDigits>(adc_id_lo, digitsBufferLo);
915  ATH_CHECK( digitsContainer->push_back(std::move(pDigitsLo)) );
916 
917  if(m_doDigiTruth && digitsContainer_DigiHSTruth){
918  auto pDigitsLo_DigiHSTruth = std::make_unique<TileDigits>(adc_id_lo, digitsBufferLo_DigiHSTruth);
919  ATH_CHECK( digitsContainer_DigiHSTruth->push_back(std::move(pDigitsLo_DigiHSTruth)) );
920  }
921  } else { //normal run
922 
923  bool hiGain = (igain[ich] == TileID::HIGHGAIN);
924 
925  // If tileThresh, apply threshold cut to the in-time Digits signal
926  bool isChannelGood = true;
927  if (m_tileThresh) {
928  if (hiGain) { // make threshold only on high gain
929  double ampInTime = digitsBuffer[m_iTrig] - pedSimHi;
930  if (m_integerDigits)
931  ampInTime = round(ampInTime);
932  if (m_tileThreshHi < 0) {
933  if (fabs(ampInTime) < fabs(m_tileThreshHi))
934  isChannelGood = false;
935  } else {
936  if (ampInTime < m_tileThreshHi)
937  isChannelGood = false;
938  }
939  }
940  }
941  // If channel is good, create TileDigits object and store in container.
942  if (isChannelGood) {
943  echtot_Acc += ech_tot[ich];
944  echint_Acc += fabs(ech_int[ich]);
945  if (hiGain) {
946  ++nChHiAcc;
947  } else {
948  ++nChLoAcc;
949  }
950 
951  if (hiGain) {
952  //if (m_rndmEvtOverlay // not needed, because DQstatus have been already checked before
953  // && !(theDQstatus->isAdcDQgood(ros, drawer, ich, TileID::HIGHGAIN))) {
954  // chanHiIsBad = true;
955  // ATH_MSG_DEBUG( "BAD DQ Channel " << ros << '/' << drawer << '/' << ich << "/1 HG");
956  //}
957  if (chanHiIsBad) {
958  if (pmt_id.is_valid()) {
959  std::fill(digitsBuffer.begin(), digitsBuffer.end(), m_f_ADCmaskValue);
960  if (m_doDigiTruth) {
961  std::fill(digitsBuffer_DigiHSTruth.begin(), digitsBuffer_DigiHSTruth.end(), m_f_ADCmaskValue);
962  }
963  } else if (good_ch) {
964  ATH_MSG_DEBUG( "Disconnected Channel " << ros << '/' << drawer << '/' << ich);
965  std::fill(digitsBuffer.begin(), digitsBuffer.end(), 0.);
966  if (m_doDigiTruth) {
967  std::fill(digitsBuffer_DigiHSTruth.begin(), digitsBuffer_DigiHSTruth.end(), 0.);
968  }
969  }
970  ATH_MSG_DEBUG( "Masking Channel " << ros << '/' << drawer << '/' << ich << "/1 HG");
971  }
972  } else {
973  //if (m_rndmEvtOverlay // not needed, because DQstatus have been already checked before
974  // && !(theDQstatus->isAdcDQgood(ros, drawer, ich, TileID::LOWGAIN))) {
975  // chanLoIsBad = true;
976  // ATH_MSG_DEBUG( "BAD DQ Channel " << ros << '/' << drawer << '/' << ich << "/0 LG");
977  //}
978  if (chanLoIsBad) {
979  if (pmt_id.is_valid()) {
980  std::fill(digitsBuffer.begin(), digitsBuffer.end(), m_f_ADCmaskValue);
981  if (m_doDigiTruth) {
982  std::fill(digitsBuffer_DigiHSTruth.begin(), digitsBuffer_DigiHSTruth.end(), m_f_ADCmaskValue);
983  }
984  } else if (good_ch) {
985  ATH_MSG_DEBUG( "Disconnected Channel " << ros << '/' << drawer << '/' << ich);
986  std::fill(digitsBuffer.begin(), digitsBuffer.end(), 0.);
987  if (m_doDigiTruth) {
988  std::fill(digitsBuffer_DigiHSTruth.begin(), digitsBuffer_DigiHSTruth.end(), 0.);
989  }
990  }
991  ATH_MSG_DEBUG( "Masking Channel " << ros << '/' << drawer << '/' << ich << "/0 LG");
992  }
993  }
994 
995  auto pDigits = std::make_unique<TileDigits>(adc_id, digitsBuffer);
996 
997  if (ech_int[ich] > m_filterThreshold || ech_int[ich] < -m_filterThresholdMBTS) {
998  if (filteredContainer) ATH_CHECK( filteredContainer->push_back(pDigits.get()) );
999  if (hiGain) {
1000  ++nChHiFlt;
1001  } else {
1002  ++nChLoFlt;
1003  }
1004  }
1005 
1006  ATH_CHECK( digitsContainer->push_back(std::move(pDigits)) );
1007  if(m_doDigiTruth && digitsContainer_DigiHSTruth){
1008  auto pDigits_DigiHSTruth = std::make_unique<TileDigits>(adc_id, digitsBuffer_DigiHSTruth);
1009  ATH_CHECK( digitsContainer_DigiHSTruth->push_back(std::move(pDigits_DigiHSTruth)) );
1010  }
1011 
1012  if (msgLvl(MSG::VERBOSE)) {
1013  double pedSim = ((hiGain) ? pedSimHi : pedSimLo);
1014  double ampInTime = digitsBuffer[m_iTrig] - pedSim;
1015  if (m_integerDigits)
1016  ampInTime = round(ampInTime);
1017  msg(MSG::VERBOSE) << ((ech_int[ich] > m_filterThreshold
1018  || ech_int[ich] < -m_filterThresholdMBTS) ? "AccFlt" : "Accept")
1019  << " ADC " << m_tileHWID->to_string(adc_id)
1020  << " AinT=" << ampInTime
1021  << " ped=" << pedSim
1022  << " Ech=" << ech_tot[ich]
1023  << " EinT=" << ech_int[ich] << endmsg;
1024  msg(MSG::VERBOSE) << "digits";
1025  for (unsigned int i = 0; i < digitsBuffer.size(); ++i)
1026  msg(MSG::VERBOSE) << " " << digitsBuffer[i];
1027  msg(MSG::VERBOSE) << endmsg;
1028  }
1029  } else {
1030  echtot_Cut += ech_tot[ich];
1031  echint_Cut += ech_int[ich];
1032  if (hiGain) {
1033  ++nChHiCut;
1034  } else {
1035  ++nChLoCut;
1036  }
1037 
1038  if (msgLvl(MSG::VERBOSE)) {
1039  double pedSim = ((hiGain) ? pedSimHi : pedSimLo);
1040  double ampInTime = digitsBuffer[m_iTrig] - pedSim;
1041  if (m_integerDigits)
1042  ampInTime = round(ampInTime);
1043  msg(MSG::VERBOSE) << "Reject. ADC " << m_tileHWID->to_string(adc_id)
1044  << " AinT=" << ampInTime
1045  << " ped=" << pedSim
1046  << " Ech=" << ech_tot[ich]
1047  << " EinT=" << ech_int[ich] << endmsg;
1048  }
1049  }
1050  }
1051  }
1052  if(m_doDigiTruth) ++collItr_DigiHSTruth;
1053  }
1054 
1055  if (msgLvl(MSG::DEBUG)) {
1056  msg(MSG::DEBUG) << "TileDigitsMaker execution completed." << endmsg;
1057  msg(MSG::DEBUG) << " nCh=" << nChSum
1058  << " nChH/L=" << nChHiSum << "/" << nChLoSum
1059  << " nFltH/L=" << nChHiFlt << "/" << nChLoFlt
1060  << " Hit=" << HitSum
1061  << " Ene=" << EneSum
1062  << " RChSum=" << RChSum << endmsg;
1063  if (m_tileThresh) {
1064  msg(MSG::DEBUG) << " Accepted: nChLo/Hi=" << nChLoAcc << "/" << nChHiAcc
1065  << " eTot=" << echtot_Acc
1066  << " eInT=" << echint_Acc << endmsg;
1067  msg(MSG::DEBUG) << " Rejected: nChLo/Hi=" << nChLoCut << "/" << nChHiCut
1068  << " eTot=" << echtot_Cut
1069  << " eInT=" << echint_Cut << endmsg;
1070  }
1071  }
1072 
1073 
1074  // step3: register the Digit container in the TES
1076  ATH_CHECK( digitsCnt.record(std::move(digitsContainer)) );
1077 
1078  if(m_doDigiTruth && digitsContainer_DigiHSTruth){
1080  ATH_CHECK( digits_DigiHSTruth.record(std::move(digitsContainer_DigiHSTruth)) );
1081  }
1082 
1083  if (filteredContainer) {
1085  ATH_CHECK( filteredDigitsContainer.record(std::move(filteredContainer)) );
1086  }
1087 
1088  return StatusCode::SUCCESS;
1089 }
1090 
1092  ATH_MSG_INFO( "TileDigitsMaker finalized successfully");
1093 
1094  return StatusCode::SUCCESS;
1095 }
1096 
1098  std::vector<std::vector<double>>& drawerBufferLo,
1099  std::vector<std::vector<double>>& drawerBufferHi,
1100  std::vector<int>& igain, std::vector<int>& over_gain, std::vector<double>& ech_int,
1101  std::vector<bool> &signal_in_channel, const TileEMScale* emScale,
1102  const TileSamplingFraction* samplingFraction, const TilePulse* pulse) const{
1103 
1104  constexpr int nchMax = 48; // number of channels per drawer
1105  std::array<int, nchMax> ntot_ch; ntot_ch.fill(0);
1106  std::array<double, nchMax> ech_tot; ech_tot.fill(0.0);
1107  //double ech_int[nchMax];
1108 
1109  IdContext drawer_context = m_tileHWID->drawer_context();
1110 
1111  /* Set up buffers for handling information in a single collection. */
1112  HWIdentifier drawer_id = m_tileHWID->drawer_id(hitCollection->identify());
1113  int ros = m_tileHWID->ros(drawer_id);
1114  int drawer = m_tileHWID->drawer(drawer_id);
1115  int drawerIdx = TileCalibUtils::getDrawerIdx(ros, drawer);
1116 
1117 
1118  // iterate over all hits in a collection
1119  for (const TileHit* tileHit : *hitCollection) {
1120 
1121  /* Get hit Identifier (= pmt_ID) and needed parameters for this channel */
1122  Identifier pmt_id = tileHit->pmt_ID();
1123  double mbts_extra_factor = (m_tileTBID->is_tiletb(pmt_id)) ? -1.0 : 1.0;
1124  HWIdentifier channel_id = tileHit->pmt_HWID();
1125  int ich = m_tileHWID->channel(channel_id);
1126  signal_in_channel[ich] = true;
1127 
1128  if (over_gain[ich] > 9) {
1129  if (msgLvl(MSG::DEBUG)) {
1130  int n_hits = tileHit->size();
1131  double e_hit(0.);
1132  for (int ihit = 0; ihit < n_hits; ++ihit) {
1133  e_hit += tileHit->energy(ihit);
1134  }
1135  e_hit *= std::round(samplingFraction->getSamplingFraction(drawerIdx, ich) * 1000) / 1000;
1136  ech_tot[ich] += e_hit;
1137  ntot_ch[ich] += n_hits;
1138  ATH_MSG_VERBOSE("BAD Overlay digits - skip hit in channel " << m_tileHWID->to_string(channel_id,-1));
1139  }
1140  continue;
1141  } else {
1142  ATH_MSG_VERBOSE("new hit in channel " << m_tileHWID->to_string(channel_id,-1));
1143  }
1144 
1145  /* Set gain=high and get digitSamples and calibration for this channel. */
1146  if (igain[ich] < 0)
1147  igain[ich] = TileID::HIGHGAIN;
1148  // conversion from scintillator energy to total cell energy (sampling fraction)
1149  double hit_calib = samplingFraction->getSamplingFraction(drawerIdx, ich);
1150  hit_calib = std::round(hit_calib * 1000) / 1000;
1151 
1152  // conversion to ADC counts for high gain
1153  double efactorHi = hit_calib / emScale->calibrateChannel(drawerIdx, ich, TileID::HIGHGAIN, 1.
1155  // conversion to ADC counts for low gain
1156  double efactorLo = hit_calib / emScale->calibrateChannel(drawerIdx, ich, TileID::LOWGAIN, 1.
1158 
1159  std::vector<double>& digitSamplesHi = drawerBufferHi[ich];
1160  std::vector<double>& digitSamplesLo = drawerBufferLo[ich];
1161  /* Loop over the subhits for this channel. For each one,
1162  convolute with shaping function and add to digitSamples. */
1163  int n_hits = tileHit->size();
1164  for (int ihit = 0; ihit < n_hits; ++ihit) {
1165  /* Get hit energy and convert to amplitude of high-gain and low-gain channel */
1166  double e_hit = tileHit->energy(ihit);
1167  double amp_ch = e_hit * efactorHi;
1168  double amp_ch_lo = e_hit * efactorLo;
1169  double ech_sub = e_hit * hit_calib;
1170  double t_hit = tileHit->time(ihit);
1171 
1172  ech_tot[ich] += ech_sub;
1173  if (fabs(t_hit) < 50.0) // ene within +/- 50 ns, used for filtered digits cut
1174  ech_int[ich] += ech_sub * mbts_extra_factor;
1175  ntot_ch[ich] += 1;
1176 
1177  // Assume time is in nanoseconds, use fine-grain shaping:
1178  int ishiftHi = (int) (t_hit / m_timeStepHi + 0.5);
1179  for (int js = 0; js < m_nSamples; ++js) {
1180  int k = m_binTime0Hi + (js - m_iTrig) * m_nBinsPerXHi - ishiftHi;
1181  if (k < 0)
1182  k = 0;
1183  else if (k > m_nShapeHi)
1184  k = m_nShapeHi;
1185 
1186  if (m_useCoolPulseShapes) {
1187  float phase = (k - m_binTime0Hi) * m_timeStepHi;
1188  float y, dy;
1189  pulse->getPulseShapeYDY(drawerIdx, ich, 1, phase, y, dy);
1190  double ampl = (double) y;
1191  digitSamplesHi[js] += amp_ch * ampl;
1192  ATH_MSG_VERBOSE( "Sample no.=" << js
1193  << " Pulse index=" << k
1194  << " Shape wt. =" << ampl
1195  << " HIGAIN from COOL");
1196 
1197  } else {
1198  digitSamplesHi[js] += amp_ch * m_digitShapeHi[k];
1199  ATH_MSG_VERBOSE( "Sample no.=" << js
1200  << " Pulse index=" << k
1201  << " Shape wt. =" << m_digitShapeHi[k]
1202  << " HIGAIN from TileInfo");
1203  }
1204 
1205  }
1206  int ishiftLo = (int) (t_hit / m_timeStepLo + 0.5);
1207  for (int js = 0; js < m_nSamples; ++js) {
1208  int k = m_binTime0Lo + (js - m_iTrig) * m_nBinsPerXLo - ishiftLo;
1209  if (k < 0)
1210  k = 0;
1211  else if (k > m_nShapeLo)
1212  k = m_nShapeLo;
1213 
1214  if (m_useCoolPulseShapes) {
1215  float phase = (k - m_binTime0Lo) * m_timeStepLo;
1216  float y, dy;
1217  pulse->getPulseShapeYDY(drawerIdx, ich, 0, phase, y, dy);
1218  double ampl = (double) y;
1219  digitSamplesLo[js] += amp_ch_lo * ampl;
1220  ATH_MSG_VERBOSE( "Sample no.=" << js
1221  << " Pulse index=" << k
1222  << " Shape wt. =" << ampl
1223  << " LOGAIN from COOL");
1224  } else {
1225  digitSamplesLo[js] += amp_ch_lo * m_digitShapeLo[k];
1226  ATH_MSG_VERBOSE( "Sample no.=" << js
1227  << " Pulse index=" << k
1228  << " Shape wt. =" << m_digitShapeLo[k]
1229  << " LOGAIN from TileInfo");
1230  }
1231 
1232  }
1233 
1234  if (msgLvl(MSG::VERBOSE)) {
1235  msg(MSG::VERBOSE) << "subHit: ch=" << ich
1236  << " e_hit=" << e_hit
1237  << " t_hit=" << t_hit
1238  << " SamplesHi[" << m_iTrig << "]=" << digitSamplesHi[m_iTrig]
1239  << " SamplesLo[" << m_iTrig << "]=" << digitSamplesLo[m_iTrig] << endmsg;
1240  }
1241  } /* end loop over sub-hits */
1242  } /* end loop over hits for this collection. */
1243 
1244 
1245  return StatusCode::SUCCESS;
1246 
1247 }
1248 
1250  const TileHitCollection* hitCollection,
1251  std::vector<std::vector<double>>& drawerBufferLo,
1252  std::vector<std::vector<double>>& drawerBufferHi,
1253  std::vector<int>& igain, int ros, int drawer, int drawerIdx,
1254  std::vector<int>& over_gain, const TileEMScale* emScale,
1255  const TileSampleNoise* sampleNoise, const TileDQstatus* dqStatus,
1256  const TileBadChannels* badChannels) const {
1257 
1258  if (hitCollection->identify() != bkgDigitCollection->identify()) {
1259  ATH_MSG_ERROR ( "Frag IDs for hit collection and digits overlay collection do not match "
1260  << MSG::hex << hitCollection->identify() << " != " << bkgDigitCollection->identify()
1261  << MSG::dec );
1262  return StatusCode::FAILURE;
1263  }
1264 
1265 
1266  // iterate over all digits in a collection
1267  for (const auto* bkgDigit : *bkgDigitCollection) {
1268 
1269  /* Get digit HWIdentifier (= adc_id) */
1270  HWIdentifier adcId = bkgDigit->adc_HWID();
1271  int channel = m_tileHWID->channel(adcId);
1272  int gain = m_tileHWID->adc(adcId);
1273 
1274  igain[channel] = gain;
1275 
1276  // get channel status
1277  bool good_dq = dqStatus->isAdcDQgood(ros, drawer, channel, gain);
1278  bool good_ch = (!badChannels->getAdcStatus(adcId).isBad());
1279 
1280  // get digits
1281  std::vector<float> digits = bkgDigit->samples();
1282  // get number of time samples & compare with nSamp
1283  int nSamp2 = digits.size();
1284  int goodDigits = nSamp2;
1285  float dig(m_f_ADCmaskValue),digmin(65536.),digmax(-65536.);
1286  if (goodDigits > 0) {
1287  auto minmax = std::minmax_element(digits.begin(), digits.end());
1288  digmin = *minmax.first;
1289  digmax = *minmax.second;
1290  }
1291 
1292  if (good_dq) {
1293  if (digmax > m_ADCmaxPlusEps) { // ignore everything in case of invalid digits
1294  dig = m_f_ADCmaskValue;
1295  goodDigits = 0;
1296  } else { // skip zeros or overflows
1297  float ADCmaxMinusEps = m_ADCmaxMinusEps;
1298  int badDigits = std::count_if(digits.begin(), digits.end(), [ADCmaxMinusEps](float dig){
1299  return (dig < 0.01) || (dig > ADCmaxMinusEps);});
1300  goodDigits -= badDigits;
1301  dig = digits.back();
1302  }
1303  } else if (goodDigits>0) {
1304  goodDigits = 0;
1305  dig = digits.back();
1306  }
1307 
1308  if (goodDigits>0) {
1309  over_gain[channel] = gain;
1310  if (nSamp2 != m_nSamples) {
1311  float lastDigit = digits.back();
1312  digits.resize(m_nSamples);
1313  // repeat last value in vector (nSamp-nSamp2) times
1314  std::fill(digits.begin() + nSamp2, digits.end(), lastDigit);
1315  }
1316 
1317  std::vector<double>& buffer = (gain == TileID::HIGHGAIN) ? drawerBufferHi[channel] : drawerBufferLo[channel];
1318  std::vector<double>& bufferLG = drawerBufferLo[channel];
1319 
1320  bool isFilledLG = false;
1321  if (gain == TileID::HIGHGAIN) {
1322  if (digmax - digmin > 5. && good_ch ) {// 5 ADC counts cut - to ignore pure noise in HG (less than 0.1 count effect in LG)
1323  float ratio = emScale->applyOnlineChargeCalibration(drawerIdx, channel, TileID::HIGHGAIN, 1.)
1324  / emScale->applyOnlineChargeCalibration(drawerIdx, channel, TileID::LOWGAIN, 1.); // ratio between low and high gain
1325 
1326  dig=std::min(digits[0],std::max(digmin, sampleNoise->getPed(drawerIdx, channel, TileID::HIGHGAIN)));
1327 
1328  std::transform(digits.begin(), digits.end(), bufferLG.begin(), [dig,ratio](float digit){return (digit - dig) * ratio;});
1329  isFilledLG = true;
1330  }
1331  }
1332 
1333  std::copy(digits.begin(), digits.end(), buffer.begin());
1334 
1335  if (msgLvl(MSG::VERBOSE)) {
1336  msg(MSG::VERBOSE) << "RNDM BG ADC " << m_tileHWID->to_string(adcId)
1337  << " samples=";
1338  for (int js = 0; js < m_nSamples; ++js)
1339  msg(MSG::VERBOSE) << " " << buffer[js];
1340  if (!good_ch)
1341  msg(MSG::VERBOSE) << " BCH";
1342  if (!good_dq) {
1343  msg(MSG::VERBOSE) << " BDQ";
1344  } else if (isFilledLG) {
1345  msg(MSG::VERBOSE) << " LG=";
1346  for (int js = 0; js < m_nSamples; ++js)
1347  msg(MSG::VERBOSE) << " " << int(bufferLG[js]*100)/100.;
1348  }
1349  msg(MSG::VERBOSE) << endmsg;
1350  }
1351 
1352  } else if (nSamp2 > 0) {
1353  over_gain[channel] = 10+gain; // flag problematic channel
1354 
1355  std::vector<double>& buffer = (gain == TileID::HIGHGAIN) ? drawerBufferHi[channel] : drawerBufferLo[channel];
1356 
1357  if (digmin != digmax || (dig!=0. && dig!=m_f_ADCmax)) {
1358  dig = m_f_ADCmaskValue; // keep only 0 or m_f_ADCmax as it is
1359  }
1360  std::fill(buffer.begin(), buffer.end(), dig);
1361 
1362  if (msgLvl(MSG::VERBOSE)) {
1363  msg(MSG::VERBOSE) << "BAD BG ADC " << m_tileHWID->to_string(adcId)
1364  << " samples=";
1365  for (int js = 0; js < nSamp2; ++js)
1366  msg(MSG::VERBOSE) << " " << digits[js];
1367  msg(MSG::VERBOSE) << ((good_ch)?"":" BCH") << ((good_dq)?"":" BDQ") << endmsg;
1368  }
1369 
1370  } else {
1371  ATH_MSG_VERBOSE( "NO BG ADC " << m_tileHWID->to_string(adcId)
1372  << " samples= 0 0 0 0 0 0 0"
1373  << ((good_ch)?"":" BCH") << ((good_dq)?"":" BDQ") );
1374  }
1375  }
1376  return StatusCode::SUCCESS;
1377 }
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
TileSamplingFraction::getSamplingFraction
float getSamplingFraction(unsigned int drawerIdx, unsigned int channel) const
Return Tile Calorimeter sampling fraction.
Definition: TileSamplingFraction.h:53
ATHRNG::RNGWrapper::setSeed
void setSeed(const std::string &algName, const EventContext &ctx)
Set the random seed using a string (e.g.
Definition: RNGWrapper.h:169
TileEMScale
Condition object to keep calibration factors of TileCal channels.
Definition: TileEMScale.h:87
TileDigitsMaker::m_ADCmaxPlusEps
float m_ADCmaxPlusEps
ADC saturation value + 0.01 or something small.
Definition: TileDigitsMaker.h:173
ReadOfcFromCool.phase
phase
Definition: ReadOfcFromCool.py:127
TileInfo::digitsBinsPerXHi
int digitsBinsPerXHi() const
Return number of bins per bunch-crossing NGO high/lo makes no sense, right?
Definition: TileInfo.h:199
TileDigitsMaker::m_integerDigits
Gaudi::Property< bool > m_integerDigits
Definition: TileDigitsMaker.h:136
sendEI_SPB.ch
ch
Definition: sendEI_SPB.py:35
TileInfo::digitsFullShapeLo
const std::vector< double > & digitsFullShapeLo() const
Return shape vector with full binning to produce the TileDigits from sub-hits.
Definition: TileInfo.h:186
TileDigitsMaker::m_cabling
const TileCablingService * m_cabling
TileCabling instance.
Definition: TileDigitsMaker.h:163
TileSampleNoise::getHfn2
float getHfn2(unsigned int drawerIdx, unsigned int channel, unsigned int adc) const
Definition: TileSampleNoise.h:71
max
#define max(a, b)
Definition: cfImp.cxx:41
TileDigitsMaker::m_doDigiTruth
Gaudi::Property< bool > m_doDigiTruth
Definition: TileDigitsMaker.h:151
plotting.yearwise_efficiency.channel
channel
Definition: yearwise_efficiency.py:28
TileTBID::is_tiletb
bool is_tiletb(const Identifier &id) const
Test ID if it is TileTBID.
Definition: TileTBID.cxx:86
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
TileHWID::get_id
virtual int get_id(const IdentifierHash &hash_id, HWIdentifier &id, const IdContext *context=0) const
create compact HW ID from hash id (return == 0 for OK)
Definition: TileHWID.cxx:490
TileDigitsMaker::m_f_ADCmax
float m_f_ADCmax
ADC saturation value.
Definition: TileDigitsMaker.h:170
TileDigitsMaker::m_maskBadChannels
Gaudi::Property< bool > m_maskBadChannels
Definition: TileDigitsMaker.h:148
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
TileDigitsMaker::m_digitsContainer_DigiHSTruthKey
SG::WriteHandleKey< TileDigitsContainer > m_digitsContainer_DigiHSTruthKey
Definition: TileDigitsMaker.h:121
TileInfo::NdigitSamples
int NdigitSamples() const
Returns the number of sammples (digits) per event.
Definition: TileInfo.h:75
SG::VIEW_ELEMENTS
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts
Definition: OwnershipPolicy.h:18
make_unique
std::unique_ptr< T > make_unique(Args &&... args)
Definition: SkimmingToolEXOT5.cxx:23
TileSampleNoise
Condition object to keep and provide Tile sample noise.
Definition: TileSampleNoise.h:18
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
TileDigitsMaker::m_emScaleKey
SG::ReadCondHandleKey< TileEMScale > m_emScaleKey
Name of TileEMScale in condition store.
Definition: TileDigitsMaker.h:212
TileDigitsMaker::m_filterThreshold
Gaudi::Property< double > m_filterThreshold
Definition: TileDigitsMaker.h:127
TileMutableDataContainer::status
StatusCode status() const
Return the error status from the constructors.
TileDigitsMaker::execute
virtual StatusCode execute(const EventContext &ctx) const override
execute method
Definition: TileDigitsMaker.cxx:265
TileDigitsMaker::m_timeStepLo
double m_timeStepLo
Time step in low gain pulse shape: 25.0 / nBinsPerXLo.
Definition: TileDigitsMaker.h:191
TileDigitsMaker::m_filterThresholdMBTS
Gaudi::Property< double > m_filterThresholdMBTS
Definition: TileDigitsMaker.h:130
TileDigitsMaker::m_filteredDigitsContainerKey
SG::WriteHandleKey< TileDigitsContainer > m_filteredDigitsContainerKey
Definition: TileDigitsMaker.h:124
TileDigitsMaker::m_tileNoise
bool m_tileNoise
If true => generate noise in TileDigits.
Definition: TileDigitsMaker.h:175
TileInfo::digitsTime0BinLo
int digitsTime0BinLo() const
Return index of in-time bin in low gain DigitShape.
Definition: TileInfo.h:196
CaloCondBlobAlgs_fillNoiseFromASCII.gain
gain
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:110
python.SystemOfUnits.MeV
int MeV
Definition: SystemOfUnits.py:154
MuonGM::round
float round(const float toRound, const unsigned int decimals)
Definition: Mdt.cxx:27
TileDigitsMaker::m_f_ADCmaxHG
float m_f_ADCmaxHG
ADC saturation value - 0.5.
Definition: TileDigitsMaker.h:171
TileBchStatus
Class holding bad channel problems.
Definition: TileBchStatus.h:20
TileDigitsMaker::m_sampleNoiseKey
SG::ReadCondHandleKey< TileSampleNoise > m_sampleNoiseKey
Name of TileSampleNoise in condition store.
Definition: TileDigitsMaker.h:206
SG::ReadCondHandle::isValid
bool isValid()
Definition: ReadCondHandle.h:206
AthCommonMsg< Gaudi::Algorithm >::msgLvl
bool msgLvl(const MSG::Level lvl) const
Definition: AthCommonMsg.h:30
TileDigitsMaker::m_cablingSvc
ServiceHandle< TileCablingSvc > m_cablingSvc
Name of Tile cabling service.
Definition: TileDigitsMaker.h:196
TileInfo.h
Tile_Base_ID::HIGHGAIN
@ HIGHGAIN
Definition: Tile_Base_ID.h:57
TileHWID::drawer_hash_max
size_type drawer_hash_max(void) const
drawer hash table max size
Definition: TileHWID.h:268
TileInfo::digitsTime0BinHi
int digitsTime0BinHi() const
Return index of in-time bin in high gain DigitShape.
Definition: TileInfo.h:194
TileDigitsMaker::m_samplingFractionKey
SG::ReadCondHandleKey< TileSamplingFraction > m_samplingFractionKey
Name of TileSamplingFraction in condition store.
Definition: TileDigitsMaker.h:224
TileCalibUtils.h
TileSampleNoise::getHfn
float getHfn(unsigned int drawerIdx, unsigned int channel, unsigned int adc) const
Definition: TileSampleNoise.h:51
python.TurnDataReader.dr
dr
Definition: TurnDataReader.py:112
TileHWID::drawer_context
IdContext drawer_context(void) const
idContext for drawers
Definition: TileHWID.cxx:470
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
SG::VarHandleKey::key
const std::string & key() const
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:141
TileDigitsMaker::m_digitsContainerKey
SG::WriteHandleKey< TileDigitsContainer > m_digitsContainerKey
Definition: TileDigitsMaker.h:118
checkRpcDigits.digit
digit
Definition: checkRpcDigits.py:186
TileFragHash::Digitizer
@ Digitizer
Definition: TileFragHash.h:33
TileHitCollection
Definition: TileHitCollection.h:12
SG::VarHandleKey::empty
bool empty() const
Test if the key is blank.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:150
TileDigitsMaker::m_nSamples
int m_nSamples
Number of time slices for each channel.
Definition: TileDigitsMaker.h:167
HWIdentifier
Definition: HWIdentifier.h:13
TileDigitsMaker::m_hitContainer_DigiHSTruthKey
SG::ReadHandleKey< TileHitContainer > m_hitContainer_DigiHSTruthKey
Definition: TileDigitsMaker.h:109
Identifier::is_valid
bool is_valid() const
Check if id is in a valid state.
TileDigitsMaker::m_tileTBID
const TileTBID * m_tileTBID
Definition: TileDigitsMaker.h:160
TileDigitsMaker::m_useCoolPulseShapes
Gaudi::Property< bool > m_useCoolPulseShapes
Definition: TileDigitsMaker.h:145
Example_ReadSampleNoise.drawer
drawer
Definition: Example_ReadSampleNoise.py:39
TileInfo::DecoCovariance
const TMatrixD * DecoCovariance(int ros, int drawer, int hilo) const
Returns the decomposed covariance matrix.
Definition: TileInfo.cxx:211
ReadCondHandle.h
TileHWID::channel
int channel(const HWIdentifier &id) const
extract channel field from HW identifier
Definition: TileHWID.h:189
TileID.h
TileDigitsMaker::m_tileInfo
const TileInfo * m_tileInfo
Definition: TileDigitsMaker.h:162
TileDigitsMaker::m_nShapeHi
int m_nShapeHi
Number of bins in high gain pulse shape.
Definition: TileDigitsMaker.h:182
AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::detStore
const ServiceHandle< StoreGateSvc > & detStore() const
The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:95
TileHWID::ros
int ros(const HWIdentifier &id) const
extract ros field from HW identifier
Definition: TileHWID.h:167
PileUpMergeSvc::TimedList::type
std::list< value_t > type
type of the collection of timed data object
Definition: PileUpMergeSvc.h:75
TileInfo::ADCmaskValue
int ADCmaskValue() const
Returns the overlay magic number that indicates channels which were masked in background dataset.
Definition: TileInfo.h:73
TileDigitsMaker::m_nBinsPerXLo
int m_nBinsPerXLo
Number of bins per bunch crossing in low gain pulse shape.
Definition: TileDigitsMaker.h:189
TileRawChannelContainer.h
TileEMScale::calibrateChannel
float calibrateChannel(unsigned int drawerIdx, unsigned int channel, unsigned int adc, float amplitude, TileRawChannelUnit::UNIT rawDataUnitIn, TileRawChannelUnit::UNIT rawDataUnitOut) const
Calibrate a Tile channel.
Definition: TileEMScale.cxx:136
WriteHandle.h
Handle class for recording to StoreGate.
TileDQstatus
Class that holds Data Quality fragment information and provides functions to extract the data quality...
Definition: TileDQstatus.h:49
TilePulseShapes.h
TileDigitsMaker::finalize
virtual StatusCode finalize() override
finalize method
Definition: TileDigitsMaker.cxx:1091
TileHWID::adc
int adc(const HWIdentifier &id) const
extract adc field from HW identifier
Definition: TileHWID.h:193
TileDigitsMaker::m_binTime0Lo
int m_binTime0Lo
Index of time=0 bin for low gain pulse shape.
Definition: TileDigitsMaker.h:190
TileTBID.h
TileDigitsMaker::m_tileThresh
bool m_tileThresh
If true => apply threshold to Digits.
Definition: TileDigitsMaker.h:177
TileInfo::ItrigSample
int ItrigSample() const
The sample at which the pulse should ideally peak.
Definition: TileInfo.h:77
createCoolChannelIdFile.buffer
buffer
Definition: createCoolChannelIdFile.py:12
TileHWID.h
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
SG::ReadCondHandle::retrieve
const_pointer_type retrieve()
Definition: ReadCondHandle.h:162
TileDigitsMaker::overlayBackgroundDigits
StatusCode overlayBackgroundDigits(const TileDigitsCollection *bkgDigitCollection, const TileHitCollection *hitCollection, std::vector< std::vector< double >> &drawerBufferLo, std::vector< std::vector< double >> &drawerBufferHi, std::vector< int > &igain, int ros, int drawer, int drawerIdx, std::vector< int > &over_gain, const TileEMScale *emScale, const TileSampleNoise *sampleNoise, const TileDQstatus *dqStatus, const TileBadChannels *badChannels) const
Definition: TileDigitsMaker.cxx:1249
TileDigitsMaker::m_binTime0Hi
int m_binTime0Hi
Index of time=0 bin for high gain pulse shape.
Definition: TileDigitsMaker.h:184
TileCablingService.h
TileSamplingFraction
Condition object to keep and provide Tile Calorimeter sampling fraction and number of photoelectrons.
Definition: TileSamplingFraction.h:16
TileSampleNoise::getHfn1
float getHfn1(unsigned int drawerIdx, unsigned int channel, unsigned int adc) const
Definition: TileSampleNoise.h:63
TileDigitsMaker::m_tileThreshLo
double m_tileThreshLo
Actual threshold value for low gain.
Definition: TileDigitsMaker.h:179
lumiFormat.i
int i
Definition: lumiFormat.py:92
TileHWID::get_hash
virtual IdentifierHash get_hash(const HWIdentifier &id) const
create hash id from compact ADC id without error checking
Definition: TileHWID.cxx:543
TileInfo::digitsNBinsLo
int digitsNBinsLo() const
Return number of bins in low gain DigitShape.
Definition: TileInfo.h:191
Identifier
Definition: DetectorDescription/Identifier/Identifier/Identifier.h:32
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
SG::ReadHandle::get
const_pointer_type get() const
Dereference the pointer, but don't cache anything.
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
TileInfo::digitsFullShapeHi
const std::vector< double > & digitsFullShapeHi() const
Return shape vector with full binning to produce the TileDigits from sub-hits.
Definition: TileInfo.h:184
Amg::transform
Amg::Vector3D transform(Amg::Vector3D &v, Amg::Transform3D &tr)
Transform a point from a Trasformation3D.
Definition: GeoPrimitivesHelpers.h:156
createCoolChannelIdFile.channel_id
channel_id
Definition: createCoolChannelIdFile.py:52
TileRawChannelUnit::MegaElectronVolts
@ MegaElectronVolts
Definition: TileRawChannelUnit.h:20
TileMutableDigitsContainer.h
Helper for holding non-const raw data prior to recording in SG.
TileDigitsMaker::m_badChannelsKey
SG::ReadCondHandleKey< TileBadChannels > m_badChannelsKey
Name of TileBadChannels in condition store.
Definition: TileDigitsMaker.h:230
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
TileDigitsMaker::m_nBinsPerXHi
int m_nBinsPerXHi
Number of bins per bunch crossing in high gain pulse shape.
Definition: TileDigitsMaker.h:183
Tile_Base_ID::LOWGAIN
@ LOWGAIN
Definition: Tile_Base_ID.h:57
WriteCellNoiseToCool.igain
igain
Definition: WriteCellNoiseToCool.py:338
IdentifiableContainerMT::const_iterator
Definition: IdentifiableContainerMT.h:82
TileDigitsMaker::m_tileCoherNoise
bool m_tileCoherNoise
If true => generate coherent noise in TileDigits.
Definition: TileDigitsMaker.h:176
IdentifiableContainerMT::begin
const_iterator begin() const
return const_iterator for first entry
Definition: IdentifiableContainerMT.h:236
TileSampleNoise::getHfnNorm
float getHfnNorm(unsigned int drawerIdx, unsigned int channel, unsigned int adc) const
Definition: TileSampleNoise.h:78
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
xAOD::double
double
Definition: CompositeParticle_v1.cxx:159
TileDigitsMaker::m_i_ADCmax
int m_i_ADCmax
ADC saturation value.
Definition: TileDigitsMaker.h:169
maskDeadModules.ros
ros
Definition: maskDeadModules.py:35
python.ElectronD3PDObject.HitSum
HitSum
Definition: ElectronD3PDObject.py:313
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
TileDQstatus::isAdcDQgood
bool isAdcDQgood(int partition, int drawer, int ch, int gain) const
returns status of single ADC returns False if there are any errors
Definition: TileDQstatus.cxx:178
TileDigitsMaker::m_randomStreamName
Gaudi::Property< std::string > m_randomStreamName
Random Stream Name.
Definition: TileDigitsMaker.h:201
TileDigitsMaker::m_calibRun
Gaudi::Property< bool > m_calibRun
Definition: TileDigitsMaker.h:139
min
#define min(a, b)
Definition: cfImp.cxx:40
TileRawDataCollection::identify
ID identify() const
Definition: TileRawDataCollection.h:71
TileInfo::digitsBinsPerXLo
int digitsBinsPerXLo() const
Return number of bins per bunch-crossing.
Definition: TileInfo.h:201
TileDigitsMaker::m_digitShapeHi
std::vector< double > m_digitShapeHi
High gain pulse shape.
Definition: TileDigitsMaker.h:181
TileDigitsMaker::m_tileID
const TileID * m_tileID
Definition: TileDigitsMaker.h:159
TileDigitsCollection
Definition: TileDigitsCollection.h:18
TileDigitsMaker::m_inputDigitContainerName
std::string m_inputDigitContainerName
Definition: TileDigitsMaker.h:116
TileHWID::drawer_id
HWIdentifier drawer_id(int frag) const
ROS HWIdentifer.
Definition: TileHWID.cxx:186
TileMutableDataContainer::push_back
StatusCode push_back(std::unique_ptr< Element > rch)
Add a new channel.
ATHRNG::RNGWrapper
A wrapper class for event-slot-local random engines.
Definition: RNGWrapper.h:56
TileBadChannels
Condition object to keep Tile channel and ADC status.
Definition: TileBadChannels.h:24
TileDigitsMaker::m_iTrig
int m_iTrig
Index of the triggering time slice.
Definition: TileDigitsMaker.h:168
errorcheck.h
Helpers for checking error return status codes and reporting errors.
TileDigitsMaker::m_allChannels
Gaudi::Property< int > m_allChannels
Definition: TileDigitsMaker.h:154
TileDigitsMaker::m_tileThreshHi
double m_tileThreshHi
Actual threshold value for high gain.
Definition: TileDigitsMaker.h:178
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
TileDigitsMaker::m_rndmEvtOverlay
Gaudi::Property< bool > m_rndmEvtOverlay
Definition: TileDigitsMaker.h:142
TileHit
Definition: TileSimEvent/TileSimEvent/TileHit.h:30
Units.h
Wrapper to avoid constant divisions when using units.
ATHRNG::RNGWrapper::getEngine
CLHEP::HepRandomEngine * getEngine(const EventContext &ctx) const
Retrieve the random engine corresponding to the provided EventContext.
Definition: RNGWrapper.h:134
RNGWrapper.h
TileInfo::TileNoise
bool TileNoise() const
Noise switched on/off?
Definition: TileInfo.h:87
TileDigitsMaker::m_inputDigitContainerKey
SG::ReadHandleKey< TileDigitsContainer > m_inputDigitContainerKey
Definition: TileDigitsMaker.h:115
TileBadChannels::getAdcStatus
const TileBchStatus & getAdcStatus(const HWIdentifier adc_id) const
Return Tile ADC status.
Definition: TileBadChannels.cxx:24
TileDigitsMaker::fillDigitCollection
StatusCode fillDigitCollection(const TileHitCollection *hitCollection, std::vector< std::vector< double >> &drawerBufferLo, std::vector< std::vector< double >> &drawerBufferHi, std::vector< int > &igain, std::vector< int > &overgain, std::vector< double > &ech_int, std::vector< bool > &signal_in_channel, const TileEMScale *emScale, const TileSamplingFraction *samplingFraction, const TilePulse *pulse) const
Definition: TileDigitsMaker.cxx:1097
TileHWID::adc_id
HWIdentifier adc_id(int ros, int drawer, int channel, int adc) const
adc HWIdentifer
Definition: TileHWID.cxx:228
TileDigitsMaker::m_hitContainerKey
SG::ReadHandleKey< TileHitContainer > m_hitContainerKey
Definition: TileDigitsMaker.h:106
makeTRTBarrelCans.dy
tuple dy
Definition: makeTRTBarrelCans.py:21
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:76
TileInfo::ThresholdDigits
double ThresholdDigits(int) const
Return the threshold value for good TileDigits (cut applied to in-time digit only)
Definition: TileInfo.h:102
y
#define y
TileDigitsMaker::m_onlyUseContainerName
Gaudi::Property< bool > m_onlyUseContainerName
Definition: TileDigitsMaker.h:112
TileInfo::TileZeroSuppress
bool TileZeroSuppress() const
Zero suppression switched on/off?
Definition: TileInfo.h:91
TileHWID::drawer
int drawer(const HWIdentifier &id) const
extract drawer field from HW identifier
Definition: TileHWID.h:171
python.compareTCTs.ratio
ratio
Definition: compareTCTs.py:295
SG::WriteHandle::record
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
TileDigitsMaker::m_pulseShapeKey
SG::ReadCondHandleKey< TilePulse > m_pulseShapeKey
Name of TilePulseShape in condition store.
Definition: TileDigitsMaker.h:218
TileInfo::TileCoherNoise
bool TileCoherNoise() const
Coherent noise switched on/off?
Definition: TileInfo.h:89
TileEMScale::applyOnlineChargeCalibration
float applyOnlineChargeCalibration(unsigned int drawerIdx, unsigned int channel, unsigned int adc, float amplitude) const
Apply online CIS calibration: ADC counts -> pC.
Definition: TileEMScale.cxx:349
Tile_Base_ID::to_string
std::string to_string(const Identifier &id, int level=0) const
Definition: Tile_Base_ID.cxx:52
lumiFormat.fill
fill
Definition: lumiFormat.py:111
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
PileUpMergeSvc.h
the preferred mechanism to access information from the different event stores in a pileup job.
TileCablingService::connected
bool connected(int ros, int drawer) const
Definition: TileCablingService.h:275
DeMoScan.first
bool first
Definition: DeMoScan.py:534
TileDigitsMaker::m_DQstatusKey
SG::ReadHandleKey< TileDQstatus > m_DQstatusKey
Definition: TileDigitsMaker.h:233
DEBUG
#define DEBUG
Definition: page_access.h:11
TileDigitsMaker::m_ADCmaxMinusEps
float m_ADCmaxMinusEps
ADC saturation value - 0.01 or something small.
Definition: TileDigitsMaker.h:172
AthCommonMsg< Gaudi::Algorithm >::msg
MsgStream & msg() const
Definition: AthCommonMsg.h:24
TileDigitsMaker::m_tileHWID
const TileHWID * m_tileHWID
Definition: TileDigitsMaker.h:161
TilePulse::getPulseShapeYDY
bool getPulseShapeYDY(unsigned int drawerIdx, unsigned int channel, unsigned int adc, float time, float &y, float &dy) const
Definition: TilePulse.h:35
TileDigitsMaker::initialize
virtual StatusCode initialize() override
initialize method
Definition: TileDigitsMaker.cxx:68
TileDigitsMaker::m_rndmSvc
ServiceHandle< IAthRNGSvc > m_rndmSvc
Random number service to use.
Definition: TileDigitsMaker.h:199
TilePulse
Condition object to keep and provide Tile pulse shape.
Definition: TilePulse.h:15
TileCablingService::h2s_pmt_id
Identifier h2s_pmt_id(const HWIdentifier &id) const
Definition: TileCablingService.cxx:791
TileCalibUtils::getDrawerIdx
static unsigned int getDrawerIdx(unsigned int ros, unsigned int drawer)
Returns a drawer hash.
Definition: TileCalibUtils.cxx:60
TileInfo::digitsNBinsHi
int digitsNBinsHi() const
Return number of bins in high gain DigitShape.
Definition: TileInfo.h:189
calibdata.copy
bool copy
Definition: calibdata.py:27
python.Constants.VERBOSE
int VERBOSE
Definition: Control/AthenaCommon/python/Constants.py:14
TileDigitsMaker::m_f_ADCmaskValue
float m_f_ADCmaskValue
indicates channels which were masked in background dataset
Definition: TileDigitsMaker.h:174
TileHWID::to_string
std::string to_string(const HWIdentifier &id, int level=0) const
extract all fields from HW identifier HWIdentifier get_all_fields ( const HWIdentifier & id,...
Definition: TileHWID.cxx:49
ReadHandle.h
Handle class for reading from StoreGate.
IdentifierHash
Definition: IdentifierHash.h:38
TileDigitsMaker::m_all_ids
std::vector< std::unique_ptr< HWIdentifier[]> > m_all_ids
Definition: TileDigitsMaker.h:165
TileSampleNoise::getPed
float getPed(unsigned int drawerIdx, unsigned int channel, unsigned int adc) const
Definition: TileSampleNoise.h:46
TileDigitsMaker::m_nShapeLo
int m_nShapeLo
Number of bins in low gain pulse shape.
Definition: TileDigitsMaker.h:188
IdContext
class IdContext
Definition: IdContext.h:34
TileDigitsMaker.h
TileInfo::ADCmax
int ADCmax() const
Returns the maximum ADC output (10 bits --> 1023)
Definition: TileInfo.h:71
TileDigitsMaker::m_infoName
Gaudi::Property< std::string > m_infoName
Definition: TileDigitsMaker.h:133
TileBchStatus::isBad
bool isBad() const
Definition: TileBchStatus.h:145
TileRawChannelUnit::ADCcounts
@ ADCcounts
Definition: TileRawChannelUnit.h:17
fitman.k
k
Definition: fitman.py:528
TileDigitsMaker::m_mergeSvc
PileUpMergeSvc * m_mergeSvc
Pointer to PileUpMergeService.
Definition: TileDigitsMaker.h:157
PileUpMergeSvc::retrieveSubEvtsData
StatusCode retrieveSubEvtsData(const KEY &dataKey, TIMEDDATA &timedData)
retrieve keyed DATA objs for all sub-events and attach a time to them
TileDigitsMaker::m_timeStepHi
double m_timeStepHi
Time step in high gain pulse shape: 25.0 / nBinsPerXHi.
Definition: TileDigitsMaker.h:185
IAthRNGSvc.h
TileDigitsMaker::m_digitShapeLo
std::vector< double > m_digitShapeLo
Low gain pulse shape.
Definition: TileDigitsMaker.h:187