/
githubmirror
/
cmssw
Обзор
Документация
Войти
/
githubmirror
/
cmssw
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
Validation/RecoTrack/plugins/TrackingNtuple.cc
4 818 строк
203 KB
cmsbuild
Merge pull request #50135 from slava77/CMSSW_16_1_0_pre1/mkf003-tknt
18 фев 2026, 12:30
Не верифицирован
18 фев 2026, 12:30
3ec113c
Код
Авторство
О чём код?
// -*- C++ -*- // // Package: NtupleDump/TrackingNtuple // Class: TrackingNtuple // /**\class TrackingNtuple TrackingNtuple.cc NtupleDump/TrackingNtuple/plugins/TrackingNtuple.cc Description: [one line class summary] Implementation: [Notes on implementation] */ // // Original Author: Giuseppe Cerati // Created: Tue, 25 Aug 2015 13:22:49 GMT // // // system include files #include <memory> // user include files #include "FWCore/Framework/interface/Frameworkfwd.h" #include "FWCore/Framework/interface/one/EDAnalyzer.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/MakerMacros.h" #include "FWCore/Framework/interface/ESHandle.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" #include "FWCore/Utilities/interface/isFinite.h" #include "FWCore/ServiceRegistry/interface/Service.h" #include "CommonTools/UtilAlgos/interface/TFileService.h" #include "CommonTools/Utils/interface/DynArray.h" #include "DataFormats/Provenance/interface/ProductID.h" #include "DataFormats/Common/interface/ContainerMask.h" #include "DataFormats/Math/interface/deltaR.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "FWCore/Utilities/interface/transform.h" #include "DataFormats/TrackReco/interface/Track.h" #include "DataFormats/TrackReco/interface/TrackFwd.h" #include "DataFormats/TrackReco/interface/SeedStopInfo.h" #include "TrackingTools/Records/interface/TransientRecHitRecord.h" #include "TrackingTools/TransientTrackingRecHit/interface/TransientTrackingRecHitBuilder.h" #include "RecoTracker/TransientTrackingRecHit/interface/TkTransientTrackingRecHitBuilder.h" #include "DataFormats/TrajectorySeed/interface/TrajectorySeed.h" #include "DataFormats/TrajectorySeed/interface/TrajectorySeedCollection.h" #include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h" #include "RecoTracker/PixelTrackFitting/interface/RZLine.h" #include "TrackingTools/PatternTools/interface/TSCBLBuilderNoMaterial.h" #include "TrackingTools/TrajectoryState/interface/PerigeeConversions.h" #include "MagneticField/Engine/interface/MagneticField.h" #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h" #include "DataFormats/Phase2TrackerCluster/interface/Phase2TrackerCluster1D.h" #include "DataFormats/SiPixelDetId/interface/PixelChannelIdentifier.h" #include "DataFormats/SiStripCluster/interface/SiStripClusterTools.h" #include "DataFormats/TrackerRecHit2D/interface/SiPixelRecHitCollection.h" #include "DataFormats/TrackerRecHit2D/interface/SiStripRecHit1D.h" #include "DataFormats/TrackerRecHit2D/interface/SiStripRecHit2DCollection.h" #include "DataFormats/TrackerRecHit2D/interface/SiStripMatchedRecHit2DCollection.h" #include "DataFormats/TrackerRecHit2D/interface/Phase2TrackerRecHit1D.h" #include "DataFormats/TrackerCommon/interface/TrackerTopology.h" #include "Geometry/Records/interface/TrackerTopologyRcd.h" #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h" #include "Geometry/Records/interface/TrackerDigiGeometryRecord.h" #include "DataFormats/VertexReco/interface/Vertex.h" #include "DataFormats/VertexReco/interface/VertexFwd.h" #include "SimDataFormats/Associations/interface/TrackToTrackingParticleAssociator.h" #include "SimGeneral/TrackingAnalysis/interface/SimHitTPAssociationProducer.h" #include "SimTracker/TrackerHitAssociation/interface/ClusterTPAssociation.h" #include "SimTracker/TrackAssociation/interface/ParametersDefinerForTP.h" #include "SimTracker/TrackAssociation/interface/TrackingParticleIP.h" #include "SimTracker/TrackAssociation/interface/trackAssociationChi2.h" #include "SimTracker/TrackAssociation/interface/trackHitsToClusterRefs.h" #include "SimDataFormats/TrackerDigiSimLink/interface/PixelDigiSimLink.h" #include "SimDataFormats/TrackerDigiSimLink/interface/StripDigiSimLink.h" #include "SimDataFormats/TrackingAnalysis/interface/TrackingVertex.h" #include "SimDataFormats/TrackingAnalysis/interface/TrackingVertexContainer.h" #include "SimTracker/TrackHistory/interface/HistoryBase.h" #include "HepPDT/ParticleID.hh" #include "DataFormats/TrackReco/interface/trackFromSeedFitFailed.h" #include "RecoTracker/FinalTrackSelectors/interface/getBestVertex.h" // GenJet headers #include "DataFormats/HepMCCandidate/interface/GenParticle.h" #include "DataFormats/HepMCCandidate/interface/GenParticleFwd.h" #include "DataFormats/JetReco/interface/GenJet.h" #include "DataFormats/JetReco/interface/GenJetCollection.h" #include <set> #include <map> #include <unordered_set> #include <unordered_map> #include <tuple> #include <utility> #include "TTree.h" /* todo: add refitted hit position after track/seed fit add local angle, path length! */ namespace { // This pattern is copied from QuickTrackAssociatorByHitsImpl. If // further needs arises, it wouldn't hurt to abstract it somehow. using TrackingParticleRefKeyToIndex = std::unordered_map<reco::RecoToSimCollection::index_type, size_t>; using TrackingVertexRefKeyToIndex = TrackingParticleRefKeyToIndex; using SimHitFullKey = std::pair<TrackPSimHitRef::key_type, edm::ProductID>; using SimHitRefKeyToIndex = std::map<SimHitFullKey, size_t>; using TrackingParticleRefKeyToCount = TrackingParticleRefKeyToIndex; std::string subdetstring(int subdet) { switch (subdet) { case StripSubdetector::TIB: return "- TIB"; case StripSubdetector::TOB: return "- TOB"; case StripSubdetector::TEC: return "- TEC"; case StripSubdetector::TID: return "- TID"; case PixelSubdetector::PixelBarrel: return "- PixBar"; case PixelSubdetector::PixelEndcap: return "- PixFwd"; default: return "UNKNOWN TRACKER HIT TYPE"; } } struct ProductIDSetPrinter { ProductIDSetPrinter(const std::set<edm::ProductID>& set) : set_(set) {} void print(std::ostream& os) const { for (const auto& item : set_) { os << item << " "; } } const std::set<edm::ProductID>& set_; }; std::ostream& operator<<(std::ostream& os, const ProductIDSetPrinter& o) { o.print(os); return os; } template <typename T> struct ProductIDMapPrinter { ProductIDMapPrinter(const std::map<edm::ProductID, T>& map) : map_(map) {} void print(std::ostream& os) const { for (const auto& item : map_) { os << item.first << " "; } } const std::map<edm::ProductID, T>& map_; }; template <typename T> auto make_ProductIDMapPrinter(const std::map<edm::ProductID, T>& map) { return ProductIDMapPrinter<T>(map); } template <typename T> std::ostream& operator<<(std::ostream& os, const ProductIDMapPrinter<T>& o) { o.print(os); return os; } template <typename T> struct VectorPrinter { VectorPrinter(const std::vector<T>& vec) : vec_(vec) {} void print(std::ostream& os) const { for (const auto& item : vec_) { os << item << " "; } } const std::vector<T>& vec_; }; template <typename T> auto make_VectorPrinter(const std::vector<T>& vec) { return VectorPrinter<T>(vec); } template <typename T> std::ostream& operator<<(std::ostream& os, const VectorPrinter<T>& o) { o.print(os); return os; } void checkProductID(const std::set<edm::ProductID>& set, const edm::ProductID& id, const char* name) { if (set.find(id) == set.end()) throw cms::Exception("Configuration") << "Got " << name << " with a hit with ProductID " << id << " which does not match to the set of ProductID's for the hits: " << ProductIDSetPrinter(set) << ". Usually this is caused by a wrong hit collection in the configuration."; } template <typename SimLink, typename Func> void forEachMatchedSimLink(const edm::DetSet<SimLink>& digiSimLinks, uint32_t channel, Func func) { for (const auto& link : digiSimLinks) { if (link.channel() == channel) { func(link); } } } /// No-op function used in the trick of CombineDetId::impl2() template <typename... Args> void call_nop(Args&&... args) {} template <typename... Types> class CombineDetId { public: CombineDetId() {} /// Return the raw DetId, assumes that the first type is /// DetIdCommon that has operator[]() unsigned int operator[](size_t i) const { return std::get<0>(content_)[i]; } template <typename... Args> void book(Args&&... args) { impl([&](auto& vec) { vec.book(std::forward<Args>(args)...); }); } template <typename... Args> void push_back(Args&&... args) { impl([&](auto& vec) { vec.push_back(std::forward<Args>(args)...); }); } template <typename... Args> void resize(Args&&... args) { impl([&](auto& vec) { vec.resize(std::forward<Args>(args)...); }); } template <typename... Args> void set(Args&&... args) { impl([&](auto& vec) { vec.set(std::forward<Args>(args)...); }); } void clear() { impl([&](auto& vec) { vec.clear(); }); } private: // Trick to not repeate std::index_sequence_for in each of the methods above template <typename F> void impl(F&& func) { impl2(std::index_sequence_for<Types...>{}, std::forward<F>(func)); } // Trick to exploit parameter pack expansion in function call // arguments to call a member function for each tuple element // (with the same signature). The comma operator is needed to // return a value from the expression as an argument for the // call_nop. template <std::size_t... Is, typename F> void impl2(std::index_sequence<Is...>, F&& func) { call_nop((func(std::get<Is>(content_)), 0)...); } std::tuple<Types...> content_; }; std::map<unsigned int, double> chargeFraction(const SiPixelCluster& cluster, const DetId& detId, const edm::DetSetVector<PixelDigiSimLink>& digiSimLink) { std::map<unsigned int, double> simTrackIdToAdc; auto idetset = digiSimLink.find(detId); if (idetset == digiSimLink.end()) return simTrackIdToAdc; double adcSum = 0; PixelDigiSimLink found; for (int iPix = 0; iPix != cluster.size(); ++iPix) { const SiPixelCluster::Pixel& pixel = cluster.pixel(iPix); adcSum += pixel.adc; uint32_t channel = PixelChannelIdentifier::pixelToChannel(pixel.x, pixel.y); forEachMatchedSimLink(*idetset, channel, [&](const PixelDigiSimLink& simLink) { double& adc = simTrackIdToAdc[simLink.SimTrackId()]; adc += pixel.adc * simLink.fraction(); }); } for (auto& pair : simTrackIdToAdc) { if (adcSum == 0.) pair.second = 0.; else pair.second /= adcSum; } return simTrackIdToAdc; } std::map<unsigned int, double> chargeFraction(const SiStripCluster& cluster, const DetId& detId, const edm::DetSetVector<StripDigiSimLink>& digiSimLink) { std::map<unsigned int, double> simTrackIdToAdc; auto idetset = digiSimLink.find(detId); if (idetset == digiSimLink.end()) return simTrackIdToAdc; double adcSum = 0; StripDigiSimLink found; int first = cluster.firstStrip(); for (size_t i = 0; i < cluster.amplitudes().size(); ++i) { adcSum += cluster.amplitudes()[i]; forEachMatchedSimLink(*idetset, first + i, [&](const StripDigiSimLink& simLink) { double& adc = simTrackIdToAdc[simLink.SimTrackId()]; adc += cluster.amplitudes()[i] * simLink.fraction(); }); for (const auto& pair : simTrackIdToAdc) { simTrackIdToAdc[pair.first] = (adcSum != 0. ? pair.second / adcSum : 0.); } } return simTrackIdToAdc; } std::map<unsigned int, double> chargeFraction(const Phase2TrackerCluster1D& cluster, const DetId& detId, const edm::DetSetVector<StripDigiSimLink>& digiSimLink) { std::map<unsigned int, double> simTrackIdToAdc; throw cms::Exception("LogicError") << "Not possible to use StripDigiSimLink with Phase2TrackerCluster1D! "; return simTrackIdToAdc; } //In the OT, there is no measurement of the charge, so no ADC value. //Only in the SSA chip (so in PSs) you have one "threshold" flag that tells you if the charge of at least one strip in the cluster exceeded 1.2 MIPs. std::map<unsigned int, double> chargeFraction(const Phase2TrackerCluster1D& cluster, const DetId& detId, const edm::DetSetVector<PixelDigiSimLink>& digiSimLink) { std::map<unsigned int, double> simTrackIdToAdc; return simTrackIdToAdc; } struct TrackTPMatch { int key = -1; int countClusters = 0; }; template <typename HRange> TrackTPMatch findBestMatchingTrackingParticle(const HRange& hits, const ClusterTPAssociation& clusterToTPMap, const TrackingParticleRefKeyToIndex& tpKeyToIndex) { struct Count { int clusters = 0; size_t innermostHit = std::numeric_limits<size_t>::max(); }; std::vector<OmniClusterRef> clusters = track_associator::hitsToClusterRefs(hits.begin(), hits.end()); std::unordered_map<int, Count> count; for (size_t iCluster = 0, end = clusters.size(); iCluster < end; ++iCluster) { const auto& clusterRef = clusters[iCluster]; auto range = clusterToTPMap.equal_range(clusterRef); for (auto ip = range.first; ip != range.second; ++ip) { const auto tpKey = ip->second.key(); if (tpKeyToIndex.find(tpKey) == tpKeyToIndex.end()) // filter out TPs not given as an input continue; auto& elem = count[tpKey]; ++elem.clusters; elem.innermostHit = std::min(elem.innermostHit, iCluster); } } // In case there are many matches with the same number of clusters, // select the one with innermost hit TrackTPMatch best; int bestCount = 2; // require >= 3 cluster for the best match size_t bestInnermostHit = std::numeric_limits<size_t>::max(); for (auto& keyCount : count) { if (keyCount.second.clusters > bestCount || (keyCount.second.clusters == bestCount && keyCount.second.innermostHit < bestInnermostHit)) { best.key = keyCount.first; best.countClusters = bestCount = keyCount.second.clusters; bestInnermostHit = keyCount.second.innermostHit; } } LogTrace("TrackingNtuple") << "findBestMatchingTrackingParticle key " << best.key; return best; } template <typename HRange> TrackTPMatch findMatchingTrackingParticleFromFirstHit(const HRange& hits, const ClusterTPAssociation& clusterToTPMap, const TrackingParticleRefKeyToIndex& tpKeyToIndex) { TrackTPMatch best; std::vector<OmniClusterRef> clusters = track_associator::hitsToClusterRefs(hits.begin(), hits.end()); if (clusters.empty()) { return best; } auto operateCluster = [&](const auto& clusterRef, const auto& func) { auto range = clusterToTPMap.equal_range(clusterRef); for (auto ip = range.first; ip != range.second; ++ip) { const auto tpKey = ip->second.key(); if (tpKeyToIndex.find(tpKey) == tpKeyToIndex.end()) // filter out TPs not given as an input continue; func(tpKey); } }; std::vector<unsigned int> validTPs; // first cluster can be associated to multiple TPs, use vector as set as this should be small auto iCluster = clusters.begin(); operateCluster(*iCluster, [&](unsigned int tpKey) { validTPs.push_back(tpKey); }); if (validTPs.empty()) { return best; } ++iCluster; ++best.countClusters; std::vector<bool> foundTPs(validTPs.size(), false); for (auto iEnd = clusters.end(); iCluster != iEnd; ++iCluster) { const auto& clusterRef = *iCluster; // find out to which first-cluster TPs this cluster is matched to operateCluster(clusterRef, [&](unsigned int tpKey) { auto found = std::find(cbegin(validTPs), cend(validTPs), tpKey); if (found != cend(validTPs)) { foundTPs[std::distance(cbegin(validTPs), found)] = true; } }); // remove the non-found TPs auto iTP = validTPs.size(); do { --iTP; if (!foundTPs[iTP]) { validTPs.erase(validTPs.begin() + iTP); foundTPs.erase(foundTPs.begin() + iTP); } } while (iTP > 0); if (!validTPs.empty()) { // for multiple TPs the "first one" is a bit arbitrary, but // I hope it is rare that a track would have many // consecutive hits matched to two TPs best.key = validTPs[0]; } else { break; } std::fill(begin(foundTPs), end(foundTPs), false); ++best.countClusters; } // Reqquire >= 3 clusters for a match return best.countClusters >= 3 ? best : TrackTPMatch(); } } // namespace // // class declaration // class TrackingNtuple : public edm::one::EDAnalyzer<edm::one::SharedResources> { public: explicit TrackingNtuple(const edm::ParameterSet&); ~TrackingNtuple() override; static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); private: void analyze(const edm::Event&, const edm::EventSetup&) override; void clearVariables(); enum class HitType { Pixel = 0, Strip = 1, Glued = 2, Invalid = 3, Phase2OT = 4, Unknown = 99 }; // This gives the "best" classification of a reco hit // In case of reco hit mathing to multiple sim, smaller number is // considered better // To be kept in synch with class HitSimType in ntuple.py enum class HitSimType { Signal = 0, ITPileup = 1, OOTPileup = 2, Noise = 3, Unknown = 99 }; using MVACollection = std::vector<float>; using QualityMaskCollection = std::vector<unsigned char>; using PixelMaskContainer = edm::ContainerMask<edmNew::DetSetVector<SiPixelCluster>>; using StripMaskContainer = edm::ContainerMask<edmNew::DetSetVector<SiStripCluster>>; using Phase2OTMaskContainer = edm::ContainerMask<edmNew::DetSetVector<Phase2TrackerCluster1D>>; struct TPHitIndex { TPHitIndex(unsigned int tp = 0, unsigned int simHit = 0, float to = 0, unsigned int id = 0) : tpKey(tp), simHitIdx(simHit), tof(to), detId(id) {} unsigned int tpKey; unsigned int simHitIdx; float tof; unsigned int detId; }; static bool tpHitIndexListLess(const TPHitIndex& i, const TPHitIndex& j) { return (i.tpKey < j.tpKey); } static bool tpHitIndexListLessSort(const TPHitIndex& i, const TPHitIndex& j) { if (i.tpKey == j.tpKey) { if (edm::isNotFinite(i.tof) && edm::isNotFinite(j.tof)) { return i.detId < j.detId; } return i.tof < j.tof; // works as intended if either one is NaN } return i.tpKey < j.tpKey; } void fillBeamSpot(const reco::BeamSpot& bs); void fillPixelHits(const edm::Event& iEvent, const TrackerGeometry& tracker, const ClusterTPAssociation& clusterToTPMap, const TrackingParticleRefKeyToIndex& tpKeyToIndex, const SimHitTPAssociationProducer::SimHitTPAssociationList& simHitsTPAssoc, const edm::DetSetVector<PixelDigiSimLink>& digiSimLink, const TrackerTopology& tTopo, const SimHitRefKeyToIndex& simHitRefKeyToIndex, std::set<edm::ProductID>& hitProductIds); void fillStripRphiStereoHits(const edm::Event& iEvent, const TrackerGeometry& tracker, const ClusterTPAssociation& clusterToTPMap, const TrackingParticleRefKeyToIndex& tpKeyToIndex, const SimHitTPAssociationProducer::SimHitTPAssociationList& simHitsTPAssoc, const edm::DetSetVector<StripDigiSimLink>& digiSimLink, const TrackerTopology& tTopo, const SimHitRefKeyToIndex& simHitRefKeyToIndex, std::set<edm::ProductID>& hitProductIds); void fillStripMatchedHits(const edm::Event& iEvent, const TrackerGeometry& tracker, const TrackerTopology& tTopo, std::vector<std::pair<int, int>>& monoStereoClusterList); size_t addStripMatchedHit(const SiStripMatchedRecHit2D& hit, const TrackerGeometry& tracker, const TrackerTopology& tTopo, const std::vector<std::pair<uint64_t, StripMaskContainer const*>>& stripMasks, std::vector<std::pair<int, int>>& monoStereoClusterList); void fillPhase2OTHits(const edm::Event& iEvent, const ClusterTPAssociation& clusterToTPMap, const TrackerGeometry& tracker, const TrackingParticleRefKeyToIndex& tpKeyToIndex, const SimHitTPAssociationProducer::SimHitTPAssociationList& simHitsTPAssoc, const edm::DetSetVector<PixelDigiSimLink>& digiSimLink, const TrackerTopology& tTopo, const SimHitRefKeyToIndex& simHitRefKeyToIndex, std::set<edm::ProductID>& hitProductIds); void fillSeeds(const edm::Event& iEvent, const TrackingParticleRefVector& tpCollection, const TrackingParticleRefKeyToIndex& tpKeyToIndex, const reco::BeamSpot& bs, const TrackerGeometry& tracker, const reco::TrackToTrackingParticleAssociator& associatorByHits, const ClusterTPAssociation& clusterToTPMap, const MagneticField& theMF, const TrackerTopology& tTopo, std::vector<std::pair<int, int>>& monoStereoClusterList, const std::set<edm::ProductID>& hitProductIds, std::map<edm::ProductID, size_t>& seedToCollIndex); void fillTracks(const edm::RefToBaseVector<reco::Track>& tracks, const TrackerGeometry& tracker, const TrackingParticleRefVector& tpCollection, const TrackingParticleRefKeyToIndex& tpKeyToIndex, const TrackingParticleRefKeyToCount& tpKeyToClusterCount, const MagneticField& mf, const reco::BeamSpot& bs, const reco::VertexCollection& vertices, const reco::TrackToTrackingParticleAssociator& associatorByHits, const ClusterTPAssociation& clusterToTPMap, const TrackerTopology& tTopo, const std::set<edm::ProductID>& hitProductIds, const std::map<edm::ProductID, size_t>& seedToCollIndex, const std::vector<const MVACollection*>& mvaColls, const std::vector<const QualityMaskCollection*>& qualColls); void fillCandidates(const edm::Handle<TrackCandidateCollection>& candsHandle, int algo, const TrackingParticleRefVector& tpCollection, const TrackingParticleRefKeyToIndex& tpKeyToIndex, const TrackingParticleRefKeyToCount& tpKeyToClusterCount, const MagneticField& mf, const reco::BeamSpot& bs, const reco::VertexCollection& vertices, const reco::TrackToTrackingParticleAssociator& associatorByHits, const ClusterTPAssociation& clusterToTPMap, const TrackerGeometry& tracker, const TrackerTopology& tTopo, const std::set<edm::ProductID>& hitProductIds, const std::map<edm::ProductID, size_t>& seedToCollIndex); void fillSimHits(const TrackerGeometry& tracker, const TrackingParticleRefKeyToIndex& tpKeyToIndex, const SimHitTPAssociationProducer::SimHitTPAssociationList& simHitsTPAssoc, const TrackerTopology& tTopo, SimHitRefKeyToIndex& simHitRefKeyToIndex, std::vector<TPHitIndex>& tpHitList); void fillTrackingParticles(const edm::Event& iEvent, const edm::EventSetup& iSetup, const edm::RefToBaseVector<reco::Track>& tracks, const reco::BeamSpot& bs, const TrackingParticleRefVector& tpCollection, const TrackingVertexRefKeyToIndex& tvKeyToIndex, const reco::TrackToTrackingParticleAssociator& associatorByHits, const std::vector<TPHitIndex>& tpHitList, const TrackingParticleRefKeyToCount& tpKeyToClusterCount); void fillTrackingParticlesForSeeds(const TrackingParticleRefVector& tpCollection, const reco::SimToRecoCollection& simRecColl, const TrackingParticleRefKeyToIndex& tpKeyToIndex, const unsigned int seedOffset); void fillVertices(const reco::VertexCollection& vertices, const edm::RefToBaseVector<reco::Track>& tracks); void fillTrackingVertices(const TrackingVertexRefVector& trackingVertices, const TrackingParticleRefKeyToIndex& tpKeyToIndex); void fillGenJets(const edm::Event& iEvent, const TrackingParticleRefVector& tpCollection); struct SimHitData { std::vector<int> matchingSimHit; std::vector<float> chargeFraction; std::vector<float> xySignificance; std::vector<int> bunchCrossing; std::vector<int> event; HitSimType type = HitSimType::Unknown; }; template <typename SimLink> SimHitData matchCluster(const OmniClusterRef& cluster, DetId hitId, int clusterKey, const TrackingRecHit& hit, const ClusterTPAssociation& clusterToTPMap, const TrackingParticleRefKeyToIndex& tpKeyToIndex, const SimHitTPAssociationProducer::SimHitTPAssociationList& simHitsTPAssoc, const edm::DetSetVector<SimLink>& digiSimLinks, const SimHitRefKeyToIndex& simHitRefKeyToIndex, HitType hitType); // ----------member data --------------------------- const edm::ESGetToken<MagneticField, IdealMagneticFieldRecord> mfToken_; const edm::ESGetToken<TrackerTopology, TrackerTopologyRcd> tTopoToken_; const edm::ESGetToken<TrackerGeometry, TrackerDigiGeometryRecord> tGeomToken_; std::vector<edm::EDGetTokenT<edm::View<reco::Track>>> seedTokens_; std::vector<edm::EDGetTokenT<std::vector<SeedStopInfo>>> seedStopInfoTokens_; std::vector<edm::EDGetTokenT<TrackCandidateCollection>> candidateTokens_; edm::EDGetTokenT<edm::View<reco::Track>> trackToken_; std::vector<std::tuple<edm::EDGetTokenT<MVACollection>, edm::EDGetTokenT<QualityMaskCollection>>> mvaQualityCollectionTokens_; edm::EDGetTokenT<TrackingParticleCollection> trackingParticleToken_; edm::EDGetTokenT<TrackingParticleRefVector> trackingParticleRefToken_; edm::EDGetTokenT<ClusterTPAssociation> clusterTPMapToken_; edm::EDGetTokenT<SimHitTPAssociationProducer::SimHitTPAssociationList> simHitTPMapToken_; edm::EDGetTokenT<reco::TrackToTrackingParticleAssociator> trackAssociatorToken_; edm::EDGetTokenT<edm::DetSetVector<PixelDigiSimLink>> pixelSimLinkToken_; edm::EDGetTokenT<edm::DetSetVector<StripDigiSimLink>> stripSimLinkToken_; edm::EDGetTokenT<edm::DetSetVector<PixelDigiSimLink>> siphase2OTSimLinksToken_; bool includeStripHits_, includePhase2OTHits_; edm::EDGetTokenT<reco::BeamSpot> beamSpotToken_; edm::EDGetTokenT<SiPixelRecHitCollection> pixelRecHitToken_; edm::EDGetTokenT<SiStripRecHit2DCollection> stripRphiRecHitToken_; edm::EDGetTokenT<SiStripRecHit2DCollection> stripStereoRecHitToken_; edm::EDGetTokenT<SiStripMatchedRecHit2DCollection> stripMatchedRecHitToken_; edm::EDGetTokenT<Phase2TrackerRecHit1DCollectionNew> phase2OTRecHitToken_; edm::EDGetTokenT<reco::VertexCollection> vertexToken_; edm::EDGetTokenT<TrackingVertexCollection> trackingVertexToken_; edm::EDGetTokenT<edm::ValueMap<unsigned int>> tpNLayersToken_; edm::EDGetTokenT<edm::ValueMap<unsigned int>> tpNPixelLayersToken_; edm::EDGetTokenT<edm::ValueMap<unsigned int>> tpNStripStereoLayersToken_; std::vector<std::pair<unsigned int, edm::EDGetTokenT<PixelMaskContainer>>> pixelUseMaskTokens_; std::vector<std::pair<unsigned int, edm::EDGetTokenT<StripMaskContainer>>> stripUseMaskTokens_; std::vector<std::pair<unsigned int, edm::EDGetTokenT<Phase2OTMaskContainer>>> ph2OTUseMaskTokens_; std::string builderName_; const bool includeSeeds_; const bool seedUniqueCheck_; const bool seedAlgoDetect_; std::vector<unsigned int> seedAlgos_; const bool includeTrackCandidates_; const bool addSeedCurvCov_; const bool includeAllHits_; const bool includeOnTrackHitData_; const bool includeMVA_; const bool includeTrackingParticles_; const bool includeOOT_; const bool keepEleSimHits_; const bool saveSimHitsP3_; const bool simHitBySignificance_; HistoryBase tracer_; ParametersDefinerForTP parametersDefiner_; const edm::EDGetTokenT<reco::GenJetCollection> tok_jets_; TTree* t; // DetId branches #define BOOK(name) tree->Branch((prefix + "_" + #name).c_str(), &name); class DetIdCommon { public: DetIdCommon() {} unsigned int operator[](size_t i) const { return detId[i]; } void book(const std::string& prefix, TTree* tree) { BOOK(detId); BOOK(subdet); BOOK(layer); BOOK(side); BOOK(module); BOOK(moduleType); } void push_back(const TrackerGeometry& tracker, const TrackerTopology& tTopo, const DetId& id) { detId.push_back(id.rawId()); subdet.push_back(id.subdetId()); layer.push_back(tTopo.layer(id)); module.push_back(tTopo.module(id)); moduleType.push_back(static_cast<int>(tracker.getDetectorType(id))); unsigned short s = 0; switch (id.subdetId()) { case StripSubdetector::TIB: s = tTopo.tibSide(id); break; case StripSubdetector::TOB: s = tTopo.tobSide(id); break; default: s = tTopo.side(id); } side.push_back(s); } void resize(size_t size) { detId.resize(size); subdet.resize(size); layer.resize(size); side.resize(size); module.resize(size); moduleType.resize(size); } void set(size_t index, const TrackerGeometry& tracker, const TrackerTopology& tTopo, const DetId& id) { detId[index] = id.rawId(); subdet[index] = id.subdetId(); layer[index] = tTopo.layer(id); side[index] = tTopo.side(id); module[index] = tTopo.module(id); moduleType[index] = static_cast<int>(tracker.getDetectorType(id)); } void clear() { detId.clear(); subdet.clear(); layer.clear(); side.clear(); module.clear(); moduleType.clear(); } private: std::vector<unsigned int> detId; std::vector<unsigned short> subdet; std::vector<unsigned short> layer; // or disk/wheel std::vector<unsigned short> side; std::vector<unsigned short> module; std::vector<unsigned int> moduleType; }; class DetIdPixelOnly { public: DetIdPixelOnly() {} void book(const std::string& prefix, TTree* tree) { BOOK(ladder); BOOK(blade); BOOK(panel); } void push_back(const TrackerGeometry& tracker, const TrackerTopology& tTopo, const DetId& id) { const bool isBarrel = id.subdetId() == PixelSubdetector::PixelBarrel; ladder.push_back(isBarrel ? tTopo.pxbLadder(id) : 0); blade.push_back(isBarrel ? 0 : tTopo.pxfBlade(id)); panel.push_back(isBarrel ? 0 : tTopo.pxfPanel(id)); } void clear() { ladder.clear(); blade.clear(); panel.clear(); } private: std::vector<unsigned short> ladder; std::vector<unsigned short> blade; std::vector<unsigned short> panel; }; class DetIdOTCommon { public: DetIdOTCommon() {} void book(const std::string& prefix, TTree* tree) { BOOK(order); BOOK(ring); BOOK(rod); } void push_back(const TrackerGeometry& tracker, const TrackerTopology& tTopo, const DetId& id) { const auto parsed = parse(tTopo, id); order.push_back(parsed.order); ring.push_back(parsed.ring); rod.push_back(parsed.rod); } void resize(size_t size) { order.resize(size); ring.resize(size); rod.resize(size); } void set(size_t index, const TrackerGeometry& tracker, const TrackerTopology& tTopo, const DetId& id) { const auto parsed = parse(tTopo, id); order[index] = parsed.order; ring[index] = parsed.ring; rod[index] = parsed.rod; } void clear() { order.clear(); ring.clear(); rod.clear(); } private: struct Parsed { // use int here instead of short to avoid compilation errors due // to narrowing conversion (less boilerplate than explicit static_casts) unsigned int order = 0; unsigned int ring = 0; unsigned int rod = 0; }; Parsed parse(const TrackerTopology& tTopo, const DetId& id) const { switch (id.subdetId()) { case StripSubdetector::TIB: return Parsed{tTopo.tibOrder(id), 0, 0}; case StripSubdetector::TID: return Parsed{tTopo.tidOrder(id), tTopo.tidRing(id), 0}; case StripSubdetector::TOB: return Parsed{0, 0, tTopo.tobRod(id)}; case StripSubdetector::TEC: return Parsed{tTopo.tecOrder(id), tTopo.tecRing(id), 0}; default: return Parsed{}; }; } std::vector<unsigned short> order; std::vector<unsigned short> ring; std::vector<unsigned short> rod; }; class DetIdStripOnly { public: DetIdStripOnly() {} void book(const std::string& prefix, TTree* tree) { BOOK(string); BOOK(petalNumber); BOOK(isStereo); BOOK(isRPhi); BOOK(isGlued); } void push_back(const TrackerGeometry& tracker, const TrackerTopology& tTopo, const DetId& id) { const auto parsed = parse(tTopo, id); string.push_back(parsed.string); petalNumber.push_back(parsed.petalNumber); isStereo.push_back(tTopo.isStereo(id)); isRPhi.push_back(tTopo.isRPhi(id)); isGlued.push_back(parsed.glued); } void resize(size_t size) { string.resize(size); petalNumber.resize(size); isStereo.resize(size); isRPhi.resize(size); isGlued.resize(size); } void set(size_t index, const TrackerGeometry& tracker, const TrackerTopology& tTopo, const DetId& id) { const auto parsed = parse(tTopo, id); string[index] = parsed.string; petalNumber[index] = parsed.petalNumber; isStereo[index] = tTopo.isStereo(id); isRPhi[index] = tTopo.isRPhi(id); isGlued[index] = parsed.glued; } void clear() { string.clear(); isStereo.clear(); isRPhi.clear(); isGlued.clear(); petalNumber.clear(); } private: struct Parsed { // use int here instead of short to avoid compilation errors due // to narrowing conversion (less boilerplate than explicit static_casts) unsigned int string = 0; unsigned int petalNumber = 0; bool glued = false; }; Parsed parse(const TrackerTopology& tTopo, const DetId& id) const { switch (id.subdetId()) { case StripSubdetector::TIB: return Parsed{tTopo.tibString(id), 0, tTopo.tibIsDoubleSide(id)}; case StripSubdetector::TID: return Parsed{0, 0, tTopo.tidIsDoubleSide(id)}; case StripSubdetector::TOB: return Parsed{0, 0, tTopo.tobIsDoubleSide(id)}; case StripSubdetector::TEC: return Parsed{0, tTopo.tecPetalNumber(id), tTopo.tecIsDoubleSide(id)}; default: return Parsed{}; } } std::vector<unsigned short> string; std::vector<unsigned short> petalNumber; std::vector<unsigned short> isStereo; std::vector<unsigned short> isRPhi; std::vector<unsigned short> isGlued; }; class DetIdPhase2OTOnly { public: DetIdPhase2OTOnly() {} void book(const std::string& prefix, TTree* tree) { BOOK(isLower); BOOK(isUpper); BOOK(isStack); } void push_back(const TrackerGeometry& tracker, const TrackerTopology& tTopo, const DetId& id) { isLower.push_back(tTopo.isLower(id)); isUpper.push_back(tTopo.isUpper(id)); isStack.push_back(tTopo.stack(id) == 0); // equivalent to *IsDoubleSide() but without the hardcoded layer+ring requirements } void clear() { isLower.clear(); isUpper.clear(); isStack.clear(); } private: std::vector<unsigned short> isLower; std::vector<unsigned short> isUpper; std::vector<unsigned short> isStack; }; #undef BOOK using DetIdPixel = CombineDetId<DetIdCommon, DetIdPixelOnly>; using DetIdStrip = CombineDetId<DetIdCommon, DetIdOTCommon, DetIdStripOnly>; using DetIdPhase2OT = CombineDetId<DetIdCommon, DetIdOTCommon, DetIdPhase2OTOnly>; using DetIdAll = CombineDetId<DetIdCommon, DetIdPixelOnly, DetIdOTCommon, DetIdStripOnly>; using DetIdAllPhase2 = CombineDetId<DetIdCommon, DetIdPixelOnly, DetIdOTCommon, DetIdPhase2OTOnly>; // event edm::RunNumber_t ev_run; edm::LuminosityBlockNumber_t ev_lumi; edm::EventNumber_t ev_event; //////////////////// // tracks // (first) index runs through tracks std::vector<float> trk_px; std::vector<float> trk_py; std::vector<float> trk_pz; std::vector<float> trk_pt; std::vector<float> trk_inner_px; std::vector<float> trk_inner_py; std::vector<float> trk_inner_pz; std::vector<float> trk_inner_pt; std::vector<float> trk_outer_px; std::vector<float> trk_outer_py; std::vector<float> trk_outer_pz; std::vector<float> trk_outer_pt; std::vector<float> trk_eta; std::vector<float> trk_lambda; std::vector<float> trk_cotTheta; std::vector<float> trk_phi; std::vector<float> trk_dxy; std::vector<float> trk_dz; std::vector<float> trk_dxyPV; std::vector<float> trk_dzPV; std::vector<float> trk_dxyClosestPV; std::vector<float> trk_dzClosestPV; std::vector<float> trk_ptErr; std::vector<float> trk_etaErr; std::vector<float> trk_lambdaErr; std::vector<float> trk_phiErr; std::vector<float> trk_dxyErr; std::vector<float> trk_dzErr; std::vector<float> trk_refpoint_x; std::vector<float> trk_refpoint_y; std::vector<float> trk_refpoint_z; std::vector<float> trk_nChi2; std::vector<float> trk_nChi2_1Dmod; std::vector<float> trk_ndof; std::vector<std::vector<float>> trk_mvas; std::vector<std::vector<unsigned short>> trk_qualityMasks; std::vector<int> trk_q; std::vector<unsigned int> trk_nValid; std::vector<unsigned int> trk_nLost; std::vector<unsigned int> trk_nInactive; std::vector<unsigned int> trk_nPixel; std::vector<unsigned int> trk_nStrip; std::vector<unsigned int> trk_nOuterLost; std::vector<unsigned int> trk_nInnerLost; std::vector<unsigned int> trk_nOuterInactive; std::vector<unsigned int> trk_nInnerInactive; std::vector<unsigned int> trk_nPixelLay; std::vector<unsigned int> trk_nStripLay; std::vector<unsigned int> trk_n3DLay; std::vector<unsigned int> trk_nLostLay; std::vector<unsigned int> trk_nCluster; std::vector<unsigned int> trk_algo; std::vector<unsigned int> trk_originalAlgo; std::vector<decltype(reco::TrackBase().algoMaskUL())> trk_algoMask; std::vector<unsigned short> trk_stopReason; std::vector<short> trk_isHP; std::vector<int> trk_seedIdx; std::vector<int> trk_vtxIdx; std::vector<short> trk_isTrue; std::vector<int> trk_bestSimTrkIdx; std::vector<float> trk_bestSimTrkShareFrac; std::vector<float> trk_bestSimTrkShareFracSimDenom; std::vector<float> trk_bestSimTrkShareFracSimClusterDenom; std::vector<float> trk_bestSimTrkNChi2; std::vector<int> trk_bestFromFirstHitSimTrkIdx; std::vector<float> trk_bestFromFirstHitSimTrkShareFrac; std::vector<float> trk_bestFromFirstHitSimTrkShareFracSimDenom; std::vector<float> trk_bestFromFirstHitSimTrkShareFracSimClusterDenom; std::vector<float> trk_bestFromFirstHitSimTrkNChi2; std::vector<std::vector<float>> trk_simTrkShareFrac; // second index runs through matched TrackingParticles std::vector<std::vector<float>> trk_simTrkNChi2; // second index runs through matched TrackingParticles std::vector<std::vector<int>> trk_simTrkIdx; // second index runs through matched TrackingParticles std::vector<std::vector<int>> trk_hitIdx; // second index runs through hits std::vector<std::vector<int>> trk_hitType; // second index runs through hits //////////////////// // track candidates // (first) index runs through track candidates std::vector<short> tcand_pca_valid; // pca: propagated params at BS std::vector<float> tcand_pca_px; std::vector<float> tcand_pca_py; std::vector<float> tcand_pca_pz; std::vector<float> tcand_pca_pt; std::vector<float> tcand_pca_eta; std::vector<float> tcand_pca_phi; std::vector<float> tcand_pca_dxy; std::vector<float> tcand_pca_dz; std::vector<float> tcand_pca_ptErr; std::vector<float> tcand_pca_etaErr; std::vector<float> tcand_pca_lambdaErr; std::vector<float> tcand_pca_phiErr; std::vector<float> tcand_pca_dxyErr; std::vector<float> tcand_pca_dzErr; std::vector<float> tcand_px; // from PState std::vector<float> tcand_py; std::vector<float> tcand_pz; std::vector<float> tcand_pt; std::vector<float> tcand_x; std::vector<float> tcand_y; std::vector<float> tcand_z; std::vector<float> tcand_qbpErr; std::vector<float> tcand_lambdaErr; std::vector<float> tcand_phiErr; std::vector<float> tcand_xtErr; std::vector<float> tcand_ytErr; std::vector<float> tcand_ndof; // sum(hit.dimention) - 5 std::vector<int> tcand_q; std::vector<unsigned int> tcand_nValid; std::vector<unsigned int> tcand_nPixel; std::vector<unsigned int> tcand_nStrip; std::vector<unsigned int> tcand_nCluster; std::vector<unsigned int> tcand_algo; std::vector<unsigned short> tcand_stopReason; std::vector<int> tcand_seedIdx; std::vector<int> tcand_vtxIdx; std::vector<short> tcand_isTrue; std::vector<int> tcand_bestSimTrkIdx; std::vector<float> tcand_bestSimTrkShareFrac; std::vector<float> tcand_bestSimTrkShareFracSimDenom; std::vector<float> tcand_bestSimTrkShareFracSimClusterDenom; std::vector<float> tcand_bestSimTrkNChi2; std::vector<int> tcand_bestFromFirstHitSimTrkIdx; std::vector<float> tcand_bestFromFirstHitSimTrkShareFrac; std::vector<float> tcand_bestFromFirstHitSimTrkShareFracSimDenom; std::vector<float> tcand_bestFromFirstHitSimTrkShareFracSimClusterDenom; std::vector<float> tcand_bestFromFirstHitSimTrkNChi2; std::vector<std::vector<float>> tcand_simTrkShareFrac; // second index runs through matched TrackingParticles std::vector<std::vector<float>> tcand_simTrkNChi2; // second index runs through matched TrackingParticles std::vector<std::vector<int>> tcand_simTrkIdx; // second index runs through matched TrackingParticles std::vector<std::vector<int>> tcand_hitIdx; // second index runs through hits std::vector<std::vector<int>> tcand_hitType; // second index runs through hits //////////////////// // sim tracks // (first) index runs through TrackingParticles std::vector<int> sim_event; std::vector<int> sim_bunchCrossing; std::vector<int> sim_pdgId; std::vector<std::vector<int>> sim_genPdgIds; std::vector<int> sim_isFromBHadron; std::vector<float> sim_px; std::vector<float> sim_py; std::vector<float> sim_pz; std::vector<float> sim_pt; std::vector<float> sim_eta; std::vector<float> sim_phi; std::vector<float> sim_pca_pt; std::vector<float> sim_pca_eta; std::vector<float> sim_pca_lambda; std::vector<float> sim_pca_cotTheta; std::vector<float> sim_pca_phi; std::vector<float> sim_pca_dxy; std::vector<float> sim_pca_dz; std::vector<int> sim_q; // numbers of sim hits/layers std::vector<unsigned int> sim_nValid; std::vector<unsigned int> sim_nPixel; std::vector<unsigned int> sim_nStrip; std::vector<unsigned int> sim_nLay; std::vector<unsigned int> sim_nPixelLay; std::vector<unsigned int> sim_n3DLay; // number of sim hits as calculated in TrackingTruthAccumulator std::vector<unsigned int> sim_nTrackerHits; // number of clusters associated to TP std::vector<unsigned int> sim_nRecoClusters; // links to other objects std::vector<std::vector<int>> sim_trkIdx; // second index runs through matched tracks std::vector<std::vector<float>> sim_trkShareFrac; // second index runs through matched tracks std::vector<std::vector<int>> sim_seedIdx; // second index runs through matched seeds std::vector<int> sim_parentVtxIdx; std::vector<std::vector<int>> sim_decayVtxIdx; // second index runs through decay vertices std::vector<std::vector<int>> sim_simHitIdx; // second index runs through SimHits //////////////////// // pixel hits // (first) index runs through hits std::vector<short> pix_isBarrel; DetIdPixel pix_detId; std::vector<std::vector<int>> pix_trkIdx; // second index runs through tracks containing this hit std::vector<std::vector<float>> pix_onTrk_x; // second index runs through tracks containing this hit std::vector<std::vector<float>> pix_onTrk_y; // same for all pix_onTrk_* std::vector<std::vector<float>> pix_onTrk_z; // std::vector<std::vector<float>> pix_onTrk_xx; // std::vector<std::vector<float>> pix_onTrk_xy; // std::vector<std::vector<float>> pix_onTrk_yy; // std::vector<std::vector<float>> pix_onTrk_yz; // std::vector<std::vector<float>> pix_onTrk_zz; // std::vector<std::vector<float>> pix_onTrk_zx; // std::vector<std::vector<int>> pix_tcandIdx; // second index runs through candidates containing this hit std::vector<std::vector<int>> pix_seeIdx; // second index runs through seeds containing this hit std::vector<std::vector<int>> pix_simHitIdx; // second index runs through SimHits inducing this hit std::vector<std::vector<float>> pix_xySignificance; // second index runs through SimHits inducing this hit std::vector<std::vector<float>> pix_chargeFraction; // second index runs through SimHits inducing this hit std::vector<unsigned short> pix_simType; std::vector<float> pix_x; std::vector<float> pix_y; std::vector<float> pix_z; std::vector<float> pix_xx; std::vector<float> pix_xy; std::vector<float> pix_yy; std::vector<float> pix_yz; std::vector<float> pix_zz; std::vector<float> pix_zx; std::vector<float> pix_radL; //http://cmslxr.fnal.gov/lxr/source/DataFormats/GeometrySurface/interface/MediumProperties.h std::vector<float> pix_bbxi; std::vector<int> pix_clustSizeCol; std::vector<int> pix_clustSizeRow; std::vector<uint64_t> pix_usedMask; //////////////////// // strip hits // (first) index runs through hits std::vector<short> str_isBarrel; DetIdStrip str_detId; std::vector<std::vector<int>> str_trkIdx; // second index runs through tracks containing this hit std::vector<std::vector<float>> str_onTrk_x; // second index runs through tracks containing this hit std::vector<std::vector<float>> str_onTrk_y; // same for all pix_onTrk_* std::vector<std::vector<float>> str_onTrk_z; // std::vector<std::vector<float>> str_onTrk_xx; // std::vector<std::vector<float>> str_onTrk_xy; // std::vector<std::vector<float>> str_onTrk_yy; // std::vector<std::vector<float>> str_onTrk_yz; // std::vector<std::vector<float>> str_onTrk_zz; // std::vector<std::vector<float>> str_onTrk_zx; // std::vector<std::vector<int>> str_tcandIdx; // second index runs through candidates containing this hit std::vector<std::vector<int>> str_seeIdx; // second index runs through seeds containing this hit std::vector<std::vector<int>> str_simHitIdx; // second index runs through SimHits inducing this hit std::vector<std::vector<float>> str_xySignificance; // second index runs through SimHits inducing this hit std::vector<std::vector<float>> str_chargeFraction; // second index runs through SimHits inducing this hit std::vector<unsigned short> str_simType; std::vector<float> str_x; std::vector<float> str_y; std::vector<float> str_z; std::vector<float> str_xx; std::vector<float> str_xy; std::vector<float> str_yy; std::vector<float> str_yz; std::vector<float> str_zz; std::vector<float> str_zx; std::vector<float> str_radL; //http://cmslxr.fnal.gov/lxr/source/DataFormats/GeometrySurface/interface/MediumProperties.h std::vector<float> str_bbxi; std::vector<float> str_chargePerCM; std::vector<int> str_clustSize; std::vector<uint64_t> str_usedMask; //////////////////// // strip matched hits // (first) index runs through hits std::vector<short> glu_isBarrel; DetIdStrip glu_detId; std::vector<int> glu_monoIdx; std::vector<int> glu_stereoIdx; std::vector<std::vector<int>> glu_seeIdx; // second index runs through seeds containing this hit std::vector<float> glu_x; std::vector<float> glu_y; std::vector<float> glu_z; std::vector<float> glu_xx; std::vector<float> glu_xy; std::vector<float> glu_yy; std::vector<float> glu_yz; std::vector<float> glu_zz; std::vector<float> glu_zx; std::vector<float> glu_radL; //http://cmslxr.fnal.gov/lxr/source/DataFormats/GeometrySurface/interface/MediumProperties.h std::vector<float> glu_bbxi; std::vector<float> glu_chargePerCM; std::vector<int> glu_clustSizeMono; std::vector<int> glu_clustSizeStereo; std::vector<uint64_t> glu_usedMaskMono; std::vector<uint64_t> glu_usedMaskStereo; //////////////////// // phase2 Outer Tracker hits // (first) index runs through hits std::vector<short> ph2_isBarrel; DetIdPhase2OT ph2_detId; std::vector<std::vector<int>> ph2_trkIdx; // second index runs through tracks containing this hit std::vector<std::vector<float>> ph2_onTrk_x; // second index runs through tracks containing this hit std::vector<std::vector<float>> ph2_onTrk_y; // same for all pix_onTrk_* std::vector<std::vector<float>> ph2_onTrk_z; // std::vector<std::vector<float>> ph2_onTrk_xx; // std::vector<std::vector<float>> ph2_onTrk_xy; // std::vector<std::vector<float>> ph2_onTrk_yy; // std::vector<std::vector<float>> ph2_onTrk_yz; // std::vector<std::vector<float>> ph2_onTrk_zz; // std::vector<std::vector<float>> ph2_onTrk_zx; // std::vector<std::vector<int>> ph2_tcandIdx; // second index runs through candidates containing this hit std::vector<std::vector<int>> ph2_seeIdx; // second index runs through seeds containing this hit std::vector<std::vector<int>> ph2_simHitIdx; // second index runs through SimHits inducing this hit std::vector<std::vector<float>> ph2_xySignificance; // second index runs through SimHits inducing this hit //std::vector<std::vector<float>> ph2_chargeFraction; // Not supported at the moment for Phase2 std::vector<unsigned short> ph2_simType; std::vector<float> ph2_x; std::vector<float> ph2_y; std::vector<float> ph2_z; std::vector<float> ph2_xx; std::vector<float> ph2_xy; std::vector<float> ph2_yy; std::vector<float> ph2_yz; std::vector<float> ph2_zz; std::vector<float> ph2_zx; std::vector<float> ph2_radL; //http://cmslxr.fnal.gov/lxr/source/DataFormats/GeometrySurface/interface/MediumProperties.h std::vector<float> ph2_bbxi; std::vector<uint64_t> ph2_usedMask; std::vector<uint16_t> ph2_clustSize; //////////////////// // invalid (missing/inactive/etc) hits // (first) index runs through hits std::vector<short> inv_isBarrel; DetIdAll inv_detId; DetIdAllPhase2 inv_detId_phase2; std::vector<unsigned short> inv_type; //////////////////// // sim hits // (first) index runs through hits DetIdAll simhit_detId; DetIdAllPhase2 simhit_detId_phase2; std::vector<float> simhit_x; std::vector<float> simhit_y; std::vector<float> simhit_z; std::vector<float> simhit_px; std::vector<float> simhit_py; std::vector<float> simhit_pz; std::vector<int> simhit_particle; std::vector<short> simhit_process; std::vector<float> simhit_eloss; std::vector<float> simhit_tof; //std::vector<unsigned int> simhit_simTrackId; // can be useful for debugging, but not much of general interest std::vector<int> simhit_simTrkIdx; std::vector<std::vector<int>> simhit_hitIdx; // second index runs through induced reco hits std::vector<std::vector<int>> simhit_hitType; // second index runs through induced reco hits //////////////////// // beam spot float bsp_x; float bsp_y; float bsp_z; float bsp_sigmax; float bsp_sigmay; float bsp_sigmaz; //////////////////// // seeds // (first) index runs through seeds std::vector<short> see_fitok; std::vector<float> see_px; std::vector<float> see_py; std::vector<float> see_pz; std::vector<float> see_pt; std::vector<float> see_eta; std::vector<float> see_phi; std::vector<float> see_dxy; std::vector<float> see_dz; std::vector<float> see_ptErr; std::vector<float> see_etaErr; std::vector<float> see_phiErr; std::vector<float> see_dxyErr; std::vector<float> see_dzErr; std::vector<float> see_chi2; std::vector<float> see_statePt; std::vector<float> see_stateTrajX; std::vector<float> see_stateTrajY; std::vector<float> see_stateTrajPx; std::vector<float> see_stateTrajPy; std::vector<float> see_stateTrajPz; std::vector<float> see_stateTrajGlbX; std::vector<float> see_stateTrajGlbY; std::vector<float> see_stateTrajGlbZ; std::vector<float> see_stateTrajGlbPx; std::vector<float> see_stateTrajGlbPy; std::vector<float> see_stateTrajGlbPz; std::vector<std::vector<float>> see_stateCurvCov; std::vector<int> see_q; std::vector<unsigned int> see_nValid; std::vector<unsigned int> see_nPixel; std::vector<unsigned int> see_nGlued; std::vector<unsigned int> see_nStrip; std::vector<unsigned int> see_nPhase2OT; std::vector<unsigned int> see_nCluster; std::vector<unsigned int> see_algo; std::vector<unsigned short> see_stopReason; std::vector<unsigned short> see_nCands; std::vector<unsigned int> see_nTrk; std::vector<unsigned int> see_nTCand; std::vector<std::vector<unsigned int>> see_trkIdx; std::vector<std::vector<unsigned int>> see_tcandIdx; std::vector<short> see_isTrue; std::vector<int> see_bestSimTrkIdx; std::vector<float> see_bestSimTrkShareFrac; std::vector<int> see_bestFromFirstHitSimTrkIdx; std::vector<float> see_bestFromFirstHitSimTrkShareFrac; std::vector<std::vector<float>> see_simTrkShareFrac; // second index runs through matched TrackingParticles std::vector<std::vector<int>> see_simTrkIdx; // second index runs through matched TrackingParticles std::vector<std::vector<int>> see_hitIdx; // second index runs through hits std::vector<std::vector<int>> see_hitType; // second index runs through hits //seed algo offset, index runs through iterations std::vector<unsigned int> see_offset; //////////////////// // Vertices // (first) index runs through vertices std::vector<float> vtx_x; std::vector<float> vtx_y; std::vector<float> vtx_z; std::vector<float> vtx_xErr; std::vector<float> vtx_yErr; std::vector<float> vtx_zErr; std::vector<float> vtx_ndof; std::vector<float> vtx_chi2; std::vector<short> vtx_fake; std::vector<short> vtx_valid; std::vector<std::vector<int>> vtx_trkIdx; // second index runs through tracks used in the vertex fit //////////////////// // Tracking vertices // (first) index runs through TrackingVertices std::vector<int> simvtx_event; std::vector<int> simvtx_bunchCrossing; std::vector<unsigned int> simvtx_processType; // only from first SimVertex of TrackingVertex std::vector<float> simvtx_x; std::vector<float> simvtx_y; std::vector<float> simvtx_z; std::vector<std::vector<int>> simvtx_sourceSimIdx; // second index runs through source TrackingParticles std::vector<std::vector<int>> simvtx_daughterSimIdx; // second index runs through daughter TrackingParticles std::vector<int> simpv_idx; std::vector<float> sim_genjet_deltaEta; // distance to closest GenJet std::vector<float> sim_genjet_deltaPhi; std::vector<float> sim_genjet_deltaR; std::vector<int> sim_genjet_idx; // index of GenJet for each Sim track //////////////////// // GenJets std::vector<float> genjet_pt; std::vector<float> genjet_eta; std::vector<float> genjet_phi; std::vector<float> genjet_invisible_energy; std::vector<float> genjet_auxiliary_energy; }; // // constructors and destructor // TrackingNtuple::TrackingNtuple(const edm::ParameterSet& iConfig) : mfToken_(esConsumes()), tTopoToken_(esConsumes()), tGeomToken_(esConsumes()), trackToken_(consumes<edm::View<reco::Track>>(iConfig.getUntrackedParameter<edm::InputTag>("tracks"))), clusterTPMapToken_(consumes<ClusterTPAssociation>(iConfig.getUntrackedParameter<edm::InputTag>("clusterTPMap"))), simHitTPMapToken_(consumes<SimHitTPAssociationProducer::SimHitTPAssociationList>( iConfig.getUntrackedParameter<edm::InputTag>("simHitTPMap"))), trackAssociatorToken_(consumes<reco::TrackToTrackingParticleAssociator>( iConfig.getUntrackedParameter<edm::InputTag>("trackAssociator"))), pixelSimLinkToken_(consumes<edm::DetSetVector<PixelDigiSimLink>>( iConfig.getUntrackedParameter<edm::InputTag>("pixelDigiSimLink"))), stripSimLinkToken_(consumes<edm::DetSetVector<StripDigiSimLink>>( iConfig.getUntrackedParameter<edm::InputTag>("stripDigiSimLink"))), siphase2OTSimLinksToken_(consumes<edm::DetSetVector<PixelDigiSimLink>>( iConfig.getUntrackedParameter<edm::InputTag>("phase2OTSimLink"))), includeStripHits_(!iConfig.getUntrackedParameter<edm::InputTag>("stripDigiSimLink").label().empty()), includePhase2OTHits_(!iConfig.getUntrackedParameter<edm::InputTag>("phase2OTSimLink").label().empty()), beamSpotToken_(consumes<reco::BeamSpot>(iConfig.getUntrackedParameter<edm::InputTag>("beamSpot"))), pixelRecHitToken_( consumes<SiPixelRecHitCollection>(iConfig.getUntrackedParameter<edm::InputTag>("pixelRecHits"))), stripRphiRecHitToken_( consumes<SiStripRecHit2DCollection>(iConfig.getUntrackedParameter<edm::InputTag>("stripRphiRecHits"))), stripStereoRecHitToken_( consumes<SiStripRecHit2DCollection>(iConfig.getUntrackedParameter<edm::InputTag>("stripStereoRecHits"))), stripMatchedRecHitToken_(consumes<SiStripMatchedRecHit2DCollection>( iConfig.getUntrackedParameter<edm::InputTag>("stripMatchedRecHits"))), phase2OTRecHitToken_(consumes<Phase2TrackerRecHit1DCollectionNew>( iConfig.getUntrackedParameter<edm::InputTag>("phase2OTRecHits"))), vertexToken_(consumes<reco::VertexCollection>(iConfig.getUntrackedParameter<edm::InputTag>("vertices"))), trackingVertexToken_( consumes<TrackingVertexCollection>(iConfig.getUntrackedParameter<edm::InputTag>("trackingVertices"))), tpNLayersToken_(consumes<edm::ValueMap<unsigned int>>( iConfig.getUntrackedParameter<edm::InputTag>("trackingParticleNlayers"))), tpNPixelLayersToken_(consumes<edm::ValueMap<unsigned int>>( iConfig.getUntrackedParameter<edm::InputTag>("trackingParticleNpixellayers"))), tpNStripStereoLayersToken_(consumes<edm::ValueMap<unsigned int>>( iConfig.getUntrackedParameter<edm::InputTag>("trackingParticleNstripstereolayers"))), includeSeeds_(iConfig.getUntrackedParameter<bool>("includeSeeds")), seedUniqueCheck_(includeSeeds_ && iConfig.getUntrackedParameter<bool>("seedUniqueCheck")), seedAlgoDetect_(includeSeeds_ && iConfig.getUntrackedParameter<bool>("seedAlgoDetect")), seedAlgos_(seedAlgoDetect_ ? std::vector<unsigned int>() : iConfig.getUntrackedParameter<std::vector<unsigned int>>("seedAlgos")), includeTrackCandidates_(iConfig.getUntrackedParameter<bool>("includeTrackCandidates")), addSeedCurvCov_(iConfig.getUntrackedParameter<bool>("addSeedCurvCov")), includeAllHits_(iConfig.getUntrackedParameter<bool>("includeAllHits")), includeOnTrackHitData_(iConfig.getUntrackedParameter<bool>("includeOnTrackHitData")), includeMVA_(iConfig.getUntrackedParameter<bool>("includeMVA")), includeTrackingParticles_(iConfig.getUntrackedParameter<bool>("includeTrackingParticles")), includeOOT_(iConfig.getUntrackedParameter<bool>("includeOOT")), keepEleSimHits_(iConfig.getUntrackedParameter<bool>("keepEleSimHits")), saveSimHitsP3_(iConfig.getUntrackedParameter<bool>("saveSimHitsP3")), simHitBySignificance_(iConfig.getUntrackedParameter<bool>("simHitBySignificance")), parametersDefiner_(iConfig.getUntrackedParameter<edm::InputTag>("beamSpot"), consumesCollector()), tok_jets_(consumes<reco::GenJetCollection>(iConfig.getParameter<edm::InputTag>("jetSource"))) { if (includeSeeds_) { seedTokens_ = edm::vector_transform(iConfig.getUntrackedParameter<std::vector<edm::InputTag>>("seedTracks"), [&](const edm::InputTag& tag) { return consumes<edm::View<reco::Track>>(tag); }); seedStopInfoTokens_ = edm::vector_transform(iConfig.getUntrackedParameter<std::vector<edm::InputTag>>("trackCandidates"), [&](const edm::InputTag& tag) { return consumes<std::vector<SeedStopInfo>>(tag); }); if (seedTokens_.size() != seedStopInfoTokens_.size()) { throw cms::Exception("Configuration") << "Got " << seedTokens_.size() << " seed collections, but " << seedStopInfoTokens_.size() << " track candidate collections"; } if (seedAlgoDetect_) { for (auto const& token : seedStopInfoTokens_) { edm::EDConsumerBase::Labels labels; labelsForToken(token, labels); TString label = labels.module; //format label to match algoName label.ReplaceAll("seedTracks", ""); label.ReplaceAll("Seeds", ""); label.ReplaceAll("TrackCandidates", ""); label.ReplaceAll("muonSeeded", "muonSeededStep"); //for HLT seeds label.ReplaceAll("FromPixelTracks", ""); label.ReplaceAll("PFLowPixel", ""); label.ReplaceAll("PFlowPixel", ""); label.ReplaceAll("hltIni", "ini"); label.ReplaceAll("hltHigh", "high"); label.ReplaceAll("hltDoubletRecovery", "pixelPairStep"); label.ReplaceAll("hltInputLST", "hltPixel"); int algo = reco::TrackBase::algoByName(label.Data()); if (algo == 0) throw cms::Exception("LogicError") << "Failed to detect seed algo for collection " << labels.module << ":" << labels.productInstance << " last transform is " << label; seedAlgos_.push_back(algo); } } else { if (seedAlgos_.size() != seedTokens_.size()) throw cms::Exception("Configuration") << "Got " << seedTokens_.size() << " seed collections, but " << seedAlgos_.size() << " algo overrides"; } } if (includeTrackCandidates_) candidateTokens_ = edm::vector_transform(iConfig.getUntrackedParameter<std::vector<edm::InputTag>>("trackCandidates"), [&](const edm::InputTag& tag) { return consumes<TrackCandidateCollection>(tag); }); if (includeAllHits_) { if (includeStripHits_ && includePhase2OTHits_) { throw cms::Exception("Configuration") << "Both stripDigiSimLink and phase2OTSimLink are set, please set only either one (this information is used " "to infer if you're running phase0/1 or phase2 detector)"; } if (!includeStripHits_ && !includePhase2OTHits_) { throw cms::Exception("Configuration") << "Neither stripDigiSimLink or phase2OTSimLink are set, please set either one."; } auto const& maskVPset = iConfig.getUntrackedParameterSetVector("clusterMasks"); pixelUseMaskTokens_.reserve(maskVPset.size()); stripUseMaskTokens_.reserve(maskVPset.size()); ph2OTUseMaskTokens_.reserve(maskVPset.size()); for (auto const& mask : maskVPset) { auto index = mask.getUntrackedParameter<unsigned int>("index"); assert(index < 64); pixelUseMaskTokens_.emplace_back(index, consumes<PixelMaskContainer>(mask.getUntrackedParameter<edm::InputTag>("src"))); if (includeStripHits_) stripUseMaskTokens_.emplace_back( index, consumes<StripMaskContainer>(mask.getUntrackedParameter<edm::InputTag>("src"))); if (includePhase2OTHits_) ph2OTUseMaskTokens_.emplace_back( index, consumes<Phase2OTMaskContainer>(mask.getUntrackedParameter<edm::InputTag>("src"))); } } const bool tpRef = iConfig.getUntrackedParameter<bool>("trackingParticlesRef"); const auto tpTag = iConfig.getUntrackedParameter<edm::InputTag>("trackingParticles"); if (tpRef) { trackingParticleRefToken_ = consumes<TrackingParticleRefVector>(tpTag); } else { trackingParticleToken_ = consumes<TrackingParticleCollection>(tpTag); } tracer_.depth(-2); // as in SimTracker/TrackHistory/src/TrackClassifier.cc if (includeMVA_) { mvaQualityCollectionTokens_ = edm::vector_transform( iConfig.getUntrackedParameter<std::vector<std::string>>("trackMVAs"), [&](const std::string& tag) { return std::make_tuple(consumes<MVACollection>(edm::InputTag(tag, "MVAValues")), consumes<QualityMaskCollection>(edm::InputTag(tag, "QualityMasks"))); }); } usesResource(TFileService::kSharedResource); edm::Service<TFileService> fs; t = fs->make<TTree>("tree", "tree"); t->Branch("event", &ev_event); t->Branch("lumi", &ev_lumi); t->Branch("run", &ev_run); //tracks t->Branch("trk_px", &trk_px); t->Branch("trk_py", &trk_py); t->Branch("trk_pz", &trk_pz); t->Branch("trk_pt", &trk_pt); t->Branch("trk_inner_px", &trk_inner_px); t->Branch("trk_inner_py", &trk_inner_py); t->Branch("trk_inner_pz", &trk_inner_pz); t->Branch("trk_inner_pt", &trk_inner_pt); t->Branch("trk_outer_px", &trk_outer_px); t->Branch("trk_outer_py", &trk_outer_py); t->Branch("trk_outer_pz", &trk_outer_pz); t->Branch("trk_outer_pt", &trk_outer_pt); t->Branch("trk_eta", &trk_eta); t->Branch("trk_lambda", &trk_lambda); t->Branch("trk_cotTheta", &trk_cotTheta); t->Branch("trk_phi", &trk_phi); t->Branch("trk_dxy", &trk_dxy); t->Branch("trk_dz", &trk_dz); t->Branch("trk_dxyPV", &trk_dxyPV); t->Branch("trk_dzPV", &trk_dzPV); t->Branch("trk_dxyClosestPV", &trk_dxyClosestPV); t->Branch("trk_dzClosestPV", &trk_dzClosestPV); t->Branch("trk_ptErr", &trk_ptErr); t->Branch("trk_etaErr", &trk_etaErr); t->Branch("trk_lambdaErr", &trk_lambdaErr); t->Branch("trk_phiErr", &trk_phiErr); t->Branch("trk_dxyErr", &trk_dxyErr); t->Branch("trk_dzErr", &trk_dzErr); t->Branch("trk_refpoint_x", &trk_refpoint_x); t->Branch("trk_refpoint_y", &trk_refpoint_y); t->Branch("trk_refpoint_z", &trk_refpoint_z); t->Branch("trk_nChi2", &trk_nChi2); t->Branch("trk_nChi2_1Dmod", &trk_nChi2_1Dmod); t->Branch("trk_ndof", &trk_ndof); if (includeMVA_) { trk_mvas.resize(mvaQualityCollectionTokens_.size()); trk_qualityMasks.resize(mvaQualityCollectionTokens_.size()); if (!trk_mvas.empty()) { t->Branch("trk_mva", &(trk_mvas[0])); t->Branch("trk_qualityMask", &(trk_qualityMasks[0])); for (size_t i = 1; i < trk_mvas.size(); ++i) { t->Branch(("trk_mva" + std::to_string(i + 1)).c_str(), &(trk_mvas[i])); t->Branch(("trk_qualityMask" + std::to_string(i + 1)).c_str(), &(trk_qualityMasks[i])); } } } t->Branch("trk_q", &trk_q); t->Branch("trk_nValid", &trk_nValid); t->Branch("trk_nLost", &trk_nLost); t->Branch("trk_nInactive", &trk_nInactive); t->Branch("trk_nPixel", &trk_nPixel); t->Branch("trk_nStrip", &trk_nStrip); t->Branch("trk_nOuterLost", &trk_nOuterLost); t->Branch("trk_nInnerLost", &trk_nInnerLost); t->Branch("trk_nOuterInactive", &trk_nOuterInactive); t->Branch("trk_nInnerInactive", &trk_nInnerInactive); t->Branch("trk_nPixelLay", &trk_nPixelLay); t->Branch("trk_nStripLay", &trk_nStripLay); t->Branch("trk_n3DLay", &trk_n3DLay); t->Branch("trk_nLostLay", &trk_nLostLay); t->Branch("trk_nCluster", &trk_nCluster); t->Branch("trk_algo", &trk_algo); t->Branch("trk_originalAlgo", &trk_originalAlgo); t->Branch("trk_algoMask", &trk_algoMask); t->Branch("trk_stopReason", &trk_stopReason); t->Branch("trk_isHP", &trk_isHP); if (includeSeeds_) { t->Branch("trk_seedIdx", &trk_seedIdx); } t->Branch("trk_vtxIdx", &trk_vtxIdx); if (includeTrackingParticles_) { t->Branch("trk_simTrkIdx", &trk_simTrkIdx); t->Branch("trk_simTrkShareFrac", &trk_simTrkShareFrac); t->Branch("trk_simTrkNChi2", &trk_simTrkNChi2); t->Branch("trk_bestSimTrkIdx", &trk_bestSimTrkIdx); t->Branch("trk_bestFromFirstHitSimTrkIdx", &trk_bestFromFirstHitSimTrkIdx); } else { t->Branch("trk_isTrue", &trk_isTrue); } t->Branch("trk_bestSimTrkShareFrac", &trk_bestSimTrkShareFrac); t->Branch("trk_bestSimTrkShareFracSimDenom", &trk_bestSimTrkShareFracSimDenom); t->Branch("trk_bestSimTrkShareFracSimClusterDenom", &trk_bestSimTrkShareFracSimClusterDenom); t->Branch("trk_bestSimTrkNChi2", &trk_bestSimTrkNChi2); t->Branch("trk_bestFromFirstHitSimTrkShareFrac", &trk_bestFromFirstHitSimTrkShareFrac); t->Branch("trk_bestFromFirstHitSimTrkShareFracSimDenom", &trk_bestFromFirstHitSimTrkShareFracSimDenom); t->Branch("trk_bestFromFirstHitSimTrkShareFracSimClusterDenom", &trk_bestFromFirstHitSimTrkShareFracSimClusterDenom); t->Branch("trk_bestFromFirstHitSimTrkNChi2", &trk_bestFromFirstHitSimTrkNChi2); if (includeAllHits_) { t->Branch("trk_hitIdx", &trk_hitIdx); t->Branch("trk_hitType", &trk_hitType); } if (includeTrackCandidates_) { t->Branch("tcand_pca_valid", &tcand_pca_valid); t->Branch("tcand_pca_px", &tcand_pca_px); t->Branch("tcand_pca_py", &tcand_pca_py); t->Branch("tcand_pca_pz", &tcand_pca_pz); t->Branch("tcand_pca_pt", &tcand_pca_pt); t->Branch("tcand_pca_eta", &tcand_pca_eta); t->Branch("tcand_pca_phi", &tcand_pca_phi); t->Branch("tcand_pca_dxy", &tcand_pca_dxy); t->Branch("tcand_pca_dz", &tcand_pca_dz); t->Branch("tcand_pca_ptErr", &tcand_pca_ptErr); t->Branch("tcand_pca_etaErr", &tcand_pca_etaErr); t->Branch("tcand_pca_lambdaErr", &tcand_pca_lambdaErr); t->Branch("tcand_pca_phiErr", &tcand_pca_phiErr); t->Branch("tcand_pca_dxyErr", &tcand_pca_dxyErr); t->Branch("tcand_pca_dzErr", &tcand_pca_dzErr); t->Branch("tcand_px", &tcand_px); t->Branch("tcand_py", &tcand_py); t->Branch("tcand_pz", &tcand_pz); t->Branch("tcand_pt", &tcand_pt); t->Branch("tcand_x", &tcand_x); t->Branch("tcand_y", &tcand_y); t->Branch("tcand_z", &tcand_z); t->Branch("tcand_qbpErr", &tcand_qbpErr); t->Branch("tcand_lambdaErr", &tcand_lambdaErr); t->Branch("tcand_phiErr", &tcand_phiErr); t->Branch("tcand_xtErr", &tcand_xtErr); t->Branch("tcand_ytErr", &tcand_ytErr); t->Branch("tcand_q", &tcand_q); t->Branch("tcand_ndof", &tcand_ndof); t->Branch("tcand_nValid", &tcand_nValid); t->Branch("tcand_nPixel", &tcand_nPixel); t->Branch("tcand_nStrip", &tcand_nStrip); t->Branch("tcand_nCluster", &tcand_nCluster); t->Branch("tcand_algo", &tcand_algo); t->Branch("tcand_stopReason", &tcand_stopReason); if (includeSeeds_) { t->Branch("tcand_seedIdx", &tcand_seedIdx); } t->Branch("tcand_vtxIdx", &tcand_vtxIdx); if (includeTrackingParticles_) { t->Branch("tcand_simTrkIdx", &tcand_simTrkIdx); t->Branch("tcand_simTrkShareFrac", &tcand_simTrkShareFrac); t->Branch("tcand_simTrkNChi2", &tcand_simTrkNChi2); t->Branch("tcand_bestSimTrkIdx", &tcand_bestSimTrkIdx); t->Branch("tcand_bestFromFirstHitSimTrkIdx", &tcand_bestFromFirstHitSimTrkIdx); } else { t->Branch("tcand_isTrue", &tcand_isTrue); } t->Branch("tcand_bestSimTrkShareFrac", &tcand_bestSimTrkShareFrac); t->Branch("tcand_bestSimTrkShareFracSimDenom", &tcand_bestSimTrkShareFracSimDenom); t->Branch("tcand_bestSimTrkShareFracSimClusterDenom", &tcand_bestSimTrkShareFracSimClusterDenom); t->Branch("tcand_bestSimTrkNChi2", &tcand_bestSimTrkNChi2); t->Branch("tcand_bestFromFirstHitSimTrkShareFrac", &tcand_bestFromFirstHitSimTrkShareFrac); t->Branch("tcand_bestFromFirstHitSimTrkShareFracSimDenom", &tcand_bestFromFirstHitSimTrkShareFracSimDenom); t->Branch("tcand_bestFromFirstHitSimTrkShareFracSimClusterDenom", &tcand_bestFromFirstHitSimTrkShareFracSimClusterDenom); t->Branch("tcand_bestFromFirstHitSimTrkNChi2", &tcand_bestFromFirstHitSimTrkNChi2); if (includeAllHits_) { t->Branch("tcand_hitIdx", &tcand_hitIdx); t->Branch("tcand_hitType", &tcand_hitType); } } if (includeTrackingParticles_) { //sim tracks t->Branch("sim_event", &sim_event); t->Branch("sim_bunchCrossing", &sim_bunchCrossing); t->Branch("sim_pdgId", &sim_pdgId); t->Branch("sim_genPdgIds", &sim_genPdgIds); t->Branch("sim_isFromBHadron", &sim_isFromBHadron); t->Branch("sim_px", &sim_px); t->Branch("sim_py", &sim_py); t->Branch("sim_pz", &sim_pz); t->Branch("sim_pt", &sim_pt); t->Branch("sim_eta", &sim_eta); t->Branch("sim_phi", &sim_phi); t->Branch("sim_pca_pt", &sim_pca_pt); t->Branch("sim_pca_eta", &sim_pca_eta); t->Branch("sim_pca_lambda", &sim_pca_lambda); t->Branch("sim_pca_cotTheta", &sim_pca_cotTheta); t->Branch("sim_pca_phi", &sim_pca_phi); t->Branch("sim_pca_dxy", &sim_pca_dxy); t->Branch("sim_pca_dz", &sim_pca_dz); t->Branch("sim_q", &sim_q); t->Branch("sim_nValid", &sim_nValid); t->Branch("sim_nPixel", &sim_nPixel); t->Branch("sim_nStrip", &sim_nStrip); t->Branch("sim_nLay", &sim_nLay); t->Branch("sim_nPixelLay", &sim_nPixelLay); t->Branch("sim_n3DLay", &sim_n3DLay); t->Branch("sim_nTrackerHits", &sim_nTrackerHits); t->Branch("sim_nRecoClusters", &sim_nRecoClusters); t->Branch("sim_trkIdx", &sim_trkIdx); t->Branch("sim_trkShareFrac", &sim_trkShareFrac); if (includeSeeds_) { t->Branch("sim_seedIdx", &sim_seedIdx); } t->Branch("sim_parentVtxIdx", &sim_parentVtxIdx); t->Branch("sim_decayVtxIdx", &sim_decayVtxIdx); if (includeAllHits_) { t->Branch("sim_simHitIdx", &sim_simHitIdx); } } if (includeAllHits_) { //pixels t->Branch("pix_isBarrel", &pix_isBarrel); pix_detId.book("pix", t); t->Branch("pix_trkIdx", &pix_trkIdx); if (includeOnTrackHitData_) { t->Branch("pix_onTrk_x", &pix_onTrk_x); t->Branch("pix_onTrk_y", &pix_onTrk_y); t->Branch("pix_onTrk_z", &pix_onTrk_z); t->Branch("pix_onTrk_xx", &pix_onTrk_xx); t->Branch("pix_onTrk_xy", &pix_onTrk_xy); t->Branch("pix_onTrk_yy", &pix_onTrk_yy); t->Branch("pix_onTrk_yz", &pix_onTrk_yz); t->Branch("pix_onTrk_zz", &pix_onTrk_zz); t->Branch("pix_onTrk_zx", &pix_onTrk_zx); } if (includeTrackCandidates_) t->Branch("pix_tcandIdx", &pix_tcandIdx); if (includeSeeds_) { t->Branch("pix_seeIdx", &pix_seeIdx); } if (includeTrackingParticles_) { t->Branch("pix_simHitIdx", &pix_simHitIdx); if (simHitBySignificance_) { t->Branch("pix_xySignificance", &pix_xySignificance); } t->Branch("pix_chargeFraction", &pix_chargeFraction); t->Branch("pix_simType", &pix_simType); } t->Branch("pix_x", &pix_x); t->Branch("pix_y", &pix_y); t->Branch("pix_z", &pix_z); t->Branch("pix_xx", &pix_xx); t->Branch("pix_xy", &pix_xy); t->Branch("pix_yy", &pix_yy); t->Branch("pix_yz", &pix_yz); t->Branch("pix_zz", &pix_zz); t->Branch("pix_zx", &pix_zx); t->Branch("pix_radL", &pix_radL); t->Branch("pix_bbxi", &pix_bbxi); t->Branch("pix_clustSizeCol", &pix_clustSizeCol); t->Branch("pix_clustSizeRow", &pix_clustSizeRow); t->Branch("pix_usedMask", &pix_usedMask); //strips if (includeStripHits_) { t->Branch("str_isBarrel", &str_isBarrel); str_detId.book("str", t); t->Branch("str_trkIdx", &str_trkIdx); if (includeOnTrackHitData_) { t->Branch("str_onTrk_x", &str_onTrk_x); t->Branch("str_onTrk_y", &str_onTrk_y); t->Branch("str_onTrk_z", &str_onTrk_z); t->Branch("str_onTrk_xx", &str_onTrk_xx); t->Branch("str_onTrk_xy", &str_onTrk_xy); t->Branch("str_onTrk_yy", &str_onTrk_yy); t->Branch("str_onTrk_yz", &str_onTrk_yz); t->Branch("str_onTrk_zz", &str_onTrk_zz); t->Branch("str_onTrk_zx", &str_onTrk_zx); } if (includeTrackCandidates_) t->Branch("str_tcandIdx", &str_tcandIdx); if (includeSeeds_) { t->Branch("str_seeIdx", &str_seeIdx); } if (includeTrackingParticles_) { t->Branch("str_simHitIdx", &str_simHitIdx); if (simHitBySignificance_) { t->Branch("str_xySignificance", &str_xySignificance); } t->Branch("str_chargeFraction", &str_chargeFraction); t->Branch("str_simType", &str_simType); } t->Branch("str_x", &str_x); t->Branch("str_y", &str_y); t->Branch("str_z", &str_z); t->Branch("str_xx", &str_xx); t->Branch("str_xy", &str_xy); t->Branch("str_yy", &str_yy); t->Branch("str_yz", &str_yz); t->Branch("str_zz", &str_zz); t->Branch("str_zx", &str_zx); t->Branch("str_radL", &str_radL); t->Branch("str_bbxi", &str_bbxi); t->Branch("str_chargePerCM", &str_chargePerCM); t->Branch("str_clustSize", &str_clustSize); t->Branch("str_usedMask", &str_usedMask); //matched hits t->Branch("glu_isBarrel", &glu_isBarrel); glu_detId.book("glu", t); t->Branch("glu_monoIdx", &glu_monoIdx); t->Branch("glu_stereoIdx", &glu_stereoIdx); if (includeSeeds_) { t->Branch("glu_seeIdx", &glu_seeIdx); } t->Branch("glu_x", &glu_x); t->Branch("glu_y", &glu_y); t->Branch("glu_z", &glu_z); t->Branch("glu_xx", &glu_xx); t->Branch("glu_xy", &glu_xy); t->Branch("glu_yy", &glu_yy); t->Branch("glu_yz", &glu_yz); t->Branch("glu_zz", &glu_zz); t->Branch("glu_zx", &glu_zx); t->Branch("glu_radL", &glu_radL); t->Branch("glu_bbxi", &glu_bbxi); t->Branch("glu_chargePerCM", &glu_chargePerCM); t->Branch("glu_clustSizeMono", &glu_clustSizeMono); t->Branch("glu_clustSizeStereo", &glu_clustSizeStereo); t->Branch("glu_usedMaskMono", &glu_usedMaskMono); t->Branch("glu_usedMaskStereo", &glu_usedMaskStereo); } //phase2 OT if (includePhase2OTHits_) { t->Branch("ph2_isBarrel", &ph2_isBarrel); ph2_detId.book("ph2", t); t->Branch("ph2_trkIdx", &ph2_trkIdx); if (includeOnTrackHitData_) { t->Branch("ph2_onTrk_x", &ph2_onTrk_x); t->Branch("ph2_onTrk_y", &ph2_onTrk_y); t->Branch("ph2_onTrk_z", &ph2_onTrk_z); t->Branch("ph2_onTrk_xx", &ph2_onTrk_xx); t->Branch("ph2_onTrk_xy", &ph2_onTrk_xy); t->Branch("ph2_onTrk_yy", &ph2_onTrk_yy); t->Branch("ph2_onTrk_yz", &ph2_onTrk_yz); t->Branch("ph2_onTrk_zz", &ph2_onTrk_zz); t->Branch("ph2_onTrk_zx", &ph2_onTrk_zx); } if (includeTrackCandidates_) t->Branch("ph2_tcandIdx", &ph2_tcandIdx); if (includeSeeds_) { t->Branch("ph2_seeIdx", &ph2_seeIdx); } if (includeTrackingParticles_) { t->Branch("ph2_simHitIdx", &ph2_simHitIdx); if (simHitBySignificance_) { t->Branch("ph2_xySignificance", &ph2_xySignificance); } t->Branch("ph2_simType", &ph2_simType); } t->Branch("ph2_x", &ph2_x); t->Branch("ph2_y", &ph2_y); t->Branch("ph2_z", &ph2_z); t->Branch("ph2_xx", &ph2_xx); t->Branch("ph2_xy", &ph2_xy); t->Branch("ph2_yy", &ph2_yy); t->Branch("ph2_yz", &ph2_yz); t->Branch("ph2_zz", &ph2_zz); t->Branch("ph2_zx", &ph2_zx); t->Branch("ph2_radL", &ph2_radL); t->Branch("ph2_bbxi", &ph2_bbxi); t->Branch("ph2_usedMask", &ph2_usedMask); t->Branch("ph2_clustSize", &ph2_clustSize); } //invalid hits t->Branch("inv_isBarrel", &inv_isBarrel); if (includeStripHits_) inv_detId.book("inv", t); else inv_detId_phase2.book("inv", t); t->Branch("inv_type", &inv_type); //simhits if (includeTrackingParticles_) { if (includeStripHits_) simhit_detId.book("simhit", t); else simhit_detId_phase2.book("simhit", t); t->Branch("simhit_x", &simhit_x); t->Branch("simhit_y", &simhit_y); t->Branch("simhit_z", &simhit_z); if (saveSimHitsP3_) { t->Branch("simhit_px", &simhit_px); t->Branch("simhit_py", &simhit_py); t->Branch("simhit_pz", &simhit_pz); } t->Branch("simhit_particle", &simhit_particle); t->Branch("simhit_process", &simhit_process); t->Branch("simhit_eloss", &simhit_eloss); t->Branch("simhit_tof", &simhit_tof); t->Branch("simhit_simTrkIdx", &simhit_simTrkIdx); t->Branch("simhit_hitIdx", &simhit_hitIdx); t->Branch("simhit_hitType", &simhit_hitType); } } //beam spot t->Branch("bsp_x", &bsp_x, "bsp_x/F"); t->Branch("bsp_y", &bsp_y, "bsp_y/F"); t->Branch("bsp_z", &bsp_z, "bsp_z/F"); t->Branch("bsp_sigmax", &bsp_sigmax, "bsp_sigmax/F"); t->Branch("bsp_sigmay", &bsp_sigmay, "bsp_sigmay/F"); t->Branch("bsp_sigmaz", &bsp_sigmaz, "bsp_sigmaz/F"); if (includeSeeds_) { //seeds t->Branch("see_fitok", &see_fitok); t->Branch("see_px", &see_px); t->Branch("see_py", &see_py); t->Branch("see_pz", &see_pz); t->Branch("see_pt", &see_pt); t->Branch("see_eta", &see_eta); t->Branch("see_phi", &see_phi); t->Branch("see_dxy", &see_dxy); t->Branch("see_dz", &see_dz); t->Branch("see_ptErr", &see_ptErr); t->Branch("see_etaErr", &see_etaErr); t->Branch("see_phiErr", &see_phiErr); t->Branch("see_dxyErr", &see_dxyErr); t->Branch("see_dzErr", &see_dzErr); t->Branch("see_chi2", &see_chi2); t->Branch("see_statePt", &see_statePt); t->Branch("see_stateTrajX", &see_stateTrajX); t->Branch("see_stateTrajY", &see_stateTrajY); t->Branch("see_stateTrajPx", &see_stateTrajPx); t->Branch("see_stateTrajPy", &see_stateTrajPy); t->Branch("see_stateTrajPz", &see_stateTrajPz); t->Branch("see_stateTrajGlbX", &see_stateTrajGlbX); t->Branch("see_stateTrajGlbY", &see_stateTrajGlbY); t->Branch("see_stateTrajGlbZ", &see_stateTrajGlbZ); t->Branch("see_stateTrajGlbPx", &see_stateTrajGlbPx); t->Branch("see_stateTrajGlbPy", &see_stateTrajGlbPy); t->Branch("see_stateTrajGlbPz", &see_stateTrajGlbPz); if (addSeedCurvCov_) { t->Branch("see_stateCurvCov", &see_stateCurvCov); } t->Branch("see_q", &see_q); t->Branch("see_nValid", &see_nValid); t->Branch("see_nPixel", &see_nPixel); t->Branch("see_nGlued", &see_nGlued); t->Branch("see_nStrip", &see_nStrip); t->Branch("see_nPhase2OT", &see_nPhase2OT); t->Branch("see_nCluster", &see_nCluster); t->Branch("see_algo", &see_algo); t->Branch("see_stopReason", &see_stopReason); t->Branch("see_nCands", &see_nCands); t->Branch("see_nTrk", &see_nTrk); t->Branch("see_trkIdx", &see_trkIdx); if (includeTrackCandidates_) { t->Branch("see_nTCand", &see_nTCand); t->Branch("see_tcandIdx", &see_tcandIdx); } if (includeTrackingParticles_) { t->Branch("see_simTrkIdx", &see_simTrkIdx); t->Branch("see_simTrkShareFrac", &see_simTrkShareFrac); t->Branch("see_bestSimTrkIdx", &see_bestSimTrkIdx); t->Branch("see_bestFromFirstHitSimTrkIdx", &see_bestFromFirstHitSimTrkIdx); } else { t->Branch("see_isTrue", &see_isTrue); } t->Branch("see_bestSimTrkShareFrac", &see_bestSimTrkShareFrac); t->Branch("see_bestFromFirstHitSimTrkShareFrac", &see_bestFromFirstHitSimTrkShareFrac); if (includeAllHits_) { t->Branch("see_hitIdx", &see_hitIdx); t->Branch("see_hitType", &see_hitType); } //seed algo offset t->Branch("see_offset", &see_offset); } //vertices t->Branch("vtx_x", &vtx_x); t->Branch("vtx_y", &vtx_y); t->Branch("vtx_z", &vtx_z); t->Branch("vtx_xErr", &vtx_xErr); t->Branch("vtx_yErr", &vtx_yErr); t->Branch("vtx_zErr", &vtx_zErr); t->Branch("vtx_ndof", &vtx_ndof); t->Branch("vtx_chi2", &vtx_chi2); t->Branch("vtx_fake", &vtx_fake); t->Branch("vtx_valid", &vtx_valid); t->Branch("vtx_trkIdx", &vtx_trkIdx); // tracking vertices t->Branch("simvtx_event", &simvtx_event); t->Branch("simvtx_bunchCrossing", &simvtx_bunchCrossing); t->Branch("simvtx_processType", &simvtx_processType); t->Branch("simvtx_x", &simvtx_x); t->Branch("simvtx_y", &simvtx_y); t->Branch("simvtx_z", &simvtx_z); t->Branch("simvtx_sourceSimIdx", &simvtx_sourceSimIdx); t->Branch("simvtx_daughterSimIdx", &simvtx_daughterSimIdx); t->Branch("sim_genjet_deltaEta", &sim_genjet_deltaEta); t->Branch("sim_genjet_deltaPhi", &sim_genjet_deltaPhi); t->Branch("sim_genjet_deltaR", &sim_genjet_deltaR); t->Branch("simpv_idx", &simpv_idx); // GenJets t->Branch("genjet_pt", &genjet_pt); t->Branch("genjet_eta", &genjet_eta); t->Branch("genjet_phi", &genjet_phi); t->Branch("genjet_invisible_energy", &genjet_invisible_energy); t->Branch("genjet_auxiliary_energy", &genjet_auxiliary_energy); t->Branch("sim_genjet_idx", &sim_genjet_idx); //t->Branch("" , &); } TrackingNtuple::~TrackingNtuple() { // do anything here that needs to be done at desctruction time // (e.g. close files, deallocate resources etc.) } // // member functions // void TrackingNtuple::clearVariables() { ev_run = 0; ev_lumi = 0; ev_event = 0; //tracks trk_px.clear(); trk_py.clear(); trk_pz.clear(); trk_pt.clear(); trk_inner_px.clear(); trk_inner_py.clear(); trk_inner_pz.clear(); trk_inner_pt.clear(); trk_outer_px.clear(); trk_outer_py.clear(); trk_outer_pz.clear(); trk_outer_pt.clear(); trk_eta.clear(); trk_lambda.clear(); trk_cotTheta.clear(); trk_phi.clear(); trk_dxy.clear(); trk_dz.clear(); trk_dxyPV.clear(); trk_dzPV.clear(); trk_dxyClosestPV.clear(); trk_dzClosestPV.clear(); trk_ptErr.clear(); trk_etaErr.clear(); trk_lambdaErr.clear(); trk_phiErr.clear(); trk_dxyErr.clear(); trk_dzErr.clear(); trk_refpoint_x.clear(); trk_refpoint_y.clear(); trk_refpoint_z.clear(); trk_nChi2.clear(); trk_nChi2_1Dmod.clear(); trk_ndof.clear(); for (auto& mva : trk_mvas) { mva.clear(); } for (auto& mask : trk_qualityMasks) { mask.clear(); } trk_q.clear(); trk_nValid.clear(); trk_nLost.clear(); trk_nInactive.clear(); trk_nPixel.clear(); trk_nStrip.clear(); trk_nOuterLost.clear(); trk_nInnerLost.clear(); trk_nOuterInactive.clear(); trk_nInnerInactive.clear(); trk_nPixelLay.clear(); trk_nStripLay.clear(); trk_n3DLay.clear(); trk_nLostLay.clear(); trk_nCluster.clear(); trk_algo.clear(); trk_originalAlgo.clear(); trk_algoMask.clear(); trk_stopReason.clear(); trk_isHP.clear(); trk_seedIdx.clear(); trk_vtxIdx.clear(); trk_isTrue.clear(); trk_bestSimTrkIdx.clear(); trk_bestSimTrkShareFrac.clear(); trk_bestSimTrkShareFracSimDenom.clear(); trk_bestSimTrkShareFracSimClusterDenom.clear(); trk_bestSimTrkNChi2.clear(); trk_bestFromFirstHitSimTrkIdx.clear(); trk_bestFromFirstHitSimTrkShareFrac.clear(); trk_bestFromFirstHitSimTrkShareFracSimDenom.clear(); trk_bestFromFirstHitSimTrkShareFracSimClusterDenom.clear(); trk_bestFromFirstHitSimTrkNChi2.clear(); trk_simTrkIdx.clear(); trk_simTrkShareFrac.clear(); trk_simTrkNChi2.clear(); trk_hitIdx.clear(); trk_hitType.clear(); //track candidates tcand_pca_valid.clear(); tcand_pca_px.clear(); tcand_pca_py.clear(); tcand_pca_pz.clear(); tcand_pca_pt.clear(); tcand_pca_eta.clear(); tcand_pca_phi.clear(); tcand_pca_dxy.clear(); tcand_pca_dz.clear(); tcand_pca_ptErr.clear(); tcand_pca_etaErr.clear(); tcand_pca_lambdaErr.clear(); tcand_pca_phiErr.clear(); tcand_pca_dxyErr.clear(); tcand_pca_dzErr.clear(); tcand_px.clear(); tcand_py.clear(); tcand_pz.clear(); tcand_pt.clear(); tcand_x.clear(); tcand_y.clear(); tcand_z.clear(); tcand_qbpErr.clear(); tcand_lambdaErr.clear(); tcand_phiErr.clear(); tcand_xtErr.clear(); tcand_ytErr.clear(); tcand_ndof.clear(); tcand_q.clear(); tcand_nValid.clear(); tcand_nPixel.clear(); tcand_nStrip.clear(); tcand_nCluster.clear(); tcand_algo.clear(); tcand_stopReason.clear(); tcand_seedIdx.clear(); tcand_vtxIdx.clear(); tcand_isTrue.clear(); tcand_bestSimTrkIdx.clear(); tcand_bestSimTrkShareFrac.clear(); tcand_bestSimTrkShareFracSimDenom.clear(); tcand_bestSimTrkShareFracSimClusterDenom.clear(); tcand_bestSimTrkNChi2.clear(); tcand_bestFromFirstHitSimTrkIdx.clear(); tcand_bestFromFirstHitSimTrkShareFrac.clear(); tcand_bestFromFirstHitSimTrkShareFracSimDenom.clear(); tcand_bestFromFirstHitSimTrkShareFracSimClusterDenom.clear(); tcand_bestFromFirstHitSimTrkNChi2.clear(); tcand_simTrkShareFrac.clear(); tcand_simTrkNChi2.clear(); tcand_simTrkIdx.clear(); tcand_hitIdx.clear(); tcand_hitType.clear(); //sim tracks sim_event.clear(); sim_bunchCrossing.clear(); sim_pdgId.clear(); sim_genPdgIds.clear(); sim_isFromBHadron.clear(); sim_px.clear(); sim_py.clear(); sim_pz.clear(); sim_pt.clear(); sim_eta.clear(); sim_phi.clear(); sim_pca_pt.clear(); sim_pca_eta.clear(); sim_pca_lambda.clear(); sim_pca_cotTheta.clear(); sim_pca_phi.clear(); sim_pca_dxy.clear(); sim_pca_dz.clear(); sim_q.clear(); sim_nValid.clear(); sim_nPixel.clear(); sim_nStrip.clear(); sim_nLay.clear(); sim_nPixelLay.clear(); sim_n3DLay.clear(); sim_nTrackerHits.clear(); sim_nRecoClusters.clear(); sim_trkIdx.clear(); sim_seedIdx.clear(); sim_trkShareFrac.clear(); sim_parentVtxIdx.clear(); sim_decayVtxIdx.clear(); sim_simHitIdx.clear(); //pixels pix_isBarrel.clear(); pix_detId.clear(); pix_trkIdx.clear(); pix_onTrk_x.clear(); pix_onTrk_y.clear(); pix_onTrk_z.clear(); pix_onTrk_xx.clear(); pix_onTrk_xy.clear(); pix_onTrk_yy.clear(); pix_onTrk_yz.clear(); pix_onTrk_zz.clear(); pix_onTrk_zx.clear(); pix_tcandIdx.clear(); pix_seeIdx.clear(); pix_simHitIdx.clear(); pix_xySignificance.clear(); pix_chargeFraction.clear(); pix_simType.clear(); pix_x.clear(); pix_y.clear(); pix_z.clear(); pix_xx.clear(); pix_xy.clear(); pix_yy.clear(); pix_yz.clear(); pix_zz.clear(); pix_zx.clear(); pix_radL.clear(); pix_bbxi.clear(); pix_clustSizeCol.clear(); pix_clustSizeRow.clear(); pix_usedMask.clear(); //strips str_isBarrel.clear(); str_detId.clear(); str_trkIdx.clear(); str_onTrk_x.clear(); str_onTrk_y.clear(); str_onTrk_z.clear(); str_onTrk_xx.clear(); str_onTrk_xy.clear(); str_onTrk_yy.clear(); str_onTrk_yz.clear(); str_onTrk_zz.clear(); str_onTrk_zx.clear(); str_tcandIdx.clear(); str_seeIdx.clear(); str_simHitIdx.clear(); str_xySignificance.clear(); str_chargeFraction.clear(); str_simType.clear(); str_x.clear(); str_y.clear(); str_z.clear(); str_xx.clear(); str_xy.clear(); str_yy.clear(); str_yz.clear(); str_zz.clear(); str_zx.clear(); str_radL.clear(); str_bbxi.clear(); str_chargePerCM.clear(); str_clustSize.clear(); str_usedMask.clear(); //matched hits glu_isBarrel.clear(); glu_detId.clear(); glu_monoIdx.clear(); glu_stereoIdx.clear(); glu_seeIdx.clear(); glu_x.clear(); glu_y.clear(); glu_z.clear(); glu_xx.clear(); glu_xy.clear(); glu_yy.clear(); glu_yz.clear(); glu_zz.clear(); glu_zx.clear(); glu_radL.clear(); glu_bbxi.clear(); glu_chargePerCM.clear(); glu_clustSizeMono.clear(); glu_clustSizeStereo.clear(); glu_usedMaskMono.clear(); glu_usedMaskStereo.clear(); //phase2 OT ph2_isBarrel.clear(); ph2_detId.clear(); ph2_trkIdx.clear(); ph2_onTrk_x.clear(); ph2_onTrk_y.clear(); ph2_onTrk_z.clear(); ph2_onTrk_xx.clear(); ph2_onTrk_xy.clear(); ph2_onTrk_yy.clear(); ph2_onTrk_yz.clear(); ph2_onTrk_zz.clear(); ph2_onTrk_zx.clear(); ph2_tcandIdx.clear(); ph2_seeIdx.clear(); ph2_xySignificance.clear(); ph2_simHitIdx.clear(); ph2_simType.clear(); ph2_x.clear(); ph2_y.clear(); ph2_z.clear(); ph2_xx.clear(); ph2_xy.clear(); ph2_yy.clear(); ph2_yz.clear(); ph2_zz.clear(); ph2_zx.clear(); ph2_radL.clear(); ph2_bbxi.clear(); ph2_usedMask.clear(); ph2_clustSize.clear(); //invalid hits inv_isBarrel.clear(); inv_detId.clear(); inv_detId_phase2.clear(); inv_type.clear(); // simhits simhit_detId.clear(); simhit_detId_phase2.clear(); simhit_x.clear(); simhit_y.clear(); simhit_z.clear(); simhit_px.clear(); simhit_py.clear(); simhit_pz.clear(); simhit_particle.clear(); simhit_process.clear(); simhit_eloss.clear(); simhit_tof.clear(); //simhit_simTrackId.clear(); simhit_simTrkIdx.clear(); simhit_hitIdx.clear(); simhit_hitType.clear(); //beamspot bsp_x = -9999.; bsp_y = -9999.; bsp_z = -9999.; bsp_sigmax = -9999.; bsp_sigmay = -9999.; bsp_sigmaz = -9999.; //seeds see_fitok.clear(); see_px.clear(); see_py.clear(); see_pz.clear(); see_pt.clear(); see_eta.clear(); see_phi.clear(); see_dxy.clear(); see_dz.clear(); see_ptErr.clear(); see_etaErr.clear(); see_phiErr.clear(); see_dxyErr.clear(); see_dzErr.clear(); see_chi2.clear(); see_statePt.clear(); see_stateTrajX.clear(); see_stateTrajY.clear(); see_stateTrajPx.clear(); see_stateTrajPy.clear(); see_stateTrajPz.clear(); see_stateTrajGlbX.clear(); see_stateTrajGlbY.clear(); see_stateTrajGlbZ.clear(); see_stateTrajGlbPx.clear(); see_stateTrajGlbPy.clear(); see_stateTrajGlbPz.clear(); see_stateCurvCov.clear(); see_q.clear(); see_nValid.clear(); see_nPixel.clear(); see_nGlued.clear(); see_nStrip.clear(); see_nPhase2OT.clear(); see_nCluster.clear(); see_algo.clear(); see_stopReason.clear(); see_nCands.clear(); see_nTrk.clear(); see_nTCand.clear(); see_trkIdx.clear(); see_tcandIdx.clear(); see_isTrue.clear(); see_bestSimTrkIdx.clear(); see_bestSimTrkShareFrac.clear(); see_bestFromFirstHitSimTrkIdx.clear(); see_bestFromFirstHitSimTrkShareFrac.clear(); see_simTrkIdx.clear(); see_simTrkShareFrac.clear(); see_hitIdx.clear(); see_hitType.clear(); //seed algo offset see_offset.clear(); // vertices vtx_x.clear(); vtx_y.clear(); vtx_z.clear(); vtx_xErr.clear(); vtx_yErr.clear(); vtx_zErr.clear(); vtx_ndof.clear(); vtx_chi2.clear(); vtx_fake.clear(); vtx_valid.clear(); vtx_trkIdx.clear(); // Tracking vertices simvtx_event.clear(); simvtx_bunchCrossing.clear(); simvtx_processType.clear(); simvtx_x.clear(); simvtx_y.clear(); simvtx_z.clear(); simvtx_sourceSimIdx.clear(); simvtx_daughterSimIdx.clear(); simpv_idx.clear(); sim_genjet_deltaEta.clear(); sim_genjet_deltaPhi.clear(); sim_genjet_deltaR.clear(); sim_genjet_idx.clear(); // GenJets genjet_pt.clear(); genjet_eta.clear(); genjet_phi.clear(); genjet_invisible_energy.clear(); genjet_auxiliary_energy.clear(); } // ------------ method called for each event ------------ void TrackingNtuple::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) { using namespace edm; using namespace reco; using namespace std; const auto& mf = iSetup.getData(mfToken_); const TrackerTopology& tTopo = iSetup.getData(tTopoToken_); const TrackerGeometry& tracker = iSetup.getData(tGeomToken_); edm::Handle<reco::TrackToTrackingParticleAssociator> theAssociator; iEvent.getByToken(trackAssociatorToken_, theAssociator); const reco::TrackToTrackingParticleAssociator& associatorByHits = *theAssociator; LogDebug("TrackingNtuple") << "Analyzing new event"; //initialize tree variables clearVariables(); // FIXME: we really need to move to edm::View for reading the // TrackingParticles... Unfortunately it has non-trivial // consequences on the associator/association interfaces etc. TrackingParticleRefVector tmpTP; const TrackingParticleRefVector* tmpTPptr = nullptr; edm::Handle<TrackingParticleCollection> TPCollectionH; edm::Handle<TrackingParticleRefVector> TPCollectionHRefVector; if (!trackingParticleToken_.isUninitialized()) { iEvent.getByToken(trackingParticleToken_, TPCollectionH); for (size_t i = 0, size = TPCollectionH->size(); i < size; ++i) { tmpTP.push_back(TrackingParticleRef(TPCollectionH, i)); } tmpTPptr = &tmpTP; } else { iEvent.getByToken(trackingParticleRefToken_, TPCollectionHRefVector); tmpTPptr = TPCollectionHRefVector.product(); } const TrackingParticleRefVector& tpCollection = *tmpTPptr; // Fill mapping from Ref::key() to index TrackingParticleRefKeyToIndex tpKeyToIndex; for (size_t i = 0; i < tpCollection.size(); ++i) { tpKeyToIndex[tpCollection[i].key()] = i; } // tracking vertices edm::Handle<TrackingVertexCollection> htv; iEvent.getByToken(trackingVertexToken_, htv); const TrackingVertexCollection& tvs = *htv; // Fill mapping from Ref::key() to index TrackingVertexRefVector tvRefs; TrackingVertexRefKeyToIndex tvKeyToIndex; for (size_t i = 0; i < tvs.size(); ++i) { const TrackingVertex& v = tvs[i]; if (!includeOOT_ && v.eventId().bunchCrossing() != 0) // Ignore OOTPU continue; tvKeyToIndex[i] = tvRefs.size(); tvRefs.push_back(TrackingVertexRef(htv, i)); } //get association maps, etc. Handle<ClusterTPAssociation> pCluster2TPListH; iEvent.getByToken(clusterTPMapToken_, pCluster2TPListH); const ClusterTPAssociation& clusterToTPMap = *pCluster2TPListH; edm::Handle<SimHitTPAssociationProducer::SimHitTPAssociationList> simHitsTPAssoc; iEvent.getByToken(simHitTPMapToken_, simHitsTPAssoc); // TP -> cluster count TrackingParticleRefKeyToCount tpKeyToClusterCount; for (const auto& clusterTP : clusterToTPMap) { tpKeyToClusterCount[clusterTP.second.key()] += 1; } // SimHit key -> index mapping SimHitRefKeyToIndex simHitRefKeyToIndex; //make a list to link TrackingParticles to its simhits std::vector<TPHitIndex> tpHitList; // Count the number of reco cluster per TP std::set<edm::ProductID> hitProductIds; std::map<edm::ProductID, size_t> seedCollToOffset; ev_run = iEvent.id().run(); ev_lumi = iEvent.id().luminosityBlock(); ev_event = iEvent.id().event(); // Digi->Sim links for pixels and strips edm::Handle<edm::DetSetVector<PixelDigiSimLink>> pixelDigiSimLinksHandle; iEvent.getByToken(pixelSimLinkToken_, pixelDigiSimLinksHandle); const auto& pixelDigiSimLinks = *pixelDigiSimLinksHandle; edm::Handle<edm::DetSetVector<StripDigiSimLink>> stripDigiSimLinksHandle; iEvent.getByToken(stripSimLinkToken_, stripDigiSimLinksHandle); // Phase2 OT DigiSimLink edm::Handle<edm::DetSetVector<PixelDigiSimLink>> siphase2OTSimLinksHandle; iEvent.getByToken(siphase2OTSimLinksToken_, siphase2OTSimLinksHandle); //beamspot Handle<reco::BeamSpot> recoBeamSpotHandle; iEvent.getByToken(beamSpotToken_, recoBeamSpotHandle); BeamSpot const& bs = *recoBeamSpotHandle; fillBeamSpot(bs); //prapare list to link matched hits to collection vector<pair<int, int>> monoStereoClusterList; if (includeAllHits_) { // simhits, only if TPs are saved as well if (includeTrackingParticles_) { fillSimHits(tracker, tpKeyToIndex, *simHitsTPAssoc, tTopo, simHitRefKeyToIndex, tpHitList); } //pixel hits fillPixelHits(iEvent, tracker, clusterToTPMap, tpKeyToIndex, *simHitsTPAssoc, pixelDigiSimLinks, tTopo, simHitRefKeyToIndex, hitProductIds); //strip hits if (includeStripHits_) { LogDebug("TrackingNtuple") << "foundStripSimLink"; const auto& stripDigiSimLinks = *stripDigiSimLinksHandle; fillStripRphiStereoHits(iEvent, tracker, clusterToTPMap, tpKeyToIndex, *simHitsTPAssoc, stripDigiSimLinks, tTopo, simHitRefKeyToIndex, hitProductIds); //matched hits fillStripMatchedHits(iEvent, tracker, tTopo, monoStereoClusterList); } if (includePhase2OTHits_) { LogDebug("TrackingNtuple") << "foundPhase2OTSimLinks"; const auto& phase2OTSimLinks = *siphase2OTSimLinksHandle; fillPhase2OTHits(iEvent, clusterToTPMap, tracker, tpKeyToIndex, *simHitsTPAssoc, phase2OTSimLinks, tTopo, simHitRefKeyToIndex, hitProductIds); } } //seeds if (includeSeeds_) { fillSeeds(iEvent, tpCollection, tpKeyToIndex, bs, tracker, associatorByHits, clusterToTPMap, mf, tTopo, monoStereoClusterList, hitProductIds, seedCollToOffset); } //tracks edm::Handle<edm::View<reco::Track>> tracksHandle; iEvent.getByToken(trackToken_, tracksHandle); const edm::View<reco::Track>& tracks = *tracksHandle; // The associator interfaces really need to be fixed... edm::RefToBaseVector<reco::Track> trackRefs; for (edm::View<Track>::size_type i = 0; i < tracks.size(); ++i) { trackRefs.push_back(tracks.refAt(i)); } std::vector<const MVACollection*> mvaColls; std::vector<const QualityMaskCollection*> qualColls; if (includeMVA_) { edm::Handle<MVACollection> hmva; edm::Handle<QualityMaskCollection> hqual; for (const auto& tokenTpl : mvaQualityCollectionTokens_) { iEvent.getByToken(std::get<0>(tokenTpl), hmva); iEvent.getByToken(std::get<1>(tokenTpl), hqual); mvaColls.push_back(hmva.product()); qualColls.push_back(hqual.product()); if (mvaColls.back()->size() != tracks.size()) { throw cms::Exception("Configuration") << "Inconsistency in track collection and MVA sizes. Track collection has " << tracks.size() << " tracks, whereas the MVA " << (mvaColls.size() - 1) << " has " << mvaColls.back()->size() << " entries. Double-check your configuration."; } if (qualColls.back()->size() != tracks.size()) { throw cms::Exception("Configuration") << "Inconsistency in track collection and quality mask sizes. Track collection has " << tracks.size() << " tracks, whereas the quality mask " << (qualColls.size() - 1) << " has " << qualColls.back()->size() << " entries. Double-check your configuration."; } } } edm::Handle<reco::VertexCollection> vertices; iEvent.getByToken(vertexToken_, vertices); fillTracks(trackRefs, tracker, tpCollection, tpKeyToIndex, tpKeyToClusterCount, mf, bs, *vertices, associatorByHits, clusterToTPMap, tTopo, hitProductIds, seedCollToOffset, mvaColls, qualColls); if (includeTrackCandidates_) { //candidates for (auto const& token : candidateTokens_) { auto const tCandsHandle = iEvent.getHandle(token); edm::EDConsumerBase::Labels labels; labelsForToken(token, labels); TString label = labels.module; label.ReplaceAll("TrackCandidates", ""); label.ReplaceAll("muonSeeded", "muonSeededStep"); int algo = reco::TrackBase::algoByName(label.Data()); fillCandidates(tCandsHandle, algo, tpCollection, tpKeyToIndex, tpKeyToClusterCount, mf, bs, *vertices, associatorByHits, clusterToTPMap, tracker, tTopo, hitProductIds, seedCollToOffset); } } //tracking particles //sort association maps with simHits std::sort(tpHitList.begin(), tpHitList.end(), tpHitIndexListLessSort); fillTrackingParticles( iEvent, iSetup, trackRefs, bs, tpCollection, tvKeyToIndex, associatorByHits, tpHitList, tpKeyToClusterCount); // vertices fillVertices(*vertices, trackRefs); // tracking vertices fillTrackingVertices(tvRefs, tpKeyToIndex); // GenJets fillGenJets(iEvent, tpCollection); t->Fill(); } void TrackingNtuple::fillGenJets(const edm::Event& iEvent, const TrackingParticleRefVector& tpCollection) { auto const& genJets = iEvent.get(tok_jets_); for (auto const& jet : genJets) { genjet_pt.push_back(jet.pt()); genjet_eta.push_back(jet.eta()); genjet_phi.push_back(jet.phi()); genjet_invisible_energy.push_back(jet.invisibleEnergy()); genjet_auxiliary_energy.push_back(jet.auxiliaryEnergy()); } for (const TrackingParticleRef& tp : tpCollection) { float sim_eta = tp->eta(); float sim_phi = tp->phi(); float best_dR2 = std::numeric_limits<float>::max(); float best_dEta = 0.f, best_dPhi = 0.f; int best_jet_idx = -1; for (size_t i = 0; i < genJets.size(); ++i) { const auto& jet = genJets[i]; const float dEta = sim_eta - jet.eta(); const float dPhi = reco::deltaPhi(sim_phi, jet.phi()); const float dR2 = reco::deltaR2(sim_eta, sim_phi, jet.eta(), jet.phi()); if (dR2 < best_dR2) { best_dR2 = dR2; best_dEta = dEta; best_dPhi = dPhi; best_jet_idx = i; } } sim_genjet_deltaEta.push_back(best_dEta); sim_genjet_deltaPhi.push_back(best_dPhi); sim_genjet_deltaR.push_back(std::sqrt(best_dR2)); sim_genjet_idx.push_back(best_jet_idx); } } void TrackingNtuple::fillBeamSpot(const reco::BeamSpot& bs) { bsp_x = bs.x0(); bsp_y = bs.y0(); bsp_z = bs.x0(); bsp_sigmax = bs.BeamWidthX(); bsp_sigmay = bs.BeamWidthY(); bsp_sigmaz = bs.sigmaZ(); } namespace { template <typename SimLink> struct GetCluster; template <> struct GetCluster<PixelDigiSimLink> { static const SiPixelCluster& call(const OmniClusterRef& cluster) { return cluster.pixelCluster(); } }; template <> struct GetCluster<StripDigiSimLink> { static const SiStripCluster& call(const OmniClusterRef& cluster) { return cluster.stripCluster(); } }; } // namespace template <typename SimLink> TrackingNtuple::SimHitData TrackingNtuple::matchCluster( const OmniClusterRef& cluster, DetId hitId, int clusterKey, const TrackingRecHit& hit, const ClusterTPAssociation& clusterToTPMap, const TrackingParticleRefKeyToIndex& tpKeyToIndex, const SimHitTPAssociationProducer::SimHitTPAssociationList& simHitsTPAssoc, const edm::DetSetVector<SimLink>& digiSimLinks, const SimHitRefKeyToIndex& simHitRefKeyToIndex, HitType hitType) { SimHitData ret; std::map<unsigned int, double> simTrackIdToChargeFraction; if (hitType == HitType::Phase2OT) simTrackIdToChargeFraction = chargeFraction(cluster.phase2OTCluster(), hitId, digiSimLinks); else simTrackIdToChargeFraction = chargeFraction(GetCluster<SimLink>::call(cluster), hitId, digiSimLinks); float h_x = 0, h_y = 0; float h_xx = 0, h_xy = 0, h_yy = 0; if (simHitBySignificance_) { h_x = hit.localPosition().x(); h_y = hit.localPosition().y(); h_xx = hit.localPositionError().xx(); h_xy = hit.localPositionError().xy(); h_yy = hit.localPositionError().yy(); } ret.type = HitSimType::Noise; auto range = clusterToTPMap.equal_range(cluster); if (range.first != range.second) { for (auto ip = range.first; ip != range.second; ++ip) { const TrackingParticleRef& trackingParticle = ip->second; // Find out if the cluster is from signal/ITPU/OOTPU const auto event = trackingParticle->eventId().event(); const auto bx = trackingParticle->eventId().bunchCrossing(); HitSimType type = HitSimType::OOTPileup; if (bx == 0) { type = (event == 0 ? HitSimType::Signal : HitSimType::ITPileup); } else type = HitSimType::OOTPileup; ret.type = static_cast<HitSimType>(std::min(static_cast<int>(ret.type), static_cast<int>(type))); // Limit to only input TrackingParticles (usually signal+ITPU) auto tpIndex = tpKeyToIndex.find(trackingParticle.key()); if (tpIndex == tpKeyToIndex.end()) continue; //now get the corresponding sim hit std::pair<TrackingParticleRef, TrackPSimHitRef> simHitTPpairWithDummyTP(trackingParticle, TrackPSimHitRef()); //SimHit is dummy: for simHitTPAssociationListGreater sorting only the TP is needed auto range = std::equal_range(simHitsTPAssoc.begin(), simHitsTPAssoc.end(), simHitTPpairWithDummyTP, SimHitTPAssociationProducer::simHitTPAssociationListGreater); bool foundSimHit = false; bool foundElectron = false; int foundNonElectrons = 0; for (auto ip = range.first; ip != range.second; ++ip) { TrackPSimHitRef TPhit = ip->second; DetId dId = DetId(TPhit->detUnitId()); if (dId.rawId() == hitId.rawId()) { // skip electron SimHits for non-electron TPs also here if (std::abs(TPhit->particleType()) == 11 && std::abs(trackingParticle->pdgId()) != 11) { continue; //electrons found } else { foundNonElectrons++; } } } float minSignificance = 1e12; if (simHitBySignificance_) { //save the best matching hit int simHitKey = -1; edm::ProductID simHitID; for (auto ip = range.first; ip != range.second; ++ip) { TrackPSimHitRef TPhit = ip->second; DetId dId = DetId(TPhit->detUnitId()); if (dId.rawId() == hitId.rawId()) { // skip electron SimHits for non-electron TPs also here if (std::abs(TPhit->particleType()) == 11 && std::abs(trackingParticle->pdgId()) != 11) { foundElectron = true; if (!keepEleSimHits_) continue; } float sx = TPhit->localPosition().x(); float sy = TPhit->localPosition().y(); float dx = sx - h_x; float dy = sy - h_y; float sig = (dx * dx * h_yy - 2 * dx * dy * h_xy + dy * dy * h_xx) / (h_xx * h_yy - h_xy * h_xy); if (sig < minSignificance) { minSignificance = sig; foundSimHit = true; simHitKey = TPhit.key(); simHitID = TPhit.id(); } } } //loop over matching hits auto simHitIndex = simHitRefKeyToIndex.at(std::make_pair(simHitKey, simHitID)); ret.matchingSimHit.push_back(simHitIndex); double chargeFraction = 0.; for (const SimTrack& simtrk : trackingParticle->g4Tracks()) { auto found = simTrackIdToChargeFraction.find(simtrk.trackId()); if (found != simTrackIdToChargeFraction.end()) { chargeFraction += found->second; } } ret.xySignificance.push_back(minSignificance); ret.chargeFraction.push_back(chargeFraction); // only for debug prints ret.bunchCrossing.push_back(bx); ret.event.push_back(event); simhit_hitIdx[simHitIndex].push_back(clusterKey); simhit_hitType[simHitIndex].push_back(static_cast<int>(hitType)); } else { //save all matching hits for (auto ip = range.first; ip != range.second; ++ip) { TrackPSimHitRef TPhit = ip->second; DetId dId = DetId(TPhit->detUnitId()); if (dId.rawId() == hitId.rawId()) { // skip electron SimHits for non-electron TPs also here if (std::abs(TPhit->particleType()) == 11 && std::abs(trackingParticle->pdgId()) != 11) { foundElectron = true; if (!keepEleSimHits_) continue; if (foundNonElectrons > 0) continue; //prioritize: skip electrons if non-electrons are present } foundSimHit = true; auto simHitKey = TPhit.key(); auto simHitID = TPhit.id(); auto simHitIndex = simHitRefKeyToIndex.at(std::make_pair(simHitKey, simHitID)); ret.matchingSimHit.push_back(simHitIndex); double chargeFraction = 0.; for (const SimTrack& simtrk : trackingParticle->g4Tracks()) { auto found = simTrackIdToChargeFraction.find(simtrk.trackId()); if (found != simTrackIdToChargeFraction.end()) { chargeFraction += found->second; } } ret.xySignificance.push_back(minSignificance); ret.chargeFraction.push_back(chargeFraction); // only for debug prints ret.bunchCrossing.push_back(bx); ret.event.push_back(event); simhit_hitIdx[simHitIndex].push_back(clusterKey); simhit_hitType[simHitIndex].push_back(static_cast<int>(hitType)); } } } //if/else simHitBySignificance_ if (!foundSimHit) { // In case we didn't find a simhit because of filtered-out // electron SimHit, just ignore the missing SimHit. if (foundElectron && !keepEleSimHits_) continue; auto ex = cms::Exception("LogicError") << "Did not find SimHit for reco hit DetId " << hitId.rawId() << " for TP " << trackingParticle.key() << " bx:event " << bx << ":" << event << " PDGid " << trackingParticle->pdgId() << " q " << trackingParticle->charge() << " p4 " << trackingParticle->p4() << " nG4 " << trackingParticle->g4Tracks().size() << ".\nFound SimHits from detectors "; for (auto ip = range.first; ip != range.second; ++ip) { TrackPSimHitRef TPhit = ip->second; DetId dId = DetId(TPhit->detUnitId()); ex << dId.rawId() << " "; } if (trackingParticle->eventId().event() != 0) { ex << "\nSince this is a TrackingParticle from pileup, check that you're running the pileup mixing in " "playback mode."; } throw ex; } } } return ret; } void TrackingNtuple::fillSimHits(const TrackerGeometry& tracker, const TrackingParticleRefKeyToIndex& tpKeyToIndex, const SimHitTPAssociationProducer::SimHitTPAssociationList& simHitsTPAssoc, const TrackerTopology& tTopo, SimHitRefKeyToIndex& simHitRefKeyToIndex, std::vector<TPHitIndex>& tpHitList) { for (const auto& assoc : simHitsTPAssoc) { auto tpKey = assoc.first.key(); // SimHitTPAssociationList can contain more TrackingParticles than // what are given to this EDAnalyzer, so we can filter those out here. auto found = tpKeyToIndex.find(tpKey); if (found == tpKeyToIndex.end()) continue; const auto tpIndex = found->second; // skip non-tracker simhits (mostly muons) const auto& simhit = *(assoc.second); auto detId = DetId(simhit.detUnitId()); if (detId.det() != DetId::Tracker) continue; // Skip electron SimHits for non-electron TrackingParticles to // filter out delta rays. The delta ray hits just confuse. If we // need them later, let's add them as a separate "collection" of // hits of a TP const TrackingParticle& tp = *(assoc.first); if (!keepEleSimHits_ && std::abs(simhit.particleType()) == 11 && std::abs(tp.pdgId()) != 11) continue; auto simHitKey = std::make_pair(assoc.second.key(), assoc.second.id()); if (simHitRefKeyToIndex.find(simHitKey) != simHitRefKeyToIndex.end()) { for (const auto& assoc2 : simHitsTPAssoc) { if (std::make_pair(assoc2.second.key(), assoc2.second.id()) == simHitKey) { #ifdef EDM_ML_DEBUG auto range1 = std::equal_range(simHitsTPAssoc.begin(), simHitsTPAssoc.end(), std::make_pair(assoc.first, TrackPSimHitRef()), SimHitTPAssociationProducer::simHitTPAssociationListGreater); auto range2 = std::equal_range(simHitsTPAssoc.begin(), simHitsTPAssoc.end(), std::make_pair(assoc2.first, TrackPSimHitRef()), SimHitTPAssociationProducer::simHitTPAssociationListGreater); LogTrace("TrackingNtuple") << "Earlier TP " << assoc2.first.key() << " SimTrack Ids"; for (const auto& simTrack : assoc2.first->g4Tracks()) { edm::LogPrint("TrackingNtuple") << " SimTrack " << simTrack.trackId() << " BX:event " << simTrack.eventId().bunchCrossing() << ":" << simTrack.eventId().event(); } for (auto iHit = range2.first; iHit != range2.second; ++iHit) { LogTrace("TrackingNtuple") << " SimHit " << iHit->second.key() << " " << iHit->second.id() << " tof " << iHit->second->tof() << " trackId " << iHit->second->trackId() << " BX:event " << iHit->second->eventId().bunchCrossing() << ":" << iHit->second->eventId().event(); } LogTrace("TrackingNtuple") << "Current TP " << assoc.first.key() << " SimTrack Ids"; for (const auto& simTrack : assoc.first->g4Tracks()) { edm::LogPrint("TrackingNtuple") << " SimTrack " << simTrack.trackId() << " BX:event " << simTrack.eventId().bunchCrossing() << ":" << simTrack.eventId().event(); } for (auto iHit = range1.first; iHit != range1.second; ++iHit) { LogTrace("TrackingNtuple") << " SimHit " << iHit->second.key() << " " << iHit->second.id() << " tof " << iHit->second->tof() << " trackId " << iHit->second->trackId() << " BX:event " << iHit->second->eventId().bunchCrossing() << ":" << iHit->second->eventId().event(); } #endif throw cms::Exception("LogicError") << "Got second time the SimHit " << simHitKey.first << " of " << simHitKey.second << ", first time with TrackingParticle " << assoc2.first.key() << ", now with " << tpKey; } } throw cms::Exception("LogicError") << "Got second time the SimHit " << simHitKey.first << " of " << simHitKey.second << ", now with TrackingParticle " << tpKey << ", but I didn't find the first occurrance!"; } auto det = tracker.idToDetUnit(detId); if (!det) throw cms::Exception("LogicError") << "Did not find a det unit for DetId " << simhit.detUnitId() << " from tracker geometry"; const auto pos = det->surface().toGlobal(simhit.localPosition()); const float tof = simhit.timeOfFlight(); const auto simHitIndex = simhit_x.size(); simHitRefKeyToIndex[simHitKey] = simHitIndex; if (includeStripHits_) simhit_detId.push_back(tracker, tTopo, detId); else simhit_detId_phase2.push_back(tracker, tTopo, detId); simhit_x.push_back(pos.x()); simhit_y.push_back(pos.y()); simhit_z.push_back(pos.z()); if (saveSimHitsP3_) { const auto mom = det->surface().toGlobal(simhit.momentumAtEntry()); simhit_px.push_back(mom.x()); simhit_py.push_back(mom.y()); simhit_pz.push_back(mom.z()); } simhit_particle.push_back(simhit.particleType()); simhit_process.push_back(simhit.processType()); simhit_eloss.push_back(simhit.energyLoss()); simhit_tof.push_back(tof); //simhit_simTrackId.push_back(simhit.trackId()); simhit_simTrkIdx.push_back(tpIndex); simhit_hitIdx.emplace_back(); // filled in matchCluster simhit_hitType.emplace_back(); // filled in matchCluster tpHitList.emplace_back(tpKey, simHitIndex, tof, simhit.detUnitId()); } } void TrackingNtuple::fillPixelHits(const edm::Event& iEvent, const TrackerGeometry& tracker, const ClusterTPAssociation& clusterToTPMap, const TrackingParticleRefKeyToIndex& tpKeyToIndex, const SimHitTPAssociationProducer::SimHitTPAssociationList& simHitsTPAssoc, const edm::DetSetVector<PixelDigiSimLink>& digiSimLink, const TrackerTopology& tTopo, const SimHitRefKeyToIndex& simHitRefKeyToIndex, std::set<edm::ProductID>& hitProductIds) { std::vector<std::pair<uint64_t, PixelMaskContainer const*>> pixelMasks; pixelMasks.reserve(pixelUseMaskTokens_.size()); for (const auto& itoken : pixelUseMaskTokens_) { edm::Handle<PixelMaskContainer> aH; iEvent.getByToken(itoken.second, aH); pixelMasks.emplace_back(1 << itoken.first, aH.product()); } auto pixUsedMask = [&pixelMasks](size_t key) { uint64_t mask = 0; for (auto const& m : pixelMasks) { if (m.second->mask(key)) mask |= m.first; } return mask; }; edm::Handle<SiPixelRecHitCollection> pixelHits; iEvent.getByToken(pixelRecHitToken_, pixelHits); for (auto it = pixelHits->begin(); it != pixelHits->end(); it++) { const DetId hitId = it->detId(); for (auto hit = it->begin(); hit != it->end(); hit++) { hitProductIds.insert(hit->cluster().id()); const int key = hit->cluster().key(); const int lay = tTopo.layer(hitId); pix_isBarrel.push_back(hitId.subdetId() == 1); pix_detId.push_back(tracker, tTopo, hitId); pix_trkIdx.emplace_back(); // filled in fillTracks pix_onTrk_x.emplace_back(); pix_onTrk_y.emplace_back(); pix_onTrk_z.emplace_back(); pix_onTrk_xx.emplace_back(); pix_onTrk_xy.emplace_back(); pix_onTrk_yy.emplace_back(); pix_onTrk_yz.emplace_back(); pix_onTrk_zz.emplace_back(); pix_onTrk_zx.emplace_back(); pix_tcandIdx.emplace_back(); // filled in fillCandidates pix_seeIdx.emplace_back(); // filled in fillSeeds pix_x.push_back(hit->globalPosition().x()); pix_y.push_back(hit->globalPosition().y()); pix_z.push_back(hit->globalPosition().z()); pix_xx.push_back(hit->globalPositionError().cxx()); pix_xy.push_back(hit->globalPositionError().cyx()); pix_yy.push_back(hit->globalPositionError().cyy()); pix_yz.push_back(hit->globalPositionError().czy()); pix_zz.push_back(hit->globalPositionError().czz()); pix_zx.push_back(hit->globalPositionError().czx()); pix_radL.push_back(hit->surface()->mediumProperties().radLen()); pix_bbxi.push_back(hit->surface()->mediumProperties().xi()); pix_clustSizeCol.push_back(hit->cluster()->sizeY()); pix_clustSizeRow.push_back(hit->cluster()->sizeX()); pix_usedMask.push_back(pixUsedMask(hit->firstClusterRef().key())); LogTrace("TrackingNtuple") << "pixHit cluster=" << key << " subdId=" << hitId.subdetId() << " lay=" << lay << " rawId=" << hitId.rawId() << " pos =" << hit->globalPosition(); if (includeTrackingParticles_) { SimHitData simHitData = matchCluster(hit->firstClusterRef(), hitId, key, *hit, clusterToTPMap, tpKeyToIndex, simHitsTPAssoc, digiSimLink, simHitRefKeyToIndex, HitType::Pixel); pix_simHitIdx.push_back(simHitData.matchingSimHit); pix_simType.push_back(static_cast<int>(simHitData.type)); pix_xySignificance.push_back(simHitData.xySignificance); pix_chargeFraction.push_back(simHitData.chargeFraction); LogTrace("TrackingNtuple") << " nMatchingSimHit=" << simHitData.matchingSimHit.size(); if (!simHitData.matchingSimHit.empty()) { const auto simHitIdx = simHitData.matchingSimHit[0]; LogTrace("TrackingNtuple") << " firstMatchingSimHit=" << simHitIdx << " simHitPos=" << GlobalPoint(simhit_x[simHitIdx], simhit_y[simHitIdx], simhit_z[simHitIdx]) << " energyLoss=" << simhit_eloss[simHitIdx] << " particleType=" << simhit_particle[simHitIdx] << " processType=" << simhit_process[simHitIdx] << " bunchCrossing=" << simHitData.bunchCrossing[0] << " event=" << simHitData.event[0]; } } } } } void TrackingNtuple::fillStripRphiStereoHits(const edm::Event& iEvent, const TrackerGeometry& tracker, const ClusterTPAssociation& clusterToTPMap, const TrackingParticleRefKeyToIndex& tpKeyToIndex, const SimHitTPAssociationProducer::SimHitTPAssociationList& simHitsTPAssoc, const edm::DetSetVector<StripDigiSimLink>& digiSimLink, const TrackerTopology& tTopo, const SimHitRefKeyToIndex& simHitRefKeyToIndex, std::set<edm::ProductID>& hitProductIds) { std::vector<std::pair<uint64_t, StripMaskContainer const*>> stripMasks; stripMasks.reserve(stripUseMaskTokens_.size()); for (const auto& itoken : stripUseMaskTokens_) { edm::Handle<StripMaskContainer> aH; iEvent.getByToken(itoken.second, aH); stripMasks.emplace_back(1 << itoken.first, aH.product()); } auto strUsedMask = [&stripMasks](size_t key) { uint64_t mask = 0; for (auto const& m : stripMasks) { if (m.second->mask(key)) mask |= m.first; } return mask; }; //index strip hit branches by cluster index edm::Handle<SiStripRecHit2DCollection> rphiHits; iEvent.getByToken(stripRphiRecHitToken_, rphiHits); edm::Handle<SiStripRecHit2DCollection> stereoHits; iEvent.getByToken(stripStereoRecHitToken_, stereoHits); int totalStripHits = rphiHits->dataSize() + stereoHits->dataSize(); str_isBarrel.resize(totalStripHits); str_detId.resize(totalStripHits); str_trkIdx.resize(totalStripHits); // filled in fillTracks str_onTrk_x.resize(totalStripHits); str_onTrk_y.resize(totalStripHits); str_onTrk_z.resize(totalStripHits); str_onTrk_xx.resize(totalStripHits); str_onTrk_xy.resize(totalStripHits); str_onTrk_yy.resize(totalStripHits); str_onTrk_yz.resize(totalStripHits); str_onTrk_zz.resize(totalStripHits); str_onTrk_zx.resize(totalStripHits); str_tcandIdx.resize(totalStripHits); // filled in fillCandidates str_seeIdx.resize(totalStripHits); // filled in fillSeeds str_simHitIdx.resize(totalStripHits); str_simType.resize(totalStripHits); str_chargeFraction.resize(totalStripHits); str_x.resize(totalStripHits); str_y.resize(totalStripHits); str_z.resize(totalStripHits); str_xx.resize(totalStripHits); str_xy.resize(totalStripHits); str_yy.resize(totalStripHits); str_yz.resize(totalStripHits); str_zz.resize(totalStripHits); str_zx.resize(totalStripHits); str_xySignificance.resize(totalStripHits); str_chargeFraction.resize(totalStripHits); str_radL.resize(totalStripHits); str_bbxi.resize(totalStripHits); str_chargePerCM.resize(totalStripHits); str_clustSize.resize(totalStripHits); str_usedMask.resize(totalStripHits); auto fill = [&](const SiStripRecHit2DCollection& hits, const char* name) { for (const auto& detset : hits) { const DetId hitId = detset.detId(); for (const auto& hit : detset) { hitProductIds.insert(hit.cluster().id()); const int key = hit.cluster().key(); const int lay = tTopo.layer(hitId); str_isBarrel[key] = (hitId.subdetId() == StripSubdetector::TIB || hitId.subdetId() == StripSubdetector::TOB); str_detId.set(key, tracker, tTopo, hitId); str_x[key] = hit.globalPosition().x(); str_y[key] = hit.globalPosition().y(); str_z[key] = hit.globalPosition().z(); str_xx[key] = hit.globalPositionError().cxx(); str_xy[key] = hit.globalPositionError().cyx(); str_yy[key] = hit.globalPositionError().cyy(); str_yz[key] = hit.globalPositionError().czy(); str_zz[key] = hit.globalPositionError().czz(); str_zx[key] = hit.globalPositionError().czx(); str_radL[key] = hit.surface()->mediumProperties().radLen(); str_bbxi[key] = hit.surface()->mediumProperties().xi(); str_chargePerCM[key] = siStripClusterTools::chargePerCM(hitId, hit.firstClusterRef().stripCluster()); str_clustSize[key] = hit.cluster()->amplitudes().size(); str_usedMask[key] = strUsedMask(key); LogTrace("TrackingNtuple") << name << " cluster=" << key << " subdId=" << hitId.subdetId() << " lay=" << lay << " rawId=" << hitId.rawId() << " pos =" << hit.globalPosition(); if (includeTrackingParticles_) { SimHitData simHitData = matchCluster(hit.firstClusterRef(), hitId, key, hit, clusterToTPMap, tpKeyToIndex, simHitsTPAssoc, digiSimLink, simHitRefKeyToIndex, HitType::Strip); str_simHitIdx[key] = simHitData.matchingSimHit; str_simType[key] = static_cast<int>(simHitData.type); str_xySignificance[key] = simHitData.xySignificance; str_chargeFraction[key] = simHitData.chargeFraction; LogTrace("TrackingNtuple") << " nMatchingSimHit=" << simHitData.matchingSimHit.size(); if (!simHitData.matchingSimHit.empty()) { const auto simHitIdx = simHitData.matchingSimHit[0]; LogTrace("TrackingNtuple") << " firstMatchingSimHit=" << simHitIdx << " simHitPos=" << GlobalPoint(simhit_x[simHitIdx], simhit_y[simHitIdx], simhit_z[simHitIdx]) << " simHitPos=" << GlobalPoint(simhit_x[simHitIdx], simhit_y[simHitIdx], simhit_z[simHitIdx]) << " energyLoss=" << simhit_eloss[simHitIdx] << " particleType=" << simhit_particle[simHitIdx] << " processType=" << simhit_process[simHitIdx] << " bunchCrossing=" << simHitData.bunchCrossing[0] << " event=" << simHitData.event[0]; } } } } }; fill(*rphiHits, "stripRPhiHit"); fill(*stereoHits, "stripStereoHit"); } size_t TrackingNtuple::addStripMatchedHit(const SiStripMatchedRecHit2D& hit, const TrackerGeometry& tracker, const TrackerTopology& tTopo, const std::vector<std::pair<uint64_t, StripMaskContainer const*>>& stripMasks, std::vector<std::pair<int, int>>& monoStereoClusterList) { auto strUsedMask = [&stripMasks](size_t key) { uint64_t mask = 0; for (auto const& m : stripMasks) { if (m.second->mask(key)) mask |= m.first; } return mask; }; const auto hitId = hit.geographicalId(); const int lay = tTopo.layer(hitId); monoStereoClusterList.emplace_back(hit.monoHit().cluster().key(), hit.stereoHit().cluster().key()); glu_isBarrel.push_back((hitId.subdetId() == StripSubdetector::TIB || hitId.subdetId() == StripSubdetector::TOB)); glu_detId.push_back(tracker, tTopo, hitId); glu_monoIdx.push_back(hit.monoHit().cluster().key()); glu_stereoIdx.push_back(hit.stereoHit().cluster().key()); glu_seeIdx.emplace_back(); // filled in fillSeeds glu_x.push_back(hit.globalPosition().x()); glu_y.push_back(hit.globalPosition().y()); glu_z.push_back(hit.globalPosition().z()); glu_xx.push_back(hit.globalPositionError().cxx()); glu_xy.push_back(hit.globalPositionError().cyx()); glu_yy.push_back(hit.globalPositionError().cyy()); glu_yz.push_back(hit.globalPositionError().czy()); glu_zz.push_back(hit.globalPositionError().czz()); glu_zx.push_back(hit.globalPositionError().czx()); glu_radL.push_back(hit.surface()->mediumProperties().radLen()); glu_bbxi.push_back(hit.surface()->mediumProperties().xi()); glu_chargePerCM.push_back(siStripClusterTools::chargePerCM(hitId, hit.firstClusterRef().stripCluster())); glu_clustSizeMono.push_back(hit.monoHit().cluster()->amplitudes().size()); glu_clustSizeStereo.push_back(hit.stereoHit().cluster()->amplitudes().size()); glu_usedMaskMono.push_back(strUsedMask(hit.monoHit().cluster().key())); glu_usedMaskStereo.push_back(strUsedMask(hit.stereoHit().cluster().key())); LogTrace("TrackingNtuple") << "stripMatchedHit" << " cluster0=" << hit.stereoHit().cluster().key() << " cluster1=" << hit.monoHit().cluster().key() << " subdId=" << hitId.subdetId() << " lay=" << lay << " rawId=" << hitId.rawId() << " pos =" << hit.globalPosition(); return glu_isBarrel.size() - 1; } void TrackingNtuple::fillStripMatchedHits(const edm::Event& iEvent, const TrackerGeometry& tracker, const TrackerTopology& tTopo, std::vector<std::pair<int, int>>& monoStereoClusterList) { std::vector<std::pair<uint64_t, StripMaskContainer const*>> stripMasks; stripMasks.reserve(stripUseMaskTokens_.size()); for (const auto& itoken : stripUseMaskTokens_) { edm::Handle<StripMaskContainer> aH; iEvent.getByToken(itoken.second, aH); stripMasks.emplace_back(1 << itoken.first, aH.product()); } edm::Handle<SiStripMatchedRecHit2DCollection> matchedHits; iEvent.getByToken(stripMatchedRecHitToken_, matchedHits); for (auto it = matchedHits->begin(); it != matchedHits->end(); it++) { for (auto hit = it->begin(); hit != it->end(); hit++) { addStripMatchedHit(*hit, tracker, tTopo, stripMasks, monoStereoClusterList); } } } void TrackingNtuple::fillPhase2OTHits(const edm::Event& iEvent, const ClusterTPAssociation& clusterToTPMap, const TrackerGeometry& tracker, const TrackingParticleRefKeyToIndex& tpKeyToIndex, const SimHitTPAssociationProducer::SimHitTPAssociationList& simHitsTPAssoc, const edm::DetSetVector<PixelDigiSimLink>& digiSimLink, const TrackerTopology& tTopo, const SimHitRefKeyToIndex& simHitRefKeyToIndex, std::set<edm::ProductID>& hitProductIds) { std::vector<std::pair<uint64_t, Phase2OTMaskContainer const*>> phase2OTMasks; phase2OTMasks.reserve(ph2OTUseMaskTokens_.size()); for (const auto& itoken : ph2OTUseMaskTokens_) { edm::Handle<Phase2OTMaskContainer> aH; iEvent.getByToken(itoken.second, aH); phase2OTMasks.emplace_back(1 << itoken.first, aH.product()); } auto ph2OTUsedMask = [&phase2OTMasks](size_t key) { uint64_t mask = 0; for (auto const& m : phase2OTMasks) { if (m.second->mask(key)) mask |= m.first; } return mask; }; edm::Handle<Phase2TrackerRecHit1DCollectionNew> phase2OTHits; iEvent.getByToken(phase2OTRecHitToken_, phase2OTHits); for (auto it = phase2OTHits->begin(); it != phase2OTHits->end(); it++) { const DetId hitId = it->detId(); for (auto hit = it->begin(); hit != it->end(); hit++) { hitProductIds.insert(hit->cluster().id()); const int key = hit->cluster().key(); const int lay = tTopo.layer(hitId); ph2_isBarrel.push_back(hitId.subdetId() == 1); ph2_detId.push_back(tracker, tTopo, hitId); ph2_trkIdx.emplace_back(); // filled in fillTracks ph2_onTrk_x.emplace_back(); ph2_onTrk_y.emplace_back(); ph2_onTrk_z.emplace_back(); ph2_onTrk_xx.emplace_back(); ph2_onTrk_xy.emplace_back(); ph2_onTrk_yy.emplace_back(); ph2_onTrk_yz.emplace_back(); ph2_onTrk_zz.emplace_back(); ph2_onTrk_zx.emplace_back(); ph2_tcandIdx.emplace_back(); // filled in fillCandidates ph2_seeIdx.emplace_back(); // filled in fillSeeds ph2_x.push_back(hit->globalPosition().x()); ph2_y.push_back(hit->globalPosition().y()); ph2_z.push_back(hit->globalPosition().z()); ph2_xx.push_back(hit->globalPositionError().cxx()); ph2_xy.push_back(hit->globalPositionError().cyx()); ph2_yy.push_back(hit->globalPositionError().cyy()); ph2_yz.push_back(hit->globalPositionError().czy()); ph2_zz.push_back(hit->globalPositionError().czz()); ph2_zx.push_back(hit->globalPositionError().czx()); ph2_radL.push_back(hit->surface()->mediumProperties().radLen()); ph2_bbxi.push_back(hit->surface()->mediumProperties().xi()); ph2_usedMask.push_back(ph2OTUsedMask(hit->firstClusterRef().key())); ph2_clustSize.push_back(hit->cluster()->size()); LogTrace("TrackingNtuple") << "phase2 OT cluster=" << key << " subdId=" << hitId.subdetId() << " lay=" << lay << " rawId=" << hitId.rawId() << " pos =" << hit->globalPosition(); if (includeTrackingParticles_) { SimHitData simHitData = matchCluster(hit->firstClusterRef(), hitId, key, *hit, clusterToTPMap, tpKeyToIndex, simHitsTPAssoc, digiSimLink, simHitRefKeyToIndex, HitType::Phase2OT); ph2_xySignificance.push_back(simHitData.xySignificance); ph2_simHitIdx.push_back(simHitData.matchingSimHit); ph2_simType.push_back(static_cast<int>(simHitData.type)); LogTrace("TrackingNtuple") << " nMatchingSimHit=" << simHitData.matchingSimHit.size(); if (!simHitData.matchingSimHit.empty()) { const auto simHitIdx = simHitData.matchingSimHit[0]; LogTrace("TrackingNtuple") << " firstMatchingSimHit=" << simHitIdx << " simHitPos=" << GlobalPoint(simhit_x[simHitIdx], simhit_y[simHitIdx], simhit_z[simHitIdx]) << " energyLoss=" << simhit_eloss[simHitIdx] << " particleType=" << simhit_particle[simHitIdx] << " processType=" << simhit_process[simHitIdx] << " bunchCrossing=" << simHitData.bunchCrossing[0] << " event=" << simHitData.event[0]; } } } } } void TrackingNtuple::fillSeeds(const edm::Event& iEvent, const TrackingParticleRefVector& tpCollection, const TrackingParticleRefKeyToIndex& tpKeyToIndex, const reco::BeamSpot& bs, const TrackerGeometry& tracker, const reco::TrackToTrackingParticleAssociator& associatorByHits, const ClusterTPAssociation& clusterToTPMap, const MagneticField& theMF, const TrackerTopology& tTopo, std::vector<std::pair<int, int>>& monoStereoClusterList, const std::set<edm::ProductID>& hitProductIds, std::map<edm::ProductID, size_t>& seedCollToOffset) { TSCBLBuilderNoMaterial tscblBuilder; for (size_t iColl = 0; iColl < seedTokens_.size(); ++iColl) { const auto& seedToken = seedTokens_[iColl]; const auto algo = seedAlgos_[iColl]; edm::Handle<edm::View<reco::Track>> seedTracksHandle; iEvent.getByToken(seedToken, seedTracksHandle); const auto& seedTracks = *seedTracksHandle; if (seedTracks.empty()) continue; edm::EDConsumerBase::Labels labels; labelsForToken(seedToken, labels); const auto& seedStopInfoToken = seedStopInfoTokens_[iColl]; edm::Handle<std::vector<SeedStopInfo>> seedStopInfoHandle; iEvent.getByToken(seedStopInfoToken, seedStopInfoHandle); const auto& seedStopInfos = *seedStopInfoHandle; if (seedTracks.size() != seedStopInfos.size()) { edm::EDConsumerBase::Labels labels2; labelsForToken(seedStopInfoToken, labels2); throw cms::Exception("LogicError") << "Got " << seedTracks.size() << " seeds, but " << seedStopInfos.size() << " seed stopping infos for collections " << labels.module << ", " << labels2.module; } std::vector<std::pair<uint64_t, StripMaskContainer const*>> stripMasks; stripMasks.reserve(stripUseMaskTokens_.size()); for (const auto& itoken : stripUseMaskTokens_) { edm::Handle<StripMaskContainer> aH; iEvent.getByToken(itoken.second, aH); stripMasks.emplace_back(1 << itoken.first, aH.product()); } // The associator interfaces really need to be fixed... edm::RefToBaseVector<reco::Track> seedTrackRefs; for (edm::View<reco::Track>::size_type i = 0; i < seedTracks.size(); ++i) { seedTrackRefs.push_back(seedTracks.refAt(i)); } reco::RecoToSimCollection recSimColl = associatorByHits.associateRecoToSim(seedTrackRefs, tpCollection); reco::SimToRecoCollection simRecColl = associatorByHits.associateSimToReco(seedTrackRefs, tpCollection); edm::ProductID id = seedTracks[0].seedRef().id(); const auto offset = see_fitok.size(); auto inserted = seedCollToOffset.emplace(id, offset); if (!inserted.second) throw cms::Exception("Configuration") << "Trying to add seeds with ProductID " << id << " for a second time from collection " << labels.module << ", seed algo " << algo << ". Typically this is caused by a configuration problem."; see_offset.push_back(offset); LogTrace("TrackingNtuple") << "NEW SEED LABEL: for " << labels.module << " size: " << seedTracks.size() << " algo=" << algo << " ProductID " << id; for (size_t iSeed = 0; iSeed < seedTrackRefs.size(); ++iSeed) { const auto& seedTrackRef = seedTrackRefs[iSeed]; const auto& seedTrack = *seedTrackRef; const auto& seedRef = seedTrack.seedRef(); const auto& seed = *seedRef; const auto seedStopInfo = seedStopInfos[iSeed]; if (seedRef.id() != id) throw cms::Exception("LogicError") << "All tracks in 'TracksFromSeeds' collection should point to seeds in the same collection. Now the " "element 0 had ProductID " << id << " while the element " << seedTrackRef.key() << " had " << seedTrackRef.id() << ". The source collection is " << labels.module << "."; std::vector<int> tpIdx; std::vector<float> sharedFraction; auto foundTPs = recSimColl.find(seedTrackRef); if (foundTPs != recSimColl.end()) { for (const auto& tpQuality : foundTPs->val) { tpIdx.push_back(tpKeyToIndex.at(tpQuality.first.key())); sharedFraction.push_back(tpQuality.second); } } // Search for a best-matching TrackingParticle for a seed const int nHits = seedTrack.numberOfValidHits(); const auto clusters = track_associator::hitsToClusterRefs( seedTrack.recHitsBegin(), seedTrack.recHitsEnd()); // TODO: this function is called 3 times per track, try to reduce const int nClusters = clusters.size(); const auto bestKeyCount = findBestMatchingTrackingParticle(seedTrack.recHits(), clusterToTPMap, tpKeyToIndex); const float bestShareFrac = nClusters > 0 ? static_cast<float>(bestKeyCount.countClusters) / static_cast<float>(nClusters) : 0; // Another way starting from the first hit of the seed const auto bestFirstHitKeyCount = findMatchingTrackingParticleFromFirstHit(seedTrack.recHits(), clusterToTPMap, tpKeyToIndex); const float bestFirstHitShareFrac = nClusters > 0 ? static_cast<float>(bestFirstHitKeyCount.countClusters) / static_cast<float>(nClusters) : 0; const bool seedFitOk = !trackFromSeedFitFailed(seedTrack); const int charge = seedTrack.charge(); const float pt = seedFitOk ? seedTrack.pt() : 0; const float eta = seedFitOk ? seedTrack.eta() : 0; const float phi = seedFitOk ? seedTrack.phi() : 0; const auto seedIndex = see_fitok.size(); see_fitok.push_back(seedFitOk); see_px.push_back(seedFitOk ? seedTrack.px() : 0); see_py.push_back(seedFitOk ? seedTrack.py() : 0); see_pz.push_back(seedFitOk ? seedTrack.pz() : 0); see_pt.push_back(pt); see_eta.push_back(eta); see_phi.push_back(phi); see_q.push_back(charge); see_nValid.push_back(nHits); see_dxy.push_back(seedFitOk ? seedTrack.dxy(bs.position()) : 0); see_dz.push_back(seedFitOk ? seedTrack.dz(bs.position()) : 0); see_ptErr.push_back(seedFitOk ? seedTrack.ptError() : 0); see_etaErr.push_back(seedFitOk ? seedTrack.etaError() : 0); see_phiErr.push_back(seedFitOk ? seedTrack.phiError() : 0); see_dxyErr.push_back(seedFitOk ? seedTrack.dxyError() : 0); see_dzErr.push_back(seedFitOk ? seedTrack.dzError() : 0); see_algo.push_back(algo); see_stopReason.push_back(seedStopInfo.stopReasonUC()); see_nCands.push_back(seedStopInfo.candidatesPerSeed()); const auto& state = seedTrack.seedRef()->startingState(); const auto& pos = state.parameters().position(); const auto& mom = state.parameters().momentum(); see_statePt.push_back(state.pt()); see_stateTrajX.push_back(pos.x()); see_stateTrajY.push_back(pos.y()); see_stateTrajPx.push_back(mom.x()); see_stateTrajPy.push_back(mom.y()); see_stateTrajPz.push_back(mom.z()); ///the following is useful for analysis in global coords at seed hit surface const TrackingRecHit* lastRecHit = &*(seed.recHits().end() - 1); TrajectoryStateOnSurface tsos = trajectoryStateTransform::transientState(seed.startingState(), lastRecHit->surface(), &theMF); auto const& stateGlobal = tsos.globalParameters(); see_stateTrajGlbX.push_back(stateGlobal.position().x()); see_stateTrajGlbY.push_back(stateGlobal.position().y()); see_stateTrajGlbZ.push_back(stateGlobal.position().z()); see_stateTrajGlbPx.push_back(stateGlobal.momentum().x()); see_stateTrajGlbPy.push_back(stateGlobal.momentum().y()); see_stateTrajGlbPz.push_back(stateGlobal.momentum().z()); if (charge == 0) // replace with seed state if the track failed see_q.back() = stateGlobal.charge(); if (addSeedCurvCov_) { auto const& stateCcov = tsos.curvilinearError().matrix(); std::vector<float> cov(15); auto covP = cov.begin(); for (auto const val : stateCcov) *(covP++) = val; //row-major see_stateCurvCov.push_back(std::move(cov)); } // to be set correctly in fillTracks see_nTrk.push_back(0); see_nTCand.push_back(0); see_trkIdx.push_back({}); see_tcandIdx.push_back({}); if (includeTrackingParticles_) { see_simTrkIdx.push_back(tpIdx); see_simTrkShareFrac.push_back(sharedFraction); see_bestSimTrkIdx.push_back(bestKeyCount.key >= 0 ? tpKeyToIndex.at(bestKeyCount.key) : -1); see_bestFromFirstHitSimTrkIdx.push_back( bestFirstHitKeyCount.key >= 0 ? tpKeyToIndex.at(bestFirstHitKeyCount.key) : -1); } else { see_isTrue.push_back(!tpIdx.empty()); } see_bestSimTrkShareFrac.push_back(bestShareFrac); see_bestFromFirstHitSimTrkShareFrac.push_back(bestFirstHitShareFrac); /// Hmm, the following could make sense instead of plain failing if propagation to beam line fails /* const TrackingRecHit* lastRecHit = &*(seed.recHits().second-1); TrajectoryStateOnSurface state = trajectoryStateTransform::transientState( itSeed->startingState(), lastRecHit->surface(), &theMF); float pt = state.globalParameters().momentum().perp(); float eta = state.globalParameters().momentum().eta(); float phi = state.globalParameters().momentum().phi(); see_px .push_back( state.globalParameters().momentum().x() ); see_py .push_back( state.globalParameters().momentum().y() ); see_pz .push_back( state.globalParameters().momentum().z() ); */ std::vector<int> hitIdx; std::vector<int> hitType; for (auto const& hit : seed.recHits()) { int subid = hit.geographicalId().subdetId(); if (subid == (int)PixelSubdetector::PixelBarrel || subid == (int)PixelSubdetector::PixelEndcap) { const BaseTrackerRecHit* bhit = dynamic_cast<const BaseTrackerRecHit*>(&hit); const auto& clusterRef = bhit->firstClusterRef(); const auto clusterKey = clusterRef.cluster_pixel().key(); if (includeAllHits_) { checkProductID(hitProductIds, clusterRef.id(), "seed"); pix_seeIdx[clusterKey].push_back(seedIndex); } hitIdx.push_back(clusterKey); hitType.push_back(static_cast<int>(HitType::Pixel)); } else if (subid == (int)StripSubdetector::TOB || subid == (int)StripSubdetector::TID || subid == (int)StripSubdetector::TIB || subid == (int)StripSubdetector::TEC) { if (trackerHitRTTI::isMatched(hit)) { const SiStripMatchedRecHit2D* matchedHit = dynamic_cast<const SiStripMatchedRecHit2D*>(&hit); if (includeAllHits_) { checkProductID(hitProductIds, matchedHit->monoClusterRef().id(), "seed"); checkProductID(hitProductIds, matchedHit->stereoClusterRef().id(), "seed"); } int monoIdx = matchedHit->monoClusterRef().key(); int stereoIdx = matchedHit->stereoClusterRef().key(); std::vector<std::pair<int, int>>::iterator pos = find(monoStereoClusterList.begin(), monoStereoClusterList.end(), std::make_pair(monoIdx, stereoIdx)); size_t gluedIndex = -1; if (pos != monoStereoClusterList.end()) { gluedIndex = std::distance(monoStereoClusterList.begin(), pos); } else { // We can encounter glued hits not in the input // SiStripMatchedRecHit2DCollection, e.g. via muon // outside-in seeds (or anything taking hits from // MeasurementTrackerEvent). So let's add them here. gluedIndex = addStripMatchedHit(*matchedHit, tracker, tTopo, stripMasks, monoStereoClusterList); } if (includeAllHits_) glu_seeIdx[gluedIndex].push_back(seedIndex); hitIdx.push_back(gluedIndex); hitType.push_back(static_cast<int>(HitType::Glued)); } else { const BaseTrackerRecHit* bhit = dynamic_cast<const BaseTrackerRecHit*>(&hit); const auto& clusterRef = bhit->firstClusterRef(); unsigned int clusterKey; if (clusterRef.isPhase2()) { clusterKey = clusterRef.cluster_phase2OT().key(); } else { clusterKey = clusterRef.cluster_strip().key(); } if (includeAllHits_) { checkProductID(hitProductIds, clusterRef.id(), "seed"); if (clusterRef.isPhase2()) { ph2_seeIdx[clusterKey].push_back(seedIndex); } else { str_seeIdx[clusterKey].push_back(seedIndex); } } hitIdx.push_back(clusterKey); if (clusterRef.isPhase2()) { hitType.push_back(static_cast<int>(HitType::Phase2OT)); } else { hitType.push_back(static_cast<int>(HitType::Strip)); } } } else { LogTrace("TrackingNtuple") << " not pixel and not Strip detector"; } } see_hitIdx.push_back(hitIdx); see_hitType.push_back(hitType); see_nPixel.push_back(std::count(hitType.begin(), hitType.end(), static_cast<int>(HitType::Pixel))); see_nGlued.push_back(std::count(hitType.begin(), hitType.end(), static_cast<int>(HitType::Glued))); see_nStrip.push_back(std::count(hitType.begin(), hitType.end(), static_cast<int>(HitType::Strip))); see_nPhase2OT.push_back(std::count(hitType.begin(), hitType.end(), static_cast<int>(HitType::Phase2OT))); see_nCluster.push_back(nClusters); //the part below is not strictly needed float chi2 = -1; if (nHits == 2) { auto const recHit0 = seed.recHits().begin(); auto const recHit1 = seed.recHits().begin() + 1; std::vector<GlobalPoint> gp(2); std::vector<GlobalError> ge(2); gp[0] = recHit0->globalPosition(); ge[0] = recHit0->globalPositionError(); gp[1] = recHit1->globalPosition(); ge[1] = recHit1->globalPositionError(); LogTrace("TrackingNtuple") << "seed " << seedTrackRef.key() << " pt=" << pt << " eta=" << eta << " phi=" << phi << " q=" << charge << " - PAIR - ids: " << recHit0->geographicalId().rawId() << " " << recHit1->geographicalId().rawId() << " hitpos: " << gp[0] << " " << gp[1] << " trans0: " << (recHit0->transientHits().size() > 1 ? recHit0->transientHits()[0]->globalPosition() : GlobalPoint(0, 0, 0)) << " " << (recHit0->transientHits().size() > 1 ? recHit0->transientHits()[1]->globalPosition() : GlobalPoint(0, 0, 0)) << " trans1: " << (recHit1->transientHits().size() > 1 ? recHit1->transientHits()[0]->globalPosition() : GlobalPoint(0, 0, 0)) << " " << (recHit1->transientHits().size() > 1 ? recHit1->transientHits()[1]->globalPosition() : GlobalPoint(0, 0, 0)) << " eta,phi: " << gp[0].eta() << "," << gp[0].phi(); } else if (nHits == 3) { auto const recHit0 = seed.recHits().begin(); auto const recHit1 = seed.recHits().begin() + 1; auto const recHit2 = seed.recHits().begin() + 2; declareDynArray(GlobalPoint, 4, gp); declareDynArray(GlobalError, 4, ge); declareDynArray(bool, 4, bl); gp[0] = recHit0->globalPosition(); ge[0] = recHit0->globalPositionError(); int subid0 = recHit0->geographicalId().subdetId(); bl[0] = (subid0 == StripSubdetector::TIB || subid0 == StripSubdetector::TOB || subid0 == (int)PixelSubdetector::PixelBarrel); gp[1] = recHit1->globalPosition(); ge[1] = recHit1->globalPositionError(); int subid1 = recHit1->geographicalId().subdetId(); bl[1] = (subid1 == StripSubdetector::TIB || subid1 == StripSubdetector::TOB || subid1 == (int)PixelSubdetector::PixelBarrel); gp[2] = recHit2->globalPosition(); ge[2] = recHit2->globalPositionError(); int subid2 = recHit2->geographicalId().subdetId(); bl[2] = (subid2 == StripSubdetector::TIB || subid2 == StripSubdetector::TOB || subid2 == (int)PixelSubdetector::PixelBarrel); RZLine rzLine(gp, ge, bl); float seed_chi2 = rzLine.chi2(); //float seed_pt = state.globalParameters().momentum().perp(); float seed_pt = pt; LogTrace("TrackingNtuple") << "seed " << seedTrackRef.key() << " pt=" << pt << " eta=" << eta << " phi=" << phi << " q=" << charge << " - TRIPLET - ids: " << recHit0->geographicalId().rawId() << " " << recHit1->geographicalId().rawId() << " " << recHit2->geographicalId().rawId() << " hitpos: " << gp[0] << " " << gp[1] << " " << gp[2] << " trans0: " << (recHit0->transientHits().size() > 1 ? recHit0->transientHits()[0]->globalPosition() : GlobalPoint(0, 0, 0)) << " " << (recHit0->transientHits().size() > 1 ? recHit0->transientHits()[1]->globalPosition() : GlobalPoint(0, 0, 0)) << " trans1: " << (recHit1->transientHits().size() > 1 ? recHit1->transientHits()[0]->globalPosition() : GlobalPoint(0, 0, 0)) << " " << (recHit1->transientHits().size() > 1 ? recHit1->transientHits()[1]->globalPosition() : GlobalPoint(0, 0, 0)) << " trans2: " << (recHit2->transientHits().size() > 1 ? recHit2->transientHits()[0]->globalPosition() : GlobalPoint(0, 0, 0)) << " " << (recHit2->transientHits().size() > 1 ? recHit2->transientHits()[1]->globalPosition() : GlobalPoint(0, 0, 0)) << " local: " << recHit2->localPosition() //<< " tsos pos, mom: " << state.globalPosition()<<" "<<state.globalMomentum() << " eta,phi: " << gp[0].eta() << "," << gp[0].phi() << " pt,chi2: " << seed_pt << "," << seed_chi2; chi2 = seed_chi2; } see_chi2.push_back(chi2); } fillTrackingParticlesForSeeds(tpCollection, simRecColl, tpKeyToIndex, offset); } } void TrackingNtuple::fillTracks(const edm::RefToBaseVector<reco::Track>& tracks, const TrackerGeometry& tracker, const TrackingParticleRefVector& tpCollection, const TrackingParticleRefKeyToIndex& tpKeyToIndex, const TrackingParticleRefKeyToCount& tpKeyToClusterCount, const MagneticField& mf, const reco::BeamSpot& bs, const reco::VertexCollection& vertices, const reco::TrackToTrackingParticleAssociator& associatorByHits, const ClusterTPAssociation& clusterToTPMap, const TrackerTopology& tTopo, const std::set<edm::ProductID>& hitProductIds, const std::map<edm::ProductID, size_t>& seedCollToOffset, const std::vector<const MVACollection*>& mvaColls, const std::vector<const QualityMaskCollection*>& qualColls) { reco::RecoToSimCollection recSimColl = associatorByHits.associateRecoToSim(tracks, tpCollection); edm::EDConsumerBase::Labels labels; labelsForToken(trackToken_, labels); LogTrace("TrackingNtuple") << "NEW TRACK LABEL: " << labels.module; auto pvPosition = vertices[0].position(); for (size_t iTrack = 0; iTrack < tracks.size(); ++iTrack) { const auto& itTrack = tracks[iTrack]; int charge = itTrack->charge(); float pt = itTrack->pt(); float eta = itTrack->eta(); const double lambda = itTrack->lambda(); float chi2 = itTrack->normalizedChi2(); float ndof = itTrack->ndof(); float phi = itTrack->phi(); int nHits = itTrack->numberOfValidHits(); const reco::HitPattern& hp = itTrack->hitPattern(); const auto& tkParam = itTrack->parameters(); auto tkCov = itTrack->covariance(); tkCov.Invert(); // Standard track-TP matching int nSimHits = 0; bool isSimMatched = false; std::vector<int> tpIdx; std::vector<float> sharedFraction; std::vector<float> tpChi2; auto foundTPs = recSimColl.find(itTrack); if (foundTPs != recSimColl.end()) { if (!foundTPs->val.empty()) { nSimHits = foundTPs->val[0].first->numberOfTrackerHits(); isSimMatched = true; } for (const auto& tpQuality : foundTPs->val) { tpIdx.push_back(tpKeyToIndex.at(tpQuality.first.key())); sharedFraction.push_back(tpQuality.second); tpChi2.push_back(track_associator::trackAssociationChi2(tkParam, tkCov, *(tpCollection[tpIdx.back()]), mf, bs)); } } // Search for a best-matching TrackingParticle for a track const auto clusters = track_associator::hitsToClusterRefs( itTrack->recHitsBegin(), itTrack->recHitsEnd()); // TODO: this function is called 3 times per track, try to reduce const int nClusters = clusters.size(); const auto bestKeyCount = findBestMatchingTrackingParticle(itTrack->recHits(), clusterToTPMap, tpKeyToIndex); const float bestShareFrac = static_cast<float>(bestKeyCount.countClusters) / static_cast<float>(nClusters); float bestShareFracSimDenom = 0; float bestShareFracSimClusterDenom = 0; float bestChi2 = -1; if (bestKeyCount.key >= 0) { bestShareFracSimDenom = static_cast<float>(bestKeyCount.countClusters) / static_cast<float>(tpCollection[tpKeyToIndex.at(bestKeyCount.key)]->numberOfTrackerHits()); bestShareFracSimClusterDenom = static_cast<float>(bestKeyCount.countClusters) / static_cast<float>(tpKeyToClusterCount.at(bestKeyCount.key)); bestChi2 = track_associator::trackAssociationChi2( tkParam, tkCov, *(tpCollection[tpKeyToIndex.at(bestKeyCount.key)]), mf, bs); } // Another way starting from the first hit of the track const auto bestFirstHitKeyCount = findMatchingTrackingParticleFromFirstHit(itTrack->recHits(), clusterToTPMap, tpKeyToIndex); const float bestFirstHitShareFrac = static_cast<float>(bestFirstHitKeyCount.countClusters) / static_cast<float>(nClusters); float bestFirstHitShareFracSimDenom = 0; float bestFirstHitShareFracSimClusterDenom = 0; float bestFirstHitChi2 = -1; if (bestFirstHitKeyCount.key >= 0) { bestFirstHitShareFracSimDenom = static_cast<float>(bestFirstHitKeyCount.countClusters) / static_cast<float>(tpCollection[tpKeyToIndex.at(bestFirstHitKeyCount.key)]->numberOfTrackerHits()); bestFirstHitShareFracSimClusterDenom = static_cast<float>(bestFirstHitKeyCount.countClusters) / static_cast<float>(tpKeyToClusterCount.at(bestFirstHitKeyCount.key)); bestFirstHitChi2 = track_associator::trackAssociationChi2( tkParam, tkCov, *(tpCollection[tpKeyToIndex.at(bestFirstHitKeyCount.key)]), mf, bs); } float chi2_1Dmod = chi2; int count1dhits = 0; for (auto iHit = itTrack->recHitsBegin(), iEnd = itTrack->recHitsEnd(); iHit != iEnd; ++iHit) { const TrackingRecHit& hit = **iHit; if (hit.isValid() && typeid(hit) == typeid(SiStripRecHit1D)) ++count1dhits; } if (count1dhits > 0) { chi2_1Dmod = (chi2 + count1dhits) / (ndof + count1dhits); } Point bestPV = getBestVertex(*itTrack, vertices); trk_px.push_back(itTrack->px()); trk_py.push_back(itTrack->py()); trk_pz.push_back(itTrack->pz()); trk_pt.push_back(pt); trk_inner_px.push_back(itTrack->innerMomentum().x()); trk_inner_py.push_back(itTrack->innerMomentum().y()); trk_inner_pz.push_back(itTrack->innerMomentum().z()); trk_inner_pt.push_back(itTrack->innerMomentum().rho()); trk_outer_px.push_back(itTrack->outerMomentum().x()); trk_outer_py.push_back(itTrack->outerMomentum().y()); trk_outer_pz.push_back(itTrack->outerMomentum().z()); trk_outer_pt.push_back(itTrack->outerMomentum().rho()); trk_eta.push_back(eta); trk_lambda.push_back(lambda); trk_cotTheta.push_back(1 / tan(M_PI * 0.5 - lambda)); trk_phi.push_back(phi); trk_dxy.push_back(itTrack->dxy(bs.position())); trk_dz.push_back(itTrack->dz(bs.position())); trk_dxyPV.push_back(itTrack->dxy(pvPosition)); trk_dzPV.push_back(itTrack->dz(pvPosition)); trk_dxyClosestPV.push_back(itTrack->dxy(bestPV)); trk_dzClosestPV.push_back(itTrack->dz(bestPV)); trk_ptErr.push_back(itTrack->ptError()); trk_etaErr.push_back(itTrack->etaError()); trk_lambdaErr.push_back(itTrack->lambdaError()); trk_phiErr.push_back(itTrack->phiError()); trk_dxyErr.push_back(itTrack->dxyError()); trk_dzErr.push_back(itTrack->dzError()); trk_refpoint_x.push_back(itTrack->vx()); trk_refpoint_y.push_back(itTrack->vy()); trk_refpoint_z.push_back(itTrack->vz()); trk_nChi2.push_back(chi2); trk_nChi2_1Dmod.push_back(chi2_1Dmod); trk_ndof.push_back(ndof); trk_q.push_back(charge); trk_nValid.push_back(hp.numberOfValidHits()); trk_nLost.push_back(hp.numberOfLostHits(reco::HitPattern::TRACK_HITS)); trk_nInactive.push_back(hp.trackerLayersTotallyOffOrBad(reco::HitPattern::TRACK_HITS)); trk_nPixel.push_back(hp.numberOfValidPixelHits()); trk_nStrip.push_back(hp.numberOfValidStripHits()); trk_nOuterLost.push_back(hp.numberOfLostTrackerHits(reco::HitPattern::MISSING_OUTER_HITS)); trk_nInnerLost.push_back(hp.numberOfLostTrackerHits(reco::HitPattern::MISSING_INNER_HITS)); trk_nOuterInactive.push_back(hp.trackerLayersTotallyOffOrBad(reco::HitPattern::MISSING_OUTER_HITS)); trk_nInnerInactive.push_back(hp.trackerLayersTotallyOffOrBad(reco::HitPattern::MISSING_INNER_HITS)); trk_nPixelLay.push_back(hp.pixelLayersWithMeasurement()); trk_nStripLay.push_back(hp.stripLayersWithMeasurement()); trk_n3DLay.push_back(hp.numberOfValidStripLayersWithMonoAndStereo() + hp.pixelLayersWithMeasurement()); trk_nLostLay.push_back(hp.trackerLayersWithoutMeasurement(reco::HitPattern::TRACK_HITS)); trk_nCluster.push_back(nClusters); trk_algo.push_back(itTrack->algo()); trk_originalAlgo.push_back(itTrack->originalAlgo()); trk_algoMask.push_back(itTrack->algoMaskUL()); trk_stopReason.push_back(itTrack->stopReason()); trk_isHP.push_back(itTrack->quality(reco::TrackBase::highPurity)); if (includeMVA_) { for (size_t i = 0; i < trk_mvas.size(); ++i) { trk_mvas[i].push_back((*(mvaColls[i]))[iTrack]); trk_qualityMasks[i].push_back((*(qualColls[i]))[iTrack]); } } if (includeSeeds_) { auto offset = seedCollToOffset.find(itTrack->seedRef().id()); if (offset == seedCollToOffset.end()) { throw cms::Exception("Configuration") << "Track algo '" << reco::TrackBase::algoName(itTrack->algo()) << "' originalAlgo '" << reco::TrackBase::algoName(itTrack->originalAlgo()) << "' refers to seed collection " << itTrack->seedRef().id() << ", but that seed collection is not given as an input. The following collections were given as an input " << make_ProductIDMapPrinter(seedCollToOffset); } const auto seedIndex = offset->second + itTrack->seedRef().key(); trk_seedIdx.push_back(seedIndex); if (seedUniqueCheck_ && see_nTrk[seedIndex] > 0) { throw cms::Exception("LogicError") << "Track index has already been set for seed " << seedIndex << " to " << see_trkIdx[seedIndex][0] << "; was trying to set it to " << iTrack; } see_nTrk[seedIndex]++; see_trkIdx[seedIndex].push_back(iTrack); } trk_vtxIdx.push_back(-1); // to be set correctly in fillVertices if (includeTrackingParticles_) { trk_simTrkIdx.push_back(tpIdx); trk_simTrkShareFrac.push_back(sharedFraction); trk_simTrkNChi2.push_back(tpChi2); trk_bestSimTrkIdx.push_back(bestKeyCount.key >= 0 ? tpKeyToIndex.at(bestKeyCount.key) : -1); trk_bestFromFirstHitSimTrkIdx.push_back(bestFirstHitKeyCount.key >= 0 ? tpKeyToIndex.at(bestFirstHitKeyCount.key) : -1); } else { trk_isTrue.push_back(!tpIdx.empty()); } trk_bestSimTrkShareFrac.push_back(bestShareFrac); trk_bestSimTrkShareFracSimDenom.push_back(bestShareFracSimDenom); trk_bestSimTrkShareFracSimClusterDenom.push_back(bestShareFracSimClusterDenom); trk_bestSimTrkNChi2.push_back(bestChi2); trk_bestFromFirstHitSimTrkShareFrac.push_back(bestFirstHitShareFrac); trk_bestFromFirstHitSimTrkShareFracSimDenom.push_back(bestFirstHitShareFracSimDenom); trk_bestFromFirstHitSimTrkShareFracSimClusterDenom.push_back(bestFirstHitShareFracSimClusterDenom); trk_bestFromFirstHitSimTrkNChi2.push_back(bestFirstHitChi2); LogTrace("TrackingNtuple") << "Track #" << itTrack.key() << " with q=" << charge << ", pT=" << pt << " GeV, eta: " << eta << ", phi: " << phi << ", chi2=" << chi2 << ", Nhits=" << nHits << ", algo=" << itTrack->algoName(itTrack->algo()).c_str() << " hp=" << itTrack->quality(reco::TrackBase::highPurity) << " seed#=" << itTrack->seedRef().key() << " simMatch=" << isSimMatched << " nSimHits=" << nSimHits << " sharedFraction=" << (sharedFraction.empty() ? -1 : sharedFraction[0]) << " tpIdx=" << (tpIdx.empty() ? -1 : tpIdx[0]); std::vector<int> hitIdx; std::vector<int> hitType; for (auto i = itTrack->recHitsBegin(); i != itTrack->recHitsEnd(); i++) { auto hit = *i; DetId hitId = hit->geographicalId(); LogTrace("TrackingNtuple") << "hit #" << std::distance(itTrack->recHitsBegin(), i) << " subdet=" << hitId.subdetId(); if (hitId.det() != DetId::Tracker) continue; LogTrace("TrackingNtuple") << " " << subdetstring(hitId.subdetId()) << " " << tTopo.layer(hitId); if (hit->isValid()) { //ugly... but works const BaseTrackerRecHit* bhit = dynamic_cast<const BaseTrackerRecHit*>(&*hit); const auto& clusterRef = bhit->firstClusterRef(); unsigned int clusterKey; if (clusterRef.isPixel()) { clusterKey = clusterRef.cluster_pixel().key(); } else if (clusterRef.isPhase2()) { clusterKey = clusterRef.cluster_phase2OT().key(); } else { clusterKey = clusterRef.cluster_strip().key(); } LogTrace("TrackingNtuple") << " id: " << hitId.rawId() << " - globalPos =" << hit->globalPosition() << " cluster=" << clusterKey << " clusterRef ID=" << clusterRef.id() << " eta,phi: " << hit->globalPosition().eta() << "," << hit->globalPosition().phi(); if (includeAllHits_) { checkProductID(hitProductIds, clusterRef.id(), "track"); if (clusterRef.isPixel()) { pix_trkIdx[clusterKey].push_back(iTrack); pix_onTrk_x[clusterKey].push_back(hit->globalPosition().x()); pix_onTrk_y[clusterKey].push_back(hit->globalPosition().y()); pix_onTrk_z[clusterKey].push_back(hit->globalPosition().z()); pix_onTrk_xx[clusterKey].push_back(hit->globalPositionError().cxx()); pix_onTrk_xy[clusterKey].push_back(hit->globalPositionError().cyx()); pix_onTrk_yy[clusterKey].push_back(hit->globalPositionError().cyy()); pix_onTrk_yz[clusterKey].push_back(hit->globalPositionError().czy()); pix_onTrk_zz[clusterKey].push_back(hit->globalPositionError().czz()); pix_onTrk_zx[clusterKey].push_back(hit->globalPositionError().czx()); } else if (clusterRef.isPhase2()) { ph2_trkIdx[clusterKey].push_back(iTrack); ph2_onTrk_x[clusterKey].push_back(hit->globalPosition().x()); ph2_onTrk_y[clusterKey].push_back(hit->globalPosition().y()); ph2_onTrk_z[clusterKey].push_back(hit->globalPosition().z()); ph2_onTrk_xx[clusterKey].push_back(hit->globalPositionError().cxx()); ph2_onTrk_xy[clusterKey].push_back(hit->globalPositionError().cyx()); ph2_onTrk_yy[clusterKey].push_back(hit->globalPositionError().cyy()); ph2_onTrk_yz[clusterKey].push_back(hit->globalPositionError().czy()); ph2_onTrk_zz[clusterKey].push_back(hit->globalPositionError().czz()); ph2_onTrk_zx[clusterKey].push_back(hit->globalPositionError().czx()); } else { str_trkIdx[clusterKey].push_back(iTrack); str_onTrk_x[clusterKey].push_back(hit->globalPosition().x()); str_onTrk_y[clusterKey].push_back(hit->globalPosition().y()); str_onTrk_z[clusterKey].push_back(hit->globalPosition().z()); str_onTrk_xx[clusterKey].push_back(hit->globalPositionError().cxx()); str_onTrk_xy[clusterKey].push_back(hit->globalPositionError().cyx()); str_onTrk_yy[clusterKey].push_back(hit->globalPositionError().cyy()); str_onTrk_yz[clusterKey].push_back(hit->globalPositionError().czy()); str_onTrk_zz[clusterKey].push_back(hit->globalPositionError().czz()); str_onTrk_zx[clusterKey].push_back(hit->globalPositionError().czx()); } } hitIdx.push_back(clusterKey); if (clusterRef.isPixel()) { hitType.push_back(static_cast<int>(HitType::Pixel)); } else if (clusterRef.isPhase2()) { hitType.push_back(static_cast<int>(HitType::Phase2OT)); } else { hitType.push_back(static_cast<int>(HitType::Strip)); } } else { LogTrace("TrackingNtuple") << " - invalid hit"; hitIdx.push_back(inv_isBarrel.size()); hitType.push_back(static_cast<int>(HitType::Invalid)); inv_isBarrel.push_back(hitId.subdetId() == 1); if (includeStripHits_) inv_detId.push_back(tracker, tTopo, hitId); else inv_detId_phase2.push_back(tracker, tTopo, hitId); inv_type.push_back(hit->getType()); } } trk_hitIdx.push_back(hitIdx); trk_hitType.push_back(hitType); } } void TrackingNtuple::fillCandidates(const edm::Handle<TrackCandidateCollection>& candsHandle, int algo, const TrackingParticleRefVector& tpCollection, const TrackingParticleRefKeyToIndex& tpKeyToIndex, const TrackingParticleRefKeyToCount& tpKeyToClusterCount, const MagneticField& mf, const reco::BeamSpot& bs, const reco::VertexCollection& vertices, const reco::TrackToTrackingParticleAssociator& associatorByHits, const ClusterTPAssociation& clusterToTPMap, const TrackerGeometry& tracker, const TrackerTopology& tTopo, const std::set<edm::ProductID>& hitProductIds, const std::map<edm::ProductID, size_t>& seedCollToOffset) { reco::RecoToSimCollectionTCandidate recSimColl = associatorByHits.associateRecoToSim(candsHandle, tpCollection); TSCBLBuilderNoMaterial tscblBuilder; auto const& cands = *candsHandle; for (size_t iCand = 0; iCand < cands.size(); ++iCand) { const auto& aCand = cands[iCand]; const edm::Ref<TrackCandidateCollection> aCandRef(candsHandle, iCand); //get parameters and errors from the candidate state auto const& pState = aCand.trajectoryStateOnDet(); TrajectoryStateOnSurface state = trajectoryStateTransform::transientState(pState, &(tracker.idToDet(pState.detId())->surface()), &mf); TrajectoryStateClosestToBeamLine tbStateAtPCA = tscblBuilder(*state.freeState(), bs); if (!tbStateAtPCA.isValid()) { edm::LogVerbatim("TrackBuilding") << "TrajectoryStateClosestToBeamLine not valid"; } auto const& stateAtPCA = tbStateAtPCA.trackStateAtPCA(); auto v0 = stateAtPCA.position(); auto p = stateAtPCA.momentum(); math::XYZPoint pos(v0.x(), v0.y(), v0.z()); math::XYZVector mom(p.x(), p.y(), p.z()); //pseduo track for access to easy methods static const reco::Track::CovarianceMatrix dummyCov = AlgebraicMatrixID(); reco::Track trk( 0, 0, pos, mom, stateAtPCA.charge(), tbStateAtPCA.isValid() ? stateAtPCA.curvilinearError().matrix() : dummyCov); const auto& tkParam = trk.parameters(); auto tkCov = trk.covariance(); tkCov.Invert(); // Standard track-TP matching int nSimHits = 0; bool isSimMatched = false; std::vector<int> tpIdx; std::vector<float> sharedFraction; std::vector<float> tpChi2; auto foundTPs = recSimColl.find(aCandRef); if (foundTPs != recSimColl.end()) { if (!foundTPs->val.empty()) { nSimHits = foundTPs->val[0].first->numberOfTrackerHits(); isSimMatched = true; } for (const auto& tpQuality : foundTPs->val) { tpIdx.push_back(tpKeyToIndex.at(tpQuality.first.key())); sharedFraction.push_back(tpQuality.second); tpChi2.push_back(track_associator::trackAssociationChi2(tkParam, tkCov, *(tpCollection[tpIdx.back()]), mf, bs)); } } // Search for a best-matching TrackingParticle for a track const auto clusters = track_associator::hitsToClusterRefs(aCand.recHits().begin(), aCand.recHits().end()); const int nClusters = clusters.size(); const auto bestKeyCount = findBestMatchingTrackingParticle(aCand.recHits(), clusterToTPMap, tpKeyToIndex); const float bestCountF = bestKeyCount.countClusters; const float bestShareFrac = bestCountF / nClusters; float bestShareFracSimDenom = 0; float bestShareFracSimClusterDenom = 0; float bestChi2 = -1; if (bestKeyCount.key >= 0) { bestShareFracSimDenom = bestCountF / tpCollection[tpKeyToIndex.at(bestKeyCount.key)]->numberOfTrackerHits(); bestShareFracSimClusterDenom = bestCountF / tpKeyToClusterCount.at(bestKeyCount.key); bestChi2 = track_associator::trackAssociationChi2( tkParam, tkCov, *(tpCollection[tpKeyToIndex.at(bestKeyCount.key)]), mf, bs); } // Another way starting from the first hit of the track const auto bestFirstHitKeyCount = findMatchingTrackingParticleFromFirstHit(aCand.recHits(), clusterToTPMap, tpKeyToIndex); const float bestFirstCountF = bestFirstHitKeyCount.countClusters; const float bestFirstHitShareFrac = bestFirstCountF / nClusters; float bestFirstHitShareFracSimDenom = 0; float bestFirstHitShareFracSimClusterDenom = 0; float bestFirstHitChi2 = -1; if (bestFirstHitKeyCount.key >= 0) { bestFirstHitShareFracSimDenom = bestFirstCountF / tpCollection[tpKeyToIndex.at(bestFirstHitKeyCount.key)]->numberOfTrackerHits(); bestFirstHitShareFracSimClusterDenom = bestFirstCountF / tpKeyToClusterCount.at(bestFirstHitKeyCount.key); bestFirstHitChi2 = track_associator::trackAssociationChi2( tkParam, tkCov, *(tpCollection[tpKeyToIndex.at(bestFirstHitKeyCount.key)]), mf, bs); } auto iglobCand = tcand_pca_valid.size(); //global cand index tcand_pca_valid.push_back(tbStateAtPCA.isValid()); tcand_pca_px.push_back(trk.px()); tcand_pca_py.push_back(trk.py()); tcand_pca_pz.push_back(trk.pz()); tcand_pca_pt.push_back(trk.pt()); tcand_pca_eta.push_back(trk.eta()); tcand_pca_phi.push_back(trk.phi()); tcand_pca_dxy.push_back(trk.dxy()); tcand_pca_dz.push_back(trk.dz()); tcand_pca_ptErr.push_back(trk.ptError()); tcand_pca_etaErr.push_back(trk.etaError()); tcand_pca_lambdaErr.push_back(trk.lambdaError()); tcand_pca_phiErr.push_back(trk.phiError()); tcand_pca_dxyErr.push_back(trk.dxyError()); tcand_pca_dzErr.push_back(trk.dzError()); tcand_px.push_back(state.globalMomentum().x()); tcand_py.push_back(state.globalMomentum().y()); tcand_pz.push_back(state.globalMomentum().z()); tcand_pt.push_back(state.globalMomentum().perp()); tcand_x.push_back(state.globalPosition().x()); tcand_y.push_back(state.globalPosition().y()); tcand_z.push_back(state.globalPosition().z()); auto const& pStateCov = state.curvilinearError().matrix(); tcand_qbpErr.push_back(sqrt(pStateCov(0, 0))); tcand_lambdaErr.push_back(sqrt(pStateCov(1, 1))); tcand_phiErr.push_back(sqrt(pStateCov(2, 2))); tcand_xtErr.push_back(sqrt(pStateCov(3, 3))); tcand_ytErr.push_back(sqrt(pStateCov(4, 4))); int ndof = -5; int nValid = 0; int nPixel = 0; int nStrip = 0; for (auto const& hit : aCand.recHits()) { if (hit.isValid()) { ndof += hit.dimension(); nValid++; auto const subdet = hit.geographicalId().subdetId(); if (subdet == PixelSubdetector::PixelBarrel || subdet == PixelSubdetector::PixelEndcap) nPixel++; else nStrip++; } } tcand_ndof.push_back(ndof); tcand_q.push_back(trk.charge()); tcand_nValid.push_back(nValid); tcand_nPixel.push_back(nPixel); tcand_nStrip.push_back(nStrip); tcand_nCluster.push_back(nClusters); tcand_algo.push_back(algo); tcand_stopReason.push_back(aCand.stopReason()); if (includeSeeds_) { auto offset = seedCollToOffset.find(aCand.seedRef().id()); if (offset == seedCollToOffset.end()) { throw cms::Exception("Configuration") << "Track candidate refers to seed collection " << aCand.seedRef().id() << ", but that seed collection is not given as an input. The following collections were given as an input " << make_ProductIDMapPrinter(seedCollToOffset); } const auto seedIndex = offset->second + aCand.seedRef().key(); tcand_seedIdx.push_back(seedIndex); if (seedUniqueCheck_ && see_nTCand[seedIndex] > 0) { throw cms::Exception("LogicError") << "Track cand index has already been set for seed " << seedIndex << " to " << see_tcandIdx[seedIndex][0] << "; was trying to set it to " << iglobCand << " current " << iCand; } see_nTCand[seedIndex]++; see_tcandIdx[seedIndex].push_back(iglobCand); } tcand_vtxIdx.push_back(-1); // to be set correctly in fillVertices if (includeTrackingParticles_) { tcand_simTrkIdx.push_back(tpIdx); tcand_simTrkShareFrac.push_back(sharedFraction); tcand_simTrkNChi2.push_back(tpChi2); tcand_bestSimTrkIdx.push_back(bestKeyCount.key >= 0 ? tpKeyToIndex.at(bestKeyCount.key) : -1); tcand_bestFromFirstHitSimTrkIdx.push_back( bestFirstHitKeyCount.key >= 0 ? tpKeyToIndex.at(bestFirstHitKeyCount.key) : -1); } else { tcand_isTrue.push_back(!tpIdx.empty()); } tcand_bestSimTrkShareFrac.push_back(bestShareFrac); tcand_bestSimTrkShareFracSimDenom.push_back(bestShareFracSimDenom); tcand_bestSimTrkShareFracSimClusterDenom.push_back(bestShareFracSimClusterDenom); tcand_bestSimTrkNChi2.push_back(bestChi2); tcand_bestFromFirstHitSimTrkShareFrac.push_back(bestFirstHitShareFrac); tcand_bestFromFirstHitSimTrkShareFracSimDenom.push_back(bestFirstHitShareFracSimDenom); tcand_bestFromFirstHitSimTrkShareFracSimClusterDenom.push_back(bestFirstHitShareFracSimClusterDenom); tcand_bestFromFirstHitSimTrkNChi2.push_back(bestFirstHitChi2); LogTrace("TrackingNtuple") << "Track cand #" << iCand << " glob " << iglobCand << " with q=" << trk.charge() << ", pT=" << trk.pt() << " GeV, eta: " << trk.eta() << ", phi: " << trk.phi() << ", nValid=" << nValid << " seed#=" << aCand.seedRef().key() << " simMatch=" << isSimMatched << " nSimHits=" << nSimHits << " sharedFraction=" << (sharedFraction.empty() ? -1 : sharedFraction[0]) << " tpIdx=" << (tpIdx.empty() ? -1 : tpIdx[0]); std::vector<int> hitIdx; std::vector<int> hitType; for (auto i = aCand.recHits().begin(); i != aCand.recHits().end(); i++) { const TrackingRecHit* hit = &*i; DetId hitId = hit->geographicalId(); LogTrace("TrackingNtuple") << "hit #" << std::distance(aCand.recHits().begin(), i) << " subdet=" << hitId.subdetId(); if (hitId.det() != DetId::Tracker) continue; LogTrace("TrackingNtuple") << " " << subdetstring(hitId.subdetId()) << " " << tTopo.layer(hitId); if (hit->isValid()) { //ugly... but works const BaseTrackerRecHit* bhit = dynamic_cast<const BaseTrackerRecHit*>(&*hit); const auto& clusterRef = bhit->firstClusterRef(); unsigned int clusterKey; if (clusterRef.isPixel()) { clusterKey = clusterRef.cluster_pixel().key(); } else if (clusterRef.isPhase2()) { clusterKey = clusterRef.cluster_phase2OT().key(); } else { clusterKey = clusterRef.cluster_strip().key(); } LogTrace("TrackingNtuple") << " id: " << hitId.rawId() << " - globalPos =" << hit->globalPosition() << " cluster=" << clusterKey << " clusterRef ID=" << clusterRef.id() << " eta,phi: " << hit->globalPosition().eta() << "," << hit->globalPosition().phi(); if (includeAllHits_) { checkProductID(hitProductIds, clusterRef.id(), "track"); if (clusterRef.isPixel()) { pix_tcandIdx[clusterKey].push_back(iglobCand); } else if (clusterRef.isPhase2()) { ph2_tcandIdx[clusterKey].push_back(iglobCand); } else { str_tcandIdx[clusterKey].push_back(iglobCand); } } hitIdx.push_back(clusterKey); if (clusterRef.isPixel()) { hitType.push_back(static_cast<int>(HitType::Pixel)); } else if (clusterRef.isPhase2()) { hitType.push_back(static_cast<int>(HitType::Phase2OT)); } else { hitType.push_back(static_cast<int>(HitType::Strip)); } } } tcand_hitIdx.push_back(hitIdx); tcand_hitType.push_back(hitType); } } void TrackingNtuple::fillTrackingParticles(const edm::Event& iEvent, const edm::EventSetup& iSetup, const edm::RefToBaseVector<reco::Track>& tracks, const reco::BeamSpot& bs, const TrackingParticleRefVector& tpCollection, const TrackingVertexRefKeyToIndex& tvKeyToIndex, const reco::TrackToTrackingParticleAssociator& associatorByHits, const std::vector<TPHitIndex>& tpHitList, const TrackingParticleRefKeyToCount& tpKeyToClusterCount) { // Number of 3D layers for TPs edm::Handle<edm::ValueMap<unsigned int>> tpNLayersH; iEvent.getByToken(tpNLayersToken_, tpNLayersH); const auto& nLayers_tPCeff = *tpNLayersH; iEvent.getByToken(tpNPixelLayersToken_, tpNLayersH); const auto& nPixelLayers_tPCeff = *tpNLayersH; iEvent.getByToken(tpNStripStereoLayersToken_, tpNLayersH); const auto& nStripMonoAndStereoLayers_tPCeff = *tpNLayersH; reco::SimToRecoCollection simRecColl = associatorByHits.associateSimToReco(tracks, tpCollection); for (const TrackingParticleRef& tp : tpCollection) { LogTrace("TrackingNtuple") << "tracking particle pt=" << tp->pt() << " eta=" << tp->eta() << " phi=" << tp->phi(); bool isRecoMatched = false; std::vector<int> tkIdx; std::vector<float> sharedFraction; auto foundTracks = simRecColl.find(tp); if (foundTracks != simRecColl.end()) { isRecoMatched = true; for (const auto& trackQuality : foundTracks->val) { sharedFraction.push_back(trackQuality.second); tkIdx.push_back(trackQuality.first.key()); } } sim_genPdgIds.emplace_back(); for (const auto& genRef : tp->genParticles()) { if (genRef.isNonnull()) sim_genPdgIds.back().push_back(genRef->pdgId()); } bool isFromBHadron = false; // Logic is similar to SimTracker/TrackHistory if (tracer_.evaluate(tp)) { // ignore TP if history can not be traced // following is from TrackClassifier::processesAtGenerator() HistoryBase::RecoGenParticleTrail const& recoGenParticleTrail = tracer_.recoGenParticleTrail(); for (const auto& particle : recoGenParticleTrail) { HepPDT::ParticleID particleID(particle->pdgId()); if (particleID.hasBottom()) { isFromBHadron = true; break; } } } LogTrace("TrackingNtuple") << "matched to tracks = " << make_VectorPrinter(tkIdx) << " isRecoMatched=" << isRecoMatched; sim_event.push_back(tp->eventId().event()); sim_bunchCrossing.push_back(tp->eventId().bunchCrossing()); sim_pdgId.push_back(tp->pdgId()); sim_isFromBHadron.push_back(isFromBHadron); sim_px.push_back(tp->px()); sim_py.push_back(tp->py()); sim_pz.push_back(tp->pz()); sim_pt.push_back(tp->pt()); sim_eta.push_back(tp->eta()); sim_phi.push_back(tp->phi()); sim_q.push_back(tp->charge()); sim_trkIdx.push_back(tkIdx); sim_trkShareFrac.push_back(sharedFraction); sim_parentVtxIdx.push_back(tvKeyToIndex.at(tp->parentVertex().key())); std::vector<int> decayIdx; for (const auto& v : tp->decayVertices()) decayIdx.push_back(tvKeyToIndex.at(v.key())); sim_decayVtxIdx.push_back(decayIdx); //Calcualte the impact parameters w.r.t. PCA TrackingParticle::Vector momentum = parametersDefiner_.momentum(iEvent, iSetup, tp); TrackingParticle::Point vertex = parametersDefiner_.vertex(iEvent, iSetup, tp); auto dxySim = TrackingParticleIP::dxy(vertex, momentum, bs.position()); auto dzSim = TrackingParticleIP::dz(vertex, momentum, bs.position()); const double lambdaSim = M_PI / 2 - momentum.theta(); sim_pca_pt.push_back(std::sqrt(momentum.perp2())); sim_pca_eta.push_back(momentum.Eta()); sim_pca_lambda.push_back(lambdaSim); sim_pca_cotTheta.push_back(1 / tan(M_PI * 0.5 - lambdaSim)); sim_pca_phi.push_back(momentum.phi()); sim_pca_dxy.push_back(dxySim); sim_pca_dz.push_back(dzSim); std::vector<int> hitIdx; int nPixel = 0, nStrip = 0; auto rangeHit = std::equal_range(tpHitList.begin(), tpHitList.end(), TPHitIndex(tp.key()), tpHitIndexListLess); for (auto ip = rangeHit.first; ip != rangeHit.second; ++ip) { auto type = HitType::Unknown; if (!simhit_hitType[ip->simHitIdx].empty()) type = static_cast<HitType>(simhit_hitType[ip->simHitIdx][0]); LogTrace("TrackingNtuple") << "simhit=" << ip->simHitIdx << " type=" << static_cast<int>(type); hitIdx.push_back(ip->simHitIdx); const auto detid = DetId(includeStripHits_ ? simhit_detId[ip->simHitIdx] : simhit_detId_phase2[ip->simHitIdx]); if (detid.det() != DetId::Tracker) { throw cms::Exception("LogicError") << "Encountered SimHit for TP " << tp.key() << " with DetId " << detid.rawId() << " whose det() is not Tracker but " << detid.det(); } const auto subdet = detid.subdetId(); switch (subdet) { case PixelSubdetector::PixelBarrel: case PixelSubdetector::PixelEndcap: ++nPixel; break; case StripSubdetector::TIB: case StripSubdetector::TID: case StripSubdetector::TOB: case StripSubdetector::TEC: ++nStrip; break; default: throw cms::Exception("LogicError") << "Encountered SimHit for TP " << tp.key() << " with DetId " << detid.rawId() << " whose subdet is not recognized, is " << subdet; }; } sim_nValid.push_back(hitIdx.size()); sim_nPixel.push_back(nPixel); sim_nStrip.push_back(nStrip); const auto nSimLayers = nLayers_tPCeff[tp]; const auto nSimPixelLayers = nPixelLayers_tPCeff[tp]; const auto nSimStripMonoAndStereoLayers = nStripMonoAndStereoLayers_tPCeff[tp]; sim_nLay.push_back(nSimLayers); sim_nPixelLay.push_back(nSimPixelLayers); sim_n3DLay.push_back(nSimPixelLayers + nSimStripMonoAndStereoLayers); sim_nTrackerHits.push_back(tp->numberOfTrackerHits()); auto found = tpKeyToClusterCount.find(tp.key()); sim_nRecoClusters.push_back(found != cend(tpKeyToClusterCount) ? found->second : 0); sim_simHitIdx.push_back(hitIdx); } } // called from fillSeeds void TrackingNtuple::fillTrackingParticlesForSeeds(const TrackingParticleRefVector& tpCollection, const reco::SimToRecoCollection& simRecColl, const TrackingParticleRefKeyToIndex& tpKeyToIndex, const unsigned int seedOffset) { if (sim_seedIdx.empty()) // first call sim_seedIdx.resize(tpCollection.size()); for (const auto& keyVal : simRecColl) { const auto& tpRef = keyVal.key; auto found = tpKeyToIndex.find(tpRef.key()); if (found == tpKeyToIndex.end()) throw cms::Exception("Assert") << __FILE__ << ":" << __LINE__ << " fillTrackingParticlesForSeeds: tpRef.key() " << tpRef.key() << " not found from tpKeyToIndex. tpKeyToIndex size " << tpKeyToIndex.size(); const auto tpIndex = found->second; for (const auto& pair : keyVal.val) { const auto& seedRef = pair.first->seedRef(); sim_seedIdx[tpIndex].push_back(seedOffset + seedRef.key()); } } } void TrackingNtuple::fillVertices(const reco::VertexCollection& vertices, const edm::RefToBaseVector<reco::Track>& tracks) { for (size_t iVertex = 0, size = vertices.size(); iVertex < size; ++iVertex) { const reco::Vertex& vertex = vertices[iVertex]; vtx_x.push_back(vertex.x()); vtx_y.push_back(vertex.y()); vtx_z.push_back(vertex.z()); vtx_xErr.push_back(vertex.xError()); vtx_yErr.push_back(vertex.yError()); vtx_zErr.push_back(vertex.zError()); vtx_chi2.push_back(vertex.chi2()); vtx_ndof.push_back(vertex.ndof()); vtx_fake.push_back(vertex.isFake()); vtx_valid.push_back(vertex.isValid()); std::vector<int> trkIdx; for (auto iTrack = vertex.tracks_begin(); iTrack != vertex.tracks_end(); ++iTrack) { // Ignore link if vertex was fit from a track collection different from the input if (iTrack->id() != tracks.id()) continue; trkIdx.push_back(iTrack->key()); if (trk_vtxIdx[iTrack->key()] != -1) { throw cms::Exception("LogicError") << "Vertex index has already been set for track " << iTrack->key() << " to " << trk_vtxIdx[iTrack->key()] << "; was trying to set it to " << iVertex; } trk_vtxIdx[iTrack->key()] = iVertex; } vtx_trkIdx.push_back(trkIdx); } } void TrackingNtuple::fillTrackingVertices(const TrackingVertexRefVector& trackingVertices, const TrackingParticleRefKeyToIndex& tpKeyToIndex) { int current_event = -1; for (const auto& ref : trackingVertices) { const TrackingVertex v = *ref; if (v.eventId().event() != current_event) { // next PV current_event = v.eventId().event(); simpv_idx.push_back(simvtx_x.size()); } unsigned int processType = std::numeric_limits<unsigned int>::max(); if (!v.g4Vertices().empty()) { processType = v.g4Vertices()[0].processType(); } simvtx_event.push_back(v.eventId().event()); simvtx_bunchCrossing.push_back(v.eventId().bunchCrossing()); simvtx_processType.push_back(processType); simvtx_x.push_back(v.position().x()); simvtx_y.push_back(v.position().y()); simvtx_z.push_back(v.position().z()); auto fill = [&](const TrackingParticleRefVector& tps, std::vector<int>& idx) { for (const auto& tpRef : tps) { auto found = tpKeyToIndex.find(tpRef.key()); if (found != tpKeyToIndex.end()) { idx.push_back(found->second); } } }; std::vector<int> sourceIdx; std::vector<int> daughterIdx; fill(v.sourceTracks(), sourceIdx); fill(v.daughterTracks(), daughterIdx); simvtx_sourceSimIdx.push_back(sourceIdx); simvtx_daughterSimIdx.push_back(daughterIdx); } } // ------------ method fills 'descriptions' with the allowed parameters for the module ------------ void TrackingNtuple::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { //The following says we do not know what parameters are allowed so do no validation // Please change this to state exactly what you do use, even if it is no parameters edm::ParameterSetDescription desc; desc.addUntracked<std::vector<edm::InputTag>>( "seedTracks", std::vector<edm::InputTag>{edm::InputTag("seedTracksinitialStepSeeds"), edm::InputTag("seedTracksdetachedTripletStepSeeds"), edm::InputTag("seedTrackspixelPairStepSeeds"), edm::InputTag("seedTrackslowPtTripletStepSeeds"), edm::InputTag("seedTracksmixedTripletStepSeeds"), edm::InputTag("seedTrackspixelLessStepSeeds"), edm::InputTag("seedTrackstobTecStepSeeds"), edm::InputTag("seedTracksjetCoreRegionalStepSeeds"), edm::InputTag("seedTracksmuonSeededSeedsInOut"), edm::InputTag("seedTracksmuonSeededSeedsOutIn")}); desc.addUntracked<std::vector<edm::InputTag>>( "trackCandidates", std::vector<edm::InputTag>{edm::InputTag("initialStepTrackCandidates"), edm::InputTag("detachedTripletStepTrackCandidates"), edm::InputTag("pixelPairStepTrackCandidates"), edm::InputTag("lowPtTripletStepTrackCandidates"), edm::InputTag("mixedTripletStepTrackCandidates"), edm::InputTag("pixelLessStepTrackCandidates"), edm::InputTag("tobTecStepTrackCandidates"), edm::InputTag("jetCoreRegionalStepTrackCandidates"), edm::InputTag("muonSeededTrackCandidatesInOut"), edm::InputTag("muonSeededTrackCandidatesOutIn")}); desc.addUntracked<edm::InputTag>("tracks", edm::InputTag("generalTracks")); desc.addUntracked<std::vector<std::string>>("trackMVAs", std::vector<std::string>{{"generalTracks"}}); edm::ParameterSetDescription cMaskDesc; cMaskDesc.addUntracked<unsigned int>("index"); cMaskDesc.addUntracked<edm::InputTag>("src"); std::vector<edm::ParameterSet> cMasks; auto addMask = [&cMasks](reco::Track::TrackAlgorithm algo) { edm::ParameterSet ps; ps.addUntrackedParameter<unsigned int>("index", static_cast<unsigned int>(algo)); ps.addUntrackedParameter<edm::InputTag>("src", {reco::Track::algoName(algo) + "Clusters"}); cMasks.push_back(ps); }; addMask(reco::Track::detachedQuadStep); addMask(reco::Track::highPtTripletStep); addMask(reco::Track::detachedTripletStep); addMask(reco::Track::lowPtQuadStep); addMask(reco::Track::lowPtTripletStep); addMask(reco::Track::mixedTripletStep); addMask(reco::Track::pixelLessStep); addMask(reco::Track::pixelPairStep); addMask(reco::Track::tobTecStep); desc.addVPSetUntracked("clusterMasks", cMaskDesc, cMasks); desc.addUntracked<edm::InputTag>("trackingParticles", edm::InputTag("mix", "MergedTrackTruth")); desc.addUntracked<bool>("trackingParticlesRef", false); desc.addUntracked<edm::InputTag>("clusterTPMap", edm::InputTag("tpClusterProducer")); desc.addUntracked<edm::InputTag>("simHitTPMap", edm::InputTag("simHitTPAssocProducer")); desc.addUntracked<edm::InputTag>("trackAssociator", edm::InputTag("quickTrackAssociatorByHits")); desc.addUntracked<edm::InputTag>("pixelDigiSimLink", edm::InputTag("simSiPixelDigis")); desc.addUntracked<edm::InputTag>("stripDigiSimLink", edm::InputTag("simSiStripDigis")); desc.addUntracked<edm::InputTag>("phase2OTSimLink", edm::InputTag("")); desc.addUntracked<edm::InputTag>("beamSpot", edm::InputTag("offlineBeamSpot")); desc.addUntracked<edm::InputTag>("pixelRecHits", edm::InputTag("siPixelRecHits")); desc.addUntracked<edm::InputTag>("stripRphiRecHits", edm::InputTag("siStripMatchedRecHits", "rphiRecHit")); desc.addUntracked<edm::InputTag>("stripStereoRecHits", edm::InputTag("siStripMatchedRecHits", "stereoRecHit")); desc.addUntracked<edm::InputTag>("stripMatchedRecHits", edm::InputTag("siStripMatchedRecHits", "matchedRecHit")); desc.addUntracked<edm::InputTag>("phase2OTRecHits", edm::InputTag("siPhase2RecHits")); desc.addUntracked<edm::InputTag>("vertices", edm::InputTag("offlinePrimaryVertices")); desc.addUntracked<edm::InputTag>("trackingVertices", edm::InputTag("mix", "MergedTrackTruth")); desc.addUntracked<edm::InputTag>("trackingParticleNlayers", edm::InputTag("trackingParticleNumberOfLayersProducer", "trackerLayers")); desc.addUntracked<edm::InputTag>("trackingParticleNpixellayers", edm::InputTag("trackingParticleNumberOfLayersProducer", "pixelLayers")); desc.addUntracked<edm::InputTag>("trackingParticleNstripstereolayers", edm::InputTag("trackingParticleNumberOfLayersProducer", "stripStereoLayers")); desc.addUntracked<std::string>("TTRHBuilder", "WithTrackAngle") ->setComment("currently not used: keep for possible future use"); desc.addUntracked<bool>("includeSeeds", false); desc.addOptionalUntracked<bool>("seedUniqueCheck", true); desc.addOptionalUntracked<bool>("seedAlgoDetect", true); desc.addOptionalUntracked<std::vector<unsigned int>>("seedAlgos"); desc.addUntracked<bool>("includeTrackCandidates", false); desc.addUntracked<bool>("addSeedCurvCov", false); desc.addUntracked<bool>("includeAllHits", false); desc.addUntracked<bool>("includeOnTrackHitData", false); desc.addUntracked<bool>("includeMVA", true); desc.addUntracked<bool>("includeTrackingParticles", true); desc.addUntracked<bool>("includeOOT", false); desc.addUntracked<bool>("keepEleSimHits", false); desc.addUntracked<bool>("saveSimHitsP3", false); desc.addUntracked<bool>("simHitBySignificance", false); desc.add<edm::InputTag>("jetSource", edm::InputTag("ak4GenJets")); descriptions.add("trackingNtuple", desc); } //define this as a plug-in DEFINE_FWK_MODULE(TrackingNtuple);