File indexing completed on 2025-04-08 03:34:54
0001
0002
0003
0004
0005
0006
0007
0008 #include "CommonTools/Utils/interface/StringCutObjectSelector.h"
0009 #include "DataFormats/Math/interface/deltaR.h"
0010 #include "DataFormats/MuonReco/interface/Muon.h"
0011 #include "FWCore/Framework/interface/Event.h"
0012 #include "FWCore/Framework/interface/EventSetup.h"
0013 #include "FWCore/Framework/interface/stream/EDProducer.h"
0014 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0015 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0016 #include "FWCore/Utilities/interface/InputTag.h"
0017 #include "Geometry/CommonDetUnit/interface/GlobalTrackingGeometry.h"
0018 #include "Geometry/Records/interface/GlobalTrackingGeometryRecord.h"
0019 #include "MagneticField/Engine/interface/MagneticField.h"
0020 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
0021 #include "RecoTracker/MeasurementDet/interface/MeasurementTracker.h"
0022 #include "RecoTracker/MeasurementDet/interface/MeasurementTrackerEvent.h"
0023 #include "RecoTracker/TkDetLayers/interface/GeometricSearchTracker.h"
0024 #include "TrackingTools/GeomPropagators/interface/Propagator.h"
0025 #include "TrackingTools/KalmanUpdators/interface/Chi2MeasurementEstimatorBase.h"
0026 #include "TrackingTools/KalmanUpdators/interface/KFUpdator.h"
0027 #include "TrackingTools/MeasurementDet/interface/MeasurementDet.h"
0028 #include "TrackingTools/PatternTools/interface/TrajMeasLessEstim.h"
0029 #include "TrackingTools/PatternTools/interface/TrajectoryMeasurement.h"
0030 #include "TrackingTools/PatternTools/interface/TrajectoryStateUpdator.h"
0031 #include "TrackingTools/Records/interface/TrackingComponentsRecord.h"
0032 #include "TrackingTools/TrackRefitter/interface/TrackTransformer.h"
0033 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateOnSurface.h"
0034 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h"
0035
0036 class OutsideInMuonSeeder final : public edm::stream::EDProducer<> {
0037 public:
0038 explicit OutsideInMuonSeeder(const edm::ParameterSet &iConfig);
0039 ~OutsideInMuonSeeder() override = default;
0040
0041 void produce(edm::Event &iEvent, const edm::EventSetup &iSetup) override;
0042
0043 static void fillDescriptions(edm::ConfigurationDescriptions &descriptions);
0044
0045 private:
0046
0047 edm::EDGetTokenT<edm::View<reco::Muon>> src_;
0048
0049
0050 StringCutObjectSelector<reco::Muon> selector_;
0051
0052
0053 const int layersToTry_;
0054
0055
0056 const int hitsToTry_;
0057
0058
0059 const bool fromVertex_;
0060
0061
0062 const double errorRescaling_;
0063
0064 const edm::ESGetToken<Propagator, TrackingComponentsRecord> trackerPropagatorToken_;
0065 const edm::ESGetToken<Propagator, TrackingComponentsRecord> muonPropagatorToken_;
0066 const edm::EDGetTokenT<MeasurementTrackerEvent> measurementTrackerTag_;
0067 const edm::ESGetToken<Chi2MeasurementEstimatorBase, TrackingComponentsRecord> estimatorToken_;
0068 const edm::ESGetToken<TrajectoryStateUpdator, TrackingComponentsRecord> updatorToken_;
0069 const edm::ESGetToken<MagneticField, IdealMagneticFieldRecord> magfieldToken_;
0070 const edm::ESGetToken<GlobalTrackingGeometry, GlobalTrackingGeometryRecord> geometryToken_;
0071 const edm::ESGetToken<TrackerGeometry, TrackerDigiGeometryRecord> tkGeometryToken_;
0072
0073 float const minEtaForTEC_;
0074 float const maxEtaForTOB_;
0075
0076 const MagneticField *magfield_;
0077 const Propagator *muonPropagator_;
0078 const GlobalTrackingGeometry *geometry_;
0079 const Chi2MeasurementEstimatorBase *estimator_;
0080 const TrajectoryStateUpdator *updator_;
0081
0082
0083 const bool debug_;
0084
0085 int doLayer(const GeometricSearchDet &layer,
0086 const TrajectoryStateOnSurface &state,
0087 std::vector<TrajectorySeed> &out,
0088 const Propagator &muon_propagator,
0089 const Propagator &tracker_propagator,
0090 const MeasurementTrackerEvent &mte) const;
0091 void doDebug(const reco::Track &tk) const;
0092 };
0093
0094 OutsideInMuonSeeder::OutsideInMuonSeeder(const edm::ParameterSet &iConfig)
0095 : src_(consumes<edm::View<reco::Muon>>(iConfig.getParameter<edm::InputTag>("src"))),
0096 selector_(iConfig.existsAs<std::string>("cut") ? iConfig.getParameter<std::string>("cut") : "", true),
0097 layersToTry_(iConfig.getParameter<int32_t>("layersToTry")),
0098 hitsToTry_(iConfig.getParameter<int32_t>("hitsToTry")),
0099 fromVertex_(iConfig.getParameter<bool>("fromVertex")),
0100 errorRescaling_(iConfig.getParameter<double>("errorRescaleFactor")),
0101 trackerPropagatorToken_(esConsumes(edm::ESInputTag("", iConfig.getParameter<std::string>("trackerPropagator")))),
0102 muonPropagatorToken_(esConsumes(edm::ESInputTag("", iConfig.getParameter<std::string>("muonPropagator")))),
0103 measurementTrackerTag_(
0104 consumes<MeasurementTrackerEvent>(iConfig.getParameter<edm::InputTag>("measurementTkEvent"))),
0105 estimatorToken_(esConsumes(edm::ESInputTag("", iConfig.getParameter<std::string>("hitCollector")))),
0106 updatorToken_(esConsumes(edm::ESInputTag("", iConfig.getParameter<std::string>("updatorLabel")))),
0107 magfieldToken_(esConsumes()),
0108 geometryToken_(esConsumes()),
0109 tkGeometryToken_(esConsumes()),
0110 minEtaForTEC_(iConfig.getParameter<double>("minEtaForTEC")),
0111 maxEtaForTOB_(iConfig.getParameter<double>("maxEtaForTOB")),
0112 debug_(iConfig.getUntrackedParameter<bool>("debug", false)) {
0113 produces<std::vector<TrajectorySeed>>();
0114 }
0115
0116 void OutsideInMuonSeeder::produce(edm::Event &iEvent, const edm::EventSetup &iSetup) {
0117 using namespace edm;
0118 using namespace std;
0119
0120 magfield_ = &iSetup.getData(magfieldToken_);
0121 auto const &trackerPropagator = iSetup.getData(trackerPropagatorToken_);
0122 muonPropagator_ = &iSetup.getData(muonPropagatorToken_);
0123 geometry_ = &iSetup.getData(geometryToken_);
0124 estimator_ = &iSetup.getData(estimatorToken_);
0125 updator_ = &iSetup.getData(updatorToken_);
0126
0127 Handle<MeasurementTrackerEvent> measurementTracker;
0128 iEvent.getByToken(measurementTrackerTag_, measurementTracker);
0129
0130 const auto &tmpTkGeometry = iSetup.getData(tkGeometryToken_);
0131
0132 Handle<View<reco::Muon>> src;
0133 iEvent.getByToken(src_, src);
0134
0135 auto out = std::make_unique<std::vector<TrajectorySeed>>();
0136
0137 for (auto const &mu : *src) {
0138 if (mu.outerTrack().isNull() || !selector_(mu))
0139 continue;
0140 if (debug_ && mu.innerTrack().isNonnull())
0141 doDebug(*mu.innerTrack());
0142
0143
0144
0145
0146 std::unique_ptr<Propagator> pmuon_cloned =
0147 SetPropagationDirection(*muonPropagator_, fromVertex_ ? alongMomentum : oppositeToMomentum);
0148 std::unique_ptr<Propagator> ptracker_cloned = SetPropagationDirection(trackerPropagator, alongMomentum);
0149
0150 int sizeBefore = out->size();
0151 if (debug_)
0152 LogDebug("OutsideInMuonSeeder") << "\n\n\nSeeding for muon of pt " << mu.pt() << ", eta " << mu.eta() << ", phi "
0153 << mu.phi() << std::endl;
0154 const reco::Track &tk = *mu.outerTrack();
0155
0156 TrajectoryStateOnSurface state =
0157 fromVertex_ ? TrajectoryStateOnSurface(trajectoryStateTransform::initialFreeState(tk, magfield_))
0158 : trajectoryStateTransform::innerStateOnSurface(tk, *geometry_, magfield_);
0159
0160 if (std::abs(tk.eta()) < maxEtaForTOB_) {
0161 std::vector<BarrelDetLayer const *> const &tob = measurementTracker->geometricSearchTracker()->tobLayers();
0162 int found = 0;
0163 int iLayer = tob.size();
0164 if (iLayer == 0)
0165 LogError("OutsideInMuonSeeder") << "TOB has no layers.";
0166
0167 for (auto it = tob.rbegin(), ed = tob.rend(); it != ed; ++it, --iLayer) {
0168 if (debug_)
0169 LogDebug("OutsideInMuonSeeder") << "\n ==== Trying TOB " << iLayer << " ====" << std::endl;
0170 if (doLayer(**it, state, *out, *(pmuon_cloned.get()), *(ptracker_cloned.get()), *measurementTracker)) {
0171 if (++found == layersToTry_)
0172 break;
0173 }
0174 }
0175 }
0176 if (tk.eta() > minEtaForTEC_) {
0177 const auto &forwLayers = tmpTkGeometry.isThere(GeomDetEnumerators::P2OTEC)
0178 ? measurementTracker->geometricSearchTracker()->posTidLayers()
0179 : measurementTracker->geometricSearchTracker()->posTecLayers();
0180 if (tmpTkGeometry.isThere(GeomDetEnumerators::P2OTEC)) {
0181 LogDebug("OutsideInMuonSeeder") << "\n We are using the Phase2 Outer Tracker (defined as a TID+). ";
0182 }
0183 LogTrace("OutsideInMuonSeeder") << "\n ==== TEC+ tot layers " << forwLayers.size() << " ====" << std::endl;
0184 int found = 0;
0185 int iLayer = forwLayers.size();
0186 if (iLayer == 0)
0187 LogError("OutsideInMuonSeeder") << "TEC+ has no layers.";
0188
0189 if (debug_)
0190 LogDebug("OutsideInMuonSeeder") << "\n ==== Tot layers " << forwLayers.size() << " ====" << std::endl;
0191 for (auto it = forwLayers.rbegin(), ed = forwLayers.rend(); it != ed; ++it, --iLayer) {
0192 if (debug_)
0193 LogDebug("OutsideInMuonSeeder") << "\n ==== Trying Forward Layer +" << +iLayer << " ====" << std::endl;
0194 if (doLayer(**it, state, *out, *(pmuon_cloned.get()), *(ptracker_cloned.get()), *measurementTracker)) {
0195 if (++found == layersToTry_)
0196 break;
0197 }
0198 }
0199 }
0200 if (tk.eta() < -minEtaForTEC_) {
0201 const auto &forwLayers = tmpTkGeometry.isThere(GeomDetEnumerators::P2OTEC)
0202 ? measurementTracker->geometricSearchTracker()->negTidLayers()
0203 : measurementTracker->geometricSearchTracker()->negTecLayers();
0204 if (tmpTkGeometry.isThere(GeomDetEnumerators::P2OTEC)) {
0205 LogDebug("OutsideInMuonSeeder") << "\n We are using the Phase2 Outer Tracker (defined as a TID-). ";
0206 }
0207 LogTrace("OutsideInMuonSeeder") << "\n ==== TEC- tot layers " << forwLayers.size() << " ====" << std::endl;
0208 int found = 0;
0209 int iLayer = forwLayers.size();
0210 if (iLayer == 0)
0211 LogError("OutsideInMuonSeeder") << "TEC- has no layers.";
0212
0213 if (debug_)
0214 LogDebug("OutsideInMuonSeeder") << "\n ==== Tot layers " << forwLayers.size() << " ====" << std::endl;
0215 for (auto it = forwLayers.rbegin(), ed = forwLayers.rend(); it != ed; ++it, --iLayer) {
0216 if (debug_)
0217 LogDebug("OutsideInMuonSeeder") << "\n ==== Trying Forward Layer -" << -iLayer << " ====" << std::endl;
0218 if (doLayer(**it, state, *out, *(pmuon_cloned.get()), *(ptracker_cloned.get()), *measurementTracker)) {
0219 if (++found == layersToTry_)
0220 break;
0221 }
0222 }
0223 }
0224 if (debug_)
0225 LogDebug("OutsideInMuonSeeder") << "Outcome of seeding for muon of pt " << mu.pt() << ", eta " << mu.eta()
0226 << ", phi " << mu.phi() << ": found " << (out->size() - sizeBefore) << " seeds."
0227 << std::endl;
0228 }
0229
0230 iEvent.put(std::move(out));
0231 }
0232
0233 int OutsideInMuonSeeder::doLayer(const GeometricSearchDet &layer,
0234 const TrajectoryStateOnSurface &state,
0235 std::vector<TrajectorySeed> &out,
0236 const Propagator &muon_propagator,
0237 const Propagator &tracker_propagator,
0238 const MeasurementTrackerEvent &measurementTracker) const {
0239 TrajectoryStateOnSurface onLayer(state);
0240 onLayer.rescaleError(errorRescaling_);
0241 std::vector<GeometricSearchDet::DetWithState> dets;
0242 layer.compatibleDetsV(onLayer, muon_propagator, *estimator_, dets);
0243
0244 if (debug_) {
0245 LogDebug("OutsideInMuonSeeder") << "Query on layer around x = " << onLayer.globalPosition()
0246 << " with local pos error " << sqrt(onLayer.localError().positionError().xx())
0247 << " , " << sqrt(onLayer.localError().positionError().yy()) << " , "
0248 << " returned " << dets.size() << " compatible detectors" << std::endl;
0249 }
0250
0251 std::vector<TrajectoryMeasurement> meas;
0252 for (std::vector<GeometricSearchDet::DetWithState>::const_iterator it = dets.begin(), ed = dets.end(); it != ed;
0253 ++it) {
0254 MeasurementDetWithData det = measurementTracker.idToDet(it->first->geographicalId());
0255 if (det.isNull()) {
0256 std::cerr << "BOGUS detid " << it->first->geographicalId().rawId() << std::endl;
0257 continue;
0258 }
0259 if (!it->second.isValid())
0260 continue;
0261 std::vector<TrajectoryMeasurement> mymeas =
0262 det.fastMeasurements(it->second, state, tracker_propagator, *estimator_);
0263 if (debug_)
0264 LogDebug("OutsideInMuonSeeder") << "Query on detector " << it->first->geographicalId().rawId() << " returned "
0265 << mymeas.size() << " measurements." << std::endl;
0266 for (std::vector<TrajectoryMeasurement>::const_iterator it2 = mymeas.begin(), ed2 = mymeas.end(); it2 != ed2;
0267 ++it2) {
0268 if (it2->recHit()->isValid())
0269 meas.push_back(*it2);
0270 }
0271 }
0272 int found = 0;
0273 std::sort(meas.begin(), meas.end(), TrajMeasLessEstim());
0274 for (std::vector<TrajectoryMeasurement>::const_iterator it2 = meas.begin(), ed2 = meas.end(); it2 != ed2; ++it2) {
0275 if (debug_) {
0276 LogDebug("OutsideInMuonSeeder") << " inspecting Hit with chi2 = " << it2->estimate() << std::endl;
0277 LogDebug("OutsideInMuonSeeder") << " track state " << it2->forwardPredictedState().globalPosition()
0278 << std::endl;
0279 LogDebug("OutsideInMuonSeeder") << " rechit position " << it2->recHit()->globalPosition() << std::endl;
0280 }
0281 TrajectoryStateOnSurface updated = updator_->update(it2->forwardPredictedState(), *it2->recHit());
0282 if (updated.isValid()) {
0283 if (debug_)
0284 LogDebug("OutsideInMuonSeeder") << " --> updated state: x = " << updated.globalPosition()
0285 << ", p = " << updated.globalMomentum() << std::endl;
0286 edm::OwnVector<TrackingRecHit> seedHits;
0287 seedHits.push_back(*it2->recHit()->hit());
0288 PTrajectoryStateOnDet const &pstate =
0289 trajectoryStateTransform::persistentState(updated, it2->recHit()->geographicalId().rawId());
0290 TrajectorySeed seed(pstate, std::move(seedHits), oppositeToMomentum);
0291 out.push_back(seed);
0292 found++;
0293 if (found == hitsToTry_)
0294 break;
0295 }
0296 }
0297 return found;
0298 }
0299
0300 void OutsideInMuonSeeder::doDebug(const reco::Track &tk) const {
0301 TrajectoryStateOnSurface tsos = trajectoryStateTransform::innerStateOnSurface(tk, *geometry_, magfield_);
0302 std::unique_ptr<Propagator> pmuon_cloned = SetPropagationDirection(*muonPropagator_, alongMomentum);
0303 for (unsigned int i = 0; i < tk.recHitsSize(); ++i) {
0304 const TrackingRecHit *hit = &*tk.recHit(i);
0305 const GeomDet *det = geometry_->idToDet(hit->geographicalId());
0306 if (det == nullptr)
0307 continue;
0308 if (i != 0)
0309 tsos = pmuon_cloned->propagate(tsos, det->surface());
0310 if (!tsos.isValid())
0311 continue;
0312 LogDebug("OutsideInMuonSeeder") << " state " << i << " at x = " << tsos.globalPosition()
0313 << ", p = " << tsos.globalMomentum() << std::endl;
0314 if (hit->isValid()) {
0315 LogDebug("OutsideInMuonSeeder") << " valid rechit on detid " << hit->geographicalId().rawId()
0316 << std::endl;
0317 } else {
0318 LogDebug("OutsideInMuonSeeder") << " invalid rechit on detid " << hit->geographicalId().rawId()
0319 << std::endl;
0320 }
0321 }
0322 }
0323
0324 void OutsideInMuonSeeder::fillDescriptions(edm::ConfigurationDescriptions &descriptions) {
0325 edm::ParameterSetDescription desc;
0326 desc.add<edm::InputTag>("src", edm::InputTag("muons"));
0327 desc.add<std::string>("cut", {});
0328 desc.add<int32_t>("layersToTry", 3);
0329 desc.add<int32_t>("hitsToTry", 3);
0330 desc.add<bool>("fromVertex", true);
0331 desc.add<double>("errorRescaleFactor", 2.0);
0332 desc.add<std::string>("trackerPropagator", {});
0333 desc.add<std::string>("muonPropagator", {});
0334 desc.add<edm::InputTag>("measurementTkEvent", edm::InputTag("MeasurementTrackerEvent"));
0335 desc.add<std::string>("hitCollector", {});
0336 desc.add<std::string>("updatorLabel", "KFUpdator");
0337 desc.add<double>("minEtaForTEC", 0.7);
0338 desc.add<double>("maxEtaForTOB", 1.8);
0339 desc.addUntracked<bool>("debug", false);
0340 descriptions.addWithDefaultLabel(desc);
0341 }
0342
0343 #include "FWCore/Framework/interface/MakerMacros.h"
0344 DEFINE_FWK_MODULE(OutsideInMuonSeeder);