10 #include "GaudiKernel/PhysicalConstants.h"
37 if (std::abs(descriptor->
getStationS()) < std::numeric_limits<double>::epsilon()) {
41 double measuredPerp = std::sqrt(nominalTubePos.perp2() - descriptor->
getStationS()* descriptor->
getStationS());
43 Amg::Vector3D measurePos{tubeSC.
cs * measuredPerp, tubeSC.sn *measuredPerp, nominalTubePos.z()};
49 std::stringstream sstr{};
53 ", tdc: "<<prd.
tdc()<<
", adc: "<<prd.
adc()<<
", status: "<<prd.
status();
62 m_idHelperSvc{idHelperSvc} {
63 addedCols.resize(
m_idHelperSvc->mdtIdHelper().module_hash_max());
68 IdentifierHash mdtHashId =
m_idHelperSvc->moduleHash(elementId);
70 std::unique_ptr<MdtPrepDataCollection>& coll {addedCols[mdtHashId]};
72 coll = std::make_unique<MdtPrepDataCollection>(mdtHashId);
80 for (
unsigned int moduleHash =0; moduleHash < addedCols.size(); ++moduleHash) {
81 std::unique_ptr<MdtPrepDataCollection>& toInsert{addedCols[moduleHash]};
82 if (!toInsert || toInsert->empty())
continue;
85 std::vector<const MdtPrepData*> sortMe{toInsert->begin(), toInsert->end()};
91 if (!xAODTwinPrd|| !twinTubeMap || twinTubeMap->twinId(prdId) == prdId ||
92 prd->dimension() == 1) {
93 dc = xAODPrd->push_back(std::make_unique<xAOD::MdtDriftCircle>());
95 dc = xAODTwinPrd->push_back(std::make_unique<xAOD::MdtTwinDriftCircle>());
99 dc->setTdc(prd->tdc());
100 dc->setAdc(prd->adc());
101 dc->setTube(idHelper.tube(prdId));
102 dc->setLayer(idHelper.tubeLayer(prdId));
103 dc->setStatus(prd->status());
105 dc->setReadoutElement(r4DetMgr->getMdtReadoutElement(prdId));
107 const IdentifierHash detHash{
m_idHelperSvc->detElementHash(prdId)};
111 driftCov = prd->localCovariance()(0,0);
114 const float maxR = r4DetMgr ? dc->readoutElement()->innerTubeRadius()
115 : prd->detectorElement()->innerTubeRadius();
119 if (dc->numDimensions() == 1) {
122 dc->setMeasurement<1>(detHash, std::move(locPos), std::move(locCov));
127 dc->setMeasurement<2>(detHash,
xAOD::toStorage(prd->localPosition()), std::move(locCov));
130 twinDC->setTwinAdc(twinPRD->adcTwin());
131 twinDC->setTwinTdc(twinPRD->tdcTwin());
132 const Identifier twinId = twinTubeMap->twinId(prdId);
133 twinDC->setTwinTube(idHelper.tube(twinId));
134 twinDC->setTwinLayer(idHelper.tubeLayer(twinId));
139 if (
lock.addOrDelete(std::move(toInsert)).isFailure()) {
140 msg << MSG::ERROR <<
" Failed to add prep data collection " << moduleHash <<
endmsg;
141 return StatusCode::FAILURE;
150 return StatusCode::SUCCESS;
172 ATH_MSG_INFO(
"Processing configuration for layouts with BMG chambers.");
174 for (
int phi = 6; phi < 8; phi++) {
175 for (
int eta = 1; eta < 4; eta++) {
178 for (
int roe = 1; roe <= (muDetMgr->
getMuonStation(
"BMG",
side * eta, phi))->nMuonReadoutElements();
188 std::vector<const MuonGMR4::MdtReadoutElement*> mdtRE =
m_detMgrR4->getAllMdtReadoutElements();
193 for (
const IdentifierHash& dead :
re->getParameters().removedTubes) {
207 return StatusCode::SUCCESS;
213 return decode(ctx, readCdo->getMultiLayerHashVec(robIds, msgStream()));
218 if (rdoContainerHandle.isValid()) {
220 return rdoContainerHandle.cptr();
231 const std::vector<IdentifierHash>& multiLayerHashInRobs)
const {
232 for (
const IdentifierHash&
hash : multiLayerHashInRobs) {
239 IdentifierHash rdoHash)
const {
242 if (rdoContainer->empty()) {
246 const MdtCsm* rdoColl = rdoContainer->indexFindPtr(rdoHash);
248 ATH_MSG_DEBUG(
"The rdo container does not have the hash " << rdoHash);
251 if (
processCsm(ctx, mdtPrepDataContainer, rdoColl).isFailure()) {
259 const std::vector<IdentifierHash>& idVect)
const {
261 ATH_MSG_DEBUG(
"decodeMdtRDO for " << idVect.size() <<
" offline collections called");
265 if (!mdtPrepDataContainer.
isValid) {
266 return StatusCode::FAILURE;
271 ATH_MSG_DEBUG(
"Stored empty container. Decoding MDT RDO into MDT PrepRawData is switched off");
272 return StatusCode::SUCCESS;
275 if (!idVect.empty()) {
279 std::vector<IdentifierHash> rdoHashes{};
281 if (!rdoContainer || rdoContainer->
empty())
return StatusCode::SUCCESS;
282 rdoHashes.reserve(rdoContainer->
size());
283 for (
const MdtCsm* csm : *rdoContainer) rdoHashes.push_back(csm->identifyHash());
289 return StatusCode::SUCCESS;
298 <<
", adc: "<<calibInput.
adc()<<
" vs. "<<
m_adcCut<<
", calibration bailed out "
310 <<std::endl<<calibInput<<std::endl<<calibOutput);
319 (
cov)(0, 0) = sigR * sigR;
322 return std::make_unique<MdtPrepData>(calibInput.
identify(),
349 << mrodId <<
" / " << csmId);
355 for (
const MdtAmtHit* amtHit : *rdoColl) {
360 std::unique_ptr<MdtDigit> newDigit{
m_mdtDecoder->getDigit(ctx, *amtHit, subdetId, mrodId, csmId)};
362 ATH_MSG_WARNING(
"Found issue MDT RDO decoder for subdetId/mrodId/csmId "
363 << subdetId <<
"/" << mrodId <<
"/" << csmId <<
" amtHit channelId/tdcId =" << amtHit->channelId() <<
"/"
375 if (!driftCircleColl) {
389 newDigit->setAdc(newDigit->adc() / 4);
390 newDigit->setTdc(newDigit->tdc() / 4);
396 std::unique_ptr<MdtPrepData> newPrepData =
createPrepData(calibIn, calibResult, cache);
400 if (driftCircleColl->
size()) {
403 std::stringstream sstr{};
405 <<
" **** "<<
print(*prevPrd)<<std::endl
406 <<
" **** "<<
print(*newPrepData));
410 (*prevPrd) = std::move(*newPrepData);
417 newPrepData->setHashAndIndex(driftCircleColl->
identifyHash(), driftCircleColl->
size());
418 driftCircleColl->
push_back(std::move(newPrepData));
420 return StatusCode::SUCCESS;
433 <<
" / " << rdoColl->
MrodId() <<
" / " << rdoColl->
CsmId());
437 std::map<Identifier, std::array<std::unique_ptr<MdtDigit>, 2>> mdtDigitColl{};
439 for (
const MdtAmtHit* amtHit : *rdoColl) {
440 std::unique_ptr<MdtDigit> newDigit{
m_mdtDecoder->getDigit(ctx, *amtHit, subdetId, mrodId, csmId)};
444 << subdetId <<
"/" << mrodId <<
"/" << csmId <<
" amtHit channelId/tdcId =" << amtHit->channelId() <<
"/"
448 std::array<std::unique_ptr<MdtDigit>, 2> & moveTo = mdtDigitColl[newDigit->identify()];
450 moveTo[0] = std::move(newDigit);
452 moveTo[1] = std::move(newDigit);
454 ATH_MSG_VERBOSE(
" TWIN TUBES: found a tertiary hit in a twin tube in one RdoCollection for "
455 <<
m_idHelperSvc->toString(newDigit->identify()) <<
" with adc = " << newDigit->adc()
456 <<
" tdc = " << newDigit->tdc());
460 auto convertTwins = [
this, &cache, &ctx](std::unique_ptr<MdtDigit>
digit,
461 std::unique_ptr<MdtDigit> digit2) {
468 if (!digit2 || digit2->isMasked()) {
479 std::unique_ptr<MdtPrepData> newPrepData =
createPrepData(mdtCalibIn, mdtCalibOut, cache);
480 if (!newPrepData)
return;
482 newPrepData->setHashAndIndex(driftCircleColl->
identifyHash(), driftCircleColl->
size());
483 driftCircleColl->
push_back(std::move(newPrepData));
487 <<
", tdc: "<<
digit->tdc()<<
", adc: "<<
digit->adc()<<
" -- "
489 <<
", tdc: "<<digit2->tdc()<<
", adc: "<<digit2->adc());
496 updateClosestApproachTwin(mdtCalib1st);
497 updateClosestApproachTwin(mdtCalib2nd);
500 std::move(mdtCalib1st),
501 std::move(mdtCalib2nd));
507 cov(0, 1) =
cov(1, 0) = 0;
510 auto twin_newPrepData = std::make_unique<MdtTwinPrepData>(twinCalib.
primaryID(),
524 <<
"local pos center tube w/ TWIN INFO "<<
Amg::toString(twinCalib.
locZ() * Amg::Vector3D::UnitZ(), 2)<<std::endl
527 twin_newPrepData->setHashAndIndex(driftCircleColl->
identifyHash(), driftCircleColl->
size());
528 driftCircleColl->
push_back(std::move(twin_newPrepData));
532 for (
auto &[
id, digits] : mdtDigitColl) {
537 std::array<std::unique_ptr<MdtDigit>, 2>& twinDigits = mdtDigitColl[twinId];
539 convertTwins(std::move(digits[0]), std::move(twinDigits[0]));
541 convertTwins(std::move(digits[1]), std::move(twinDigits[1]));
543 convertTwins(std::move(digits[0]),
nullptr);
544 convertTwins(std::move(digits[1]),
nullptr);
547 return StatusCode::SUCCESS;
550 PVConstLink cv = mydetEl->getMaterialGeom();
551 int nGrandchildren = cv->getNChildVols();
552 if (nGrandchildren <= 0)
return;
554 std::vector<int> tubes;
555 geoGetIds([&](
int id) { tubes.push_back(
id); }, &*cv);
556 std::sort(tubes.begin(), tubes.end());
563 int want_id =
layer * maxNTubesPerLayer +
tube;
564 if (
it != tubes.end() && *
it == want_id) {
567 it = std::lower_bound(tubes.begin(), tubes.end(), want_id);
568 if (
it != tubes.end() && *
it == want_id) {
589 if (
status.isFailure() || !handle.isValid()) {
594 cache.legacyPrd = handle.ptr();
598 if (!update.isValid()) {
602 StatusCode status = handle.record(std::make_unique<MdtPrepDataContainer>(update.ptr()));
603 if (
status.isFailure() || !handle.isValid()) {
609 cache.legacyPrd = handle.ptr();
613 if (!writeHandle.recordNonConst(std::make_unique<xAOD::MdtTwinDriftCircleContainer>(),
614 std::make_unique<xAOD::MdtTwinDriftCircleAuxContainer>()).isSuccess() ||
615 !writeHandle.isValid()) {
619 cache.xAODTwinPrd = writeHandle.ptr();
623 if (!writeHandle.recordNonConst(std::make_unique<xAOD::MdtDriftCircleContainer>(),
624 std::make_unique<xAOD::MdtDriftCircleAuxContainer>()).isSuccess() ||
625 !writeHandle.isValid()) {
629 cache.xAODPrd = writeHandle.ptr();
634 if (!readHandle.isPresent()) {
638 cache.gctx = readHandle.cptr();
643 if (!detMgrHandle.isValid()) {
647 cache.legacyDetMgr = detMgrHandle.cptr();
651 if (!twinTubeHandle.isValid()) {
655 cache.twinTubeMap = twinTubeHandle.cptr();
659 cache.isValid =
true;