File indexing completed on 2024-04-06 12:24:50
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 #include "FWCore/Framework/interface/Event.h"
0025 #include "FWCore/Framework/interface/EventSetup.h"
0026 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0027 #include "FWCore/Utilities/interface/InputTag.h"
0028 #include "FWCore/Framework/interface/ConsumesCollector.h"
0029 #include "FWCore/Framework/interface/ESHandle.h"
0030 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0031 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0032
0033 #include "DataFormats/GeometryVector/interface/GlobalPoint.h"
0034 #include "DataFormats/GeometryVector/interface/GlobalVector.h"
0035 #include "DataFormats/VertexReco/interface/Vertex.h"
0036 #include "DataFormats/VertexReco/interface/VertexFwd.h"
0037 #include "DataFormats/BeamSpot/interface/BeamSpot.h"
0038 #include "DataFormats/EgammaReco/interface/SuperClusterFwd.h"
0039 #include "DataFormats/EgammaReco/interface/SuperCluster.h"
0040
0041 #include "MagneticField/Engine/interface/MagneticField.h"
0042 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
0043 #include "RecoTracker/Record/interface/TrackerMultipleScatteringRecord.h"
0044 #include "RecoTracker/TkMSParametrization/interface/MultipleScatteringParametrisationMaker.h"
0045 #include "RecoTracker/TkTrackingRegions/interface/TrackingRegionProducer.h"
0046 #include "RecoTracker/TkTrackingRegions/interface/RectangularEtaPhiTrackingRegion.h"
0047 #include "RecoTracker/MeasurementDet/interface/MeasurementTrackerEvent.h"
0048
0049 #include "TrackingTools/TrajectoryState/interface/ftsFromVertexToPoint.h"
0050
0051 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
0052 #include "CommonTools/Utils/interface/StringToEnumValue.h"
0053
0054
0055 #include "TEnum.h"
0056 #include "TEnumConstant.h"
0057 namespace {
0058 template <typename MyEnum>
0059 MyEnum strToEnum(std::string const& enumConstName) {
0060 TEnum* en = TEnum::GetEnum(typeid(MyEnum));
0061 if (en != nullptr) {
0062 if (TEnumConstant const* enc = en->GetConstant(enumConstName.c_str())) {
0063 return static_cast<MyEnum>(enc->GetValue());
0064 } else {
0065 throw cms::Exception("Configuration") << enumConstName << " is not a valid member of " << typeid(MyEnum).name();
0066 }
0067 }
0068 throw cms::Exception("LogicError") << typeid(MyEnum).name() << " not recognised by ROOT";
0069 }
0070 template <>
0071 RectangularEtaPhiTrackingRegion::UseMeasurementTracker strToEnum(std::string const& enumConstName) {
0072 using MyEnum = RectangularEtaPhiTrackingRegion::UseMeasurementTracker;
0073 if (enumConstName == "kNever")
0074 return MyEnum::kNever;
0075 else if (enumConstName == "kForSiStrips")
0076 return MyEnum::kForSiStrips;
0077 else if (enumConstName == "kAlways")
0078 return MyEnum::kAlways;
0079 else {
0080 throw cms::Exception("InvalidConfiguration")
0081 << enumConstName << " is not a valid member of " << typeid(MyEnum).name()
0082 << " (or strToEnum needs updating, this is a manual translation found at " << __FILE__ << " line " << __LINE__
0083 << ")";
0084 }
0085 }
0086
0087 }
0088 class TrackingRegionsFromSuperClustersProducer : public TrackingRegionProducer {
0089 public:
0090 enum class Charge { NEG = -1, POS = +1 };
0091
0092 public:
0093 TrackingRegionsFromSuperClustersProducer(const edm::ParameterSet& cfg, edm::ConsumesCollector&& cc);
0094
0095 ~TrackingRegionsFromSuperClustersProducer() override {}
0096
0097 static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0098
0099 std::vector<std::unique_ptr<TrackingRegion>> regions(const edm::Event& iEvent,
0100 const edm::EventSetup& iSetup) const override;
0101
0102 private:
0103 GlobalPoint getVtxPos(const edm::Event& iEvent, double& deltaZVertex) const;
0104
0105 std::unique_ptr<TrackingRegion> createTrackingRegion(const reco::SuperCluster& superCluster,
0106 const GlobalPoint& vtxPos,
0107 const double deltaZVertex,
0108 const Charge charge,
0109 const MeasurementTrackerEvent* measTrackerEvent,
0110 const MagneticField& magField,
0111 const MultipleScatteringParametrisationMaker* msmaker) const;
0112
0113 private:
0114 void validateConfigSettings() const;
0115
0116 private:
0117
0118
0119
0120
0121
0122
0123 double ptMin_;
0124 double originRadius_;
0125 double originHalfLength_;
0126 double deltaEtaRegion_;
0127 double deltaPhiRegion_;
0128 bool useZInVertex_;
0129 bool useZInBeamspot_;
0130 double nrSigmaForBSDeltaZ_;
0131 double defaultZ_;
0132 double minBSDeltaZ_;
0133 bool precise_;
0134 RectangularEtaPhiTrackingRegion::UseMeasurementTracker whereToUseMeasTracker_;
0135
0136 edm::EDGetTokenT<reco::VertexCollection> verticesToken_;
0137 edm::EDGetTokenT<reco::BeamSpot> beamSpotToken_;
0138 edm::EDGetTokenT<MeasurementTrackerEvent> measTrackerEventToken_;
0139 std::vector<edm::EDGetTokenT<std::vector<reco::SuperClusterRef>>> superClustersTokens_;
0140
0141 const edm::ESGetToken<MagneticField, IdealMagneticFieldRecord> magFieldToken_;
0142 edm::ESGetToken<MultipleScatteringParametrisationMaker, TrackerMultipleScatteringRecord> msmakerToken_;
0143 };
0144
0145 namespace {
0146 template <typename T>
0147 edm::Handle<T> getHandle(const edm::Event& event, const edm::EDGetTokenT<T>& token) {
0148 edm::Handle<T> handle;
0149 event.getByToken(token, handle);
0150 return handle;
0151 }
0152 }
0153
0154 TrackingRegionsFromSuperClustersProducer::TrackingRegionsFromSuperClustersProducer(const edm::ParameterSet& cfg,
0155 edm::ConsumesCollector&& iC)
0156 : magFieldToken_{iC.esConsumes()} {
0157 edm::ParameterSet regionPSet = cfg.getParameter<edm::ParameterSet>("RegionPSet");
0158
0159 ptMin_ = regionPSet.getParameter<double>("ptMin");
0160 originRadius_ = regionPSet.getParameter<double>("originRadius");
0161 originHalfLength_ = regionPSet.getParameter<double>("originHalfLength");
0162 deltaPhiRegion_ = regionPSet.getParameter<double>("deltaPhiRegion");
0163 deltaEtaRegion_ = regionPSet.getParameter<double>("deltaEtaRegion");
0164 useZInVertex_ = regionPSet.getParameter<bool>("useZInVertex");
0165 useZInBeamspot_ = regionPSet.getParameter<bool>("useZInBeamspot");
0166 nrSigmaForBSDeltaZ_ = regionPSet.getParameter<double>("nrSigmaForBSDeltaZ");
0167 defaultZ_ = regionPSet.getParameter<double>("defaultZ");
0168 minBSDeltaZ_ = regionPSet.getParameter<double>("minBSDeltaZ");
0169 precise_ = regionPSet.getParameter<bool>("precise");
0170 whereToUseMeasTracker_ = strToEnum<RectangularEtaPhiTrackingRegion::UseMeasurementTracker>(
0171 regionPSet.getParameter<std::string>("whereToUseMeasTracker"));
0172
0173 validateConfigSettings();
0174
0175 auto verticesTag = regionPSet.getParameter<edm::InputTag>("vertices");
0176 auto beamSpotTag = regionPSet.getParameter<edm::InputTag>("beamSpot");
0177 auto superClustersTags = regionPSet.getParameter<std::vector<edm::InputTag>>("superClusters");
0178 auto measTrackerEventTag = regionPSet.getParameter<edm::InputTag>("measurementTrackerEvent");
0179
0180 if (useZInVertex_) {
0181 verticesToken_ = iC.consumes(verticesTag);
0182 } else {
0183 beamSpotToken_ = iC.consumes(beamSpotTag);
0184 }
0185 if (whereToUseMeasTracker_ != RectangularEtaPhiTrackingRegion::UseMeasurementTracker::kNever) {
0186 measTrackerEventToken_ = iC.consumes(measTrackerEventTag);
0187 }
0188 for (const auto& tag : superClustersTags) {
0189 superClustersTokens_.emplace_back(iC.consumes(tag));
0190 }
0191 if (precise_) {
0192 msmakerToken_ = iC.esConsumes();
0193 }
0194 }
0195
0196 void TrackingRegionsFromSuperClustersProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0197 edm::ParameterSetDescription desc;
0198
0199 desc.add<double>("ptMin", 1.5);
0200 desc.add<double>("originRadius", 0.2);
0201 desc.add<double>("originHalfLength", 15.0)
0202 ->setComment("z range is +/- this value except when using the beamspot (useZInBeamspot=true)");
0203 desc.add<double>("deltaPhiRegion", 0.4);
0204 desc.add<double>("deltaEtaRegion", 0.1);
0205 desc.add<bool>("useZInVertex", false)
0206 ->setComment("use the leading vertex position +/-orginHalfLength, mutually exclusive with useZInBeamspot");
0207 desc.add<bool>("useZInBeamspot", true)
0208 ->setComment(
0209 "use the beamspot position +/- nrSigmaForBSDeltaZ* sigmaZ_{bs}, mutually exclusive with useZInVertex");
0210 desc.add<double>("nrSigmaForBSDeltaZ", 3.0)
0211 ->setComment("# of sigma to extend the z region when using the beamspot, only active if useZInBeamspot=true");
0212 desc.add<double>("minBSDeltaZ", 0.0)
0213 ->setComment("a minimum value of the beamspot sigma z to use, only active if useZInBeamspot=true");
0214 desc.add<double>("defaultZ", 0.)
0215 ->setComment("the default z position, only used if useZInVertex and useZInBeamspot are both false");
0216 desc.add<bool>("precise", true);
0217 desc.add<std::string>("whereToUseMeasTracker", "kNever");
0218 desc.add<edm::InputTag>("beamSpot", edm::InputTag("hltOnlineBeamSpot"))
0219 ->setComment("only used if useZInBeamspot is true");
0220 desc.add<edm::InputTag>("vertices", edm::InputTag())->setComment("only used if useZInVertex is true");
0221 desc.add<std::vector<edm::InputTag>>("superClusters",
0222 std::vector<edm::InputTag>{edm::InputTag{"hltEgammaSuperClustersToPixelMatch"}});
0223 desc.add<edm::InputTag>("measurementTrackerEvent", edm::InputTag());
0224
0225 edm::ParameterSetDescription descRegion;
0226 descRegion.add<edm::ParameterSetDescription>("RegionPSet", desc);
0227
0228 descriptions.add("trackingRegionsFromSuperClusters", descRegion);
0229 }
0230
0231 std::vector<std::unique_ptr<TrackingRegion>> TrackingRegionsFromSuperClustersProducer::regions(
0232 const edm::Event& iEvent, const edm::EventSetup& iSetup) const {
0233 std::vector<std::unique_ptr<TrackingRegion>> trackingRegions;
0234
0235 double deltaZVertex = 0;
0236 GlobalPoint vtxPos = getVtxPos(iEvent, deltaZVertex);
0237
0238 const MeasurementTrackerEvent* measTrackerEvent = nullptr;
0239 if (!measTrackerEventToken_.isUninitialized()) {
0240 measTrackerEvent = getHandle(iEvent, measTrackerEventToken_).product();
0241 }
0242 auto const& magField = iSetup.getData(magFieldToken_);
0243 const MultipleScatteringParametrisationMaker* msmaker = nullptr;
0244 if (precise_) {
0245 msmaker = &iSetup.getData(msmakerToken_);
0246 }
0247
0248 for (auto& superClustersToken : superClustersTokens_) {
0249 auto superClustersHandle = getHandle(iEvent, superClustersToken);
0250 for (auto& superClusterRef : *superClustersHandle) {
0251
0252 trackingRegions.emplace_back(createTrackingRegion(
0253 *superClusterRef, vtxPos, deltaZVertex, Charge::POS, measTrackerEvent, magField, msmaker));
0254 trackingRegions.emplace_back(createTrackingRegion(
0255 *superClusterRef, vtxPos, deltaZVertex, Charge::NEG, measTrackerEvent, magField, msmaker));
0256 }
0257 }
0258 return trackingRegions;
0259 }
0260
0261 GlobalPoint TrackingRegionsFromSuperClustersProducer::getVtxPos(const edm::Event& iEvent, double& deltaZVertex) const {
0262 if (useZInVertex_) {
0263 auto verticesHandle = getHandle(iEvent, verticesToken_);
0264
0265
0266 if (!verticesHandle->empty()) {
0267 deltaZVertex = originHalfLength_;
0268 const auto& pv = verticesHandle->front();
0269 return GlobalPoint(pv.x(), pv.y(), pv.z());
0270 } else {
0271 deltaZVertex = originHalfLength_;
0272 return GlobalPoint(0, 0, defaultZ_);
0273 }
0274 } else {
0275 auto beamSpotHandle = getHandle(iEvent, beamSpotToken_);
0276 const reco::BeamSpot::Point& bsPos = beamSpotHandle->position();
0277
0278 if (useZInBeamspot_) {
0279
0280 const double bsSigmaZ = std::sqrt(beamSpotHandle->sigmaZ() * beamSpotHandle->sigmaZ() +
0281 beamSpotHandle->sigmaZ0Error() * beamSpotHandle->sigmaZ0Error());
0282 const double sigmaZ = std::max(bsSigmaZ, minBSDeltaZ_);
0283 deltaZVertex = nrSigmaForBSDeltaZ_ * sigmaZ;
0284
0285 return GlobalPoint(bsPos.x(), bsPos.y(), bsPos.z());
0286 } else {
0287 deltaZVertex = originHalfLength_;
0288 return GlobalPoint(bsPos.x(), bsPos.y(), defaultZ_);
0289 }
0290 }
0291 }
0292
0293 std::unique_ptr<TrackingRegion> TrackingRegionsFromSuperClustersProducer::createTrackingRegion(
0294 const reco::SuperCluster& superCluster,
0295 const GlobalPoint& vtxPos,
0296 const double deltaZVertex,
0297 const Charge charge,
0298 const MeasurementTrackerEvent* measTrackerEvent,
0299 const MagneticField& magField,
0300 const MultipleScatteringParametrisationMaker* msmaker) const {
0301 const GlobalPoint clusterPos(superCluster.position().x(), superCluster.position().y(), superCluster.position().z());
0302 const double energy = superCluster.energy();
0303
0304 auto fts = trackingTools::ftsFromVertexToPoint(magField, clusterPos, vtxPos, energy, static_cast<int>(charge));
0305 return std::make_unique<RectangularEtaPhiTrackingRegion>(fts.momentum(),
0306 vtxPos,
0307 ptMin_,
0308 originRadius_,
0309 deltaZVertex,
0310 deltaEtaRegion_,
0311 deltaPhiRegion_,
0312 magField,
0313 msmaker,
0314 precise_,
0315 whereToUseMeasTracker_,
0316 measTrackerEvent);
0317 }
0318
0319 void TrackingRegionsFromSuperClustersProducer::validateConfigSettings() const {
0320 if (useZInVertex_ && useZInBeamspot_) {
0321 throw cms::Exception("InvalidConfiguration")
0322 << " when constructing TrackingRegionsFromSuperClustersProducer both useZInVertex (" << useZInVertex_
0323 << ") and useZInBeamspot (" << useZInBeamspot_ << ") can not be true as they are mutually exclusive options"
0324 << std::endl;
0325 }
0326 }
0327
0328 #include "FWCore/Framework/interface/MakerMacros.h"
0329
0330 #include "RecoTracker/TkTrackingRegions/interface/TrackingRegionProducerFactory.h"
0331 #include "RecoTracker/TkTrackingRegions/interface/TrackingRegionEDProducerT.h"
0332 DEFINE_EDM_PLUGIN(TrackingRegionProducerFactory,
0333 TrackingRegionsFromSuperClustersProducer,
0334 "TrackingRegionsFromSuperClustersProducer");
0335 using TrackingRegionsFromSuperClustersEDProducer = TrackingRegionEDProducerT<TrackingRegionsFromSuperClustersProducer>;
0336 DEFINE_FWK_MODULE(TrackingRegionsFromSuperClustersEDProducer);