ATLAS Offline Software
Loading...
Searching...
No Matches
MdtRdoToPrepDataToolMT.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7#include <algorithm>
8#include <vector>
9
10#include "GaudiKernel/PhysicalConstants.h"
12#include "MdtRDO_Decoder.h"
18
19
20using namespace MuonGM;
21using namespace Trk;
22
24
25
26namespace {
27 // the tube number of a tube in a tubeLayer is encoded in the GeoSerialIdentifier (modulo maxNTubesPerLayer)
28 constexpr unsigned int maxNTubesPerLayer = MdtIdHelper::maxNTubesPerLayer;
29
30 inline void updateClosestApproachTwin(MdtCalibInput & in) {
31 const MuonGM::MdtReadoutElement* descriptor = in.legacyDescriptor();
32 if (descriptor) {
33 if (std::abs(descriptor->getStationS()) < std::numeric_limits<double>::epsilon()) {
34 return;
35 }
36 const Amg::Vector3D nominalTubePos = descriptor->tubePos(in.identify());
37 double measuredPerp = std::sqrt(nominalTubePos.perp2() - descriptor->getStationS()* descriptor->getStationS());
38 CxxUtils::sincos tubeSC{nominalTubePos.phi()};
39 Amg::Vector3D measurePos{tubeSC.cs * measuredPerp, tubeSC.sn *measuredPerp, nominalTubePos.z()};
40 in.setClosestApproach(measurePos);
41 }
42 }
43 inline std::string print(const Muon::MdtPrepData& prd) {
44 const auto* idHelperSvc = prd.detectorElement()->idHelperSvc();
45 std::stringstream sstr{};
46 sstr<<" PrepData "<<idHelperSvc->toString(prd.identify())
47 <<" radius: "<<prd.localPosition()[Trk::locR]<<" pm "
48 <<std::sqrt(prd.localCovariance()(Trk::locR, Trk::locR))<<
49 ", tdc: "<<prd.tdc()<<", adc: "<<prd.adc()<<", status: "<<prd.status();
50 return sstr.str();
51 }
52} // namespace
53
54namespace Muon {
55
56
58 m_idHelperSvc{idHelperSvc} {
59 addedCols.resize(m_idHelperSvc->mdtIdHelper().module_hash_max());
60 }
61
63
64 IdentifierHash mdtHashId = m_idHelperSvc->moduleHash(elementId);
65
66 std::unique_ptr<MdtPrepDataCollection>& coll {addedCols[mdtHashId]};
67 if (!coll) {
68 coll = std::make_unique<MdtPrepDataCollection>(mdtHashId);
69 coll->setIdentifier(m_idHelperSvc->chamberId(elementId));
70 }
71 return coll.get();
72 }
74 for (unsigned int moduleHash =0; moduleHash < addedCols.size(); ++moduleHash) {
75 std::unique_ptr<MdtPrepDataCollection>& toInsert{addedCols[moduleHash]};
76 if (!toInsert || toInsert->empty()) continue;
77 MdtPrepDataContainer::IDC_WriteHandle lock = legacyPrd->getWriteHandle(moduleHash);
78 if (lock.addOrDelete(std::move(toInsert)).isFailure()) {
79 msg << MSG::ERROR << " Failed to add prep data collection " << moduleHash << endmsg;
80 return StatusCode::FAILURE;
81 }
82 }
83 return StatusCode::SUCCESS;
84 }
85
87 ATH_CHECK(m_calibrationTool.retrieve());
88 ATH_MSG_VERBOSE("MdtCalibrationTool retrieved with pointer = " << m_calibrationTool);
90 ATH_CHECK(m_idHelperSvc.retrieve());
91 // Retrieve the RDO decoder
92 ATH_CHECK(m_mdtDecoder.retrieve());
93
95
96 m_BMGid = m_idHelperSvc->mdtIdHelper().stationNameIndex("BMG");
97 m_BMGpresent = m_BMGid != -1;
98 if (m_BMGpresent) {
99 const MuonGM::MuonDetectorManager* muDetMgr = nullptr;
100 ATH_CHECK(detStore()->retrieve(muDetMgr));
101
102 ATH_MSG_INFO("Processing configuration for layouts with BMG chambers.");
103
104 for (int phi = 6; phi < 8; phi++) { // phi sectors
105 for (int eta = 1; eta < 4; eta++) { // eta sectors
106 for (int side = -1; side < 2; side += 2) { // side
107 if (!muDetMgr->getMuonStation("BMG", side * eta, phi)) continue;
108 for (int roe = 1; roe <= (muDetMgr->getMuonStation("BMG", side * eta, phi))->nMuonReadoutElements();
109 roe++) { // iterate on readout elemets
110 const MdtReadoutElement* mdtRE = dynamic_cast<const MdtReadoutElement*>(
111 (muDetMgr->getMuonStation("BMG", side * eta, phi))->getMuonReadoutElement(roe)); // has to be an MDT
112 if (mdtRE) initDeadChannels(mdtRE);
113 }
114 }
115 }
116 }
117 }
118 // initialize handle keys
119 ATH_CHECK(m_rdoContainerKey.initialize());
121 ATH_CHECK(m_readKey.initialize());
122 ATH_CHECK(m_muDetMgrKey.initialize());
123 return StatusCode::SUCCESS;
124 }
125
126 StatusCode MdtRdoToPrepDataToolMT::decode(const EventContext& ctx, const std::vector<uint32_t>& robIds) const {
127 const MuonMDT_CablingMap* readCdo{nullptr};
128 ATH_CHECK(SG::get(readCdo, m_readKey, ctx));
129 return decode(ctx, readCdo->getMultiLayerHashVec(robIds, msgStream()));
130 }
131
132 const MdtCsmContainer* MdtRdoToPrepDataToolMT::getRdoContainer(const EventContext& ctx) const {
133 SG::ReadHandle rdoContainerHandle{m_rdoContainerKey, ctx};
134 if (rdoContainerHandle.isValid()) {
135 ATH_MSG_DEBUG("MdtgetRdoContainer success");
136 return rdoContainerHandle.cptr();
137 }
138 ATH_MSG_WARNING("Retrieval of Mdt RDO container failed !");
139 return nullptr;
140 }
141
142 StatusCode MdtRdoToPrepDataToolMT::provideEmptyContainer(const EventContext& ctx) const{
143 return setupMdtPrepDataContainer(ctx).isValid ? StatusCode::SUCCESS : StatusCode::FAILURE;
144 }
145
146 void MdtRdoToPrepDataToolMT::processPRDHashes(const EventContext& ctx, ConvCache& mdtPrepDataContainer,
147 const std::vector<IdentifierHash>& multiLayerHashInRobs) const {
148 for (const IdentifierHash& hash : multiLayerHashInRobs) {
149 if (!handlePRDHash(ctx, mdtPrepDataContainer, hash)) { ATH_MSG_DEBUG("Failed to process hash " << hash); }
150 } // ends loop over chamberhash
151 }
152
153 bool MdtRdoToPrepDataToolMT::handlePRDHash(const EventContext& ctx,
154 ConvCache& mdtPrepDataContainer,
155 IdentifierHash rdoHash) const {
156 const MdtCsmContainer* rdoContainer{getRdoContainer(ctx)};
157
158 if (rdoContainer->empty()) {
159 ATH_MSG_DEBUG("The container is empty");
160 return true;
161 }
162 const MdtCsm* rdoColl = rdoContainer->indexFindPtr(rdoHash);
163 if (!rdoColl) {
164 ATH_MSG_DEBUG("The rdo container does not have the hash " << rdoHash);
165 return true;
166 }
167 if (processCsm(ctx, mdtPrepDataContainer, rdoColl).isFailure()) {
168 ATH_MSG_WARNING("processCsm failed for RDO id " << m_idHelperSvc->toString(rdoColl->identify()));
169 return false;
170 }
171 return true;
172 }
173
174 StatusCode MdtRdoToPrepDataToolMT::decode(const EventContext& ctx,
175 const std::vector<IdentifierHash>& idVect) const {
176
177 ATH_MSG_DEBUG("decodeMdtRDO for " << idVect.size() << " offline collections called");
178
179 // setup output container
180 ConvCache mdtPrepDataContainer = setupMdtPrepDataContainer(ctx);
181 if (!mdtPrepDataContainer.isValid) {
182 return StatusCode::FAILURE;
183 }
184
185
186 if (!m_decodeData) {
187 ATH_MSG_DEBUG("Stored empty container. Decoding MDT RDO into MDT PrepRawData is switched off");
188 return StatusCode::SUCCESS;
189 }
190 // seeded or unseeded decoding
191 if (!idVect.empty()) {
192 processPRDHashes(ctx, mdtPrepDataContainer, idVect);
193 } else {
195 std::vector<IdentifierHash> rdoHashes{};
196 const MdtCsmContainer* rdoContainer = getRdoContainer(ctx);
197 if (!rdoContainer || rdoContainer->empty()) return StatusCode::SUCCESS;
198 rdoHashes.reserve(rdoContainer->size());
199 for (const MdtCsm* csm : *rdoContainer) rdoHashes.push_back(csm->identifyHash());
200
201 processPRDHashes(ctx, mdtPrepDataContainer, rdoHashes);
202 }
203 ATH_CHECK(mdtPrepDataContainer.finalize(msgStream()));
204
205 return StatusCode::SUCCESS;
206 }
207
208 std::unique_ptr<MdtPrepData> MdtRdoToPrepDataToolMT::createPrepData(const MdtCalibInput& calibInput,
209 const MdtCalibOutput& calibOutput) const {
210 if (calibInput.adc() < m_adcCut ||
211 calibOutput.status() == MdtDriftCircleStatus::MdtStatusUnDefined) {
212 ATH_MSG_VERBOSE("Do not create calib hit for "<<m_idHelperSvc->toString(calibInput.identify())
213 <<", adc: "<<calibInput.adc()<<" vs. "<<m_adcCut<<", calibration bailed out "
214 <<(calibOutput.status() == MdtDriftCircleStatus::MdtStatusUnDefined? "si": "no"));
215 return nullptr;
216 }
217 const MuonGM::MdtReadoutElement* descriptor = calibInput.legacyDescriptor();
218 ATH_MSG_VERBOSE("Calibrated prepdata "<<m_idHelperSvc->toString(calibInput.identify())
219 <<std::endl<<calibInput<<std::endl<<calibOutput);
220
221 Amg::Vector2D driftRadius{Amg::Vector2D::Zero()};
222 Amg::MatrixX cov(1, 1);
223 if (calibOutput.status() == MdtDriftCircleStatus::MdtStatusDriftTime){
225 const float r = calibOutput.driftRadius();
226 const float sigR = calibOutput.driftRadiusUncert();
227 driftRadius[0] = r;
228 (cov)(0, 0) = sigR * sigR;
229 } else (cov)(0, 0) = std::pow(descriptor->innerTubeRadius(), 2);
230
231 return std::make_unique<MdtPrepData>(calibInput.identify(),
232 std::move(driftRadius),
233 std::move(cov),
234 descriptor,
235 calibInput.tdc(),
236 calibInput.adc(),
237 calibOutput.status());
238 }
239
240 StatusCode MdtRdoToPrepDataToolMT::processCsm(const EventContext& ctx, ConvCache& cache, const MdtCsm* rdoColl) const {
241 const MdtIdHelper& id_helper = m_idHelperSvc->mdtIdHelper();
242 // first handle the case of twin tubes
243 if (m_useTwin) {
244 if (cache.twinTubeMap->isTwinTubeLayer(rdoColl->identify())) {
245 return processCsmTwin(ctx, cache, rdoColl);
246 }
247 }
248
249 ATH_MSG_DEBUG(" ***************** Start of processCsm");
250
252 const Identifier elementId = id_helper.parentID(rdoColl->identify());
253
254 uint16_t subdetId = rdoColl->SubDetId();
255 uint16_t mrodId = rdoColl->MrodId();
256 uint16_t csmId = rdoColl->CsmId();
257 ATH_MSG_VERBOSE("Identifier = " << m_idHelperSvc->toString(elementId) << " subdetId/ mrodId/ csmId = " << subdetId << " / "
258 << mrodId << " / " << csmId);
259
260 // for each Csm, loop over AmtHit, converter AmtHit to digit
261 // retrieve/create digit collection, and insert digit into collection
262 unsigned mc{0};
263
264 for (const MdtAmtHit* amtHit : *rdoColl) {
265 ++mc;
266
267 // FIXME: Still use the digit class.
268 ATH_MSG_VERBOSE("Amt Hit n. " << mc << " tdcId = " << amtHit->tdcId());
269 std::unique_ptr<MdtDigit> newDigit{m_mdtDecoder->getDigit(ctx, *amtHit, subdetId, mrodId, csmId)};
270 if (!newDigit) {
271 ATH_MSG_WARNING("Found issue MDT RDO decoder for subdetId/mrodId/csmId "
272 << subdetId << "/" << mrodId << "/" << csmId << " amtHit channelId/tdcId =" << amtHit->channelId() << "/"
273 << amtHit->tdcId());
274 continue;
275 }
276 // Do something with it
277 Identifier channelId = newDigit->identify();
278 if (newDigit->isMasked() || m_DeadChannels.count(channelId)) {
279 continue;
280 }
281 // Retrieve the proper PRD container. Note that there are cases where one CSM is either split into 2 chambers (BEE / BIS78
282 // legacy) or 2 CSMs are split into one chamber
283 MdtPrepDataCollection* driftCircleColl = cache.createCollection(channelId);
284 if (!driftCircleColl) {
285 ATH_MSG_DEBUG("Corresponding multi layer " << m_idHelperSvc->toString(channelId) << " is already decoded.");
286 continue;
287 }
288
289 // check if the module ID of this channel is different from the CSM one
290 // If it's the first case, create the additional collection
291
292 ATH_MSG_VERBOSE("got digit with id ext / hash " << m_idHelperSvc->toString(channelId) << " / "
293 << driftCircleColl->identifyHash());
294
295 // Rescale ADC/TDC of chambers using HPTDC digitization chip
296 // Must create a new digit from the old one, because MdtDigit has no methods to set ADC/TDC
297 if (m_idHelperSvc->hasHPTDC(channelId)) {
298 newDigit->setAdc(newDigit->adc() / 4);
299 newDigit->setTdc(newDigit->tdc() / 4);
300 }
301
302 const MdtCalibInput calibIn{*newDigit, *cache.legacyDetMgr};
303 const MdtCalibOutput calibResult{m_calibrationTool->calibrate(ctx, calibIn, false)};
304
305 std::unique_ptr<MdtPrepData> newPrepData = createPrepData(calibIn, calibResult);
306 if (!newPrepData) {
307 continue;
308 }
309 if (driftCircleColl->size()) {
310 MdtPrepData* prevPrd = driftCircleColl->at(driftCircleColl->size()-1);
311 if (prevPrd->identify() == channelId) {
312 std::stringstream sstr{};
313 ATH_MSG_VERBOSE("Duplicated prep data object detected: "<<std::endl
314 <<" **** "<<print(*prevPrd)<<std::endl
315 <<" **** "<<print(*newPrepData));
316 if (prevPrd->status() == MdtDriftCircleStatus::MdtStatusDriftTime) {
317 ATH_MSG_VERBOSE("Prd is already good");
318 } else if (newPrepData->status() == MdtDriftCircleStatus::MdtStatusDriftTime) {
319 (*prevPrd) = std::move(*newPrepData);
320 prevPrd->setHashAndIndex(driftCircleColl->identifyHash(), driftCircleColl->size()-1);
321 }
322 continue;
323 }
324 }
325 ATH_MSG_VERBOSE("New prd created "<<print(*newPrepData));
326 newPrepData->setHashAndIndex(driftCircleColl->identifyHash(), driftCircleColl->size());
327 driftCircleColl->push_back(std::move(newPrepData));
328 }
329 return StatusCode::SUCCESS;
330 }
331 StatusCode MdtRdoToPrepDataToolMT::processCsmTwin(const EventContext& ctx, ConvCache& cache, const MdtCsm* rdoColl) const {
332 const MdtIdHelper& id_helper = m_idHelperSvc->mdtIdHelper();
333 ATH_MSG_DEBUG(" ***************** Start of processCsmTwin");
334 ATH_MSG_DEBUG(" Number of AmtHit in this Csm " << rdoColl->size());
336 Identifier elementId = id_helper.parentID(rdoColl->identify());
337
338 uint16_t subdetId = rdoColl->SubDetId();
339 uint16_t mrodId = rdoColl->MrodId();
340 uint16_t csmId = rdoColl->CsmId();
341 ATH_MSG_VERBOSE("Identifier = " << m_idHelperSvc->toString(elementId) << " subdetId/ mrodId/ csmId = " << rdoColl->SubDetId()
342 << " / " << rdoColl->MrodId() << " / " << rdoColl->CsmId());
343
344 // for each Csm, loop over AmtHit, converter AmtHit to digit
345 // retrieve/create digit collection, and insert digit into collection
346 std::map<Identifier, std::array<std::unique_ptr<MdtDigit>, 2>> mdtDigitColl{};
347
348 for (const MdtAmtHit* amtHit : *rdoColl) {
349 std::unique_ptr<MdtDigit> newDigit{m_mdtDecoder->getDigit(ctx, *amtHit, subdetId, mrodId, csmId)};
350
351 if (!newDigit) {
352 ATH_MSG_WARNING("Error in MDT RDO decoder for subdetId/mrodId/csmId "
353 << subdetId << "/" << mrodId << "/" << csmId << " amtHit channelId/tdcId =" << amtHit->channelId() << "/"
354 << amtHit->tdcId());
355 continue;
356 }
357 std::array<std::unique_ptr<MdtDigit>, 2> & moveTo = mdtDigitColl[newDigit->identify()];
358 if (!moveTo[0]) {
359 moveTo[0] = std::move(newDigit);
360 } else if (!moveTo[1] && !m_discardSecondaryHitTwin) {
361 moveTo[1] = std::move(newDigit);
362 } else {
363 ATH_MSG_VERBOSE(" TWIN TUBES: found a tertiary hit in a twin tube in one RdoCollection for "
364 << m_idHelperSvc->toString(newDigit->identify()) << " with adc = " << newDigit->adc()
365 << " tdc = " << newDigit->tdc());
366 }
367 } // end for-loop over rdoColl
368
369 auto convertTwins = [this, &cache, &ctx](std::unique_ptr<MdtDigit> digit,
370 std::unique_ptr<MdtDigit> digit2) {
371 if (!digit || digit->isMasked()) { return; }
372
373 MdtPrepDataCollection* driftCircleColl = cache.createCollection(digit->identify());
374
375 if (!digit2 || digit2->isMasked()) {
376 ATH_MSG_VERBOSE("Got single digit " << m_idHelperSvc->toString(digit->identify())<<", tdc: "
377 <<digit->tdc()<<", adc: "<<digit->adc()
378 << ", hash: "<< driftCircleColl->identifyHash());
379
380 const MdtCalibInput mdtCalibIn{*digit, *cache.legacyDetMgr};
381 const MdtCalibOutput mdtCalibOut{m_calibrationTool->calibrate(ctx, mdtCalibIn, false)};
382
384 std::unique_ptr<MdtPrepData> newPrepData = createPrepData(mdtCalibIn, mdtCalibOut);
385 if (!newPrepData) return;
386
387 newPrepData->setHashAndIndex(driftCircleColl->identifyHash(), driftCircleColl->size());
388 driftCircleColl->push_back(std::move(newPrepData));
389 return;
390 }
391 ATH_MSG_VERBOSE("Twin digit calibration "<<m_idHelperSvc->toString(digit->identify())
392 <<", tdc: "<<digit->tdc()<<", adc: "<<digit->adc()<<" -- "
393 <<m_idHelperSvc->toString(digit2->identify())
394 <<", tdc: "<<digit2->tdc()<<", adc: "<<digit2->adc());
395
396 MdtCalibInput mdtCalib1st{*digit, *cache.legacyDetMgr};
397 MdtCalibInput mdtCalib2nd{*digit2, *cache.legacyDetMgr};
398
399 updateClosestApproachTwin(mdtCalib1st);
400 updateClosestApproachTwin(mdtCalib2nd);
401
402 const MdtCalibTwinOutput twinCalib = m_calibrationTool->calibrateTwinTubes(ctx,
403 std::move(mdtCalib1st),
404 std::move(mdtCalib2nd));
405
406 Amg::Vector2D hitPos{twinCalib.primaryDriftR(), twinCalib.locZ()};
407 Amg::MatrixX cov(2, 2);
408 cov(0, 0) = twinCalib.uncertPrimaryR() * twinCalib.uncertPrimaryR();
409 cov(1, 1) = twinCalib.sigmaZ() * twinCalib.sigmaZ();
410 cov(0, 1) = cov(1, 0) = 0;
411
412 const MuonGM::MdtReadoutElement* descriptor = cache.legacyDetMgr->getMdtReadoutElement(digit->identify());
413 auto twin_newPrepData = std::make_unique<MdtTwinPrepData>(twinCalib.primaryID(),
414 std::move(hitPos),
415 std::move(cov),
416 descriptor,
417 twinCalib.primaryTdc(),
418 twinCalib.primaryAdc(),
419 twinCalib.twinTdc(),
420 twinCalib.twinAdc(),
421 twinCalib.primaryStatus());
422
423 ATH_MSG_VERBOSE(" MADE A 2D TWINPREPDATA " << m_idHelperSvc->toString(twinCalib.primaryID()) << " & "
424 << m_idHelperSvc->toString(twinCalib.twinID()) << " "<<twinCalib);
425
426 ATH_MSG_VERBOSE("global pos center tube " << Amg::toString(twin_newPrepData->globalPosition(), 2) << std::endl
427 <<"local pos center tube w/ TWIN INFO "<<Amg::toString(twinCalib.locZ() * Amg::Vector3D::UnitZ(), 2)<<std::endl
428 <<"global pos w/o TWIN INFO "<<Amg::toString(descriptor->tubePos(twinCalib.primaryID())));
429
430 twin_newPrepData->setHashAndIndex(driftCircleColl->identifyHash(), driftCircleColl->size());
431 driftCircleColl->push_back(std::move(twin_newPrepData));
432 };
433
434 // iterate over mdtDigitColl
435 for (auto &[id, digits] : mdtDigitColl) {
436 // get the twin hits from mdtDigitColl
437 const Identifier twinId = cache.twinTubeMap->twinId(id);
439 if (id != twinId) {
440 std::array<std::unique_ptr<MdtDigit>, 2>& twinDigits = mdtDigitColl[twinId];
441 ATH_MSG_VERBOSE("Convert digits: "<<digits[0].get()<<" "<<twinDigits[0].get());
442 convertTwins(std::move(digits[0]), std::move(twinDigits[0]));
443 ATH_MSG_VERBOSE("Convert digits: "<<digits[1].get()<<" "<<twinDigits[1].get());
444 convertTwins(std::move(digits[1]), std::move(twinDigits[1]));
445 } else {
446 convertTwins(std::move(digits[0]), nullptr);
447 convertTwins(std::move(digits[1]), nullptr);
448 }
449 }
450 return StatusCode::SUCCESS;
451 }
453 PVConstLink cv = mydetEl->getMaterialGeom(); // it is "Multilayer"
454 int nGrandchildren = cv->getNChildVols();
455 if (nGrandchildren <= 0) return;
456
457 std::vector<int> tubes;
458 geoGetIds([&](int id) { tubes.push_back(id); }, &*cv);
459 std::sort(tubes.begin(), tubes.end());
460
461 const Identifier detElId = mydetEl->identify();
462 const int ml = mydetEl->getMultilayer();
463 std::vector<int>::iterator it = tubes.begin();
464 for (int layer = 1; layer <= mydetEl->getNLayers(); layer++) {
465 for (int tube = 1; tube <= mydetEl->getNtubesperlayer(); tube++) {
466 int want_id = layer * maxNTubesPerLayer + tube;
467 if (it != tubes.end() && *it == want_id) {
468 ++it;
469 } else {
470 it = std::lower_bound(tubes.begin(), tubes.end(), want_id);
471 if (it != tubes.end() && *it == want_id) {
472 ++it;
473 } else {
474 Identifier deadTubeId = m_idHelperSvc->mdtIdHelper().channelID(detElId, ml, layer, tube);
475 m_DeadChannels.insert(deadTubeId);
476 ATH_MSG_VERBOSE("adding dead tube "<<m_idHelperSvc->toString(deadTubeId));
477 }
478 }
479 }
480 }
481
482 }
484
486
488 // Caching of PRD container
489 if (m_prdContainerCacheKey.key().empty()) {
490 // without the cache we just record the container
491 StatusCode status = handle.record(std::make_unique<MdtPrepDataContainer>(m_idHelperSvc->mdtIdHelper().module_hash_max()));
492 if (status.isFailure() || !handle.isValid()) {
493 ATH_MSG_FATAL("Could not record container of MDT PrepData Container at " << m_mdtPrepDataContainerKey.key());
494 return cache;
495 }
496 ATH_MSG_VERBOSE("Created container " << m_mdtPrepDataContainerKey.key());
497 cache.legacyPrd = handle.ptr();
498 } else {
499 // use the cache to get the container
501 if (!update.isValid()) {
502 ATH_MSG_FATAL("Invalid UpdateHandle " << m_prdContainerCacheKey.key());
503 return cache;
504 }
505 StatusCode status = handle.record(std::make_unique<MdtPrepDataContainer>(update.ptr()));
506 if (status.isFailure() || !handle.isValid()) {
507 ATH_MSG_FATAL("Could not record container of MDT PrepData Container using cache " << m_prdContainerCacheKey.key() << " - "
509 return cache;
510 }
511 ATH_MSG_VERBOSE("Created container using cache for " << m_prdContainerCacheKey.key());
512 cache.legacyPrd = handle.ptr();
513 }
514 cache.isValid = SG::get(cache.legacyDetMgr, m_muDetMgrKey, ctx).isSuccess() &&
515 SG::get(cache.twinTubeMap, m_twinTubeKey, ctx).isSuccess();
516 return cache;
517 }
518} // namespace Muon
Scalar eta() const
pseudorapidity method
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
Visitor to collect all IDs under a GeoModel node.
void geoGetIds(FUNCTION f, const GeoGraphNode *node, int depthLimit=1)
Template helper for running the visitor.
Definition GeoGetIds.h:82
virtual void lock()=0
Interface to allow an object to lock itself when made const in SG.
MdtCalibOutput::MdtDriftCircleStatus MdtDriftCircleStatus
void print(char *figname, TCanvas *c1)
const PrepDataT * at(size_type n) const
value_type push_back(value_type pElem)
size_type size() const noexcept
bool empty() const
return true if container is empty
virtual const T * indexFindPtr(IdentifierHash hashId) const override final
return pointer on the found entry or null if out of range using hashed index - fast version,...
size_t size() const
Duplicate of fullSize for backwards compatability.
This is a "hash" representation of an Identifier.
MDT RDO's : data from a single channel of an AMT Atlas Muon TDC.
Definition MdtAmtHit.h:20
const MuonGM::MdtReadoutElement * legacyDescriptor() const
Returns the legacy readout element.
void setClosestApproach(const Amg::Vector3D &approach)
Sets the closest approach.
int16_t tdc() const
Returns the tdc counts of the hit.
int16_t adc() const
Returns the amount of accumulated charge.
const Identifier & identify() const
Returns the Identifier of the hit.
double driftRadiusUncert() const
Returns the uncertainty on the drift radius.
double driftRadius() const
Returns the drift radius of the calibrated object.
Muon::MdtDriftCircleStatus MdtDriftCircleStatus
MdtDriftCircleStatus status() const
Status of the calibration.
MdtDriftCircleStatus primaryStatus() const
double primaryDriftR() const
Identifier twinID() const
Identifier primaryID() const
double uncertPrimaryR() const
This container provides acces to the MDT RDOs.
MDT RDOs : Chamber Service Module, container of AmtHits of a single Mdt chamber.
Definition MdtCsm.h:22
uint16_t CsmId() const
Returns the CSM online id (online identifier inside a MROD).
Definition MdtCsm.h:65
uint16_t MrodId() const
Returns the MROD id from the CSM header.
Definition MdtCsm.h:63
Identifier identify() const
Returns the CSM offline identifier (chamber offline id).
Definition MdtCsm.h:55
uint16_t SubDetId() const
Returns the sub-detector Id.
Definition MdtCsm.h:61
Identifier parentID(const Identifier &id) const
get parent id from channel id
static constexpr int maxNTubesPerLayer
The maxNTubesPerLayer represents the absolute maximum of tubes which are built into a single multilay...
Definition MdtIdHelper.h:68
Amg::Vector3D tubePos(const Identifier &id) const
Returns the global position of the given tube.
int getNLayers() const
Returns the number of tube layers inside the multilayer.
int getMultilayer() const
Returns the multilayer represented by the readout element.
int getNtubesperlayer() const
Returns the number of tubes in each tube layer.
double innerTubeRadius() const
Returns the inner tube radius excluding the aluminium walls.
The MuonDetectorManager stores the transient representation of the Muon Spectrometer geometry and pro...
const MuonStation * getMuonStation(const std::string &stName, int eta, int phi) const
double getStationS() const
Seems to be exclusively used by the MDTs --> Move it to MdtReadoutElement.
Identifier identify() const override final
Returns the ATLAS Identifier of the MuonReadOutElement.
std::vector< IdentifierHash > getMultiLayerHashVec(const std::vector< uint32_t > &ROBId_list, MsgStream &log) const
return a vector of HashId lists for a given list of ROD's
Interface for Helper service that creates muon Identifiers and can be used to print Identifiers.
Class to represent measurements from the Monitored Drift Tubes.
Definition MdtPrepData.h:33
int adc() const
Returns the ADC (typically range is 0 to 250).
virtual const MuonGM::MdtReadoutElement * detectorElement() const override
Returns the detector element corresponding to this PRD.
MdtDriftCircleStatus status() const
Returns the status of the measurement.
int tdc() const
Returns the TDC (typically range is 0 to 2500).
SG::ReadCondHandleKey< MuonMDT_CablingMap > m_readKey
virtual StatusCode provideEmptyContainer(const EventContext &ctx) const override
SG::ReadHandleKey< MdtCsmContainer > m_rdoContainerKey
SG::UpdateHandleKey< MdtPrepDataCollection_Cache > m_prdContainerCacheKey
This is the key for the cache for the MDT PRD containers, can be empty.
ConvCache setupMdtPrepDataContainer(const EventContext &ctx) const
Creates the prep data container to be written.
const MdtCsmContainer * getRdoContainer(const EventContext &ctx) const
Loads the input RDO container from StoreGate.
ToolHandle< IMdtCalibrationTool > m_calibrationTool
MDT calibration service.
std::unique_ptr< MdtPrepData > createPrepData(const MdtCalibInput &calibInput, const MdtCalibOutput &calibOutput) const
Creates the PRD object.
StatusCode processCsm(const EventContext &ctx, ConvCache &mdtPrepDataContainer, const MdtCsm *rdoColl) const
SG::ReadCondHandleKey< TwinTubeMap > m_twinTubeKey
Gaudi::Property< bool > m_discardSecondaryHitTwin
SG::WriteHandleKey< Muon::MdtPrepDataContainer > m_mdtPrepDataContainerKey
MdtPrepRawData containers.
std::unordered_set< Identifier > m_DeadChannels
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
Gaudi::Property< int > m_adcCut
member variables for algorithm properties:
SG::ReadCondHandleKey< MuonGM::MuonDetectorManager > m_muDetMgrKey
void processPRDHashes(const EventContext &ctx, ConvCache &mdtPrepDataContainer, const std::vector< IdentifierHash > &chamberHashInRobs) const
Gaudi::Property< bool > m_decodeData
toggle on/off the decoding of MDT RDO into MdtPrepData
virtual StatusCode decode(const EventContext &ctx, const std::vector< IdentifierHash > &idVect) const override
Decode method - declared in Muon::IMuonRdoToPrepDataTool.
virtual StatusCode initialize() override
standard Athena-Algorithm method
bool handlePRDHash(const EventContext &ctx, ConvCache &mdtPrepDataContainer, IdentifierHash rdoHash) const
void initDeadChannels(const MuonGM::MdtReadoutElement *mydetEl)
StatusCode processCsmTwin(const EventContext &ctx, ConvCache &mdtPrepDataContainer, const MdtCsm *rdoColll) const
ToolHandle< Muon::IMDT_RDO_Decoder > m_mdtDecoder
virtual IdentifierHash identifyHash() const override final
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
const Amg::Vector2D & localPosition() const
return the local position reference
Identifier identify() const
return the identifier
void setHashAndIndex(unsigned short collHash, unsigned short objIndex)
TEMP for testing: might make some classes friends later ...
const Amg::MatrixX & localCovariance() const
return const ref to the error matrix
int r
Definition globals.cxx:22
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition hcg.cxx:132
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
Ensure that the Athena extensions are properly loaded.
Definition GeoMuonHits.h:27
NRpcCablingAlg reads raw condition data and writes derived condition data to the condition store.
std::string print(const MuPatSegment &)
MuonPrepDataCollection< MdtPrepData > MdtPrepDataCollection
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.
Ensure that the ATLAS eigen extensions are properly loaded.
@ driftRadius
trt, straws
Definition ParamDefs.h:53
@ locR
Definition ParamDefs.h:44
@ phi
Definition ParamDefs.h:75
const IIntersectionCache * cache() const
Retrieve the associated cache block, if it exists.
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
Helper to simultaneously calculate sin and cos of the same angle.
Definition sincos.h:39
Helper struct to parse the event data around the tool.
bool isValid
Flag set to indicate that the complete validation was successful.
const Muon::IMuonIdHelperSvc * m_idHelperSvc
ConvCache(const Muon::IMuonIdHelperSvc *idHelperSvc)
std::vector< std::unique_ptr< MdtPrepDataCollection > > addedCols
StatusCode finalize(MsgStream &msg)
Copy the non-empty collections into the created prd container.
MdtPrepDataCollection * createCollection(const Identifier &id)
Creates a new MdtPrepDataCollection, if it's neccessary and also possible.
MsgStream & msg
Definition testRead.cxx:32