Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:24:50

0001 //******************************************************************************
0002 //
0003 // Part of the refactorisation of of the E/gamma pixel matching pre-2017
0004 // This refactorisation converts the monolithic  approach to a series of
0005 // independent producer modules, with each modules performing  a specific
0006 // job as recommended by the 2017 tracker framework
0007 //
0008 // This module is called a Producer even though its not an ED producer
0009 // This was done to be consistant with other TrackingRegion producers
0010 // in RecoTracker/TkTrackingRegions
0011 //
0012 // The module closely follows the other TrackingRegion producers
0013 // in RecoTracker/TkTrackingRegions and is intended to become an EDProducer
0014 // by TrackingRegionEDProducerT<TrackingRegionsFromSuperClustersProducer>
0015 
0016 // This module c tracking regions from the superclusters. It mostly
0017 // replicates the functionality of the SeedFilter class
0018 // although unlike that class, it does not actually create seeds
0019 //
0020 // Author : Sam Harper (RAL), 2017
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 //stick this in common tools
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 }  // namespace
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   //there are 3 modes in which to define the Z area of the tracking region
0118   //1) from first vertex in the passed vertices collection +/- originHalfLength in z (useZInVertex=true)
0119   //2) the beamspot +/- nrSigmaForBSDeltaZ* zSigma of beamspot (useZInBeamspot=true)
0120   //   the zSigma of the beamspot can have a minimum value specified
0121   //   we do this because a common error is that beamspot has too small of a value
0122   //3) defaultZ_ +/- originHalfLength  (if useZInVertex and useZInBeamspot are both false)
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 }  // namespace
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       //do both charge hypothesises
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     //we throw if the vertices are not there but if no vertex is
0265     //recoed in the event, we default to 0,0,defaultZ as the vertex
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       //as this is what has been done traditionally for e/gamma, others just use sigmaZ
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);