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