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