1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
/**\class ParticleDecayProducer
*
* Original Author: Nicola De Filippis
*
*/
// user include files
#include "FWCore/Framework/interface/Frameworkfwd.h"
#include "FWCore/Framework/interface/global/EDProducer.h"
#include "FWCore/ParameterSet/interface/ParameterSet.h"
#include "FWCore/Utilities/interface/InputTag.h"
#include "DataFormats/Candidate/interface/Candidate.h"
#include <vector>
class ParticleDecayProducer : public edm::global::EDProducer<> {
public:
explicit ParticleDecayProducer(const edm::ParameterSet&);
~ParticleDecayProducer() override = default;
private:
void produce(edm::StreamID, edm::Event& e, edm::EventSetup const& c) const override;
edm::EDGetTokenT<reco::CandidateCollection> genCandidatesToken_;
const int motherPdgId_;
const std::vector<int> daughtersPdgId_;
const std::string decayChain_;
std::vector<std::string> valias;
};
// Candidate handling
#include "DataFormats/Candidate/interface/CandMatchMap.h"
#include "DataFormats/Common/interface/AssociationVector.h"
#include "CommonTools/Utils/interface/PtComparator.h"
#include "FWCore/Framework/interface/Event.h"
#include <sstream>
using namespace edm;
using namespace std;
using namespace reco;
// constructors
ParticleDecayProducer::ParticleDecayProducer(const edm::ParameterSet& iConfig)
: genCandidatesToken_(consumes<CandidateCollection>(iConfig.getParameter<InputTag>("src"))),
motherPdgId_(iConfig.getParameter<int>("motherPdgId")),
daughtersPdgId_(iConfig.getParameter<vector<int> >("daughtersPdgId")),
decayChain_(iConfig.getParameter<std::string>("decayChain")) {
string alias;
produces<CandidateCollection>(alias = decayChain_ + "Mother").setBranchAlias(alias);
for (unsigned int j = 0; j < daughtersPdgId_.size(); ++j) {
ostringstream index, collection;
index << j;
collection << decayChain_ << "Lepton" << index.str();
valias.push_back(collection.str());
produces<CandidateCollection>(valias.at(j)).setBranchAlias(valias.at(j));
}
}
void ParticleDecayProducer::produce(edm::StreamID, edm::Event& iEvent, edm::EventSetup const&) const {
// get gen particle candidates
const edm::Handle<CandidateCollection> genCandidatesCollection = iEvent.getHandle(genCandidatesToken_);
unique_ptr<CandidateCollection> mothercands(new CandidateCollection);
unique_ptr<CandidateCollection> daughterscands(new CandidateCollection);
size_t daughtersize = daughtersPdgId_.size();
for (CandidateCollection::const_iterator p = genCandidatesCollection->begin(); p != genCandidatesCollection->end();
++p) {
if (p->pdgId() == motherPdgId_ && p->status() == 3) {
mothercands->push_back(p->clone());
size_t ndau = p->numberOfDaughters();
for (size_t i = 0; i < ndau; ++i) {
for (size_t j = 0; j < daughtersize; ++j) {
if (p->daughter(i)->pdgId() == daughtersPdgId_[j] && p->daughter(i)->status() == 3) {
daughterscands->push_back(p->daughter(i)->clone());
}
}
}
}
}
iEvent.put(std::move(mothercands), decayChain_ + "Mother");
daughterscands->sort(GreaterByPt<reco::Candidate>());
for (unsigned int row = 0; row < daughtersize; ++row) {
unique_ptr<CandidateCollection> leptonscands_(new CandidateCollection);
leptonscands_->push_back((daughterscands->begin() + row)->clone());
iEvent.put(std::move(leptonscands_), valias.at(row));
}
}
#include "FWCore/Framework/interface/MakerMacros.h"
DEFINE_FWK_MODULE(ParticleDecayProducer);
|