ATLAS Offline Software
Loading...
Searching...
No Matches
TileHitToRawChannel.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 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 CLHEP::HepRandomEngine* rndmEngine = rngWrapper->getEngine(ctx);
173
175 ATH_CHECK( samplingFraction.isValid() );
176
178 ATH_CHECK( emScale.isValid() );
179
180 // step1: read hits from TES
182 ATH_CHECK( hitContainer.isValid() );
183
184 //Zero sums for monitoring.
185 int nChan = 0;
186 int nChLG = 0;
187 int nChHG = 0;
188 double eHitTot = 0.;
189 double eCh = 0.;
190 double eChLG = 0.;
191 double eChHG = 0.;
192
193 // prepare arrays for all channels in one drawer (collection)
194 const int nChMax = 48;
195 double random[nChMax];
196 memset(random, 0, sizeof(random));
197 HWIdentifier * adc_ids;
198 int adc_gain[nChMax];
199 double adc_ampl[nChMax];
200 double adc_time[nChMax];
201 double adc_qual[nChMax];
202
203 IdContext drawer_context = m_tileHWID->drawer_context();
204
205 // step2: form raw channels, and put them in container
206 auto rawChannelContainer = std::make_unique<TileMutableRawChannelContainer>(true, m_rChType, m_rChUnit);
207 ATH_CHECK( rawChannelContainer->status() );
208
209 // iterate over all collections in a container
210 for (const TileHitCollection* hitCollection : *hitContainer) {
211
212 HWIdentifier drawer_id = m_tileHWID->drawer_id(hitCollection->identify());
213 int ros = m_tileHWID->ros(drawer_id);
214 int drawer = m_tileHWID->drawer(drawer_id);
215 int drawerIdx = TileCalibUtils::getDrawerIdx(ros, drawer);
216 if (m_cabling->connected(ros, drawer)) {
217 ATH_MSG_VERBOSE( "ROS " << ros
218 << " drawer " << drawer
219 << " is connected" );
220 } else {
221 continue;
222 }
223 int ch;
224
225 ATH_MSG_VERBOSE( MSG::hex
226 << "Collection = 0x" << hitCollection->identify() << MSG::dec
227 << " : ROS=" << ros
228 << ", drawer=" << drawer );
229
230 IdentifierHash idhash;
231 /* int result = */m_tileHWID->get_hash(drawer_id, idhash, &drawer_context);
232 adc_ids = m_all_ids[idhash];
233
234 // If tileNoise is requested, generate random numbers to give noise
235 if (m_tileNoise) {
236
237 RandGaussQ::shootArray(rndmEngine, nChMax, random, 0.0, 1.0);
238
239 for (ch = 0; ch < nChMax; ++ch) {
240 adc_gain[ch] = TileID::HIGHGAIN;
241 adc_ampl[ch] = random[ch] * m_tileToolNoiseSample->getHfn(drawerIdx, ch, TileID::HIGHGAIN, TileRawChannelUnit::ADCcounts, ctx)
242 * m_tileInfo->getNoiseScaleFactor();
243
244 }
245 } else {
246 memset(adc_gain, -1, sizeof(adc_gain)); /* TileID::INVALID */
247 memset(adc_ampl, 0, sizeof(adc_ampl));
248 }
249
250 memset(adc_time, 0, sizeof(adc_time));
251 memset(adc_qual, 0, sizeof(adc_qual));
252
253 // iterate over all hits in a collection
254 for (const TileHit* tile_hit : *hitCollection) {
255
256 // Get hit Identifier (= identifier of pmt)
257 Identifier pmt_id = tile_hit->pmt_ID();
258 HWIdentifier channel_id = tile_hit->pmt_HWID();
259
260 // index for array is the channel number
261 ch = m_tileHWID->channel(channel_id);
262
263 /* Get hit amplitude and convert to energy (cell-dependent) */
264 double e_hit = tile_hit->energy();
265 double time = tile_hit->time();
266 if (m_deltaT > 0.0) {
267 if (fabs(time) >= m_deltaT) { // reset first hit if it's outside deltaT window
268 e_hit = 0.0;
269 time = 0.0;
270 }
271 double etime = e_hit * time;
272 for (int i = tile_hit->size() - 1; i > 0; --i) { // don't use first hit (i=0)
273 double en = tile_hit->energy(i);
274 double ti = tile_hit->time(i);
275 if (fabs(ti) < m_deltaT && en > 0.0) {
276 e_hit += en;
277 etime += en * ti;
278 }
279 }
280 if (e_hit > 0.0)
281 time = etime / e_hit;
282 else
283 continue; // go to next hit, do not create channels with zero energy
284 }
285 adc_time[ch] = time;
286 double hit_calib = samplingFraction->getSamplingFraction(drawerIdx, ch);
287 double e_ch = e_hit * hit_calib;
288
289 /* Convert to amplitude of channel (assuming high gain) */
290 /* need to divide here, because "calib" converts amp to energy */
291 int gain = TileID::HIGHGAIN;
292 double amp_ch = e_ch / emScale->calibrateChannel(drawerIdx, ch, gain, 1., m_rChUnit
294 double noise;
295 // If high saturates, convert adc_id to low-gain value and recalculate.
296 if (adc_ampl[ch] + amp_ch + m_tileToolNoiseSample->getPed(drawerIdx, ch, gain, TileRawChannelUnit::ADCcounts, ctx) > m_ampMaxHi) {
297
298 gain = TileID::LOWGAIN;
299 amp_ch = e_ch / emScale->calibrateChannel(drawerIdx, ch, gain, 1., m_rChUnit
301
302 // If Noise is requested,
303 // recalculate noise using the SAME random number as for high.
304 if (m_tileNoise) {
305 adc_ampl[ch] = random[ch] * m_tileToolNoiseSample->getHfn(drawerIdx, ch, TileID::LOWGAIN, TileRawChannelUnit::ADCcounts, ctx)
306 * m_tileInfo->getNoiseScaleFactor();
307 }
308 }
309
310 adc_gain[ch] = gain;
311 noise = adc_ampl[ch];
312 adc_ampl[ch] += amp_ch; // add real amplitude to the noise
313
314 ATH_MSG_VERBOSE( "ch=" << ch << ((gain == TileID::HIGHGAIN) ? " Hi" :" Lo")
315 << " pmt=" << m_tileID->to_string(pmt_id, -1)
316 << " adc=" << m_tileHWID->to_string(channel_id, -1) << "/" << gain
317 << " noise=" << noise
318 << " amp=" << amp_ch
319 << " tot=" << adc_ampl[ch]);
320
321 ++nChan;
322 eHitTot += e_hit;
323 eCh += e_ch;
324 }
325
326 // store raw channels for one drawer
327
328 for (int ch = 0; ch < nChMax; ++ch) {
329
330 int gain = adc_gain[ch];
331
332 // without noise most of channels do not exist
333 // select only valid channels
334 if (gain != -1) {
335
336 HWIdentifier adc_id = adc_ids[ch];
337 double amp = adc_ampl[ch];
338
339 bool lrcGood = true;
340 double thresh = -99999;
341
342 if (TileID::HIGHGAIN != gain) {
343 // change ADC ID (channel switched to low gain)
344 adc_id = m_tileHWID->adc_id(m_tileHWID->channel_id(adc_id), gain);
345
346 } else {
347 // Apply threshold cut to small signals (always high gain)
348 if (m_tileThresh) {
349 thresh = m_threshHi;
350 if (thresh < 0) {
351 if (fabs(amp) < fabs(thresh))
352 lrcGood = false;
353 } else {
354 if (amp < thresh)
355 lrcGood = false;
356 }
357 }
358 }
359
360 if (lrcGood) {
361
362 auto rawChannel = std::make_unique<TileRawChannel>(adc_id, amp, adc_time[ch], adc_qual[ch]);
363 ATH_CHECK( rawChannelContainer->push_back(std::move(rawChannel)) );
364
365 if (TileID::HIGHGAIN == gain) {
366 ++nChHG;
367 eChHG += amp;
368 } else {
369 ++nChLG;
370 eChLG += amp;
371 }
372
373 ATH_MSG_VERBOSE( "Accept RC thr=" << ((thresh < 0) ? "+" : "" ) << thresh
374 << ", id=" << m_tileHWID->to_string(adc_id)
375 << ", amp=" << amp );
376
377 } else {
378
379 ATH_MSG_VERBOSE( "Reject RC thr=" << ((thresh < 0) ? "+" : "") << thresh
380 << ", id=" << m_tileHWID->to_string(adc_id)
381 << ", amp=" << amp );
382 }
383 }
384 }
385 }
386
387
388 // Execution completed.
389 if (msgLvl(MSG::DEBUG)) {
390 msg(MSG::DEBUG) << "TileHitToRawChannel execution completed." << endmsg;
391 msg(MSG::DEBUG) << " nChan=" << nChan
392 << " eHitTot=" << eHitTot
393 << " eneTot=" << eCh
394 << " nchLG=" << nChLG
395 << " eChLG=" << eChLG
396 << " nchHG=" << nChHG
397 << " eChHG=" << eChHG << endmsg;
398 }
399
400
402 ATH_CHECK( rawChannelCnt.record(std::move(rawChannelContainer)) );
403
404 return StatusCode::SUCCESS;
405}
406
408
409 ATH_MSG_INFO( "TileHitToRawChannel::finalize() end." );
410
411 return StatusCode::SUCCESS;
412}
413
#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
CLHEP::HepRandomEngine * getEngine(const EventContext &ctx) const
Retrieve the random engine corresponding to the provided EventContext.
Definition RNGWrapper.h:134
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).