ATLAS Offline Software
Loading...
Searching...
No Matches
TileRawChannelToTTL1.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3*/
4
5//*****************************************************************************
6// Filename : TileRawChannelToTTL1.cxx
7// Author : Pedro Amaral, based on TileHitToTTL1
8// Created : Feb, 2005
9//
10// DESCRIPTION:
11// Created to simulate the Tile Level 1 Trigger Towers (TTL1), which are
12// hardware sums of the Tile channels, about 3 or 4 channels per tower.
13// The towers are read out in N time slices, with N=9 as a default.
14// Noise, pedestal and threshold counts are included, in units of mV.
15// Units into TTL1 are in mV.
16//
17// Option to have variable phases for each trigger tower, of the sampling
18// of the TTL1 shape.
19// Default = option turned off, all phases set to zero.
20// to turn on, set TileConstantTTL1Shape = False, and
21// phase info is then read from TileInfo.
22//
23// HISTORY:
24//
25// BUGS:
26//
27//*****************************************************************************
28
29// Tile includes
30// small hack to be able to modify original TileRawChannel
32
34
43
44// Calo includes
47
48// Atlas includes
52
53//CLHEP includes
54#include <CLHEP/Random/Randomize.h>
55
56using namespace CLHEP;
57
58//C++ STL includes
59#include <vector>
60
61//
62// Constructor
63//
64TileRawChannelToTTL1::TileRawChannelToTTL1(const std::string& name, ISvcLocator* pSvcLocator)
65 : AthAlgorithm(name, pSvcLocator)
66 , m_tileID(0)
67 , m_tileHWID(0)
68 , m_tileInfo(0)
69 , m_TT_ID(0)
70 , m_phase(0)
71 , m_nSamp(0)
72 , m_iTrig(0)
73 , m_tileBadChanTool("TileBadChanTool")
74 , m_tileToolEmscale("TileCondToolEmscale")
75{
76 declareProperty("TileInfoName", m_infoName = "TileInfo");
77 declareProperty("TileConstantTTL1Shape", m_constantTTL1shape = true);
78 declareProperty("TileBadChanTool", m_tileBadChanTool);
79 declareProperty("TileCondToolEmscale", m_tileToolEmscale);
80}
81
84
85//
86// Alg standard initialize function
87//
89
90 // retrieve CaloLVL1_ID, TileID, TileHWID helpers and TileIfno from det store
91
92 CHECK( detStore()->retrieve(m_TT_ID) );
93 CHECK( detStore()->retrieve(m_tileID) );
94 CHECK( detStore()->retrieve(m_tileHWID) );
95
96 //=== get TileBadChanTool
97 CHECK( m_tileBadChanTool.retrieve() );
98
99 //=== get TileCondToolEmscale
100 CHECK( m_tileToolEmscale.retrieve() );
101
102 CHECK( detStore()->retrieve(m_tileInfo, m_infoName) );
103
104
105 // Here get already TTL1 Shapes, so as not to perform this on every execute:
106 m_nSamp = m_tileInfo->NdigitSamples(); // number of time slices for each chan
107 m_iTrig = m_tileInfo->ItrigSample(); // index of the triggering time slice
108 m_TTL1Shape.resize(m_nSamp, 0.);
110 m_phase = 0.0;
112 for (int jsamp = 0; jsamp < m_nSamp; ++jsamp) {
113 ATH_MSG_DEBUG( "jsamp=" << jsamp << " ttl1shape=" << m_TTL1Shape[jsamp] );
114 }
115 }
116
117 ATH_CHECK( m_rawChannelContainerKey.initialize() );
118 ATH_CHECK( m_ttl1ContainerKey.initialize() );
119
120 ATH_MSG_INFO( "TileRawChannelToTTL1 initialization completed" );
121
122 return StatusCode::SUCCESS;
123}
124/*==========================================================================*/
125//
126// Begin Execution Phase.
127//
129
130 ATH_MSG_DEBUG( "Executing TileRawChannelToTTL1");
131
132 /*......................................................*/
133 // Step 2: Get all global parameters that will be needed for processing.
134 /* Get TileNoise flag from TileInfo (true => generate noise in TileDigits) */
135 bool tileNoise = m_tileInfo->TileNoise();
136 /* Get TileZeroSuppress flag from TileInfo
137 (true => apply threshold to Digits) */
138 bool tileThresh = m_tileInfo->TileZeroSuppress();
139 // declare array for random number generation for noise in samples.
140 double Rndm[16]; // Can't use variable size array
141 // declare TTL1 parameters to be obtained from TileInfo
142 float ttL1Calib, ttL1NoiseSigma, ttL1Ped, ttL1Thresh;
143
144 ATH_MSG_DEBUG( "nSamp=" << m_nSamp
145 << ", iTrig=" << m_iTrig
146 << ", tileNoise=" << ((tileNoise) ? "true" : "false")
147 << ", tileThresh=" << ((tileThresh) ? "true" : "false") );
148
149 /*......................................................*/
150 // step 3: Get rawChannel container from TES and create TTL1 container
151 /* Note that rawChannel container has 256 collections (one for each drawer),
152 but TTL1 container has no collections and no structure. */
154 ATH_CHECK( rawChannelContainer.isValid() );
155
156 TileRawChannelUnit::UNIT rChUnit = rawChannelContainer->get_unit();
157 //TileFragHash::TYPE rChType = rawChannelContainer->get_type();
158
160 ATH_CHECK( ttl1Container.record(std::make_unique<TileTTL1Container>()) );
161 ATH_MSG_DEBUG( "TileTTL1Container registered successfully (" << m_ttl1ContainerKey.key() << ")" );
162
163 /*......................................................*/
164 // Step 4: Create temporary arrays for processing signals.
165 /* Create array for all TT amplitudes in a single drawer. */
166 Identifier ttId[16]; // array of TT identifiers in a single drawer
167 float ttAmp[16]; // array of all TT amplitudes in a single drawer
168 bool ttRawChannel[16]; // array of TT occupancy in a single drawer
169 int nTT; // number of rawChannel towers in this drawer.
170 int nRawChannel; // number of rawChannels in this drawer.
171 int nIgnore; // number of ignored rawChannels in this drawer.
172 int nTTTot = 0; // total number of rawChannel towers.
173 int nRawChannelTot = 0; // total number of rawChannels.
174 int nIgnoreTot = 0; // total number of ignored rawChannels.
175 float ttAmpTot = 0; // total energy in good level-1 towers.
176 float ttAmpTotIg = 0.; // total energy in "ignored" level-1 towers.
177 int minieta, maxieta, posneg;
178
179 /* Create array for the nSamp time-samples of a single tower. */
180 std::vector<float> ttL1samples(m_nSamp);
181
182 /*......................................................*/
183 // Step 5: Begin loop over all collections (collection = electronic drawer).
184 for (const TileRawChannelCollection* rawChannelCollection : *rawChannelContainer) {
185
186 HWIdentifier drawer_id = m_tileHWID->drawer_id(rawChannelCollection->identify());
187 int ros = m_tileHWID->ros(drawer_id);
188 int drawer = m_tileHWID->drawer(drawer_id);
189 int drawerIdx = TileCalibUtils::getDrawerIdx(ros, drawer);
190
191 switch (ros) {
193 posneg = +1;
194 minieta = 0;
195 maxieta = 8;
196 break;
198 posneg = -1;
199 minieta = 0;
200 maxieta = 8;
201 break;
203 posneg = +1;
204 minieta = 9;
205 maxieta = 14;
206 break;
208 posneg = -1;
209 minieta = 9;
210 maxieta = 14;
211 break;
212 default:
213 posneg = minieta = maxieta = 0;
214 }
215
216 /* Zero temporary array of trigger tower amplitudes (TTL1amp) for this collection. */
217 memset(ttAmp, 0, sizeof(ttAmp));
218 memset(ttRawChannel, 0, sizeof(ttRawChannel));
219 nTT = nIgnore = nRawChannel = 0;
220
221 /*......................................................*/
222 // Step 6: Iterate over all rawChannels in this collection, summing amps for each tower.
223 for (const TileRawChannel* rawChannel : *rawChannelCollection) {
224
225 /* Get rawChannel Identifier */
226 HWIdentifier hwid = rawChannel->adc_HWID();
227 int channel = m_tileHWID->channel(hwid);
228 int adc = m_tileHWID->adc(hwid);
229
230 // note that amplitude() is in unknown units (can be even online MeV), convert it to MeV first
231 float e = m_tileToolEmscale->channelCalib(drawerIdx, channel, adc,
232 rawChannel->amplitude(),
233 rChUnit,
235
236 // convert MeV to pCb
237 float q = e / m_tileToolEmscale->channelCalib(drawerIdx, channel, adc, 1.0,
239
240 int ieta = 999;
241 int iphi = 999;
242
243 Identifier pmt_id = rawChannel->pmt_ID();
244 if (pmt_id.is_valid() && m_tileID->section(pmt_id) < 4
245 && m_tileID->section(pmt_id) > 0) {
246
247 /* Get TT Identifier for this pmt */
248 Identifier tt_id = rawChannel->tt_ID();
249 /* Get eta-phi indices of TTL1 for this channel. */
250 ieta = m_TT_ID->eta(tt_id);
251 iphi = m_TT_ID->phi(tt_id); // (same as module).
252 if (iphi != drawer)
253 ATH_MSG_ERROR( "drawer=" << drawer
254 << ", iphi=" << iphi
255 << "id=" << m_tileID->to_string(pmt_id) );
256
257 if (ttRawChannel[ieta]) { // already exists - just add charge
258 ttAmp[ieta] += q;
259 } else { // rawChannel in new TT
260 ttId[ieta] = tt_id;
261 ttRawChannel[ieta] = true;
262 ttAmp[ieta] = q;
263 if (ieta >= minieta && ieta <= maxieta)
264 ++nTT; // count only valid TT
265 }
266 ++nRawChannel;
267 if (ieta < minieta || ieta > maxieta)
268 ++nIgnore;
269 //Sum cell energy for comparison to other algos.
270 if (ieta >= minieta && ieta <= maxieta) {
271 ttAmpTot += e;
272 } else {
273 ttAmpTotIg += e;
274 }
275
276 if (msgLvl(MSG::VERBOSE)) {
277 /* Diagnostic checks: */
278 int side = m_tileID->side(pmt_id);
279 int tower = m_tileID->tower(pmt_id);
280 int sample = m_tileID->sample(pmt_id);
281 int pmt = m_tileID->pmt(pmt_id);
282 int channel = m_tileHWID->channel(hwid);
283 msg(MSG::VERBOSE) << "New RawChannel:"
284 << " ros=" << ros
285 << ", drawer=" << drawer
286 << ", ch=" << channel
287 << ", side=" << side
288 << ", tower=" << tower
289 << ", sample=" << sample
290 << ", pmt=" << pmt
291 << ", e=" << e
292 << ", ie=" << ieta
293 << ", ip=" << iphi;
294
295 if (ieta >= minieta && ieta <= maxieta)
296 msg(MSG::VERBOSE) << endmsg;
297 else
298 msg(MSG::VERBOSE) << " Outside limits" << endmsg;
299 }
300
301 } else {
302 ATH_MSG_VERBOSE( "Tile Channel with no tt_id" );
303 }
304
305 } // end loop over rawChannels in this drawer.
306
307 nTTTot += nTT;
308 nRawChannelTot += nRawChannel;
309 nIgnoreTot += nIgnore;
310
311 ATH_MSG_VERBOSE( "Statistics for"
312 << " ROS=" << ros
313 << ", drawer=" << drawer
314 << "; posneg=" << posneg
315 << ", minieta=" << minieta
316 << ", maxieta=" << maxieta
317 << "; nTT=" << nTT
318 << ", nRawChannel=" << nRawChannel
319 << ", nIgnore=" << nIgnore );
320
321 /*......................................................*/
322 // Step 7: We now have all the TTL1 amplitudes for this drawer.
323 // Loop over towers to produce the electronics signals (= time samples).
324 // If tileNoise is requested, generate random numbers to give noise
325 for (int ieta = minieta; ieta <= maxieta; ++ieta) {
326 int iphi = drawer;
327 bool Good = ttRawChannel[ieta];
328 if (tileNoise)
329 Good = true;
330 if (Good) {
331 if (!ttRawChannel[ieta])
332 ttId[ieta] = m_TT_ID->tower_id(posneg, 1, 0, ieta, drawer);
333
334 ttL1NoiseSigma = m_tileInfo->TTL1NoiseSigma(ttId[ieta]);
335 ttL1Thresh = m_tileInfo->TTL1Thresh(ttId[ieta]);
336 ttL1Ped = m_tileInfo->TTL1Ped(ttId[ieta]);
337 ttL1Calib = m_tileInfo->TTL1Calib(ttId[ieta]);
338 ttAmp[ieta] *= ttL1Calib; // convert pCb to mV
339 if (!m_constantTTL1shape) {
340 // Get phase of the TTL1 tower. default=0,
341 // meaning L1Cal Trigger samples TTL1 pulse right at the peak.
342 // ieta: barrel=0-8, ext.barrel=9-14
343 m_phase = m_tileInfo->ttl1Phase(posneg, ieta, iphi);
344 /* Include shaping fuction, pedestal, and noise. */
346 }
347 if (tileNoise)
348 CLHEP::RandGauss::shootArray(m_nSamp, Rndm);
349 for (int jsamp = 0; jsamp < m_nSamp; ++jsamp) {
350 ttL1samples[jsamp] = ttAmp[ieta] * m_TTL1Shape[jsamp] + ttL1Ped;
351 if (tileNoise)
352 ttL1samples[jsamp] += ttL1NoiseSigma * Rndm[jsamp];
353 } // end loop over samples
354 if (tileThresh) {
355 if (ttL1samples[m_iTrig] - ttL1Ped < ttL1Thresh)
356 Good = false;
357 }
358 } // end first "Good" section.
359 /* Create the new TTL1 object and store in TTL1Container. */
360 if (Good) {
361 ATH_MSG_DEBUG( " TTL1: "
362 << " ros=" << ros
363 << ", ieta=" << ieta
364 << ", iphi=" << iphi
365 << ", rawChannelTrue=" << ttRawChannel[ieta]
366 << ", Good=" << Good
367 << ", amp0=" << ttAmp[ieta]
368 << ", digitIn=" << ttL1samples[m_iTrig] );
369
370 /*
371 The following lines are commented out.
372
373 if (msgLvl(MSG::VERBOSE)) {
374 msg(MSG::VERBOSE) << " ttL1Digits=";
375 for (int jsamp = 0; jsamp < nSamp; ++jsamp) {
376 msg(MSG::VERBOSE) << ttL1samples[jsamp] << " ";
377 }
378 msg(MSG::VERBOSE) << endmsg;
379
380 msg(MSG::VERBOSE) << " Rndm=";
381 for (int jsamp = 0; jsamp < nSamp; ++jsamp) {
382 msg(MSG::VERBOSE) << Rndm[jsamp] << " ";
383 }
384 msg(MSG::VERBOSE) << endmsg;
385 }
386 The preceding lines are commented out
387 */
388
389 ttl1Container->push_back(std::make_unique<TileTTL1>(ttId[ieta], ttL1samples));
390 } // end second "Good" section.
391 } // end loop over towers
392 } // end loop over collections
393
394 // Execution completed.
395 ATH_MSG_DEBUG( "TileRawChannelToTTL1 execution completed." );
396 ATH_MSG_DEBUG( " nTTTot=" << nTTTot
397 << " nRawChannelTot=" << nRawChannelTot
398 << " nIgnoreTot=" << nIgnoreTot
399 << " ttAmpTot=" << ttAmpTot
400 << " ttAmpTotIg=" << ttAmpTotIg
401 << " =>eneTot=" << ttAmpTot + ttAmpTotIg );
402
403 return StatusCode::SUCCESS;
404}
405
407
408 ATH_MSG_INFO( "TileRawChannelToTTL1::finalize() end" );
409
410 return StatusCode::SUCCESS;
411}
412
413
414
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#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.
#define CHECK(...)
Evaluate an expression and check for errors.
Handle class for reading from StoreGate.
Handle class for recording to StoreGate.
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
bool is_valid() const
Check if id is in a valid state.
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.
@ BARREL_POS
Definition TileHWID.h:68
@ EXTBAR_NEG
Definition TileHWID.h:71
@ BARREL_NEG
Definition TileHWID.h:69
@ EXTBAR_POS
Definition TileHWID.h:70
std::vector< double > m_TTL1Shape
ToolHandle< ITileBadChanTool > m_tileBadChanTool
Tile Bad Channel tool.
const TileInfo * m_tileInfo
const TileHWID * m_tileHWID
TileRawChannelToTTL1(const std::string &name, ISvcLocator *pSvcLocator)
SG::WriteHandleKey< TileTTL1Container > m_ttl1ContainerKey
ToolHandle< TileCondToolEmscale > m_tileToolEmscale
main Tile Calibration tool
SG::ReadHandleKey< TileRawChannelContainer > m_rawChannelContainerKey
const CaloLVL1_ID * m_TT_ID