CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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 
43  const MuonServiceProxy* service,
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  TrajectorySeed seedVoid;
283  seedForBW = seedVoid;
284  }
285  else if(theBWSeedType == "fromFWFit") {
286 
287 
288 
289  PTrajectoryStateOnDet seedTSOS =
290  trajectoryStateTransform::persistentState( tsosAfterRefit, trajectoryFW.lastMeasurement().recHit()->geographicalId().rawId());
291 
292  edm::OwnVector<TrackingRecHit> recHitsContainer;
294  TrajectorySeed fwFit(seedTSOS,recHitsContainer,seedDirection);
295 
296  seedForBW = fwFit;
297  }
298  else if(theBWSeedType == "fromGenerator") {
299  seedForBW = seed;
300  }
301  else
302  LogWarning(metname) << "Wrong seed type for the backward filter!";
303 
305  Trajectory trajectoryBW(seedForBW,bwDirection);
306 
307  // FIXME! under check!
308  bwfilter()->refit(tsosAfterRefit,filter()->lastDetLayer(),trajectoryBW);
309 
310  // Get the last TSOS
311  TrajectoryStateOnSurface tsosAfterBWRefit = bwfilter()->lastUpdatedTSOS();
312 
313  LogTrace(metname) << "StandAloneMuonTrajectoryBuilder BW filter output " << endl ;
314  LogTrace(metname) << debug.dumpTSOS(tsosAfterBWRefit);
315 
316  LogTrace(metname)
317  << "Number of RecHits: " << trajectoryBW.foundHits() << "\n"
318  << "Number of DT/CSC/RPC/GEM/ME0 chamber used (bw): "
319  << bwfilter()->getDTChamberUsed() << "/"
320  << bwfilter()->getCSCChamberUsed() << "/"
321  << bwfilter()->getRPCChamberUsed() << "/"
322  << bwfilter()->getGEMChamberUsed() << "/"
323  << bwfilter()->getME0ChamberUsed();
324 
325  // -- The trajectory is "good" if there are at least 2 chambers used in total and at
326  // least 1 is "tracking" (DT or CSC)
327  // -- The trajectory satisfies the "compatibility" requirements if there are at least
328  // 2 compatible chambers (not necessarily used!) in total and at
329  // least 1 is "tracking" (DT or CSC)
330  // 1st attempt
331  /*
332  if (bwfilter()->isCompatibilitySatisfied()) {
333 
334  if (doRefit && !trajectoryBW.empty() && bwfilter()->goodState()){
335  pair<bool,Trajectory> refitResult = refitter()->refit(trajectoryBW);
336  if (refitResult.first){
337  trajectoryContainer.push_back(new Trajectory(refitResult.second));
338  LogTrace(metname) << "StandAloneMuonTrajectoryBuilder Refit output " << endl;
339  LogTrace(metname) << debug.dumpTSOS(refitResult.second.lastMeasurement().updatedState());
340  }
341  else
342  trajectoryContainer.push_back(new Trajectory(trajectoryBW));
343  }
344  else
345  trajectoryContainer.push_back(new Trajectory(trajectoryBW));
346 
347  LogTrace(metname)<< "Trajectory saved" << endl;
348 
349  }
350  //if the trajectory is not saved, but at least two chamber are used in the
351  //forward filtering, try to build a new trajectory starting from the old
352  //trajectory w/o the latest measurement and a looser chi2 cut
353  else if ( filter()->getTotalChamberUsed() >= 2 ) {
354  LogTrace(metname)<< "Trajectory NOT saved. Second Attempt." << endl;
355  // FIXME:
356  // a better choice could be: identify the poorest one, exclude it, redo
357  // the fw and bw filtering. Or maybe redo only the bw without the excluded
358  // measure. As first step I will port the ORCA algo, then I will move to the
359  // above pattern.
360 
361  }
362 
363  else {
364  LogTrace(metname) << "Compatibility NOT satisfied after Backward filter!" << endl;
365  LogTrace(metname) << "The result of Forward filter will be loaded!" << endl;
366 
367  trajectoryContainer.push_back(new Trajectory(trajectoryFW));
368  }
369  */
370  // end 1st attempt
371 
372  // 2nd attempt
373  if( bwfilter()->goodState() ) {
374  LogTrace(metname) << debug.dumpLayer( bwfilter()->lastDetLayer() );
375  }
376  else if( bwfilter()->isCompatibilitySatisfied() ) {
377  LogTrace(metname) << "Compatibility satisfied after Backward filter, but too few valid RecHits ("
378  << trajectoryBW.foundHits() << ")." << endl
379  << "The (good) result of FW filter will be loaded!" << endl;
380  trajectoryContainer.push_back(new Trajectory(trajectoryFW));
381  return trajectoryContainer;
382  }
383  else {
384  LogTrace(metname) << "Compatibility NOT satisfied after Backward filter!" << endl
385  << "The Forward trajectory will be invalidated and then loaded!" << endl;
386  Trajectory defaultTraj(seed,fwDirection);
387  filter()->createDefaultTrajectory(trajectoryFW, defaultTraj);
388  trajectoryContainer.push_back(new Trajectory(defaultTraj));
389  return trajectoryContainer;
390  }
391  // end 2nd attempt
392 
393  if(doRefit) {
394  pair<bool,Trajectory> refitResult = refitter()->refit(trajectoryBW);
395  if(refitResult.first) {
396  trajectoryContainer.push_back(new Trajectory(refitResult.second));
397  LogTrace(metname) << "StandAloneMuonTrajectoryBuilder Refit output " << endl;
398  LogTrace(metname) << debug.dumpTSOS(refitResult.second.lastMeasurement().updatedState());
399  }
400  else
401  trajectoryContainer.push_back(new Trajectory(trajectoryBW));
402  }
403  else
404  trajectoryContainer.push_back(new Trajectory(trajectoryBW));
405 
406  LogTrace(metname) << "Trajectory saved" << endl;
407 
408  return trajectoryContainer;
409 }
410 
411 
414 
415  const std::string metname = "Muon|RecoMuon|StandAloneMuonTrajectoryBuilder";
417 
418  DetId seedDetId(aDetId);
419  // const GeomDet* gdet = theService->trackingGeometry()->idToDet( seedDetId );
420 
421  TrajectoryStateOnSurface initialState(aTSOS);
422 
423  LogTrace(metname)<<"Seed's Pt: "<<initialState.freeState()->momentum().perp()<<endl;
424 
425  LogTrace(metname)<< "Seed's id: "<< endl ;
426  LogTrace(metname) << debug.dumpMuonId(seedDetId);
427 
428  // Get the layer on which the seed relies
429  const DetLayer *initialLayer = theService->detLayerGeometry()->idToLayer( seedDetId );
430 
431  LogTrace(metname)<< "Seed's detLayer: "<< endl ;
432  LogTrace(metname) << debug.dumpLayer(initialLayer);
433 
434  LogTrace(metname)<< "TrajectoryStateOnSurface before propagation:" << endl;
435  LogTrace(metname) << debug.dumpTSOS(initialState);
436 
437 
439 
440  // ask for compatible layers
441  vector<const DetLayer*> detLayers;
442 
443  if(theNavigationType == "Standard")
444  detLayers = theService->muonNavigationSchool()->compatibleLayers(*initialLayer, *initialState.freeState(),detLayerOrder);
445  else if (theNavigationType == "Direct"){
446  DirectMuonNavigation navigation( &*theService->detLayerGeometry() );
447  detLayers = navigation.compatibleLayers( *initialState.freeState(),detLayerOrder);
448  }
449  else
450  edm::LogError(metname) << "No Properly Navigation Selected!!"<<endl;
451 
452 
453  LogTrace(metname) << "There are "<< detLayers.size() <<" compatible layers"<<endl;
454 
455  DetLayerWithState result = DetLayerWithState(initialLayer,initialState);
456 
457  if(detLayers.size()){
458 
459  LogTrace(metname) << "Compatible layers:"<<endl;
460  for( vector<const DetLayer*>::const_iterator layer = detLayers.begin();
461  layer != detLayers.end(); layer++){
462  LogTrace(metname) << debug.dumpMuonId((*layer)->basicComponents().front()->geographicalId());
463  LogTrace(metname) << debug.dumpLayer(*layer);
464  }
465 
466  const DetLayer* finalLayer = detLayers.back();
467 
468  if(theSeedPosition == recoMuon::in) LogTrace(metname) << "Most internal one:"<<endl;
469  else LogTrace(metname) << "Most external one:"<<endl;
470 
471  LogTrace(metname) << debug.dumpLayer(finalLayer);
472 
473  const TrajectoryStateOnSurface propagatedState =
474  theService->propagator(theSeedPropagatorName)->propagate(initialState,
475  finalLayer->surface());
476 
477  if(propagatedState.isValid()){
478  result = DetLayerWithState(finalLayer,propagatedState);
479 
480  LogTrace(metname) << "Trajectory State on Surface after the extrapolation"<<endl;
481  LogTrace(metname) << debug.dumpTSOS(propagatedState);
482  LogTrace(metname) << debug.dumpLayer(finalLayer);
483  }
484  else
485  LogTrace(metname)<< "Extrapolation failed. Keep the original seed state" <<endl;
486  }
487  else
488  LogTrace(metname)<< "No compatible layers. Keep the original seed state" <<endl;
489 
490  return result;
491 }
492 
493 
bool empty() const
True if trajectory has no measurements.
Definition: Trajectory.h:299
T getParameter(std::string const &) const
int foundHits() const
Definition: Trajectory.h:279
virtual const BoundSurface & surface() const =0
The surface of the GeometricSearchDet.
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
virtual void setEvent(const edm::Event &event)
Pass the Event to the algo at each event.
TrajectoryMeasurement const & lastMeasurement() const
Definition: Trajectory.h:228
FreeTrajectoryState const * freeState(bool withErrors=true) const
void addParameter(std::string const &name, T const &value)
Definition: ParameterSet.h:144
tuple result
Definition: query.py:137
StandAloneMuonFilter * bwfilter() const
actual filter
unsigned int detId() const
RefitResult refit(const Trajectory &)
virtual void setEvent(const edm::Event &event)
Pass the Event to the algo at each event.
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger but the state exists so we define the behavior If all triggers are the negative crieriion will lead to accepting the event(this again matches the behavior of"!*"before the partial wildcard feature was incorporated).The per-event"cost"of each negative criterion with multiple relevant triggers is about the same as!*was in the past
GlobalVector momentum() const
#define LogTrace(id)
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
TrajectoryContainer trajectories(const TrajectorySeed &)
return a container of the reconstructed trajectories compatible with a given seed ...
int getTotalCompatibleChambers() const
std::string theSeedPropagatorName
Propagator for the seed extrapolation.
virtual ~StandAloneMuonTrajectoryBuilder()
Destructor.
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)