CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
CkfTrackCandidateMakerBase.cc
Go to the documentation of this file.
1 #include <memory>
2 #include <string>
3 
10 
14 
16 
21 
27 
28 
33 
35 
38 
40 
41 #include<algorithm>
42 #include<functional>
43 
44 // #define VI_SORTSEED
45 // #define VI_REPRODUCIBLE
46 // #define VI_TBB
47 
48 #include <thread>
49 #ifdef VI_TBB
50 #include "tbb/parallel_for.h"
51 #endif
52 
54 
55 using namespace edm;
56 using namespace std;
57 
58 namespace {
59  BaseCkfTrajectoryBuilder *createBaseCkfTrajectoryBuilder(const edm::ParameterSet& pset, edm::ConsumesCollector& iC) {
60  return BaseCkfTrajectoryBuilderFactory::get()->create(pset.getParameter<std::string>("ComponentType"), pset, iC);
61  }
62 }
63 
64 namespace cms{
65  CkfTrackCandidateMakerBase::CkfTrackCandidateMakerBase(edm::ParameterSet const& conf, edm::ConsumesCollector && iC) :
66  theTrackCandidateOutput(true),
67  theTrajectoryOutput(false),
68  useSplitting(conf.getParameter<bool>("useHitsSplitting")),
69  doSeedingRegionRebuilding(conf.getParameter<bool>("doSeedingRegionRebuilding")),
70  cleanTrajectoryAfterInOut(conf.getParameter<bool>("cleanTrajectoryAfterInOut")),
71  reverseTrajectories(conf.existsAs<bool>("reverseTrajectories") && conf.getParameter<bool>("reverseTrajectories")),
72  theMaxNSeeds(conf.getParameter<unsigned int>("maxNSeeds")),
73  theTrajectoryBuilder(createBaseCkfTrajectoryBuilder(conf.getParameter<edm::ParameterSet>("TrajectoryBuilderPSet"), iC)),
74  theTrajectoryCleanerName(conf.getParameter<std::string>("TrajectoryCleaner")),
75  theTrajectoryCleaner(0),
76  theInitialState(new TransientInitialStateEstimator(conf.getParameter<ParameterSet>("TransientInitialStateEstimatorParameters"))),
77  theMagFieldName(conf.exists("SimpleMagneticField") ? conf.getParameter<std::string>("SimpleMagneticField") : ""),
78  theNavigationSchoolName(conf.getParameter<std::string>("NavigationSchool")),
79  theNavigationSchool(0),
80  theSeedCleaner(0),
81  maxSeedsBeforeCleaning_(0),
82  theMTELabel(iC.consumes<MeasurementTrackerEvent>(conf.getParameter<edm::InputTag>("MeasurementTrackerEvent"))),
83  skipClusters_(false)
84  {
85  //produces<TrackCandidateCollection>();
86  // old configuration totally descoped.
87  // if (!conf.exists("src"))
88  // theSeedLabel = InputTag(conf_.getParameter<std::string>("SeedProducer"),conf_.getParameter<std::string>("SeedLabel"));
89  // else
91 #ifndef VI_REPRODUCIBLE
92  if ( conf.exists("maxSeedsBeforeCleaning") )
93  maxSeedsBeforeCleaning_=conf.getParameter<unsigned int>("maxSeedsBeforeCleaning");
94 #endif
95  if (conf.existsAs<edm::InputTag>("clustersToSkip")) {
96  skipClusters_ = true;
97  maskPixels_ = iC.consumes<PixelClusterMask>(conf.getParameter<edm::InputTag>("clustersToSkip"));
98  maskStrips_ = iC.consumes<StripClusterMask>(conf.getParameter<edm::InputTag>("clustersToSkip"));
99  }
100 #ifndef VI_REPRODUCIBLE
101  std::string cleaner = conf.getParameter<std::string>("RedundantSeedCleaner");
102  if (cleaner == "SeedCleanerByHitPosition") {
104  } else if (cleaner == "SeedCleanerBySharedInput") {
106  } else if (cleaner == "CachingSeedCleanerByHitPosition") {
108  } else if (cleaner == "CachingSeedCleanerBySharedInput") {
109  int numHitsForSeedCleaner = conf.existsAs<int>("numHitsForSeedCleaner") ?
110  conf.getParameter<int>("numHitsForSeedCleaner") : 4;
111  int onlyPixelHits = conf.existsAs<bool>("onlyPixelHitsForSeedCleaner") ?
112  conf.getParameter<bool>("onlyPixelHitsForSeedCleaner") : false;
113  theSeedCleaner = new CachingSeedCleanerBySharedInput(numHitsForSeedCleaner,onlyPixelHits);
114  } else if (cleaner == "none") {
115  theSeedCleaner = 0;
116  } else {
117  throw cms::Exception("RedundantSeedCleaner not found", cleaner);
118  }
119 #endif
120 
121 #ifdef VI_REPRODUCIBLE
122  std::cout << "CkfTrackCandidateMaker in reproducible setting" << std::endl;
123  assert(nullptr==theSeedCleaner);
125 #endif
126 
127  }
128 
129 
130  // Virtual destructor needed.
132  if (theSeedCleaner) delete theSeedCleaner;
133  }
134 
136  {
137  /* no op*/
138  }
139 
141 
142  //services
145  // edm::ESInputTag mfESInputTag(mfName);
146  // es.get<IdealMagneticFieldRecord>().get(mfESInputTag,theMagField );
147 
148  edm::ESHandle<TrajectoryCleaner> trajectoryCleanerH;
149  es.get<TrajectoryCleaner::Record>().get(theTrajectoryCleanerName, trajectoryCleanerH);
150  theTrajectoryCleaner= trajectoryCleanerH.product();
151 
152  edm::ESHandle<NavigationSchool> navigationSchoolH;
153  es.get<NavigationSchoolRecord>().get(theNavigationSchoolName, navigationSchoolH);
154  theNavigationSchool = navigationSchoolH.product();
155  theTrajectoryBuilder->setNavigationSchool(theNavigationSchool);
156  }
157 
158  // Functions that gets called by framework every event
160  {
161  // getting objects from the EventSetup
162  setEventSetup( es );
163 
164  // set the correct navigation
165  // NavigationSetter setter( *theNavigationSchool);
166 
167  // propagator
168  edm::ESHandle<Propagator> thePropagator;
169  es.get<TrackingComponentsRecord>().get("AnyDirectionAnalyticalPropagator",
170  thePropagator);
171 
172  // method for Debugging
174 
175  // Step A: set Event for the TrajectoryBuilder
177  e.getByToken(theMTELabel, data);
178 
179  std::auto_ptr<MeasurementTrackerEvent> dataWithMasks;
180  if (skipClusters_) {
182  e.getByToken(maskPixels_, pixelMask);
184  e.getByToken(maskStrips_, stripMask);
185  dataWithMasks.reset(new MeasurementTrackerEvent(*data, *stripMask, *pixelMask));
186  //std::cout << "Trajectory builder " << conf_.getParameter<std::string>("@module_label") << " created with masks, " << std::endl;
187  theTrajectoryBuilder->setEvent(e, es, &*dataWithMasks);
188  } else {
189  //std::cout << "Trajectory builder " << conf_.getParameter<std::string>("@module_label") << " created without masks, " << std::endl;
190  theTrajectoryBuilder->setEvent(e, es, &*data);
191  }
192  // TISE ES must be set here due to dependence on theTrajectoryBuilder
193  theInitialState->setEventSetup( es, static_cast<TkTransientTrackingRecHitBuilder const *>(theTrajectoryBuilder->hitBuilder())->cloner() );
194 
195  // Step B: Retrieve seeds
196 
198  e.getByToken(theSeedLabel, collseed);
199 
200  // Step C: Create empty output collection
201  std::auto_ptr<TrackCandidateCollection> output(new TrackCandidateCollection);
202  std::auto_ptr<std::vector<Trajectory> > outputT (new std::vector<Trajectory>());
203 
204  if ( (*collseed).size()>theMaxNSeeds ) {
205  LogError("TooManySeeds")<<"Exceeded maximum numeber of seeds! theMaxNSeeds="<<theMaxNSeeds<<" nSeed="<<(*collseed).size();
206  if (theTrackCandidateOutput){ e.put(output);}
207  if (theTrajectoryOutput){e.put(outputT);}
208  return;
209  }
210 
211  // Step D: Invoke the building algorithm
212  if ((*collseed).size()>0){
213 
214  unsigned int lastCleanResult=0;
215  std::vector<Trajectory> rawResult;
216  rawResult.reserve(collseed->size() * 4);
217 
218  if (theSeedCleaner) theSeedCleaner->init( &rawResult );
219 
220  // method for debugging
222 
223  // the mutex
224  std::mutex theMutex;
225  using Lock = std::unique_lock<std::mutex>;
226 
227  // Loop over seeds
228  size_t collseed_size = collseed->size();
229 
230  unsigned int indeces[collseed_size]; for (auto i=0U; i< collseed_size; ++i) indeces[i]=i;
231 
232 
233 
234 
235 #ifdef VI_SORTSEED
236  // std::random_shuffle(indeces,indeces+collseed_size);
237 
238  // here only for reference: does not seems to help
239 
240  auto const & seeds = *collseed;
241 
242 
243  float val[collseed_size];
244  for (auto i=0U; i< collseed_size; ++i)
245  { val[i] = seeds[i].startingState().pt();};
246  // { val[i] = std::abs((*seeds[i].recHits().first).surface()->eta());}
247 
248  /*
249  unsigned long long val[collseed_size];
250  for (auto i=0U; i< collseed_size; ++i) {
251  if (seeds[i].nHits()<2) { val[i]=0; continue;}
252  auto h = seeds[i].recHits().first;
253  auto const & hit = static_cast<BaseTrackerRecHit const&>(*h);
254  val[i] = hit.firstClusterRef().key();
255  if (++h != seeds[i].recHits().second) {
256  auto const & hit = static_cast<BaseTrackerRecHit const&>(*h);
257  val[i] |= (unsigned long long)(hit.firstClusterRef().key())<<32;
258  }
259  }
260  */
261  std::sort(indeces,indeces+collseed_size, [&](unsigned int i, unsigned int j){return val[i]<val[j];});
262 
263 
264  // std::cout << spt(indeces[0]) << ' ' << spt(indeces[collseed_size-1]) << std::endl;
265 #endif
266 
267  std::atomic<unsigned int> ntseed(0);
268  auto theLoop = [&](size_t ii) {
269  auto j = indeces[ii];
270 
271  ntseed++;
272 
273  // to be moved inside a par section (how with tbb??)
274  std::vector<Trajectory> theTmpTrajectories;
275 
276 
277  LogDebug("CkfPattern") << "======== Begin to look for trajectories from seed " << j << " ========"<<endl;
278 
279  { Lock lock(theMutex);
280  // Check if seed hits already used by another track
281  if (theSeedCleaner && !theSeedCleaner->good( &((*collseed)[j])) ) {
282  LogDebug("CkfTrackCandidateMakerBase")<<" Seed cleaning kills seed "<<j;
283  return; // from the lambda!
284  }}
285 
286  // Build trajectory from seed outwards
287  theTmpTrajectories.clear();
288  auto const & startTraj = theTrajectoryBuilder->buildTrajectories( (*collseed)[j], theTmpTrajectories, nullptr );
289 
290  LogDebug("CkfPattern") << "======== In-out trajectory building found " << theTmpTrajectories.size()
291  << " trajectories from seed " << j << " ========"<<endl
292  <<PrintoutHelper::dumpCandidates(theTmpTrajectories);
293 
295 
296  // Select the best trajectory from this seed (declare others invalid)
297  theTrajectoryCleaner->clean(theTmpTrajectories);
298 
299  LogDebug("CkfPattern") << "======== In-out trajectory cleaning gave the following valid trajectories from seed "
300  << j << " ========"<<endl
301  << PrintoutHelper::dumpCandidates(theTmpTrajectories);
302  }
303 
304  // Optionally continue building trajectory back through
305  // seed and if possible further inwards.
306 
308  theTrajectoryBuilder->rebuildTrajectories(startTraj,(*collseed)[j],theTmpTrajectories);
309 
310  LogDebug("CkfPattern") << "======== Out-in trajectory building found " << theTmpTrajectories.size()
311  << " valid/invalid trajectories from seed " << j << " ========"<<endl
312  <<PrintoutHelper::dumpCandidates(theTmpTrajectories);
313  }
314 
315 
316  // Select the best trajectory from this seed (after seed region rebuilding, can be more than one)
317  theTrajectoryCleaner->clean(theTmpTrajectories);
318 
319  LogDebug("CkfPattern") << "======== Trajectory cleaning gave the following valid trajectories from seed "
320  << j << " ========"<<endl
321  <<PrintoutHelper::dumpCandidates(theTmpTrajectories);
322 
323  { Lock lock(theMutex);
324  for(vector<Trajectory>::iterator it=theTmpTrajectories.begin();
325  it!=theTmpTrajectories.end(); it++){
326  if( it->isValid() ) {
327  it->setSeedRef(collseed->refAt(j));
328  // Store trajectory
329  rawResult.push_back(std::move(*it));
330  // Tell seed cleaner which hits this trajectory used.
331  //TO BE FIXED: this cut should be configurable via cfi file
332  if (theSeedCleaner && rawResult.back().foundHits()>3) theSeedCleaner->add( &rawResult.back() );
333  //if (theSeedCleaner ) theSeedCleaner->add( & (*it) );
334  }
335  }}
336 
337  theTmpTrajectories.clear();
338 
339  LogDebug("CkfPattern") << "rawResult trajectories found so far = " << rawResult.size();
340 
341  { Lock lock(theMutex);
342  if ( maxSeedsBeforeCleaning_ >0 && rawResult.size() > maxSeedsBeforeCleaning_+lastCleanResult) {
343  theTrajectoryCleaner->clean(rawResult);
344  rawResult.erase(std::remove_if(rawResult.begin()+lastCleanResult,rawResult.end(),
345  std::not1(std::mem_fun_ref(&Trajectory::isValid))),
346  rawResult.end());
347  lastCleanResult=rawResult.size();
348  }
349  }
350 
351  };
352  // end of loop over seeds
353 
354 
355 #ifdef VI_TBB
356  tbb::parallel_for(0UL,collseed_size,1UL,theLoop);
357 #else
358 #ifdef VI_OMP
359 #pragma omp parallel for schedule(dynamic,4)
360 #endif
361  for (size_t j = 0; j < collseed_size; j++){
362  theLoop(j);
363  }
364 #endif
365  assert(ntseed==collseed_size);
367 
368  // std::cout << "VICkfPattern " << "rawResult trajectories found = " << rawResult.size() << " in " << ntseed << " seeds " << collseed_size << std::endl;
369 
370 #ifdef VI_REPRODUCIBLE
371  // sort trajectory
372  std::sort(rawResult.begin(), rawResult.end(),[](const Trajectory & a, const Trajectory & b)
373  { return a.seedRef().key() < b.seedRef().key();});
374  //{ return a.chiSquared()*b.ndof() < b.chiSquared()*a.ndof();});
375 #endif
376 
377  // Step E: Clean the results to avoid duplicate tracks
378  // Rejected ones just flagged as invalid.
379  theTrajectoryCleaner->clean(rawResult);
380 
381  LogDebug("CkfPattern") << "======== Final cleaning of entire event found " << rawResult.size()
382  << " valid/invalid trajectories ======="<<endl
383  <<PrintoutHelper::dumpCandidates(rawResult);
384 
385  LogDebug("CkfPattern") << "removing invalid trajectories.";
386 
387  vector<Trajectory> & unsmoothedResult(rawResult);
388  unsmoothedResult.erase(std::remove_if(unsmoothedResult.begin(),unsmoothedResult.end(),
389  std::not1(std::mem_fun_ref(&Trajectory::isValid))),
390  unsmoothedResult.end());
391  unsmoothedResult.shrink_to_fit();
392  // If requested, reverse the trajectories creating a new 1-hit seed on the last measurement of the track
393  if (reverseTrajectories) {
394  for (auto it = unsmoothedResult.begin(), ed = unsmoothedResult.end(); it != ed; ++it) {
395  // reverse the trajectory only if it has valid hit on the last measurement (should happen)
396  if (it->lastMeasurement().updatedState().isValid() &&
397  it->lastMeasurement().recHit().get() != 0 &&
398  it->lastMeasurement().recHit()->isValid()) {
399  // I can't use reverse in place, because I want to change the seed
400  // 1) reverse propagation direction
401  PropagationDirection direction = it->direction();
402  if (direction == alongMomentum) direction = oppositeToMomentum;
403  else if (direction == oppositeToMomentum) direction = alongMomentum;
404  // 2) make a seed
405  TrajectoryStateOnSurface const & initState = it->lastMeasurement().updatedState();
406  auto initId = it->lastMeasurement().recHitR().rawId();
409  hits.push_back(it->lastMeasurement().recHit()->hit()->clone());
410  boost::shared_ptr<const TrajectorySeed> seed(new TrajectorySeed(state, std::move(hits), direction));
411  // 3) make a trajectory
412  Trajectory trajectory(seed, direction);
413  trajectory.setNLoops(it->nLoops());
414  trajectory.setSeedRef(it->seedRef());
415  trajectory.setStopReason(it->stopReason());
416  // 4) push states in reversed order
417  Trajectory::DataContainer &meas = it->measurements();
418  trajectory.reserve(meas.size());
419  for (auto itmeas = meas.rbegin(), endmeas = meas.rend(); itmeas != endmeas; ++itmeas) {
420  trajectory.push(std::move(*itmeas));
421  }
422  // replace
423  (*it)= std::move(trajectory);
424  } else {
425  edm::LogWarning("CkfPattern_InvalidLastMeasurement") << "Last measurement of the trajectory is invalid, cannot reverse it";
426  }
427  }
428  }
429 
430 
431  int viTotHits=0;
432 
434  // Step F: Convert to TrackCandidates
435  output->reserve(unsmoothedResult.size());
436  Traj2TrackHits t2t(theTrajectoryBuilder->hitBuilder(),true);
437 
438  for (vector<Trajectory>::const_iterator it = unsmoothedResult.begin();
439  it != unsmoothedResult.end(); ++it) {
440 
441  LogDebug("CkfPattern") << "copying "<<(useSplitting?"splitted":"un-splitted")<<" hits from trajectory";
443  if(it->direction() != alongMomentum) LogDebug("CkfPattern") << "not along momentum... " << std::endl;
444  t2t(*it,recHits,useSplitting);
445 
446  viTotHits+=recHits.size();
447 
448 
449  LogDebug("CkfPattern") << "getting initial state.";
450  Trajectory trialTrajectory = (*it);
451  std::pair<TrajectoryStateOnSurface, const GeomDet*> initState;
452  bool failed = false;
453 
454  do {
455  // Drop last hit if previous backFitter was not successful
456  if(failed) {
457  LogDebug("CkfPattern") << "removing last hit";
458  trialTrajectory.pop();
459  LogDebug("CkfPattern") << "hits remaining " << trialTrajectory.foundHits();
460  }
461 
462  // Get inner state
463  const bool doBackFit = (!doSeedingRegionRebuilding) & (!reverseTrajectories);
464  initState = theInitialState->innerState(trialTrajectory, doBackFit);
465 
466  // Check if that was successful
467  failed = (!initState.first.isValid()) || initState.second == nullptr || edm::isNotFinite(initState.first.globalPosition().x());
468  } while(failed && trialTrajectory.foundHits() > 3);
469 
470  if(failed) continue;
471 
472 
473 
474  PTrajectoryStateOnDet state;
475  if(useSplitting && (initState.second != recHits.front().det()) && recHits.front().det() ){
476  LogDebug("CkfPattern") << "propagating to hit front in case of splitting.";
477  TrajectoryStateOnSurface && propagated = thePropagator->propagate(initState.first,recHits.front().det()->surface());
478  if (!propagated.isValid()) continue;
480  recHits.front().rawId());
481  }
482  else state = trajectoryStateTransform::persistentState( initState.first,
483  initState.second->geographicalId().rawId());
484  LogDebug("CkfPattern") << "pushing a TrackCandidate.";
485  output->emplace_back(recHits,it->seed(),state,it->seedRef(),it->nLoops(), (uint8_t)it->stopReason());
486  }
487  }//output trackcandidates
488 
490  es.get<TrackerDigiGeometryRecord>().get(tracker);
491  LogTrace("CkfPattern|TrackingRegressionTest") << "========== CkfTrackCandidateMaker Info =========="
492  << "number of Seed: " << collseed->size()<<endl
493  <<PrintoutHelper::regressionTest(*tracker,unsmoothedResult);
494 
495  assert(viTotHits>=0); // just to use it...
496  // std::cout << "VICkfPattern result " << output->size() << " " << viTotHits << std::endl;
497 
498  if (theTrajectoryOutput){ outputT->swap(unsmoothedResult);}
499 
500  }// end of ((*collseed).size()>0)
501 
502  // method for debugging
504 
505  // Step G: write output to file
506  if (theTrackCandidateOutput){ e.put(output);}
507  if (theTrajectoryOutput){e.put(outputT);}
508  }
509 
510 }
511 
#define LogDebug(id)
T getParameter(std::string const &) const
int foundHits() const
Definition: Trajectory.h:279
int i
Definition: DBlmapReader.cc:9
tuple cleanTrajectoryAfterInOut
static std::string dumpCandidates(collection &candidates)
bool existsAs(std::string const &parameterName, bool trackiness=true) const
checks if a parameter exists as a given type
Definition: ParameterSet.h:186
static boost::mutex mutex
Definition: LHEProxy.cc:11
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:462
edm::EDGetTokenT< StripClusterMask > maskStrips_
void setStopReason(StopReason s)
Definition: Trajectory.h:392
assert(m_qm.get())
std::vector< TrackCandidate > TrackCandidateCollection
std::unique_ptr< TransientInitialStateEstimator > theInitialState
size_type size() const
Definition: OwnVector.h:264
void setNLoops(signed char value)
Definition: Trajectory.h:389
PTrajectoryStateOnDet persistentState(const TrajectoryStateOnSurface &ts, unsigned int detid)
bool exists(std::string const &parameterName) const
checks if a parameter exists
virtual void printHitsDebugger(edm::Event &e)
edm::ESHandle< GeometricSearchTracker > theGeomSearchTracker
PropagationDirection
virtual void done()=0
Tells the cleaner that the seeds are finished, and so it can clear any cache it has.
void reserve(unsigned int n)
Definition: Trajectory.h:204
int ii
Definition: cuy.py:588
const Plane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:40
virtual void add(const Trajectory *traj)=0
Informs the cleaner that a new trajectory has been made, in case the cleaner keeps a local collection...
virtual bool good(const TrajectorySeed *seed)=0
Returns true if the seed is not overlapping with another trajectory.
static std::string regressionTest(const TrackerGeometry &tracker, std::vector< Trajectory > &unsmoothedResult)
tuple reverseTrajectories
void push_back(D *&d)
Definition: OwnVector.h:290
edm::EDGetTokenT< PixelClusterMask > maskPixels_
std::vector< TrajectoryMeasurement > DataContainer
Definition: Trajectory.h:44
bool isNotFinite(T x)
Definition: isFinite.h:10
const TrajectoryCleaner * theTrajectoryCleaner
const NavigationSchool * theNavigationSchool
OrphanHandle< PROD > put(std::auto_ptr< PROD > product)
Put a new product.
Definition: Event.h:121
const GeomDet * det() const
virtual void produceBase(edm::Event &e, const edm::EventSetup &es)
size_t key() const
Definition: RefToBase.h:235
def move
Definition: eostools.py:510
std::unique_ptr< BaseCkfTrajectoryBuilder > theTrajectoryBuilder
virtual void clean(TrajectoryContainer &) const
edm::EDGetTokenT< MeasurementTrackerEvent > theMTELabel
int j
Definition: DBlmapReader.cc:9
edm::RefToBase< TrajectorySeed > seedRef(void) const
Definition: Trajectory.h:361
tuple doSeedingRegionRebuilding
#define LogTrace(id)
edm::EDGetTokenT< edm::View< TrajectorySeed > > theSeedLabel
bool isValid() const
Definition: Trajectory.h:324
void pop()
Definition: Trajectory.cc:16
const T & get() const
Definition: EventSetup.h:56
T const * product() const
Definition: ESHandle.h:86
double b
Definition: hdecay.h:120
void setSeedRef(const edm::RefToBase< TrajectorySeed > &seedRef)
Definition: Trajectory.h:363
void setEventSetup(const edm::EventSetup &es)
Initialize EventSetup objects at each event.
virtual void beginRunBase(edm::Run const &, edm::EventSetup const &es)
double a
Definition: hdecay.h:121
tuple cout
Definition: gather_cfg.py:145
volatile std::atomic< bool > shutdown_flag false
void push(const TrajectoryMeasurement &tm)
Definition: Trajectory.cc:35
virtual void init(const std::vector< Trajectory > *vect)=0
Provides the cleaner a pointer to the vector where trajectories are stored, in case it does not want ...
reference front()
Definition: OwnVector.h:429
id_type rawId() const
T get(const Candidate &c)
Definition: component.h:55
Definition: Run.h:43
edm::ESHandle< MagneticField > theMagField