10#include "GaudiKernel/PhysicalConstants.h"
33 if (std::abs(descriptor->
getStationS()) < std::numeric_limits<double>::epsilon()) {
37 double measuredPerp = std::sqrt(nominalTubePos.perp2() - descriptor->
getStationS()* descriptor->
getStationS());
39 Amg::Vector3D measurePos{tubeSC.
cs * measuredPerp, tubeSC.
sn *measuredPerp, nominalTubePos.z()};
45 std::stringstream sstr{};
46 sstr<<
" PrepData "<<idHelperSvc->toString(prd.
identify())
49 ", tdc: "<<prd.
tdc()<<
", adc: "<<prd.
adc()<<
", status: "<<prd.
status();
66 std::unique_ptr<MdtPrepDataCollection>& coll {
addedCols[mdtHashId]};
68 coll = std::make_unique<MdtPrepDataCollection>(mdtHashId);
74 for (
unsigned int moduleHash =0; moduleHash <
addedCols.size(); ++moduleHash) {
75 std::unique_ptr<MdtPrepDataCollection>& toInsert{
addedCols[moduleHash]};
76 if (!toInsert || toInsert->empty())
continue;
78 if (
lock.addOrDelete(std::move(toInsert)).isFailure()) {
79 msg << MSG::ERROR <<
" Failed to add prep data collection " << moduleHash <<
endmsg;
80 return StatusCode::FAILURE;
83 return StatusCode::SUCCESS;
100 ATH_CHECK(detStore()->retrieve(muDetMgr));
102 ATH_MSG_INFO(
"Processing configuration for layouts with BMG chambers.");
106 for (
int side = -1; side < 2; side += 2) {
108 for (
int roe = 1; roe <= (muDetMgr->
getMuonStation(
"BMG", side *
eta,
phi))->nMuonReadoutElements();
123 return StatusCode::SUCCESS;
134 if (rdoContainerHandle.
isValid()) {
136 return rdoContainerHandle.
cptr();
147 const std::vector<IdentifierHash>& multiLayerHashInRobs)
const {
158 if (rdoContainer->
empty()) {
164 ATH_MSG_DEBUG(
"The rdo container does not have the hash " << rdoHash);
167 if (
processCsm(ctx, mdtPrepDataContainer, rdoColl).isFailure()) {
175 const std::vector<IdentifierHash>& idVect)
const {
177 ATH_MSG_DEBUG(
"decodeMdtRDO for " << idVect.size() <<
" offline collections called");
181 if (!mdtPrepDataContainer.
isValid) {
182 return StatusCode::FAILURE;
187 ATH_MSG_DEBUG(
"Stored empty container. Decoding MDT RDO into MDT PrepRawData is switched off");
188 return StatusCode::SUCCESS;
191 if (!idVect.empty()) {
195 std::vector<IdentifierHash> rdoHashes{};
197 if (!rdoContainer || rdoContainer->
empty())
return StatusCode::SUCCESS;
198 rdoHashes.reserve(rdoContainer->
size());
199 for (
const MdtCsm* csm : *rdoContainer) rdoHashes.push_back(csm->identifyHash());
205 return StatusCode::SUCCESS;
211 calibOutput.
status() == MdtDriftCircleStatus::MdtStatusUnDefined) {
213 <<
", adc: "<<calibInput.
adc()<<
" vs. "<<
m_adcCut<<
", calibration bailed out "
214 <<(calibOutput.
status() == MdtDriftCircleStatus::MdtStatusUnDefined?
"si":
"no"));
219 <<std::endl<<calibInput<<std::endl<<calibOutput);
223 if (calibOutput.
status() == MdtDriftCircleStatus::MdtStatusDriftTime){
228 (cov)(0, 0) = sigR * sigR;
231 return std::make_unique<MdtPrepData>(calibInput.
identify(),
244 if (
cache.twinTubeMap->isTwinTubeLayer(rdoColl->
identify())) {
254 uint16_t subdetId = rdoColl->
SubDetId();
255 uint16_t mrodId = rdoColl->
MrodId();
256 uint16_t csmId = rdoColl->
CsmId();
258 << mrodId <<
" / " << csmId);
264 for (
const MdtAmtHit* amtHit : *rdoColl) {
269 std::unique_ptr<MdtDigit> newDigit{
m_mdtDecoder->getDigit(ctx, *amtHit, subdetId, mrodId, csmId)};
271 ATH_MSG_WARNING(
"Found issue MDT RDO decoder for subdetId/mrodId/csmId "
272 << subdetId <<
"/" << mrodId <<
"/" << csmId <<
" amtHit channelId/tdcId =" << amtHit->channelId() <<
"/"
284 if (!driftCircleColl) {
298 newDigit->setAdc(newDigit->adc() / 4);
299 newDigit->setTdc(newDigit->tdc() / 4);
305 std::unique_ptr<MdtPrepData> newPrepData =
createPrepData(calibIn, calibResult);
309 if (driftCircleColl->
size()) {
311 if (prevPrd->
identify() == channelId) {
312 std::stringstream sstr{};
314 <<
" **** "<<
print(*prevPrd)<<std::endl
315 <<
" **** "<<
print(*newPrepData));
316 if (prevPrd->
status() == MdtDriftCircleStatus::MdtStatusDriftTime) {
318 }
else if (newPrepData->status() == MdtDriftCircleStatus::MdtStatusDriftTime) {
319 (*prevPrd) = std::move(*newPrepData);
326 newPrepData->setHashAndIndex(driftCircleColl->
identifyHash(), driftCircleColl->
size());
327 driftCircleColl->
push_back(std::move(newPrepData));
329 return StatusCode::SUCCESS;
338 uint16_t subdetId = rdoColl->
SubDetId();
339 uint16_t mrodId = rdoColl->
MrodId();
340 uint16_t csmId = rdoColl->
CsmId();
342 <<
" / " << rdoColl->
MrodId() <<
" / " << rdoColl->
CsmId());
346 std::map<Identifier, std::array<std::unique_ptr<MdtDigit>, 2>> mdtDigitColl{};
348 for (
const MdtAmtHit* amtHit : *rdoColl) {
349 std::unique_ptr<MdtDigit> newDigit{
m_mdtDecoder->getDigit(ctx, *amtHit, subdetId, mrodId, csmId)};
353 << subdetId <<
"/" << mrodId <<
"/" << csmId <<
" amtHit channelId/tdcId =" << amtHit->channelId() <<
"/"
357 std::array<std::unique_ptr<MdtDigit>, 2> & moveTo = mdtDigitColl[newDigit->identify()];
359 moveTo[0] = std::move(newDigit);
361 moveTo[1] = std::move(newDigit);
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());
369 auto convertTwins = [
this, &
cache, &ctx](std::unique_ptr<MdtDigit> digit,
370 std::unique_ptr<MdtDigit> digit2) {
371 if (!digit || digit->isMasked()) {
return; }
375 if (!digit2 || digit2->isMasked()) {
377 <<digit->tdc()<<
", adc: "<<digit->adc()
384 std::unique_ptr<MdtPrepData> newPrepData =
createPrepData(mdtCalibIn, mdtCalibOut);
385 if (!newPrepData)
return;
387 newPrepData->setHashAndIndex(driftCircleColl->
identifyHash(), driftCircleColl->
size());
388 driftCircleColl->
push_back(std::move(newPrepData));
392 <<
", tdc: "<<digit->tdc()<<
", adc: "<<digit->adc()<<
" -- "
394 <<
", tdc: "<<digit2->tdc()<<
", adc: "<<digit2->adc());
399 updateClosestApproachTwin(mdtCalib1st);
400 updateClosestApproachTwin(mdtCalib2nd);
403 std::move(mdtCalib1st),
404 std::move(mdtCalib2nd));
410 cov(0, 1) = cov(1, 0) = 0;
413 auto twin_newPrepData = std::make_unique<MdtTwinPrepData>(twinCalib.
primaryID(),
427 <<
"local pos center tube w/ TWIN INFO "<<
Amg::toString(twinCalib.
locZ() * Amg::Vector3D::UnitZ(), 2)<<std::endl
430 twin_newPrepData->setHashAndIndex(driftCircleColl->
identifyHash(), driftCircleColl->
size());
431 driftCircleColl->
push_back(std::move(twin_newPrepData));
435 for (
auto &[
id, digits] : mdtDigitColl) {
440 std::array<std::unique_ptr<MdtDigit>, 2>& twinDigits = mdtDigitColl[twinId];
442 convertTwins(std::move(digits[0]), std::move(twinDigits[0]));
444 convertTwins(std::move(digits[1]), std::move(twinDigits[1]));
446 convertTwins(std::move(digits[0]),
nullptr);
447 convertTwins(std::move(digits[1]),
nullptr);
450 return StatusCode::SUCCESS;
453 PVConstLink cv = mydetEl->getMaterialGeom();
454 int nGrandchildren = cv->getNChildVols();
455 if (nGrandchildren <= 0)
return;
457 std::vector<int> tubes;
458 geoGetIds([&](
int id) { tubes.push_back(
id); }, &*cv);
463 std::vector<int>::iterator it = tubes.begin();
464 for (
int layer = 1; layer <= mydetEl->
getNLayers(); layer++) {
466 int want_id = layer * maxNTubesPerLayer + tube;
467 if (it != tubes.end() && *it == want_id) {
470 it = std::lower_bound(tubes.begin(), tubes.end(), want_id);
471 if (it != tubes.end() && *it == want_id) {
491 StatusCode status = handle.record(std::make_unique<MdtPrepDataContainer>(
m_idHelperSvc->mdtIdHelper().module_hash_max()));
492 if (status.isFailure() || !handle.isValid()) {
497 cache.legacyPrd = handle.ptr();
501 if (!update.isValid()) {
505 StatusCode status = handle.record(std::make_unique<MdtPrepDataContainer>(update.ptr()));
506 if (status.isFailure() || !handle.isValid()) {
512 cache.legacyPrd = handle.ptr();
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.
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.
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
static constexpr int maxNTubesPerLayer
The maxNTubesPerLayer represents the absolute maximum of tubes which are built into a single multilay...
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
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).
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
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.
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.