ATLAS Offline Software
Loading...
Searching...
No Matches
TileHitToRawChannel.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5//*****************************************************************************
6// Filename : TileHitToRawChannel.cxx
7// Author : Zhifang
8// Created : April, 2002
9//
10// DESCRIPTION:
11// Implement the TileHitToRawChannel class
12//
13// HISTORY:
14//
15// BUGS:
16//
17//*****************************************************************************
18
19// Tile includes
27
28// Calo includes
31
32// Atlas includes
37// For the Athena-based random numbers.
40
41//CLHEP includes
42#include <CLHEP/Random/Randomize.h>
43
44
45using CLHEP::RandGaussQ;
46
47
48//
49// Constructor
50//
51TileHitToRawChannel::TileHitToRawChannel(const std::string& name, ISvcLocator* pSvcLocator)
52 : AthAlgorithm(name, pSvcLocator)
53 , m_rChUnit(TileRawChannelUnit::ADCcounts)
55 , m_tileID(nullptr)
56 , m_tileTBID(nullptr)
57 , m_tileHWID(nullptr)
58 , m_tileInfo(nullptr)
59 , m_cabling(nullptr)
60 , m_tileNoise(false)
61 , m_tileThresh(false)
62 , m_threshHi(0.0)
63 , m_ampMaxHi(0.0)
64{
65 declareProperty("TileInfoName", m_infoName = "TileInfo");
66 declareProperty("DeltaT", m_deltaT = -1.0); // keep hits only within deltaT;
67 declareProperty("calibrateEnergy", m_calibrateEnergy = false); // convert or not to pCb
68}
69
71 std::vector<HWIdentifier *>::iterator itr = m_all_ids.begin();
72 std::vector<HWIdentifier *>::iterator last = m_all_ids.end();
73
74 for (; itr != last; ++itr) {
75 delete[] (*itr);
76 }
77}
78
79//
80// Alg standard initialize function
81//
86
87 // retrieve TileID helper and TileInfo from det store
88
89 ATH_CHECK( detStore()->retrieve(m_tileID) );
90
91 ATH_CHECK( detStore()->retrieve(m_tileTBID) );
92
93 ATH_CHECK( detStore()->retrieve(m_tileHWID) );
94
95 ATH_CHECK( detStore()->retrieve(m_tileInfo, m_infoName) );
96
97 ATH_CHECK( m_samplingFractionKey.initialize() );
98 ATH_CHECK( m_emScaleKey.initialize() );
99
100 ATH_CHECK( m_tileToolNoiseSample.retrieve() );
101
102 if (m_tileNoise) {
103 ATH_CHECK(m_atRndmGenSvc.retrieve());
104 }
105
106 ATH_CHECK( m_cablingSvc.retrieve() );
107 m_cabling = m_cablingSvc->cablingService();
108
109 // Get needed parameters from TileInfo
110 m_ampMaxHi = m_tileInfo->ADCmax();
111
112 /* Get TileNoise flag from TileInfo
113 (true => generate noise in RC's). */
114 m_tileNoise = m_tileInfo->TileNoise();
115
116 /* Get TileZeroSuppress flag from TileInfo
117 (true => apply threshold cut for RC's). */
118 m_tileThresh = m_tileInfo->TileZeroSuppress();
119
120 m_threshHi = m_tileInfo->ThresholdRawChannel(TileID::HIGHGAIN);
121
122 if (m_tileThresh) {
123 ATH_MSG_INFO( "ampMaxHi=" << m_ampMaxHi
124 << ", tileNoise=" << ((m_tileNoise) ? "true" : "false")
125 << ", tileThresh=" << "true, thresh_hi=" << m_threshHi );
126 } else {
127 ATH_MSG_INFO( "ampMaxHi=" << m_ampMaxHi
128 << ", tileNoise=" << ((m_tileNoise) ? "true" : "false")
129 << ", tileThresh=" << "false" );
130 }
131
132
133 IdContext drawer_context = m_tileHWID->drawer_context();
134 int ndrawers = m_tileHWID->drawer_hash_max();
135 int nchannels = 48;
136
137 m_all_ids.reserve(ndrawers);
138
139 for (int dr = 0; dr < ndrawers; ++dr) {
140
141 HWIdentifier drawer_id;
142 /* int result = */m_tileHWID->get_id(dr, drawer_id, &drawer_context);
143
144 HWIdentifier * adc_ids = new HWIdentifier[nchannels];
145 if (m_tileHWID->ros(drawer_id) > 0) { // protection against BEAM ROD
146 for (int ch = 0; ch < nchannels; ++ch) {
147 adc_ids[ch] = m_tileHWID->adc_id(drawer_id, ch, TileID::HIGHGAIN);
148 }
149 }
150 m_all_ids.push_back(adc_ids);
151 }
152
153 ATH_CHECK( m_hitContainerKey.initialize() );
154 ATH_CHECK( m_rawChannelContainerKey.initialize() );
155
156 ATH_MSG_INFO( "TileHitToRawChannel initialization completed" );
157
158 return StatusCode::SUCCESS;
159}
160
161//
162// Alg standard execute function
163//
165
166 ATH_MSG_DEBUG( "Executing TileHitToRawChannel" );
167
168 const EventContext& ctx = Gaudi::Hive::currentContext();
169
170 ATHRNG::RNGWrapper* rngWrapper = m_atRndmGenSvc->getEngine(this, m_randomStreamName);
171 rngWrapper->setSeed( m_randomStreamName, ctx );
172
174 ATH_CHECK( samplingFraction.isValid() );
175
177 ATH_CHECK( emScale.isValid() );
178
179 // step1: read hits from TES
181 ATH_CHECK( hitContainer.isValid() );
182
183 //Zero sums for monitoring.
184 int nChan = 0;
185 int nChLG = 0;
186 int nChHG = 0;
187 double eHitTot = 0.;
188 double eCh = 0.;
189 double eChLG = 0.;
190 double eChHG = 0.;
191
192 // prepare arrays for all channels in one drawer (collection)
193 const int nChMax = 48;
194 double random[nChMax];
195 memset(random, 0, sizeof(random));
196 HWIdentifier * adc_ids;
197 int adc_gain[nChMax];
198 double adc_ampl[nChMax];
199 double adc_time[nChMax];
200 double adc_qual[nChMax];
201
202 IdContext drawer_context = m_tileHWID->drawer_context();
203
204 // step2: form raw channels, and put them in container
205 auto rawChannelContainer = std::make_unique<TileMutableRawChannelContainer>(true, m_rChType, m_rChUnit);
206 ATH_CHECK( rawChannelContainer->status() );
207
208 // iterate over all collections in a container
209 for (const TileHitCollection* hitCollection : *hitContainer) {
210
211 HWIdentifier drawer_id = m_tileHWID->drawer_id(hitCollection->identify());
212 int ros = m_tileHWID->ros(drawer_id);
213 int drawer = m_tileHWID->drawer(drawer_id);
214 int drawerIdx = TileCalibUtils::getDrawerIdx(ros, drawer);
215 if (m_cabling->connected(ros, drawer)) {
216 ATH_MSG_VERBOSE( "ROS " << ros
217 << " drawer " << drawer
218 << " is connected" );
219 } else {
220 continue;
221 }
222 int ch;
223
224 ATH_MSG_VERBOSE( MSG::hex
225 << "Collection = 0x" << hitCollection->identify() << MSG::dec
226 << " : ROS=" << ros
227 << ", drawer=" << drawer );
228
229 IdentifierHash idhash;
230 /* int result = */m_tileHWID->get_hash(drawer_id, idhash, &drawer_context);
231 adc_ids = m_all_ids[idhash];
232
233 // If tileNoise is requested, generate random numbers to give noise
234 if (m_tileNoise) {
235
236 RandGaussQ::shootArray(*rngWrapper, nChMax, random, 0.0, 1.0);
237
238 for (ch = 0; ch < nChMax; ++ch) {
239 adc_gain[ch] = TileID::HIGHGAIN;
240 adc_ampl[ch] = random[ch] * m_tileToolNoiseSample->getHfn(drawerIdx, ch, TileID::HIGHGAIN, TileRawChannelUnit::ADCcounts, ctx)
241 * m_tileInfo->getNoiseScaleFactor();
242
243 }
244 } else {
245 memset(adc_gain, -1, sizeof(adc_gain)); /* TileID::INVALID */
246 memset(adc_ampl, 0, sizeof(adc_ampl));
247 }
248
249 memset(adc_time, 0, sizeof(adc_time));
250 memset(adc_qual, 0, sizeof(adc_qual));
251
252 // iterate over all hits in a collection
253 for (const TileHit* tile_hit : *hitCollection) {
254
255 // Get hit Identifier (= identifier of pmt)
256 Identifier pmt_id = tile_hit->pmt_ID();
257 HWIdentifier channel_id = tile_hit->pmt_HWID();
258
259 // index for array is the channel number
260 ch = m_tileHWID->channel(channel_id);
261
262 /* Get hit amplitude and convert to energy (cell-dependent) */
263 double e_hit = tile_hit->energy();
264 double time = tile_hit->time();
265 if (m_deltaT > 0.0) {
266 if (fabs(time) >= m_deltaT) { // reset first hit if it's outside deltaT window
267 e_hit = 0.0;
268 time = 0.0;
269 }
270 double etime = e_hit * time;
271 for (int i = tile_hit->size() - 1; i > 0; --i) { // don't use first hit (i=0)
272 double en = tile_hit->energy(i);
273 double ti = tile_hit->time(i);
274 if (fabs(ti) < m_deltaT && en > 0.0) {
275 e_hit += en;
276 etime += en * ti;
277 }
278 }
279 if (e_hit > 0.0)
280 time = etime / e_hit;
281 else
282 continue; // go to next hit, do not create channels with zero energy
283 }
284 adc_time[ch] = time;
285 double hit_calib = samplingFraction->getSamplingFraction(drawerIdx, ch);
286 double e_ch = e_hit * hit_calib;
287
288 /* Convert to amplitude of channel (assuming high gain) */
289 /* need to divide here, because "calib" converts amp to energy */
290 int gain = TileID::HIGHGAIN;
291 double amp_ch = e_ch / emScale->calibrateChannel(drawerIdx, ch, gain, 1., m_rChUnit
293 double noise;
294 // If high saturates, convert adc_id to low-gain value and recalculate.
295 if (adc_ampl[ch] + amp_ch + m_tileToolNoiseSample->getPed(drawerIdx, ch, gain, TileRawChannelUnit::ADCcounts, ctx) > m_ampMaxHi) {
296
297 gain = TileID::LOWGAIN;
298 amp_ch = e_ch / emScale->calibrateChannel(drawerIdx, ch, gain, 1., m_rChUnit
300
301 // If Noise is requested,
302 // recalculate noise using the SAME random number as for high.
303 if (m_tileNoise) {
304 adc_ampl[ch] = random[ch] * m_tileToolNoiseSample->getHfn(drawerIdx, ch, TileID::LOWGAIN, TileRawChannelUnit::ADCcounts, ctx)
305 * m_tileInfo->getNoiseScaleFactor();
306 }
307 }
308
309 adc_gain[ch] = gain;
310 noise = adc_ampl[ch];
311 adc_ampl[ch] += amp_ch; // add real amplitude to the noise
312
313 ATH_MSG_VERBOSE( "ch=" << ch << ((gain == TileID::HIGHGAIN) ? " Hi" :" Lo")
314 << " pmt=" << m_tileID->to_string(pmt_id, -1)
315 << " adc=" << m_tileHWID->to_string(channel_id, -1) << "/" << gain
316 << " noise=" << noise
317 << " amp=" << amp_ch
318 << " tot=" << adc_ampl[ch]);
319
320 ++nChan;
321 eHitTot += e_hit;
322 eCh += e_ch;
323 }
324
325 // store raw channels for one drawer
326
327 for (int ch = 0; ch < nChMax; ++ch) {
328
329 int gain = adc_gain[ch];
330
331 // without noise most of channels do not exist
332 // select only valid channels
333 if (gain != -1) {
334
335 HWIdentifier adc_id = adc_ids[ch];
336 double amp = adc_ampl[ch];
337
338 bool lrcGood = true;
339 double thresh = -99999;
340
341 if (TileID::HIGHGAIN != gain) {
342 // change ADC ID (channel switched to low gain)
343 adc_id = m_tileHWID->adc_id(m_tileHWID->channel_id(adc_id), gain);
344
345 } else {
346 // Apply threshold cut to small signals (always high gain)
347 if (m_tileThresh) {
348 thresh = m_threshHi;
349 if (thresh < 0) {
350 if (fabs(amp) < fabs(thresh))
351 lrcGood = false;
352 } else {
353 if (amp < thresh)
354 lrcGood = false;
355 }
356 }
357 }
358
359 if (lrcGood) {
360
361 auto rawChannel = std::make_unique<TileRawChannel>(adc_id, amp, adc_time[ch], adc_qual[ch]);
362 ATH_CHECK( rawChannelContainer->push_back(std::move(rawChannel)) );
363
364 if (TileID::HIGHGAIN == gain) {
365 ++nChHG;
366 eChHG += amp;
367 } else {
368 ++nChLG;
369 eChLG += amp;
370 }
371
372 ATH_MSG_VERBOSE( "Accept RC thr=" << ((thresh < 0) ? "+" : "" ) << thresh
373 << ", id=" << m_tileHWID->to_string(adc_id)
374 << ", amp=" << amp );
375
376 } else {
377
378 ATH_MSG_VERBOSE( "Reject RC thr=" << ((thresh < 0) ? "+" : "") << thresh
379 << ", id=" << m_tileHWID->to_string(adc_id)
380 << ", amp=" << amp );
381 }
382 }
383 }
384 }
385
386
387 // Execution completed.
388 if (msgLvl(MSG::DEBUG)) {
389 msg(MSG::DEBUG) << "TileHitToRawChannel execution completed." << endmsg;
390 msg(MSG::DEBUG) << " nChan=" << nChan
391 << " eHitTot=" << eHitTot
392 << " eneTot=" << eCh
393 << " nchLG=" << nChLG
394 << " eChLG=" << eChLG
395 << " nchHG=" << nChHG
396 << " eChHG=" << eChHG << endmsg;
397 }
398
399
401 ATH_CHECK( rawChannelCnt.record(std::move(rawChannelContainer)) );
402
403 return StatusCode::SUCCESS;
404}
405
407
408 ATH_MSG_INFO( "TileHitToRawChannel::finalize() end." );
409
410 return StatusCode::SUCCESS;
411}
412
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_DEBUG(x)
Helpers for checking error return status codes and reporting errors.
Handle class for reading from StoreGate.
Handle class for recording to StoreGate.
Helper for holding non-const raw data prior to recording in SG.
A wrapper class for event-slot-local random engines.
Definition RNGWrapper.h:56
void setSeed(const std::string &algName, const EventContext &ctx)
Set the random seed using a string (e.g.
Definition RNGWrapper.h:169
AthAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor with parameters:
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
const ServiceHandle< StoreGateSvc > & detStore() const
bool msgLvl(const MSG::Level lvl) const
MsgStream & msg() const
This class saves the "context" of an expanded identifier (ExpandedIdentifier) for compact or hash ver...
Definition IdContext.h:26
This is a "hash" representation of an Identifier.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
static unsigned int getDrawerIdx(unsigned int ros, unsigned int drawer)
Returns a drawer hash.
Hash table for Tile fragments (==drawers ==collections in StoreGate)
bool m_tileThresh
If true => apply threshold on the conversion to raw channels.
ServiceHandle< IAthRNGSvc > m_atRndmGenSvc
Random number generator engine to use.
double m_ampMaxHi
Value of the maximum amplitude to be stored as a high gain channel.
double m_threshHi
Value of the mimimal amplitude required to do the conversion to raw channel in high gain (not used fo...
SG::ReadCondHandleKey< TileSamplingFraction > m_samplingFractionKey
Name of TileSamplingFraction in condition store.
SG::WriteHandleKey< TileRawChannelContainer > m_rawChannelContainerKey
TileFragHash::TYPE m_rChType
Type of TileRawChannels (Digitizar, OF1, OF2, Fit, etc.)(see TileFragHash.h)
std::vector< HWIdentifier * > m_all_ids
Vector to store all the drawer ids.
SG::ReadHandleKey< TileHitContainer > m_hitContainerKey
std::string m_infoName
name of the TileInfo object
SG::ReadCondHandleKey< TileEMScale > m_emScaleKey
Name of TileEMScale in condition store.
const TileCablingService * m_cabling
Pointer to the TileCablingService instance.
virtual ~TileHitToRawChannel()
Destructor.
bool m_calibrateEnergy
if true, amplitude is converted to pCb
ServiceHandle< TileCablingSvc > m_cablingSvc
Name of Tile cabling service.
virtual StatusCode finalize() override
finalize method
TileHitToRawChannel(const std::string &name, ISvcLocator *pSvcLocator)
Constructor.
double m_deltaT
if true, keep only hits in deltaT range
const TileInfo * m_tileInfo
Pointer to TileInfo.
Gaudi::Property< std::string > m_randomStreamName
Random Stream Name.
const TileID * m_tileID
Pointer to TileID helper.
virtual StatusCode initialize() override
initialize method
virtual StatusCode execute() override
execute method
const TileTBID * m_tileTBID
Pointer to TileID helper.
ToolHandle< TileCondToolNoiseSample > m_tileToolNoiseSample
bool m_tileNoise
If true => generate noise for the TileRawChannel creation.
const TileHWID * m_tileHWID
Pointer to TileHWID helper.
TileRawChannelUnit::UNIT m_rChUnit
Units used for the TileRawChannels (ADC, pCb, etc.)(see TileInfo.h)