|
| 1 | +#include <memory> |
| 2 | + |
| 3 | +// user include files |
| 4 | +#include "FWCore/Framework/interface/Frameworkfwd.h" |
| 5 | +#include "FWCore/Framework/interface/stream/EDProducer.h" |
| 6 | + |
| 7 | +#include "FWCore/Framework/interface/Event.h" |
| 8 | +#include "FWCore/Framework/interface/MakerMacros.h" |
| 9 | + |
| 10 | +#include "FWCore/ParameterSet/interface/ParameterSet.h" |
| 11 | +#include "FWCore/Utilities/interface/StreamID.h" |
| 12 | + |
| 13 | +#include "DataFormats/VertexReco/interface/Vertex.h" |
| 14 | +#include "DataFormats/Candidate/interface/VertexCompositePtrCandidate.h" |
| 15 | + |
| 16 | +#include "CommonTools/Utils/interface/StringCutObjectSelector.h" |
| 17 | + |
| 18 | +#include "DataFormats/NanoAOD/interface/FlatTable.h" |
| 19 | +#include "RecoVertex/VertexTools/interface/VertexDistance3D.h" |
| 20 | +#include "RecoVertex/VertexTools/interface/VertexDistanceXY.h" |
| 21 | +#include "RecoVertex/VertexPrimitives/interface/ConvertToFromReco.h" |
| 22 | +#include "RecoVertex/VertexPrimitives/interface/VertexState.h" |
| 23 | +#include "DataFormats/Common/interface/ValueMap.h" |
| 24 | + |
| 25 | +#include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h" |
| 26 | + |
| 27 | +// |
| 28 | +// class declaration |
| 29 | +// |
| 30 | + |
| 31 | +class HLTVertexTableProducer : public edm::stream::EDProducer<> { |
| 32 | +public: |
| 33 | + explicit HLTVertexTableProducer(const edm::ParameterSet&); |
| 34 | + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); |
| 35 | + |
| 36 | +private: |
| 37 | + void produce(edm::Event&, const edm::EventSetup&) override; |
| 38 | + |
| 39 | + // ----------member data --------------------------- |
| 40 | + const edm::EDGetTokenT<std::vector<reco::Vertex>> pvs_; |
| 41 | + const edm::EDGetTokenT<reco::PFCandidateCollection> pfc_; |
| 42 | + const edm::EDGetTokenT<edm::ValueMap<float>> pvsScore_; |
| 43 | + const StringCutObjectSelector<reco::Vertex> goodPvCut_; |
| 44 | + const std::string goodPvCutString_; |
| 45 | + const std::string pvName_; |
| 46 | + const double dlenMin_, dlenSigMin_; |
| 47 | +}; |
| 48 | + |
| 49 | +// |
| 50 | +// constructors |
| 51 | +// |
| 52 | + |
| 53 | +HLTVertexTableProducer::HLTVertexTableProducer(const edm::ParameterSet& params) |
| 54 | + : pvs_(consumes<std::vector<reco::Vertex>>(params.getParameter<edm::InputTag>("pvSrc"))), |
| 55 | + pfc_(consumes<reco::PFCandidateCollection>(params.getParameter<edm::InputTag>("pfSrc"))), |
| 56 | + pvsScore_(consumes<edm::ValueMap<float>>(params.getParameter<edm::InputTag>("pvSrc"))), |
| 57 | + goodPvCut_(params.getParameter<std::string>("goodPvCut"), true), |
| 58 | + goodPvCutString_(params.getParameter<std::string>("goodPvCut")), |
| 59 | + pvName_(params.getParameter<std::string>("pvName")), |
| 60 | + dlenMin_(params.getParameter<double>("dlenMin")), |
| 61 | + dlenSigMin_(params.getParameter<double>("dlenSigMin")) |
| 62 | + |
| 63 | +{ |
| 64 | + produces<nanoaod::FlatTable>("PV"); |
| 65 | + produces<edm::PtrVector<reco::VertexCompositePtrCandidate>>(); |
| 66 | +} |
| 67 | + |
| 68 | +// |
| 69 | +// member functions |
| 70 | +// |
| 71 | + |
| 72 | +// ------------ method called to produce the data ------------ |
| 73 | +void HLTVertexTableProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { |
| 74 | + using namespace edm; |
| 75 | + |
| 76 | + //vertex collection |
| 77 | + auto pvsIn = iEvent.getHandle(pvs_); |
| 78 | + if (!pvsIn.isValid()) { |
| 79 | + edm::LogWarning("HLTVertexTableProducer") |
| 80 | + << "Invalid handle for " << pvName_ << " in primary vertex input collection"; |
| 81 | + return; |
| 82 | + } |
| 83 | + const auto& pvsScoreProd = iEvent.get(pvsScore_); |
| 84 | + |
| 85 | + //pf candidates collection |
| 86 | + auto pfcIn = iEvent.getHandle(pfc_); |
| 87 | + if (!pfcIn.isValid()) { |
| 88 | + edm::LogWarning("HLTVertexTableProducer") |
| 89 | + << "Invalid handle for " << pvName_ << " in PF candidate input collection"; |
| 90 | + return; |
| 91 | + } |
| 92 | + |
| 93 | + std::vector<float> v_ndof; |
| 94 | + std::vector<float> v_chi2; |
| 95 | + std::vector<float> v_x; |
| 96 | + std::vector<float> v_y; |
| 97 | + std::vector<float> v_z; |
| 98 | + std::vector<float> v_xError; |
| 99 | + std::vector<float> v_yError; |
| 100 | + std::vector<float> v_zError; |
| 101 | + std::vector<uint8_t> v_is_good; |
| 102 | + std::vector<uint8_t> v_nTracks; |
| 103 | + std::vector<float> v_pv_score; |
| 104 | + std::vector<float> v_pv_sumpt2; |
| 105 | + std::vector<float> v_pv_sumpx; |
| 106 | + std::vector<float> v_pv_sumpy; |
| 107 | + |
| 108 | + for (size_t i = 0; i < (*pvsIn).size(); i++) { |
| 109 | + v_ndof.push_back((*pvsIn)[i].ndof()); |
| 110 | + v_chi2.push_back((*pvsIn)[i].normalizedChi2()); |
| 111 | + v_x.push_back((*pvsIn)[i].x()); |
| 112 | + v_y.push_back((*pvsIn)[i].y()); |
| 113 | + v_z.push_back((*pvsIn)[i].z()); |
| 114 | + v_xError.push_back((*pvsIn)[i].xError()); |
| 115 | + v_yError.push_back((*pvsIn)[i].yError()); |
| 116 | + v_zError.push_back((*pvsIn)[i].zError()); |
| 117 | + v_nTracks.push_back((*pvsIn)[i].nTracks()); |
| 118 | + v_is_good.push_back(goodPvCut_((*pvsIn)[i])); |
| 119 | + v_pv_score.push_back(pvsScoreProd.get(pvsIn.id(), i)); |
| 120 | + |
| 121 | + float pv_sumpt2 = 0; |
| 122 | + float pv_sumpx = 0; |
| 123 | + float pv_sumpy = 0; |
| 124 | + for (const auto& obj : *pfcIn) { |
| 125 | + // skip neutrals |
| 126 | + if (obj.charge() == 0) |
| 127 | + continue; |
| 128 | + double dz = fabs(obj.trackRef()->dz((*pvsIn)[i].position())); |
| 129 | + bool include_pfc = false; |
| 130 | + if (dz < 0.2) { |
| 131 | + include_pfc = true; |
| 132 | + for (size_t j = 0; j < (*pvsIn).size() && j != i; j++) { |
| 133 | + double newdz = fabs(obj.trackRef()->dz((*pvsIn)[j].position())); |
| 134 | + if (newdz < dz) { |
| 135 | + include_pfc = false; |
| 136 | + break; |
| 137 | + } |
| 138 | + } // this pf candidate belongs to other PV |
| 139 | + } |
| 140 | + if (include_pfc) { |
| 141 | + float pfc_pt = obj.pt(); |
| 142 | + pv_sumpt2 += pfc_pt * pfc_pt; |
| 143 | + pv_sumpx += obj.px(); |
| 144 | + pv_sumpy += obj.py(); |
| 145 | + } |
| 146 | + } |
| 147 | + |
| 148 | + v_pv_sumpt2.push_back(pv_sumpt2); |
| 149 | + v_pv_sumpx.push_back(pv_sumpx); |
| 150 | + v_pv_sumpy.push_back(pv_sumpy); |
| 151 | + } |
| 152 | + |
| 153 | + //table for all primary vertices |
| 154 | + auto pvTable = std::make_unique<nanoaod::FlatTable>((*pvsIn).size(), pvName_, true); |
| 155 | + pvTable->addColumn<float>("ndof", v_ndof, "primary vertex number of degrees of freedom", 8); |
| 156 | + pvTable->addColumn<float>("chi2", v_chi2, "primary vertex reduced chi2", 8); |
| 157 | + pvTable->addColumn<float>("x", v_x, "primary vertex x coordinate", 10); |
| 158 | + pvTable->addColumn<float>("y", v_y, "primary vertex y coordinate", 10); |
| 159 | + pvTable->addColumn<float>("z", v_z, "primary vertex z coordinate", 16); |
| 160 | + pvTable->addColumn<float>("xError", v_xError, "primary vertex error in x coordinate", 10); |
| 161 | + pvTable->addColumn<float>("yError", v_yError, "primary vertex error in y coordinate", 10); |
| 162 | + pvTable->addColumn<float>("zError", v_zError, "primary vertex error in z coordinate", 16); |
| 163 | + pvTable->addColumn<uint8_t>( |
| 164 | + "isGood", v_is_good, "wheter the primary vertex passes selection: " + goodPvCutString_ + ")"); |
| 165 | + pvTable->addColumn<uint8_t>("nTracks", v_nTracks, "primary vertex number of associated tracks"); |
| 166 | + pvTable->addColumn<float>("score", v_pv_score, "primary vertex score, i.e. sum pt2 of clustered objects", 8); |
| 167 | + pvTable->addColumn<float>( |
| 168 | + "sumpt2", v_pv_sumpt2, "sum pt2 of pf charged candidates within dz=0.2 for the main primary vertex", 10); |
| 169 | + pvTable->addColumn<float>( |
| 170 | + "sumpx", v_pv_sumpx, "sum px of pf charged candidates within dz=0.2 for the main primary vertex", 10); |
| 171 | + pvTable->addColumn<float>( |
| 172 | + "sumpy", v_pv_sumpy, "sum py of pf charged candidates within dz=0.2 for the main primary vertex", 10); |
| 173 | + |
| 174 | + iEvent.put(std::move(pvTable), "PV"); |
| 175 | +} |
| 176 | + |
| 177 | +// ------------ fill 'descriptions' with the allowed parameters for the module ------------ |
| 178 | +void HLTVertexTableProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { |
| 179 | + edm::ParameterSetDescription desc; |
| 180 | + |
| 181 | + desc.add<std::string>("pvName")->setComment("name of the flat table ouput"); |
| 182 | + desc.add<edm::InputTag>("pvSrc")->setComment( |
| 183 | + "std::vector<reco::Vertex> and ValueMap<float> primary vertex input collections"); |
| 184 | + desc.add<edm::InputTag>("pfSrc")->setComment("reco::PFCandidateCollection PF candidates input collections"); |
| 185 | + desc.add<std::string>("goodPvCut")->setComment("selection on the primary vertex"); |
| 186 | + |
| 187 | + desc.add<double>("dlenMin")->setComment("minimum value of dl to select secondary vertex"); |
| 188 | + desc.add<double>("dlenSigMin")->setComment("minimum value of dl significance to select secondary vertex"); |
| 189 | + |
| 190 | + descriptions.addWithDefaultLabel(desc); |
| 191 | +} |
| 192 | + |
| 193 | +// ------------ define this as a plug-in ------------ |
| 194 | +DEFINE_FWK_MODULE(HLTVertexTableProducer); |
0 commit comments