ATLAS Offline Software
Loading...
Searching...
No Matches
TileMuonReceiverDecision.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4
5//****************************************************************************
6// Filename : TileMuonReceiverDecision.cxx
7// Author : Joao Gentil Mendes Saraiva (jmendes@cern.ch)
8// Created : December 2013
9//
10// DESCRIPTION
11//
12// Tile Muon Receiver decision
13//
14// Properties (JobOption Parameters):
15//
16//
17// BUGS:
18//
19// History:
20//
21//
22//****************************************************************************
23
24// Tile includes
31
32// Calo includes
34
35// Atlas includes
39
40TileMuonReceiverDecision::TileMuonReceiverDecision(const std::string& name, ISvcLocator* pSvcLocator)
41 : AthReentrantAlgorithm(name, pSvcLocator),
42 m_tileID(nullptr),
43 m_tileHWID(nullptr),
44 m_cablingService(nullptr),
45 m_tileInfo(nullptr),
47{
48 // declare properties...
49 declareProperty( "MuonReceiverEneThreshCellD6Low" , m_threshold_d6_lo = 500. , "(RUN2) Setting the lowest trigger threshold for cell D6 in MeV (Def=500 MeV)");
50 declareProperty( "MuonReceiverEneThreshCellD6andD5Low" , m_threshold_d5d6_lo = 500. , "(RUN2) Setting the lowest trigger threshold for cell D5+D6 in MeV (Def=500 MeV)");
51 declareProperty( "MuonReceiverEneThreshCellD6High" , m_threshold_d6_hi = 600. , "(RUN2) Setting the highest trigger threshold for cell D6 in MeV (Def=600 MeV)");
52 declareProperty( "MuonReceiverEneThreshCellD6andD5High" , m_threshold_d5d6_hi = 600. , "(RUN2) Setting the highest trigger threshold for cell D5+D6 in MeV (Def=600 MeV)");
53 declareProperty( "MuonReceiverEneThreshCellD5" , m_threshold_d5 = 500. , "(RUN3) Setting the single threshold for cell D5 during Run 3 in MeV (Def=500 MeV)");
54 declareProperty( "MuonReceiverEneThreshCellD6" , m_threshold_d6 = 500. , "(RUN3) Setting the single threshold for cell D6 during Run 3 in MeV (Def=500 MeV)");
55 declareProperty( "MuonReceiverEneThreshCellD5andD6" , m_threshold_d5d6 = 500. , "(RUN3) Setting the single threshold for cell D5+D6 during Run 3 in MeV (Def=500 MeV)");
56 declareProperty( "SelectionCutForMatchedFilterQf" , m_selCutQf = 0. , "n cut for the quality factor of the matched filters");
57 declareProperty( "TileInfoName" , m_infoName = "TileInfo" );
58}
59
63
65
66 ATH_CHECK( m_cablingSvc.retrieve() );
67 m_cablingService = m_cablingSvc->cablingService();
68 m_runPeriod = m_cablingService->runPeriod();
69
70 if( m_manualRunPeriod.value() > 0 ){
71 ATH_MSG_INFO("Overwriting run period from " << m_runPeriod << " to " << m_manualRunPeriod.value());
73 }
74
75 bool doTileMuonReceiverCnt = (m_runPeriod > 1);
76 ATH_CHECK( m_rawChannelContainerKey.initialize(doTileMuonReceiverCnt) );
77 ATH_CHECK( m_muonReceiverContainerKey.initialize(doTileMuonReceiverCnt) );
78 ATH_CHECK( m_emScaleKey.initialize(m_runPeriod != 0) );
79
80 if (m_runPeriod == 0) {
81 ATH_MSG_INFO("Stopping ... TileMuonReceiverDecision should not be used for RUN1 simulations");
82 return StatusCode::SUCCESS;
83 } else {
84 ATH_MSG_INFO("Initializing TileMuonReceiverDecision");
85 }
86
87 //=== retrieve TileID helper from det store
88 ATH_CHECK( detStore()->retrieve(m_tileID) );
89 ATH_CHECK( detStore()->retrieve(m_tileHWID) );
91
92 ATH_MSG_INFO("TileMuonReceiverDecision initialization completed" );
93 return StatusCode::SUCCESS;
94}
95
96StatusCode TileMuonReceiverDecision::execute(const EventContext &ctx) const {
97
98 std::vector<float> thresholds;
99
100 if ( m_runPeriod == 0 ) {
101 ATH_MSG_VERBOSE( "ATT: RUN1 settings TileMuonReceiverDecision will end now" );
102 return StatusCode::SUCCESS;
103 }
104 if ( m_runPeriod == 2 ) {
105 ATH_MSG_VERBOSE( "ATT: RUN2 settings TileMuonReceiverDecsionTool will run now" );
106 ATH_MSG_DEBUG( "Executing TileMuonReceiverDecision" );
107
108 thresholds.push_back(m_threshold_d5d6_hi);
109 thresholds.push_back(m_threshold_d5d6_lo);
110 thresholds.push_back(m_threshold_d6_hi);
111 thresholds.push_back(m_threshold_d6_lo);
112 }
113 if ( m_runPeriod == 3 ) {
114 ATH_MSG_VERBOSE( "ATT: RUN3 settings TileMuonReceiverDecsionTool will run now" );
115 ATH_MSG_DEBUG( "Executing TileMuonReceiverDecision" );
116
117 thresholds.push_back(m_threshold_d5);
118 thresholds.push_back(m_threshold_d6);
119 thresholds.push_back(m_threshold_d5d6);
120 }
121
123 ATH_CHECK( emScale.isValid() );
124
125 // Get the container with the matched filter reconstructed raw channels in MeV
126 //
128 ATH_CHECK( rawChannelContainer.isValid() );
129
130 // Vectors for managemnt for TMDB 2015 configuration with inclusion in trigger in 1.1<eta<1.3
131 //
132 std::vector<bool> tile2SL(4,false);
133 std::vector<float> ene(2,0.0);
134 std::vector<float> time(2,0.0);
135
136 // Create the container to store the decision from the algorithm
137 //
139 ATH_CHECK( decisionContainer.record(std::make_unique<TileMuonReceiverContainer>()) );
140
141 // Special object with thresholds
142 std::unique_ptr<TileMuonReceiverObj> tileMuRcvObj = std::make_unique<TileMuonReceiverObj>(0,thresholds);
143 decisionContainer->push_back(tileMuRcvObj.release());
144
145 // Conversion from TMDB channel number the index to channel number in a drawer
146 //
147#define nEBchan 6
148#define nLBchan 9
149#define maxCell 5
150 // EB: D5(L,R),D6(L,R),D4(L,R)
151 int EBchan[nEBchan]={17,16,37,38,3,2};
152 // LB: D0,D1(L,R),D2(L,R),D3(L,R),BC8(L,R)
153 int LBchan[nLBchan]={0,13,14,25,24,41,44,39,40};
154 // Auxiliary array for cell index
155 int EBIdCell[nEBchan]={0,0,1,1,2,2};
156 int LBIdCell[nLBchan]={0,1,1,2,2,3,3,4,4};
157 // Used for validation only not including in container at the moment
158 float energy_HLX[maxCell]={0.,0.,0.,0.,0.};
159 float time_HLX[maxCell]={0.,0.,0.,0.,0.};
160
161 int suppression_counter = 20;
162 bool suppress_printout = false;
163
164 for (const TileRawChannelCollection* rawChannelCollection : *rawChannelContainer) {
165
166 if (rawChannelCollection->empty()) continue;
167
168 float energy_d5 = 0.0;
169 float energy_d6 = 0.0;
170 float energy_d5d6 = 0.0;
171 float time_d6 = 0.0;
172 float time_d5d6 = 0.0;
173
174 int ich = 0;
175 int jch6 = 0;
176 int jch56 = 0;
177
178 int frag_id = rawChannelCollection->identify();
179 int drawerIdx = TileCalibUtils::getDrawerIdxFromFragId(frag_id);
180 int ros = frag_id>>8;
181 bool eb_ros = ((ros == TileHWID::EXTBAR_POS) || (ros == TileHWID::EXTBAR_NEG));
182 int upperLim = (eb_ros) ? nEBchan : nLBchan;
183
184 if (msgLvl(MSG::VERBOSE)) {
185 int drawer = (frag_id&0xFF);
186 memset(energy_HLX,0,sizeof(energy_HLX));
187 memset(time_HLX,0,sizeof(time_HLX));
188 ATH_MSG_VERBOSE( "(E.0.0) Frag_id: 0x"<< MSG::hex << frag_id << MSG::dec <<" ros: "<< ros <<" drawer: "<< drawer );
189 }
190
191 for (const TileRawChannel* rawChannel : *rawChannelCollection) {
192
193 ++ich;
194 // For TMDB channel numbers are being set differently (17,16,37,38)->(D5L,D5r,D6L,D6R)->(0,1,2,3)
195 HWIdentifier adc_id = rawChannel->adc_HWID() ;
196 // TMDB channel is used in COOL and goes from 0..n with n=5 for EB and n=8 in LB
197 int TMDBchan = m_tileHWID->channel(adc_id) ;
198 if ( TMDBchan >= upperLim ) {
199 if ( !suppress_printout ) {
200 if ( suppression_counter-- ) {
201 ATH_MSG_WARNING( "(E.1."<< ich <<") hwid: "<< m_tileHWID->to_string(adc_id,-1) <<" ch: "<< TMDBchan <<" --> Tile ch: UNKNOWN" );
202 }
203 else {
204 ATH_MSG_WARNING( "Too many HWID WARNINGS - suppressing further output - switch to debug mode to view them all" );
205 suppress_printout = true;
206 }
207 }
208 else {
209 ATH_MSG_DEBUG( "(E.1."<< ich <<") hwid: "<< m_tileHWID->to_string(adc_id,-1) <<" ch: "<< TMDBchan <<" --> Tile ch: UNKNOWN" );
210 }
211 continue;
212 }
213 // TILE channel is the Tile HW channel
214 int TILEchan = (eb_ros) ? EBchan[TMDBchan] : LBchan[TMDBchan];
215
216 float ADC2MeV_factor = emScale->calibrateChannel(drawerIdx, TILEchan, TileID::LOWGAIN, 1.
219 / m_tileInfo->MuRcvCalib(adc_id);
220
221 float energy = rawChannel->amplitude()*ADC2MeV_factor;
222 float time = rawChannel->time();
223
224 ATH_MSG_DEBUG( "(E.1."<< ich <<") hwid: "<< m_tileHWID->to_string(adc_id,-1) <<" ch: "<< TMDBchan <<" --> Tile ch: "<< TILEchan );
225 ATH_MSG_DEBUG( " E[ADC]: "<<rawChannel->amplitude()<<" E[MeV]: "<<energy<<" t[ns]: "<<time<<" QF: "<<rawChannel->quality() );
226
227 if ( eb_ros ) {
228 if ( TMDBchan<4 ) {
229 energy_d5d6 += energy;
230 time_d5d6 += time;
231 ++jch56;
232
233 if ( TMDBchan==2 || TMDBchan==3 ) { /* choose d6 cell */
234 energy_d6 += energy;
235 time_d6 += time;
236 ++jch6;
237 }
238 if ( TMDBchan==0 || TMDBchan==1 ) { /* choose d5 cell */
239 energy_d5 += energy;
240 }
241
242 }
243 if (msgLvl(MSG::VERBOSE)) {
244 energy_HLX[EBIdCell[TMDBchan]] += energy;
245 time_HLX[EBIdCell[TMDBchan]] += time;
246 }
247 } else {
248 if (msgLvl(MSG::VERBOSE)) {
249 energy_HLX[LBIdCell[TMDBchan]] += energy;
250 time_HLX[LBIdCell[TMDBchan]] += time;
251 }
252 }
253 }
254
255 if (msgLvl(MSG::VERBOSE)) {
256 ATH_MSG_VERBOSE( "(X.0.0) Summary of the extended results for HL-LHC: " );
257 if ( eb_ros ) {
258 ATH_MSG_VERBOSE( "(X.1.0) Energy D-5 "<<energy_HLX[0]<<" D-6 "<<energy_HLX[1]<<" D-4 "<<energy_HLX[2] );
259 ATH_MSG_VERBOSE( "(X.2.0) Time D-5 "<<time_HLX[0]/2.<<" D-6 "<<time_HLX[1]/2.<<" D-4 "<<time_HLX[2]/2. );
260 } else {
261 ATH_MSG_VERBOSE( "(X.1.0) Energy D-0 "<<energy_HLX[0]<<" D-1 "<<energy_HLX[1]<<" D-2 "<<energy_HLX[2]<<" D-3 "<<energy_HLX[3]<<" BC-8 "<<energy_HLX[4] );
262 ATH_MSG_VERBOSE( "(X.2.0) Time D-0 "<<time_HLX[0]<<" D-1 "<<time_HLX[1]/2.<<" D-2 "<<time_HLX[2]/2.<<" D-3 "<<time_HLX[3]/2.<<" BC-8 "<<time_HLX[4]/2. );
263 }
264 }
265
266 if (jch56 == 0) { // neither D5 nor D6 found - nothing to do
267 ATH_MSG_VERBOSE( "== NO trigger for this drawer " );
268 continue;
269 }
270
271 if (jch56>1) {
272 time_d5d6 /= jch56;
273 if (jch6>1) time_d6 /= jch6;
274 }
275
276 // A. Above threshold(s)
277 // run2 dual (hi and lo) d5+d6
278 // run3 single d5+d6
279 //
280 bool pass_d5d6_hi = (energy_d5d6>m_threshold_d5d6_hi);
281 bool pass_d5d6_lo = (energy_d5d6>m_threshold_d5d6_lo);
282 bool pass_d5d6 = (energy_d5d6>m_threshold_d5d6);
283 // run2 dual (hi and lo) d6
284 // run3 single d5 and d6
285 bool pass_d6_hi = (energy_d6>m_threshold_d6_hi);
286 bool pass_d6_lo = (energy_d6>m_threshold_d6_lo);
287 bool pass_d5 = (energy_d5>m_threshold_d5);
288 bool pass_d6 = (energy_d6>m_threshold_d6);
289
290 // B.
291 // (RUN2) Fill a vector with size 4 reproducing the 4-bit word with the structure HLHL:[d5+d6][d6][d5+d6][d6]
292 // vector at 0 (d56hi) is the most significant digit in the 4 bits output
293 // (...)
294 // vector at 3 (d6lo) is the least significant digit in the 4 bits output
295 // (RUN3) Fill a vector with size 4 reproducing the 4-bit word with the structure 0HHH:0[d5+d6][d6][d5]
296 // vector at 0 set to 0
297 // vector at 1 [d5+d6] result
298 // vector at 2 [d6] result
299 // vector at 3 [d5] result
300
301 // query for RUN2; if false it must be RUN3
302 //
303 if ( m_runPeriod == 2 ) tile2SL = { pass_d5d6_hi, (!pass_d5d6_hi && pass_d5d6_lo), pass_d6_hi, !pass_d6_hi && pass_d6_lo};
304 if ( m_runPeriod == 3 ) tile2SL = { 0, pass_d5d6, pass_d6, pass_d5};
305
306 // tile2SL[0] = m_run2? pass_d5d6_hi : 0;
307 // tile2SL[1] = m_run2? (!pass_d5d6_hi && pass_d5d6_lo) : pass_d5d6;
308 // tile2SL[2] = m_run2? (pass_d6_hi) : pass_d6;
309 // tile2SL[3] = m_run2? (!pass_d6_hi && pass_d6_lo) : pass_d5;
310
311 if (msgLvl(MSG::VERBOSE)) {
312 if ( m_runPeriod == 2 ) {
313 ATH_MSG_VERBOSE( "(E.2.0) Summary: e(d5+d6)= " << energy_d5d6 << " e(d6)= " << energy_d6 );
314 ATH_MSG_VERBOSE( "(E.3.0) Thresholds: " << m_threshold_d5d6_lo << " " << m_threshold_d5d6_hi << " " << m_threshold_d6_lo << " " << m_threshold_d6_hi );
315 ATH_MSG_VERBOSE( "(E.4.0) Check which thresholds were passed: d56 high " << pass_d5d6_hi << " d56 low " << pass_d5d6_lo << " d6 high " << pass_d6_hi << " d6 low " << pass_d6_lo );
316 ATH_MSG_VERBOSE( "(E.5.0) Output to SL: " << tile2SL[0] << tile2SL[1] << tile2SL[2] << tile2SL[3] );
317 }
318 if ( m_runPeriod == 3 ) {
319 ATH_MSG_VERBOSE( "(E.2.0) Summary: e(d5+d6)= " << energy_d5d6 << " e(d6)= " << energy_d6 << " e(d5)= " << energy_d5 );
320 ATH_MSG_VERBOSE( "(E.3.0) Thresholds: " << m_threshold_d5d6 << " " << m_threshold_d6 << " " << m_threshold_d5 );
321 ATH_MSG_VERBOSE( "(E.4.0) Check which thresholds were passed: d56 " << pass_d5d6 << " d6 " << pass_d6 << " d5 " << pass_d5 );
322 ATH_MSG_VERBOSE( "(E.5.0) Output to SL: " << tile2SL[0] << tile2SL[1] << tile2SL[2] << tile2SL[3] );
323 }
324 }
325 if (tile2SL[0] || tile2SL[1] || tile2SL[2] || tile2SL[3]) {
326 ene[0] = energy_d5d6; ene[1] = energy_d6;
327 time[0] = time_d5d6 ; time[1] = time_d6;
328 std::unique_ptr<TileMuonReceiverObj> tileMuRcvObj = std::make_unique<TileMuonReceiverObj>(frag_id,ene,time,tile2SL);
329 decisionContainer->push_back(tileMuRcvObj.release());
330 } else {
331 ATH_MSG_VERBOSE( "== NULL trigger not include in container " );
332 }
333 } // end loop over collection
334
335 if (msgLvl(MSG::DEBUG)) {
336 ATH_MSG_DEBUG( "== Print TileD decision container output to SL" );
337 decisionContainer->print();
338 }
339
340 ATH_MSG_DEBUG("TileMuonReceiverDecision execution completed" );
341 return StatusCode::SUCCESS;
342}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(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.
#define nLBchan
#define maxCell
#define nEBchan
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
const ServiceHandle< StoreGateSvc > & detStore() const
bool msgLvl(const MSG::Level lvl) const
An algorithm that can be simultaneously executed in multiple threads.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
static unsigned int getDrawerIdxFromFragId(unsigned int fragId)
Returns a drawer hash from fragId This function assumes drawer context (i.e.
@ EXTBAR_NEG
Definition TileHWID.h:71
@ EXTBAR_POS
Definition TileHWID.h:70
TileMuonReceiverDecision(const std::string &name, ISvcLocator *pSvcLocator)
SG::ReadCondHandleKey< TileEMScale > m_emScaleKey
Name of TileEMScale in condition store.
SG::WriteHandleKey< TileMuonReceiverContainer > m_muonReceiverContainerKey
const TileCablingService * m_cablingService
TileCabling instance.
ServiceHandle< TileCablingSvc > m_cablingSvc
Name of Tile cabling service.
virtual StatusCode execute(const EventContext &ctx) const override
execute method
virtual StatusCode initialize() override
initialize method
SG::ReadHandleKey< TileRawChannelContainer > m_rawChannelContainerKey
std::string m_infoName
Name of tile info object in TES.