ATLAS Offline Software
Loading...
Searching...
No Matches
MuonSegmentAmbiCleaner.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
6
24
25#include <sstream>
26#include <iostream>
27#include <vector>
28
29MuonSegmentAmbiCleaner::MuonSegmentAmbiCleaner(const std::string& type,const std::string& name,const IInterface* parent):AthAlgTool(type,name,parent)
30{
31 declareInterface<IMuonSegmentCleaner>(this);
32
33 m_debug = false;
34 declareProperty("DoDebug",m_debug);
35
36 m_summary = false;
37 declareProperty("DoSummary",m_summary);
38
39}
40
42{
43 ATH_MSG_VERBOSE(" MuonSegmentiAmbiCleaner::Initializing ");
44 ATH_CHECK( m_idHelperSvc.retrieve() );
45 ATH_MSG_VERBOSE("End of Initializing");
46 return StatusCode::SUCCESS;
47}
48
50{
51 ATH_MSG_VERBOSE(" Executing MuonSegmentAmbiCleanerTools ");
52
54
55// create new surface
56 Trk::PlaneSurface* psf = (segment->associatedSurface()).clone();
57 Amg::Transform3D globalToLocal = psf->transform().inverse();
58 Amg::Vector3D lSegmentPos = globalToLocal*(segment->globalPosition());
59 Amg::Vector3D lSegmentDir = globalToLocal*(segment->globalDirection());
60
61
62 const std::vector<const Trk::MeasurementBase*>& meas = segment->containedMeasurements();
63 std::vector<const Trk::MeasurementBase*>::const_iterator mit = meas.begin();
64 std::vector<const Trk::MeasurementBase*>::const_iterator mit_end = meas.end();
65 // loop over hits
66 int nphirpc = 0;
67 int nphitgc = 0;
68 int nphicsc = 0;
69 int netamdt = 0;
70 int netarpc = 0;
71 int netatgc = 0;
72 int netacsc = 0;
73
74 std::vector<const Trk::RIO_OnTrack*> rots;
75 std::vector<const Trk::CompetingRIOsOnTrack*> crots; // lookup vector to check if rot is part of competing rio. vector contains 0 if not part of competing rio
76 rots.reserve(2*meas.size()); // factor 2, to be on safe side
77 crots.reserve(2*meas.size());
78
79 for( ; mit!=mit_end;++mit ){
80
81 //dynamic cast to either rio or competingrio:
82 const Trk::RIO_OnTrack* rot = dynamic_cast<const Trk::RIO_OnTrack*>(*mit);
83 if (rot)
84 {
85 rots.push_back(rot);
86 crots.push_back(nullptr);
87 }
88
89 else
90 {
91 const Trk::CompetingRIOsOnTrack* crio = dynamic_cast<const Trk::CompetingRIOsOnTrack*>(*mit);
92 if (crio)
93 {
94 for (unsigned int i = 0; i<crio->numberOfContainedROTs(); i++)
95 {
96 rot = &crio->rioOnTrack(i);
97 rots.push_back(rot);
98 crots.push_back(crio);
99 }
100 }
101 }
102 }
103
104 unsigned int nMeas = rots.size();
105 unsigned int nphi = 0;
106
107 // Vectors for the phi hits
108 std::vector <const Trk::RIO_OnTrack*> rots_phi(nMeas);
109 std::vector <const Trk::CompetingRIOsOnTrack*> crots_phi(nMeas);
110 std::vector <const Trk::MeasurementBase*> meas_phi(nMeas);
111 std::vector <double> dis_phi(nMeas); // distance to segment
112 std::vector <int> chambercode_phi(nMeas);
113 std::vector <int> stripcode_phi(nMeas);
114 std::vector <int> ok_phi(nMeas); // 0 Not selected 1 selected/
115 std::vector <int> det_phi(nMeas); // 1 = RPC 2 = TGC /
116 std::vector <Identifier> id_phi(nMeas); // 1 = RPC 2 = TGC /
117
118 if (m_debug) std::cout << " MuonSegmentAmbiCleanerTool nMeas " << nMeas << " competing rios: " << crots.size() << std::endl;
119
120 for (unsigned int i=0; i<rots.size(); i++){
121
122 const Trk::RIO_OnTrack* rot = rots[i];
123 const Trk::PrepRawData* prd = rot->prepRawData();
124 Identifier id = prd->identify();
125 if( m_idHelperSvc->isMdt( rot->identify() ) ){
126 meas_keep.push_back(rot->clone());
127 netamdt++;
128 continue;
129 }else if( m_idHelperSvc->isRpc( rot->identify() ) ){
130 if( m_idHelperSvc->rpcIdHelper().measuresPhi(id) != 1) {
131 meas_keep.push_back(rot->clone());
132 netarpc++;
133 continue ;
134 }
135 }else if( m_idHelperSvc->isTgc( rot->identify() ) ){
136 if( m_idHelperSvc->tgcIdHelper().isStrip(id) != 1 ) {
137 meas_keep.push_back(rot->clone());
138 netatgc++;
139 continue;
140 }
141 }else if( m_idHelperSvc->isCsc( rot->identify() ) ){
142 meas_keep.push_back(rot->clone());
143 if( m_idHelperSvc->cscIdHelper().measuresPhi(id) != 1) {
144 netacsc++;
145 } else {
146 nphicsc++;
147 }
148 continue;
149 }
150
151 //add Phi Hits
152 id_phi[nphi] = id;
153 rots_phi[nphi] = rot;
154 crots_phi[nphi] = crots[i];
155 chambercode_phi[nphi] = 0;
156 stripcode_phi[nphi] = 0;
157 ok_phi[nphi] = 0;
158 det_phi[nphi] = 0;
159 dis_phi[nphi] = 10000000;
160 if (m_idHelperSvc->isRpc( rot->identify())) {
161 nphirpc++;
162 int code = 1000000*(m_idHelperSvc->rpcIdHelper().stationName(id));
163 code = code + 2*((m_idHelperSvc->rpcIdHelper().doubletR(id))-1)+16*((m_idHelperSvc->rpcIdHelper().gasGap(id))-1);
164 chambercode_phi[nphi] = code;
165 stripcode_phi[nphi] = m_idHelperSvc->rpcIdHelper().strip(id);
166 ok_phi[nphi] = 1;
167 det_phi[nphi] = 1;
168 const Muon::RpcClusterOnTrack* rrot = dynamic_cast<const Muon::RpcClusterOnTrack*>(rot);
169 if( !rrot ){
170 ATH_MSG_WARNING("This is not a RpcClusterOnTrack!!! ");
171 continue;
172 }
173 const Muon::RpcPrepData* rprd = rrot->prepRawData();
174 Amg::Vector3D gHitPos = rprd->globalPosition();
175 Amg::Vector3D lHitPos = globalToLocal*gHitPos;
176
177 // In the barrel local z is measured
178 double disRPC = lSegmentPos.z() - lHitPos.z() + lSegmentDir.z()*(lHitPos.y()-lSegmentPos.y())/lSegmentDir.y();
179 if (m_debug) {
180 std::cout << " ghit pos x " << gHitPos.x() << " y " << gHitPos.y() << " z " << gHitPos.z() << std::endl;
181 std::cout << " dis RPC " << disRPC << std::endl;
182 }
183 dis_phi[nphi] = disRPC;
184 } else if ( m_idHelperSvc->isTgc( rot->identify())) {
185 nphitgc++;
186 int code = 1000000*(m_idHelperSvc->tgcIdHelper().stationName(id))+100*(m_idHelperSvc->tgcIdHelper().stationEta(id)+10);
187 code = code + m_idHelperSvc->tgcIdHelper().gasGap(id);
188 chambercode_phi[nphi] = code;
189 stripcode_phi[nphi] = m_idHelperSvc->tgcIdHelper().channel(id);
190 ok_phi[nphi] = 1;
191 det_phi[nphi] = 2;
192
193 const Muon::TgcClusterOnTrack* rrot = dynamic_cast<const Muon::TgcClusterOnTrack*>(rot);
194 if( !rrot ){
195 ATH_MSG_WARNING("This is not a TgcClusterOnTrack!!! ");
196 continue;
197 }
198 const Muon::TgcPrepData* rprd = rrot->prepRawData();
199 Amg::Vector3D gHitPos = rprd->globalPosition();
200 Amg::Vector3D lHitPos = globalToLocal*gHitPos;
201 // In the forward local y is measured
202 double disTGC = lSegmentPos.y() - lHitPos.y() + lSegmentDir.y()*(lHitPos.z()-lSegmentPos.z())/lSegmentDir.z();
203 if (m_debug) {
204 std::cout << " ghit pos x " << gHitPos.x() << " y " << gHitPos.y() << " z " << gHitPos.z() << std::endl;
205 std::cout << " dis TGC " << disTGC << std::endl;
206 }
207 dis_phi[nphi] = disTGC;
208 } else {
209 dis_phi[nphi] = 0.;
210 }
211 if (m_debug) std::cout << " Distance to segment " << dis_phi[nphi] << std::endl;
212 if (ok_phi[nphi] == 1 ) nphi++;
213 }
214// Code to select and flag ambiguous phi hits
215
216 bool changeSegment = false;
217 int nphirpcn = 0;
218 int nphitgcn = 0;
219 if (nphi > 0) {
220 for(unsigned int i = 0; i < nphi-1 ; ++i ) {
221 if (ok_phi[i] == 0) continue;
222 for(unsigned int j = i+1 ; j < nphi ; ++j ) {
223 if (ok_phi[j] == 0) continue;
224 bool ambi = false;
225 if ( stripcode_phi[i] == stripcode_phi[j] && chambercode_phi[i] == chambercode_phi[j] ) ambi = true;
226 if ( ambi ) {
227 Identifier id1 = id_phi[i];
228 Identifier id2 = id_phi[j];
229 if (det_phi[i] == 1 && det_phi[j] == 1 && m_debug) {
230 ATH_MSG_INFO(" RPC Station 1 eta " << m_idHelperSvc->rpcIdHelper().stationEta(id1) << " phi " << m_idHelperSvc->rpcIdHelper().stationPhi(id1));
231 ATH_MSG_INFO(" RPC Station 2 eta " << m_idHelperSvc->rpcIdHelper().stationEta(id2) << " phi " << m_idHelperSvc->rpcIdHelper().stationPhi(id2));
232 }
233 if (det_phi[i] == 2 && det_phi[j] == 2 && m_debug) {
234 ATH_MSG_INFO(" TGC Station 1 eta " << m_idHelperSvc->tgcIdHelper().stationEta(id1) << " phi " << m_idHelperSvc->tgcIdHelper().stationPhi(id1));
235 ATH_MSG_INFO(" TGC Station 2 eta " << m_idHelperSvc->tgcIdHelper().stationEta(id2) << " phi " << m_idHelperSvc->tgcIdHelper().stationPhi(id2));
236 }
237
238 if (m_debug) { ATH_MSG_DEBUG(" Ambiguous " << " Distance1 " << dis_phi[i] << " Distance1 " << dis_phi[j]); }
239 if (dis_phi[i]!= 0.&& dis_phi[j]!=0) {
240 if ( fabs(dis_phi[i]) < fabs(dis_phi[j]) ) {
241 ok_phi[j] = 0;
242 } else {
243 ok_phi[i] = 0;
244 }
245 }
246 if (m_debug) {
247 if (det_phi[i] == 1) { ATH_MSG_DEBUG(" RPC Ambiguities "); }
248 if (det_phi[i] == 2) { ATH_MSG_DEBUG(" TGC Ambiguities "); }
249 ATH_MSG_DEBUG(" index " << i << " strip " << stripcode_phi [i] << " chambercode " << chambercode_phi[i] << " selected " << ok_phi[i] << " segment distance " << dis_phi[i]);
250 ATH_MSG_DEBUG(" index " << j << " strip " << stripcode_phi [j] << " chambercode " << chambercode_phi[j] << " selected " << ok_phi[j] << " segment distance " << dis_phi[j]);
251 }
252 }
253 }
254 }
255
256 // if any phi hits belonging to a competing rio is removed, remove the pointer to the competing rio and only store the single phi hit
257
258 for(unsigned int i = 0; i < nphi ; i++ ) {
259 if (ok_phi[i] == 0)
260 {
261 for(unsigned int j = 0; j < nphi ; j++ ) {
262 if (crots_phi[j] == crots_phi[i] && j!=i)
263 {
264 crots_phi[j]=nullptr;
265 }
266 }
267 crots_phi[i]=nullptr;
268 }
269 }
270
271// Put kept hits on segment
272// Put selected phi hits on segment
273
274 std::set <const Trk::CompetingRIOsOnTrack*> selected_crots;
275
276 for (unsigned int i=0;i<nphi;++i){
277 if (ok_phi[i] == 1) {
278 if (!crots_phi[i]) // not a competing measurement
279 {
280 if (det_phi[i] == 1) nphirpcn++;
281 if (det_phi[i] == 2) nphitgcn++;
282 meas_keep.push_back(rots_phi[i]->clone());
283 }
284 else if (selected_crots.count(crots_phi[i]) == 0) // competing measurement not yet added
285 {
286 meas_keep.push_back(crots_phi[i]->clone());
287 selected_crots.insert(crots_phi[i]);
288 if (det_phi[i] == 1) nphirpcn++;
289 if (det_phi[i] == 2) nphitgcn++;
290 }
291 } if (ok_phi[i] == 0 && (det_phi[i] == 1||det_phi[i] == 2)) {
292 changeSegment = true;
293 }
294 }
295 }
296
297 if ((m_summary&&changeSegment)||m_debug) {
298 std::cout << " Summary MuonSegmentAmbiCleaner (not accurate with competing rios!)" << std::endl;
299 std::cout << " Input Segment with " << netamdt << " MDT hits " << netacsc << " eta CSC hits " << netatgc << " eta TGC Hits " << netarpc << " eta RPC hits " << std::endl;
300 std::cout << " and " << nphicsc << " phi CSC hits " << nphitgc << " phi TGC Hits " << nphirpc << " phi RPC hits " << std::endl;
301 std::cout << " Output after Ambiguity removal " << nphitgcn << " phi TGC Hits " << nphirpcn << " phi RPC hits " << std::endl;
302 }
303
304 // Make new segment with cleaned up rios
305// MuonSegment( const Trk::LocalPosition& segLocPos, // 2 local position coordinates
306// const Trk::LocalDirection* segLocDir, // 2 local direction coordinates
307// const Trk::ErrorMatrix* segLocalErr, // 4 x 4 full local error
308// Trk::PlaneSurface* psf, // plane surface to define frame
309// std::vector<const Trk::RIO_OnTrack*>* crots, // vector of contained rios on track
310// Trk::FitQuality* fqual);
311
312
313 const Trk::LocalDirection locSegmentDir(segment->localDirection());
314 Amg::Vector2D locSegmentPos(lSegmentPos.x(),lSegmentPos.y());
315 Trk::FitQuality* fitQuality = segment->fitQuality()->clone();
316 Muon::MuonSegment* newSegment = new Muon::MuonSegment(locSegmentPos,
317 locSegmentDir,
318 Amg::MatrixX(segment->localCovariance()),
319 psf,
320 std::move(meas_keep),
321 fitQuality);
322
323 return newSegment;
324} // execute
325
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
HWIdentifier id2
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)
Derived DataVector<T>.
Definition DataVector.h:795
bool m_debug
flag to print out debugging information
MuonSegmentAmbiCleaner(const std::string &, const std::string &, const IInterface *)
virtual StatusCode initialize()
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
bool m_summary
flag to print out a summary of what comes in and what comes out
virtual const Muon::MuonSegment * resolve(const Muon::MuonSegment *segment) const
For one segment solve ambiguous RPC and TGC hits: different eta but same phi using the MDT extrapolat...
This is the common class for 3D segments used in the muon spectrometer.
virtual const Amg::Vector3D & globalPosition() const override final
global position
virtual const Trk::PlaneSurface & associatedSurface() const override final
returns the surface for the local to global transformation
Class to represent calibrated clusters formed from RPC strips.
virtual const RpcPrepData * prepRawData() const override final
Returns the RpcPrepData - is a TRT_DriftCircle in this scope.
Class to represent RPC measurements.
Definition RpcPrepData.h:35
virtual const Amg::Vector3D & globalPosition() const override
Returns the global position.
Class to represent calibrated clusters formed from TGC strips.
virtual const TgcPrepData * prepRawData() const
Returns the TgcPrepData - is a TRT_DriftCircle in this scope.
Class to represent TGC measurements.
Definition TgcPrepData.h:32
virtual const Amg::Vector3D & globalPosition() const override final
Returns the global position.
Base class for all CompetingRIOsOnTack implementations, extends the common MeasurementBase.
virtual unsigned int numberOfContainedROTs() const =0
Number of RIO_OnTracks to be contained by this CompetingRIOsOnTrack.
virtual const RIO_OnTrack & rioOnTrack(unsigned int) const =0
returns the RIO_OnTrack (also known as ROT) objects depending on the integer.
Class to represent and store fit qualities from track reconstruction in terms of and number of degre...
Definition FitQuality.h:97
virtual FitQuality * clone() const
Virtual constructor.
represents the three-dimensional global direction with respect to a planar surface frame.
const Amg::MatrixX & localCovariance() const
Interface method to get the localError.
Class for a planaer rectangular or trapezoidal surface in the ATLAS detector.
virtual PlaneSurface * clone() const override
Virtual constructor.
Identifier identify() const
return the identifier
Class to handle RIO On Tracks ROT) for InDet and Muons, it inherits from the common MeasurementBase.
Definition RIO_OnTrack.h:70
virtual RIO_OnTrack * clone() const override=0
Pseudo-constructor, needed to avoid excessive RTTI.
virtual const Trk::PrepRawData * prepRawData() const =0
returns the PrepRawData (also known as RIO) object to which this RIO_OnTrack is associated.
Identifier identify() const
return the identifier -extends MeasurementBase
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
const Amg::Transform3D & transform() const
Returns HepGeom::Transform3D by reference.
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D