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