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{};
50 sstr<<
" PrepData "<<idHelperSvc->toString(prd.
identify())
53 ", tdc: "<<prd.
tdc()<<
", adc: "<<prd.
adc()<<
", status: "<<prd.
status();
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()};
93 dc =
xAODPrd->push_back(std::make_unique<xAOD::MdtDriftCircle>());
95 dc =
xAODTwinPrd->push_back(std::make_unique<xAOD::MdtTwinDriftCircle>());
109 if (prd->
status() == MdtDriftCircleStatus::MdtStatusDriftTime) {
116 driftCov = std::pow(maxR, 2);
122 dc->
setMeasurement<1>(detHash, std::move(locPos), std::move(locCov));
130 twinDC->setTwinAdc(twinPRD->adcTwin());
131 twinDC->setTwinTdc(twinPRD->tdcTwin());
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;
170 ATH_CHECK(detStore()->retrieve(muDetMgr));
172 ATH_MSG_INFO(
"Processing configuration for layouts with BMG chambers.");
176 for (
int side = -1; side < 2; side += 2) {
178 for (
int roe = 1; roe <= (muDetMgr->
getMuonStation(
"BMG", side *
eta,
phi))->nMuonReadoutElements();
188 std::vector<const MuonGMR4::MdtReadoutElement*> mdtRE =
m_detMgrR4->getAllMdtReadoutElements();
207 return StatusCode::SUCCESS;
218 if (rdoContainerHandle.
isValid()) {
220 return rdoContainerHandle.
cptr();
231 const std::vector<IdentifierHash>& multiLayerHashInRobs)
const {
242 if (rdoContainer->
empty()) {
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;
296 calibOutput.
status() == MdtDriftCircleStatus::MdtStatusUnDefined) {
298 <<
", adc: "<<calibInput.
adc()<<
" vs. "<<
m_adcCut<<
", calibration bailed out "
299 <<(calibOutput.
status() == MdtDriftCircleStatus::MdtStatusUnDefined?
"si":
"no"));
310 <<std::endl<<calibInput<<std::endl<<calibOutput);
314 if (calibOutput.
status() == MdtDriftCircleStatus::MdtStatusDriftTime){
319 (cov)(0, 0) = sigR * sigR;
322 return std::make_unique<MdtPrepData>(calibInput.
identify(),
345 uint16_t subdetId = rdoColl->
SubDetId();
346 uint16_t mrodId = rdoColl->
MrodId();
347 uint16_t csmId = rdoColl->
CsmId();
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()) {
402 if (prevPrd->
identify() == channelId) {
403 std::stringstream sstr{};
405 <<
" **** "<<
print(*prevPrd)<<std::endl
406 <<
" **** "<<
print(*newPrepData));
407 if (prevPrd->
status() == MdtDriftCircleStatus::MdtStatusDriftTime) {
409 }
else if (newPrepData->status() == MdtDriftCircleStatus::MdtStatusDriftTime) {
410 (*prevPrd) = std::move(*newPrepData);
417 newPrepData->setHashAndIndex(driftCircleColl->
identifyHash(), driftCircleColl->
size());
418 driftCircleColl->
push_back(std::move(newPrepData));
420 return StatusCode::SUCCESS;
429 uint16_t subdetId = rdoColl->
SubDetId();
430 uint16_t mrodId = rdoColl->
MrodId();
431 uint16_t csmId = rdoColl->
CsmId();
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) {
462 if (!digit || digit->isMasked() || !cache.
legacyDetMgr) {
468 if (!digit2 || digit2->isMasked()) {
470 <<digit->tdc()<<
", adc: "<<digit->adc()
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);
560 std::vector<int>::iterator it = tubes.begin();
561 for (
int layer = 1; layer <= mydetEl->
getNLayers(); layer++) {
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) {
588 StatusCode status = handle.
record(std::make_unique<MdtPrepDataContainer>(
m_idHelperSvc->mdtIdHelper().module_hash_max()));
589 if (status.isFailure() || !handle.
isValid()) {
598 if (!update.isValid()) {
602 StatusCode status = handle.
record(std::make_unique<MdtPrepDataContainer>(update.ptr()));
603 if (status.isFailure() || !handle.
isValid()) {
613 if (!writeHandle.
recordNonConst(std::make_unique<xAOD::MdtTwinDriftCircleContainer>(),
614 std::make_unique<xAOD::MdtTwinDriftCircleAuxContainer>()).isSuccess() ||
623 if (!writeHandle.
recordNonConst(std::make_unique<xAOD::MdtDriftCircleContainer>(),
624 std::make_unique<xAOD::MdtDriftCircleAuxContainer>()).isSuccess() ||
651 if (!twinTubeHandle.
isValid()) {
const boost::regex re(r_e)
Scalar eta() const
pseudorapidity method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(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.
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
StatusCode addOrDelete(std::unique_ptr< T > ptr)
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.
value_type get_compact() const
Get the compact id.
MDT RDO's : data from a single channel of an AMT Atlas Muon TDC.
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.
uint16_t CsmId() const
Returns the CSM online id (online identifier inside a MROD)
uint16_t MrodId() const
Returns the MROD id from the CSM header.
Identifier identify() const
Returns the CSM offline identifier (chamber offline id)
uint16_t SubDetId() const
Returns the sub-detector Id.
Identifier parentID(const Identifier &id) const
get parent id from channel id
int tube(const Identifier &id) const
int tubeLayer(const Identifier &id) const
static constexpr int maxNTubesPerLayer
The maxNTubesPerLayer represents the absolute maximum of tubes which are built into a single multilay...
double innerTubeRadius() const
Returns the inner tube radius.
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 MdtReadoutElement * getMdtReadoutElement(const Identifier &id) const
access via extended identifier (requires unpacking)
const MuonStation * getMuonStation(const std::string &stName, int eta, int phi) const
const Muon::IMuonIdHelperSvc * idHelperSvc() 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.
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).
unsigned int dimension() const
Returns the dimension of the MdtPrepData.
Class to represent measurements from the Monitored Drift Tubes.
virtual IdentifierHash identifyHash() const override final
bool isTwinTubeLayer(const Identifier &channelId) const
Returns whether the multilayer is equipped with twin-tubes or not.
Identifier twinId(const Identifier &channelId) const
Returns the Identifier of the mapped twin tube.
const_pointer_type cptr()
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
bool isPresent() const
Is the referenced object present in SG?
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
StatusCode recordNonConst(std::unique_ptr< T > data)
Record a non-const object to the store.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
pointer_type ptr()
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
unsigned int numDimensions() const override
Override the dimensions to be 1.
void setAdc(int16_t adc)
Sets the ADC counts.
void setReadoutElement(const MuonGMR4::MdtReadoutElement *readoutEle)
set the pointer to the MdtReadoutElement
const MuonGMR4::MdtReadoutElement * readoutElement() const
Retrieve the associated MdtReadoutElement.
void setLayer(uint8_t layer_n)
Sets the layer number.
void setStatus(MdtDriftCircleStatus st)
Sets the status of the drift circle.
void setTdc(int16_t tdc)
Setter methods.
void setTube(uint16_t tube_n)
Sets the tube number.
void setMeasurement(const DetectorIDHashType idHash, MeasVector< N > locPos, MeasMatrix< N > locCov)
Sets IdentifierHash, local position and local covariance of the measurement.
void setIdentifier(const DetectorIdentType measId)
Sets the full Identifier of the measurement.
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
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.
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.
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
MdtDriftCircle_v1 MdtDriftCircle
MdtTwinDriftCircle_v1 MdtTwinDriftCircle
Eigen::Matrix< float, N, N > MeasMatrix
Eigen::Matrix< float, N, 1 > MeasVector
Abrivation of the Matrix & Covariance definitions.
MeasVector< N > toStorage(const AmgVector(N)&amgVec)
Converts the double precision of the AmgVector into the floating point storage precision of the MeasV...
Helper to simultaneously calculate sin and cos of the same angle.