CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
TrackListMerger.cc
Go to the documentation of this file.
1 //
2 // Package: RecoTracker/FinalTrackSelectors
3 // Class: TrackListMerger
4 //
5 // Description: Hit Dumper
6 //
7 // Original Author: Steve Wagner, stevew@pizero.colorado.edu
8 // Created: Sat Jan 14 22:00:00 UTC 2006
9 //
10 //
11 
16 
28 
29 #include "trackAlgoPriorityOrder.h"
30 
32  {
33  public:
34 
35  explicit TrackListMerger(const edm::ParameterSet& conf);
36 
37  virtual ~TrackListMerger();
38 
39  virtual void produce(edm::Event& e, const edm::EventSetup& c) override;
40 
41  private:
42 
43  using MVACollection = std::vector<float>;
44  using QualityMaskCollection = std::vector<unsigned char>;
45 
46  std::auto_ptr<reco::TrackCollection> outputTrks;
47  std::auto_ptr<reco::TrackExtraCollection> outputTrkExtras;
48  std::auto_ptr< TrackingRecHitCollection> outputTrkHits;
49  std::auto_ptr< std::vector<Trajectory> > outputTrajs;
50  std::auto_ptr< TrajTrackAssociationCollection > outputTTAss;
51  std::auto_ptr< TrajectorySeedCollection > outputSeeds;
52 
58 
61 
62  struct TkEDGetTokenss {
71  edm::EDGetTokenT<std::vector<Trajectory> > && traj_, edm::EDGetTokenT<TrajTrackAssociationCollection > && tass_,
73  tag(tag_), tk(tk_), traj(traj_), tass(tass_), tsel(tsel_), tmva(tmva_) {}
74  };
75  TkEDGetTokenss edTokens(const edm::InputTag &tag, const edm::InputTag &seltag, const edm::InputTag &mvatag) {
76  return TkEDGetTokenss(tag, consumes<reco::TrackCollection>(tag),
77  consumes<std::vector<Trajectory> >(tag), consumes<TrajTrackAssociationCollection >(tag),
78  consumes<edm::ValueMap<int> >(seltag), consumes<edm::ValueMap<float> >(mvatag));
79  }
81  return TkEDGetTokenss(tag, consumes<reco::TrackCollection>(tag),
82  consumes<std::vector<Trajectory> >(tag), consumes<TrajTrackAssociationCollection >(tag),
84  }
85  std::vector<TkEDGetTokenss> trackProducers_;
86 
88  double minPT_;
89  unsigned int minFound_;
90  float epsilon_;
91  float shareFrac_;
94  std::vector<double> indivShareFrac_;
95 
96  std::vector< std::vector< int> > listsToMerge_;
97  std::vector<bool> promoteQuality_;
98  std::vector<int> hasSelector_;
99  bool copyMVA_;
100 
105 
106 
107  };
108 
109 
110 
111 #include <memory>
112 #include <string>
113 #include <iostream>
114 #include <cmath>
115 #include <vector>
116 
124 
126 
131 
132 //#include "DataFormats/TrackReco/src/classes.h"
133 
135 
136 #ifdef STAT_TSB
137 #include <x86intrin.h>
138 #endif
139 
140 namespace {
141 #ifdef STAT_TSB
142 inline volatile unsigned long long rdtsc() {
143  return __rdtsc();
144 }
145 
146  struct StatCount {
147  float maxDP=0.;
148  float maxDE=0.;
149  unsigned long long st;
150  long long totBegin=0;
151  long long totPre=0;
152  long long totEnd=0;
153  unsigned long long timeNo; // no-overlap
154  unsigned long long timeOv; // overlap
155  void begin(int tt) {
156  totBegin+=tt;
157  }
158  void start() { st=rdtsc(); }
159  void noOverlap() { timeNo += (rdtsc()-st);}
160  void overlap() { timeOv += (rdtsc()-st);}
161  void pre(int tt) { totPre+=tt;}
162  void end(int tt) { totEnd+=tt;}
163  void de(float d) { if (d>maxDE) maxDE=d;}
164  void dp(float d) { if (d>maxDP) maxDP=d;}
165 
166 
167  void print() const {
168  std::cout << "TrackListMerger stat\nBegin/Pre/End/maxDPhi/maxDEta/Overlap/NoOverlap "
169  << totBegin <<'/'<< totPre <<'/'<< totEnd <<'/'<< maxDP <<'/'<< maxDE
170  <<'/'<< timeOv/1000 <<'/'<< timeNo/1000
171  << std::endl;
172  }
173  StatCount() {}
174  ~StatCount() { print();}
175  };
176  StatCount statCount;
177 
178 #else
179  struct StatCount {
180  void begin(int){}
181  void pre(int){}
182  void end(int){}
183  void start(){}
184  void noOverlap(){}
185  void overlap(){}
186  void de(float){}
187  void dp(float){}
188 
189 
190  };
191  [[cms::thread_safe]] StatCount statCount;
192 #endif
193 
194 
195 }
196 
197 
198 
199 namespace {
200  edm::ProductID clusterProductB( const TrackingRecHit *hit){
201  return reinterpret_cast<const BaseTrackerRecHit *>(hit)->firstClusterRef().id();
202  }
203 }
204 
205 
207  copyExtras_ = conf.getUntrackedParameter<bool>("copyExtras", true);
208 
209  std::vector<edm::InputTag> trackProducerTags(conf.getParameter<std::vector<edm::InputTag> >("TrackProducers"));
210  //which of these do I need to turn into vectors?
211  maxNormalizedChisq_ = conf.getParameter<double>("MaxNormalizedChisq");
212  minPT_ = conf.getParameter<double>("MinPT");
213  minFound_ = (unsigned int)conf.getParameter<int>("MinFound");
214  epsilon_ = conf.getParameter<double>("Epsilon");
215  shareFrac_ = conf.getParameter<double>("ShareFrac");
216  allowFirstHitShare_ = conf.getParameter<bool>("allowFirstHitShare");
217  foundHitBonus_ = conf.getParameter<double>("FoundHitBonus");
218  lostHitPenalty_ = conf.getParameter<double>("LostHitPenalty");
219  indivShareFrac_=conf.getParameter<std::vector<double> >("indivShareFrac");
220  std::string qualityStr = conf.getParameter<std::string>("newQuality");
221 
222  if (qualityStr != "") {
224  }
225  else
227 
228  use_sharesInput_ = true;
229  if ( epsilon_ > 0.0 )use_sharesInput_ = false;
230 
232 
233  for ( unsigned int i=0; i<setsToMerge.size(); i++) {
234  listsToMerge_.push_back(setsToMerge[i].getParameter<std::vector< int> >("tLists"));
235  promoteQuality_.push_back(setsToMerge[i].getParameter<bool>("pQual"));
236  }
237  hasSelector_ = conf.getParameter<std::vector<int> > ("hasSelector");
238  copyMVA_ = conf.getParameter<bool>("copyMVA");
239 
240  std::vector<edm::InputTag> selectors(conf.getParameter<std::vector<edm::InputTag> >("selectedTrackQuals"));
241  std::vector<edm::InputTag> mvaStores;
242  if(conf.exists("mvaValueTags")){
243  mvaStores = conf.getParameter<std::vector<edm::InputTag> >("mvaValueTags");
244  }else{
245  for (int i = 0; i < (int)selectors.size(); i++){
246  edm::InputTag ntag(selectors[i].label(),"MVAVals");
247  mvaStores.push_back(ntag);
248  }
249  }
250  unsigned int numTrkColl = trackProducerTags.size();
251  if (numTrkColl != hasSelector_.size() || numTrkColl != selectors.size()) {
252  throw cms::Exception("Inconsistent size") << "need same number of track collections and selectors";
253  }
254  if (numTrkColl != hasSelector_.size() || numTrkColl != mvaStores.size()) {
255  throw cms::Exception("Inconsistent size") << "need same number of track collections and MVA stores";
256  }
257  for (unsigned int i = indivShareFrac_.size(); i < numTrkColl; i++) {
258  // edm::LogWarning("TrackListMerger") << "No indivShareFrac for " << trackProducersTags <<". Using default value of 1";
259  indivShareFrac_.push_back(1.0);
260  }
261 
262  trkQualMod_=conf.getParameter<bool>("writeOnlyTrkQuals");
263  if ( trkQualMod_) {
264  bool ok=true;
265  for ( unsigned int i=1; i<numTrkColl; i++) {
266  if (!(trackProducerTags[i]==trackProducerTags[0])) ok=false;
267  }
268  if ( !ok) {
269  throw cms::Exception("Bad input") << "to use writeOnlyTrkQuals=True all input InputTags must be the same";
270  }
271  produces<edm::ValueMap<int> >();
272  produces<QualityMaskCollection>("QualityMasks");
273  }
274  else{
275  produces<reco::TrackCollection>();
276 
277  makeReKeyedSeeds_ = conf.getUntrackedParameter<bool>("makeReKeyedSeeds",false);
278  if (makeReKeyedSeeds_){
279  copyExtras_=true;
280  produces<TrajectorySeedCollection>();
281  }
282 
283  if (copyExtras_) {
284  produces<reco::TrackExtraCollection>();
285  produces<TrackingRecHitCollection>();
286  }
287  produces< std::vector<Trajectory> >();
288  produces< TrajTrackAssociationCollection >();
289  }
290  produces<edm::ValueMap<float> >("MVAVals");
291  produces<MVACollection>("MVAValues");
292 
293  // Do all the consumes
294  trackProducers_.resize(numTrkColl);
295  for (unsigned int i = 0; i < numTrkColl; ++i) {
296  trackProducers_[i] = hasSelector_[i]>0 ? edTokens(trackProducerTags[i], selectors[i], mvaStores[i]) : edTokens(trackProducerTags[i], mvaStores[i]);
297  }
298 }
299 
300 
301 // Virtual destructor needed.
303 
304  // Functions that gets called by framework every event
306  {
307  // extract tracker geometry
308  //
309  //edm::ESHandle<TrackerGeometry> theG;
310  //es.get<TrackerDigiGeometryRecord>().get(theG);
311 
312  // using namespace reco;
313 
314  // get Inputs
315  // if 1 input list doesn't exist, make an empty list, issue a warning, and continue
316  // this allows TrackListMerger to be used as a cleaner only if handed just one list
317  // if both input lists don't exist, will issue 2 warnings and generate an empty output collection
318  //
319  static const reco::TrackCollection s_empty;
320 
321  std::vector<const reco::TrackCollection *> trackColls;
322  std::vector<edm::Handle<reco::TrackCollection> > trackHandles(trackProducers_.size());
323  for ( unsigned int i=0; i<trackProducers_.size(); i++) {
324  trackColls.push_back(0);
325  //edm::Handle<reco::TrackCollection> trackColl;
326  e.getByToken(trackProducers_[i].tk, trackHandles[i]);
327  if (trackHandles[i].isValid()) {
328  trackColls[i]= trackHandles[i].product();
329  } else {
330  edm::LogWarning("TrackListMerger") << "TrackCollection " << trackProducers_[i].tag <<" not found";
331  trackColls[i]=&s_empty;
332  }
333  }
334 
335  unsigned int collsSize =trackColls.size();
336  unsigned int rSize=0;
337  unsigned int trackCollSizes[collsSize];
338  unsigned int trackCollFirsts[collsSize];
339  for (unsigned int i=0; i!=collsSize; i++) {
340  trackCollSizes[i]=trackColls[i]->size();
341  trackCollFirsts[i]=rSize;
342  rSize+=trackCollSizes[i];
343  }
344 
345  statCount.begin(rSize);
346 
347  //
348  // quality cuts first
349  //
350  int i=-1;
351 
352  int selected[rSize];
353  int indexG[rSize];
354  bool trkUpdated[rSize];
355  int trackCollNum[rSize];
356  int trackQuals[rSize];
357  float trackMVAs[rSize];
358  reco::TrackBase::TrackAlgorithm oriAlgo[rSize];
359  std::vector<reco::TrackBase::AlgoMask> algoMask(rSize);
360  for (unsigned int j=0; j<rSize;j++) {
361  indexG[j]=-1; selected[j]=1; trkUpdated[j]=false; trackCollNum[j]=0; trackQuals[j]=0;trackMVAs[j] = -998.0;oriAlgo[j]=reco::TrackBase::undefAlgorithm;
362  }
363 
364  int ngood=0;
365  for (unsigned int j=0; j!= collsSize; j++) {
366  const reco::TrackCollection *tC1=trackColls[j];
367 
368  edm::Handle<edm::ValueMap<int> > trackSelColl;
369  edm::Handle<edm::ValueMap<float> > trackMVAStore;
370  if ( copyMVA_ )
371  e.getByToken(trackProducers_[j].tmva, trackMVAStore);
372  if ( hasSelector_[j]>0 ){
373  e.getByToken(trackProducers_[j].tsel, trackSelColl);
374  }
375 
376  if ( 0<tC1->size() ){
377  unsigned int iC=0;
378  for (reco::TrackCollection::const_iterator track=tC1->begin(); track!=tC1->end(); track++){
379  i++;
380  trackCollNum[i]=j;
381  trackQuals[i]=track->qualityMask();
382  oriAlgo[i]=track->originalAlgo();
383  algoMask[i]=track->algoMask();
384 
385  reco::TrackRef trkRef=reco::TrackRef(trackHandles[j],iC);
386  if ( copyMVA_ )
387  if( (*trackMVAStore).contains(trkRef.id()) ) trackMVAs[i] = (*trackMVAStore)[trkRef];
388  if ( hasSelector_[j]>0 ) {
389  int qual=(*trackSelColl)[trkRef];
390  if ( qual < 0 ) {
391  selected[i]=0;
392  iC++;
393  continue;
394  }else{
395  trackQuals[i]=qual;
396  }
397  }
398  iC++;
399  selected[i]=trackQuals[i]+10;//10 is magic number used throughout...
400  if ((short unsigned)track->ndof() < 1){
401  selected[i]=0;
402  continue;
403  }
404  if (track->normalizedChi2() > maxNormalizedChisq_){
405  selected[i]=0;
406  continue;
407  }
408  if (track->found() < minFound_){
409  selected[i]=0;
410  continue;
411  }
412  if (track->pt() < minPT_){
413  selected[i]=0;
414  continue;
415  }
416  // good!
417  indexG[i] = ngood++;
418  //if ( beVerb) std::cout << "inverb " << track->pt() << " " << selected[i] << std::endl;
419  }//end loop over tracks
420  }//end more than 0 track
421  } // loop over trackcolls
422 
423 
424  statCount.pre(ngood);
425 
426  //cache the id and rechits of valid hits
427  typedef std::pair<unsigned int, const TrackingRecHit*> IHit;
428  std::vector<std::vector<IHit>> rh1(ngood); // "not an array" of vectors!
429  //const TrackingRecHit* fh1[ngood]; // first hit...
430  uint8_t algo[ngood];
431  float score[ngood];
432 
433 
434  for ( unsigned int j=0; j<rSize; j++) {
435  if (selected[j]==0) continue;
436  int i = indexG[j];
437  assert(i>=0);
438  unsigned int collNum=trackCollNum[j];
439  unsigned int trackNum=j-trackCollFirsts[collNum];
440  const reco::Track *track=&((trackColls[collNum])->at(trackNum));
441 
442  algo[i]=track->algo();
443  int validHits=track->numberOfValidHits();
444  int validPixelHits=track->hitPattern().numberOfValidPixelHits();
445  int lostHits=track->numberOfLostHits();
446  score[i] = foundHitBonus_*validPixelHits+foundHitBonus_*validHits - lostHitPenalty_*lostHits - track->chi2();
447 
448 
449  rh1[i].reserve(validHits) ;
450  auto compById = [](IHit const & h1, IHit const & h2) {return h1.first < h2.first;};
451  for (trackingRecHit_iterator it = track->recHitsBegin(); it != track->recHitsEnd(); ++it) {
452  const TrackingRecHit* hit = (*it);
453  unsigned int id = hit->rawId() ;
454  if(hit->geographicalId().subdetId()>2) id &= (~3); // mask mono/stereo in strips...
455  if likely(hit->isValid()) { rh1[i].emplace_back(id,hit); std::push_heap(rh1[i].begin(),rh1[i].end(),compById); }
456  }
457  std::sort_heap(rh1[i].begin(),rh1[i].end(),compById);
458  }
459 
460  //DL here
461  if likely(ngood>1 && collsSize>1)
462  for ( unsigned int ltm=0; ltm<listsToMerge_.size(); ltm++) {
463  int saveSelected[rSize];
464  bool notActive[collsSize];
465  for (unsigned int cn=0;cn!=collsSize;++cn)
466  notActive[cn]= find(listsToMerge_[ltm].begin(),listsToMerge_[ltm].end(),cn)==listsToMerge_[ltm].end();
467 
468  for ( unsigned int i=0; i<rSize; i++) saveSelected[i]=selected[i];
469 
470  //DL protect against 0 tracks?
471  for ( unsigned int i=0; i<rSize-1; i++) {
472  if (selected[i]==0) continue;
473  unsigned int collNum=trackCollNum[i];
474 
475  //check that this track is in one of the lists for this iteration
476  if (notActive[collNum]) continue;
477 
478  int k1 = indexG[i];
479  unsigned int nh1=rh1[k1].size();
480  int qualityMaskT1 = trackQuals[i];
481 
482  int nhit1 = nh1; // validHits[k1];
483  float score1 = score[k1];
484 
485  // start at next collection
486  for ( unsigned int j=i+1; j<rSize; j++) {
487  if (selected[j]==0) continue;
488  unsigned int collNum2=trackCollNum[j];
489  if ( (collNum == collNum2) && indivShareFrac_[collNum] > 0.99) continue;
490  //check that this track is in one of the lists for this iteration
491  if (notActive[collNum2]) continue;
492 
493  int k2 = indexG[j];
494 
495  int newQualityMask = -9; //avoid resetting quality mask if not desired 10+ -9 =1
496  if (promoteQuality_[ltm]) {
497  int maskT1= saveSelected[i]>1? saveSelected[i]-10 : qualityMaskT1;
498  int maskT2= saveSelected[j]>1? saveSelected[j]-10 : trackQuals[j];
499  newQualityMask =(maskT1 | maskT2); // take OR of trackQuality
500  }
501  unsigned int nh2=rh1[k2].size();
502  int nhit2 = nh2;
503 
504 
505  auto share = use_sharesInput_ ?
506  [](const TrackingRecHit* it,const TrackingRecHit* jt, float)->bool { return it->sharesInput(jt,TrackingRecHit::some); } :
507  [](const TrackingRecHit* it,const TrackingRecHit* jt, float eps)->bool {
508  float delta = std::abs ( it->localPosition().x()-jt->localPosition().x() );
509  return (it->geographicalId()==jt->geographicalId())&&(delta<eps);
510  };
511 
512  statCount.start();
513 
514  //loop over rechits
515  int noverlap=0;
516  int firstoverlap=0;
517  // check first hit (should use REAL first hit?)
518  if unlikely(allowFirstHitShare_ && rh1[k1][0].first==rh1[k2][0].first ) {
519  const TrackingRecHit* it = rh1[k1][0].second;
520  const TrackingRecHit* jt = rh1[k2][0].second;
521  if (share(it,jt,epsilon_)) firstoverlap=1;
522  }
523 
524 
525  // exploit sorting
526  unsigned int jh=0;
527  unsigned int ih=0;
528  while (ih!=nh1 && jh!=nh2) {
529  // break if not enough to go...
530  // if ( nprecut-noverlap+firstoverlap > int(nh1-ih)) break;
531  // if ( nprecut-noverlap+firstoverlap > int(nh2-jh)) break;
532  auto const id1 = rh1[k1][ih].first;
533  auto const id2 = rh1[k2][jh].first;
534  if (id1<id2) ++ih;
535  else if (id2<id1) ++jh;
536  else {
537  // in case of split-hit do full conbinatorics
538  auto li=ih; while( (++li)!=nh1 && id1 == rh1[k1][li].first);
539  auto lj=jh; while( (++lj)!=nh2 && id2 == rh1[k2][lj].first);
540  for (auto ii=ih; ii!=li; ++ii)
541  for (auto jj=jh; jj!=lj; ++jj) {
542  const TrackingRecHit* it = rh1[k1][ii].second;
543  const TrackingRecHit* jt = rh1[k2][jj].second;
544  if (share(it,jt,epsilon_)) noverlap++;
545  }
546  jh=lj; ih=li;
547  } // equal ids
548 
549  } //loop over ih & jh
550 
551  bool dupfound = (collNum != collNum2) ? (noverlap-firstoverlap) > (std::min(nhit1,nhit2)-firstoverlap)*shareFrac_ :
552  (noverlap-firstoverlap) > (std::min(nhit1,nhit2)-firstoverlap)*indivShareFrac_[collNum];
553 
554  auto seti = [&](unsigned int ii, unsigned int jj) {
555  selected[jj]=0;
556  selected[ii]=10+newQualityMask; // add 10 to avoid the case where mask = 1
557  trkUpdated[ii]=true;
558  if (trackAlgoPriorityOrder[oriAlgo[jj]] < trackAlgoPriorityOrder[oriAlgo[ii]]) oriAlgo[ii] = oriAlgo[jj];
559  algoMask[ii] |= algoMask[jj];
560  algoMask[jj] = algoMask[ii]; // in case we keep discarded
561  };
562 
563  if ( dupfound ) {
564  float score2 = score[k2];
565  constexpr float almostSame = 0.01f; // difference rather than ratio due to possible negative values for score
566  if ( score1 - score2 > almostSame ) {
567  seti(i,j);
568  } else if ( score2 - score1 > almostSame ) {
569  seti(j,i);
570  }else{
571  // If tracks from both iterations are virtually identical, choose the one with the best quality or with lower algo
574  //same quality, pick earlier algo
575  if (trackAlgoPriorityOrder[algo[k1]] <= trackAlgoPriorityOrder[algo[k2]]) {
576  seti(i,j);
577  } else {
578  seti(j,i);
579  }
580  } else if ((trackQuals[j] & (1<<reco::TrackBase::loose|1<<reco::TrackBase::tight|1<<reco::TrackBase::highPurity) ) <
582  seti(i,j);
583  }else{
584  seti(j,i);
585  }
586  }//end fi < fj
587  statCount.overlap();
588  /*
589  if (at0[k1]&&at0[k2]) {
590  statCount.dp(dphi);
591  if (dz<1.f) statCount.de(deta);
592  }
593  */
594  }//end got a duplicate
595  else {
596  statCount.noOverlap();
597  }
598  //stop if the ith track is now unselected
599  if (selected[i]==0) break;
600  }//end track2 loop
601  }//end track loop
602  } //end loop over track list sets
603 
604 
605 
606  std::auto_ptr<edm::ValueMap<float> > vmMVA = std::auto_ptr<edm::ValueMap<float> >(new edm::ValueMap<float>);
607  edm::ValueMap<float>::Filler fillerMVA(*vmMVA);
608 
609 
610 
611  // special case - if just doing the trkquals
612  if (trkQualMod_) {
613  unsigned int tSize=trackColls[0]->size();
614  std::auto_ptr<edm::ValueMap<int> > vm = std::auto_ptr<edm::ValueMap<int> >(new edm::ValueMap<int>);
615  edm::ValueMap<int>::Filler filler(*vm);
616 
617  std::vector<int> finalQuals(tSize,-1); //default is unselected
618  for ( unsigned int i=0; i<rSize; i++) {
619  unsigned int tNum=i%tSize;
620 
621  if (selected[i]>1 ) {
622  finalQuals[tNum]=selected[i]-10;
623  if (trkUpdated[i])
624  finalQuals[tNum]=(finalQuals[tNum] | (1<<qualityToSet_));
625  }
626  if ( selected[i]==1 )
627  finalQuals[tNum]=trackQuals[i];
628  }
629 
630  filler.insert(trackHandles[0], finalQuals.begin(),finalQuals.end());
631  filler.fill();
632 
633  e.put(vm);
634  for (auto & q : finalQuals) q=std::max(q,0);
635  auto quals = std::make_unique<QualityMaskCollection>(finalQuals.begin(),finalQuals.end());
636  e.put(std::move(quals),"QualityMasks");
637 
638  std::vector<float> mvaVec(tSize,-99);
639 
640  for(unsigned int i = 0; i < rSize; i++){
641  unsigned int tNum = i % tSize;
642  mvaVec[tNum] = trackMVAs[tNum];
643  }
644 
645  fillerMVA.insert(trackHandles[0],mvaVec.begin(),mvaVec.end());
646  fillerMVA.fill();
647  if ( copyMVA_) {
648  e.put(vmMVA,"MVAVals");
649  auto mvas = std::make_unique<MVACollection>(mvaVec.begin(),mvaVec.end());
650  e.put(std::move(mvas),"MVAValues");
651  }
652  return;
653  }
654 
655 
656  //
657  // output selected tracks - if any
658  //
659 
660  std::vector<reco::TrackRef> trackRefs(rSize);
661  std::vector<edm::RefToBase<TrajectorySeed>> seedsRefs(rSize);
662 
663  unsigned int nToWrite=0;
664  for ( unsigned int i=0; i<rSize; i++)
665  if (selected[i]!=0) nToWrite++;
666 
667  std::vector<float> mvaVec;
668 
669  outputTrks = std::auto_ptr<reco::TrackCollection>(new reco::TrackCollection);
670  outputTrks->reserve(nToWrite);
672 
673  if (copyExtras_) {
674  outputTrkExtras = std::auto_ptr<reco::TrackExtraCollection>(new reco::TrackExtraCollection);
675  outputTrkExtras->reserve(nToWrite);
677  outputTrkHits = std::auto_ptr<TrackingRecHitCollection>(new TrackingRecHitCollection);
678  outputTrkHits->reserve(nToWrite*25);
680  if (makeReKeyedSeeds_){
681  outputSeeds = std::auto_ptr<TrajectorySeedCollection>(new TrajectorySeedCollection);
682  outputSeeds->reserve(nToWrite);
684  }
685  }
686 
687 
688  outputTrajs = std::auto_ptr< std::vector<Trajectory> >(new std::vector<Trajectory>());
689  outputTrajs->reserve(rSize);
690 
691  for ( unsigned int i=0; i<rSize; i++) {
692  if (selected[i]==0) {
693  trackRefs[i]=reco::TrackRef();
694  continue;
695  }
696 
697  unsigned int collNum=trackCollNum[i];
698  unsigned int trackNum=i-trackCollFirsts[collNum];
699  const reco::Track *track=&((trackColls[collNum])->at(trackNum));
700  outputTrks->push_back( reco::Track( *track ) );
701  mvaVec.push_back(trackMVAs[i]);
702  if (selected[i]>1 ) {
703  outputTrks->back().setQualityMask(selected[i]-10);
704  if (trkUpdated[i])
705  outputTrks->back().setQuality(qualityToSet_);
706  }
707  //might duplicate things, but doesnt hurt
708  if ( selected[i]==1 )
709  outputTrks->back().setQualityMask(trackQuals[i]);
710  outputTrks->back().setOriginalAlgorithm(oriAlgo[i]);
711  outputTrks->back().setAlgoMask(algoMask[i]);
712 
713  // if ( beVerb ) std::cout << "selected " << outputTrks->back().pt() << " " << outputTrks->back().qualityMask() << " " << selected[i] << std::endl;
714 
715  //fill the TrackCollection
716  if (copyExtras_) {
717  edm::RefToBase<TrajectorySeed> origSeedRef = track->seedRef();
718  //creating a seed with rekeyed clusters if required
719  if (makeReKeyedSeeds_){
720  bool doRekeyOnThisSeed=false;
721 
722  edm::InputTag clusterRemovalInfos("");
723  //grab on of the hits of the seed
724  if (origSeedRef->nHits()!=0){
725  TrajectorySeed::const_iterator firstHit=origSeedRef->recHits().first;
726  const TrackingRecHit *hit = &*firstHit;
727  if (firstHit->isValid()){
728  edm::ProductID pID=clusterProductB(hit);
729  // the cluster collection either produced a removalInfo or mot
730  //get the clusterremoval info from the provenance: will rekey if this is found
732  edm::Provenance prov=e.getProvenance(pID);
733  clusterRemovalInfos=edm::InputTag(prov.moduleLabel(),
734  prov.productInstanceName(),
735  prov.processName());
736  doRekeyOnThisSeed=e.getByLabel(clusterRemovalInfos,CRIh);
737  }//valid hit
738  }//nhit!=0
739 
740  if (doRekeyOnThisSeed && !(clusterRemovalInfos==edm::InputTag(""))) {
741  ClusterRemovalRefSetter refSetter(e,clusterRemovalInfos);
742  TrajectorySeed::recHitContainer newRecHitContainer;
743  newRecHitContainer.reserve(origSeedRef->nHits());
744  TrajectorySeed::const_iterator iH=origSeedRef->recHits().first;
745  TrajectorySeed::const_iterator iH_end=origSeedRef->recHits().second;
746  for (;iH!=iH_end;++iH){
747  newRecHitContainer.push_back(*iH);
748  refSetter.reKey(&newRecHitContainer.back());
749  }
750  outputSeeds->push_back( TrajectorySeed( origSeedRef->startingState(),
751  newRecHitContainer,
752  origSeedRef->direction()));
753  }
754  //doRekeyOnThisSeed=true
755  else{
756  //just copy the one we had before
757  outputSeeds->push_back( TrajectorySeed(*origSeedRef));
758  }
760  origSeedRef=edm::RefToBase<TrajectorySeed>( pureRef);
761  }//creating a new seed and rekeying it rechit clusters.
762 
763  // Fill TrackExtra collection
764  outputTrkExtras->push_back( reco::TrackExtra(
765  track->outerPosition(), track->outerMomentum(), track->outerOk(),
766  track->innerPosition(), track->innerMomentum(), track->innerOk(),
767  track->outerStateCovariance(), track->outerDetId(),
768  track->innerStateCovariance(), track->innerDetId(),
769  track->seedDirection(), origSeedRef ) );
770  seedsRefs[i]=origSeedRef;
771  outputTrks->back().setExtra( reco::TrackExtraRef( refTrkExtras, outputTrkExtras->size() - 1) );
772  reco::TrackExtra & tx = outputTrkExtras->back();
773  tx.setResiduals(track->residuals());
774 
775  // fill TrackingRecHits
776  unsigned nh1=track->recHitsSize();
777  tx.setHits(refTrkHits,outputTrkHits->size(),nh1);
778  for (auto hh = track->recHitsBegin(), eh=track->recHitsEnd(); hh!=eh; ++hh ) {
779  outputTrkHits->push_back( (*hh)->clone() );
780  }
781  }
782  trackRefs[i] = reco::TrackRef(refTrks, outputTrks->size() - 1);
783 
784 
785  }//end faux loop over tracks
786 
787  //Fill the trajectories, etc. for 1st collection
788  refTrajs = e.getRefBeforePut< std::vector<Trajectory> >();
789 
790  outputTTAss = std::auto_ptr< TrajTrackAssociationCollection >(new TrajTrackAssociationCollection(refTrajs, refTrks));
791 
792  for (unsigned int ti=0; ti<trackColls.size(); ti++) {
795  e.getByToken(trackProducers_[ti].traj, hTraj1);
796  e.getByToken(trackProducers_[ti].tass, hTTAss1);
797 
798  if (hTraj1.failedToGet() || hTTAss1.failedToGet()) continue;
799 
800  for (size_t i = 0, n = hTraj1->size(); i < n; ++i) {
801  edm::Ref< std::vector<Trajectory> > trajRef(hTraj1, i);
802  TrajTrackAssociationCollection::const_iterator match = hTTAss1->find(trajRef);
803  if (match != hTTAss1->end()) {
804  const edm::Ref<reco::TrackCollection> &trkRef = match->val;
805  uint32_t oldKey = trackCollFirsts[ti]+static_cast<uint32_t>(trkRef.key());
806  if (trackRefs[oldKey].isNonnull()) {
807  outputTrajs->push_back( *trajRef );
808  //if making extras and the seeds at the same time, change the seed ref on the trajectory
810  outputTrajs->back().setSeedRef( seedsRefs[oldKey] );
811  outputTTAss->insert ( edm::Ref< std::vector<Trajectory> >(refTrajs, outputTrajs->size() - 1),
812  trackRefs[oldKey] );
813  }
814  }
815  }
816  }
817 
818  statCount.end(outputTrks->size());
819 
820  edm::ProductID nPID = refTrks.id();
822  fillerMVA.insert(outHandle,mvaVec.begin(),mvaVec.end());
823  fillerMVA.fill();
824 
825  e.put(outputTrks);
826  if ( copyMVA_ ) {
827  e.put(vmMVA,"MVAVals");
828  auto mvas = std::make_unique<MVACollection>(mvaVec.begin(),mvaVec.end());
829  e.put(std::move(mvas),"MVAValues");
830  }
831  if (copyExtras_) {
832  e.put(outputTrkExtras);
833  e.put(outputTrkHits);
834  if (makeReKeyedSeeds_)
835  e.put(outputSeeds);
836  }
837  e.put(outputTrajs);
838  e.put(outputTTAss);
839  return;
840 
841  }//end produce
842 
843 
846 
848 
PropagationDirection direction() const
std::auto_ptr< reco::TrackCollection > outputTrks
dbl * delta
Definition: mlp_gen.cc:36
T getParameter(std::string const &) const
#define dso_hidden
T getUntrackedParameter(std::string const &, T const &) const
int i
Definition: DBlmapReader.cc:9
TrackListMerger(const edm::ParameterSet &conf)
std::vector< unsigned char > QualityMaskCollection
reference back()
Definition: OwnVector.h:401
tuple start
Check for commandline option errors.
Definition: dqm_diff.py:58
std::vector< bool > promoteQuality_
reco::TrackRefProd refTrks
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:462
edm::EDGetTokenT< TrajTrackAssociationCollection > tass
edm::RefProd< std::vector< Trajectory > > refTrajs
TkEDGetTokenss edTokens(const edm::InputTag &tag, const edm::InputTag &mvatag)
virtual void produce(Event &, EventSetup const &)=0
TrackQuality
track quality
Definition: TrackBase.h:151
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
size_t recHitsSize() const
Get number of RecHits. (Warning, this includes invalid hits, which are not physical hits)...
Definition: Track.h:119
void setHits(TrackingRecHitRefProd const &prod, unsigned firstH, unsigned int nH)
std::vector< ParameterSet > VParameterSet
Definition: ParameterSet.h:33
std::string print(const Track &, edm::Verbosity=edm::Concise)
Track print utility.
Definition: print.cc:10
void reKey(TrackingRecHit *hit) const
assert(m_qm.get())
reco::TrackBase::TrackQuality qualityToSet_
std::vector< Track > TrackCollection
collection of Tracks
Definition: TrackFwd.h:14
bool exists(std::string const &parameterName) const
checks if a parameter exists
bool innerOk() const
return true if the innermost hit is valid
Definition: Track.h:50
unsigned short numberOfLostHits() const
number of cases where track crossed a layer without getting a hit.
Definition: TrackBase.h:821
key_type key() const
Accessor for product key.
Definition: Ref.h:264
int ii
Definition: cuy.py:588
std::string const & processName() const
Definition: Provenance.h:52
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:7
const math::XYZPoint & outerPosition() const
position of the outermost hit
Definition: Track.h:65
std::vector< float > MVACollection
edm::RefProd< TrajectorySeedCollection > refTrajSeeds
#define constexpr
ProductID id() const
Accessor for product ID.
Definition: Ref.h:258
TrackAlgorithm
track algorithm
Definition: TrackBase.h:99
TrackingRecHitRefProd refTrkHits
virtual void produce(edm::Event &e, const edm::EventSetup &c) override
std::vector< double > indivShareFrac_
bool overlap(const reco::Muon &muon1, const reco::Muon &muon2, double pullX=1.0, double pullY=1.0, bool checkAdjacentChambers=false)
const math::XYZPoint & innerPosition() const
position of the innermost hit
Definition: Track.h:55
TrackAlgorithm algo() const
Definition: TrackBase.h:492
#define unlikely(x)
tuple d
Definition: ztail.py:151
#define likely(x)
void push_back(D *&d)
Definition: OwnVector.h:290
std::auto_ptr< TrackingRecHitCollection > outputTrkHits
edm::EDGetTokenT< edm::ValueMap< int > > tsel
std::vector< TrajectorySeed > TrajectorySeedCollection
double chi2() const
chi-squared of the fit
Definition: TrackBase.h:544
OrphanHandle< PROD > put(std::auto_ptr< PROD > product)
Put a new product.
Definition: Event.h:121
recHitContainer::const_iterator const_iterator
CovarianceMatrix outerStateCovariance() const
outermost trajectory state curvilinear errors
Definition: Track.h:75
def move
Definition: eostools.py:510
edm::EDGetTokenT< reco::TrackCollection > tk
unsigned int outerDetId() const
DetId of the detector on which surface the outermost state is located.
Definition: Track.h:94
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
int j
Definition: DBlmapReader.cc:9
TkEDGetTokenss edTokens(const edm::InputTag &tag, const edm::InputTag &seltag, const edm::InputTag &mvatag)
unsigned short numberOfValidHits() const
number of valid hits found
Definition: TrackBase.h:815
#define end
Definition: vmac.h:37
T min(T a, T b)
Definition: MathUtil.h:58
std::auto_ptr< TrajTrackAssociationCollection > outputTTAss
trackingRecHit_iterator recHitsBegin() const
Iterator to first hit on the track.
Definition: Track.h:104
virtual ~TrackListMerger()
edm::AssociationMap< edm::OneToOne< std::vector< Trajectory >, reco::TrackCollection, unsigned short > > TrajTrackAssociationCollection
int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:37
std::auto_ptr< std::vector< Trajectory > > outputTrajs
std::auto_ptr< TrajectorySeedCollection > outputSeeds
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:418
RefProd< PROD > getRefBeforePut()
Definition: Event.h:141
std::vector< int > hasSelector_
bool failedToGet() const
Definition: HandleBase.h:79
std::vector< TrackExtra > TrackExtraCollection
collection of TrackExtra objects
Definition: TrackExtraFwd.h:11
double maxNormalizedChisq_
edm::OwnVector< TrackingRecHit > TrackingRecHitCollection
collection of TrackingRecHits
edm::RefToBase< TrajectorySeed > seedRef() const
Definition: Track.h:213
PTrajectoryStateOnDet const & startingState() const
static TrackQuality qualityByName(const std::string &name)
Definition: TrackBase.cc:125
const math::XYZVector & outerMomentum() const
momentum vector at the outermost hit position
Definition: Track.h:70
bool outerOk() const
return true if the outermost hit is valid
Definition: Track.h:45
const HitPattern & hitPattern() const
Access the hit pattern, indicating in which Tracker layers the track has hits.
Definition: TrackBase.h:445
edm::EDGetTokenT< edm::ValueMap< float > > tmva
auto dp
Definition: deltaR.h:22
edm::Ref< TrackCollection > TrackRef
persistent reference to a Track
Definition: TrackFwd.h:20
CovarianceMatrix innerStateCovariance() const
innermost trajectory state curvilinear errors
Definition: Track.h:80
std::array< unsigned int, reco::TrackBase::algoSize > trackAlgoPriorityOrder
range recHits() const
bool isValid() const
std::string const & moduleLabel() const
Definition: Provenance.h:51
std::auto_ptr< reco::TrackExtraCollection > outputTrkExtras
unsigned int nHits() const
#define begin
Definition: vmac.h:30
unsigned int minFound_
std::vector< TkEDGetTokenss > trackProducers_
const math::XYZVector & innerMomentum() const
momentum vector at the innermost hit position
Definition: Track.h:60
ProductID id() const
Accessor for product ID.
Definition: RefProd.h:137
const TrackResiduals & residuals() const
Definition: Track.h:220
int numberOfValidPixelHits() const
Definition: HitPattern.h:838
edm::EDGetTokenT< std::vector< Trajectory > > traj
PropagationDirection seedDirection() const
direction of how the hits were sorted in the original seed
Definition: Track.h:204
tuple cout
Definition: gather_cfg.py:145
std::pair< typename Association::data_type::first_type, double > match(Reference key, Association association, bool bestMatchByMaxValue)
Generic matching function.
Definition: Utils.h:10
TkEDGetTokenss(const edm::InputTag &tag_, edm::EDGetTokenT< reco::TrackCollection > &&tk_, edm::EDGetTokenT< std::vector< Trajectory > > &&traj_, edm::EDGetTokenT< TrajTrackAssociationCollection > &&tass_, edm::EDGetTokenT< edm::ValueMap< int > > &&tsel_, edm::EDGetTokenT< edm::ValueMap< float > > &&tmva_)
DetId geographicalId() const
std::string const & productInstanceName() const
Definition: Provenance.h:53
std::vector< std::vector< int > > listsToMerge_
Provenance getProvenance(BranchID const &theID) const
Definition: Event.cc:80
T x() const
Definition: PV3DBase.h:62
virtual LocalPoint localPosition() const =0
unsigned int innerDetId() const
DetId of the detector on which surface the innermost state is located.
Definition: Track.h:99
id_type rawId() const
void reserve(size_t)
Definition: OwnVector.h:284
reco::TrackExtraRefProd refTrkExtras
TrackingRecHitCollection::base::const_iterator trackingRecHit_iterator
iterator over a vector of reference to TrackingRecHit in the same collection
trackingRecHit_iterator recHitsEnd() const
Iterator to last hit on the track.
Definition: Track.h:109
void setResiduals(const TrackResiduals &r)
set the residuals
Definition: TrackExtra.h:179