CMS 3D CMS Logo

ConversionTrackMerger.cc
Go to the documentation of this file.
1 //
2 // Package: RecoTracker/FinalTrackSelectors
3 // Class: ConversionTrackMerger
4 //
5 // Description: Merger for ConversionTracks, adapted from SimpleTrackListMerger
6 //
7 // Original Author: J.Bendavid
8 //
9 //
10 
11 #include <memory>
12 #include <string>
13 #include <iostream>
14 #include <cmath>
15 #include <vector>
16 
18 
24 
26 
28 
32 
33 //#include "DataFormats/TrackReco/src/classes.h"
34 
36 
37 
39  conf_(conf)
40  {
41  // retrieve producer name of input TrackCollection(s)
42  trackProducer1 = consumes<reco::ConversionTrackCollection>(conf_.getParameter<edm::InputTag>("TrackProducer1"));
43  trackProducer2 = consumes<reco::ConversionTrackCollection>(conf_.getParameter<edm::InputTag>("TrackProducer2"));
44 
45  produces<reco::ConversionTrackCollection>();
46 
47  }
48 
49 
50  // Virtual destructor needed.
52 
53  // Functions that gets called by framework every event
55  {
56 
57 
58  double shareFrac = conf_.getParameter<double>("ShareFrac");
59  bool allowFirstHitShare = conf_.getParameter<bool>("allowFirstHitShare");
60  bool checkCharge = conf_.getParameter<bool>("checkCharge");
61  double minProb = conf_.getParameter<double>("minProb");
62 
63  int outputPreferCollection = conf_.getParameter<int>("outputPreferCollection");
64  int trackerOnlyPreferCollection = conf_.getParameter<int>("trackerOnlyPreferCollection");
65  int arbitratedEcalSeededPreferCollection = conf_.getParameter<int>("arbitratedEcalSeededPreferCollection");
66  int arbitratedMergedPreferCollection = conf_.getParameter<int>("arbitratedMergedPreferCollection");
67  int arbitratedMergedEcalGeneralPreferCollection = conf_.getParameter<int>("arbitratedMergedEcalGeneralPreferCollection");
68 
69  // get Inputs
70  // if 1 input list doesn't exist, make an empty list, issue a warning, and continue
71  // this allows ConversionTrackMerger to be used as a cleaner only if handed just one list
72  // if both input lists don't exist, will issue 2 warnings and generate an empty output collection
73  //
74  const reco::ConversionTrackCollection *TC1 = nullptr;
75  static const reco::ConversionTrackCollection s_empty1, s_empty2;
77  e.getByToken(trackProducer1, trackCollection1);
78  if (trackCollection1.isValid()) {
79  TC1 = trackCollection1.product();
80  //std::cout << "1st collection " << trackProducer1 << " has "<< TC1->size() << " tracks" << std::endl ;
81  } else {
82  TC1 = &s_empty1;
83  edm::LogWarning("ConversionTrackMerger")
84  << "1st TrackCollection not found;"
85  << " will only clean 2nd TrackCollection ";
86  }
88 
89  const reco::ConversionTrackCollection *TC2 = nullptr;
91  e.getByToken(trackProducer2, trackCollection2);
92  if (trackCollection2.isValid()) {
93  TC2 = trackCollection2.product();
94  //std::cout << "2nd collection " << trackProducer2 << " has "<< TC2->size() << " tracks" << std::endl ;
95  } else {
96  TC2 = &s_empty2;
97  edm::LogWarning("ConversionTrackMerger")
98  << "2nd TrackCollection not found;"
99  <<" will only clean 1st TrackCollection ";
100  }
102 
103  // Step B: create empty output collection
104  outputTrks = std::make_unique<reco::ConversionTrackCollection>();
105  int i;
106 
107  std::vector<int> selected1; for (unsigned int i=0; i<tC1.size(); ++i){selected1.push_back(1);}
108  std::vector<int> selected2; for (unsigned int i=0; i<tC2.size(); ++i){selected2.push_back(1);}
109 
110 
111  std::map<reco::ConversionTrackCollection::const_iterator, std::vector<const TrackingRecHit*> > rh1;
112  std::map<reco::ConversionTrackCollection::const_iterator, std::vector<const TrackingRecHit*> > rh2;
113  for (reco::ConversionTrackCollection::const_iterator track=tC1.begin(); track!=tC1.end(); ++track){
114  trackingRecHit_iterator itB = track->track()->recHitsBegin();
115  trackingRecHit_iterator itE = track->track()->recHitsEnd();
116  for (trackingRecHit_iterator it = itB; it != itE; ++it) {
117  const TrackingRecHit* hit = &(**it);
118  rh1[track].push_back(hit);
119  }
120  }
121  for (reco::ConversionTrackCollection::const_iterator track=tC2.begin(); track!=tC2.end(); ++track){
122  trackingRecHit_iterator jtB = track->track()->recHitsBegin();
123  trackingRecHit_iterator jtE = track->track()->recHitsEnd();
124  for (trackingRecHit_iterator jt = jtB; jt != jtE; ++jt) {
125  const TrackingRecHit* hit = &(**jt);
126  rh2[track].push_back(hit);
127  }
128  }
129 
130  if ( (!tC1.empty())&&(!tC2.empty()) ){
131  i=-1;
132  for (reco::ConversionTrackCollection::iterator track=tC1.begin(); track!=tC1.end(); ++track){
133  i++;
134 
135  //clear flags if preferCollection was set to 0
136  selected1[i] = selected1[i] && outputPreferCollection!=0;
137  track->setIsTrackerOnly ( track->isTrackerOnly() && trackerOnlyPreferCollection!=0 );
138  track->setIsArbitratedEcalSeeded( track->isArbitratedEcalSeeded() && arbitratedEcalSeededPreferCollection!=0 );
139  track->setIsArbitratedMerged( track->isArbitratedMerged() && arbitratedMergedPreferCollection!=0 );
140  track->setIsArbitratedMergedEcalGeneral( track->isArbitratedMergedEcalGeneral() && arbitratedMergedEcalGeneralPreferCollection!=0 );
141 
142 
143  std::vector<const TrackingRecHit*>& iHits = rh1[track];
144  unsigned nh1 = iHits.size();
145  int j=-1;
146  for (reco::ConversionTrackCollection::iterator track2=tC2.begin(); track2!=tC2.end(); ++track2){
147  j++;
148 
149  //clear flags if preferCollection was set to 0
150  selected2[j] = selected2[j] && outputPreferCollection!=0;
151  track2->setIsTrackerOnly ( track2->isTrackerOnly() && trackerOnlyPreferCollection!=0 );
152  track2->setIsArbitratedEcalSeeded( track2->isArbitratedEcalSeeded() && arbitratedEcalSeededPreferCollection!=0 );
153  track2->setIsArbitratedMerged( track2->isArbitratedMerged() && arbitratedMergedPreferCollection!=0 );
154  track2->setIsArbitratedMergedEcalGeneral( track2->isArbitratedMergedEcalGeneral() && arbitratedMergedEcalGeneralPreferCollection!=0 );
155 
156  std::vector<const TrackingRecHit*>& jHits = rh2[track2];
157  unsigned nh2 = jHits.size();
158  int noverlap=0;
159  int firstoverlap=0;
160  for ( unsigned ih=0; ih<nh1; ++ih ) {
161  const TrackingRecHit* it = iHits[ih];
162  if (it->isValid()){
163  int jj=-1;
164  for ( unsigned jh=0; jh<nh2; ++jh ) {
165  const TrackingRecHit* jt = jHits[jh];
166  jj++;
167  if (jt->isValid()){
168  if ( it->sharesInput(jt,TrackingRecHit::some) ) {
169  noverlap++;
170  if ( allowFirstHitShare && ( ih == 0 ) && ( jh == 0 ) ) firstoverlap=1;
171  }
172  }
173  }
174  }
175  }
176  int nhit1 = track->track()->numberOfValidHits();
177  int nhit2 = track2->track()->numberOfValidHits();
178  //if (noverlap>0) printf("noverlap = %i, firstoverlap = %i, nhit1 = %i, nhit2 = %i, algo1 = %i, algo2 = %i, q1 = %i, q2 = %i\n",noverlap,firstoverlap,nhit1,nhit2,track->track()->algo(),track2->track()->algo(),track->track()->charge(),track2->track()->charge());
179  //std::cout << " trk1 trk2 nhits1 nhits2 nover " << i << " " << j << " " << track->numberOfValidHits() << " " << track2->numberOfValidHits() << " " << noverlap << " " << fi << " " << fj <<std::endl;
180  if ( (noverlap-firstoverlap) > (std::min(nhit1,nhit2)-firstoverlap)*shareFrac && (!checkCharge || track->track()->charge()*track2->track()->charge()>0) ) {
181  //printf("overlapping tracks\n");
182  //printf ("ndof1 = %5f, chisq1 = %5f, ndof2 = %5f, chisq2 = %5f\n",track->track()->ndof(),track->track()->chi2(),track2->track()->ndof(),track2->track()->chi2());
183 
184  double probFirst = ChiSquaredProbability(track->track()->chi2(), track->track()->ndof());
185  double probSecond = ChiSquaredProbability(track2->track()->chi2(), track2->track()->ndof());
186 
187  //arbitrate by number of hits and reduced chisq
188  bool keepFirst = ( nhit1>nhit2 || (nhit1==nhit2 && track->track()->normalizedChi2()<track2->track()->normalizedChi2()) );
189 
190  //override decision in case one track is radically worse quality than the other
191  keepFirst |= (probFirst>minProb && probSecond<=minProb);
192  keepFirst &= !(probFirst<=minProb && probSecond>minProb);
193 
194  bool keepSecond = !keepFirst;
195 
196  //set flags based on arbitration decision and precedence settings
197 
198  selected1[i] = selected1[i] && ( (keepFirst && outputPreferCollection==3) || outputPreferCollection==-1 || outputPreferCollection==1 );
199  track->setIsTrackerOnly ( track->isTrackerOnly() && ( (keepFirst && trackerOnlyPreferCollection==3) || trackerOnlyPreferCollection==-1 || trackerOnlyPreferCollection==1 ) );
200  track->setIsArbitratedEcalSeeded( track->isArbitratedEcalSeeded() && ( (keepFirst && arbitratedEcalSeededPreferCollection==3) || arbitratedEcalSeededPreferCollection==-1 || arbitratedEcalSeededPreferCollection==1 ) );
201  track->setIsArbitratedMerged( track->isArbitratedMerged() && ( (keepFirst && arbitratedMergedPreferCollection==3) || arbitratedMergedPreferCollection==-1 || arbitratedMergedPreferCollection==1 ) );
202  track->setIsArbitratedMergedEcalGeneral( track->isArbitratedMergedEcalGeneral() && ( (keepFirst && arbitratedMergedEcalGeneralPreferCollection==3) || arbitratedMergedEcalGeneralPreferCollection==-1 || arbitratedMergedEcalGeneralPreferCollection==1 ) );
203 
204  selected2[j] = selected2[j] && ( (keepSecond && outputPreferCollection==3) || outputPreferCollection==-1 || outputPreferCollection==2 );
205  track2->setIsTrackerOnly ( track2->isTrackerOnly() && ( (keepSecond && trackerOnlyPreferCollection==3) || trackerOnlyPreferCollection==-1 || trackerOnlyPreferCollection==2 ) );
206  track2->setIsArbitratedEcalSeeded( track2->isArbitratedEcalSeeded() && ( (keepSecond && arbitratedEcalSeededPreferCollection==3) || arbitratedEcalSeededPreferCollection==-1 || arbitratedEcalSeededPreferCollection==2 ) );
207  track2->setIsArbitratedMerged( track2->isArbitratedMerged() && ( (keepSecond && arbitratedMergedPreferCollection==3) || arbitratedMergedPreferCollection==-1 || arbitratedMergedPreferCollection==2 ) );
208  track2->setIsArbitratedMergedEcalGeneral( track2->isArbitratedMergedEcalGeneral() && ( (keepSecond && arbitratedMergedEcalGeneralPreferCollection==3) || arbitratedMergedEcalGeneralPreferCollection==-1 || arbitratedMergedEcalGeneralPreferCollection==2 ) );
209 
210  }//end got a duplicate
211  }//end track2 loop
212  }//end track loop
213  }//end more than 1 track
214 
215  //
216  // output selected tracks - if any
217  //
218 
219  if ( !tC1.empty() ){
220  i=0;
221  for (reco::ConversionTrackCollection::const_iterator track=tC1.begin(); track!=tC1.end();
222  ++track, ++i){
223  //don't store tracks rejected as duplicates
224  if (!selected1[i]){
225  continue;
226  }
227  //fill the TrackCollection
228  outputTrks->push_back(*track);
229  }//end faux loop over tracks
230  }//end more than 0 track
231 
232  //Fill the trajectories, etc. for 1st collection
233 
234 
235  if ( !tC2.empty() ){
236  i=0;
237  for (reco::ConversionTrackCollection::const_iterator track=tC2.begin(); track!=tC2.end();
238  ++track, ++i){
239  //don't store tracks rejected as duplicates
240  if (!selected2[i]){
241  continue;
242  }
243  //fill the TrackCollection
244  outputTrks->push_back(*track);
245  }//end faux loop over tracks
246  }//end more than 0 track
247 
249  return;
250 
251  }//end produce
T getParameter(std::string const &) const
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:137
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:579
virtual bool sharesInput(const TrackingRecHit *other, SharedInputType what) const
edm::EDGetTokenT< reco::ConversionTrackCollection > trackProducer1
std::vector< ConversionTrack > ConversionTrackCollection
collection of ConversionTracks
std::unique_ptr< reco::ConversionTrackCollection > outputTrks
float ChiSquaredProbability(double chiSquared, double nrDOF)
ConversionTrackMerger(const edm::ParameterSet &conf)
T min(T a, T b)
Definition: MathUtil.h:58
bool isValid() const
Definition: HandleBase.h:74
T const * product() const
Definition: Handle.h:81
bool isValid() const
def move(src, dest)
Definition: eostools.py:511
void produce(edm::Event &e, const edm::EventSetup &c) override
edm::EDGetTokenT< reco::ConversionTrackCollection > trackProducer2