/
githubmirror
/
cmssw
Обзор
Документация
Войти
/
githubmirror
/
cmssw
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
RecoMTD/TrackExtender/plugins/TrackExtenderWithMTD.cc
965 строк
44 KB
xabier.cid.vidal@cern.ch
RecoMTD/TrackExtender: apply clang-format fixes
23 июл 2026, 16:51
23 июл 2026, 16:51
37960b2
Код
Авторство
О чём код?
#include <sstream> #include <format> #include <CLHEP/Units/GlobalPhysicalConstants.h> #include "RecoMTD/TimingTools/interface/MTDHitMatchingInfo.h" #include "RecoMTD/TimingTools/interface/TrackSegments.h" #include "RecoMTD/TimingTools/interface/TrackTofPidInfo.h" #include "RecoMTD/TrackExtender/interface/MTDHitMatcher.h" #include "DataFormats/ForwardDetId/interface/BTLDetId.h" #include "DataFormats/ForwardDetId/interface/ETLDetId.h" #include "DataFormats/ForwardDetId/interface/MTDChannelIdentifier.h" #include "DataFormats/GeometryVector/interface/GlobalPoint.h" #include "DataFormats/Math/interface/GeantUnits.h" #include "DataFormats/Math/interface/LorentzVector.h" #include "DataFormats/Math/interface/Rounding.h" #include "DataFormats/TrackerRecHit2D/interface/MTDTrackingRecHit.h" #include "DataFormats/VertexReco/interface/Vertex.h" #include "DataFormats/VertexReco/interface/VertexFwd.h" #include "FWCore/Framework/interface/ConsumesCollector.h" #include "FWCore/Framework/interface/ESHandle.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/EventSetup.h" #include "FWCore/Framework/interface/Frameworkfwd.h" #include "FWCore/Framework/interface/stream/EDProducer.h" #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "FWCore/ParameterSet/interface/ParameterSetDescription.h" #include "Geometry/CommonTopologies/interface/PixelTopology.h" #include "Geometry/CommonTopologies/interface/Topology.h" #include "MagneticField/Engine/interface/MagneticField.h" #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h" #include "RecoMTD/DetLayers/interface/MTDDetLayerGeometry.h" #include "RecoMTD/DetLayers/interface/MTDTrayBarrelLayer.h" #include "RecoMTD/Records/interface/MTDRecoGeometryRecord.h" #include "RecoMTD/TransientTrackingRecHit/interface/MTDTransientTrackingRecHitBuilder.h" #include "RecoTracker/TransientTrackingRecHit/interface/Traj2TrackHits.h" #include "TrackingTools/DetLayers/interface/ForwardDetLayer.h" #include "TrackingTools/GeomPropagators/interface/Propagator.h" #include "TrackingTools/KalmanUpdators/interface/Chi2MeasurementEstimator.h" #include "TrackingTools/PatternTools/interface/TSCBLBuilderWithPropagator.h" #include "TrackingTools/PatternTools/interface/TrajTrackAssociation.h" #include "TrackingTools/PatternTools/interface/Trajectory.h" #include "TrackingTools/Records/interface/TrackingComponentsRecord.h" #include "TrackingTools/Records/interface/TransientRecHitRecord.h" #include "TrackingTools/Records/interface/TransientTrackRecord.h" #include "TrackingTools/TrackRefitter/interface/TrackTransformer.h" #include "TrackingTools/TransientTrack/interface/TransientTrack.h" #include "TrackingTools/TransientTrack/interface/TransientTrackBuilder.h" #include "TrackingTools/TransientTrackingRecHit/interface/TransientTrackingRecHit.h" using namespace std; using namespace edm; using namespace reco; using mtd::c_cm_ns; using mtd::c_inv; using mtd::computeTrackTofPidInfo; using mtd::MTDHitMatcher; using mtd::MTDHitMatchingInfo; using mtd::MTDHitMatchResult; using mtd::SigmaTofCalc; using mtd::TofCalc; using mtd::TrackSegments; using mtd::TrackTofPidInfo; namespace { bool getTrajectoryStateClosestToBeamLine(const Trajectory& traj, const reco::BeamSpot& bs, const Propagator* thePropagator, TrajectoryStateClosestToBeamLine& tscbl) { // get the state closest to the beamline TrajectoryStateOnSurface stateForProjectionToBeamLineOnSurface = traj.closestMeasurement(GlobalPoint(bs.x0(), bs.y0(), bs.z0())).updatedState(); if (!stateForProjectionToBeamLineOnSurface.isValid()) { edm::LogError("CannotPropagateToBeamLine") << "the state on the closest measurement isnot valid. skipping track."; return false; } const FreeTrajectoryState& stateForProjectionToBeamLine = *stateForProjectionToBeamLineOnSurface.freeState(); TSCBLBuilderWithPropagator tscblBuilder(*thePropagator); tscbl = tscblBuilder(stateForProjectionToBeamLine, bs); return tscbl.isValid(); } bool trackPathLength(const Trajectory& traj, const TrajectoryStateClosestToBeamLine& tscbl, const Propagator* thePropagator, float& pathlength, TrackSegments& trs) { pathlength = 0.f; bool validpropagation = true; float oldp = traj.measurements().begin()->updatedState().globalMomentum().mag(); float pathlength1 = 0.f; float pathlength2 = 0.f; //add pathlength layer by layer for (auto it = traj.measurements().begin(); it != traj.measurements().end() - 1; ++it) { const auto& propresult = thePropagator->propagateWithPath(it->updatedState(), (it + 1)->updatedState().surface()); float layerpathlength = std::abs(propresult.second); if (layerpathlength == 0.f) { validpropagation = false; } pathlength1 += layerpathlength; // sigma(p) from curvilinear error (on q/p) float sigma_p = sqrt((it + 1)->updatedState().curvilinearError().matrix()(0, 0)) * (it + 1)->updatedState().globalMomentum().mag2(); trs.addSegment(layerpathlength, (it + 1)->updatedState().globalMomentum().mag2(), sigma_p); LogTrace("TrackExtenderWithMTD") << "TSOS " << std::fixed << std::setw(4) << trs.size() << " R_i " << std::fixed << std::setw(14) << it->updatedState().globalPosition().perp() << " z_i " << std::fixed << std::setw(14) << it->updatedState().globalPosition().z() << " R_e " << std::fixed << std::setw(14) << (it + 1)->updatedState().globalPosition().perp() << " z_e " << std::fixed << std::setw(14) << (it + 1)->updatedState().globalPosition().z() << " p " << std::fixed << std::setw(14) << (it + 1)->updatedState().globalMomentum().mag() << " dp " << std::fixed << std::setw(14) << (it + 1)->updatedState().globalMomentum().mag() - oldp; oldp = (it + 1)->updatedState().globalMomentum().mag(); } //add distance from bs to first measurement auto const& tscblPCA = tscbl.trackStateAtPCA(); auto const& aSurface = traj.direction() == alongMomentum ? traj.firstMeasurement().updatedState().surface() : traj.lastMeasurement().updatedState().surface(); pathlength2 = thePropagator->propagateWithPath(tscblPCA, aSurface).second; if (pathlength2 == 0.f) { validpropagation = false; } pathlength = pathlength1 + pathlength2; float sigma_p = sqrt(tscblPCA.curvilinearError().matrix()(0, 0)) * tscblPCA.momentum().mag2(); trs.addSegment(pathlength2, tscblPCA.momentum().mag2(), sigma_p); LogTrace("TrackExtenderWithMTD") << "TSOS " << std::fixed << std::setw(4) << trs.size() << " R_e " << std::fixed << std::setw(14) << tscblPCA.position().perp() << " z_e " << std::fixed << std::setw(14) << tscblPCA.position().z() << " p " << std::fixed << std::setw(14) << tscblPCA.momentum().mag() << " dp " << std::fixed << std::setw(14) << tscblPCA.momentum().mag() - oldp << " sigma_p = " << std::fixed << std::setw(14) << sigma_p << " sigma_p/p = " << std::fixed << std::setw(14) << sigma_p / tscblPCA.momentum().mag() * 100 << " %"; return validpropagation; } bool trackPathLength(const Trajectory& traj, const reco::BeamSpot& bs, const Propagator* thePropagator, float& pathlength, TrackSegments& trs) { pathlength = 0.f; TrajectoryStateClosestToBeamLine tscbl; bool tscbl_status = getTrajectoryStateClosestToBeamLine(traj, bs, thePropagator, tscbl); if (!tscbl_status) return false; return trackPathLength(traj, tscbl, thePropagator, pathlength, trs); } } // namespace template <class TrackCollection> class TrackExtenderWithMTDT : public edm::stream::EDProducer<> { public: typedef typename TrackCollection::value_type TrackType; typedef edm::View<TrackType> InputCollection; TrackExtenderWithMTDT(const ParameterSet& pset); template <class H, class T> void fillValueMap(edm::Event& iEvent, const H& handle, const std::vector<T>& vec, const edm::EDPutToken& token) const; void produce(edm::Event& ev, const edm::EventSetup& es) final; static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); RefitDirection::GeometricalDirection checkRecHitsOrdering( TransientTrackingRecHit::ConstRecHitContainer const& recHits) const { if (!recHits.empty()) { GlobalPoint first = gtg_->idToDet(recHits.front()->geographicalId())->position(); GlobalPoint last = gtg_->idToDet(recHits.back()->geographicalId())->position(); // maybe perp2? auto rFirst = first.mag2(); auto rLast = last.mag2(); if (rFirst < rLast) return RefitDirection::insideOut; if (rFirst > rLast) return RefitDirection::outsideIn; } LogDebug("TrackExtenderWithMTD") << "Impossible to determine the rechits order" << endl; return RefitDirection::undetermined; } reco::Track buildTrack(const reco::TrackRef&, const Trajectory&, const Trajectory&, const reco::BeamSpot&, const MagneticField* field, const Propagator* prop, bool hasMTD, float& pathLength, float& tmtdOut, float& sigmatmtdOut, GlobalPoint& tmtdPosOut, float& tofpi, float& tofk, float& tofp, float& sigmatofpi, float& sigmatofk, float& sigmatofp) const; reco::TrackExtra buildTrackExtra(const Trajectory& trajectory) const; string dumpLayer(const DetLayer* layer) const; private: edm::EDPutToken btlMatchChi2Token_; edm::EDPutToken etlMatchChi2Token_; edm::EDPutToken btlMatchTimeChi2Token_; edm::EDPutToken etlMatchTimeChi2Token_; edm::EDPutToken npixBarrelToken_; edm::EDPutToken npixEndcapToken_; edm::EDPutToken outermostHitPositionToken_; edm::EDPutToken pOrigTrkToken_; edm::EDPutToken betaOrigTrkToken_; edm::EDPutToken t0OrigTrkToken_; edm::EDPutToken sigmat0OrigTrkToken_; edm::EDPutToken pathLengthOrigTrkToken_; edm::EDPutToken tmtdOrigTrkToken_; edm::EDPutToken sigmatmtdOrigTrkToken_; edm::EDPutToken tmtdPosOrigTrkToken_; edm::EDPutToken tofpiOrigTrkToken_; edm::EDPutToken tofkOrigTrkToken_; edm::EDPutToken tofpOrigTrkToken_; edm::EDPutToken sigmatofpiOrigTrkToken_; edm::EDPutToken sigmatofkOrigTrkToken_; edm::EDPutToken sigmatofpOrigTrkToken_; edm::EDPutToken assocOrigTrkToken_; edm::EDGetTokenT<InputCollection> tracksToken_; edm::EDGetTokenT<TrajTrackAssociationCollection> trajTrackAToken_; edm::EDGetTokenT<MTDTrackingDetSetVector> hitsToken_; edm::EDGetTokenT<reco::BeamSpot> bsToken_; edm::EDGetTokenT<VertexCollection> vtxToken_; const bool updateTraj_, updateExtra_, updatePattern_; const std::string propagator_, transientTrackBuilder_; std::unique_ptr<TrackTransformer> theTransformer; MTDHitMatcher matcher_; edm::ESHandle<TransientTrackBuilder> builder_; edm::ESGetToken<TransientTrackBuilder, TransientTrackRecord> builderToken_; edm::ESHandle<GlobalTrackingGeometry> gtg_; edm::ESGetToken<GlobalTrackingGeometry, GlobalTrackingGeometryRecord> gtgToken_; edm::ESGetToken<MTDDetLayerGeometry, MTDRecoGeometryRecord> dlgeoToken_; edm::ESGetToken<MagneticField, IdealMagneticFieldRecord> magfldToken_; edm::ESGetToken<Propagator, TrackingComponentsRecord> propToken_; edm::ESGetToken<TrackerTopology, TrackerTopologyRcd> ttopoToken_; const bool useVertex_; const float dzCut_; static constexpr float trackMaxBtlEta_ = 1.5; }; template <class TrackCollection> TrackExtenderWithMTDT<TrackCollection>::TrackExtenderWithMTDT(const ParameterSet& iConfig) : tracksToken_(consumes<InputCollection>(iConfig.getParameter<edm::InputTag>("tracksSrc"))), trajTrackAToken_(consumes<TrajTrackAssociationCollection>(iConfig.getParameter<edm::InputTag>("trjtrkAssSrc"))), hitsToken_(consumes<MTDTrackingDetSetVector>(iConfig.getParameter<edm::InputTag>("hitsSrc"))), bsToken_(consumes<reco::BeamSpot>(iConfig.getParameter<edm::InputTag>("beamSpotSrc"))), updateTraj_(iConfig.getParameter<bool>("updateTrackTrajectory")), updateExtra_(iConfig.getParameter<bool>("updateTrackExtra")), updatePattern_(iConfig.getParameter<bool>("updateTrackHitPattern")), propagator_(iConfig.getParameter<std::string>("Propagator")), transientTrackBuilder_(iConfig.getParameter<std::string>("TransientTrackBuilder")), matcher_(iConfig.getParameterSet("MTDHitMatcher"), consumesCollector()), useVertex_(iConfig.getParameter<bool>("useVertex")), dzCut_(iConfig.getParameter<double>("dZCut")) { if (useVertex_) { vtxToken_ = consumes<VertexCollection>(iConfig.getParameter<edm::InputTag>("vtxSrc")); } theTransformer = std::make_unique<TrackTransformer>(iConfig.getParameterSet("TrackTransformer"), consumesCollector()); btlMatchChi2Token_ = produces<edm::ValueMap<float>>("btlMatchChi2"); etlMatchChi2Token_ = produces<edm::ValueMap<float>>("etlMatchChi2"); btlMatchTimeChi2Token_ = produces<edm::ValueMap<float>>("btlMatchTimeChi2"); etlMatchTimeChi2Token_ = produces<edm::ValueMap<float>>("etlMatchTimeChi2"); npixBarrelToken_ = produces<edm::ValueMap<int>>("npixBarrel"); npixEndcapToken_ = produces<edm::ValueMap<int>>("npixEndcap"); outermostHitPositionToken_ = produces<edm::ValueMap<float>>("generalTrackOutermostHitPosition"); pOrigTrkToken_ = produces<edm::ValueMap<float>>("generalTrackp"); betaOrigTrkToken_ = produces<edm::ValueMap<float>>("generalTrackBeta"); t0OrigTrkToken_ = produces<edm::ValueMap<float>>("generalTrackt0"); sigmat0OrigTrkToken_ = produces<edm::ValueMap<float>>("generalTracksigmat0"); pathLengthOrigTrkToken_ = produces<edm::ValueMap<float>>("generalTrackPathLength"); tmtdOrigTrkToken_ = produces<edm::ValueMap<float>>("generalTracktmtd"); sigmatmtdOrigTrkToken_ = produces<edm::ValueMap<float>>("generalTracksigmatmtd"); tmtdPosOrigTrkToken_ = produces<edm::ValueMap<GlobalPoint>>("generalTrackmtdpos"); tofpiOrigTrkToken_ = produces<edm::ValueMap<float>>("generalTrackTofPi"); tofkOrigTrkToken_ = produces<edm::ValueMap<float>>("generalTrackTofK"); tofpOrigTrkToken_ = produces<edm::ValueMap<float>>("generalTrackTofP"); sigmatofpiOrigTrkToken_ = produces<edm::ValueMap<float>>("generalTrackSigmaTofPi"); sigmatofkOrigTrkToken_ = produces<edm::ValueMap<float>>("generalTrackSigmaTofK"); sigmatofpOrigTrkToken_ = produces<edm::ValueMap<float>>("generalTrackSigmaTofP"); assocOrigTrkToken_ = produces<edm::ValueMap<int>>("generalTrackassoc"); builderToken_ = esConsumes<TransientTrackBuilder, TransientTrackRecord>(edm::ESInputTag("", transientTrackBuilder_)); gtgToken_ = esConsumes<GlobalTrackingGeometry, GlobalTrackingGeometryRecord>(); dlgeoToken_ = esConsumes<MTDDetLayerGeometry, MTDRecoGeometryRecord>(); magfldToken_ = esConsumes<MagneticField, IdealMagneticFieldRecord>(); propToken_ = esConsumes<Propagator, TrackingComponentsRecord>(edm::ESInputTag("", propagator_)); ttopoToken_ = esConsumes<TrackerTopology, TrackerTopologyRcd>(); produces<edm::OwnVector<TrackingRecHit>>(); produces<reco::TrackExtraCollection>(); produces<TrackCollection>(); } template <class TrackCollection> void TrackExtenderWithMTDT<TrackCollection>::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { edm::ParameterSetDescription desc, transDesc; desc.add<edm::InputTag>("tracksSrc", edm::InputTag("generalTracks")); desc.add<edm::InputTag>("trjtrkAssSrc", edm::InputTag("generalTracks")); desc.add<edm::InputTag>("hitsSrc", edm::InputTag("mtdTrackingRecHits")); desc.add<edm::InputTag>("beamSpotSrc", edm::InputTag("offlineBeamSpot")); desc.add<edm::InputTag>("vtxSrc", edm::InputTag("offlinePrimaryVertices4D")); desc.add<bool>("updateTrackTrajectory", true); desc.add<bool>("updateTrackExtra", true); desc.add<bool>("updateTrackHitPattern", true); desc.add<std::string>("TransientTrackBuilder", "TransientTrackBuilder"); desc.add<std::string>("Propagator", "PropagatorWithMaterialForMTD"); TrackTransformer::fillPSetDescription(transDesc, false, "KFFitterForRefitInsideOut", "KFSmootherForRefitInsideOut", "PropagatorWithMaterialForMTD", "alongMomentum", true, "WithTrackAngle", "MuonRecHitBuilder", "MTDRecHitBuilder"); desc.add<edm::ParameterSetDescription>("TrackTransformer", transDesc); edm::ParameterSetDescription matcherDesc; MTDHitMatcher::fillPSetDescription(matcherDesc); desc.add<edm::ParameterSetDescription>("MTDHitMatcher", matcherDesc); desc.add<bool>("useVertex", false); desc.add<double>("dZCut", 0.1); descriptions.add("trackExtenderWithMTDBase", desc); } template <class TrackCollection> template <class H, class T> void TrackExtenderWithMTDT<TrackCollection>::fillValueMap(edm::Event& iEvent, const H& handle, const std::vector<T>& vec, const edm::EDPutToken& token) const { auto out = std::make_unique<edm::ValueMap<T>>(); typename edm::ValueMap<T>::Filler filler(*out); filler.insert(handle, vec.begin(), vec.end()); filler.fill(); iEvent.put(token, std::move(out)); } template <class TrackCollection> void TrackExtenderWithMTDT<TrackCollection>::produce(edm::Event& ev, const edm::EventSetup& es) { //this produces pieces of the track extra Traj2TrackHits t2t; theTransformer->setServices(es); matcher_.setServices(es); TrackingRecHitRefProd hitsRefProd = ev.getRefBeforePut<TrackingRecHitCollection>(); reco::TrackExtraRefProd extrasRefProd = ev.getRefBeforePut<reco::TrackExtraCollection>(); gtg_ = es.getHandle(gtgToken_); auto geo = es.getTransientHandle(dlgeoToken_); auto magfield = es.getTransientHandle(magfldToken_); builder_ = es.getHandle(builderToken_); auto propH = es.getTransientHandle(propToken_); const Propagator* prop = propH.product(); auto httopo = es.getTransientHandle(ttopoToken_); const TrackerTopology& ttopo = *httopo; auto output = std::make_unique<TrackCollection>(); auto extras = std::make_unique<reco::TrackExtraCollection>(); auto outhits = std::make_unique<edm::OwnVector<TrackingRecHit>>(); std::vector<float> btlMatchChi2; std::vector<float> etlMatchChi2; std::vector<float> btlMatchTimeChi2; std::vector<float> etlMatchTimeChi2; std::vector<int> npixBarrel; std::vector<int> npixEndcap; std::vector<float> outermostHitPosition; std::vector<float> pOrigTrkRaw; std::vector<float> betaOrigTrkRaw; std::vector<float> t0OrigTrkRaw; std::vector<float> sigmat0OrigTrkRaw; std::vector<float> pathLengthsOrigTrkRaw; std::vector<float> tmtdOrigTrkRaw; std::vector<float> sigmatmtdOrigTrkRaw; std::vector<GlobalPoint> tmtdPosOrigTrkRaw; std::vector<float> tofpiOrigTrkRaw; std::vector<float> tofkOrigTrkRaw; std::vector<float> tofpOrigTrkRaw; std::vector<float> sigmatofpiOrigTrkRaw; std::vector<float> sigmatofkOrigTrkRaw; std::vector<float> sigmatofpOrigTrkRaw; std::vector<int> assocOrigTrkRaw; auto const tracksH = ev.getHandle(tracksToken_); const auto& trjtrks = ev.get(trajTrackAToken_); //MTD hits DetSet const auto& hits = ev.get(hitsToken_); //beam spot const auto& bs = ev.get(bsToken_); bool vtxConstraint(false); VertexCollection vtxs; if (useVertex_) { vtxs = ev.get(vtxToken_); if (!vtxs.empty()) { vtxConstraint = true; } } std::vector<unsigned> track_indices; unsigned itrack = 0; for (const auto& trjtrk : trjtrks) { const Trajectory& trajs = *trjtrk.key; const reco::TrackRef& track = trjtrk.val; LogTrace("TrackExtenderWithMTD") << "TrackExtenderWithMTD: extrapolating track " << itrack << " p/pT = " << track->p() << " " << track->pt() << " eta = " << track->eta(); LogTrace("TrackExtenderWithMTD") << "TrackExtenderWithMTD: sigma_p = " << sqrt(track->covariance()(0, 0)) * track->p2() << " sigma_p/p = " << sqrt(track->covariance()(0, 0)) * track->p() * 100 << " %"; float trackVtxTime = 0.f; float trackVtxTimeError = 0.f; if (vtxConstraint) { for (const auto& vtx : vtxs) { for (size_t itrk = 0; itrk < vtx.tracksSize(); itrk++) { if (track == vtx.trackRefAt(itrk).castTo<TrackRef>()) { trackVtxTime = vtx.t(); trackVtxTimeError = vtx.tError(); break; } } } } reco::TransientTrack ttrack(track, magfield.product(), gtg_); auto thits = theTransformer->getTransientRecHits(ttrack); TransientTrackingRecHit::ConstRecHitContainer mtdthits; MTDHitMatchingInfo mBTL, mETL; if (trajs.isValid()) { // get the outermost trajectory point on the track TrajectoryStateOnSurface tsos = builder_->build(track).outermostMeasurementState(); TrajectoryStateClosestToBeamLine tscbl; bool tscbl_status = getTrajectoryStateClosestToBeamLine(trajs, bs, prop, tscbl); if (tscbl_status) { float pmag2 = tscbl.trackStateAtPCA().momentum().mag2(); float pathlength0; TrackSegments trs0; trackPathLength(trajs, tscbl, prop, pathlength0, trs0); auto btlResult = matcher_.matchBTL( tsos, trajs, pmag2, pathlength0, trs0, hits, geo.product(), prop, bs, trackVtxTime, trackVtxTimeError); mBTL = btlResult.bestHit; mtdthits.insert(mtdthits.end(), btlResult.hits.begin(), btlResult.hits.end()); // in the future this should include an intermediate refit before propagating to the ETL // for now it is ok auto etlResult = matcher_.matchETL( tsos, trajs, pmag2, pathlength0, trs0, hits, geo.product(), prop, bs, trackVtxTime, trackVtxTimeError); mETL = etlResult.bestHit; mtdthits.insert(mtdthits.end(), etlResult.hits.begin(), etlResult.hits.end()); } #ifdef EDM_ML_DEBUG else { LogTrace("TrackExtenderWithMTD") << "Failing getTrajectoryStateClosestToBeamLine, no search for hits in MTD!"; } #endif } auto ordering = checkRecHitsOrdering(thits); if (ordering == RefitDirection::insideOut) { thits.insert(thits.end(), mtdthits.begin(), mtdthits.end()); } else { std::reverse(mtdthits.begin(), mtdthits.end()); mtdthits.insert(mtdthits.end(), thits.begin(), thits.end()); thits.swap(mtdthits); } const auto& trajwithmtd = mtdthits.empty() ? std::vector<Trajectory>(1, trajs) : theTransformer->transform(ttrack, thits); float pMap = 0.f, betaMap = 0.f, t0Map = 0.f, sigmat0Map = -1.f, pathLengthMap = -1.f, tmtdMap = 0.f, sigmatmtdMap = -1.f, tofpiMap = 0.f, tofkMap = 0.f, tofpMap = 0.f, sigmatofpiMap = -1.f, sigmatofkMap = -1.f, sigmatofpMap = -1.f; GlobalPoint tmtdPosMap{0., 0., 0.}; int iMap = -1; for (const auto& trj : trajwithmtd) { const auto& thetrj = (updateTraj_ ? trj : trajs); float pathLength = 0.f, tmtd = 0.f, sigmatmtd = -1.f, tofpi = 0.f, tofk = 0.f, tofp = 0.f, sigmatofpi = -1.f, sigmatofk = -1.f, sigmatofp = -1.f; GlobalPoint tmtdPos{0., 0., 0.}; LogTrace("TrackExtenderWithMTD") << "TrackExtenderWithMTD: refit track " << itrack << " p/pT = " << track->p() << " " << track->pt() << " eta = " << track->eta(); reco::Track result = buildTrack(track, thetrj, trj, bs, magfield.product(), prop, !trajwithmtd.empty() && !mtdthits.empty(), pathLength, tmtd, sigmatmtd, tmtdPos, tofpi, tofk, tofp, sigmatofpi, sigmatofk, sigmatofp); if (result.ndof() >= 0) { /// setup the track extras reco::TrackExtra::TrajParams trajParams; reco::TrackExtra::Chi2sFive chi2s; size_t hitsstart = outhits->size(); if (updatePattern_) { t2t(trj, *outhits, trajParams, chi2s); // this fills the output hit collection } else { t2t(thetrj, *outhits, trajParams, chi2s); } size_t hitsend = outhits->size(); extras->push_back(buildTrackExtra(trj)); // always push back the fully built extra, update by setting in track extras->back().setHits(hitsRefProd, hitsstart, hitsend - hitsstart); extras->back().setTrajParams(trajParams, chi2s); //create the track output->push_back(result); btlMatchChi2.push_back(mBTL.hit ? mBTL.estChi2 : -1.f); etlMatchChi2.push_back(mETL.hit ? mETL.estChi2 : -1.f); btlMatchTimeChi2.push_back(mBTL.hit ? mBTL.timeChi2 : -1.f); etlMatchTimeChi2.push_back(mETL.hit ? mETL.timeChi2 : -1.f); pathLengthMap = pathLength; tmtdMap = tmtd; sigmatmtdMap = sigmatmtd; tmtdPosMap = tmtdPos; auto& backtrack = output->back(); iMap = output->size() - 1; pMap = backtrack.p(); betaMap = backtrack.beta(); t0Map = backtrack.t0(); sigmat0Map = std::copysign(std::sqrt(std::abs(backtrack.covt0t0())), backtrack.covt0t0()); tofpiMap = tofpi; tofkMap = tofk; tofpMap = tofp; sigmatofpiMap = sigmatofpi; sigmatofkMap = sigmatofk; sigmatofpMap = sigmatofp; reco::TrackExtraRef extraRef(extrasRefProd, extras->size() - 1); backtrack.setExtra((updateExtra_ ? extraRef : track->extra())); for (unsigned ihit = hitsstart; ihit < hitsend; ++ihit) { backtrack.appendHitPattern((*outhits)[ihit], ttopo); } #ifdef EDM_ML_DEBUG LogTrace("TrackExtenderWithMTD") << "TrackExtenderWithMTD: hit pattern of refitted track"; for (int i = 0; i < backtrack.hitPattern().numberOfAllHits(reco::HitPattern::TRACK_HITS); i++) { backtrack.hitPattern().printHitPattern(reco::HitPattern::TRACK_HITS, i, std::cout); } LogTrace("TrackExtenderWithMTD") << "TrackExtenderWithMTD: missing hit pattern of refitted track"; for (int i = 0; i < backtrack.hitPattern().numberOfAllHits(reco::HitPattern::MISSING_INNER_HITS); i++) { backtrack.hitPattern().printHitPattern(reco::HitPattern::MISSING_INNER_HITS, i, std::cout); } #endif npixBarrel.push_back(backtrack.hitPattern().numberOfValidPixelBarrelHits()); npixEndcap.push_back(backtrack.hitPattern().numberOfValidPixelEndcapHits()); if (mBTL.hit || mETL.hit) { outermostHitPosition.push_back( mBTL.hit ? (float)(*track).outerRadius() : (float)(*track).outerZ()); // save R of the outermost hit for BTL, z for ETL. } else { outermostHitPosition.push_back(std::abs(track->eta()) < trackMaxBtlEta_ ? (float)(*track).outerRadius() : (float)(*track).outerZ()); } LogTrace("TrackExtenderWithMTD") << "TrackExtenderWithMTD: tmtd " << tmtdMap << " +/- " << sigmatmtdMap << " t0 " << t0Map << " +/- " << sigmat0Map << " tof pi/K/p " << tofpiMap << "+/-" << std::format("{:0.2g}", sigmatofpiMap) << " (" << std::format("{:0.2g}", sigmatofpiMap / tofpiMap * 100) << "%) " << tofkMap << "+/-" << std::format("{:0.2g}", sigmatofkMap) << " (" << std::format("{:0.2g}", sigmatofkMap / tofkMap * 100) << "%) " << tofpMap << "+/-" << std::format("{:0.2g}", sigmatofpMap) << " (" << std::format("{:0.2g}", sigmatofpMap / tofpMap * 100) << "%) "; } else { LogTrace("TrackExtenderWithMTD") << "Error in the MTD track refitting. This should not happen"; } } pOrigTrkRaw.push_back(pMap); betaOrigTrkRaw.push_back(betaMap); t0OrigTrkRaw.push_back(t0Map); sigmat0OrigTrkRaw.push_back(sigmat0Map); pathLengthsOrigTrkRaw.push_back(pathLengthMap); tmtdOrigTrkRaw.push_back(tmtdMap); sigmatmtdOrigTrkRaw.push_back(sigmatmtdMap); tmtdPosOrigTrkRaw.push_back(tmtdPosMap); tofpiOrigTrkRaw.push_back(tofpiMap); tofkOrigTrkRaw.push_back(tofkMap); tofpOrigTrkRaw.push_back(tofpMap); sigmatofpiOrigTrkRaw.push_back(sigmatofpiMap); sigmatofkOrigTrkRaw.push_back(sigmatofkMap); sigmatofpOrigTrkRaw.push_back(sigmatofpMap); assocOrigTrkRaw.push_back(iMap); if (iMap == -1) { btlMatchChi2.push_back(-1.f); etlMatchChi2.push_back(-1.f); btlMatchTimeChi2.push_back(-1.f); etlMatchTimeChi2.push_back(-1.f); npixBarrel.push_back(-1.f); npixEndcap.push_back(-1.f); outermostHitPosition.push_back(0.); } ++itrack; } ev.put(std::move(output)); ev.put(std::move(extras)); ev.put(std::move(outhits)); fillValueMap(ev, tracksH, btlMatchChi2, btlMatchChi2Token_); fillValueMap(ev, tracksH, etlMatchChi2, etlMatchChi2Token_); fillValueMap(ev, tracksH, btlMatchTimeChi2, btlMatchTimeChi2Token_); fillValueMap(ev, tracksH, etlMatchTimeChi2, etlMatchTimeChi2Token_); fillValueMap(ev, tracksH, npixBarrel, npixBarrelToken_); fillValueMap(ev, tracksH, npixEndcap, npixEndcapToken_); fillValueMap(ev, tracksH, outermostHitPosition, outermostHitPositionToken_); fillValueMap(ev, tracksH, pOrigTrkRaw, pOrigTrkToken_); fillValueMap(ev, tracksH, betaOrigTrkRaw, betaOrigTrkToken_); fillValueMap(ev, tracksH, t0OrigTrkRaw, t0OrigTrkToken_); fillValueMap(ev, tracksH, sigmat0OrigTrkRaw, sigmat0OrigTrkToken_); fillValueMap(ev, tracksH, pathLengthsOrigTrkRaw, pathLengthOrigTrkToken_); fillValueMap(ev, tracksH, tmtdOrigTrkRaw, tmtdOrigTrkToken_); fillValueMap(ev, tracksH, sigmatmtdOrigTrkRaw, sigmatmtdOrigTrkToken_); fillValueMap(ev, tracksH, tmtdPosOrigTrkRaw, tmtdPosOrigTrkToken_); fillValueMap(ev, tracksH, tofpiOrigTrkRaw, tofpiOrigTrkToken_); fillValueMap(ev, tracksH, tofkOrigTrkRaw, tofkOrigTrkToken_); fillValueMap(ev, tracksH, tofpOrigTrkRaw, tofpOrigTrkToken_); fillValueMap(ev, tracksH, sigmatofpiOrigTrkRaw, sigmatofpiOrigTrkToken_); fillValueMap(ev, tracksH, sigmatofkOrigTrkRaw, sigmatofkOrigTrkToken_); fillValueMap(ev, tracksH, sigmatofpOrigTrkRaw, sigmatofpOrigTrkToken_); fillValueMap(ev, tracksH, assocOrigTrkRaw, assocOrigTrkToken_); } //below is unfortunately ripped from other places but //since track producer doesn't know about MTD we have to do this template <class TrackCollection> reco::Track TrackExtenderWithMTDT<TrackCollection>::buildTrack(const reco::TrackRef& orig, const Trajectory& traj, const Trajectory& trajWithMtd, const reco::BeamSpot& bs, const MagneticField* field, const Propagator* thePropagator, bool hasMTD, float& pathLengthOut, float& tmtdOut, float& sigmatmtdOut, GlobalPoint& tmtdPosOut, float& tofpi, float& tofk, float& tofp, float& sigmatofpi, float& sigmatofk, float& sigmatofp) const { TrajectoryStateClosestToBeamLine tscbl; bool tsbcl_status = getTrajectoryStateClosestToBeamLine(traj, bs, thePropagator, tscbl); if (!tsbcl_status) return reco::Track(); GlobalPoint v = tscbl.trackStateAtPCA().position(); math::XYZPoint pos(v.x(), v.y(), v.z()); GlobalVector p = tscbl.trackStateAtPCA().momentum(); math::XYZVector mom(p.x(), p.y(), p.z()); int ndof = traj.ndof(); float t0 = 0.f; float covt0t0 = -1.f; pathLengthOut = -1.f; // if there is no MTD flag the pathlength with -1 tmtdOut = 0.f; sigmatmtdOut = -1.f; float betaOut = 0.f; float covbetabeta = -1.f; auto routput = [&]() { return reco::Track(traj.chiSquared(), int(ndof), pos, mom, tscbl.trackStateAtPCA().charge(), tscbl.trackStateAtPCA().curvilinearError(), orig->algo(), reco::TrackBase::undefQuality, t0, betaOut, covt0t0, covbetabeta); }; //compute path length for time backpropagation, using first MTD hit for the momentum if (hasMTD) { float pathlength; TrackSegments trs; bool validpropagation = trackPathLength(trajWithMtd, bs, thePropagator, pathlength, trs); float thit = 0.f; float thiterror = -1.f; GlobalPoint thitpos{0., 0., 0.}; bool validmtd = false; if (!validpropagation) { return routput(); } uint32_t ihitcount(0), ietlcount(0); for (auto const& hit : trajWithMtd.measurements()) { if (hit.recHit()->geographicalId().det() == DetId::Forward && ForwardSubdetector(hit.recHit()->geographicalId().subdetId()) == FastTime) { ihitcount++; if (MTDDetId(hit.recHit()->geographicalId()).mtdSubDetector() == MTDDetId::MTDType::ETL) { ietlcount++; } } } LogTrace("TrackExtenderWithMTD") << "TrackExtenderWithMTD: selected #hits " << ihitcount << " from ETL " << ietlcount; auto ihit1 = trajWithMtd.measurements().cbegin(); if (ihitcount == 1) { const MTDTrackingRecHit* mtdhit = static_cast<const MTDTrackingRecHit*>((*ihit1).recHit()->hit()); thit = mtdhit->time(); thiterror = mtdhit->timeError(); thitpos = mtdhit->globalPosition(); validmtd = true; } else if (ihitcount == 2 && ietlcount == 2) { std::pair<float, float> lastStep = trs.segmentPathAndMom2(0); float etlpathlength = std::abs(lastStep.first * c_cm_ns); // // The information of the two ETL hits is combined and attributed to the innermost hit // if (etlpathlength == 0.f) { validpropagation = false; } else { pathlength -= etlpathlength; trs.removeFirstSegment(); const MTDTrackingRecHit* mtdhit1 = static_cast<const MTDTrackingRecHit*>((*ihit1).recHit()->hit()); const MTDTrackingRecHit* mtdhit2 = static_cast<const MTDTrackingRecHit*>((*(ihit1 + 1)).recHit()->hit()); TrackTofPidInfo tofInfo = computeTrackTofPidInfo( lastStep.second, etlpathlength, trs, mtdhit1->time(), mtdhit1->timeError(), 0.f, 0.f, true, TofCalc::kCost); // // Protect against incompatible times // float err1 = tofInfo.dterror2; float err2 = mtdhit2->timeError() * mtdhit2->timeError(); if (cms_rounding::roundIfNear0(err1) == 0.f || cms_rounding::roundIfNear0(err2) == 0.f) { edm::LogError("TrackExtenderWithMTD") << "MTD tracking hits with zero time uncertainty: " << err1 << " " << err2; } else { if ((tofInfo.dt - mtdhit2->time()) * (tofInfo.dt - mtdhit2->time()) < (err1 + err2) * matcher_.etlTimeChi2Cut()) { // // Subtract the ETL time of flight from the outermost measurement, and combine it in a weighted average with the innermost // the mass ambiguity related uncertainty on the time of flight is added as an additional uncertainty // err1 = 1.f / err1; err2 = 1.f / err2; thiterror = 1.f / (err1 + err2); thit = (tofInfo.dt * err1 + mtdhit2->time() * err2) * thiterror; thiterror = std::sqrt(thiterror); thitpos = mtdhit2->globalPosition(); LogTrace("TrackExtenderWithMTD") << "TrackExtenderWithMTD: p trk = " << p.mag() << " ETL hits times/errors: 1) " << mtdhit1->time() << " +/- " << mtdhit1->timeError() << " , 2) " << mtdhit2->time() << " +/- " << mtdhit2->timeError() << " extrapolated time1: " << tofInfo.dt << " +/- " << tofInfo.dterror << " average = " << thit << " +/- " << thiterror << "\n hit1 pos: " << mtdhit1->globalPosition() << " hit2 pos: " << mtdhit2->globalPosition() << " etl path length " << etlpathlength << std::endl; validmtd = true; } else { // if back extrapolated time of the outermost measurement not compatible with the innermost, keep the one with smallest error if (err1 <= err2) { thit = tofInfo.dt; thiterror = tofInfo.dterror; validmtd = true; } else { thit = mtdhit2->time(); thiterror = mtdhit2->timeError(); validmtd = true; } } } } } else { edm::LogInfo("TrackExtenderWithMTD") << "MTD hits #" << ihitcount << "ETL hits #" << ietlcount << " anomalous pattern, skipping..."; } if (validmtd && validpropagation) { //here add the PID uncertainty for later use in the 1st step of 4D vtx reconstruction TrackTofPidInfo tofInfo = computeTrackTofPidInfo( p.mag2(), pathlength, trs, thit, thiterror, 0.f, 0.f, true, TofCalc::kSegm, SigmaTofCalc::kCost); pathLengthOut = pathlength; // set path length if we've got a timing hit tmtdOut = thit; sigmatmtdOut = thiterror; tmtdPosOut = thitpos; t0 = tofInfo.dt; covt0t0 = tofInfo.dterror2; betaOut = tofInfo.beta_pi; covbetabeta = tofInfo.betaerror * tofInfo.betaerror; tofpi = tofInfo.dt_pi; tofk = tofInfo.dt_k; tofp = tofInfo.dt_p; sigmatofpi = tofInfo.sigma_dt_pi; sigmatofk = tofInfo.sigma_dt_k; sigmatofp = tofInfo.sigma_dt_p; } } return routput(); } template <class TrackCollection> reco::TrackExtra TrackExtenderWithMTDT<TrackCollection>::buildTrackExtra(const Trajectory& trajectory) const { static const string metname = "TrackExtenderWithMTD"; const Trajectory::RecHitContainer transRecHits = trajectory.recHits(); // put the collection of TrackingRecHit in the event // sets the outermost and innermost TSOSs // ToDo: validation for track states with MTD TrajectoryStateOnSurface outerTSOS; TrajectoryStateOnSurface innerTSOS; unsigned int innerId = 0, outerId = 0; TrajectoryMeasurement::ConstRecHitPointer outerRecHit; DetId outerDetId; if (trajectory.direction() == alongMomentum) { LogTrace(metname) << "alongMomentum"; outerTSOS = trajectory.lastMeasurement().updatedState(); innerTSOS = trajectory.firstMeasurement().updatedState(); outerId = trajectory.lastMeasurement().recHit()->geographicalId().rawId(); innerId = trajectory.firstMeasurement().recHit()->geographicalId().rawId(); outerRecHit = trajectory.lastMeasurement().recHit(); outerDetId = trajectory.lastMeasurement().recHit()->geographicalId(); } else if (trajectory.direction() == oppositeToMomentum) { LogTrace(metname) << "oppositeToMomentum"; outerTSOS = trajectory.firstMeasurement().updatedState(); innerTSOS = trajectory.lastMeasurement().updatedState(); outerId = trajectory.firstMeasurement().recHit()->geographicalId().rawId(); innerId = trajectory.lastMeasurement().recHit()->geographicalId().rawId(); outerRecHit = trajectory.firstMeasurement().recHit(); outerDetId = trajectory.firstMeasurement().recHit()->geographicalId(); } else LogError(metname) << "Wrong propagation direction!"; const GeomDet* outerDet = gtg_->idToDet(outerDetId); GlobalPoint outerTSOSPos = outerTSOS.globalParameters().position(); bool inside = outerDet->surface().bounds().inside(outerDet->toLocal(outerTSOSPos)); GlobalPoint hitPos = (outerRecHit->isValid()) ? outerRecHit->globalPosition() : outerTSOS.globalParameters().position(); if (!inside) { LogTrace(metname) << "The Global Muon outerMostMeasurementState is not compatible with the recHit detector!" << " Setting outerMost postition to recHit position if recHit isValid: " << outerRecHit->isValid(); LogTrace(metname) << "From " << outerTSOSPos << " to " << hitPos; } //build the TrackExtra GlobalPoint v = (inside) ? outerTSOSPos : hitPos; GlobalVector p = outerTSOS.globalParameters().momentum(); math::XYZPoint outpos(v.x(), v.y(), v.z()); math::XYZVector outmom(p.x(), p.y(), p.z()); v = innerTSOS.globalParameters().position(); p = innerTSOS.globalParameters().momentum(); math::XYZPoint inpos(v.x(), v.y(), v.z()); math::XYZVector inmom(p.x(), p.y(), p.z()); reco::TrackExtra trackExtra(outpos, outmom, true, inpos, inmom, true, outerTSOS.curvilinearError(), outerId, innerTSOS.curvilinearError(), innerId, trajectory.direction(), trajectory.seedRef()); return trackExtra; } template <class TrackCollection> string TrackExtenderWithMTDT<TrackCollection>::dumpLayer(const DetLayer* layer) const { stringstream output; const BoundSurface* sur = nullptr; const BoundCylinder* bc = nullptr; const BoundDisk* bd = nullptr; sur = &(layer->surface()); if ((bc = dynamic_cast<const BoundCylinder*>(sur))) { output << " Cylinder of radius: " << bc->radius() << endl; } else if ((bd = dynamic_cast<const BoundDisk*>(sur))) { output << " Disk at: " << bd->position().z() << endl; } return output.str(); } //define this as a plug-in #include <FWCore/Framework/interface/MakerMacros.h> #include "DataFormats/TrackReco/interface/Track.h" #include "DataFormats/TrackReco/interface/TrackFwd.h" #include "DataFormats/GsfTrackReco/interface/GsfTrack.h" #include "DataFormats/GsfTrackReco/interface/GsfTrackFwd.h" typedef TrackExtenderWithMTDT<reco::TrackCollection> TrackExtenderWithMTD; DEFINE_FWK_MODULE(TrackExtenderWithMTD);