File indexing completed on 2024-04-06 12:28:57
0001 #ifndef RecoTracker_TkTrackingRegions_L1MuonSeededTrackingRegionsProducer_h
0002 #define RecoTracker_TkTrackingRegions_L1MuonSeededTrackingRegionsProducer_h
0003
0004 #include "RecoTracker/TkTrackingRegions/interface/TrackingRegionProducer.h"
0005 #include "RecoTracker/TkTrackingRegions/interface/RectangularEtaPhiTrackingRegion.h"
0006 #include "RecoTracker/MeasurementDet/interface/MeasurementTrackerEvent.h"
0007
0008 #include "FWCore/Framework/interface/Event.h"
0009 #include "FWCore/Framework/interface/EventSetup.h"
0010 #include "FWCore/Utilities/interface/InputTag.h"
0011 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0012 #include "FWCore/Framework/interface/ConsumesCollector.h"
0013 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0014 #include "DataFormats/Common/interface/Handle.h"
0015 #include "DataFormats/BeamSpot/interface/BeamSpot.h"
0016 #include "DataFormats/VertexReco/interface/Vertex.h"
0017 #include "DataFormats/VertexReco/interface/VertexFwd.h"
0018 #include "DataFormats/L1Trigger/interface/Muon.h"
0019 #include "DataFormats/MuonDetId/interface/DTChamberId.h"
0020 #include "DataFormats/MuonDetId/interface/CSCDetId.h"
0021 #include "MagneticField/Engine/interface/MagneticField.h"
0022 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
0023 #include "RecoTracker/Record/interface/TrackerMultipleScatteringRecord.h"
0024 #include "RecoTracker/TkMSParametrization/interface/MultipleScatteringParametrisationMaker.h"
0025 #include "CLHEP/Vector/ThreeVector.h"
0026
0027 #include "RecoMuon/TrackingTools/interface/MuonServiceProxy.h"
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055 class L1MuonSeededTrackingRegionsProducer : public TrackingRegionProducer {
0056 public:
0057 typedef enum { BEAM_SPOT_FIXED, BEAM_SPOT_SIGMA, VERTICES_FIXED, VERTICES_SIGMA } Mode;
0058
0059 explicit L1MuonSeededTrackingRegionsProducer(const edm::ParameterSet& iConfig, edm::ConsumesCollector&& iC)
0060 : token_field(iC.esConsumes()),
0061 l1MinPt_(iConfig.getParameter<double>("L1MinPt")),
0062 l1MaxEta_(iConfig.getParameter<double>("L1MaxEta")),
0063 l1MinQuality_(iConfig.getParameter<unsigned int>("L1MinQuality")),
0064 minPtBarrel_(iConfig.getParameter<double>("SetMinPtBarrelTo")),
0065 minPtEndcap_(iConfig.getParameter<double>("SetMinPtEndcapTo")),
0066 centralBxOnly_(iConfig.getParameter<bool>("CentralBxOnly")),
0067 propagatorName_(iConfig.getParameter<std::string>("Propagator")) {
0068 edm::ParameterSet regPSet = iConfig.getParameter<edm::ParameterSet>("RegionPSet");
0069
0070
0071 std::string modeString = regPSet.getParameter<std::string>("mode");
0072 if (modeString == "BeamSpotFixed")
0073 m_mode = BEAM_SPOT_FIXED;
0074 else if (modeString == "BeamSpotSigma")
0075 m_mode = BEAM_SPOT_SIGMA;
0076 else if (modeString == "VerticesFixed")
0077 m_mode = VERTICES_FIXED;
0078 else if (modeString == "VerticesSigma")
0079 m_mode = VERTICES_SIGMA;
0080 else
0081 edm::LogError("L1MuonSeededTrackingRegionsProducer") << "Unknown mode string: " << modeString;
0082
0083
0084 token_input = iC.consumes<l1t::MuonBxCollection>(regPSet.getParameter<edm::InputTag>("input"));
0085 m_maxNRegions = regPSet.getParameter<int>("maxNRegions");
0086 token_beamSpot = iC.consumes<reco::BeamSpot>(regPSet.getParameter<edm::InputTag>("beamSpot"));
0087 m_maxNVertices = 1;
0088 if (m_mode == VERTICES_FIXED || m_mode == VERTICES_SIGMA) {
0089 token_vertex = iC.consumes<reco::VertexCollection>(regPSet.getParameter<edm::InputTag>("vertexCollection"));
0090 m_maxNVertices = regPSet.getParameter<int>("maxNVertices");
0091 }
0092
0093
0094 m_ptMin = regPSet.getParameter<double>("ptMin");
0095 m_originRadius = regPSet.getParameter<double>("originRadius");
0096 m_zErrorBeamSpot = regPSet.getParameter<double>("zErrorBeamSpot");
0097 m_ptRanges = regPSet.getParameter<std::vector<double>>("ptRanges");
0098 if (m_ptRanges.size() < 2) {
0099 edm::LogError("L1MuonSeededTrackingRegionsProducer") << "Size of ptRanges does not be less than 2" << std::endl;
0100 }
0101 m_deltaEtas = regPSet.getParameter<std::vector<double>>("deltaEtas");
0102 if (m_deltaEtas.size() != m_ptRanges.size() - 1) {
0103 edm::LogError("L1MuonSeededTrackingRegionsProducer")
0104 << "Size of deltaEtas does not match number of pt bins." << std::endl;
0105 }
0106 m_deltaPhis = regPSet.getParameter<std::vector<double>>("deltaPhis");
0107 if (m_deltaPhis.size() != m_ptRanges.size() - 1) {
0108 edm::LogError("L1MuonSeededTrackingRegionsProducer")
0109 << "Size of deltaPhis does not match number of pt bins." << std::endl;
0110 }
0111
0112 m_precise = regPSet.getParameter<bool>("precise");
0113 m_whereToUseMeasurementTracker = RectangularEtaPhiTrackingRegion::stringToUseMeasurementTracker(
0114 regPSet.getParameter<std::string>("whereToUseMeasurementTracker"));
0115 if (m_whereToUseMeasurementTracker != RectangularEtaPhiTrackingRegion::UseMeasurementTracker::kNever) {
0116 token_measurementTracker =
0117 iC.consumes<MeasurementTrackerEvent>(regPSet.getParameter<edm::InputTag>("measurementTrackerName"));
0118 }
0119
0120 m_searchOpt = regPSet.getParameter<bool>("searchOpt");
0121
0122
0123 if (m_mode == VERTICES_SIGMA)
0124 m_nSigmaZVertex = regPSet.getParameter<double>("nSigmaZVertex");
0125 if (m_mode == VERTICES_FIXED)
0126 m_zErrorVetex = regPSet.getParameter<double>("zErrorVetex");
0127 m_nSigmaZBeamSpot = -1.;
0128 if (m_mode == BEAM_SPOT_SIGMA) {
0129 m_nSigmaZBeamSpot = regPSet.getParameter<double>("nSigmaZBeamSpot");
0130 if (m_nSigmaZBeamSpot < 0.)
0131 edm::LogError("L1MuonSeededTrackingRegionsProducer")
0132 << "nSigmaZBeamSpot must be positive for BeamSpotSigma mode!";
0133 }
0134 if (m_precise) {
0135 token_msmaker = iC.esConsumes();
0136 }
0137
0138
0139 edm::ParameterSet serviceParameters = iConfig.getParameter<edm::ParameterSet>("ServiceParameters");
0140 service_ = std::make_unique<MuonServiceProxy>(serviceParameters, std::move(iC));
0141 }
0142
0143 ~L1MuonSeededTrackingRegionsProducer() override = default;
0144
0145 static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0146 edm::ParameterSetDescription desc;
0147
0148
0149 desc.add<std::string>("Propagator", "");
0150 desc.add<double>("L1MinPt", -1.);
0151 desc.add<double>("L1MaxEta", 5.0);
0152 desc.add<unsigned int>("L1MinQuality", 0);
0153 desc.add<double>("SetMinPtBarrelTo", 3.5);
0154 desc.add<double>("SetMinPtEndcapTo", 1.0);
0155 desc.add<bool>("CentralBxOnly", true);
0156
0157
0158 edm::ParameterSetDescription descRegion;
0159 descRegion.add<std::string>("mode", "BeamSpotSigma");
0160 descRegion.add<edm::InputTag>("input", edm::InputTag(""));
0161 descRegion.add<int>("maxNRegions", 10);
0162 descRegion.add<edm::InputTag>("beamSpot", edm::InputTag("hltOnlineBeamSpot"));
0163 descRegion.add<edm::InputTag>("vertexCollection", edm::InputTag("notUsed"));
0164 descRegion.add<int>("maxNVertices", 1);
0165 descRegion.add<double>("ptMin", 0.0);
0166 descRegion.add<double>("originRadius", 0.2);
0167 descRegion.add<double>("zErrorBeamSpot", 24.2);
0168 descRegion.add<std::vector<double>>("ptRanges", {0., 1.e9});
0169 descRegion.add<std::vector<double>>("deltaEtas", {0.35});
0170 descRegion.add<std::vector<double>>("deltaPhis", {0.2});
0171 descRegion.add<bool>("precise", true);
0172 descRegion.add<double>("nSigmaZVertex", 3.);
0173 descRegion.add<double>("zErrorVetex", 0.2);
0174 descRegion.add<double>("nSigmaZBeamSpot", 4.);
0175 descRegion.add<std::string>("whereToUseMeasurementTracker", "Never");
0176 descRegion.add<edm::InputTag>("measurementTrackerName", edm::InputTag(""));
0177 descRegion.add<bool>("searchOpt", false);
0178 desc.add<edm::ParameterSetDescription>("RegionPSet", descRegion);
0179
0180
0181 edm::ParameterSetDescription psd0;
0182 psd0.addUntracked<std::vector<std::string>>("Propagators", {"SteppingHelixPropagatorAny"});
0183 psd0.add<bool>("RPCLayers", false);
0184 psd0.addUntracked<bool>("UseMuonNavigation", false);
0185 desc.add<edm::ParameterSetDescription>("ServiceParameters", psd0);
0186
0187 descriptions.add("hltIterL3MuonPixelTracksTrackingRegions", desc);
0188 }
0189
0190 std::vector<std::unique_ptr<TrackingRegion>> regions(const edm::Event& iEvent,
0191 const edm::EventSetup& iSetup) const override {
0192 std::vector<std::unique_ptr<TrackingRegion>> result;
0193
0194
0195 edm::Handle<l1t::MuonBxCollection> muColl;
0196 iEvent.getByToken(token_input, muColl);
0197 if (muColl->size() == 0)
0198 return result;
0199
0200
0201 edm::Handle<reco::BeamSpot> bs;
0202 iEvent.getByToken(token_beamSpot, bs);
0203 if (!bs.isValid())
0204 return result;
0205
0206
0207 GlobalPoint default_origin(bs->x0(), bs->y0(), bs->z0());
0208
0209
0210 std::vector<std::pair<GlobalPoint, float>> origins;
0211
0212
0213 if (m_mode == BEAM_SPOT_FIXED || m_mode == BEAM_SPOT_SIGMA) {
0214 origins.push_back(std::make_pair(
0215 default_origin, (m_mode == BEAM_SPOT_FIXED) ? m_zErrorBeamSpot : m_nSigmaZBeamSpot * bs->sigmaZ()));
0216 } else if (m_mode == VERTICES_FIXED || m_mode == VERTICES_SIGMA) {
0217 edm::Handle<reco::VertexCollection> vertices;
0218 iEvent.getByToken(token_vertex, vertices);
0219 int n_vert = 0;
0220 for (reco::VertexCollection::const_iterator v = vertices->begin();
0221 v != vertices->end() && n_vert < m_maxNVertices;
0222 ++v) {
0223 if (v->isFake() || !v->isValid())
0224 continue;
0225
0226 origins.push_back(std::make_pair(GlobalPoint(v->x(), v->y(), v->z()),
0227 (m_mode == VERTICES_FIXED) ? m_zErrorVetex : m_nSigmaZVertex * v->zError()));
0228 ++n_vert;
0229 }
0230
0231 if (origins.empty()) {
0232 origins.push_back(std::make_pair(
0233 default_origin, (m_nSigmaZBeamSpot > 0.) ? m_nSigmaZBeamSpot * bs->z0Error() : m_zErrorBeamSpot));
0234 }
0235 }
0236
0237 const MeasurementTrackerEvent* measurementTracker = nullptr;
0238 if (!token_measurementTracker.isUninitialized()) {
0239 measurementTracker = &iEvent.get(token_measurementTracker);
0240 }
0241
0242 const auto& field = iSetup.getData(token_field);
0243 const MultipleScatteringParametrisationMaker* msmaker = nullptr;
0244 if (m_precise) {
0245 msmaker = &iSetup.getData(token_msmaker);
0246 }
0247
0248
0249
0250 int n_regions = 0;
0251 for (int ibx = muColl->getFirstBX(); ibx <= muColl->getLastBX() && n_regions < m_maxNRegions; ++ibx) {
0252 if (centralBxOnly_ && (ibx != 0))
0253 continue;
0254
0255 for (auto it = muColl->begin(ibx); it != muColl->end(ibx) && n_regions < m_maxNRegions; it++) {
0256 unsigned int quality = it->hwQual();
0257 if (quality <= l1MinQuality_)
0258 continue;
0259
0260 float pt = it->pt();
0261 float eta = it->eta();
0262 if (pt < l1MinPt_ || std::abs(eta) > l1MaxEta_)
0263 continue;
0264
0265 float theta = 2 * atan(exp(-eta));
0266 float phi = it->phi();
0267
0268 int valid_charge = it->hwChargeValid();
0269 int charge = it->charge();
0270 if (!valid_charge)
0271 charge = 0;
0272
0273 int link = l1MuonTF_link_EMTFP_i_ + (int)(it->tfMuonIndex() / 3.);
0274 bool barrel = true;
0275 if ((link >= l1MuonTF_link_EMTFP_i_ && link <= l1MuonTF_link_EMTFP_f_) ||
0276 (link >= l1MuonTF_link_EMTFN_i_ && link <= l1MuonTF_link_EMTFN_f_))
0277 barrel = false;
0278
0279
0280 service_->update(iSetup);
0281 const DetLayer* detLayer = nullptr;
0282 float radius = 0.;
0283
0284 CLHEP::Hep3Vector vec(0., 1., 0.);
0285 vec.setTheta(theta);
0286 vec.setPhi(phi);
0287
0288 DetId theid;
0289
0290 if (barrel) {
0291
0292 theid = DTChamberId(0, 2, 0);
0293 detLayer = service_->detLayerGeometry()->idToLayer(theid);
0294
0295 const BoundSurface* sur = &(detLayer->surface());
0296 const BoundCylinder* bc = dynamic_cast<const BoundCylinder*>(sur);
0297
0298 radius = std::abs(bc->radius() / sin(theta));
0299
0300 if (pt < minPtBarrel_)
0301 pt = minPtBarrel_;
0302 } else {
0303
0304 theid = theta < M_PI / 2. ? CSCDetId(1, 2, 0, 0, 0) : CSCDetId(2, 2, 0, 0, 0);
0305
0306 detLayer = service_->detLayerGeometry()->idToLayer(theid);
0307
0308 radius = std::abs(detLayer->position().z() / cos(theta));
0309
0310 if (pt < minPtEndcap_)
0311 pt = minPtEndcap_;
0312 }
0313 vec.setMag(radius);
0314 GlobalPoint pos(vec.x(), vec.y(), vec.z());
0315 GlobalVector mom(pt * cos(phi), pt * sin(phi), pt * cos(theta) / sin(theta));
0316 GlobalTrajectoryParameters param(pos, mom, charge, &*service_->magneticField());
0317
0318 AlgebraicSymMatrix55 mat;
0319 mat[0][0] = (sigma_qbpt_barrel_ / pt) * (sigma_qbpt_barrel_ / pt);
0320 if (!barrel)
0321 mat[0][0] = (sigma_qbpt_endcap_ / pt) * (sigma_qbpt_endcap_ / pt);
0322
0323
0324 if (!valid_charge)
0325 mat[0][0] = (sigma_qbpt_invalid_charge_ / pt) * (sigma_qbpt_invalid_charge_ / pt);
0326
0327 mat[1][1] = sigma_lambda_ * sigma_lambda_;
0328 mat[2][2] = sigma_phi_ * sigma_phi_;
0329 mat[3][3] = sigma_x_ * sigma_x_;
0330 mat[4][4] = sigma_y_ * sigma_y_;
0331
0332 CurvilinearTrajectoryError error(mat);
0333
0334 const FreeTrajectoryState state(param, error);
0335
0336 FreeTrajectoryState state_bs = service_->propagator(propagatorName_)->propagate(state, *bs.product());
0337
0338 GlobalVector direction(state_bs.momentum().x(), state_bs.momentum().y(), state_bs.momentum().z());
0339
0340
0341 auto deltaEta = m_deltaEtas.at(0);
0342 auto deltaPhi = m_deltaPhis.at(0);
0343 if (it->pt() < m_ptRanges.back()) {
0344 auto lowEdge = std::upper_bound(m_ptRanges.begin(), m_ptRanges.end(), it->pt());
0345 deltaEta = m_deltaEtas.at(lowEdge - m_ptRanges.begin() - 1);
0346 deltaPhi = m_deltaPhis.at(lowEdge - m_ptRanges.begin() - 1);
0347 }
0348
0349 for (size_t j = 0; j < origins.size() && n_regions < m_maxNRegions; ++j) {
0350 result.push_back(std::make_unique<RectangularEtaPhiTrackingRegion>(direction,
0351 origins[j].first,
0352 m_ptMin,
0353 m_originRadius,
0354 origins[j].second,
0355 deltaEta,
0356 deltaPhi,
0357 field,
0358 msmaker,
0359 m_precise,
0360 m_whereToUseMeasurementTracker,
0361 measurementTracker,
0362 m_searchOpt));
0363 ++n_regions;
0364 }
0365 }
0366 }
0367 edm::LogInfo("L1MuonSeededTrackingRegionsProducer") << "produced " << n_regions << " regions";
0368
0369 return result;
0370 }
0371
0372 private:
0373 Mode m_mode;
0374
0375 int m_maxNRegions;
0376 edm::EDGetTokenT<reco::VertexCollection> token_vertex;
0377 edm::EDGetTokenT<reco::BeamSpot> token_beamSpot;
0378 edm::EDGetTokenT<l1t::MuonBxCollection> token_input;
0379 int m_maxNVertices;
0380
0381 float m_ptMin;
0382 float m_originRadius;
0383 float m_zErrorBeamSpot;
0384 std::vector<double> m_ptRanges;
0385 std::vector<double> m_deltaEtas;
0386 std::vector<double> m_deltaPhis;
0387 bool m_precise;
0388 edm::EDGetTokenT<MeasurementTrackerEvent> token_measurementTracker;
0389 RectangularEtaPhiTrackingRegion::UseMeasurementTracker m_whereToUseMeasurementTracker;
0390 const edm::ESGetToken<MagneticField, IdealMagneticFieldRecord> token_field;
0391 edm::ESGetToken<MultipleScatteringParametrisationMaker, TrackerMultipleScatteringRecord> token_msmaker;
0392 bool m_searchOpt;
0393
0394 float m_nSigmaZVertex;
0395 float m_zErrorVetex;
0396 float m_nSigmaZBeamSpot;
0397
0398 const double l1MinPt_;
0399 const double l1MaxEta_;
0400 const unsigned l1MinQuality_;
0401 const double minPtBarrel_;
0402 const double minPtEndcap_;
0403 const bool centralBxOnly_;
0404
0405 const std::string propagatorName_;
0406 std::unique_ptr<MuonServiceProxy> service_;
0407
0408
0409
0410 static constexpr int l1MuonTF_link_EMTFP_i_{36};
0411 static constexpr int l1MuonTF_link_EMTFP_f_{41};
0412 static constexpr int l1MuonTF_link_EMTFN_i_{66};
0413 static constexpr int l1MuonTF_link_EMTFN_f_{71};
0414
0415
0416 static constexpr double sigma_qbpt_barrel_{0.25};
0417 static constexpr double sigma_qbpt_endcap_{0.4};
0418 static constexpr double sigma_qbpt_invalid_charge_{1.0};
0419 static constexpr double sigma_lambda_{0.05};
0420 static constexpr double sigma_phi_{0.2};
0421 static constexpr double sigma_x_{20.0};
0422 static constexpr double sigma_y_{20.0};
0423 };
0424
0425 #endif