CMS 3D CMS Logo

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