Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-04-01 23:54:10

0001 #include "CommonTools/UtilAlgos/interface/TFileService.h"
0002 #include "TObjString.h"
0003 #include "DataFormats/Candidate/interface/Candidate.h"
0004 #include "DataFormats/Common/interface/ValueMap.h"
0005 #include "DataFormats/HepMCCandidate/interface/GenParticle.h"
0006 #include "DataFormats/L1TrackTrigger/interface/TTTypes.h"
0007 #include "DataFormats/L1Trigger/interface/Vertex.h"
0008 #include "DataFormats/L1Trigger/interface/VertexWord.h"
0009 #include "DataFormats/JetReco/interface/GenJet.h"
0010 #include "DataFormats/Phase2TrackerDigi/interface/Phase2TrackerDigi.h"
0011 #include "DataFormats/TrackerCommon/interface/TrackerTopology.h"
0012 #include "FWCore/Framework/interface/one/EDAnalyzer.h"
0013 #include "FWCore/Framework/interface/MakerMacros.h"
0014 #include "FWCore/Framework/interface/Event.h"
0015 #include "FWCore/Framework/interface/EventSetup.h"
0016 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0017 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0018 #include "FWCore/ServiceRegistry/interface/Service.h"
0019 #include "Geometry/Records/interface/TrackerDigiGeometryRecord.h"
0020 #include "L1Trigger/VertexFinder/interface/AnalysisSettings.h"
0021 #include "L1Trigger/VertexFinder/interface/InputData.h"
0022 #include "L1Trigger/VertexFinder/interface/L1TrackTruthMatched.h"
0023 #include "L1Trigger/VertexFinder/interface/RecoVertex.h"
0024 #include "L1Trigger/VertexFinder/interface/selection.h"
0025 #include "SimDataFormats/GeneratorProducts/interface/HepMCProduct.h"
0026 #include "SimDataFormats/PileupSummaryInfo/interface/PileupSummaryInfo.h"
0027 #include "SimDataFormats/TrackingAnalysis/interface/TrackingParticle.h"
0028 #include "SimTracker/TrackTriggerAssociation/interface/TTClusterAssociationMap.h"
0029 #include "SimTracker/TrackTriggerAssociation/interface/TTStubAssociationMap.h"
0030 #include "SimTracker/TrackTriggerAssociation/interface/TTTrackAssociationMap.h"
0031 
0032 #include "TTree.h"
0033 
0034 #include <map>
0035 #include <string>
0036 #include <vector>
0037 #include <iostream>
0038 
0039 using namespace std;
0040 
0041 namespace l1tVertexFinder {
0042 
0043   class VertexNTupler : public edm::one::EDAnalyzer<edm::one::SharedResources> {
0044   public:
0045     explicit VertexNTupler(const edm::ParameterSet&);
0046     ~VertexNTupler() override;
0047 
0048   private:
0049     struct EmulationVerticesBranchData {
0050       std::vector<unsigned> numTracks;
0051       std::vector<float> z0;
0052       std::vector<float> sumPt;
0053 
0054       void clear() {
0055         numTracks.clear();
0056         z0.clear();
0057         sumPt.clear();
0058       }
0059     };
0060 
0061     struct GenJetsBranchData {
0062       std::vector<float> energy;
0063       std::vector<float> pt;
0064       std::vector<float> eta;
0065       std::vector<float> phi;
0066 
0067       void clear() {
0068         energy.clear();
0069         pt.clear();
0070         eta.clear();
0071         phi.clear();
0072       }
0073     };
0074 
0075     struct GenParticlesBranchData {
0076       std::vector<float> energy;
0077       std::vector<float> pt;
0078       std::vector<float> eta;
0079       std::vector<float> phi;
0080       std::vector<int> pdgId;
0081       std::vector<int> status;
0082 
0083       void clear() {
0084         energy.clear();
0085         pt.clear();
0086         eta.clear();
0087         phi.clear();
0088         pdgId.clear();
0089         status.clear();
0090       }
0091     };
0092 
0093     struct RecoVerticesBranchData : public EmulationVerticesBranchData {
0094       std::vector<std::vector<unsigned>> trackIdxs;
0095 
0096       void clear() {
0097         numTracks.clear();
0098         trackIdxs.clear();
0099         z0.clear();
0100         sumPt.clear();
0101       }
0102     };
0103 
0104     struct RecoTracksBranchData {
0105       std::vector<float> pt;
0106       std::vector<float> eta;
0107       std::vector<float> phi;
0108       std::vector<float> z0;
0109       std::vector<unsigned> numStubs;
0110       std::vector<float> chi2dof;
0111       std::vector<int> trueMatchIdx;
0112       std::vector<int> truthMapMatchIdx;
0113       std::vector<float> truthMapIsGenuine;
0114       std::vector<float> truthMapIsLooselyGenuine;
0115       std::vector<float> truthMapIsCombinatoric;
0116       std::vector<float> truthMapIsUnknown;
0117 
0118       void clear() {
0119         pt.clear();
0120         eta.clear();
0121         phi.clear();
0122         z0.clear();
0123         numStubs.clear();
0124         chi2dof.clear();
0125         trueMatchIdx.clear();
0126         truthMapMatchIdx.clear();
0127         truthMapIsGenuine.clear();
0128         truthMapIsLooselyGenuine.clear();
0129         truthMapIsCombinatoric.clear();
0130         truthMapIsUnknown.clear();
0131       }
0132     };
0133 
0134     struct TrueTracksBranchData {
0135       std::vector<float> pt;
0136       std::vector<float> eta;
0137       std::vector<float> phi;
0138       std::vector<float> z0;
0139       std::vector<int> pdgId;
0140       std::vector<float> physCollision;
0141       std::vector<float> use;
0142       std::vector<float> useForEff;
0143       std::vector<float> useForAlgEff;
0144       std::vector<float> useForVertexReco;
0145 
0146       void clear() {
0147         pt.clear();
0148         eta.clear();
0149         phi.clear();
0150         z0.clear();
0151         pdgId.clear();
0152         physCollision.clear();
0153         use.clear();
0154         useForEff.clear();
0155         useForAlgEff.clear();
0156         useForVertexReco.clear();
0157       }
0158     };
0159 
0160     void beginJob() override;
0161     void analyze(const edm::Event& evt, const edm::EventSetup& setup) override;
0162     void endJob() override;
0163 
0164     // define types for stub-related classes
0165     typedef TTTrackAssociationMap<Ref_Phase2TrackerDigi_> TTTrackAssMap;
0166     typedef edm::View<TTTrack<Ref_Phase2TrackerDigi_>> TTTrackCollectionView;
0167 
0168     // references to tags containing information relevant to perofrmance analysis
0169     const edm::EDGetTokenT<l1tVertexFinder::InputData> inputDataToken_;
0170     const edm::EDGetTokenT<std::vector<PileupSummaryInfo>> pileupSummaryToken_;
0171     const edm::EDGetTokenT<edm::View<reco::GenParticle>> genParticlesToken_;
0172     const edm::EDGetTokenT<std::vector<reco::GenJet>> genJetsToken_;
0173     const edm::EDGetTokenT<std::vector<l1tVertexFinder::TP>> allMatchedTPsToken_;
0174     const edm::EDGetTokenT<edm::ValueMap<l1tVertexFinder::TP>> vTPsToken_;
0175     std::map<std::string, edm::EDGetTokenT<TTTrackCollectionView>> l1TracksTokenMap_;
0176     std::map<std::string, edm::EDGetTokenT<TTTrackAssociationMap<Ref_Phase2TrackerDigi_>>> l1TracksMapTokenMap_;
0177     std::map<std::string, edm::EDGetTokenT<std::vector<l1t::Vertex>>> l1VerticesTokenMap_;
0178     std::map<std::string, edm::EDGetTokenT<std::vector<l1t::VertexWord>>> l1VerticesEmulationTokenMap_;
0179     std::vector<edm::EDGetTokenT<std::vector<l1t::Vertex>>> l1VerticesExtraTokens_;
0180 
0181     TTree* outputTree_;
0182 
0183     const bool printResults_;
0184 
0185     // storage class for configuration parameters
0186     AnalysisSettings settings_;
0187 
0188     // Histograms for Vertex Reconstruction
0189 
0190     float numTrueInteractions_, hepMCVtxZ0_, genVtxZ0_;
0191     int numPileupVertices_;
0192 
0193     GenJetsBranchData genJetsBranchData_;
0194     TrueTracksBranchData trueTracksBranchData_;
0195     std::vector<float> truePileUpVtxZ0_;
0196     GenParticlesBranchData genParticlesHardOutgoingBranchData_;
0197 
0198     std::map<std::string, RecoTracksBranchData> l1TracksBranchData_;
0199     std::map<std::string, RecoVerticesBranchData> l1VerticesBranchData_;
0200     std::map<std::string, std::string> l1VerticesInputMap_;
0201     std::map<std::string, EmulationVerticesBranchData> l1VerticesEmulationBranchData_;
0202 
0203     std::vector<std::vector<unsigned>> l1Vertices_extra_numTracks_;
0204     std::vector<std::vector<float>> l1Vertices_extra_z0_;
0205     std::vector<std::vector<float>> l1Vertices_extra_z0_etaWeighted_;
0206     std::vector<std::vector<float>> l1Vertices_extra_sumPt_;
0207   };
0208 
0209   VertexNTupler::VertexNTupler(const edm::ParameterSet& iConfig)
0210       : inputDataToken_(consumes<l1tVertexFinder::InputData>(iConfig.getParameter<edm::InputTag>("inputDataInputTag"))),
0211         pileupSummaryToken_(consumes<std::vector<PileupSummaryInfo>>(edm::InputTag("addPileupInfo"))),
0212         genParticlesToken_(
0213             consumes<edm::View<reco::GenParticle>>(iConfig.getParameter<edm::InputTag>("genParticleInputTag"))),
0214         genJetsToken_(consumes<std::vector<reco::GenJet>>(iConfig.getParameter<edm::InputTag>("genJetsInputTag"))),
0215         allMatchedTPsToken_(
0216             consumes<std::vector<l1tVertexFinder::TP>>(iConfig.getParameter<edm::InputTag>("l1TracksTPInputTags"))),
0217         vTPsToken_(consumes<edm::ValueMap<l1tVertexFinder::TP>>(
0218             iConfig.getParameter<edm::InputTag>("l1TracksTPValueMapInputTags"))),
0219         printResults_(iConfig.getParameter<bool>("printResults")),
0220         settings_(iConfig) {
0221     const std::vector<std::string> trackBranchNames(
0222         iConfig.getParameter<std::vector<std::string>>("l1TracksBranchNames"));
0223     const std::vector<edm::InputTag> trackInputTags(
0224         iConfig.getParameter<std::vector<edm::InputTag>>("l1TracksInputTags"));
0225     const std::vector<edm::InputTag> trackMapInputTags(
0226         iConfig.getParameter<std::vector<edm::InputTag>>("l1TracksTruthMapInputTags"));
0227 
0228     if (trackBranchNames.size() != trackInputTags.size())
0229       throw cms::Exception("The number of track branch names (" + std::to_string(trackBranchNames.size()) +
0230                            ") specified in the config does not match the number of input tags (" +
0231                            std::to_string(trackInputTags.size()) + ")");
0232     if (trackBranchNames.size() != trackMapInputTags.size())
0233       throw cms::Exception("The number of track branch names (" + std::to_string(trackBranchNames.size()) +
0234                            ") specified in the config does not match the number of track map input tags (" +
0235                            std::to_string(trackMapInputTags.size()) + ")");
0236 
0237     const std::vector<std::string> vertexBranchNames(
0238         iConfig.getParameter<std::vector<std::string>>("l1VertexBranchNames"));
0239     const std::vector<edm::InputTag> vertexInputTags(
0240         iConfig.getParameter<std::vector<edm::InputTag>>("l1VertexInputTags"));
0241     const std::vector<std::string> vertexTrackNames(
0242         iConfig.getParameter<std::vector<std::string>>("l1VertexTrackInputs"));
0243 
0244     if (vertexBranchNames.size() != vertexInputTags.size())
0245       throw cms::Exception("The number of vertex branch names (" + std::to_string(vertexBranchNames.size()) +
0246                            ") specified in the config does not match the number of input tags (" +
0247                            std::to_string(vertexInputTags.size()) + ")");
0248     if (vertexBranchNames.size() != vertexTrackNames.size())
0249       throw cms::Exception(
0250           "The number of vertex branch names (" + std::to_string(vertexBranchNames.size()) +
0251           ") specified in the config does not match the number of associated input track collection names (" +
0252           std::to_string(vertexTrackNames.size()) + ")");
0253 
0254     const std::vector<std::string> emulationVertexBranchNames(
0255         iConfig.getParameter<std::vector<std::string>>("emulationVertexBranchNames"));
0256     const std::vector<edm::InputTag> emulationVertexInputTags(
0257         iConfig.getParameter<std::vector<edm::InputTag>>("emulationVertexInputTags"));
0258 
0259     const std::vector<edm::InputTag> extraVertexInputTags(
0260         iConfig.getParameter<std::vector<edm::InputTag>>("extraL1VertexInputTags"));
0261     const std::vector<std::string> extraVertexDescriptions(
0262         iConfig.getParameter<std::vector<std::string>>("extraL1VertexDescriptions"));
0263 
0264     usesResource(TFileService::kSharedResource);
0265     edm::Service<TFileService> fs;
0266     outputTree_ = fs->make<TTree>("l1VertexReco", "L1 vertex-related info");
0267 
0268     std::vector<std::string>::const_iterator branchNameIt = emulationVertexBranchNames.begin();
0269     std::vector<edm::InputTag>::const_iterator inputTagIt = emulationVertexInputTags.begin();
0270     for (; branchNameIt != emulationVertexBranchNames.end(); branchNameIt++, inputTagIt++) {
0271       l1VerticesEmulationTokenMap_[*branchNameIt] = consumes<std::vector<l1t::VertexWord>>(*inputTagIt);
0272       l1VerticesEmulationBranchData_[*branchNameIt] = EmulationVerticesBranchData();
0273       EmulationVerticesBranchData& branchData = l1VerticesEmulationBranchData_.at(*branchNameIt);
0274 
0275       outputTree_->Branch(("emulationVertices_" + *branchNameIt + "_numTracks").c_str(), &branchData.numTracks);
0276       outputTree_->Branch(("emulationVertices_" + *branchNameIt + "_z0").c_str(), &branchData.z0);
0277       outputTree_->Branch(("emulationVertices_" + *branchNameIt + "_sumPt").c_str(), &branchData.sumPt);
0278     }
0279 
0280     outputTree_->Branch("genJets_energy", &genJetsBranchData_.energy);
0281     outputTree_->Branch("genJets_pt", &genJetsBranchData_.pt);
0282     outputTree_->Branch("genJets_eta", &genJetsBranchData_.eta);
0283     outputTree_->Branch("genJets_phi", &genJetsBranchData_.phi);
0284     outputTree_->Branch("genParticles_hardProcOutgoing_energy", &genParticlesHardOutgoingBranchData_.energy);
0285     outputTree_->Branch("genParticles_hardProcOutgoing_pt", &genParticlesHardOutgoingBranchData_.pt);
0286     outputTree_->Branch("genParticles_hardProcOutgoing_eta", &genParticlesHardOutgoingBranchData_.eta);
0287     outputTree_->Branch("genParticles_hardProcOutgoing_phi", &genParticlesHardOutgoingBranchData_.phi);
0288     outputTree_->Branch("genParticles_hardProcOutgoing_pdgId", &genParticlesHardOutgoingBranchData_.pdgId);
0289     outputTree_->Branch("genParticles_hardProcOutgoing_status", &genParticlesHardOutgoingBranchData_.status);
0290     outputTree_->Branch("genVertex_z0", &genVtxZ0_);
0291     outputTree_->Branch("hepMCVertex_z0", &hepMCVtxZ0_);
0292     outputTree_->Branch("pileupSummary_trueNumInteractions", &numTrueInteractions_);
0293     outputTree_->Branch("pileupSummary_numPileupVertices", &numPileupVertices_);
0294 
0295     std::vector<std::string>::const_iterator trackBranchNameIt = trackBranchNames.begin();
0296     std::vector<edm::InputTag>::const_iterator trackInputTagIt = trackInputTags.begin();
0297     std::vector<edm::InputTag>::const_iterator trackMapInputTagIt = trackMapInputTags.begin();
0298     for (; trackBranchNameIt != trackBranchNames.end(); trackBranchNameIt++, trackInputTagIt++, trackMapInputTagIt++) {
0299       l1TracksTokenMap_[*trackBranchNameIt] = consumes<TTTrackCollectionView>(*trackInputTagIt);
0300       l1TracksMapTokenMap_[*trackBranchNameIt] =
0301           consumes<TTTrackAssociationMap<Ref_Phase2TrackerDigi_>>(*trackMapInputTagIt);
0302 
0303       RecoTracksBranchData& branchData = l1TracksBranchData_[*trackBranchNameIt];
0304 
0305       outputTree_->Branch(("recoTracks_" + *trackBranchNameIt + "_pt").c_str(), &branchData.pt);
0306       outputTree_->Branch(("recoTracks_" + *trackBranchNameIt + "_eta").c_str(), &branchData.eta);
0307       outputTree_->Branch(("recoTracks_" + *trackBranchNameIt + "_phi").c_str(), &branchData.phi);
0308       outputTree_->Branch(("recoTracks_" + *trackBranchNameIt + "_z0").c_str(), &branchData.z0);
0309       outputTree_->Branch(("recoTracks_" + *trackBranchNameIt + "_numStubs").c_str(), &branchData.numStubs);
0310       outputTree_->Branch(("recoTracks_" + *trackBranchNameIt + "_chi2dof").c_str(), &branchData.chi2dof);
0311       outputTree_->Branch(("recoTracks_" + *trackBranchNameIt + "_trueMatchIdx").c_str(), &branchData.trueMatchIdx);
0312       outputTree_->Branch(("recoTracks_" + *trackBranchNameIt + "_truthMap_matchIdx").c_str(),
0313                           &branchData.truthMapMatchIdx);
0314       outputTree_->Branch(("recoTracks_" + *trackBranchNameIt + "_truthMap_isGenuine").c_str(),
0315                           &branchData.truthMapIsGenuine);
0316       outputTree_->Branch(("recoTracks_" + *trackBranchNameIt + "_truthMap_isLooselyGenuine").c_str(),
0317                           &branchData.truthMapIsLooselyGenuine);
0318       outputTree_->Branch(("recoTracks_" + *trackBranchNameIt + "_truthMap_isCombinatoric").c_str(),
0319                           &branchData.truthMapIsCombinatoric);
0320       outputTree_->Branch(("recoTracks_" + *trackBranchNameIt + "_truthMap_isUnknown").c_str(),
0321                           &branchData.truthMapIsUnknown);
0322     }
0323 
0324     branchNameIt = vertexBranchNames.begin();
0325     inputTagIt = vertexInputTags.begin();
0326     std::vector<std::string>::const_iterator l1VertexTrackNameIt = vertexTrackNames.begin();
0327     for (; branchNameIt != vertexBranchNames.end(); branchNameIt++, inputTagIt++, l1VertexTrackNameIt++) {
0328       l1VerticesTokenMap_[*branchNameIt] = consumes<std::vector<l1t::Vertex>>(*inputTagIt);
0329       l1VerticesBranchData_[*branchNameIt] = RecoVerticesBranchData();
0330       RecoVerticesBranchData& branchData = l1VerticesBranchData_.at(*branchNameIt);
0331       l1VerticesInputMap_[*branchNameIt] = *l1VertexTrackNameIt;
0332 
0333       if (l1TracksTokenMap_.count(*l1VertexTrackNameIt) == 0)
0334         throw cms::Exception("Invalid track collection name '" + *l1VertexTrackNameIt +
0335                              "' specified as input to vertex collection '" + *branchNameIt + "'");
0336 
0337       outputTree_->Branch(("recoVertices_" + *branchNameIt + "_numTracks").c_str(), &branchData.numTracks);
0338       outputTree_->Branch(("recoVertices_" + *branchNameIt + "_trackIdxs").c_str(), &branchData.trackIdxs);
0339       outputTree_->Branch(("recoVertices_" + *branchNameIt + "_z0").c_str(), &branchData.z0);
0340       outputTree_->Branch(("recoVertices_" + *branchNameIt + "_sumPt").c_str(), &branchData.sumPt);
0341     }
0342 
0343     outputTree_->Branch("truePileUpVertices_z0", &truePileUpVtxZ0_);
0344     outputTree_->Branch("trueTracks_pt", &trueTracksBranchData_.pt);
0345     outputTree_->Branch("trueTracks_eta", &trueTracksBranchData_.eta);
0346     outputTree_->Branch("trueTracks_phi", &trueTracksBranchData_.phi);
0347     outputTree_->Branch("trueTracks_z0", &trueTracksBranchData_.z0);
0348     outputTree_->Branch("trueTracks_pdgId", &trueTracksBranchData_.pdgId);
0349     outputTree_->Branch("trueTracks_physCollision", &trueTracksBranchData_.physCollision);
0350     outputTree_->Branch("trueTracks_use", &trueTracksBranchData_.use);
0351     outputTree_->Branch("trueTracks_useForEff", &trueTracksBranchData_.useForEff);
0352     outputTree_->Branch("trueTracks_useForAlgEff", &trueTracksBranchData_.useForAlgEff);
0353     outputTree_->Branch("trueTracks_useForVtxReco", &trueTracksBranchData_.useForVertexReco);
0354 
0355     for (const auto& inputTag : extraVertexInputTags)
0356       l1VerticesExtraTokens_.push_back(consumes<std::vector<l1t::Vertex>>(inputTag));
0357     TObjArray* descriptionArray = new TObjArray();
0358     for (const auto& description : extraVertexDescriptions)
0359       descriptionArray->Add(new TObjString(description.c_str()));
0360     outputTree_->GetUserInfo()->Add(descriptionArray);
0361     outputTree_->Branch("vertices_extra_numTracks", &l1Vertices_extra_numTracks_);
0362     outputTree_->Branch("vertices_extra_z0", &l1Vertices_extra_z0_);
0363     outputTree_->Branch("vertices_extra_z0_etaWeighted", &l1Vertices_extra_z0_etaWeighted_);
0364     outputTree_->Branch("vertices_extra_sumPt", &l1Vertices_extra_sumPt_);
0365   }
0366 
0367   void VertexNTupler::beginJob() {}
0368 
0369   std::ostream& operator<<(std::ostream& out, const reco::GenParticle& particle) {
0370     const bool positive = (particle.pdgId() < 0);
0371     const size_t absId = abs(particle.pdgId());
0372     switch (absId) {
0373       case 1:
0374         return (out << (positive ? "d" : "anti-d"));
0375       case 2:
0376         return (out << (positive ? "u" : "anti-u"));
0377       case 3:
0378         return (out << (positive ? "s" : "anti-s"));
0379       case 4:
0380         return (out << (positive ? "c" : "anti-c"));
0381       case 5:
0382         return (out << (positive ? "b" : "anti-b"));
0383       case 6:
0384         return (out << (positive ? "t" : "anti-t"));
0385       case 11:
0386         return (out << (positive ? "e+" : "e-"));
0387       case 12:
0388         return (out << (positive ? "nu_e" : "anti-nu_e"));
0389       case 13:
0390         return (out << (positive ? "mu+" : "mu-"));
0391       case 14:
0392         return (out << (positive ? "nu_mu" : "anti-nu_mu"));
0393       case 15:
0394         return (out << (positive ? "tau+" : "tau-"));
0395       case 16:
0396         return (out << (positive ? "nu_tau" : "anti-nu_tau"));
0397       case 21:
0398         return (out << "g");
0399       case 22:
0400         return (out << "photon");
0401       case 23:
0402         return (out << "Z");
0403       case 24:
0404         return (out << (positive ? "W-" : "W+"));
0405       default:
0406         if ((((absId / 1000) % 10) != 0) and (((absId / 10) % 10) == 0))
0407           return (out << "diquark<" << particle.pdgId() << ">");
0408         else
0409           return (out << "unknown<" << particle.pdgId() << ">");
0410     }
0411   }
0412 
0413   void VertexNTupler::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) {
0414     // Note useful info about MC truth particles and about reconstructed stubs
0415     edm::Handle<l1tVertexFinder::InputData> inputDataHandle;
0416     iEvent.getByToken(inputDataToken_, inputDataHandle);
0417     InputData inputData = *inputDataHandle;
0418 
0419     edm::Handle<edm::ValueMap<TP>> tpValueMapHandle;
0420     iEvent.getByToken(vTPsToken_, tpValueMapHandle);
0421     edm::ValueMap<TP> tpValueMap = *tpValueMapHandle;
0422 
0423     // Create collections to hold the desired objects
0424     std::map<std::string, std::vector<L1TrackTruthMatched>> l1TrackCollections;
0425     std::map<std::string, edm::Handle<TTTrackAssMap>> truthAssocMapHandles;
0426 
0427     // Create iterators for the maps
0428     auto tokenMapEntry = l1TracksTokenMap_.begin(), tokenMapEntryEnd = l1TracksTokenMap_.end();
0429     auto mapTokenMapEntry = l1TracksMapTokenMap_.begin(), mapTokenMapEntryEnd = l1TracksMapTokenMap_.end();
0430 
0431     // Iterate over the maps
0432     for (; (tokenMapEntry != tokenMapEntryEnd) && (mapTokenMapEntry != mapTokenMapEntryEnd);
0433          ++tokenMapEntry, ++mapTokenMapEntry) {
0434       edm::Handle<TTTrackCollectionView> l1TracksHandle;
0435       edm::Handle<TTTrackAssMap>& mcTruthTTTrackHandle = truthAssocMapHandles[mapTokenMapEntry->first];
0436       iEvent.getByToken(tokenMapEntry->second, l1TracksHandle);
0437       iEvent.getByToken(l1TracksMapTokenMap_.at(mapTokenMapEntry->first), mcTruthTTTrackHandle);
0438 
0439       std::vector<L1TrackTruthMatched>& l1Tracks = l1TrackCollections[tokenMapEntry->first];
0440       l1Tracks.reserve(l1TracksHandle->size());
0441       for (const auto& track : l1TracksHandle->ptrs()) {
0442         l1Tracks.push_back(L1TrackTruthMatched(track, inputData.getTPPtrToRefMap(), tpValueMap, mcTruthTTTrackHandle));
0443       }
0444     }
0445 
0446     // create a map for associating fat reco tracks with their underlying
0447     // TTTrack pointers
0448     std::map<std::string, std::map<const edm::Ptr<TTTrack<Ref_Phase2TrackerDigi_>>, const L1TrackTruthMatched*>>
0449         edmL1TrackMaps;
0450 
0451     // get a list of reconstructed tracks with references to their TPs
0452     for (const auto& entry : l1TrackCollections) {
0453       auto& edmL1Map = edmL1TrackMaps[entry.first];
0454       for (const auto& track : entry.second) {
0455         edmL1Map.insert(std::pair<const edm::Ptr<TTTrack<Ref_Phase2TrackerDigi_>>, const L1TrackTruthMatched*>(
0456             track.getTTTrackPtr(), &track));
0457       }
0458     }
0459 
0460     ////////////////////////////////////////////////////////
0461 
0462     // Pile-up summary info
0463     edm::Handle<std::vector<PileupSummaryInfo>> pileupHandle;
0464     iEvent.getByToken(pileupSummaryToken_, pileupHandle);
0465 
0466     for (auto bxIt = pileupHandle->begin(); bxIt != pileupHandle->end(); bxIt++) {
0467       if (bxIt->getBunchCrossing() == 0) {
0468         numTrueInteractions_ = bxIt->getTrueNumInteractions();
0469         numPileupVertices_ = bxIt->getPU_NumInteractions();
0470       }
0471     }
0472 
0473     // True track info
0474     trueTracksBranchData_.clear();
0475     edm::Handle<std::vector<l1tVertexFinder::TP>> allMatchedTPsHandle;
0476     iEvent.getByToken(allMatchedTPsToken_, allMatchedTPsHandle);
0477 
0478     for (const auto& tp : *allMatchedTPsHandle) {
0479       trueTracksBranchData_.pt.push_back(tp->pt());
0480       trueTracksBranchData_.eta.push_back(tp->eta());
0481       trueTracksBranchData_.phi.push_back(tp->phi());
0482       trueTracksBranchData_.z0.push_back(tp->z0());
0483       trueTracksBranchData_.pdgId.push_back(tp->pdgId());
0484       trueTracksBranchData_.physCollision.push_back(tp.physicsCollision() ? 1.0 : 0.0);
0485       trueTracksBranchData_.use.push_back(tp.use() ? 1.0 : 0.0);
0486       trueTracksBranchData_.useForEff.push_back(tp.useForEff() ? 1.0 : 0.0);
0487       trueTracksBranchData_.useForAlgEff.push_back(tp.useForAlgEff() ? 1.0 : 0.0);
0488       trueTracksBranchData_.useForVertexReco.push_back(tp.useForVertexReco() ? 1.0 : 0.0);
0489     }
0490 
0491     // True pile-up vertex info
0492     truePileUpVtxZ0_.clear();
0493     for (const Vertex& vtx : inputData.getPileUpVertices())
0494       truePileUpVtxZ0_.push_back(vtx.z0());
0495 
0496     // Generator level vertex info
0497     hepMCVtxZ0_ = inputData.getHepMCVertex().vz();
0498     genVtxZ0_ = inputData.getGenVertex().vz();
0499 
0500     // Gen particles
0501     genParticlesHardOutgoingBranchData_.clear();
0502     edm::Handle<edm::View<reco::GenParticle>> genParticlesH;
0503     iEvent.getByToken(genParticlesToken_, genParticlesH);
0504     for (const auto& p : *genParticlesH) {
0505       genParticlesHardOutgoingBranchData_.energy.push_back(p.energy());
0506       genParticlesHardOutgoingBranchData_.pt.push_back(p.pt());
0507       genParticlesHardOutgoingBranchData_.eta.push_back(p.eta());
0508       genParticlesHardOutgoingBranchData_.phi.push_back(p.phi());
0509       genParticlesHardOutgoingBranchData_.pdgId.push_back(p.pdgId());
0510       genParticlesHardOutgoingBranchData_.status.push_back(p.status());
0511     }
0512 
0513     // Gen jet (AK4) branches
0514     genJetsBranchData_.clear();
0515     edm::Handle<std::vector<reco::GenJet>> genJetsHandle;
0516     iEvent.getByToken(genJetsToken_, genJetsHandle);
0517     for (const auto& genJet : *genJetsHandle) {
0518       genJetsBranchData_.energy.push_back(genJet.energy());
0519       genJetsBranchData_.pt.push_back(genJet.pt());
0520       genJetsBranchData_.eta.push_back(genJet.eta());
0521       genJetsBranchData_.phi.push_back(genJet.phi());
0522     }
0523 
0524     for (const auto& entry : l1TrackCollections) {
0525       const auto& l1Tracks = entry.second;
0526       RecoTracksBranchData& branchData = l1TracksBranchData_.at(entry.first);
0527 
0528       const TTTrackAssociationMap<Ref_Phase2TrackerDigi_>& truthAssocMap = *truthAssocMapHandles.at(entry.first);
0529 
0530       // Reco track branches
0531       branchData.clear();
0532       for (const L1TrackTruthMatched& track : l1Tracks) {
0533         branchData.pt.push_back(track.pt());
0534         branchData.eta.push_back(track.eta());
0535         branchData.phi.push_back(track.phi0());
0536         branchData.z0.push_back(track.z0());
0537         branchData.numStubs.push_back(track.getNumStubs());
0538         branchData.chi2dof.push_back(track.chi2dof());
0539         branchData.trueMatchIdx.push_back(track.getMatchedTPidx());
0540 
0541         edm::Ptr<TrackingParticle> matchedTP = truthAssocMap.findTrackingParticlePtr(track.getTTTrackPtr());
0542         if (matchedTP.isNull())
0543           branchData.truthMapMatchIdx.push_back(-1);
0544         else {
0545           auto it = std::find_if(allMatchedTPsHandle->begin(),
0546                                  allMatchedTPsHandle->end(),
0547                                  [&matchedTP](auto const& tp) { return tp.getTrackingParticle() == matchedTP; });
0548           assert(it != allMatchedTPsHandle->end());
0549           branchData.truthMapMatchIdx.push_back(std::distance(allMatchedTPsHandle->begin(), it));
0550         }
0551         branchData.truthMapIsGenuine.push_back(truthAssocMap.isGenuine(track.getTTTrackPtr()) ? 1.0 : 0.0);
0552         branchData.truthMapIsLooselyGenuine.push_back(truthAssocMap.isLooselyGenuine(track.getTTTrackPtr()) ? 1.0
0553                                                                                                             : 0.0);
0554         branchData.truthMapIsCombinatoric.push_back(truthAssocMap.isCombinatoric(track.getTTTrackPtr()) ? 1.0 : 0.0);
0555         branchData.truthMapIsUnknown.push_back(truthAssocMap.isUnknown(track.getTTTrackPtr()) ? 1.0 : 0.0);
0556       }
0557     }
0558 
0559     // Reco vertex branches
0560     for (const auto& tokenMapEntry : l1VerticesTokenMap_) {
0561       RecoVerticesBranchData& branchData = l1VerticesBranchData_.at(tokenMapEntry.first);
0562 
0563       edm::Handle<std::vector<l1t::Vertex>> handle;
0564       iEvent.getByToken(tokenMapEntry.second, handle);
0565       std::vector<std::shared_ptr<const RecoVertexWithTP>> recoVertices;
0566       recoVertices.reserve(handle->size());
0567       for (unsigned int i = 0; i < handle->size(); ++i) {
0568         recoVertices.push_back(std::shared_ptr<const RecoVertexWithTP>(
0569             new RecoVertexWithTP(handle->at(i), edmL1TrackMaps.at(l1VerticesInputMap_.at(tokenMapEntry.first)))));
0570       }
0571 
0572       branchData.clear();
0573       std::vector<L1TrackTruthMatched>& l1Tracks = l1TrackCollections.at(l1VerticesInputMap_.at(tokenMapEntry.first));
0574       for (const std::shared_ptr<const RecoVertexWithTP>& vtx : recoVertices) {
0575         branchData.numTracks.push_back(vtx->numTracks());
0576         branchData.trackIdxs.push_back(std::vector<unsigned>());
0577         for (const L1TrackTruthMatched* track : vtx->tracks())
0578           branchData.trackIdxs.back().push_back(track - l1Tracks.data());
0579         branchData.z0.push_back(vtx->z0());
0580         branchData.sumPt.push_back(vtx->pt());
0581       }
0582 
0583       if (printResults_) {
0584         edm::LogInfo("VertexNTupler") << "analyze::" << recoVertices.size() << " '" << tokenMapEntry.first
0585                                       << "' vertices were found ... ";
0586         for (const auto& vtx : recoVertices) {
0587           edm::LogInfo("VertexNTupler") << "analyze::"
0588                                         << "  * z0 = " << vtx->z0() << "; contains " << vtx->numTracks()
0589                                         << " tracks ...";
0590           for (const auto& trackPtr : vtx->tracks())
0591             edm::LogInfo("VertexNTupler") << "analyze::"
0592                                           << "     - z0 = " << trackPtr->z0() << "; pt = " << trackPtr->pt()
0593                                           << ", eta = " << trackPtr->eta() << ", phi = " << trackPtr->phi0();
0594         }
0595       }
0596     }
0597 
0598     // Emulation vertex branches
0599     for (const auto& tokenMapEntry : l1VerticesEmulationTokenMap_) {
0600       EmulationVerticesBranchData& branchData = l1VerticesEmulationBranchData_.at(tokenMapEntry.first);
0601       branchData.clear();
0602 
0603       edm::Handle<std::vector<l1t::VertexWord>> handle;
0604       iEvent.getByToken(tokenMapEntry.second, handle);
0605       for (const auto& vtx : *handle) {
0606         branchData.numTracks.push_back(vtx.multiplicity());
0607         branchData.z0.push_back(vtx.z0());
0608         branchData.sumPt.push_back(vtx.pt());
0609       }
0610 
0611       if (printResults_) {
0612         edm::LogInfo("VertexNTupler") << "analyze::" << handle->size() << " '" << tokenMapEntry.first
0613                                       << "' vertices were found ... ";
0614         for (const auto& vtx : *handle) {
0615           edm::LogInfo("VertexNTupler") << "analyze::"
0616                                         << "  * z0 = " << vtx.z0() << "; contains " << vtx.multiplicity()
0617                                         << " tracks ...";
0618         }
0619       }
0620     }
0621 
0622     // Extra vertex collections
0623     l1Vertices_extra_numTracks_.resize(l1VerticesExtraTokens_.size());
0624     l1Vertices_extra_z0_.resize(l1VerticesExtraTokens_.size());
0625     l1Vertices_extra_z0_etaWeighted_.resize(l1VerticesExtraTokens_.size());
0626     l1Vertices_extra_sumPt_.resize(l1VerticesExtraTokens_.size());
0627 
0628     for (size_t i = 0; i < l1VerticesExtraTokens_.size(); i++) {
0629       edm::Handle<std::vector<l1t::Vertex>> vertexHandle;
0630       iEvent.getByToken(l1VerticesExtraTokens_.at(i), vertexHandle);
0631 
0632       const std::vector<l1t::Vertex>& vertices = *vertexHandle;
0633 
0634       l1Vertices_extra_numTracks_.at(i).clear();
0635       l1Vertices_extra_z0_.at(i).clear();
0636       l1Vertices_extra_z0_etaWeighted_.at(i).clear();
0637       l1Vertices_extra_sumPt_.at(i).clear();
0638 
0639       for (const auto& vertex : vertices) {
0640         l1Vertices_extra_numTracks_.at(i).push_back(vertex.tracks().size());
0641         l1Vertices_extra_z0_.at(i).push_back(vertex.z0());
0642 
0643         float sumPt = 0.0;
0644         float etaWeightedSumZ0 = 0.0;
0645         float etaWeightSum = 0.0;
0646         for (const auto& track : vertex.tracks()) {
0647           sumPt += track->momentum().transverse();
0648           // const float zRes = 0.133616 * track->momentum().eta() * track->momentum().eta() - 0.0522353 * std::abs(track->momentum().eta()) + 0.109918;
0649           const float zRes = 0.223074 * track->momentum().eta() * track->momentum().eta() -
0650                              0.050231 * abs(track->momentum().eta()) + 0.209719;
0651           etaWeightedSumZ0 += track->POCA().z() / (zRes * zRes);
0652           etaWeightSum += 1.0 / (zRes * zRes);
0653         }
0654 
0655         l1Vertices_extra_sumPt_.at(i).push_back(sumPt);
0656         l1Vertices_extra_z0_etaWeighted_.at(i).push_back(etaWeightedSumZ0 / etaWeightSum);
0657       }
0658     }
0659 
0660     outputTree_->Fill();
0661     /////////////////////////////
0662 
0663     if (settings_.debug() > 2)
0664       edm::LogInfo("VertexNTupler") << "analyze::================ End of Event ==============";
0665   }
0666 
0667   void VertexNTupler::endJob() {}
0668 
0669   VertexNTupler::~VertexNTupler() {}
0670 
0671 }  // namespace l1tVertexFinder
0672 
0673 using namespace l1tVertexFinder;
0674 
0675 // define this as a plug-in
0676 DEFINE_FWK_MODULE(VertexNTupler);