ATLAS Offline Software
Loading...
Searching...
No Matches
AFPToFAlgorithm.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* AFPToFAlgorithm
6*
7*
8*/
9
13
14
15AFPToFAlgorithm::AFPToFAlgorithm( const std::string& name, ISvcLocator* pSvcLocator )
16:AthMonitorAlgorithm(name,pSvcLocator)
17, m_afpToFHitContainerKey("AFPToFHitContainer"), m_afpTrackContainerKey( "AFPTrackContainer" )
18
19{
20 declareProperty( "AFPToFHitContainer", m_afpToFHitContainerKey );
21 declareProperty( "AFPTrackContainer", m_afpTrackContainerKey );
22}
23
24
26
27
29 using namespace Monitored;
30
36
37 // We must declare to the framework in initialize what SG objects we are going to use
38 SG::ReadHandleKey<xAOD::AFPToFHitContainer> afpToFHitContainerKey("AFPToFHits");
40 SG::ReadHandleKey<xAOD::AFPTrackContainer> afpTrackContainerKey( "AFPTracks" );
41 ATH_CHECK( m_afpTrackContainerKey.initialize() );
42
43 ATH_MSG_INFO( "BunchCrossingKey initialization (ToF)" );
44 ATH_CHECK(m_bunchCrossingKeyToF.initialize());
45 ATH_MSG_INFO( "initialization completed (ToF)" );
46
48}
49
50
51StatusCode AFPToFAlgorithm::fillHistograms( const EventContext& ctx ) const {
52 using namespace Monitored;
53
54 const unsigned NTRAINS = 4;
55 const unsigned NBARS = 4;
56 const unsigned NSIDES = 2;
57 enum { FRONT, MIDDLE, END, NPOS } position = NPOS;
58
59 auto bcidAllToF = Monitored::Scalar<int>("bcidAllToF", 0);
60 Monitored::Scalar<int> bcidToF[NPOS] =
61 { Monitored::Scalar<int>("bcidFrontToF", 0),
62 Monitored::Scalar<int>("bcidMiddleToF", 0),
63 Monitored::Scalar<int>("bcidEndToF", 0) };
64
65 // Declare the quantities which should be monitored
66 auto lb = Monitored::Scalar<int>("lb", 0);
67 auto nTofHits = Monitored::Scalar<int>("nTofHits", 1);
68 auto trainID = Monitored::Scalar<int>("trainID", 0);
69 auto barInTrainID = Monitored::Scalar<int>("barInTrainID", 0);
70
71 auto ToFHits_MU_Weight = Monitored::Scalar<float>("ToFHits_MU_Weight", 0.0);
72 auto muPerBXToF = Monitored::Scalar<float>("muPerBXToF", 0.0);
73
74 auto numberOfHit = Monitored::Scalar<int>("numberOfHit", 0);
75 auto barInTrainIDSide = Monitored::Scalar<int>("barInTrainIDSide", 0);
76 auto barInTrainAll = Monitored::Scalar<int>("barInTrainAll", 0);
77 auto ToFHits_side = Monitored::Scalar<int>("ToFHits_side", 0);
78
79 auto lbAandCToFEvents = Monitored::Scalar<int>("lbAandCToFEvents", 0);
80 Monitored::Scalar<int> lbToFEvents[NSIDES] =
81 { Monitored::Scalar<int>("lbAToFEvents", 0),
82 Monitored::Scalar<int>("lbCToFEvents", 0) };
83
84 // per-mu TH1F variables
85 auto lbToFTrainAll = Monitored::Scalar<int>("lbToFTrainAll", 0);
86 auto weightToFTrainAll = Monitored::Scalar<float>("weightToFTrainAll", 0.0);
87 auto lbToFTrainFront = Monitored::Scalar<int>("lbToFTrainFront", 0);
88 auto weightToFTrainFront = Monitored::Scalar<float>("weightToFTrainFront", 0.0);
89 auto lbToFTrainMiddle = Monitored::Scalar<int>("lbToFTrainMiddle", 0);
90 auto weightToFTrainMiddle = Monitored::Scalar<float>("weightToFTrainMiddle", 0.0);
91 auto lbToFTrainEnd = Monitored::Scalar<int>("lbToFTrainEnd", 0);
92 auto weightToFTrainEnd = Monitored::Scalar<float>("weightToFTrainEnd", 0.0);
93 auto lbToFBar = Monitored::Scalar<int>("lbToFBar", 0);
94 auto lbToFBar_Weight = Monitored::Scalar<float>("lbToFBar_Weight", 0.0);
95
97 lb = eventInfo->lumiBlock();
98 lbAandCToFEvents = eventInfo->lumiBlock();
99 muPerBXToF = lbAverageInteractionsPerCrossing(ctx);
100
101 if (muPerBXToF == 0.0) {
102 ATH_MSG_DEBUG("AverageInteractionsPerCrossing is 0, forcing to 1.0");
103 muPerBXToF=1.0;
104 }
105
106 ToFHits_MU_Weight = 1/muPerBXToF;
107 lbToFBar_Weight = 1/muPerBXToF;
108 weightToFTrainAll = 1/muPerBXToF;
109 weightToFTrainFront = 1/muPerBXToF;
110 weightToFTrainMiddle = 1/muPerBXToF;
111 weightToFTrainEnd = 1/muPerBXToF;
112
113 for(unsigned int s = 0; s < NSIDES; s++)
114 {
115 lbToFEvents[s] = eventInfo->lumiBlock();
116 }
117
118 fill("AFPToFTool", lb, muPerBXToF);
119
120 // BCX handler
121 const unsigned int tempBCID = eventInfo->bcid();
123 if (!bcidHdlToF.isValid()) {
124 ATH_MSG_ERROR( "Unable to retrieve BunchCrossing conditions object (ToF)" );
125 }
126 const BunchCrossingCondData* bcDataToF{*bcidHdlToF};
127
128 // Classifying bunches by position in train (Front, Middle, End)
129 if(bcDataToF->isFilled(tempBCID))
130 {
131 bcidAllToF = tempBCID;
132 fill("AFPToFTool", bcidAllToF);
133 if(!bcDataToF->isFilled(tempBCID-1))
134 {
135 position = FRONT;
136 }
137 else if(bcDataToF->isFilled(tempBCID+1))
138 {
139 position = MIDDLE;
140 }
141 else
142 {
143 position = END;
144 }
145 bcidToF[position] = tempBCID;
146 fill("AFPToFTool", bcidToF[position]);
147 }
148
149
151 if(! afpToFHitContainer.isValid())
152 {
153 ATH_MSG_WARNING("evtStore() does not contain hits collection with name " << m_afpToFHitContainerKey);
154 return StatusCode::SUCCESS;
155 }
156
157 ATH_CHECK( afpToFHitContainer.initialize() );
158
160 if ( !afpTrackContainer.isValid() ) {
161 ATH_MSG_WARNING( "evtStore() does not contain hits collection with name " << m_afpTrackContainerKey );
162 return StatusCode::SUCCESS;
163 }
164 ATH_CHECK( afpTrackContainer.initialize() );
165
166 nTofHits = afpToFHitContainer->size();
167 fill("AFPToFTool", lb, nTofHits);
168
169 int eventsInStations[4] = {};
170
171 // hit counts per event for TProfile
172 unsigned int totalHitsPerTrainAll[NSIDES][NTRAINS] = {};
173 unsigned int totalHitsPerTrainFME[NSIDES][NTRAINS][NPOS] = {};
174 unsigned int totalHitsPerBar[NSIDES][NTRAINS][NBARS] = {};
175 unsigned int totalStationHits[NSIDES] = {};
176
177 for(const xAOD::AFPToFHit *hitsItr: *afpToFHitContainer)
178 {
179 if (hitsItr->stationID()<4 && hitsItr->stationID()>=0 && hitsItr->trainID()<4 && hitsItr->trainID()>=0 && hitsItr->barInTrainID()<4 && hitsItr->barInTrainID()>=0)
180 {
181 trainID = hitsItr->trainID();
182 barInTrainID = hitsItr->barInTrainID();
183 ++eventsInStations[hitsItr->stationID()];
184
185 // Only process ToF stations: 0 (farAside) and 3 (farCside)
186 if(hitsItr->stationID() != 0 && hitsItr->stationID() != 3)
187 continue;
188
189 int side = (hitsItr->stationID() == 3) ? 1 : 0;
190 unsigned int train = hitsItr->trainID();
191 unsigned int bar = hitsItr->barInTrainID();
192
193 numberOfHit = train;
194 fill(m_tools[m_SideGroup.at(m_sidesToF.at(side))], numberOfHit);
195
196 barInTrainIDSide = bar;
197 fill(m_tools[m_SideTrainGroup.at(m_sidesToF.at(side)).at(m_trainsToF.at(train))], barInTrainIDSide);
198
199 barInTrainAll = train * 4 + bar;
200 fill(m_tools[m_SideGroup.at(m_sidesToF.at(side))], barInTrainAll);
201
202 ToFHits_side = eventInfo->lumiBlock();
203 fill(m_tools[m_SideGroup.at(m_sidesToF.at(side))], ToFHits_side, ToFHits_MU_Weight);
204
205 fill(m_tools[m_StationNamesGroup.at(m_stationNamesToF.at(hitsItr->stationID()))], barInTrainID, trainID);
206
207 // per-mu TH1F per-bar
208 lbToFBar = eventInfo->lumiBlock();
209 fill(m_tools[m_BarsInTrains.at(m_sidesToF.at(side)).at(m_trainsToF.at(train)).at(m_barsToF.at(bar))], lbToFBar, lbToFBar_Weight);
210
211 // Accumulate counts for TProfile
212 ++totalStationHits[side];
213 ++totalHitsPerTrainAll[side][train];
214 if(bar < NBARS) ++totalHitsPerBar[side][train][bar];
215 if(position != NPOS) ++totalHitsPerTrainFME[side][train][position];
216
217 // per-mu TH1F: fill per-train
218 lbToFTrainAll = eventInfo->lumiBlock();
219 fill(m_tools[m_SideTrainGroup.at(m_sidesToF.at(side)).at(m_trainsToF.at(train))], lbToFTrainAll, weightToFTrainAll);
220
221 if(position == FRONT)
222 {
223 lbToFTrainFront = eventInfo->lumiBlock();
224 fill(m_tools[m_SideTrainGroup.at(m_sidesToF.at(side)).at(m_trainsToF.at(train))], lbToFTrainFront, weightToFTrainFront);
225 }
226 else if(position == MIDDLE)
227 {
228 lbToFTrainMiddle = eventInfo->lumiBlock();
229 fill(m_tools[m_SideTrainGroup.at(m_sidesToF.at(side)).at(m_trainsToF.at(train))], lbToFTrainMiddle, weightToFTrainMiddle);
230 }
231 else if(position == END)
232 {
233 lbToFTrainEnd = eventInfo->lumiBlock();
234 fill(m_tools[m_SideTrainGroup.at(m_sidesToF.at(side)).at(m_trainsToF.at(train))], lbToFTrainEnd, weightToFTrainEnd);
235 }
236
237 }
238 }
239
240 // Events histograms
241 if(eventsInStations[0] > 0 || eventsInStations[3] > 0)
242 {
243 fill("AFPToFTool", lbAandCToFEvents);
244
245 if(eventsInStations[0] > 0)
246 {
247 fill("AFPToFTool", lbToFEvents[0]);
248 }
249 if(eventsInStations[3] > 0)
250 {
251 fill("AFPToFTool", lbToFEvents[1]);
252 }
253 }
254
255 // per-event TProfile per-train
256 auto lbToFPerEvent = Monitored::Scalar<int>("lbToFPerEvent", eventInfo->lumiBlock());
257 auto hitsPerTrainAllPP = Monitored::Scalar<float>("hitsPerTrainAllPP", 0.0);
258 auto lbToFPerEventFront = Monitored::Scalar<int>("lbToFPerEventFront", eventInfo->lumiBlock());
259 auto hitsPerTrainFrontPP = Monitored::Scalar<float>("hitsPerTrainFrontPP", 0.0);
260 auto lbToFPerEventMiddle = Monitored::Scalar<int>("lbToFPerEventMiddle", eventInfo->lumiBlock());
261 auto hitsPerTrainMiddlePP = Monitored::Scalar<float>("hitsPerTrainMiddlePP", 0.0);
262 auto lbToFPerEventEnd = Monitored::Scalar<int>("lbToFPerEventEnd", eventInfo->lumiBlock());
263 auto hitsPerTrainEndPP = Monitored::Scalar<float>("hitsPerTrainEndPP", 0.0);
264
265 for(unsigned int side = 0; side < NSIDES; side++)
266 {
267 for(unsigned int train = 0; train < NTRAINS; train++)
268 {
269 hitsPerTrainAllPP = totalHitsPerTrainAll[side][train] / muPerBXToF;
270 fill(m_tools[m_SideTrainGroup.at(m_sidesToF.at(side)).at(m_trainsToF.at(train))], lbToFPerEvent, hitsPerTrainAllPP);
271
272 hitsPerTrainFrontPP = totalHitsPerTrainFME[side][train][FRONT] / muPerBXToF;
273 if(position == FRONT)
274 fill(m_tools[m_SideTrainGroup.at(m_sidesToF.at(side)).at(m_trainsToF.at(train))], lbToFPerEventFront, hitsPerTrainFrontPP);
275
276 hitsPerTrainMiddlePP = totalHitsPerTrainFME[side][train][MIDDLE] / muPerBXToF;
277 if(position == MIDDLE)
278 fill(m_tools[m_SideTrainGroup.at(m_sidesToF.at(side)).at(m_trainsToF.at(train))], lbToFPerEventMiddle, hitsPerTrainMiddlePP);
279
280 hitsPerTrainEndPP = totalHitsPerTrainFME[side][train][END] / muPerBXToF;
281 if(position == END)
282 fill(m_tools[m_SideTrainGroup.at(m_sidesToF.at(side)).at(m_trainsToF.at(train))], lbToFPerEventEnd, hitsPerTrainEndPP);
283 }
284 }
285
286 // per-event TProfile per-bar
287 auto lbToFBarPerEvent = Monitored::Scalar<int>("lbToFBarPerEvent", eventInfo->lumiBlock());
288 auto hitsPerBarPP = Monitored::Scalar<float>("hitsPerBarPP", 0.0);
289
290 for(unsigned int side = 0; side < NSIDES; side++)
291 {
292 for(unsigned int train = 0; train < NTRAINS; train++)
293 {
294 for(unsigned int bar = 0; bar < NBARS; bar++)
295 {
296 hitsPerBarPP = totalHitsPerBar[side][train][bar] / muPerBXToF;
297 fill(m_tools[m_BarsInTrains.at(m_sidesToF.at(side)).at(m_trainsToF.at(train)).at(m_barsToF.at(bar))], lbToFBarPerEvent, hitsPerBarPP);
298 }
299 }
300 }
301
302 // per-event TProfile station-level
303 auto lbToFStationPerEvent = Monitored::Scalar<int>("lbToFStationPerEvent", eventInfo->lumiBlock());
304 auto hitsPerStationPP = Monitored::Scalar<float>("hitsPerStationPP", 0.0);
305
306 for(unsigned int side = 0; side < NSIDES; side++)
307 {
308 hitsPerStationPP = totalStationHits[side] / muPerBXToF;
309 fill(m_tools[m_SideGroup.at(m_sidesToF.at(side))], lbToFStationPerEvent, hitsPerStationPP);
310 }
311
312 return fillHistograms_crossBarDeltaT(*afpTrackContainer, *afpToFHitContainer);
313}
314
316 const xAOD::AFPTrackContainer& afpTrackContainer,
317 const xAOD::AFPToFHitContainer& afpToFHitContainer) const {
318 // Initialize monitored variables for histogram filling
319 Monitored::Scalar<float> crossBarDeltaT[2] = {
320 Monitored::Scalar<float>( "crossBarDeltaT_A", 0.0 ),
321 Monitored::Scalar<float>( "crossBarDeltaT_C", 0.0 )
322 };
323
324 bool channel_present[2][16] = {};
325 bool multihit[2] = {};
326 std::size_t track_count[2] = {};
327 std::size_t train_count[2][4] = {};
328
329 for (const xAOD::AFPTrack* tracksItr : afpTrackContainer)
330 {
331 const auto side = tracksItr->stationID() == 3;
332 // Ignore tracks that are not from FAR stations
333 if (tracksItr->stationID() != 0 && tracksItr->stationID() != 3)
334 continue;
335 ++track_count[side];
336 }
337
338 // Load the necessary information
339 auto times = std::vector<std::vector<std::vector<float>>>(2, std::vector<std::vector<float>>(4, std::vector<float>(4, -10000)));
340 for (const xAOD::AFPToFHit* hitsItr : afpToFHitContainer)
341 {
342 const auto side = hitsItr->stationID() == 3;
343 const auto train = hitsItr->trainID();
344 const auto bar = hitsItr->barInTrainID();
345 const auto channel = 4 * train + bar;
346 const auto tof_time = hitsItr->time();
347 const auto TimePs=(tof_time)*1000;
348 //Cut on only 1 SiT track in the monitored station
349 if (track_count[side] != 1) continue;
350 // Ignore hits with an impossible origin
351 if (hitsItr->stationID() != 0 && hitsItr->stationID() != 3)
352 continue;
353 if (train < 0 || train >= 4 || bar < 0 || bar >= 4) continue;
354 if (channel_present[side][channel])
355 multihit[side] = true;
356 channel_present[side][channel] = true;
357 ++train_count[side][train];
358
359 times[side][train][bar]=TimePs;
360
361 }
362
363 for (uint8_t side : {0, 1})
364 {
365 // Cut on only 1 SiT track in the monitored station
366 if (track_count[side] != 1) continue;
367 // Cut on maximum of 1 hit in each ToF channel
368 if (multihit[side]) continue;
369 //Cut on maximum 1 train per event
370 uint8_t multrain[2] = {};
371 for (uint8_t train = 0; train < 4; ++train) {
372 if (train_count[side][train]>1) {
373 ++multrain[side];
374 }
375 }
376 if (multrain[side]>1) continue;
377 //fill histos
378 for (uint8_t train = 0; train < 4; ++train) {
379 for (uint8_t bar1 = 0; bar1 < 4; ++bar1) {
380 for (uint8_t bar2 = 0; bar2 < 4; ++bar2) {
381 if (bar2>bar1) {
382 int comb = bar1*bar2+bar2-1;
383 if (comb==5) {comb=4;}
384 if (comb==8) {comb=5;}
385 int global_comb = train*6 + comb;
386 if (times[side][train][bar1]>-10000 && times[side][train][bar2]>-10000) {
387 crossBarDeltaT[side] = (times[side][train][bar1] - times[side][train][bar2]);
388 fill(m_tools[m_GroupChanCombDeltaT.at(m_chanComb.at(global_comb))], crossBarDeltaT[side]);
389 }
390 }
391 }
392 }
393 }
394 }
395
396 return StatusCode::SUCCESS;
397}
Definitions of AFP stations identification numbers.
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
Property holding a SG store/key/clid from which a ReadHandle is made.
std::vector< std::string > m_barsToF
virtual StatusCode fillHistograms_crossBarDeltaT(const xAOD::AFPTrackContainer &, const xAOD::AFPToFHitContainer &) const
SG::ReadHandleKey< xAOD::AFPToFHitContainer > m_afpToFHitContainerKey
std::vector< std::string > m_trainsToF
std::map< std::string, int > m_GroupChanCombDeltaT
virtual StatusCode initialize() override
initialize
virtual StatusCode fillHistograms(const EventContext &ctx) const override
adds event to the monitoring histograms
std::vector< std::string > m_sidesToF
AFPToFAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
SG::ReadHandleKey< xAOD::AFPTrackContainer > m_afpTrackContainerKey
std::map< std::string, std::map< std::string, int > > m_SideTrainGroup
std::map< std::string, int > m_SideGroup
std::vector< std::string > m_chanComb
std::vector< std::string > m_stationNamesToF
std::map< std::string, int > m_StationNamesGroup
virtual ~AFPToFAlgorithm()
SG::ReadCondHandleKey< BunchCrossingCondData > m_bunchCrossingKeyToF
std::map< std::string, std::map< std::string, std::map< std::string, int > > > m_BarsInTrains
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
virtual StatusCode initialize() override
initialize
SG::ReadHandle< xAOD::EventInfo > GetEventInfo(const EventContext &) const
Return a ReadHandle for an EventInfo object (get run/event numbers, etc.)
AthMonitorAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor.
ToolHandleArray< GenericMonitoringTool > m_tools
Array of Generic Monitoring Tools.
bool isFilled(const bcid_type bcid) const
The simplest query: Is the bunch crossing filled or not?
Declare a monitored scalar variable.
Property holding a SG store/key/clid from which a ReadHandle is made.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
StatusCode initialize(bool used=true)
Verify that the handle has been configured properly.
int lb
Definition globals.cxx:23
void fill(const ToolHandle< GenericMonitoringTool > &groupHandle, std::vector< std::reference_wrapper< Monitored::IMonitoredVariable > > &&variables) const
Fills a vector of variables to a group by reference.
virtual float lbAverageInteractionsPerCrossing(const EventContext &ctx=Gaudi::Hive::currentContext()) const
Calculate the average mu, i.e.
Generic monitoring tool for athena components.
std::vector< V > buildToolMap(const ToolHandleArray< GenericMonitoringTool > &tools, const std::string &baseName, int nHist)
Builds an array of indices (base case)
AFPTrack_v2 AFPTrack
Definition AFPTrack.h:12
AFPToFHitContainer_v1 AFPToFHitContainer
AFPTrackContainer_v2 AFPTrackContainer
AFPToFHit_v1 AFPToFHit
Definition AFPToFHit.h:12