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 
106  event.getByToken(thePVsToken_, priVtxs);
107 
109  event.getByToken(convCollectionToken_,pConv);
110 
112  event.getByToken(pfCandidateCollectionToken_,pfcandidates);
113 
114  const reco::PFCandidateCollection pfphotons = selectPFPhotons(*pfcandidates);
115 
117 
118  for(reco::ConversionCollection::const_iterator conv = pConv->begin(); conv != pConv->end(); ++conv){
120 
121  if (! ( *convSelection_)(*conv)){
122  selection_fail++;
123  continue; // selection string
124  }
125  if (convAlgo_ != 0 && conv->algo()!= convAlgo_){
126  algo_fail++;
127  continue; // select algorithm
128  }
129  if(convQuality_.size() > 0){
130  bool flagsok=true;
131  for (std::vector<int>::const_iterator flag = convQuality_.begin(); flag!=convQuality_.end(); ++flag){
133  if (!conv->quality(q)) {
134  flagsok=false;
135  break;
136  }
137  }
138  if (!flagsok){
139  flag_fail++;
140  continue;
141  }
142  }
143  outCollection->push_back(*conv);
144  }
145 
146  removeDuplicates(*outCollection);
147 
148  for (reco::ConversionCollection::const_iterator conv = outCollection->begin(); conv != outCollection->end(); ++conv){
149 
150  bool flag1 = true;
151  bool flag2 = true;
152  bool flag3 = true;
153  bool flag4 = true;
154 
155  // The logic implies that by default this flags are true and if the check are not wanted conversions are saved.
156  // If checks are required and failed then don't save the conversion.
157 
158  bool flagTkVtxCompatibility = true;
159  if (! checkTkVtxCompatibility(*conv,*priVtxs.product())) {
160  flagTkVtxCompatibility = false;
162  TkVtxC++;
163  flag1 = false;
164  }
165  }
166  bool flagCompatibleInnerHits = false;
167  if (conv->tracks().size()==2) {
168  reco::HitPattern hitPatA=conv->tracks().at(0)->hitPattern();
169  reco::HitPattern hitPatB=conv->tracks().at(1)->hitPattern();
170  if ( foundCompatibleInnerHits(hitPatA,hitPatB) && foundCompatibleInnerHits(hitPatB,hitPatA) ) flagCompatibleInnerHits = true;
171  }
172  if (wantCompatibleInnerHits_ && ! flagCompatibleInnerHits) {
173  CInnerHits++;
174  flag2 = false;
175  }
176  bool flagHighpurity = true;
177  if (!HighpuritySubset(*conv,*priVtxs.product())) {
178  flagHighpurity = false;
179  if (wantHighpurity_) {
181  flag3 = false;
182  }
183  }
184  bool pizero_rejected = false;
185  bool large_pizero_window = CheckPi0(*conv, pfphotons, pizero_rejected);
186  if (pi0OnlineSwitch_ && pizero_rejected) {
187  pizero_fail++;
188  flag4 = false;
189  }
190 
191  int flags = 0;
192  if (flag1 && flag2 && flag3 && flag4){
193  flags = PackFlags(*conv,flagTkVtxCompatibility,flagCompatibleInnerHits,flagHighpurity,pizero_rejected,large_pizero_window);
195  pat_conv->addUserInt("flags",flags);
196  patoutCollection->push_back(*pat_conv);
198  }
199  }
200  store_conversion += patoutCollection->size();
201  event.put(patoutCollection,"conversions");
202 
203  delete convSelection_;
204 }
205 
206 int OniaPhotonConversionProducer::PackFlags(const reco::Conversion& conv, bool flagTkVtxCompatibility,
207  bool flagCompatibleInnerHits, bool flagHighpurity,
208  bool pizero_rejected, bool large_pizero_window ) {
209  int flags = 0;
210  if ( flagTkVtxCompatibility ) flags += 1;
211  if ( flagCompatibleInnerHits ) flags += 2;
212  if ( flagHighpurity ) flags += 4;
213  if ( pizero_rejected ) flags += 8;
214  if ( large_pizero_window ) flags += 16;
215 
216  flags += (conv.algo()*32);
217  int q_mask = 0;
218  std::vector<std::string> s_quals;
219  s_quals.push_back("generalTracksOnly");
220  s_quals.push_back("arbitratedEcalSeeded");
221  s_quals.push_back("arbitratedMerged");
222  s_quals.push_back("arbitratedMergedEcalGeneral");
223  s_quals.push_back("highPurity");
224  s_quals.push_back("highEfficiency");
225  s_quals.push_back("ecalMatched1Track");
226  s_quals.push_back("ecalMatched2Track");
227  std::vector<int> i_quals = StringToEnumValue<reco::Conversion::ConversionQuality>(s_quals);
228  for (std::vector<int>::const_iterator qq = i_quals.begin(); qq!=i_quals.end(); ++qq) {
230  if (conv.quality(q)) q_mask = *qq;
231  }
232  flags += (q_mask*32*8);
233  return flags;
234 }
235 
240  // first sort from high to low chi2 prob
241  std::sort(c.begin(),c.end(),ConversionLessByChi2);
242  int iter1 = 0;
243  // Cycle over all the elements of the collection and compare to all the following,
244  // if two elements have at least one track in common delete the element with the lower chi2
245  while(iter1 < (( (int) c.size() ) - 1) ){
246  int iter2 = iter1+1;
247  while( iter2 < (int) c.size()) if(ConversionEqualByTrack( c[iter1], c[iter2] ) ){
248  c.erase( c.begin() + iter2 );
249  duplicates++;
250  }else{
251  iter2++; // Increment index only if this element is no duplicate.
252  // If it is duplicate check again the same index since the vector rearranged elements index after erasing
253  }
254  iter1++;
255  }
256 }
257 
259  std::vector< std::pair< double, short> > idx[2];
260  short ik=-1;
261  BOOST_FOREACH(edm::RefToBase<reco::Track> tk, conv.tracks()){
262  ik++;
263  short count=-1;
264  BOOST_FOREACH(const reco::Vertex& vtx,priVtxs){
265  count++;
266 
267  double dz_= tk->dz(vtx.position());
268  double dzError_=tk->dzError();
269  dzError_=sqrt(dzError_*dzError_+vtx.covariance(2,2));
270 
271  if(fabs(dz_)/dzError_ > sigmaTkVtxComp_) continue;
272 
273  idx[ik].push_back(std::pair<double,short>(fabs(dz_),count));
274  }
275  if(idx[ik].size()==0) {return false;}
276 
277  std::stable_sort(idx[ik].begin(),idx[ik].end(),lt_);
278  }
279  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;
280  return false;
281 }
282 
284  size_t count=0;
285  uint32_t oldSubStr=0;
286  for (int i=0; i<hitPatA.numberOfHits(reco::HitPattern::HitCategory::TRACK_HITS) && count<2; i++) {
287  uint32_t hitA = hitPatA.getHitPattern(reco::HitPattern::HitCategory::TRACK_HITS,i);
288  if (!hitPatA.validHitFilter(hitA) || !hitPatA.trackerHitFilter(hitA)) continue;
289 
290  if(hitPatA.getSubStructure(hitA)==oldSubStr && hitPatA.getLayer(hitA)==oldSubStr)
291  continue;
292 
293  if(hitPatB.getTrackerMonoStereo(reco::HitPattern::HitCategory::TRACK_HITS,hitPatA.getSubStructure(hitA),hitPatA.getLayer(hitA)) != 0)
294  return true;
295 
296  oldSubStr=hitPatA.getSubStructure(hitA);
297  count++;
298  }
299  return false;
300 }
301 
304  // select high purity conversions our way:
305  // vertex chi2 cut
307 
308  // d0 cut
309  // Find closest primary vertex
310  int closest_pv_index = 0;
311  int i=0;
312  BOOST_FOREACH(const reco::Vertex& vtx,priVtxs){
313  if( conv.zOfPrimaryVertexFromTracks( vtx.position() ) < conv.zOfPrimaryVertexFromTracks( priVtxs[closest_pv_index].position() ) ) closest_pv_index = i;
314  i++;
315  }
316  // Now check impact parameter wtr with the just found closest primary vertex
317  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;
318 
319  // chi2 of single tracks
320  BOOST_FOREACH(const edm::RefToBase<reco::Track> tk, conv.tracks()) if(tk->normalizedChi2() > _trackchi2Cut) return false;
321 
322  // dof for each track
323  BOOST_FOREACH(const edm::RefToBase<reco::Track> tk, conv.tracks()) if(tk->ndof()< TkMinNumOfDOF_) return false;
324 
325  // distance of approach cut
327 
328  return true;
329 }
330 
332 
334  photonCand->setP4(convertVector(conv.refittedPair4Momentum()));
335  photonCand->setVertex(conv.conversionVertex().position());
336 
337  photonCand->addUserData<reco::Track>( "track0", *conv.tracks()[0] );
338  photonCand->addUserData<reco::Track>( "track1", *conv.tracks()[1] );
339 
340  return photonCand;
341 
342 }
343 
344 // create a collection of PF photons
346  reco::PFCandidateCollection pfphotons;
347  for (reco::PFCandidateCollection::const_iterator cand = pfcandidates.begin(); cand != pfcandidates.end(); ++cand){
348  if (cand->particleId() == reco::PFCandidate::gamma) pfphotons.push_back(*cand);
349  }
350  return pfphotons;
351 }
352 
354  bool &pizero_rejected ) {
355  // 2 windows are defined for Pi0 rejection, Conversions that, paired with others photons from the event, have an
356  // invariant mass inside the "small" window will be pizero_rejected and those that falls in the large window will
357  // be CheckPi0.
358  bool check_small = false;
359  bool check_large = false;
360 
361  float small1 = pi0SmallWindow_[0];
362  float small2 = pi0SmallWindow_[1];
363  float large1 = pi0LargeWindow_[0];
364  float large2 = pi0LargeWindow_[1];
365  for (reco::PFCandidateCollection::const_iterator photon = photons.begin(); photon!=photons.end(); ++photon) {
366  float inv = (conv.refittedPair4Momentum() + photon->p4()).M();
367  if (inv > large1 && inv < large2) {
368  check_large = true;
369  if (inv > small1 && inv < small2) {
370  check_small = true;
371  break;
372  }
373  }
374  }
375  pizero_rejected = check_small;
376  return check_large;
377 }
378 
380  return reco::Candidate::LorentzVector(v.x(),v.y(), v.z(), v.t());
381 }
382 
383 
385  std::cout << "############################" << std::endl;
386  std::cout << "Conversion Candidate producer report" << std::endl;
387  std::cout << "############################" << std::endl;
388  std::cout << "Total examined conversions: " << total_conversions << std::endl;
389  std::cout << "Selection fail candidates: " << selection_fail << std::endl;
390  std::cout << "Algo fail candidates: " << algo_fail << std::endl;
391  std::cout << "Quality fail candidates: " << flag_fail << std::endl;
392  std::cout << "Pi0 fail: " << pizero_fail << std::endl;
393  std::cout << "Total duplicates found: " << duplicates << std::endl;
394  std::cout << "Vertex compatibility fail: " << TkVtxC << std::endl;
395  std::cout << "Compatible inner hits fail: " << CInnerHits << std::endl;
396  std::cout << "Highpurity Subset fail: " << highpurity_count << std::endl;
397  std::cout << "############################" << std::endl;
398  std::cout << "Final number of conversions: " << final_conversion << std::endl;
399  std::cout << "Stored number of conversions: " << store_conversion << std::endl;
400  std::cout << "############################" << std::endl;
401 }
402 //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:700
bool foundCompatibleInnerHits(const reco::HitPattern &hitPatA, const reco::HitPattern &hitPatB)
ConversionAlgorithm algo() const
Definition: Conversion.h:223
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:556
static HepMC::IO_HEPEVT conv
double dxyError() const
error on dxy
Definition: TrackBase.h:791
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:469
double zOfPrimaryVertexFromTracks(const math::XYZPoint &myBeamSpot=math::XYZPoint()) const
Definition: Conversion.h:145
double distOfMinimumApproach() const
Definition: Conversion.h:125
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:116
const Point & position() const
position
Definition: Vertex.h:99
std::vector< Conversion > ConversionCollection
collectin of Conversion objects
Definition: ConversionFwd.h:9
static bool validHitFilter(uint16_t pattern)
Definition: HitPattern.h:787
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:550
T sqrt(T t)
Definition: SSEVec.h:18
int PackFlags(const reco::Conversion &, bool, bool, bool, bool, bool)
double chi2() const
chi-squares
Definition: Vertex.h:88
edm::EDGetTokenT< reco::VertexCollection > thePVsToken_
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
void addUserInt(const std::string &label, int32_t data, const bool overwrite=false)
Set user-defined int.
Definition: PATObject.h:855
static uint32_t getSubStructure(uint16_t pattern)
Definition: HitPattern.h:691
double ndof() const
Definition: Vertex.h:95
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:604
double dzError() const
error on dz
Definition: TrackBase.h:809
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:677
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
virtual void setP4(const LorentzVector &p4) final
set 4-momentum
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:145
int charge() const
track electric charge
Definition: TrackBase.h:562
void removeDuplicates(reco::ConversionCollection &)
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:515
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:586
tuple size
Write out results.
void addUserData(const std::string &label, const T &data, bool transientOnly=false, bool overwrite=false)
Definition: PATObject.h:309
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:807