CMS 3D CMS Logo

FWMuonBuilder.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: Muons
4 // Class : FWMuonBuilder
5 //
6 
7 #include "TEveVSDStructs.h"
8 #include "TEveTrack.h"
9 #include "TEveStraightLineSet.h"
10 #include "TEveGeoNode.h"
11 #include "TGeoArb8.h"
12 
18 
20 
23 
26 
30 
31 namespace {
32 std::vector<TEveVector> getRecoTrajectoryPoints( const reco::Muon* muon,
33  const FWEventItem* iItem )
34 {
35  std::vector<TEveVector> points;
36  const FWGeometry* geom = iItem->getGeom();
37 
38  float localTrajectoryPoint[3];
39  float globalTrajectoryPoint[3];
40 
41  const std::vector<reco::MuonChamberMatch>& matches = muon->matches();
42  for( std::vector<reco::MuonChamberMatch>::const_iterator chamber = matches.begin(),
43  chamberEnd = matches.end();
44  chamber != chamberEnd; ++chamber )
45  {
46  // expected track position
47  localTrajectoryPoint[0] = chamber->x;
48  localTrajectoryPoint[1] = chamber->y;
49  localTrajectoryPoint[2] = 0;
50 
51  unsigned int rawid = chamber->id.rawId();
52  if( geom->contains( rawid ))
53  {
54  geom->localToGlobal( rawid, localTrajectoryPoint, globalTrajectoryPoint );
55  points.push_back( TEveVector(globalTrajectoryPoint[0],
56  globalTrajectoryPoint[1],
57  globalTrajectoryPoint[2] ));
58  }
59  }
60  return points;
61 }
62 
63 //______________________________________________________________________________
64 
65 void addMatchInformation( const reco::Muon* muon,
67  TEveElement* parentList,
68  bool showEndcap )
69 {
70  std::set<unsigned int> ids;
71  const FWGeometry* geom = pb->context().getGeom();
72 
73  const std::vector<reco::MuonChamberMatch>& matches = muon->matches();
74 
75  //need to use auto_ptr since the segmentSet may not be passed to muonList
76  std::unique_ptr<TEveStraightLineSet> segmentSet( new TEveStraightLineSet );
77  // FIXME: This should be set elsewhere.
78  segmentSet->SetLineWidth( 4 );
79 
80  for( std::vector<reco::MuonChamberMatch>::const_iterator chamber = matches.begin(),
81  chambersEnd = matches.end();
82  chamber != chambersEnd; ++chamber )
83  {
84  unsigned int rawid = chamber->id.rawId();
85  float segmentLength = 0.0;
86  float segmentLimit = 0.0;
87 
88  if( geom->contains( rawid ))
89  {
90  TEveGeoShape* shape = geom->getEveShape( rawid );
91  shape->SetElementName( "Chamber" );
92  shape->RefMainTrans().Scale( 0.999, 0.999, 0.999 );
93 
94  FWGeometry::IdToInfoItr det = geom->find( rawid );
95  if( det->shape[0] == 1 ) // TGeoTrap
96  {
97  segmentLength = det->shape[3];
98  segmentLimit = det->shape[4];
99  }
100  else if( det->shape[0] == 2 ) // TGeoBBox
101  {
102  segmentLength = det->shape[3];
103  }
104  else
105  {
106  const double segmentLength = 15;
107  fwLog( fwlog::kWarning ) << Form("FWMuonBuilder: unknown shape type in muon chamber with detId=%d. Setting segment length to %.0f cm.\n", rawid, segmentLength);
108  }
109 
110  if( ids.insert( rawid ).second && // ensure that we add same chamber only once
111  ( chamber->detector() != MuonSubdetId::CSC || showEndcap ))
112  {
113  pb->setupAddElement( shape, parentList );
114  }
115 
116  for( std::vector<reco::MuonSegmentMatch>::const_iterator segment = chamber->segmentMatches.begin(),
117  segmentEnd = chamber->segmentMatches.end();
118  segment != segmentEnd; ++segment )
119  {
120  float segmentPosition[3] = { segment->x, segment->y, 0.0 };
121  float segmentDirection[3] = { segment->dXdZ, segment->dYdZ, 0.0 };
122 
123  float localSegmentInnerPoint[3];
124  float localSegmentOuterPoint[3];
125 
126  fireworks::createSegment( chamber->detector(), true,
127  segmentLength, segmentLimit,
128  segmentPosition, segmentDirection,
129  localSegmentInnerPoint, localSegmentOuterPoint );
130 
131  float globalSegmentInnerPoint[3];
132  float globalSegmentOuterPoint[3];
133 
134  geom->localToGlobal( *det, localSegmentInnerPoint, globalSegmentInnerPoint );
135  geom->localToGlobal( *det, localSegmentOuterPoint, globalSegmentOuterPoint );
136 
137  segmentSet->AddLine( globalSegmentInnerPoint[0], globalSegmentInnerPoint[1], globalSegmentInnerPoint[2],
138  globalSegmentOuterPoint[0], globalSegmentOuterPoint[1], globalSegmentOuterPoint[2] );
139  }
140  }
141  }
142 
143  if( !matches.empty() )
144  pb->setupAddElement( segmentSet.release(), parentList );
145 }
146 
147 //______________________________________________________________________________
148 
149 bool
150 buggyMuon( const reco::Muon* muon,
151  const FWGeometry* geom )
152 {
153  if( !muon->standAloneMuon().isAvailable() ||
154  !muon->standAloneMuon()->extra().isAvailable())
155  return false;
156 
157  float localTrajectoryPoint[3];
158  float globalTrajectoryPoint[3];
159 
160  const std::vector<reco::MuonChamberMatch>& matches = muon->matches();
161  for( std::vector<reco::MuonChamberMatch>::const_iterator chamber = matches.begin(),
162  chamberEnd = matches.end();
163  chamber != chamberEnd; ++chamber )
164  {
165  // expected track position
166  localTrajectoryPoint[0] = chamber->x;
167  localTrajectoryPoint[1] = chamber->y;
168  localTrajectoryPoint[2] = 0;
169 
170  unsigned int rawid = chamber->id.rawId();
171  if( geom->contains( rawid ))
172  {
173  geom->localToGlobal( rawid, localTrajectoryPoint, globalTrajectoryPoint );
174  double phi = atan2( globalTrajectoryPoint[1], globalTrajectoryPoint[0] );
175  if( cos( phi - muon->standAloneMuon()->innerPosition().phi()) < 0 )
176  return true;
177  }
178  }
179  return false;
180 }
181 
182 TEveTrack* prepareMuonTrackWithExtraPoints(const reco::Track& track,
183  TEveTrackPropagator* propagator,
184  const std::vector<TEveVector>& extraPoints )
185 {
186  TEveRecTrack t;
187  t.fBeta = 1.;
188  t.fSign = track.charge();
189  t.fV.Set(track.vx(), track.vy(), track.vz());
190  t.fP.Set(track.px(), track.py(), track.pz());
191  // t.fSign = muon->charge();
192  // t.fV.Set(muon->vx(), muon->vy(), muon->vz());
193  // t.fP.Set(muon->px(), muon->py(), muon->pz());
194  TEveTrack* trk = new TEveTrack( &t, propagator );
195  size_t n = extraPoints.size();
196 
197  if (n > 1) {
198  int lastDaughter = n-2;
199  for (int i = 0; i <= lastDaughter; ++i)
200  trk->AddPathMark( TEvePathMark( TEvePathMark::kDaughter, extraPoints[i] ) );
201  }
202  trk->AddPathMark( TEvePathMark( TEvePathMark::kDecay, extraPoints.back() ) );
203  return trk;
204 }
205 
206 
207 }
208 
209 //
210 // constructors and destructor
211 //
213 {
214 }
215 
217 {
218 }
219 
220 //
221 // member functions
222 //
223 //______________________________________________________________________________
224 
225 void
227 {
228  // if auto field estimation mode, do extra loop over muons.
229  // use both inner and outer track if available
230  if( field->getSource() == FWMagField::kNone )
231  {
232  if( fabs( iData.eta() ) > 2.0 || iData.pt() < 3 ) return;
233  if( iData.innerTrack().isAvailable())
234  {
235  double estimate = fw::estimate_field( *( iData.innerTrack()), true );
236  if( estimate >= 0 ) field->guessField( estimate );
237  }
238  if( iData.outerTrack().isAvailable() )
239  {
240  double estimate = fw::estimate_field( *( iData.outerTrack()));
241  if( estimate >= 0 ) field->guessFieldIsOn( estimate > 0.5 );
242  }
243  }
244 }
245 
246 //______________________________________________________________________________
247 
248 void
250  const reco::Muon* muon,
251  TEveElement* tList,
252  bool showEndcap,
253  bool tracksOnly )
254 {
255  calculateField( *muon, pb->context().getField());
256 
257  TEveRecTrack recTrack;
258  recTrack.fBeta = 1.;
259 
260  // If we deal with a tracker muon we use the inner track and guide it
261  // through the trajectory points from the reconstruction. Segments
262  // represent hits. Matching between hits and the trajectory shows
263  // how well the inner track matches with the muon hypothesis.
264  //
265  // In other cases we use a global muon track with a few states from
266  // the inner and outer tracks or just the outer track if it's the
267  // only option
268 
269  if( muon->isTrackerMuon() &&
270  muon->innerTrack().isAvailable() &&
271  muon->isMatchesValid() &&
272  !buggyMuon( &*muon, pb->context().getGeom()))
273  {
274  TEveTrack* trk = fireworks::prepareTrack( *(muon->innerTrack()),
276  getRecoTrajectoryPoints( muon, pb->item()));
277  trk->MakeTrack();
278  trk->SetLineWidth(m_lineWidth);
279  pb->setupAddElement( trk, tList );
280  if( ! tracksOnly )
281  addMatchInformation( &(*muon), pb, tList, showEndcap );
282  return;
283  }
284 
285  if( muon->isGlobalMuon() &&
286  muon->globalTrack().isAvailable())
287  {
288  std::vector<TEveVector> extraPoints;
289  if( muon->innerTrack().isAvailable() && muon->innerTrack()->extra().isAvailable())
290  {
291  extraPoints.push_back( TEveVector( muon->innerTrack()->innerPosition().x(),
292  muon->innerTrack()->innerPosition().y(),
293  muon->innerTrack()->innerPosition().z()));
294  extraPoints.push_back( TEveVector( muon->innerTrack()->outerPosition().x(),
295  muon->innerTrack()->outerPosition().y(),
296  muon->innerTrack()->outerPosition().z()));
297  }
298  if( muon->outerTrack().isAvailable() && muon->outerTrack()->extra().isAvailable())
299  {
300  extraPoints.push_back( TEveVector( muon->outerTrack()->innerPosition().x(),
301  muon->outerTrack()->innerPosition().y(),
302  muon->outerTrack()->innerPosition().z()));
303  extraPoints.push_back( TEveVector( muon->outerTrack()->outerPosition().x(),
304  muon->outerTrack()->outerPosition().y(),
305  muon->outerTrack()->outerPosition().z()));
306  }
307  TEveTrack* trk = nullptr;
308  if (extraPoints.empty())
310  else
311  trk = prepareMuonTrackWithExtraPoints(*( muon->globalTrack()),pb->context().getMuonTrackPropagator(), extraPoints);
312 
313  trk->MakeTrack();
314  trk->SetLineWidth(m_lineWidth);
315  pb->setupAddElement( trk, tList );
316  return;
317  }
318 
319  if( muon->innerTrack().isAvailable())
320  {
321  TEveTrack* trk = fireworks::prepareTrack( *( muon->innerTrack()), pb->context().getMuonTrackPropagator());
322  trk->MakeTrack();
323  pb->setupAddElement( trk, tList );
324  return;
325  }
326 
327  if( muon->outerTrack().isAvailable())
328  {
329  TEveTrack* trk = fireworks::prepareTrack( *( muon->outerTrack()), pb->context().getMuonTrackPropagator());
330  trk->MakeTrack();
331  trk->SetLineWidth(m_lineWidth);
332  pb->setupAddElement( trk, tList );
333  return;
334  }
335 
336  // if got that far it means we have nothing but a candidate
337  // show it anyway.
338  TEveTrack* trk = fireworks::prepareCandidate( *muon, pb->context().getMuonTrackPropagator());
339  trk->MakeTrack();
340  trk->SetLineWidth(m_lineWidth);
341  pb->setupAddElement( trk, tList );
342 }
bool isAvailable() const
Definition: Ref.h:577
const fireworks::Context & context() const
double eta() const final
momentum pseudorapidity
TEveTrack * prepareTrack(const reco::Track &track, TEveTrackPropagator *propagator, const std::vector< TEveVector > &extraRefPoints=std::vector< TEveVector >())
Definition: TrackUtils.cc:63
virtual TrackRef innerTrack() const
Definition: Muon.h:48
IdToInfoItr find(unsigned int) const
Definition: FWGeometry.cc:508
const FWGeometry * getGeom() const
Definition: Context.h:83
void setupAddElement(TEveElement *el, TEveElement *parent, bool set_color=true) const
double pt() const final
transverse momentum
bool isMatchesValid() const
Definition: Muon.h:142
void buildMuon(FWProxyBuilderBase *, const reco::Muon *muon, TEveElement *tList, bool showEndcap, bool onlyTracks=false)
virtual ~FWMuonBuilder()
double px() const
x coordinate of momentum vector
Definition: TrackBase.h:660
const FWEventItem * item() const
double estimate_field(const reco::Track &track, bool highQuality=false)
bool isTrackerMuon() const override
Definition: Muon.h:277
void calculateField(const reco::Muon &iData, FWMagField *field)
static const int CSC
Definition: MuonSubdetId.h:13
void createSegment(int detector, bool matchedSegment, float segmentLength, float segmentLimit, float *segmentPosition, float *segmentDirection, float *segmentInnerPoint, float *segmentOuterPoint)
Definition: SegmentUtils.cc:10
FWMagField * getField() const
Definition: Context.h:77
TEveGeoShape * getEveShape(unsigned int id) const
Definition: FWGeometry.cc:298
bool isGlobalMuon() const override
Definition: Muon.h:276
void guessField(float estimate) const
Definition: FWMagField.cc:155
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
void localToGlobal(unsigned int id, const float *local, float *global, bool translatep=true) const
Definition: FWGeometry.cc:478
bool contains(unsigned int id) const
Definition: FWGeometry.h:117
ESource getSource() const
Definition: FWMagField.h:33
virtual TrackRef outerTrack() const
reference to Track reconstructed in the muon detector only
Definition: Muon.h:51
TEveTrackPropagator * getMuonTrackPropagator() const
Definition: Context.h:75
TrackRef standAloneMuon() const override
reference to a stand-alone muon Track
Definition: Muon.h:52
double pz() const
z coordinate of momentum vector
Definition: TrackBase.h:672
double vz() const
z coordinate of the reference point on track
Definition: TrackBase.h:702
#define fwLog(_level_)
Definition: fwLog.h:50
std::vector< MuonChamberMatch > & matches()
get muon matching information
Definition: Muon.h:144
TEveTrack * prepareCandidate(const reco::Candidate &track, TEveTrackPropagator *propagator)
double vy() const
y coordinate of the reference point on track
Definition: TrackBase.h:696
void guessFieldIsOn(bool guess) const
Definition: FWMagField.cc:148
int charge() const
track electric charge
Definition: TrackBase.h:600
std::vector< FWGeometry::GeomDetInfo >::const_iterator IdToInfoItr
Definition: FWGeometry.h:114
const FWGeometry * getGeom() const
Definition: FWEventItem.cc:683
double py() const
y coordinate of momentum vector
Definition: TrackBase.h:666
double vx() const
x coordinate of the reference point on track
Definition: TrackBase.h:690
virtual TrackRef globalTrack() const
reference to Track reconstructed in both tracked and muon detector
Definition: Muon.h:54