CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
StandAloneTrajectoryBuilder.cc
Go to the documentation of this file.
1 
13 
19 
23 
27 
29 
37 
38 using namespace edm;
39 using namespace std;
40 
42  const MuonServiceProxy* service,
44  : theService(service) {
45  const std::string metname = "Muon|RecoMuon|StandAloneMuonTrajectoryBuilder";
46 
47  LogTrace(metname) << "constructor called" << endl;
48 
49  // The navigation type:
50  // "Direct","Standard"
51  theNavigationType = par.getParameter<string>("NavigationType");
52 
53  // The inward-outward fitter (starts from seed state)
54  ParameterSet filterPSet = par.getParameter<ParameterSet>("FilterParameters");
55  filterPSet.addParameter<string>("NavigationType", theNavigationType);
56  theFilter = std::make_unique<StandAloneMuonFilter>(filterPSet, theService, iC);
57 
58  // Fit direction
59  string seedPosition = par.getParameter<string>("SeedPosition");
60 
61  if (seedPosition == "in")
63  else if (seedPosition == "out")
65  else
66  throw cms::Exception("StandAloneMuonFilter constructor")
67  << "Wrong seed position chosen in StandAloneMuonFilter::StandAloneMuonFilter ParameterSet"
68  << "\n"
69  << "Possible choices are:"
70  << "\n"
71  << "SeedPosition = in or SeedPosition = out";
72 
73  // Propagator for the seed extrapolation
74  theSeedPropagatorName = par.getParameter<string>("SeedPropagator");
75 
76  // Disable/Enable the backward filter
77  doBackwardFilter = par.getParameter<bool>("DoBackwardFilter");
78 
79  // Disable/Enable the refit of the trajectory
80  doRefit = par.getParameter<bool>("DoRefit");
81 
82  // Disable/Enable the refit of the trajectory seed
83  doSeedRefit = par.getParameter<bool>("DoSeedRefit");
84 
85  if (doBackwardFilter) {
86  // The outward-inward fitter (starts from theFilter outermost state)
87  ParameterSet bwFilterPSet = par.getParameter<ParameterSet>("BWFilterParameters");
88  // theBWFilter = new StandAloneMuonBackwardFilter(bwFilterPSet,theService); // FIXME
89  bwFilterPSet.addParameter<string>("NavigationType", theNavigationType);
90  theBWFilter = std::make_unique<StandAloneMuonFilter>(bwFilterPSet, theService, iC);
91 
92  theBWSeedType = bwFilterPSet.getParameter<string>("BWSeedType");
93  }
94 
95  if (doRefit) {
96  // The outward-inward fitter (starts from theBWFilter innermost state)
97  ParameterSet refitterPSet = par.getParameter<ParameterSet>("RefitterParameters");
98  theRefitter = std::make_unique<StandAloneMuonRefitter>(refitterPSet, iC, theService);
99  }
100 
101  // The seed transformer (used to refit the seed and get the seed transient state)
102  // ParameterSet seedTransformerPSet = par.getParameter<ParameterSet>("SeedTransformerParameters");
103  ParameterSet seedTransformerParameters = par.getParameter<ParameterSet>("SeedTransformerParameters");
104  theSeedTransformer = std::make_unique<SeedTransformer>(seedTransformerParameters, iC);
105 }
106 
108  theFilter->setEvent(event);
109  if (doBackwardFilter)
110  theBWFilter->setEvent(event);
111 }
112 
114  LogTrace("Muon|RecoMuon|StandAloneMuonTrajectoryBuilder")
115  << "StandAloneMuonTrajectoryBuilder destructor called" << endl;
116 }
117 
118 namespace {
119  struct Resetter {
121  explicit Resetter(StandAloneMuonFilter* imf) : mf(imf) {}
122  ~Resetter() {
123  if (mf)
124  mf->reset();
125  }
126  };
127 } // namespace
128 
130  Resetter fwReset(filter());
131  Resetter bwReset(bwfilter());
132 
133  const std::string metname = "Muon|RecoMuon|StandAloneMuonTrajectoryBuilder";
135 
136  // Set the services for the seed transformer
137  theSeedTransformer->setServices(theService->eventSetup());
138 
139  // the trajectory container. In principle starting from one seed we can
140  // obtain more than one trajectory. TODO: this feature is not yet implemented!
141  TrajectoryContainer trajectoryContainer;
142 
144  Trajectory trajectoryFW(seed, fwDirection);
145 
146  TrajectoryStateOnSurface lastTSOS;
147  DetId lastDetId;
148 
149  vector<Trajectory> seedTrajectories;
150 
151  if (doSeedRefit) {
152  seedTrajectories = theSeedTransformer->seedTransform(seed);
153  if (!seedTrajectories.empty()) {
154  TrajectoryMeasurement lastTM(seedTrajectories.front().lastMeasurement());
155  lastTSOS = lastTM.updatedState();
156  lastDetId = lastTM.recHit()->geographicalId();
157  }
158  }
159 
160  if (!doSeedRefit || seedTrajectories.empty()) {
161  lastTSOS = theSeedTransformer->seedTransientState(seed);
162  lastDetId = seed.startingState().detId();
163  }
164 
165  LogTrace(metname) << "Trajectory State on Surface before the extrapolation" << endl;
166  LogTrace(metname) << debug.dumpTSOS(lastTSOS);
167 
168  // Segment layer
169  LogTrace(metname) << "The RecSegment relies on: " << endl;
170  LogTrace(metname) << debug.dumpMuonId(lastDetId);
171 
172  DetLayerWithState inputFromSeed = propagateTheSeedTSOS(lastTSOS, lastDetId);
173 
174  // refine the FTS given by the seed
175 
176  // the trajectory is filled in the refitter::refit
177  filter()->refit(inputFromSeed.second, inputFromSeed.first, trajectoryFW);
178 
179  // "0th order" check...
180  if (trajectoryFW.empty()) {
181  LogTrace(metname) << "Forward trajectory EMPTY! No trajectory will be loaded!" << endl;
182  return trajectoryContainer;
183  }
184 
185  // Get the last TSOS
186  // TrajectoryStateOnSurface tsosAfterRefit = filter()->lastUpdatedTSOS(); // this is the last UPDATED TSOS
187  TrajectoryStateOnSurface tsosAfterRefit = filter()->lastCompatibleTSOS(); // this is the last COMPATIBLE TSOS
188 
189  LogTrace(metname) << "StandAloneMuonTrajectoryBuilder filter output " << endl;
190  LogTrace(metname) << debug.dumpTSOS(tsosAfterRefit);
191 
192  /*
193  // -- 1st attempt
194  if( filter()->isCompatibilitySatisfied() ) {
195  if( filter()->layers().size() ) // OR if( filter()->goodState() ) ??? Maybe when only RPC hits are used...
196  LogTrace(metname) << debug.dumpLayer( filter()->lastDetLayer() );
197  else {
198  LogTrace(metname) << "Compatibility satisfied, but all RecHits are invalid! A trajectory with only invalid hits will be loaded!" << endl;
199  trajectoryContainer.push_back(new Trajectory(trajectoryFW));
200  return trajectoryContainer;
201  }
202  }
203  else {
204  LogTrace(metname) << "Compatibility NOT satisfied after Forward filter! No trajectory will be loaded!" << endl;
205  LogTrace(metname) << "Total chambers: " << filter()->getTotalCompatibleChambers() << "; DT: "
206  << filter()->getDTCompatibleChambers() << "; CSC: " << filter()->getCSCCompatibleChambers() << endl;
207  return trajectoryContainer;
208  }
209  // -- end 1st attempt
210  */
211 
212  // -- 2nd attempt
213  if (filter()->goodState()) {
214  LogTrace(metname) << debug.dumpLayer(filter()->lastDetLayer());
215  } else if (filter()->isCompatibilitySatisfied()) {
216  int foundValidRh = trajectoryFW.foundHits(); // number of valid hits
217  LogTrace(metname) << "Compatibility satisfied after Forward filter, but too few valid RecHits (" << foundValidRh
218  << ")." << endl
219  << "A trajectory with only invalid RecHits will be loaded!" << endl;
220  if (!foundValidRh) {
221  trajectoryContainer.push_back(std::make_unique<Trajectory>(trajectoryFW));
222  return trajectoryContainer;
223  }
224  Trajectory defaultTraj(seed, fwDirection);
225  filter()->createDefaultTrajectory(trajectoryFW, defaultTraj);
226  trajectoryContainer.push_back(std::make_unique<Trajectory>(defaultTraj));
227  return trajectoryContainer;
228  } else {
229  LogTrace(metname) << "Compatibility NOT satisfied after Forward filter! No trajectory will be loaded!" << endl;
230  LogTrace(metname) << "Total compatible chambers: " << filter()->getTotalCompatibleChambers()
231  << "; DT: " << filter()->getDTCompatibleChambers()
232  << "; CSC: " << filter()->getCSCCompatibleChambers()
233  << "; RPC: " << filter()->getRPCCompatibleChambers()
234  << "; GEM: " << filter()->getGEMCompatibleChambers()
235  << "; ME0: " << filter()->getME0CompatibleChambers() << endl;
236  return trajectoryContainer;
237  }
238  // -- end 2nd attempt
239 
240  LogTrace(metname) << "Number of DT/CSC/RPC/GEM/ME0 chamber used (fw): " << filter()->getDTChamberUsed() << "/"
241  << filter()->getCSCChamberUsed() << "/" << filter()->getRPCChamberUsed() << "/"
242  << filter()->getGEMChamberUsed() << "/" << filter()->getME0ChamberUsed() << endl;
243  LogTrace(metname) << "Momentum: " << tsosAfterRefit.freeState()->momentum();
244 
245  if (!doBackwardFilter) {
246  LogTrace(metname) << "Only forward refit requested. No backward refit will be performed!" << endl;
247 
248  // ***** Refit of fwd step *****
249  // if (doRefit && !trajectoryFW.empty() && filter()->goodState()){ // CHECK!!! Can trajectoryFW really be empty at this point??? And goodState...?
250  if (doRefit) {
251  pair<bool, Trajectory> refitResult = refitter()->refit(trajectoryFW);
252  if (refitResult.first) {
253  trajectoryContainer.push_back(std::make_unique<Trajectory>(refitResult.second));
254  LogTrace(metname) << "StandAloneMuonTrajectoryBuilder refit output " << endl;
255  LogTrace(metname) << debug.dumpTSOS(refitResult.second.lastMeasurement().updatedState());
256  } else
257  trajectoryContainer.push_back(std::make_unique<Trajectory>(trajectoryFW));
258  } else
259  trajectoryContainer.push_back(std::make_unique<Trajectory>(trajectoryFW));
260 
261  LogTrace(metname) << "Trajectory saved" << endl;
262  return trajectoryContainer;
263  }
264 
265  // ***** Backward filtering *****
266 
267  TrajectorySeed seedForBW;
268 
269  if (theBWSeedType == "noSeed") {
270  } else if (theBWSeedType == "fromFWFit") {
272  tsosAfterRefit, trajectoryFW.lastMeasurement().recHit()->geographicalId().rawId());
273 
274  edm::OwnVector<TrackingRecHit> recHitsContainer;
276  TrajectorySeed fwFit(seedTSOS, recHitsContainer, seedDirection);
277 
278  seedForBW = fwFit;
279  } else if (theBWSeedType == "fromGenerator") {
280  seedForBW = seed;
281  } else
282  LogWarning(metname) << "Wrong seed type for the backward filter!";
283 
285  Trajectory trajectoryBW(seedForBW, bwDirection);
286 
287  // FIXME! under check!
288  bwfilter()->refit(tsosAfterRefit, filter()->lastDetLayer(), trajectoryBW);
289 
290  // Get the last TSOS
291  TrajectoryStateOnSurface tsosAfterBWRefit = bwfilter()->lastUpdatedTSOS();
292 
293  LogTrace(metname) << "StandAloneMuonTrajectoryBuilder BW filter output " << endl;
294  LogTrace(metname) << debug.dumpTSOS(tsosAfterBWRefit);
295 
296  LogTrace(metname) << "Number of RecHits: " << trajectoryBW.foundHits() << "\n"
297  << "Number of DT/CSC/RPC/GEM/ME0 chamber used (bw): " << bwfilter()->getDTChamberUsed() << "/"
298  << bwfilter()->getCSCChamberUsed() << "/" << bwfilter()->getRPCChamberUsed() << "/"
299  << bwfilter()->getGEMChamberUsed() << "/" << bwfilter()->getME0ChamberUsed();
300 
301  // -- The trajectory is "good" if there are at least 2 chambers used in total and at
302  // least 1 is "tracking" (DT or CSC)
303  // -- The trajectory satisfies the "compatibility" requirements if there are at least
304  // 2 compatible chambers (not necessarily used!) in total and at
305  // least 1 is "tracking" (DT or CSC)
306  // 1st attempt
307  /*
308  if (bwfilter()->isCompatibilitySatisfied()) {
309 
310  if (doRefit && !trajectoryBW.empty() && bwfilter()->goodState()){
311  pair<bool,Trajectory> refitResult = refitter()->refit(trajectoryBW);
312  if (refitResult.first){
313  trajectoryContainer.push_back(new Trajectory(refitResult.second));
314  LogTrace(metname) << "StandAloneMuonTrajectoryBuilder Refit output " << endl;
315  LogTrace(metname) << debug.dumpTSOS(refitResult.second.lastMeasurement().updatedState());
316  }
317  else
318  trajectoryContainer.push_back(new Trajectory(trajectoryBW));
319  }
320  else
321  trajectoryContainer.push_back(new Trajectory(trajectoryBW));
322 
323  LogTrace(metname)<< "Trajectory saved" << endl;
324 
325  }
326  //if the trajectory is not saved, but at least two chamber are used in the
327  //forward filtering, try to build a new trajectory starting from the old
328  //trajectory w/o the latest measurement and a looser chi2 cut
329  else if ( filter()->getTotalChamberUsed() >= 2 ) {
330  LogTrace(metname)<< "Trajectory NOT saved. Second Attempt." << endl;
331  // FIXME:
332  // a better choice could be: identify the poorest one, exclude it, redo
333  // the fw and bw filtering. Or maybe redo only the bw without the excluded
334  // measure. As first step I will port the ORCA algo, then I will move to the
335  // above pattern.
336 
337  }
338 
339  else {
340  LogTrace(metname) << "Compatibility NOT satisfied after Backward filter!" << endl;
341  LogTrace(metname) << "The result of Forward filter will be loaded!" << endl;
342 
343  trajectoryContainer.push_back(new Trajectory(trajectoryFW));
344  }
345  */
346  // end 1st attempt
347 
348  // 2nd attempt
349  if (bwfilter()->goodState()) {
350  LogTrace(metname) << debug.dumpLayer(bwfilter()->lastDetLayer());
351  } else if (bwfilter()->isCompatibilitySatisfied()) {
352  LogTrace(metname) << "Compatibility satisfied after Backward filter, but too few valid RecHits ("
353  << trajectoryBW.foundHits() << ")." << endl
354  << "The (good) result of FW filter will be loaded!" << endl;
355  trajectoryContainer.push_back(std::make_unique<Trajectory>(trajectoryFW));
356  return trajectoryContainer;
357  } else {
358  LogTrace(metname) << "Compatibility NOT satisfied after Backward filter!" << endl
359  << "The Forward trajectory will be invalidated and then loaded!" << endl;
360  Trajectory defaultTraj(seed, fwDirection);
361  filter()->createDefaultTrajectory(trajectoryFW, defaultTraj);
362  trajectoryContainer.push_back(std::make_unique<Trajectory>(defaultTraj));
363  return trajectoryContainer;
364  }
365  // end 2nd attempt
366 
367  if (doRefit) {
368  pair<bool, Trajectory> refitResult = refitter()->refit(trajectoryBW);
369  if (refitResult.first) {
370  trajectoryContainer.push_back(std::make_unique<Trajectory>(refitResult.second));
371  LogTrace(metname) << "StandAloneMuonTrajectoryBuilder Refit output " << endl;
372  LogTrace(metname) << debug.dumpTSOS(refitResult.second.lastMeasurement().updatedState());
373  } else
374  trajectoryContainer.push_back(std::make_unique<Trajectory>(trajectoryBW));
375  } else
376  trajectoryContainer.push_back(std::make_unique<Trajectory>(trajectoryBW));
377 
378  LogTrace(metname) << "Trajectory saved" << endl;
379 
380  return trajectoryContainer;
381 }
382 
384  TrajectoryStateOnSurface& aTSOS, DetId& aDetId) {
385  const std::string metname = "Muon|RecoMuon|StandAloneMuonTrajectoryBuilder";
387 
388  DetId seedDetId(aDetId);
389  // const GeomDet* gdet = theService->trackingGeometry()->idToDet( seedDetId );
390 
391  TrajectoryStateOnSurface initialState(aTSOS);
392 
393  LogTrace(metname) << "Seed's Pt: " << initialState.freeState()->momentum().perp() << endl;
394 
395  LogTrace(metname) << "Seed's id: " << endl;
396  LogTrace(metname) << debug.dumpMuonId(seedDetId);
397 
398  // Get the layer on which the seed relies
399  const DetLayer* initialLayer = theService->detLayerGeometry()->idToLayer(seedDetId);
400 
401  LogTrace(metname) << "Seed's detLayer: " << endl;
402  LogTrace(metname) << debug.dumpLayer(initialLayer);
403 
404  LogTrace(metname) << "TrajectoryStateOnSurface before propagation:" << endl;
405  LogTrace(metname) << debug.dumpTSOS(initialState);
406 
408 
409  // ask for compatible layers
410  vector<const DetLayer*> detLayers;
411 
412  if (theNavigationType == "Standard")
413  detLayers =
414  theService->muonNavigationSchool()->compatibleLayers(*initialLayer, *initialState.freeState(), detLayerOrder);
415  else if (theNavigationType == "Direct") {
416  DirectMuonNavigation navigation(&*theService->detLayerGeometry());
417  detLayers = navigation.compatibleLayers(*initialState.freeState(), detLayerOrder);
418  } else
419  edm::LogError(metname) << "No Properly Navigation Selected!!" << endl;
420 
421  LogTrace(metname) << "There are " << detLayers.size() << " compatible layers" << endl;
422 
423  DetLayerWithState result = DetLayerWithState(initialLayer, initialState);
424 
425  if (!detLayers.empty()) {
426  LogTrace(metname) << "Compatible layers:" << endl;
427  for (vector<const DetLayer*>::const_iterator layer = detLayers.begin(); layer != detLayers.end(); layer++) {
428  LogTrace(metname) << debug.dumpMuonId((*layer)->basicComponents().front()->geographicalId());
429  LogTrace(metname) << debug.dumpLayer(*layer);
430  }
431 
432  const DetLayer* finalLayer = detLayers.back();
433 
435  LogTrace(metname) << "Most internal one:" << endl;
436  else
437  LogTrace(metname) << "Most external one:" << endl;
438 
439  LogTrace(metname) << debug.dumpLayer(finalLayer);
440 
441  const TrajectoryStateOnSurface propagatedState =
442  theService->propagator(theSeedPropagatorName)->propagate(initialState, finalLayer->surface());
443 
444  if (propagatedState.isValid()) {
445  result = DetLayerWithState(finalLayer, propagatedState);
446 
447  LogTrace(metname) << "Trajectory State on Surface after the extrapolation" << endl;
448  LogTrace(metname) << debug.dumpTSOS(propagatedState);
449  LogTrace(metname) << debug.dumpLayer(finalLayer);
450  } else
451  LogTrace(metname) << "Extrapolation failed. Keep the original seed state" << endl;
452  } else
453  LogTrace(metname) << "No compatible layers. Keep the original seed state" << endl;
454 
455  return result;
456 }
bool empty() const
True if trajectory has no measurements.
Definition: Trajectory.h:233
int foundHits() const
Definition: Trajectory.h:206
virtual const BoundSurface & surface() const =0
The surface of the GeometricSearchDet.
T perp() const
Definition: PV3DBase.h:69
ConstRecHitPointer const & recHit() const
void createDefaultTrajectory(const Trajectory &, Trajectory &)
std::string dumpLayer(const DetLayer *layer) const
StandAloneMuonTrajectoryBuilder(const edm::ParameterSet &, const MuonServiceProxy *, edm::ConsumesCollector &iC)
Constructor with Parameter set and MuonServiceProxy.
const std::string metname
PTrajectoryStateOnDet persistentState(const TrajectoryStateOnSurface &ts, unsigned int detid)
MuonCandidate::TrajectoryContainer TrajectoryContainer
int getRPCCompatibleChambers() const
PropagationDirection
TrajectoryStateOnSurface lastUpdatedTSOS() const
the Trajectory state on the last surface of the fitting
Log< level::Error, false > LogError
void refit(const TrajectoryStateOnSurface &initialState, const DetLayer *, Trajectory &trajectory)
Perform the inner-outward fitting.
#define LogTrace(id)
constexpr std::array< uint8_t, layerIndexSize > layer
std::vector< const DetLayer * > compatibleLayers(const FreeTrajectoryState &fts, PropagationDirection timeDirection) const
tuple result
Definition: mps_fire.py:311
std::string dumpMuonId(const DetId &id) const
std::string dumpTSOS(const TrajectoryStateOnSurface &tsos) const
int getCSCCompatibleChambers() const
int getDTCompatibleChambers() const
TrajectoryMeasurement const & lastMeasurement() const
Definition: Trajectory.h:150
FreeTrajectoryState const * freeState(bool withErrors=true) const
void addParameter(std::string const &name, T const &value)
Definition: ParameterSet.h:135
StandAloneMuonFilter * bwfilter() const
actual filter
unsigned int detId() const
RefitResult refit(const Trajectory &)
GlobalVector momentum() const
~StandAloneMuonTrajectoryBuilder() override
Destructor.
TrajectoryContainer trajectories(const TrajectorySeed &) override
return a container of the reconstructed trajectories compatible with a given seed ...
Definition: DetId.h:17
PTrajectoryStateOnDet const & startingState() const
#define debug
Definition: HDRShower.cc:19
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
int getGEMCompatibleChambers() const
int getME0CompatibleChambers() const
std::unique_ptr< StandAloneMuonFilter > theBWFilter
StandAloneMuonFilter * filter() const
pre-filter
int getTotalCompatibleChambers() const
std::unique_ptr< StandAloneMuonFilter > theFilter
std::unique_ptr< StandAloneMuonRefitter > theRefitter
std::string theSeedPropagatorName
Propagator for the seed extrapolation.
std::pair< const DetLayer *, TrajectoryStateOnSurface > DetLayerWithState
void setEvent(const edm::Event &event) override
Pass the Event to the algo at each event.
Log< level::Warning, false > LogWarning
std::unique_ptr< SeedTransformer > theSeedTransformer
StandAloneMuonRefitter * refitter() const
refitter of the hits container
TrajectoryStateOnSurface lastCompatibleTSOS() const
the Trajectory state on the last compatible surface
DetLayerWithState propagateTheSeedTSOS(TrajectoryStateOnSurface &aTSOS, DetId &aDetId)