CMS 3D CMS Logo

TtSemiEvtSolutionMaker.cc
Go to the documentation of this file.
1 //
2 //
3 
5 
7 
9 
17 
18 #include <memory>
19 
20 
23  // configurables
24  electronSrcToken_ = mayConsume<std::vector<pat::Electron> >(iConfig.getParameter<edm::InputTag> ("electronSource"));
25  muonSrcToken_ = mayConsume<std::vector<pat::Muon> >(iConfig.getParameter<edm::InputTag> ("muonSource"));
26  metSrcToken_ = consumes<std::vector<pat::MET> >(iConfig.getParameter<edm::InputTag> ("metSource"));
27  jetSrcToken_ = consumes<std::vector<pat::Jet> >(iConfig.getParameter<edm::InputTag> ("jetSource"));
28  leptonFlavour_ = iConfig.getParameter<std::string> ("leptonFlavour");
29  jetCorrScheme_ = iConfig.getParameter<int> ("jetCorrectionScheme");
30  nrCombJets_ = iConfig.getParameter<unsigned int> ("nrCombJets");
31  doKinFit_ = iConfig.getParameter<bool> ("doKinFit");
32  addLRSignalSel_ = iConfig.getParameter<bool> ("addLRSignalSel");
33  lrSignalSelObs_ = iConfig.getParameter<std::vector<int> >("lrSignalSelObs");
34  lrSignalSelFile_ = iConfig.getParameter<std::string> ("lrSignalSelFile");
35  addLRJetComb_ = iConfig.getParameter<bool> ("addLRJetComb");
36  lrJetCombObs_ = iConfig.getParameter<std::vector<int> >("lrJetCombObs");
37  lrJetCombFile_ = iConfig.getParameter<std::string> ("lrJetCombFile");
38  maxNrIter_ = iConfig.getParameter<int> ("maxNrIter");
39  maxDeltaS_ = iConfig.getParameter<double> ("maxDeltaS");
40  maxF_ = iConfig.getParameter<double> ("maxF");
41  jetParam_ = iConfig.getParameter<int> ("jetParametrisation");
42  lepParam_ = iConfig.getParameter<int> ("lepParametrisation");
43  metParam_ = iConfig.getParameter<int> ("metParametrisation");
44  constraints_ = iConfig.getParameter<std::vector<unsigned> >("constraints");
45  matchToGenEvt_ = iConfig.getParameter<bool> ("matchToGenEvt");
46  matchingAlgo_ = iConfig.getParameter<int> ("matchingAlgorithm");
47  useMaxDist_ = iConfig.getParameter<bool> ("useMaximalDistance");
48  useDeltaR_ = iConfig.getParameter<bool> ("useDeltaR");
49  maxDist_ = iConfig.getParameter<double> ("maximalDistance");
50  genEvtToken_ = mayConsume<TtGenEvent>(edm::InputTag("genEvt"));
51 
52  // define kinfitter
53  if(doKinFit_){
54  myKinFitter = new TtSemiLepKinFitter(param(jetParam_), param(lepParam_), param(metParam_), maxNrIter_, maxDeltaS_, maxF_, constraints(constraints_));
55  }
56 
57  // define jet combinations related calculators
61  if (addLRJetComb_) myLRJetCombCalc = new TtSemiLRJetCombCalc(edm::FileInPath(lrJetCombFile_).fullPath(), lrJetCombObs_);
62 
63  // instantiate signal selection calculator
64  if (addLRSignalSel_) myLRSignalSelCalc = new TtSemiLRSignalSelCalc(edm::FileInPath(lrSignalSelFile_).fullPath(), lrSignalSelObs_);
65 
66  // define what will be produced
67  produces<std::vector<TtSemiEvtSolution> >();
68 }
69 
70 
73  if (doKinFit_) delete myKinFitter;
74  delete mySimpleBestJetComb;
78  if(addLRJetComb_) delete myLRJetCombCalc;
79 }
80 
81 
83 
84  //
85  // TopObject Selection
86  //
87 
88  // select lepton (the TtLepton vectors are, for the moment, sorted on pT)
89  bool leptonFound = false;
91  if(leptonFlavour_ == "muon"){
92  iEvent.getByToken(muonSrcToken_, muons);
93  if (muons->size() > 0) leptonFound = true;
94  }
96  if(leptonFlavour_ == "electron"){
97  iEvent.getByToken(electronSrcToken_, electrons);
98  if (electrons->size() > 0) leptonFound = true;
99  }
100 
101  // select MET (TopMET vector is sorted on ET)
102  bool metFound = false;
104  iEvent.getByToken(metSrcToken_, mets);
105  if (mets->size() > 0) metFound = true;
106 
107  // select Jets
108  bool jetsFound = false;
110  iEvent.getByToken(jetSrcToken_, jets);
111  if (jets->size() >= 4) jetsFound = true;
112 
113  //
114  // Build Event solutions according to the ambiguity in the jet combination
115  //
116  std::vector<TtSemiEvtSolution> * evtsols = new std::vector<TtSemiEvtSolution>();
117  if(leptonFound && metFound && jetsFound){
118  // protect against reading beyond array boundaries
119  unsigned int nrCombJets = nrCombJets_; // do not overwrite nrCombJets_
120  if (jets->size() < nrCombJets) nrCombJets = jets->size();
121  // loop over all jets
122  for (unsigned int p=0; p<nrCombJets; p++) {
123  for (unsigned int q=0; q<nrCombJets; q++) {
124  for (unsigned int bh=0; bh<nrCombJets; bh++) {
125  if (q>p && !(bh==p || bh==q)) {
126  for (unsigned int bl=0; bl<nrCombJets; bl++) {
127  if (!(bl==p || bl==q || bl==bh)) {
128  TtSemiEvtSolution asol;
130  if(leptonFlavour_ == "muon") asol.setMuon(muons, 0);
131  if(leptonFlavour_ == "electron") asol.setElectron(electrons, 0);
132  asol.setNeutrino(mets, 0);
133  asol.setHadp(jets, p);
134  asol.setHadq(jets, q);
135  asol.setHadb(jets, bh);
136  asol.setLepb(jets, bl);
137  if (doKinFit_) {
138  asol = myKinFitter->addKinFitInfo(&asol);
139  // just to keep a record in the event (drop? -> present in provenance anyway...)
143  }
144  if(matchToGenEvt_){
146  iEvent.getByToken(genEvtToken_,genEvt);
147  if (genEvt->numberOfBQuarks() == 2 && // FIXME: in rare cases W->bc decay, resulting in a wrong filled genEvt leading to a segmentation fault
148  genEvt->numberOfLeptons() == 1) { // FIXME: temporary solution to avoid crash in JetPartonMatching for non semi-leptonic events
149  asol.setGenEvt(genEvt);
150 
151  }
152  }
153  // these lines calculate the observables to be used in the TtSemiSignalSelection LR
154  (*myLRSignalSelObservables)(asol, *jets);
155 
156  // if asked for, calculate with these observable values the LRvalue and
157  // (depending on the configuration) probability this event is signal
158  // FIXME: DO WE NEED TO DO THIS FOR EACH SOLUTION??? (S.L.20/8/07)
159  if(addLRSignalSel_) (*myLRSignalSelCalc)(asol);
160 
161  // these lines calculate the observables to be used in the TtSemiJetCombination LR
162  //(*myLRJetCombObservables)(asol);
163 
164  (*myLRJetCombObservables)(asol, iEvent);
165 
166  // if asked for, calculate with these observable values the LRvalue and
167  // (depending on the configuration) probability a jet combination is correct
168  if(addLRJetComb_) (*myLRJetCombCalc)(asol);
169 
170  //std::cout<<"SignalSelLRval = "<<asol.getLRSignalEvtLRval()<<" JetCombProb = "<<asol.getLRSignalEvtProb()<<std::endl;
171  //std::cout<<"JetCombLRval = "<<asol.getLRJetCombLRval()<<" JetCombProb = "<<asol.getLRJetCombProb()<<std::endl;
172 
173  // fill solution to vector
174  asol.setupHyp();
175  evtsols->push_back(asol);
176  }
177  }
178  }
179  }
180  }
181  }
182 
183  // if asked for, match the event solutions to the gen Event
184  if(matchToGenEvt_){
185  int bestSolution = -999;
186  int bestSolutionChangeWQ = -999;
188  iEvent.getByToken(genEvtToken_, genEvt);
189  if (genEvt->numberOfBQuarks() == 2 && // FIXME: in rare cases W->bc decay, resulting in a wrong filled genEvt leading to a segmentation fault
190  genEvt->numberOfLeptons() == 1) { // FIXME: temporary solution to avoid crash in JetPartonMatching for non semi-leptonic events
191  std::vector<const reco::Candidate*> quarks;
192  const reco::Candidate & genp = *(genEvt->hadronicDecayQuark());
193  const reco::Candidate & genq = *(genEvt->hadronicDecayQuarkBar());
194  const reco::Candidate & genbh = *(genEvt->hadronicDecayB());
195  const reco::Candidate & genbl = *(genEvt->leptonicDecayB());
196  quarks.push_back( &genp );
197  quarks.push_back( &genq );
198  quarks.push_back( &genbh );
199  quarks.push_back( &genbl );
200  std::vector<const reco::Candidate*> recjets;
201  for(size_t s=0; s<evtsols->size(); s++) {
202  recjets.clear();
203  const reco::Candidate & jetp = (*evtsols)[s].getRecHadp();
204  const reco::Candidate & jetq = (*evtsols)[s].getRecHadq();
205  const reco::Candidate & jetbh = (*evtsols)[s].getRecHadb();
206  const reco::Candidate & jetbl = (*evtsols)[s].getRecLepb();
207  recjets.push_back( &jetp );
208  recjets.push_back( &jetq );
209  recjets.push_back( &jetbh );
210  recjets.push_back( &jetbl );
211  JetPartonMatching aMatch(quarks, recjets, matchingAlgo_, useMaxDist_, useDeltaR_, maxDist_);
212  (*evtsols)[s].setGenEvt(genEvt);
213  (*evtsols)[s].setMCBestSumAngles(aMatch.getSumDistances());
214  (*evtsols)[s].setMCBestAngleHadp(aMatch.getDistanceForParton(0));
215  (*evtsols)[s].setMCBestAngleHadq(aMatch.getDistanceForParton(1));
216  (*evtsols)[s].setMCBestAngleHadb(aMatch.getDistanceForParton(2));
217  (*evtsols)[s].setMCBestAngleLepb(aMatch.getDistanceForParton(3));
218  if(aMatch.getMatchForParton(2) == 2 && aMatch.getMatchForParton(3) == 3){
219  if(aMatch.getMatchForParton(0) == 0 && aMatch.getMatchForParton(1) == 1) {
220  bestSolution = s;
221  bestSolutionChangeWQ = 0;
222  } else if(aMatch.getMatchForParton(0) == 1 && aMatch.getMatchForParton(1) == 0) {
223  bestSolution = s;
224  bestSolutionChangeWQ = 1;
225  }
226  }
227  }
228  }
229  for(size_t s=0; s<evtsols->size(); s++) {
230  (*evtsols)[s].setMCBestJetComb(bestSolution);
231  (*evtsols)[s].setMCChangeWQ(bestSolutionChangeWQ);
232  }
233  }
234 
235  // add TtSemiSimpleBestJetComb to solutions
236  int simpleBestJetComb = (*mySimpleBestJetComb)(*evtsols);
237  for(size_t s=0; s<evtsols->size(); s++) (*evtsols)[s].setSimpleBestJetComb(simpleBestJetComb);
238 
239  // choose the best jet combination according to LR value
240  if (addLRJetComb_ && evtsols->size()>0) {
241  float bestLRVal = -1000000;
242  int bestSol = (*evtsols)[0].getLRBestJetComb(); // duplicate the default
243  for(size_t s=0; s<evtsols->size(); s++) {
244  if ((*evtsols)[s].getLRJetCombLRval() > bestLRVal) {
245  bestLRVal = (*evtsols)[s].getLRJetCombLRval();
246  bestSol = s;
247  }
248  }
249  for(size_t s=0; s<evtsols->size(); s++) {
250  (*evtsols)[s].setLRBestJetComb(bestSol);
251  }
252  }
253 
254  //store the vector of solutions to the event
255  std::unique_ptr<std::vector<TtSemiEvtSolution> > pOut(evtsols);
256  iEvent.put(std::move(pOut));
257 
258  } else {
259 
260  /*
261  std::cout<<"No calibrated solutions built, because: ";
262  if(jets->size()<4) std::cout<<"nr sel jets < 4"<<std::endl;
263  if(leptonFlavour_ == "muon" && muons->size() == 0) std::cout<<"no good muon candidate"<<std::endl;
264  if(leptonFlavour_ == "electron" && electrons->size() == 0) std::cout<<"no good electron candidate"<<std::endl;
265  if(mets->size() == 0) std::cout<<"no MET reconstruction"<<std::endl;
266  */
267 // TtSemiEvtSolution asol;
268 // evtsols->push_back(asol);
269  std::unique_ptr<std::vector<TtSemiEvtSolution> > pOut(evtsols);
270  iEvent.put(std::move(pOut));
271  }
272 }
273 
275 {
277  switch(val){
281  default:
282  throw cms::Exception("WrongConfig")
283  << "Chosen jet parametrization is not supported: " << val << "\n";
284  break;
285  }
286  return result;
287 }
288 
290 {
292  switch(val){
298  default:
299  throw cms::Exception("WrongConfig")
300  << "Chosen fit constraint is not supported: " << val << "\n";
301  break;
302  }
303  return result;
304 }
305 
306 std::vector<TtSemiLepKinFitter::Constraint> TtSemiEvtSolutionMaker::constraints(std::vector<unsigned>& val)
307 {
308  std::vector<TtSemiLepKinFitter::Constraint> result;
309  for(unsigned i=0; i<val.size(); ++i){
310  result.push_back(constraint(val[i]));
311  }
312  return result;
313 }
314 
T getParameter(std::string const &) const
void setLepb(const edm::Handle< std::vector< pat::Jet > > &jet, int i)
const reco::GenParticle * hadronicDecayB(bool excludeTauLeptons=false) const
get b of hadronic decay branch
Definition: TtGenEvent.cc:196
TtSemiLRJetCombCalc * myLRJetCombCalc
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:122
edm::EDGetTokenT< std::vector< pat::Electron > > electronSrcToken_
Param
supported parameterizations
Definition: TopKinFitter.h:22
virtual void produce(edm::Event &iEvent, const edm::EventSetup &iSetup)
TtSemiLepKinFitter * myKinFitter
TtSemiLRJetCombObservables * myLRJetCombObservables
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:457
TtSemiSimpleBestJetComb * mySimpleBestJetComb
std::vector< unsigned > constraints_
const reco::GenParticle * hadronicDecayQuarkBar() const
get light anti-quark of hadronic decay branch
Definition: TtGenEvent.h:72
void setGenEvt(const edm::Handle< TtGenEvent > &aGenEvt)
TtSemiLepKinFitter::Param param(unsigned)
edm::EDGetTokenT< std::vector< pat::Muon > > muonSrcToken_
Simple method to get the correct jet combination in semileptonic ttbar events.
void setHadp(const edm::Handle< std::vector< pat::Jet > > &jet, int i)
void setLeptonParametrisation(int lp)
void setMuon(const edm::Handle< std::vector< pat::Muon > > &muon, int i)
Class to calculate the jet combination LR value and purity from a root-file with fit functions...
int iEvent
Definition: GenABIO.cc:230
void setJetCorrectionScheme(int scheme)
ConsumesCollector consumesCollector()
Use a ConsumesCollector to gather consumes information from helper functions.
vector< PseudoJet > jets
edm::EDGetTokenT< std::vector< pat::MET > > metSrcToken_
const reco::GenParticle * hadronicDecayQuark(bool invertFlavor=false) const
get light quark of hadronic decay branch
Definition: TtGenEvent.cc:166
void setJetParametrisation(int jp)
Class to calculate the jet combination LR value and purity from a root-file with fit functions...
TtSemiEvtSolutionMaker(const edm::ParameterSet &iConfig)
constructor
void setElectron(const edm::Handle< std::vector< pat::Electron > > &elec, int i)
TtSemiEvtSolution addKinFitInfo(TtSemiEvtSolution *asol)
add kin fit information to the old event solution (in for legacy reasons)
int numberOfBQuarks(bool fromTopQuark=true) const
return number of b quarks in the decay chain
Definition: TopGenEvent.cc:112
Steering class for the overall top-lepton likelihood.
edm::EDGetTokenT< std::vector< pat::Jet > > jetSrcToken_
const reco::GenParticle * leptonicDecayB(bool excludeTauLeptons=false) const
get b of leptonic decay branch
Definition: TtGenEvent.cc:248
TtSemiLepKinFitter::Constraint constraint(unsigned)
int getMatchForParton(const unsigned int part, const unsigned int comb=0)
void setNeutrinoParametrisation(int mp)
edm::EDGetTokenT< TtGenEvent > genEvtToken_
void setNeutrino(const edm::Handle< std::vector< pat::MET > > &met, int i)
std::vector< int > lrSignalSelObs_
std::vector< TtSemiLepKinFitter::Constraint > constraints(std::vector< unsigned > &)
TtSemiLRSignalSelObservables * myLRSignalSelObservables
double getSumDistances(const unsigned int comb=0)
void setHadb(const edm::Handle< std::vector< pat::Jet > > &jet, int i)
def move(src, dest)
Definition: eostools.py:510
std::vector< int > lrJetCombObs_
void setHadq(const edm::Handle< std::vector< pat::Jet > > &jet, int i)
Constraint
supported constraints
TtSemiLRSignalSelCalc * myLRSignalSelCalc
double getDistanceForParton(const unsigned int part, const unsigned int comb=0)
int numberOfLeptons(bool fromWBoson=true) const
return number of leptons in the decay chain
Definition: TopGenEvent.cc:48