ATLAS Offline Software
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 
29 MuonSegmentAmbiCleaner::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 
53  auto meas_keep = DataVector<const Trk::MeasurementBase>();
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 
MdtReadoutElement.h
MuonSegmentAmbiCleaner::MuonSegmentAmbiCleaner
MuonSegmentAmbiCleaner(const std::string &, const std::string &, const IInterface *)
Definition: MuonSegmentAmbiCleaner.cxx:29
Amg::MatrixX
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
Definition: EventPrimitives.h:27
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
CompetingRIOsOnTrack.h
MuonSegmentAmbiCleaner::initialize
virtual StatusCode initialize()
Definition: MuonSegmentAmbiCleaner.cxx:41
Trk::RIO_OnTrack::clone
virtual RIO_OnTrack * clone() const override=0
Pseudo-constructor, needed to avoid excessive RTTI.
Amg::Vector2D
Eigen::Matrix< double, 2, 1 > Vector2D
Definition: GeoPrimitives.h:48
AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
Muon::RpcPrepData::globalPosition
virtual const Amg::Vector3D & globalPosition() const override
Returns the global position.
Definition: RpcPrepData.h:218
Muon::TgcClusterOnTrack
Class to represent calibrated clusters formed from TGC strips.
Definition: TgcClusterOnTrack.h:46
Trk::RIO_OnTrack
Definition: RIO_OnTrack.h:70
Muon::RpcClusterOnTrack
Class to represent calibrated clusters formed from RPC strips.
Definition: RpcClusterOnTrack.h:35
MuonSegmentAmbiCleaner.h
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
MdtDriftCircleOnTrack.h
xAOD::MuonSegment
MuonSegment_v1 MuonSegment
Reference the current persistent version:
Definition: Event/xAOD/xAODMuon/xAODMuon/MuonSegment.h:13
PrepRawData.h
python.Utilities.clone
clone
Definition: Utilities.py:134
TgcClusterOnTrack.h
Muon::TgcClusterOnTrack::prepRawData
virtual const TgcPrepData * prepRawData() const
Returns the TgcPrepData - is a TRT_DriftCircle in this scope.
Definition: TgcClusterOnTrack.h:129
Trk::CompetingRIOsOnTrack::rioOnTrack
virtual const RIO_OnTrack & rioOnTrack(unsigned int) const =0
returns the RIO_OnTrack (also known as ROT) objects depending on the integer.
RpcClusterOnTrack.h
histSizes.code
code
Definition: histSizes.py:129
id2
HWIdentifier id2
Definition: LArRodBlockPhysicsV0.cxx:562
Trk::CompetingRIOsOnTrack::numberOfContainedROTs
virtual unsigned int numberOfContainedROTs() const =0
Number of RIO_OnTracks to be contained by this CompetingRIOsOnTrack.
lumiFormat.i
int i
Definition: lumiFormat.py:85
Muon::RpcPrepData
Class to represent RPC measurements.
Definition: RpcPrepData.h:35
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
IMuonClusterOnTrackCreator.h
CscClusterOnTrack.h
Trk::CompetingRIOsOnTrack
Base class for all CompetingRIOsOnTack implementations, extends the common MeasurementBase.
Definition: CompetingRIOsOnTrack.h:64
CscReadoutElement.h
MuonSegmentAmbiCleaner::m_idHelperSvc
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
Definition: MuonSegmentAmbiCleaner.h:33
test_pyathena.parent
parent
Definition: test_pyathena.py:15
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
Trk::FitQuality
Class to represent and store fit qualities from track reconstruction in terms of and number of degre...
Definition: FitQuality.h:97
DataVector< const Trk::MeasurementBase >
Trk::LocalDirection
represents the three-dimensional global direction with respect to a planar surface frame.
Definition: LocalDirection.h:81
Trk::PrepRawData
Definition: PrepRawData.h:62
Muon::RpcClusterOnTrack::prepRawData
virtual const RpcPrepData * prepRawData() const override final
Returns the RpcPrepData - is a TRT_DriftCircle in this scope.
Definition: RpcClusterOnTrack.h:127
Trk::PrepRawData::identify
Identifier identify() const
return the identifier
EventPrimitives.h
id
SG::auxid_t id
Definition: Control/AthContainers/Root/debug.cxx:227
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
RIO_OnTrack.h
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
Trk::RIO_OnTrack::prepRawData
virtual const Trk::PrepRawData * prepRawData() const =0
returns the PrepRawData (also known as RIO) object to which this RIO_OnTrack is associated.
Trk::GsfMeasurementUpdator::fitQuality
FitQualityOnSurface fitQuality(const MultiComponentState &, const MeasurementBase &)
Method for determining the chi2 of the multi-component state and the number of degrees of freedom.
Definition: GsfMeasurementUpdator.cxx:845
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
Trk::PlaneSurface
Definition: PlaneSurface.h:64
PlaneSurface.h
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
Trk::RIO_OnTrack::identify
Identifier identify() const
return the identifier -extends MeasurementBase
Definition: RIO_OnTrack.h:152
Muon::TgcPrepData
Class to represent TGC measurements.
Definition: TgcPrepData.h:32
MuonSegment.h
TgcReadoutElement.h
Muon::TgcPrepData::globalPosition
virtual const Amg::Vector3D & globalPosition() const override final
Returns the global position.
Definition: TgcPrepData.h:125
LocalDirection.h
MuonSegmentAmbiCleaner::m_summary
bool m_summary
flag to print out a summary of what comes in and what comes out
Definition: MuonSegmentAmbiCleaner.h:38
Muon::MuonSegment
Definition: MuonSpectrometer/MuonReconstruction/MuonRecEvent/MuonSegment/MuonSegment/MuonSegment.h:45
AthAlgTool
Definition: AthAlgTool.h:26
FitQuality.h
Trk::Surface::transform
const Amg::Transform3D & transform() const
Returns HepGeom::Transform3D by reference.
NSWL1::globalToLocal
Polygon globalToLocal(const Polygon &pol, float z, const Trk::PlaneSurface &surf)
Definition: GeoUtils.cxx:103
MuonSegmentAmbiCleaner::resolve
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...
Definition: MuonSegmentAmbiCleaner.cxx:49
MuonSegmentAmbiCleaner::m_debug
bool m_debug
flag to print out debugging information
Definition: MuonSegmentAmbiCleaner.h:36
NSWL1::PadTriggerAdapter::segment
Muon::NSW_PadTriggerSegment segment(const NSWL1::PadTrigger &data)
Definition: PadTriggerAdapter.cxx:5
RpcReadoutElement.h
Identifier
Definition: IdentifierFieldParser.cxx:14