CMS 3D CMS Logo

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