ATLAS Offline Software
Loading...
Searching...
No Matches
MuonSegmentSelectionTool.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
16MuonSegmentSelectionTool::MuonSegmentSelectionTool(const std::string& ty, const std::string& na, const IInterface* pa)
17 : AthAlgTool(ty, na, pa) {
18 declareInterface<IMuonSegmentSelectionTool>(this);
19}
20
21StatusCode
23{
24 ATH_CHECK(m_edmHelperSvc.retrieve());
25 ATH_CHECK(m_printer.retrieve());
26 ATH_CHECK(m_idHelperSvc.retrieve());
27 ATH_CHECK(m_hitSummaryTool.retrieve());
28 return StatusCode::SUCCESS;
29}
30
31int
32MuonSegmentSelectionTool::quality(const MuonSegment& seg, bool ignoreHoles, bool useEta, bool usePhi) const
33{
34 Identifier chid = m_edmHelperSvc->chamberId(seg);
35 if (!chid.is_valid()) {
36 ATH_MSG_WARNING("Got invalid segment identifier");
37 return -1;
38 }
39
40 // different treatment for CSC and MDT segments
41 // mdt treatment
42 if (m_idHelperSvc->isMdt(chid)) return mdtSegmentQuality(seg, ignoreHoles);
43
44 // csc segments
45 if (m_idHelperSvc->isCsc(chid)) return cscSegmentQuality(seg, useEta, usePhi);
46
47 // rpc/tgc case
48 if (m_idHelperSvc->isTgc(chid) || m_idHelperSvc->isRpc(chid)) return 1;
49
50 // NSW segments
51 return nswSegmentQuality(seg, chid, ignoreHoles);
52}
53
54int
55MuonSegmentSelectionTool::cscSegmentQuality(const MuonSegment& seg, bool useEta, bool usePhi) const
56{
57
58 // get hit counts
59 IMuonSegmentHitSummaryTool::HitCounts hitCounts = m_hitSummaryTool->getHitCounts(seg);
60
61 /**********************************/
62 /* cuts for quality level 0 */
63
64 // remove CSC segments with only 3 hits
65 // unless either eta or phi are broken, in that case we accept the segment
66 if (hitCounts.ncscHits() < 4 && useEta && usePhi) return -1;
67
68
69 /**********************************/
70 /* cuts for quality level 1 */
71
72 // remove CSC segments with no layer with 4 hits
73 if (hitCounts.ncscHits.nphiHits != 4 && hitCounts.ncscHits.netaHits != 4) return 1;
74
75
76 /**********************************/
77 /* cuts for quality level 2 */
78
79 // require hits in both projections
80 if (!hitCounts.ncscHits.hasEtaAndPhi()) return 1;
81
82
83 /**********************************/
84 /* cuts for quality level 3 */
85
86 // require four hits in one of the projections and hits in the other
87 if ((hitCounts.ncscHits.netaHits == 4 && hitCounts.ncscHits.nphiHits != 4)
88 || (hitCounts.ncscHits.netaHits != 4 && hitCounts.ncscHits.nphiHits == 4))
89 return 2;
90
91
92 /**********************************/
93 /* segment has highest quality */
94 return 3;
95}
96
97int
98MuonSegmentSelectionTool::nswSegmentQuality(const MuonSegment& seg, const Identifier& /*chid*/, bool /*ignoreHoles*/) const {
99
100
101 // get hit counts
102 IMuonSegmentHitSummaryTool::HitCounts hitCounts = m_hitSummaryTool->getHitCounts(seg);
103 const uint8_t nPrecHits = hitCounts.nnswHits();
105 const uint8_t nPrecEtaHits = hitCounts.nmmHits() + hitCounts.nstgcHits.netaHits;
106 const uint8_t nPrecPhiHits = hitCounts.nstgcHits.nphiHits;
107
108 const uint8_t nMM_Hits = hitCounts.nmmHits();
109 const uint8_t nSTGC_Hits = hitCounts.nstgcHits();
110 /**********************************/
111 /* cuts for quality level 0 */
112 // remove NSW segments with only 3 hits
113 if (nPrecEtaHits < 2) return -1;
114
115 /**********************************/
116 /* cuts for quality level 1 */
117
118 // remove NSW segments where both chambers have below than 4 associated hits
119 if (std::max(nMM_Hits, nSTGC_Hits) < 4) return 0;
120
121 /**********************************/
122 /* cuts for quality level 2 */
123 // require hits in both projections
124 if (nSTGC_Hits && !hitCounts.nstgcHits.hasEtaAndPhi()) return 1;
125
126 if (nMM_Hits && (!hitCounts.nmmEtaHits || !hitCounts.nmmStereoHits)) return 1;
127
128 /**********************************/
129 /* cuts for quality level 3 */
130
131 // require four hits in one of the projections and hits in the other
132 if (nPrecHits < 12 || nPrecPhiHits < 4)
133 return 2;
134
135 /**********************************/
136 /* segment has highest quality */
137 return 3;
138}
139
140int
142{
143
144
145 // get hit counts
146 IMuonSegmentHitSummaryTool::HitCounts hitCounts = m_hitSummaryTool->getHitCounts(seg);
147
148 /**********************************/
149 /* cuts for quality level 0 */
150
151 // remove segments with less than 3 mdt hits
152 if (hitCounts.nmdtHits() < 3) return -1;
153
154 // get holes
155 unsigned int nholes = !ignoreHoles ? hitCounts.nmdtHoles : 0;
156
157 // calculate hole fraction
158 double holeFraction = (double)nholes / (double)hitCounts.nmdtHits();
159
160 // check whether we expect trigger hits in the station
161 bool triggerHitRegion = hitCounts.nexpectedTrigHitLayers > 0;
162
163 ATH_MSG_DEBUG("Segment: " << m_printer->print(seg) << std::endl
164 << hitCounts.print() << " Hole frac " << holeFraction);
165
166 // only look at segments with phi hits
167 if (triggerHitRegion && hitCounts.nphiTrigHitLayers == 0) {
168
169 // reject if more holes than hits
170 if (holeFraction > 1.1) return -1;
171 }
172
173 // reject events with a good ADC fraction below the cut
174 if (hitCounts.goodADCFraction() < m_adcFractionCut) return -1;
175 if (hitCounts.nmdtHits() == 3 && hitCounts.adcMax < m_minAdcPerSegmentCut) return -1;
176
177 /**********************************/
178 /* cuts for quality level 1 */
179
180 if (!hitCounts.closeToChamberEdge) {
181
182 // reject segments with phi hits and more holes as hits
183 if (hitCounts.nphiTrigHitLayers != 0 && holeFraction > 1.1) return 0;
184
185 // // reject segments with phi hits and a hole fraction larger than 50%
186 // if( triggerHitRegion && hitCounts.nphiTrigHitLayers == 0 && holeFraction > 0.5 ) return 0;
187 }
188
189 // reject segments with more than one enclosed hole and no trigger hits
190 if (hitCounts.nphiTrigHitLayers == 0 && hitCounts.nmdtEnclosedHoles > 2) return 0;
191
192
193 /**********************************/
194 /* cuts for quality level 2 */
195
196 // reject segments with phi hits and more holes as hits
197 if (hitCounts.nphiTrigHitLayers != 0 && holeFraction > 1.1) return 1;
198
199 // reject segments with phi hits and a hole fraction larger than 50%
200 if (triggerHitRegion && hitCounts.nphiTrigHitLayers == 0 && holeFraction > 0.5) return 1;
201
202 // reject segments with more than one enclosed hole
203 if (hitCounts.nmdtEnclosedHoles > 2) return 0;
204
205 // reject all segments that have no phi hits and hits in only one multi layer
206 bool twoMultiLayerSegment = hitCounts.nmdtHitsMl1 > 1 && hitCounts.nmdtHitsMl2 > 1;
207 if (hitCounts.nphiTrigHitLayers == 0 && !twoMultiLayerSegment) return 1;
208
209
210 if (hitCounts.nphiTrigHitLayers == 0) {
211
212 // cut on segment quality
213 if (hitCounts.segmentQuality > m_cutSegmentQuality) return 1;
214
215 // tighter cut for segments with only on multi layer
216 if ((!twoMultiLayerSegment || hitCounts.nmdtHits() < 5) && hitCounts.segmentQuality > 0.5 * m_cutSegmentQuality)
217 return 1;
218 }
219
220 // cut on number of holes
221 if (hitCounts.nmdtHoles > 2) {
222 ATH_MSG_DEBUG("Failed hole cut " << hitCounts.nmdtHoles);
223 return 1;
224 }
225
226 /**********************************/
227 /* cuts for quality level 3 */
228
229 // cut on segment quality
230 if (hitCounts.segmentQuality > m_cutSegmentQuality) {
231 ATH_MSG_DEBUG("Failed quality cut" << hitCounts.segmentQuality << " cut " << m_cutSegmentQuality);
232 return 2;
233 }
234 // tighter cut for segments with only on multi layer
235 if ((!twoMultiLayerSegment || hitCounts.nmdtHits() < 5) && hitCounts.segmentQuality > 0.5 * m_cutSegmentQuality) {
236 ATH_MSG_DEBUG("Single multi layer or too few hits: quality " << hitCounts.segmentQuality << " cut "
237 << 0.5 * m_cutSegmentQuality);
238 return 2;
239 }
240
241 // reject all segments that have in only one multi layer
242 if (!twoMultiLayerSegment) {
243 ATH_MSG_DEBUG("Single multi layer");
244 return 2;
245 }
246
247 // reject segments without missing trigger layers in regions where we expect phi hits
248 if (triggerHitRegion && hitCounts.nphiTrigHitLayers < hitCounts.nexpectedTrigHitLayers) {
249 ATH_MSG_DEBUG("Missing trigger hits: phi hits " << hitCounts.nphiTrigHitLayers << " expected "
250 << hitCounts.nexpectedTrigHitLayers);
251 return 2;
252 }
253
254 /**********************************/
255 /* segment has highest quality */
256 return 3;
257}
258
259bool
260MuonSegmentSelectionTool::select(const MuonSegment& seg, bool ignoreHoles, int qualityLevel, bool useEta,
261 bool usePhi) const
262{
263 // check quality is better or equal to required level
264 return quality(seg, ignoreHoles, useEta, usePhi) >= qualityLevel;
265}
266
267} // namespace Muon
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
bool is_valid() const
Check if id is in a valid state.
PublicToolHandle< IMuonSegmentHitSummaryTool > m_hitSummaryTool
hit summary tool
ServiceHandle< IMuonEDMHelperSvc > m_edmHelperSvc
EDM Helper tool.
PublicToolHandle< MuonEDMPrinterTool > m_printer
EDM printer tool.
Gaudi::Property< int > m_minAdcPerSegmentCut
minimum value for the MDT with the highest ADC value on the segment
Gaudi::Property< double > m_adcFractionCut
cut on fraction of MDT hits above ADC cut
int quality(const MuonSegment &seg, bool ignoreHoles=false, bool useEta=true, bool usePhi=true) const
segment quality
bool select(const MuonSegment &seg, bool ignoreHoles=false, int qualityLevel=0, bool useEta=true, bool usePhi=true) const
select segment
MuonSegmentSelectionTool(const std::string &, const std::string &, const IInterface *)
int nswSegmentQuality(const MuonSegment &seg, const Identifier &chid, bool ignoreHoles) const
calculate segment quality for NSW segments
int mdtSegmentQuality(const MuonSegment &seg, bool ignoreHoles) const
calculate segment quality for MDT segments
int cscSegmentQuality(const MuonSegment &seg, bool useEta, bool usePhi) const
calculate segment quality for CSC segments
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
Gaudi::Property< double > m_cutSegmentQuality
cut on the segment quality
This is the common class for 3D segments used 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.
std::string print() const
dump content to a string
uint8_t nmdtHits() const
Returns the number of hits in both MDT layers.
uint8_t nnswHits() const
Returns the number of hits in the NSW.
uint8_t nmmHits() const
Returns the number of hits in the micromegas.
uint8_t nphiTrigHitLayers
Number of eta stereo hits.