File indexing completed on 2024-04-06 12:15:34
0001 #include "HeavyFlavorAnalysis/RecoDecay/test/stubs/TestBPHRecoDecay.h"
0002
0003 #include "FWCore/Framework/interface/MakerMacros.h"
0004 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0005 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0006
0007 #include "HeavyFlavorAnalysis/RecoDecay/interface/BPHAnalyzerTokenWrapper.h"
0008 #include "HeavyFlavorAnalysis/RecoDecay/interface/BPHRecoBuilder.h"
0009 #include "HeavyFlavorAnalysis/RecoDecay/interface/BPHRecoSelect.h"
0010 #include "HeavyFlavorAnalysis/RecoDecay/interface/BPHRecoCandidate.h"
0011 #include "HeavyFlavorAnalysis/RecoDecay/interface/BPHPlusMinusCandidate.h"
0012 #include "HeavyFlavorAnalysis/RecoDecay/interface/BPHMomentumSelect.h"
0013 #include "HeavyFlavorAnalysis/RecoDecay/interface/BPHVertexSelect.h"
0014 #include "HeavyFlavorAnalysis/RecoDecay/interface/BPHTrackReference.h"
0015
0016 #include "DataFormats/TrackReco/interface/Track.h"
0017
0018 #include "DataFormats/PatCandidates/interface/Muon.h"
0019 #include "DataFormats/PatCandidates/interface/GenericParticle.h"
0020 #include "DataFormats/PatCandidates/interface/CompositeCandidate.h"
0021
0022 #include "RecoVertex/KinematicFit/interface/TwoTrackMassKinematicConstraint.h"
0023 #include "TH1.h"
0024 #include "TFile.h"
0025 #include "TMath.h"
0026
0027 #include <set>
0028 #include <string>
0029 #include <iostream>
0030 #include <fstream>
0031
0032 using namespace std;
0033
0034 #define SET_LABEL(NAME, PSET) (NAME = PSET.getParameter<string>(#NAME))
0035
0036
0037
0038
0039 TestBPHRecoDecay::TestBPHRecoDecay(const edm::ParameterSet& ps) {
0040 usePM = (!SET_LABEL(patMuonLabel, ps).empty());
0041 useCC = (!SET_LABEL(ccCandsLabel, ps).empty());
0042 usePF = (!SET_LABEL(pfCandsLabel, ps).empty());
0043 usePC = (!SET_LABEL(pcCandsLabel, ps).empty());
0044 useGP = (!SET_LABEL(gpCandsLabel, ps).empty());
0045
0046 esConsume<TransientTrackBuilder, TransientTrackRecord>(ttBToken, "TransientTrackBuilder");
0047 if (usePM)
0048 consume<pat::MuonCollection>(patMuonToken, patMuonLabel);
0049 if (useCC)
0050 consume<vector<pat::CompositeCandidate> >(ccCandsToken, ccCandsLabel);
0051 if (usePF)
0052 consume<vector<reco::PFCandidate> >(pfCandsToken, pfCandsLabel);
0053 if (usePC)
0054 consume<vector<BPHTrackReference::candidate> >(pcCandsToken, pcCandsLabel);
0055 if (useGP)
0056 consume<vector<pat::GenericParticle> >(gpCandsToken, gpCandsLabel);
0057 SET_LABEL(outDump, ps);
0058 SET_LABEL(outHist, ps);
0059 if (outDump.empty())
0060 fPtr = &cout;
0061 else
0062 fPtr = new ofstream(outDump.c_str());
0063 }
0064
0065 void TestBPHRecoDecay::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0066 edm::ParameterSetDescription desc;
0067 desc.add<string>("patMuonLabel", "");
0068 desc.add<string>("ccCandsLabel", "");
0069 desc.add<string>("pfCandsLabel", "");
0070 desc.add<string>("pcCandsLabel", "");
0071 desc.add<string>("gpCandsLabel", "");
0072 desc.add<string>("outDump", "dump.txt");
0073 desc.add<string>("outHist", "hist.root");
0074 descriptions.add("testBPHRecoDecay", desc);
0075 return;
0076 }
0077
0078 void TestBPHRecoDecay::beginJob() {
0079 *fPtr << "TestBPHRecoDecay::beginJob" << endl;
0080 createHisto("massJPsi", 50, 2.85, 3.35);
0081 createHisto("mcstJPsi", 50, 2.85, 3.35);
0082 createHisto("massPhi", 50, 0.995, 1.045);
0083 createHisto("massBu", 20, 5.0, 5.5);
0084 createHisto("mcstBu", 20, 5.0, 5.5);
0085 createHisto("massBs", 20, 5.1, 5.6);
0086 createHisto("mcstBs", 20, 5.1, 5.6);
0087 createHisto("massBsPhi", 50, 0.995, 1.045);
0088 return;
0089 }
0090
0091 void TestBPHRecoDecay::analyze(const edm::Event& ev, const edm::EventSetup& es) {
0092 ostream& outF = *fPtr;
0093 outF << "--------- event " << ev.id().run() << " / " << ev.id().event() << " ---------" << endl;
0094
0095
0096 BPHEventSetupWrapper ew(es, BPHRecoCandidate::transientTrackBuilder, &ttBToken);
0097
0098
0099
0100
0101
0102 int nrc = 0;
0103
0104
0105 edm::Handle<vector<reco::PFCandidate> > pfCands;
0106 if (usePF) {
0107 pfCandsToken.get(ev, pfCands);
0108 nrc = pfCands->size();
0109 if (pfCands.isValid())
0110 outF << nrc << " pfCands found" << endl;
0111 else
0112 outF << "no pfCands" << endl;
0113 }
0114
0115
0116
0117
0118
0119 edm::Handle<vector<BPHTrackReference::candidate> > pcCands;
0120 if (usePC) {
0121 pcCandsToken.get(ev, pcCands);
0122 nrc = pcCands->size();
0123 if (pcCands.isValid())
0124 outF << nrc << " pcCands found" << endl;
0125 else
0126 outF << "no pcCands" << endl;
0127 }
0128
0129
0130 edm::Handle<vector<pat::GenericParticle> > gpCands;
0131 if (useGP) {
0132 gpCandsToken.get(ev, gpCands);
0133 nrc = gpCands->size();
0134 if (gpCands.isValid())
0135 outF << nrc << " gpCands found" << endl;
0136 else
0137 outF << "no gpCands" << endl;
0138 }
0139
0140
0141 edm::Handle<pat::MuonCollection> patMuon;
0142 if (usePM) {
0143 patMuonToken.get(ev, patMuon);
0144 int n = patMuon->size();
0145 if (patMuon.isValid())
0146 outF << n << " muons found" << endl;
0147 else
0148 outF << "no muons" << endl;
0149 }
0150
0151
0152
0153 vector<const reco::Candidate*> muDaugs;
0154 set<const pat::Muon*> muonSet;
0155 if (useCC) {
0156 edm::Handle<vector<pat::CompositeCandidate> > ccCands;
0157 ccCandsToken.get(ev, ccCands);
0158 int n = ccCands->size();
0159 if (ccCands.isValid())
0160 outF << n << " ccCands found" << endl;
0161 else
0162 outF << "no ccCands" << endl;
0163 muDaugs.clear();
0164 muDaugs.reserve(n);
0165 muonSet.clear();
0166 set<const pat::Muon*>::const_iterator iter;
0167 set<const pat::Muon*>::const_iterator iend;
0168 int i;
0169 for (i = 0; i < n; ++i) {
0170 const pat::CompositeCandidate& cc = ccCands->at(i);
0171 int j;
0172 int m = cc.numberOfDaughters();
0173 for (j = 0; j < m; ++j) {
0174 const reco::Candidate* dp = cc.daughter(j);
0175 const pat::Muon* mp = dynamic_cast<const pat::Muon*>(dp);
0176 iter = muonSet.begin();
0177 iend = muonSet.end();
0178 bool add = (mp != nullptr) && (muonSet.find(mp) == iend);
0179 while (add && (iter != iend)) {
0180 if (BPHRecoBuilder::sameTrack(mp, *iter++, 1.0e-5))
0181 add = false;
0182 }
0183 if (add)
0184 muonSet.insert(mp);
0185 }
0186 }
0187 iter = muonSet.begin();
0188 iend = muonSet.end();
0189 while (iter != iend)
0190 muDaugs.push_back(*iter++);
0191 if ((n = muDaugs.size()))
0192 outF << n << " muons found" << endl;
0193 }
0194
0195
0196
0197
0198
0199
0200 class MuonChargeSelect : public BPHRecoSelect {
0201 public:
0202 MuonChargeSelect(int c) : charge(c) {}
0203 ~MuonChargeSelect() override = default;
0204 bool accept(const reco::Candidate& cand) const override {
0205 const pat::Muon* p = dynamic_cast<const pat::Muon*>(&cand);
0206 if (p == nullptr)
0207 return false;
0208 return ((charge * cand.charge()) > 0);
0209 }
0210
0211 private:
0212 int charge;
0213 };
0214
0215
0216 class MuonPtSelect : public BPHRecoSelect {
0217 public:
0218 MuonPtSelect(float pt) : ptCut(pt) {}
0219 ~MuonPtSelect() override = default;
0220 bool accept(const reco::Candidate& cand) const override {
0221 const pat::Muon* p = dynamic_cast<const pat::Muon*>(&cand);
0222 if (p == nullptr)
0223 return false;
0224 return (p->p4().pt() > ptCut);
0225 }
0226
0227 private:
0228 float ptCut;
0229 };
0230
0231
0232 class MuonEtaSelect : public BPHRecoSelect {
0233 public:
0234 MuonEtaSelect(float eta) : etaCut(eta) {}
0235 ~MuonEtaSelect() override = default;
0236 bool accept(const reco::Candidate& cand) const override {
0237 const pat::Muon* p = dynamic_cast<const pat::Muon*>(&cand);
0238 if (p == nullptr)
0239 return false;
0240 return (fabs(p->p4().eta()) < etaCut);
0241 }
0242
0243 private:
0244 float etaCut;
0245 };
0246
0247
0248 class KaonChargeSelect : public BPHRecoSelect {
0249 public:
0250 KaonChargeSelect(int c) : charge(c) {}
0251 ~KaonChargeSelect() override = default;
0252 bool accept(const reco::Candidate& cand) const override { return ((charge * cand.charge()) > 0); }
0253
0254 private:
0255 int charge;
0256 };
0257
0258 class KaonNeutralVeto : public BPHRecoSelect {
0259 public:
0260 KaonNeutralVeto() {}
0261 ~KaonNeutralVeto() override = default;
0262 bool accept(const reco::Candidate& cand) const override { return lround(fabs(cand.charge())); }
0263 };
0264
0265
0266 class KaonPtSelect : public BPHRecoSelect {
0267 public:
0268 KaonPtSelect(float pt) : ptCut(pt) {}
0269 ~KaonPtSelect() override = default;
0270 bool accept(const reco::Candidate& cand) const override { return (cand.p4().pt() > ptCut); }
0271
0272 private:
0273 float ptCut;
0274 };
0275
0276
0277 class KaonEtaSelect : public BPHRecoSelect {
0278 public:
0279 KaonEtaSelect(float eta) : etaCut(eta) {}
0280 ~KaonEtaSelect() override = default;
0281 bool accept(const reco::Candidate& cand) const override { return (fabs(cand.p4().eta()) < etaCut); }
0282
0283 private:
0284 float etaCut;
0285 };
0286
0287
0288
0289
0290
0291
0292 class MassSelect : public BPHMomentumSelect {
0293 public:
0294 MassSelect(double minMass, double maxMass) : mMin(minMass), mMax(maxMass) {}
0295 ~MassSelect() override = default;
0296 bool accept(const BPHDecayMomentum& cand) const override {
0297 double mass = cand.composite().mass();
0298 return ((mass > mMin) && (mass < mMax));
0299 }
0300
0301 private:
0302 double mMin;
0303 double mMax;
0304 };
0305
0306
0307 class Chi2Select : public BPHVertexSelect {
0308 public:
0309 Chi2Select(double minProb) : mProb(minProb) {}
0310 ~Chi2Select() override = default;
0311 bool accept(const BPHDecayVertex& cand) const override {
0312 const reco::Vertex& v = cand.vertex();
0313 if (v.isFake())
0314 return false;
0315 if (!v.isValid())
0316 return false;
0317 return (TMath::Prob(v.chi2(), lround(v.ndof())) > mProb);
0318 }
0319
0320 private:
0321 double mProb;
0322 };
0323
0324
0325
0326 outF << "build and dump JPsi" << endl;
0327 MuonPtSelect muPt(4.0);
0328 MuonEtaSelect muEta(2.1);
0329 string muPos = "MuPos";
0330 string muNeg = "MuNeg";
0331 BPHRecoBuilder bJPsi(ew);
0332 if (usePM) {
0333 bJPsi.add(muPos, BPHRecoBuilder::createCollection(patMuon, "cfmig"), 0.105658);
0334 bJPsi.add(muNeg, BPHRecoBuilder::createCollection(patMuon, "cfmig"), 0.105658);
0335 } else if (useCC) {
0336 bJPsi.add(muPos, BPHRecoBuilder::createCollection(muDaugs, "cfmig"), 0.105658);
0337 bJPsi.add(muNeg, BPHRecoBuilder::createCollection(muDaugs, "cfmig"), 0.105658);
0338 }
0339 bJPsi.filter(muPos, muPt);
0340 bJPsi.filter(muNeg, muPt);
0341 bJPsi.filter(muPos, muEta);
0342 bJPsi.filter(muNeg, muEta);
0343
0344 MassSelect massJPsi(2.5, 3.7);
0345 Chi2Select chi2Valid(0.0);
0346 bJPsi.filter(massJPsi);
0347 bJPsi.filter(chi2Valid);
0348 vector<BPHPlusMinusConstCandPtr> lJPsi = BPHPlusMinusCandidate::build(bJPsi, muPos, muNeg, 3.096916, 0.00004);
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358 int iJPsi;
0359 int nJPsi = lJPsi.size();
0360 outF << nJPsi << " JPsi cand found" << endl;
0361 for (iJPsi = 0; iJPsi < nJPsi; ++iJPsi)
0362 dumpRecoCand("JPsi", lJPsi[iJPsi].get());
0363
0364
0365
0366 outF << "build and dump Phi" << endl;
0367 BPHRecoBuilder bPhi(ew);
0368 KaonChargeSelect tkPos(+1);
0369 KaonChargeSelect tkNeg(-1);
0370 KaonPtSelect tkPt(0.7);
0371 string kPos = "KPos";
0372 string kNeg = "KNeg";
0373 if (usePF) {
0374 bPhi.add(kPos, BPHRecoBuilder::createCollection(pfCands), 0.493677);
0375 bPhi.add(kNeg, BPHRecoBuilder::createCollection(pfCands), 0.493677);
0376 } else if (usePC) {
0377 bPhi.add(kPos, BPHRecoBuilder::createCollection(pcCands), 0.493677);
0378 bPhi.add(kNeg, BPHRecoBuilder::createCollection(pcCands), 0.493677);
0379 } else if (useGP) {
0380 bPhi.add(kPos, BPHRecoBuilder::createCollection(gpCands), 0.493677);
0381 bPhi.add(kNeg, BPHRecoBuilder::createCollection(gpCands), 0.493677);
0382 }
0383 bPhi.filter(kPos, tkPos);
0384 bPhi.filter(kNeg, tkNeg);
0385 bPhi.filter(kPos, tkPt);
0386 bPhi.filter(kNeg, tkPt);
0387
0388 MassSelect massPhi(1.00, 1.04);
0389 bPhi.filter(massPhi);
0390 vector<BPHRecoConstCandPtr> lPhi = BPHRecoCandidate::build(bPhi);
0391
0392
0393
0394
0395
0396
0397 int iPhi;
0398 int nPhi = lPhi.size();
0399 outF << nPhi << " Phi cand found" << endl;
0400 for (iPhi = 0; iPhi < nPhi; ++iPhi)
0401 dumpRecoCand("Phi", lPhi[iPhi].get());
0402
0403
0404
0405 if (nJPsi && nPhi) {
0406 outF << "build and dump Bs" << endl;
0407 BPHRecoBuilder bBs(ew);
0408 bBs.setMinPDiffererence(1.0e-5);
0409 bBs.add("JPsi", lJPsi);
0410 bBs.add("Phi", lPhi);
0411 MassSelect mJPsi(2.946916, 3.246916);
0412 MassSelect mPhi(1.009461, 1.029461);
0413 bBs.filter("JPsi", mJPsi);
0414 bBs.filter("Phi", mPhi);
0415 Chi2Select chi2Bs(0.02);
0416 bBs.filter(chi2Bs);
0417 vector<BPHRecoConstCandPtr> lBs = BPHRecoCandidate::build(bBs);
0418 int iBs;
0419 int nBs = lBs.size();
0420 outF << nBs << " Bs cand found" << endl;
0421
0422 for (iBs = 0; iBs < nBs; ++iBs) {
0423
0424 const BPHRecoCandidate* cptr = lBs[iBs].get();
0425 cptr->kinematicTree("JPsi", 3.096916, 0.000040);
0426 }
0427 for (iBs = 0; iBs < nBs; ++iBs)
0428 dumpRecoCand("Bs", lBs[iBs].get());
0429 }
0430
0431
0432
0433 if (nJPsi && nrc) {
0434 outF << "build and dump Bu" << endl;
0435 BPHRecoBuilder bBu(ew);
0436 bBu.setMinPDiffererence(1.0e-5);
0437 bBu.add("JPsi", lJPsi);
0438 if (usePF) {
0439 bBu.add("Kaon", BPHRecoBuilder::createCollection(pfCands), 0.493677);
0440 } else if (usePC) {
0441 bBu.add("Kaon", BPHRecoBuilder::createCollection(pcCands), 0.493677);
0442 } else if (useGP) {
0443 bBu.add("Kaon", BPHRecoBuilder::createCollection(gpCands), 0.493677);
0444 }
0445 MassSelect mJPsi(2.946916, 3.246916);
0446 KaonNeutralVeto knv;
0447 bBu.filter("JPsi", mJPsi);
0448 bBu.filter("Kaon", tkPt);
0449 bBu.filter("Kaon", knv);
0450 Chi2Select chi2Bu(0.02);
0451 bBu.filter(chi2Bu);
0452 vector<BPHRecoConstCandPtr> lBu = BPHRecoCandidate::build(bBu);
0453 int iBu;
0454 int nBu = lBu.size();
0455 outF << nBu << " Bu cand found" << endl;
0456
0457 for (iBu = 0; iBu < nBu; ++iBu) {
0458
0459 const BPHRecoCandidate* cptr = lBu[iBu].get();
0460 cptr->kinematicTree("JPsi", 3.096916, 0.000040);
0461 }
0462 for (iBu = 0; iBu < nBu; ++iBu)
0463 dumpRecoCand("Bu", lBu[iBu].get());
0464 }
0465
0466 return;
0467 }
0468
0469 void TestBPHRecoDecay::endJob() {
0470 *fPtr << "TestBPHRecoDecay::endJob" << endl;
0471 TDirectory* currentDir = gDirectory;
0472 TFile file(outHist.c_str(), "RECREATE");
0473 map<string, TH1F*>::iterator iter = histoMap.begin();
0474 map<string, TH1F*>::iterator iend = histoMap.end();
0475 while (iter != iend)
0476 iter++->second->Write();
0477 currentDir->cd();
0478 return;
0479 }
0480
0481 void TestBPHRecoDecay::dumpRecoCand(const string& name, const BPHRecoCandidate* cand) {
0482 fillHisto(name, cand);
0483
0484 ostream& outF = *fPtr;
0485
0486 static string cType = " cowboy";
0487 static string sType = " sailor";
0488 static string dType = "";
0489 string* type;
0490 const BPHPlusMinusCandidate* pmCand = dynamic_cast<const BPHPlusMinusCandidate*>(cand);
0491 if (pmCand != nullptr) {
0492 if (pmCand->isCowboy())
0493 type = &cType;
0494 else
0495 type = &sType;
0496 } else
0497 type = &dType;
0498
0499 outF << "****** " << name << " cand mass: " << cand->composite().mass() << " momentum " << cand->composite().px()
0500 << " " << cand->composite().py() << " " << cand->composite().pz() << *type << endl;
0501
0502 bool validFit = cand->isValidFit();
0503 const RefCountedKinematicTree kt = cand->kinematicTree();
0504 const RefCountedKinematicParticle kp = cand->currentParticle();
0505 if (validFit) {
0506 outF << "****** " << name << " constr mass: " << cand->p4().mass() << " momentum " << cand->p4().px() << " "
0507 << cand->p4().py() << " " << cand->p4().pz() << endl;
0508 }
0509
0510 const reco::Vertex& vx = cand->vertex();
0511 const reco::Vertex::Point& vp = vx.position();
0512 double chi2 = vx.chi2();
0513 int ndof = lround(vx.ndof());
0514 double prob = TMath::Prob(chi2, ndof);
0515 string tdca = "";
0516 if (pmCand != nullptr) {
0517 stringstream sstr;
0518 sstr << " - " << pmCand->cAppInRPhi().distance();
0519 tdca = sstr.str();
0520 }
0521 outF << "****** " << name << " vertex: " << vx.isFake() << " " << vx.isValid() << " - " << chi2 << " " << ndof << " "
0522 << prob << " - " << vp.X() << " " << vp.Y() << " " << vp.Z() << tdca << endl;
0523
0524 const vector<string>& dl = cand->daugNames();
0525 int i;
0526 int n = dl.size();
0527 for (i = 0; i < n; ++i) {
0528 const string& name = dl[i];
0529 const reco::Candidate* dp = cand->getDaug(name);
0530 GlobalPoint gp(vp.X(), vp.Y(), vp.Z());
0531 GlobalVector dm(0.0, 0.0, 0.0);
0532 const reco::TransientTrack* tt = cand->getTransientTrack(dp);
0533 if (tt != nullptr) {
0534 TrajectoryStateClosestToPoint tscp = tt->trajectoryStateClosestToPoint(gp);
0535 dm = tscp.momentum();
0536
0537
0538 }
0539 outF << "daughter " << i << " " << name << " " << (dp->charge() > 0 ? '+' : '-') << " momentum: " << dp->px() << " "
0540 << dp->py() << " " << dp->pz() << " - at vertex: " << dm.x() << " " << dm.y() << " " << dm.z() << endl;
0541 }
0542 const vector<string>& dc = cand->compNames();
0543 int j;
0544 int m = dc.size();
0545 for (j = 0; j < m; ++j) {
0546 const string& name = dc[j];
0547 const BPHRecoCandidate* dp = cand->getComp(name).get();
0548 outF << "composite daughter " << j << " " << name << " momentum: " << dp->composite().px() << " "
0549 << dp->composite().py() << " " << dp->composite().pz() << endl;
0550 }
0551
0552 if (validFit) {
0553 const RefCountedKinematicVertex kv = cand->currentDecayVertex();
0554 GlobalPoint gp = kv->position();
0555 outF << " kin fit vertex: " << gp.x() << " " << gp.y() << " " << gp.z() << endl;
0556 vector<RefCountedKinematicParticle> dk = kt->finalStateParticles();
0557 int k;
0558 int l = dk.size();
0559 for (k = 0; k < l; ++k) {
0560 const reco::TransientTrack& tt = dk[k]->refittedTransientTrack();
0561 TrajectoryStateClosestToPoint tscp = tt.trajectoryStateClosestToPoint(gp);
0562 GlobalVector dm = tscp.momentum();
0563
0564
0565 outF << "daughter " << k << " refitted: " << dm.x() << " " << dm.y() << " " << dm.z() << endl;
0566 }
0567 }
0568
0569 return;
0570 }
0571
0572 void TestBPHRecoDecay::fillHisto(const string& name, const BPHRecoCandidate* cand) {
0573 string mass = "mass";
0574 string mcst = "mcst";
0575 fillHisto(mass + name, cand->composite().mass());
0576 if (cand->isValidFit())
0577 fillHisto(mcst + name, cand->p4().mass());
0578
0579 const vector<string>& dc = cand->compNames();
0580 int i;
0581 int n = dc.size();
0582 for (i = 0; i < n; ++i) {
0583 const string& daug = dc[i];
0584 const BPHRecoCandidate* dptr = cand->getComp(daug).get();
0585 fillHisto(mass + name + daug, dptr->composite().mass());
0586 }
0587 return;
0588 }
0589
0590 void TestBPHRecoDecay::fillHisto(const string& name, float x) {
0591 map<string, TH1F*>::iterator iter = histoMap.find(name);
0592 map<string, TH1F*>::iterator iend = histoMap.end();
0593 if (iter == iend)
0594 return;
0595 iter->second->Fill(x);
0596 return;
0597 }
0598
0599 void TestBPHRecoDecay::createHisto(const string& name, int nbin, float hmin, float hmax) {
0600 histoMap[name] = new TH1F(name.c_str(), name.c_str(), nbin, hmin, hmax);
0601 return;
0602 }
0603
0604 #include "FWCore/Framework/interface/MakerMacros.h"
0605
0606 DEFINE_FWK_MODULE(TestBPHRecoDecay);