ATLAS Offline Software
Loading...
Searching...
No Matches
MuonSegmentHitSummaryTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7#include <map>
8
13
14namespace Muon {
15
16MuonSegmentHitSummaryTool::MuonSegmentHitSummaryTool(const std::string& ty, const std::string& na, const IInterface* pa)
17 : AthAlgTool(ty, na, pa)
18{
19 declareInterface<IMuonSegmentHitSummaryTool>(this);
20 declareProperty("PositionAlongTubeCut", m_positionAlongTubeCut = -200.,
21 "Cut on distance from tube end used for holes, negative value means in the tube");
22 declareProperty("MinimumADCValue", m_lowerADCBound = 70.);
23}
24
25StatusCode
27{
28 ATH_CHECK(m_DetectorManagerKey.initialize());
29 ATH_CHECK(m_edmHelperSvc.retrieve());
30 ATH_CHECK(m_printer.retrieve());
31 ATH_CHECK(m_idHelperSvc.retrieve());
32 return StatusCode::SUCCESS;
33}
34
37{
38
39 HitCounts hitCounts;
40
42 const MuonGM::MuonDetectorManager* MuonDetMgr{*DetectorManagerHandle};
43 if (!MuonDetMgr) {
44 ATH_MSG_ERROR("Null pointer to the read MuonDetectorManager conditions object");
45 return hitCounts;
46 }
47
48 // calculate shortest channel
49 double shortestTube {FLT_MAX};
50 const MdtDriftCircleOnTrack* mdtShortest = nullptr;
51 bool transformIsSet = false;
52 Amg::Transform3D gToAMDB;
53 Amg::Vector3D lpos{Amg::Vector3D::Zero()};
54 Amg::Vector3D ldir{Amg::Vector3D::Zero()};
55 double dxdy = 1.;
56
57 using namespace MuonStationIndex;
58 const Identifier chid = m_edmHelperSvc->chamberId(seg);
59 const StIndex stIdx = m_idHelperSvc->stationIndex(chid);
60
62 if ((!m_idHelperSvc->isCsc(chid) && stIdx == StIndex::EI) || stIdx == StIndex::BO)
63 hitCounts.nexpectedTrigHitLayers = 1;
64 else if (stIdx == StIndex::BM)
65 hitCounts.nexpectedTrigHitLayers = 2;
66 else if (stIdx == StIndex::EM)
67 hitCounts.nexpectedTrigHitLayers = 3;
68
69 // loop over hits
70 for (const Trk::MeasurementBase* meas : seg.containedMeasurements()) {
71
72 // get id and check that it is a muon hit id
73 Identifier id = m_edmHelperSvc->getIdentifier(*meas);
74 if (!id.is_valid() || !m_idHelperSvc->isMuon(id)) continue;
75
76 // check if MDT is so increase ml counter
77 if (m_idHelperSvc->isMdt(id)) {
78 // get layer index
79 int ml = m_idHelperSvc->mdtIdHelper().multilayer(id);
80 int lay = m_idHelperSvc->mdtIdHelper().tubeLayer(id);
81 int tube = m_idHelperSvc->mdtIdHelper().tube(id);
82 int layIndex = 4 * (ml - 1) + (lay - 1); // start at 0 rather than at 1
83 MdtLayerIntersect& layIntersect = hitCounts.mdtHitHolePerLayerCounts[layIndex];
84 ++layIntersect.nhits;
85
86 const MdtDriftCircleOnTrack* mdt = dynamic_cast<const MdtDriftCircleOnTrack*>(meas);
87 if (mdt) {
88 const MuonGM::MdtReadoutElement* detEl =
89 mdt->prepRawData() ? mdt->prepRawData()->detectorElement() : MuonDetMgr->getMdtReadoutElement(id);
90 if (!detEl) {
91 ATH_MSG_WARNING(" could not get MdtReadoutElement for tube " << m_idHelperSvc->toString(id));
92 continue;
93 }
94
95 double tubeLen = detEl->getActiveTubeLength(lay, tube);
96 layIntersect.tubeLength = tubeLen;
97 if (!transformIsSet) {
98 gToAMDB = detEl->GlobalToAmdbLRSTransform();
99 lpos = gToAMDB * seg.globalPosition();
100 ldir = (gToAMDB * seg.globalDirection()).unit();
101 dxdy = std::abs(ldir.y()) > 0.001 ? ldir.x() / ldir.y() : 1000.;
102 transformIsSet = true;
103 }
104 if (!mdtShortest || tubeLen < shortestTube) {
105 mdtShortest = mdt;
106 shortestTube = tubeLen;
107 }
108 }
109 const bool first_layer = (m_idHelperSvc->mdtIdHelper().multilayer(id) == 1);
110 hitCounts.nmdtHitsMl1 += first_layer;
111 hitCounts.nmdtHitsMl2 += !first_layer;
112 if (mdt && mdt->prepRawData()) {
113 int adc = mdt->prepRawData()->adc();
114 if (adc > m_lowerADCBound) hitCounts.nmdtHighADCHits+=(adc > m_lowerADCBound);
115 hitCounts.adcMax = std::max(adc, hitCounts.adcMax);
116 }
117
118 }
120 else if (m_idHelperSvc->isTrigger(id)) {
121 // get gasgap ID (same for eta/phi projection)
122 Identifier gasGapId = m_idHelperSvc->gasGapId(id);
123 const bool measuresPhi = m_idHelperSvc->measuresPhi(id);
124 hitCounts.hitCountsPerLayer[gasGapId].nphiHits+= measuresPhi;
125 hitCounts.hitCountsPerLayer[gasGapId].netaHits+= !measuresPhi;
126 } else if (m_idHelperSvc->isCsc(id)) {
127 const bool measuresPhi = m_idHelperSvc->measuresPhi(id);
128 hitCounts.ncscHits.nphiHits+= measuresPhi;
129 hitCounts.ncscHits.netaHits+= !measuresPhi;
130 } else if (m_idHelperSvc->issTgc(id)){
131 const bool measuresPhi = m_idHelperSvc->measuresPhi(id);
132 hitCounts.nstgcHits.nphiHits+= measuresPhi;
133 hitCounts.nstgcHits.netaHits+= !measuresPhi;
134 } else if (m_idHelperSvc->isMM(id)){
135 const bool isStereo = m_idHelperSvc->mmIdHelper().isStereo(id);
136 hitCounts.nmmEtaHits += !isStereo;
137 hitCounts.nmmStereoHits+= isStereo;
138 }
139 }
140
141 const MuonSegmentQuality* quality = dynamic_cast<const MuonSegmentQuality*>(seg.fitQuality());
142 if (quality) {
143 for (const Identifier& id : quality->channelsWithoutHit()) {
145 int ml = m_idHelperSvc->mdtIdHelper().multilayer(id);
146 int lay = m_idHelperSvc->mdtIdHelper().tubeLayer(id);
147 int tube = m_idHelperSvc->mdtIdHelper().tube(id);
148 int layIndex = 4 * (ml - 1) + (lay - 1); // subtract 1 as fields start with 1 instead of 0
149 MdtLayerIntersect& layIntersect = hitCounts.mdtHitHolePerLayerCounts[layIndex];
150 ++layIntersect.nholes;
151
152 if (transformIsSet) {
153 const MuonGM::MdtReadoutElement* detEl = MuonDetMgr->getMdtReadoutElement(id);
154 if (!detEl) {
155 ATH_MSG_WARNING(" could not get MdtReadoutElement for tube " << m_idHelperSvc->toString(id));
156 continue;
157 }
158 double tubeLen = detEl->getActiveTubeLength(lay, tube);
159 double ytube = (gToAMDB * detEl->center(id)).y();
160 double xint = dxdy * (ytube - lpos.y()) + lpos.x();
161 layIntersect.distFromTubeEnd = xint;
162 layIntersect.tubeLength = tubeLen;
163 }
164 }
165 }
166
167
168 // now loop over map and get the counts for the trigger hits
169 for (std::pair<const Identifier, EtaPhiHitCount>& it : hitCounts.hitCountsPerLayer) {
170 EtaPhiHitCount& counts = it.second;
171
172 // increase eta/phi hit counts
173 if (counts.nphiHits != 0) ++hitCounts.nphiTrigHitLayers;
174 if (counts.netaHits != 0) {
175 ++hitCounts.netaTrigHitLayers;
176
177 // if both eta/phi projection have entries increase paired counters
178 if (counts.nphiHits != 0) ++hitCounts.npairedTrigHitLayers;
179 }
180 }
181
182 int currentEnclosedHoles = 0;
183 bool firstLayerWithHits = false;
184 // now loop over mdt map and get the number of enclosed holes
185 for ( auto& lit : hitCounts.mdtHitHolePerLayerCounts) {
186 hitCounts.nmdtHoles += lit.second.nholes;
187 if (lit.second.nhits == 0) {
188 ++currentEnclosedHoles;
189 // count holes within chamber bounds
190 if (std::abs(lit.second.distFromTubeEnd) - 0.5 * lit.second.tubeLength < m_positionAlongTubeCut)
191 ++hitCounts.nmdtHolesInChamber;
192 } else {
193 if (firstLayerWithHits) hitCounts.nmdtEnclosedHoles += currentEnclosedHoles;
194 currentEnclosedHoles = 0;
195 firstLayerWithHits = true;
196 }
197 }
198
199 if (mdtShortest) {
200 double posAlongTube = (mdtShortest->associatedSurface().transform().inverse() * seg.globalPosition()).z();
201 if (0.5 * shortestTube - std::abs(posAlongTube) < 100.) hitCounts.closeToChamberEdge = true;
202 }
203
204 if (seg.fitQuality()) {
205 // combine chi2 with missing hit information and apply cut
206 hitCounts.segmentQuality = seg.fitQuality()->chiSquared() + 5.1 * (hitCounts.nmdtHoles);
207 if (seg.fitQuality()->numberDoF() > 0) hitCounts.segmentQuality /= seg.fitQuality()->numberDoF();
208 }
209
210
211 return hitCounts;
212}
213
214} // namespace Muon
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_WARNING(x)
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
double getActiveTubeLength(const int tubeLayer, const int tube) const
virtual const Amg::Vector3D & center(const Identifier &) const override final
Return the center of the surface associated with this identifier In the case of silicon it returns th...
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)
This class represents the corrected MDT measurements, where the corrections include the effects of wi...
virtual const Trk::StraightLineSurface & associatedSurface() const override final
Returns the surface on which this measurement was taken.
virtual const MdtPrepData * prepRawData() const override final
Returns the PrepRawData used to create this corrected measurement.
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.
double m_lowerADCBound
lower bound for good MDT hits
PublicToolHandle< Muon::MuonEDMPrinterTool > m_printer
EDM printer tool.
MuonSegmentHitSummaryTool(const std::string &, const std::string &, const IInterface *)
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
SG::ReadCondHandleKey< MuonGM::MuonDetectorManager > m_DetectorManagerKey
double m_positionAlongTubeCut
cut on the distance from the tube wall use for hole count
ServiceHandle< Muon::IMuonEDMHelperSvc > m_edmHelperSvc
EDM Helper tool.
virtual HitCounts getHitCounts(const MuonSegment &seg) const
calculate segment hit counts
This is the common muon segment quality object.
const std::vector< Identifier > & channelsWithoutHit() const
vector of identifiers of channels crossed by the segment but without hit
This is the common class for 3D segments used in the muon spectrometer.
virtual const Amg::Vector3D & globalPosition() const override final
global position
int numberDoF() const
returns the number of degrees of freedom of the overall track or vertex fit as integer
Definition FitQuality.h:60
double chiSquared() const
returns the of the overall track fit
Definition FitQuality.h:56
This class is the pure abstract base class for all fittable tracking measurements.
const FitQuality * fitQuality() const
return the FitQuality object, returns NULL if no FitQuality is defined
const std::vector< const Trk::MeasurementBase * > & containedMeasurements() const
returns the vector of Trk::MeasurementBase objects
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 3, 1 > Vector3D
StIndex
enum to classify the different station layers in the muon spectrometer
NRpcCablingAlg reads raw condition data and writes derived condition data to the condition store.
uint8_t nmmStereoHits
Number of eta micromega hits.
uint8_t nphiTrigHitLayers
Number of eta stereo hits.