Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:23:42

0001 #include "FWCore/Framework/interface/global/EDProducer.h"
0002 #include "FWCore/Framework/interface/Event.h"
0003 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0004 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0005 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0006 #include "DataFormats/NanoAOD/interface/FlatTable.h"
0007 #include "SimDataFormats/GeneratorProducts/interface/LHEEventProduct.h"
0008 #include "SimDataFormats/PileupSummaryInfo/interface/PileupSummaryInfo.h"
0009 #include "DataFormats/VertexReco/interface/Vertex.h"
0010 
0011 #include <vector>
0012 #include <iostream>
0013 #include <algorithm>
0014 
0015 class NPUTablesProducer : public edm::global::EDProducer<> {
0016 public:
0017   NPUTablesProducer(edm::ParameterSet const& params)
0018       : npuTag_(consumes<std::vector<PileupSummaryInfo>>(params.getParameter<edm::InputTag>("src"))),
0019         pvTag_(consumes<std::vector<reco::Vertex>>(params.getParameter<edm::InputTag>("pvsrc"))),
0020         vz_(params.getParameter<std::vector<double>>("zbins")),
0021         savePtHatMax_(params.getParameter<bool>("savePtHatMax")) {
0022     produces<nanoaod::FlatTable>();
0023   }
0024 
0025   ~NPUTablesProducer() override {}
0026 
0027   void produce(edm::StreamID id, edm::Event& iEvent, const edm::EventSetup& iSetup) const override {
0028     auto npuTab = std::make_unique<nanoaod::FlatTable>(1, "Pileup", true);
0029 
0030     const auto& pvProd = iEvent.get(pvTag_);
0031     const double refpvz = pvProd.at(0).position().z();
0032 
0033     edm::Handle<std::vector<PileupSummaryInfo>> npuInfo;
0034     if (iEvent.getByToken(npuTag_, npuInfo)) {
0035       fillNPUObjectTable(*npuInfo, *npuTab, refpvz);
0036     }
0037 
0038     iEvent.put(std::move(npuTab));
0039   }
0040 
0041   void fillNPUObjectTable(const std::vector<PileupSummaryInfo>& npuProd, nanoaod::FlatTable& out, double refpvz) const {
0042     // Get BX 0
0043     unsigned int bx0 = 0;
0044     float nt = 0;
0045     unsigned int npu = 0;
0046 
0047     auto zbin = std::lower_bound(vz_.begin(), vz_.end() - 1, std::abs(refpvz));
0048     float pudensity = 0;
0049     float gpudensity = 0;
0050 
0051     float pthatmax = 0;
0052 
0053     for (unsigned int ibx = 0; ibx < npuProd.size(); ibx++) {
0054       if (npuProd[ibx].getBunchCrossing() == 0) {
0055         bx0 = ibx;
0056         nt = npuProd[ibx].getTrueNumInteractions();
0057         npu = npuProd[ibx].getPU_NumInteractions();
0058 
0059         std::vector<float> zpositions;
0060         unsigned int nzpositions = npuProd[ibx].getPU_zpositions().size();
0061         for (unsigned int j = 0; j < nzpositions; ++j) {
0062           zpositions.push_back(npuProd[ibx].getPU_zpositions()[j]);
0063           if (std::abs(zpositions.back() - refpvz) < 0.1)
0064             pudensity++;  //N_PU/mm
0065           auto bin = std::lower_bound(vz_.begin(), vz_.end() - 1, std::abs(zpositions.back()));
0066           if (bin != vz_.end() && bin == zbin)
0067             gpudensity++;
0068         }
0069         gpudensity /= (20.0 * (*(zbin) - *(zbin - 1)));
0070 
0071         if (savePtHatMax_) {
0072           if (!npuProd[ibx].getPU_pT_hats().empty()) {
0073             pthatmax = *max_element(npuProd[ibx].getPU_pT_hats().begin(), npuProd[ibx].getPU_pT_hats().end());
0074           }
0075         }
0076       }
0077     }
0078     unsigned int eoot = 0;
0079     for (unsigned int ipu = 0; ipu < bx0; ipu++) {
0080       eoot += npuProd[ipu].getPU_NumInteractions();
0081     }
0082     unsigned int loot = 0;
0083     for (unsigned int ipu = npuProd.size() - 1; ipu > bx0; ipu--) {
0084       loot += npuProd[ipu].getPU_NumInteractions();
0085     }
0086     out.addColumnValue<float>("nTrueInt",
0087                               nt,
0088                               "the true mean number of the poisson distribution for this event from which the number "
0089                               "of interactions each bunch crossing has been sampled",
0090                               10);
0091     out.addColumnValue<int>(
0092         "nPU",
0093         npu,
0094         "the number of pileup interactions that have been added to the event in the current bunch crossing");
0095     out.addColumnValue<int>("sumEOOT", eoot, "number of early out of time pileup");
0096     out.addColumnValue<int>("sumLOOT", loot, "number of late out of time pileup");
0097     out.addColumnValue<float>("pudensity", pudensity, "PU vertices / mm");
0098     out.addColumnValue<float>("gpudensity", gpudensity, "Generator-level PU vertices / mm");
0099     if (savePtHatMax_) {
0100       out.addColumnValue<float>("pthatmax", pthatmax, "Maximum pt-hat", 10);
0101     }
0102   }
0103 
0104   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0105     edm::ParameterSetDescription desc;
0106     desc.add<edm::InputTag>("src", edm::InputTag("slimmedAddPileupInfo"))
0107         ->setComment("tag for the PU information (vector<PileupSummaryInfo>)");
0108     desc.add<edm::InputTag>("pvsrc", edm::InputTag("offlineSlimmedPrimaryVertices"))->setComment("tag for the PVs");
0109     desc.add<std::vector<double>>("zbins", {})
0110         ->setComment("Z bins to compute the generator-level number of PU vertices per mm");
0111     desc.add<bool>("savePtHatMax", false)->setComment("Store maximum pt-hat of PU");
0112     descriptions.add("puTable", desc);
0113   }
0114 
0115 protected:
0116   const edm::EDGetTokenT<std::vector<PileupSummaryInfo>> npuTag_;
0117   const edm::EDGetTokenT<std::vector<reco::Vertex>> pvTag_;
0118 
0119   const std::vector<double> vz_;
0120 
0121   bool savePtHatMax_;
0122 };
0123 
0124 #include "FWCore/Framework/interface/MakerMacros.h"
0125 DEFINE_FWK_MODULE(NPUTablesProducer);