CMS 3D CMS Logo

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