CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
OniaPhotonConversionProducer.cc
Go to the documentation of this file.
8 
12 
15 
17 
18 #include <TMath.h>
19 #include <boost/foreach.hpp>
20 #include <vector>
21 
22 
23 // to order from high to low ProbChi2
25  return TMath::Prob(c1.conversionVertex().chi2(),c1.conversionVertex().ndof()) > TMath::Prob(c2.conversionVertex().chi2(),c2.conversionVertex().ndof());
26 }
27 
28 
30  bool atLeastOneInCommon=false;
31  BOOST_FOREACH(const edm::RefToBase<reco::Track> tk1, c1.tracks()){
32  BOOST_FOREACH(const edm::RefToBase<reco::Track> tk2, c2.tracks()){
33  if(tk1==tk2){
34  atLeastOneInCommon=true;
35  break;
36  }
37  }
38  }
39  return atLeastOneInCommon;
40 }
41 
42 bool lt_(std::pair<double,short> a, std::pair<double,short> b) {
43  return a.first < b.first; }
44 
45 // define operator== for conversions, those with at least one track in common
46 namespace reco {
47  bool operator==(const reco::Conversion& c1, const reco::Conversion& c2) {
48  return c1.tracks()[0] == c2.tracks()[0] ||
49  c1.tracks()[1] == c2.tracks()[1] ||
50  c1.tracks()[1] == c2.tracks()[0] ||
51  c1.tracks()[0] == c2.tracks()[1] ;
52  }
53 }
54 
56  convCollectionToken_ = consumes<reco::ConversionCollection>(ps.getParameter<edm::InputTag>("conversions"));
57  thePVsToken_ = consumes<reco::VertexCollection>(ps.getParameter<edm::InputTag>("primaryVertexTag"));
58 
59  wantTkVtxCompatibility_ = ps.getParameter<bool>("wantTkVtxCompatibility");
60  sigmaTkVtxComp_ = ps.getParameter<uint32_t>("sigmaTkVtxComp");
61  wantCompatibleInnerHits_ = ps.getParameter<bool>("wantCompatibleInnerHits");
62  TkMinNumOfDOF_ = ps.getParameter<uint32_t>("TkMinNumOfDOF");
63 
64  wantHighpurity_ = ps.getParameter<bool>("wantHighpurity");
65  _vertexChi2ProbCut = ps.getParameter<double>("vertexChi2ProbCut");
66  _trackchi2Cut = ps.getParameter<double>("trackchi2Cut");
67  _minDistanceOfApproachMinCut = ps.getParameter<double>("minDistanceOfApproachMinCut");
68  _minDistanceOfApproachMaxCut = ps.getParameter<double>("minDistanceOfApproachMaxCut");
69 
70  pfCandidateCollectionToken_ = consumes<reco::PFCandidateCollection>(ps.getParameter<edm::InputTag>("pfcandidates"));
71 
72  pi0OnlineSwitch_ = ps.getParameter<bool>("pi0OnlineSwitch");
73  pi0SmallWindow_ = ps.getParameter<std::vector<double> >("pi0SmallWindow");
74  pi0LargeWindow_ = ps.getParameter<std::vector<double> >("pi0LargeWindow");
75 
76  std::string algo = ps.getParameter<std::string>("convAlgo");
77  convAlgo_ = StringToEnumValue<reco::Conversion::ConversionAlgorithm>(algo);
78 
79  std::vector<std::string> qual = ps.getParameter<std::vector<std::string> >("convQuality");
80  if( qual[0] != "" ) convQuality_ =StringToEnumValue<reco::Conversion::ConversionQuality>(qual);
81 
82  convSelectionCuts_ = ps.getParameter<std::string>("convSelection");
83 
84  produces<pat::CompositeCandidateCollection>("conversions");
85 
87  selection_fail = 0;
88  algo_fail = 0;
89  flag_fail = 0;
90  pizero_fail = 0;
91  duplicates = 0;
92  TkVtxC = 0;
93  CInnerHits = 0;
94  highpurity_count = 0;
95  final_conversion = 0;
96  store_conversion = 0;
97 }
98 
99 
101 
102  std::auto_ptr<reco::ConversionCollection> outCollection(new reco::ConversionCollection);
103  std::auto_ptr<pat::CompositeCandidateCollection> patoutCollection(new pat::CompositeCandidateCollection);
104  std::vector<int> flagCollection;
105 
107  event.getByToken(thePVsToken_, priVtxs);
108 
110  event.getByToken(convCollectionToken_,pConv);
111 
113  event.getByToken(pfCandidateCollectionToken_,pfcandidates);
114 
115  const reco::PFCandidateCollection pfphotons = selectPFPhotons(*pfcandidates);
116 
118 
119  for(reco::ConversionCollection::const_iterator conv = pConv->begin(); conv != pConv->end(); ++conv){
121 
122  if (! ( *convSelection_)(*conv)){
123  selection_fail++;
124  continue; // selection string
125  }
126  if (convAlgo_ != 0 && conv->algo()!= convAlgo_){
127  algo_fail++;
128  continue; // select algorithm
129  }
130  if(convQuality_.size() > 0){
131  bool flagsok=true;
132  for (std::vector<int>::const_iterator flag = convQuality_.begin(); flag!=convQuality_.end(); ++flag){
134  if (!conv->quality(q)) {
135  flagsok=false;
136  break;
137  }
138  }
139  if (!flagsok){
140  flag_fail++;
141  continue;
142  }
143  }
144 
145  bool flag1 = true;
146  bool flag2 = true;
147  bool flag3 = true;
148  bool flag4 = true;
149 
150  // The logic implies that by default this flags are true and if the check are not wanted conversions are saved.
151  // If checks are required and failed then don't save the conversion.
152 
153  bool flagTkVtxCompatibility = true;
154  if (! checkTkVtxCompatibility(*conv,*priVtxs.product())) {
155  flagTkVtxCompatibility = false;
157  TkVtxC++;
158  flag1 = false;
159  }
160  }
161  bool flagCompatibleInnerHits = false;
162  if (conv->tracks().size()==2) {
163  reco::HitPattern hitPatA=conv->tracks().at(0)->hitPattern();
164  reco::HitPattern hitPatB=conv->tracks().at(1)->hitPattern();
165  if ( foundCompatibleInnerHits(hitPatA,hitPatB) && foundCompatibleInnerHits(hitPatB,hitPatA) ) flagCompatibleInnerHits = true;
166  }
167  if (wantCompatibleInnerHits_ && ! flagCompatibleInnerHits) {
168  CInnerHits++;
169  flag2 = false;
170  }
171  bool flagHighpurity = true;
172  if (!HighpuritySubset(*conv,*priVtxs.product())) {
173  flagHighpurity = false;
174  if (wantHighpurity_) {
176  flag3 = false;
177  }
178  }
179  bool pizero_rejected = false;
180  bool large_pizero_window = CheckPi0(*conv, pfphotons, pizero_rejected);
181  if (pi0OnlineSwitch_ && pizero_rejected) {
182  pizero_fail++;
183  flag4 = false;
184  }
185 
186  if (flag1 && flag2 && flag3 && flag4){
187  int flags = PackFlags(*conv,flagTkVtxCompatibility,flagCompatibleInnerHits,flagHighpurity,pizero_rejected,large_pizero_window);
188  flagCollection.push_back(flags);
189  outCollection->push_back(*conv);
191  }
192  }
193  removeDuplicates(*outCollection,flagCollection);
194 
195  int i = -1;
196  for (reco::ConversionCollection::const_iterator conv = outCollection->begin(); conv != outCollection->end(); ++conv){
197  i++;
199  pat_conv->addUserInt("flags",flagCollection.at(i));
200  patoutCollection->push_back(*pat_conv);
201  }
202  store_conversion += patoutCollection->size();
203  event.put(patoutCollection,"conversions");
204 
205  delete convSelection_;
206 }
207 
208 int OniaPhotonConversionProducer::PackFlags(const reco::Conversion& conv, bool flagTkVtxCompatibility,
209  bool flagCompatibleInnerHits, bool flagHighpurity,
210  bool pizero_rejected, bool large_pizero_window ) {
211  int flags = 0;
212  if ( flagTkVtxCompatibility ) flags += 1;
213  if ( flagCompatibleInnerHits ) flags += 2;
214  if ( flagHighpurity ) flags += 4;
215  if ( pizero_rejected ) flags += 8;
216  if ( large_pizero_window ) flags += 16;
217 
218  flags += (conv.algo()*32);
219  int q_mask = 0;
220  std::vector<std::string> s_quals;
221  s_quals.push_back("generalTracksOnly");
222  s_quals.push_back("arbitratedEcalSeeded");
223  s_quals.push_back("arbitratedMerged");
224  s_quals.push_back("arbitratedMergedEcalGeneral");
225  s_quals.push_back("highPurity");
226  s_quals.push_back("highEfficiency");
227  s_quals.push_back("ecalMatched1Track");
228  s_quals.push_back("ecalMatched2Track");
229  std::vector<int> i_quals = StringToEnumValue<reco::Conversion::ConversionQuality>(s_quals);
230  for (std::vector<int>::const_iterator qq = i_quals.begin(); qq!=i_quals.end(); ++qq) {
232  if (conv.quality(q)) q_mask = *qq;
233  }
234  flags += (q_mask*32*8);
235  return flags;
236 }
237 
242  // first sort from high to low chi2 prob
243  std::sort(c.begin(),c.end(),ConversionLessByChi2);
244  int iter1 = 0;
245  // Cycle over all the elements of the collection and compare to all the following,
246  // if two elements have at least one track in common delete the element with the lower chi2
247  while(iter1 < (( (int) c.size() ) - 1) ){
248  int iter2 = iter1+1;
249  while( iter2 < (int) c.size()) if(ConversionEqualByTrack( c[iter1], c[iter2] ) ){
250  c.erase( c.begin() + iter2 );
251  f.erase( f.begin() + iter2 );
252  duplicates++;
253  }else{
254  iter2++; // Increment index only if this element is no duplicate.
255  // If it is duplicate check again the same index since the vector rearranged elements index after erasing
256  }
257  iter1++;
258  }
259 }
260 
262  std::vector< std::pair< double, short> > idx[2];
263  short ik=-1;
264  BOOST_FOREACH(edm::RefToBase<reco::Track> tk, conv.tracks()){
265  ik++;
266  short count=-1;
267  BOOST_FOREACH(const reco::Vertex& vtx,priVtxs){
268  count++;
269 
270  double dz_= tk->dz(vtx.position());
271  double dzError_=tk->dzError();
272  dzError_=sqrt(dzError_*dzError_+vtx.covariance(2,2));
273 
274  if(fabs(dz_)/dzError_ > sigmaTkVtxComp_) continue;
275 
276  idx[ik].push_back(std::pair<double,short>(fabs(dz_),count));
277  }
278  if(idx[ik].size()==0) {return false;}
279 
280  std::stable_sort(idx[ik].begin(),idx[ik].end(),lt_);
281  }
282  if (idx[0][0].second==idx[1][0].second || idx[0][1].second==idx[1][0].second || idx[0][0].second==idx[1][1].second) return true;
283  return false;
284 }
285 
287  size_t count=0;
288  uint32_t oldSubStr=0;
289  for (int i=0; i<hitPatA.numberOfHits(reco::HitPattern::HitCategory::TRACK_HITS) && count<2; i++) {
290  uint32_t hitA = hitPatA.getHitPattern(reco::HitPattern::HitCategory::TRACK_HITS,i);
291  if (!hitPatA.validHitFilter(hitA) || !hitPatA.trackerHitFilter(hitA)) continue;
292 
293  if(hitPatA.getSubStructure(hitA)==oldSubStr && hitPatA.getLayer(hitA)==oldSubStr)
294  continue;
295 
296  if(hitPatB.getTrackerMonoStereo(reco::HitPattern::HitCategory::TRACK_HITS,hitPatA.getSubStructure(hitA),hitPatA.getLayer(hitA)) != 0)
297  return true;
298 
299  oldSubStr=hitPatA.getSubStructure(hitA);
300  count++;
301  }
302  return false;
303 }
304 
307  // select high purity conversions our way:
308  // vertex chi2 cut
310 
311  // d0 cut
312  // Find closest primary vertex
313  int closest_pv_index = 0;
314  int i=0;
315  BOOST_FOREACH(const reco::Vertex& vtx,priVtxs){
316  if( conv.zOfPrimaryVertexFromTracks( vtx.position() ) < conv.zOfPrimaryVertexFromTracks( priVtxs[closest_pv_index].position() ) ) closest_pv_index = i;
317  i++;
318  }
319  // Now check impact parameter wtr with the just found closest primary vertex
320  BOOST_FOREACH(const edm::RefToBase<reco::Track> tk, conv.tracks()) if(-tk->dxy(priVtxs[closest_pv_index].position())*tk->charge()/tk->dxyError()<0) return false;
321 
322  // chi2 of single tracks
323  BOOST_FOREACH(const edm::RefToBase<reco::Track> tk, conv.tracks()) if(tk->normalizedChi2() > _trackchi2Cut) return false;
324 
325  // dof for each track
326  BOOST_FOREACH(const edm::RefToBase<reco::Track> tk, conv.tracks()) if(tk->ndof()< TkMinNumOfDOF_) return false;
327 
328  // distance of approach cut
330 
331  return true;
332 }
333 
335 
337  photonCand->setP4(convertVector(conv.refittedPair4Momentum()));
338  photonCand->setVertex(conv.conversionVertex().position());
339 
340  photonCand->addUserData<reco::Track>( "track0", *conv.tracks()[0] );
341  photonCand->addUserData<reco::Track>( "track1", *conv.tracks()[1] );
342 
343  return photonCand;
344 
345 }
346 
347 // create a collection of PF photons
349  reco::PFCandidateCollection pfphotons;
350  for (reco::PFCandidateCollection::const_iterator cand = pfcandidates.begin(); cand != pfcandidates.end(); ++cand){
351  if (cand->particleId() == reco::PFCandidate::gamma) pfphotons.push_back(*cand);
352  }
353  return pfphotons;
354 }
355 
357  bool &pizero_rejected ) {
358  // 2 windows are defined for Pi0 rejection, Conversions that, paired with others photons from the event, have an
359  // invariant mass inside the "small" window will be pizero_rejected and those that falls in the large window will
360  // be CheckPi0.
361  bool check_small = false;
362  bool check_large = false;
363 
364  float small1 = pi0SmallWindow_[0];
365  float small2 = pi0SmallWindow_[1];
366  float large1 = pi0LargeWindow_[0];
367  float large2 = pi0LargeWindow_[1];
368  for (reco::PFCandidateCollection::const_iterator photon = photons.begin(); photon!=photons.end(); ++photon) {
369  float inv = (conv.refittedPair4Momentum() + photon->p4()).M();
370  if (inv > large1 && inv < large2) {
371  check_large = true;
372  if (inv > small1 && inv < small2) {
373  check_small = true;
374  break;
375  }
376  }
377  }
378  pizero_rejected = check_small;
379  return check_large;
380 }
381 
383  return reco::Candidate::LorentzVector(v.x(),v.y(), v.z(), v.t());
384 }
385 
386 
388  std::cout << "############################" << std::endl;
389  std::cout << "Conversion Candidate producer report" << std::endl;
390  std::cout << "############################" << std::endl;
391  std::cout << "Total examined conversions: " << total_conversions << std::endl;
392  std::cout << "Selection fail candidates: " << selection_fail << std::endl;
393  std::cout << "Algo fail candidates: " << algo_fail << std::endl;
394  std::cout << "Quality fail candidates: " << flag_fail << std::endl;
395  std::cout << "Pi0 fail: " << pizero_fail << std::endl;
396  std::cout << "Total duplicates found: " << duplicates << std::endl;
397  std::cout << "Vertex compatibility fail: " << TkVtxC << std::endl;
398  std::cout << "Compatible inner hits fail: " << CInnerHits << std::endl;
399  std::cout << "Highpurity Subset fail: " << highpurity_count << std::endl;
400  std::cout << "############################" << std::endl;
401  std::cout << "Final number of conversions: " << final_conversion << std::endl;
402  std::cout << "Stored number of conversions: " << store_conversion << std::endl;
403  std::cout << "############################" << std::endl;
404 }
405 //define this as a plug-in
const reco::Vertex & conversionVertex() const
returns the reco conversion vertex
Definition: Conversion.h:97
Analysis-level particle class.
T getParameter(std::string const &) const
int i
Definition: DBlmapReader.cc:9
static uint32_t getLayer(uint16_t pattern)
Definition: HitPattern.h:680
bool foundCompatibleInnerHits(const reco::HitPattern &hitPatA, const reco::HitPattern &hitPatB)
ConversionAlgorithm algo() const
Definition: Conversion.h:223
void removeDuplicates(reco::ConversionCollection &, std::vector< int > &)
double normalizedChi2() const
chi-squared divided by n.d.o.f. (or chi-squared * 1e6 if n.d.o.f. is zero)
Definition: TrackBase.h:548
static HepMC::IO_HEPEVT conv
double dxyError() const
error on dxy
Definition: TrackBase.h:783
bool quality(ConversionQuality q) const
Definition: Conversion.h:181
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
reco::Candidate::LorentzVector convertVector(const math::XYZTLorentzVectorF &)
uint16_t getTrackerMonoStereo(HitCategory category, uint16_t substr, uint16_t layer) const
Definition: HitPattern.cc:458
double zOfPrimaryVertexFromTracks(const math::XYZPoint &myBeamSpot=math::XYZPoint()) const
Definition: Conversion.h:145
double distOfMinimumApproach() const
Definition: Conversion.h:125
virtual void setP4(const LorentzVector &p4)
set 4-momentum
bool HighpuritySubset(const reco::Conversion &, const reco::VertexCollection &)
std::vector< Variable::Flags > flags
Definition: MVATrainer.cc:135
std::vector< Vertex > VertexCollection
collection of Vertex objects
Definition: VertexFwd.h:9
bool ConversionLessByChi2(const reco::Conversion &c1, const reco::Conversion &c2)
double covariance(int i, int j) const
(i, j)-th element of error matrix, i, j = 0, ... 2
Definition: Vertex.h:123
const Point & position() const
position
Definition: Vertex.h:106
std::vector< Conversion > ConversionCollection
collectin of Conversion objects
Definition: ConversionFwd.h:9
static bool validHitFilter(uint16_t pattern)
Definition: HitPattern.h:765
U second(std::pair< T, U > const &p)
virtual void produce(edm::Event &event, const edm::EventSetup &esetup)
bool operator==(const reco::Conversion &c1, const reco::Conversion &c2)
bool ConversionEqualByTrack(const reco::Conversion &c1, const reco::Conversion &c2)
bool checkTkVtxCompatibility(const reco::Conversion &, const reco::VertexCollection &)
double ndof() const
number of degrees of freedom of the fit
Definition: TrackBase.h:542
T sqrt(T t)
Definition: SSEVec.h:48
int PackFlags(const reco::Conversion &, bool, bool, bool, bool, bool)
double chi2() const
chi-squares
Definition: Vertex.h:95
edm::EDGetTokenT< reco::VertexCollection > thePVsToken_
double f[11][100]
void addUserInt(const std::string &label, int32_t data)
Set user-defined int.
Definition: PATObject.h:832
float ChiSquaredProbability(double chiSquared, double nrDOF)
#define end
Definition: vmac.h:37
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger but the state exists so we define the behavior If all triggers are the negative crieriion will lead to accepting the event(this again matches the behavior of"!*"before the partial wildcard feature was incorporated).The per-event"cost"of each negative criterion with multiple relevant triggers is about the same as!*was in the past
virtual void setVertex(const Point &vertex)
set vertex
static uint32_t getSubStructure(uint16_t pattern)
Definition: HitPattern.h:671
double ndof() const
Definition: Vertex.h:102
const reco::PFCandidateCollection selectPFPhotons(const reco::PFCandidateCollection &)
OniaPhotonConversionProducer(const edm::ParameterSet &ps)
double dz() const
dz parameter (= dsz/cos(lambda)). This is the track z0 w.r.t (0,0,0) only if the refPoint is close to...
Definition: TrackBase.h:596
double dzError() const
error on dz
Definition: TrackBase.h:801
math::XYZTLorentzVectorF refittedPair4Momentum() const
Conversion track pair 4-momentum from the tracks refitted with vertex constraint. ...
Definition: Conversion.cc:235
bool lt_(std::pair< double, short > a, std::pair< double, short > b)
std::vector< reco::PFCandidate > PFCandidateCollection
collection of PFCandidates
static bool trackerHitFilter(uint16_t pattern)
Definition: HitPattern.h:657
void addUserData(const std::string &label, const T &data, bool transientOnly=false)
Definition: PATObject.h:309
edm::EDGetTokenT< reco::ConversionCollection > convCollectionToken_
std::vector< CompositeCandidate > CompositeCandidateCollection
T const * product() const
Definition: Handle.h:81
edm::EDGetTokenT< reco::PFCandidateCollection > pfCandidateCollectionToken_
tuple idx
DEBUGGING if hasattr(process,&quot;trackMonIterativeTracking2012&quot;): print &quot;trackMonIterativeTracking2012 D...
double b
Definition: hdecay.h:120
math::XYZTLorentzVector LorentzVector
Lorentz vector.
Definition: Candidate.h:37
#define begin
Definition: vmac.h:30
bool CheckPi0(const reco::Conversion &, const reco::PFCandidateCollection &, bool &)
pat::CompositeCandidate * makePhotonCandidate(const reco::Conversion &)
double a
Definition: hdecay.h:121
tuple cout
Definition: gather_cfg.py:121
int charge() const
track electric charge
Definition: TrackBase.h:554
ROOT::Math::LorentzVector< ROOT::Math::PxPyPzE4D< float > > XYZTLorentzVectorF
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:22
uint16_t getHitPattern(HitCategory category, int position) const
Definition: HitPattern.h:502
double dxy() const
dxy parameter. (This is the transverse impact parameter w.r.t. to (0,0,0) ONLY if refPoint is close t...
Definition: TrackBase.h:578
tuple size
Write out results.
std::vector< edm::RefToBase< reco::Track > > const & tracks() const
vector of track to base references
Definition: Conversion.cc:176
int numberOfHits(HitCategory category) const
Definition: HitPattern.h:785