ATLAS Offline Software
Loading...
Searching...
No Matches
TgcDigitizationTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
6
9
10// Other includes
12#include "Identifier/Identifier.h"
13
14// TGC includes
19#include "PileUpTools/IPileUpTool.h" // for SubEventIterator
20#include "TgcDigitMaker.h"
22
24 const std::string& name,
25 const IInterface* parent)
26 : PileUpToolBase(type, name, parent) {}
27
28//--------------------------------------------
30 // retrieve MuonDetctorManager from DetectorStore
31 ATH_CHECK(detStore()->retrieve(m_mdManager));
32 ATH_MSG_DEBUG("Retrieved MuonDetectorManager from DetectorStore.");
33
35 ATH_CHECK(m_mergeSvc.retrieve());
36 }
37
38 // initialize the TgcIdHelper
39 m_idHelper = m_mdManager->tgcIdHelper();
40 if (!m_idHelper) {
41 ATH_MSG_WARNING("tgcIdHelper could not be retrieved.");
42 return StatusCode::FAILURE;
43 }
44
45 // TgcHitIdHelper
47
48 // check the input object name
49 if (m_hitsContainerKey.key().empty()) {
50 ATH_MSG_FATAL("Property InputObjectName not set !");
51 return StatusCode::FAILURE;
52 }
55 ATH_MSG_DEBUG("Input objects in container : '" << m_inputHitCollectionName
56 << "'");
57
58 // Initialize Read(Cond)HandleKey
59 ATH_CHECK(m_hitsContainerKey.initialize(true));
65
66 // initialize the output WriteHandleKeys
69 ATH_MSG_DEBUG("Output Digits: '" << m_outputDigitCollectionKey.key()
70 << "'");
71
72 ATH_MSG_DEBUG("IncludePileUpTruth: " << m_includePileUpTruth);
73 ATH_MSG_DEBUG("VetoPileUpTruthLinks: " << m_vetoPileUpTruthLinks);
74
75 // initialize class to execute digitization
78 m_digitizer->setLevel(static_cast<MSG::Level>(msgLevel()));
79 ATH_CHECK(m_rndmSvc.retrieve());
80
81 ATH_CHECK(m_digitizer->initialize());
82
83 return StatusCode::SUCCESS;
84}
85
86//--------------------------------------------
87StatusCode TgcDigitizationTool::prepareEvent(const EventContext& /*ctx*/,
88 unsigned int) {
89 m_TGCHitCollList.clear();
91
92 return StatusCode::SUCCESS;
93}
94
95//--------------------------------------------
97 SubEventIterator bSubEvents,
98 SubEventIterator eSubEvents) {
99 ATH_MSG_DEBUG("TgcDigitizationTool::processBunchXing() " << bunchXing);
100
102 TimedHitCollList;
103 TimedHitCollList hitCollList;
104
105 if (!(m_mergeSvc
106 ->retrieveSubSetEvtData(m_inputHitCollectionName, hitCollList,
107 bunchXing, bSubEvents, eSubEvents)
108 .isSuccess()) &&
109 hitCollList.empty()) {
110 ATH_MSG_ERROR("Could not fill TimedHitCollList");
111 return StatusCode::FAILURE;
112 } else {
113 ATH_MSG_VERBOSE(hitCollList.size()
114 << " TGCSimHitCollection with key "
115 << m_inputHitCollectionName << " found");
116 }
117
118 TimedHitCollList::iterator iColl(hitCollList.begin());
119 TimedHitCollList::iterator endColl(hitCollList.end());
120
121 // Iterating over the list of collections
122 for (; iColl != endColl; ++iColl) {
123
124 TGCSimHitCollection* hitCollPtr =
125 new TGCSimHitCollection(*iColl->second);
126 PileUpTimeEventIndex timeIndex(iColl->first);
127
128 ATH_MSG_DEBUG("TGCSimHitCollection found with " << hitCollPtr->size()
129 << " hits");
130 ATH_MSG_VERBOSE("time index info. time: "
131 << timeIndex.time() << " index: " << timeIndex.index()
132 << " type: " << timeIndex.type());
133
134 m_thpcTGC->insert(timeIndex, hitCollPtr);
135 m_TGCHitCollList.push_back(hitCollPtr);
136 }
137
138 return StatusCode::SUCCESS;
139}
140
141//--------------------------------------------
142StatusCode TgcDigitizationTool::mergeEvent(const EventContext& ctx) {
143 ATH_MSG_DEBUG("TgcDigitizationTool::mergeEvent()");
144
146 // reset the pointer (delete null pointer should be safe)
147 delete m_thpcTGC;
148 m_thpcTGC = nullptr;
149
150 std::list<TGCSimHitCollection*>::iterator TGCHitColl =
151 m_TGCHitCollList.begin();
152 std::list<TGCSimHitCollection*>::iterator TGCHitCollEnd =
153 m_TGCHitCollList.end();
154 while (TGCHitColl != TGCHitCollEnd) {
155 delete (*TGCHitColl);
156 ++TGCHitColl;
157 }
158 m_TGCHitCollList.clear();
159
160 return StatusCode::SUCCESS;
161}
162
163//_____________________________________________________________________________
164StatusCode TgcDigitizationTool::processAllSubEvents(const EventContext& ctx) {
165 ATH_MSG_DEBUG("TgcDigitizationTool::processAllSubEvents()");
166 // merging of the hit collection in getNextEvent method
167 if (!m_thpcTGC) {
169 }
171 // reset the pointer (delete null pointer should be safe)
172 delete m_thpcTGC;
173 m_thpcTGC = nullptr;
174 return StatusCode::SUCCESS;
175}
176
177//_____________________________________________________________________________
179 ATH_MSG_DEBUG("finalize.");
180
181 delete m_digitizer;
182 m_digitizer = nullptr;
183
184 return StatusCode::SUCCESS;
185}
186
187//_____________________________________________________________________________
188// Get next event and extract collection of hit collections:
189StatusCode TgcDigitizationTool::getNextEvent(const EventContext& ctx) {
190 // initialize pointer
191 m_thpcTGC = nullptr;
192
193 // get the container(s)
194 using TimedHitCollList =
196
197 // In case of single hits container just load the collection using read
198 // handles
201 ctx);
202 if (!hitCollection.isValid()) {
203 ATH_MSG_ERROR("Could not get TGCSimHitCollection container "
204 << hitCollection.name() << " from store "
205 << hitCollection.store());
206 return StatusCode::FAILURE;
207 }
208
209 // create a new hits collection
211 m_thpcTGC->insert(0, hitCollection.cptr());
212 ATH_MSG_DEBUG("TGCSimHitCollection found with " << hitCollection->size()
213 << " hits");
214
215 return StatusCode::SUCCESS;
216 }
217
218 // this is a list<pair<time_t, DataLink<TGCSimHitCollection> > >
219 TimedHitCollList hitCollList;
220
221 if (!(m_mergeSvc->retrieveSubEvtsData(m_inputHitCollectionName, hitCollList)
222 .isSuccess())) {
223 ATH_MSG_FATAL("Could not fill TimedHitCollList");
224 return StatusCode::FAILURE;
225 }
226 if (hitCollList.empty()) {
227 ATH_MSG_FATAL("TimedHitCollList has size 0");
228 return StatusCode::FAILURE;
229 } else {
230 ATH_MSG_DEBUG(hitCollList.size()
231 << " TGCSimHitCollections with key "
232 << m_inputHitCollectionName << " found");
233 }
234
235 // create a new hits collection
237
238 // now merge all collections into one
239 TimedHitCollList::iterator iColl = hitCollList.begin();
240 TimedHitCollList::iterator endColl = hitCollList.end();
241 while (iColl != endColl) {
242 const TGCSimHitCollection* p_collection = iColl->second;
243 m_thpcTGC->insert(iColl->first, p_collection);
244 ATH_MSG_DEBUG("TGCSimHitCollection found with "
245 << p_collection->size()
246 << " hits"); // loop on the hit collections
247 ++iColl;
248 }
249 return StatusCode::SUCCESS;
250}
251
252StatusCode TgcDigitizationTool::digitizeCore(const EventContext& ctx) {
253
254 ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this);
255 rngWrapper->setSeed(name(), ctx);
256 CLHEP::HepRandomEngine* rndmEngine = rngWrapper->getEngine(ctx);
257
258 // create and record the Digit container in StoreGate
261 ATH_CHECK(digitContainer.record(
262 std::make_unique<TgcDigitContainer>(m_idHelper->module_hash_max())));
263 ATH_MSG_DEBUG("TgcDigitContainer recorded in StoreGate.");
264
265 // Create and record the SDO container in StoreGate
268 ATH_CHECK(sdoContainer.record(std::make_unique<MuonSimDataCollection>()));
269 ATH_MSG_DEBUG("TgcSDOCollection recorded in StoreGate.");
270
271 // get the iterator pairs for this DetEl
272 // iterate over hits and fill id-keyed drift time map
273 IdContext tgcContext = m_idHelper->module_context();
274
275 // Read needed conditions data
276 const TgcDigitASDposData* ASDpos{};
277 if (!m_readCondKey_ASDpos.empty()) {
280 ASDpos = readHandle_ASDpos.cptr();
281 } else {
283 "ASD Position parameters /TGC/DIGIT/ASDPOS must be available for "
284 "TGC_Digitization. Check the configuration!");
285 }
286 const TgcDigitTimeOffsetData* TOffset{};
287 if (!m_readCondKey_TimeOffset.empty()) {
288 SG::ReadCondHandle<TgcDigitTimeOffsetData> readHandle_TimeOffset{
290 TOffset = readHandle_TimeOffset.cptr();
291 } else {
293 "Timing Offset parameters /TGC/DIGIT/TOFFSET must be available for "
294 "TGC_Digitization. Check the configuration!");
295 }
296 const TgcDigitCrosstalkData* Crosstalk{};
297 if (!m_readCondKey_Crosstalk.empty()) {
300 Crosstalk = readHandle_Crosstalk.cptr();
301 } else {
303 "/TGC/DIGIT/XTALK is not provided. Probabilities of TGC channel "
304 "crosstalk will be zero.");
305 }
306
307 std::vector<std::unique_ptr<TgcDigitCollection> > collections;
308
310 while (m_thpcTGC->nextDetectorElement(i, e)) {
311 ATH_MSG_DEBUG("TgcDigitizationTool::digitizeCore next element");
312
313 // Loop over the hits:
314 while (i != e) {
315 TimedHitPtr<TGCSimHit> phit = *i++;
316 const TGCSimHit& hit = *phit;
317 double globalHitTime = hitTime(phit);
318 double tof = phit->globalTime();
319 TgcDigitCollection* digiHits = m_digitizer->executeDigi(
320 &hit, globalHitTime, ASDpos, TOffset, Crosstalk, rndmEngine);
321
322 if (!digiHits)
323 continue;
324
326 for (it_digiHits = digiHits->begin();
327 it_digiHits != digiHits->end(); ++it_digiHits) {
328
336
337 Identifier newDigiId = (*it_digiHits)->identify();
338 uint16_t newBcTag = (*it_digiHits)->bcTag();
339 Identifier elemId = m_idHelper->elementID(newDigiId);
340
341 TgcDigitCollection* digitCollection = nullptr;
342
343 IdentifierHash coll_hash;
344 if (m_idHelper->get_hash(elemId, coll_hash, &tgcContext)) {
346 "Unable to get TGC hash id from TGC Digit collection "
347 << "context begin_index = " << tgcContext.begin_index()
348 << " context end_index = " << tgcContext.end_index()
349 << " the identifier is ");
350 elemId.show();
351 }
352
353 // make new TgcDigit and record it in StoreGate
354 auto newDigit = std::make_unique<TgcDigit>(newDigiId, newBcTag);
355
356 // record the digit container in StoreGate
357 bool duplicate = false;
358 if (coll_hash >= collections.size()) {
359 collections.resize(coll_hash + 1);
360 }
361 digitCollection = collections[coll_hash].get();
362 if (nullptr == digitCollection) {
363 collections[coll_hash] =
364 std::make_unique<TgcDigitCollection>(elemId, coll_hash);
365 digitCollection = collections[coll_hash].get();
366 ATH_MSG_DEBUG("Digit Id(1st) = "
367 << m_idHelper->show_to_string(newDigiId)
368 << " BC tag = " << newBcTag
369 << " Coll. key = " << coll_hash);
370 digitCollection->push_back(std::move(newDigit));
371 } else {
372 // to avoid to store digits with identical id
374 for (it_tgcDigit = digitCollection->begin();
375 it_tgcDigit != digitCollection->end(); ++it_tgcDigit) {
376 if (newDigiId == (*it_tgcDigit)->identify() &&
377 newBcTag == (*it_tgcDigit)->bcTag()) {
378 duplicate = true;
379 IdContext context = m_idHelper->channel_context();
380 ATH_MSG_DEBUG("Duplicate digit(removed) = "
381 << m_idHelper->show_to_string(
382 newDigiId, &context)
383 << " BC tag = " << newBcTag);
384 newDigit.reset();
385 break;
386 }
387 }
388 if (!duplicate) {
389 digitCollection->push_back(std::move(newDigit));
390 ATH_MSG_DEBUG("Digit Id= "
391 << m_idHelper->show_to_string(newDigiId)
392 << " BC tag = " << newBcTag);
393 }
394 }
395
396 if (!duplicate) {
397 static const double invalid_pos = -99999.;
398 Amg::Vector3D gpos(invalid_pos, invalid_pos, invalid_pos);
399 const MuonGM::TgcReadoutElement* tgcChamber =
400 m_mdManager->getTgcReadoutElement(newDigiId);
401 if (tgcChamber) {
402 gpos = tgcChamber->localToGlobalTransf(newDigiId) * hit.localPosition();
403 }
404
405 // fill the SDO collection in StoreGate if not pile-up
407 HepMC::ignoreTruthLink(phit->particleLink(),
409 continue;
410 }
411
412 // link to MC info
413 // create here deposit for MuonSimData, link and tof
414 std::vector<MuonSimData::Deposit> deposits;
415 deposits.emplace_back(
416 HepMcParticleLink::getRedirectedLink(phit->particleLink(), phit.eventId(), ctx), // This link should now correctly resolve to the TruthEvent McEventCollection in the main StoreGateSvc.
417 MuonMCData(tof, 0));
418 MuonSimData simData(deposits, 0);
419 simData.setPosition(gpos);
420 simData.setTime(hitTime(phit));
421 sdoContainer->insert(std::make_pair(newDigiId, simData));
422 }
423 }
424 delete digiHits;
425 digiHits = nullptr;
426 } // while(i != e)
427 } // while(m_thpcTGC->nextDetectorElement(i, e))
428
429 for (size_t coll_hash = 0; coll_hash < collections.size(); ++coll_hash) {
430 if (collections[coll_hash]) {
431 ATH_CHECK(digitContainer->addCollection(
432 collections[coll_hash].release(), coll_hash));
433 }
434 }
435
436 return StatusCode::SUCCESS;
437}
float hitTime(const AFP_SIDSimHit &hit)
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(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.
a call-back interface for tools that merge pileup events information An IPileUpTool is called back fo...
std::vector< xAOD::EventInfo::SubEvent >::const_iterator SubEventIterator
Definition IPileUpTool.h:22
AtlasHitsVector< TGCSimHit > TGCSimHitCollection
implementation of IPileUpTool to produce TgcDigit objects from TGCSimHit
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
size_type size() const
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
const T * get(size_type n) const
Access an element, as an rvalue.
value_type push_back(value_type pElem)
Add an element to the end of the collection.
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
This class saves the "context" of an expanded identifier (ExpandedIdentifier) for compact or hash ver...
Definition IdContext.h:26
size_type begin_index() const
Definition IdContext.h:45
size_type end_index() const
Definition IdContext.h:46
This is a "hash" representation of an Identifier.
void show() const
Print out in hex form.
A TgcReadoutElement corresponds to a single TGC chamber; therefore typically a TGC station contains s...
const Amg::Transform3D & localToGlobalTransf(const Identifier &id) const
Returns the local -> global transformation x-axis: Parallel to the wires (strips) if the Identifier b...
Gaudi::Property< int > m_vetoPileUpTruthLinks
PileUpToolBase(const std::string &type, const std::string &name, const IInterface *parent)
const_pointer_type cptr()
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
std::string store() const
Return the name of the store holding the object we are proxying.
const std::string & name() const
Return the StoreGate ID for the referenced object.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
const Amg::Vector3D & localPosition() const
Definition TGCSimHit.h:43
virtual StatusCode mergeEvent(const EventContext &ctx) override final
called at the end of the subevts loop.
StatusCode digitizeCore(const EventContext &ctx)
Core part of digitization used by processAllSubEvents and mergeEvent.
TgcDigitizationTool(const std::string &type, const std::string &name, const IInterface *parent)
TgcDigitMaker * m_digitizer
ServiceHandle< PileUpMergeSvc > m_mergeSvc
virtual StatusCode processBunchXing(int bunchXing, SubEventIterator bSubEvents, SubEventIterator eSubEvents) override final
called for each active bunch-crossing to process current SubEvents bunchXing is in ns
const MuonGM::MuonDetectorManager * m_mdManager
SG::ReadCondHandleKey< TgcDigitCrosstalkData > m_readCondKey_Crosstalk
SG::ReadCondHandleKey< TgcDigitASDposData > m_readCondKey_ASDpos
const TgcHitIdHelper * m_hitIdHelper
TimedHitCollection< TGCSimHit > * m_thpcTGC
SG::WriteHandleKey< TgcDigitContainer > m_outputDigitCollectionKey
const TgcIdHelper * m_idHelper
SG::WriteHandleKey< MuonSimDataCollection > m_outputSDO_CollectionKey
virtual StatusCode processAllSubEvents(const EventContext &ctx) override final
alternative interface which uses the PileUpMergeSvc to obtain all the required SubEvents.
Gaudi::Property< bool > m_doFourBunchDigitization
Gaudi::Property< bool > m_onlyUseContainerName
std::list< TGCSimHitCollection * > m_TGCHitCollList
SG::ReadHandleKey< TGCSimHitCollection > m_hitsContainerKey
std::string m_inputHitCollectionName
virtual StatusCode finalize() override final
Finalize.
SG::ReadCondHandleKey< TgcDigitTimeOffsetData > m_readCondKey_TimeOffset
virtual StatusCode prepareEvent(const EventContext &ctx, unsigned int) override final
ServiceHandle< IAthRNGSvc > m_rndmSvc
Gaudi::Property< bool > m_includePileUpTruth
StatusCode getNextEvent(const EventContext &ctx)
Get next event and extract collection of hit collections.
virtual StatusCode initialize() override final
Initialize.
static const TgcHitIdHelper * GetHelper()
TimedVector::const_iterator const_iterator
a smart pointer to a hit that also provides access to the extended timing info of the host event.
Definition TimedHitPtr.h:18
unsigned short eventId() const
the index of the component event in PileUpEventInfo.
Definition TimedHitPtr.h:47
constexpr bool simData
Definition constants.h:36
Eigen::Matrix< double, 3, 1 > Vector3D
bool ignoreTruthLink(const T &p, bool vetoPileUp)
Helper function for SDO creation in PileUpTools.
std::list< value_t > type
type of the collection of timed data object
a struct encapsulating the identifier of a pile-up event
index_type index() const
the index of the component event in PileUpEventInfo
PileUpType type() const
the pileup type - minbias, cavern, beam halo, signal?
time_type time() const
bunch xing time in ns