File indexing completed on 2024-04-06 12:28:54
0001
0002 #include "FWCore/Framework/interface/stream/EDProducer.h"
0003 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0004 #include "FWCore/Framework/interface/Event.h"
0005
0006 #include "DataFormats/BeamSpot/interface/BeamSpot.h"
0007 #include "DataFormats/TrackerRecHit2D/interface/VectorHit.h"
0008 #include "DataFormats/TrackerCommon/interface/TrackerTopology.h"
0009 #include "DataFormats/TrajectorySeed/interface/TrajectorySeedCollection.h"
0010 #include "RecoTracker/MeasurementDet/interface/MeasurementTracker.h"
0011 #include "TrackingTools/MeasurementDet/interface/LayerMeasurements.h"
0012 #include "MagneticField/Engine/interface/MagneticField.h"
0013
0014 #include "RecoTracker/Record/interface/CkfComponentsRecord.h"
0015 #include "RecoTracker/MeasurementDet/interface/MeasurementTracker.h"
0016 #include "RecoTracker/MeasurementDet/interface/MeasurementTrackerEvent.h"
0017 #include "TrackingTools/KalmanUpdators/interface/Chi2MeasurementEstimator.h"
0018 #include "TrackingTools/PatternTools/interface/TrajectoryStateUpdator.h"
0019
0020 #include "Geometry/Records/interface/TrackerTopologyRcd.h"
0021
0022 #include "FWCore/Utilities/interface/ESGetToken.h"
0023
0024 #include "FWCore/Framework/interface/Frameworkfwd.h"
0025 #include "FWCore/Framework/interface/MakerMacros.h"
0026 #include "FWCore/Framework/interface/EventSetup.h"
0027
0028 #include "DataFormats/TrajectoryState/interface/LocalTrajectoryParameters.h"
0029 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h"
0030 #include "TrackingTools/MeasurementDet/interface/TrajectoryMeasurementGroup.h"
0031
0032 #include "DataFormats/SiStripDetId/interface/StripSubdetector.h"
0033 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0034
0035 class TrajectoryStateUpdator;
0036
0037 class SeedingOTEDProducer : public edm::stream::EDProducer<> {
0038 public:
0039 explicit SeedingOTEDProducer(const edm::ParameterSet&);
0040 ~SeedingOTEDProducer() override;
0041 void produce(edm::Event&, const edm::EventSetup&) override;
0042
0043 static void fillDescriptions(edm::ConfigurationDescriptions&);
0044
0045 TrajectorySeedCollection run(edm::Handle<VectorHitCollection>);
0046 unsigned int checkLayer(unsigned int iidd);
0047 std::vector<const VectorHit*> collectVHsOnLayer(const edmNew::DetSetVector<VectorHit>&, unsigned int);
0048 void printVHsOnLayer(const edmNew::DetSetVector<VectorHit>&, unsigned int);
0049 const TrajectoryStateOnSurface buildInitialTSOS(const VectorHit*) const;
0050 AlgebraicSymMatrix55 assign44To55(const AlgebraicSymMatrix44&) const;
0051 std::pair<bool, TrajectoryStateOnSurface> propagateAndUpdate(const TrajectoryStateOnSurface initialTSOS,
0052 const Propagator&,
0053 const TrackingRecHit& hit) const;
0054 float computeGlobalThetaError(const VectorHit* vh, const double sigmaZ_beamSpot) const;
0055 float computeInverseMomentumError(const VectorHit* vh,
0056 const float globalTheta,
0057 const double sigmaZ_beamSpot,
0058 const double transverseMomentum) const;
0059
0060 TrajectorySeed createSeed(const TrajectoryStateOnSurface& tsos,
0061 const edm::OwnVector<TrackingRecHit>& container,
0062 const DetId& id,
0063 const Propagator& prop) const;
0064
0065 struct isInvalid {
0066 bool operator()(const TrajectoryMeasurement& measurement) {
0067 return ((measurement.recHit() == nullptr) || !(measurement.recHit()->isValid()) ||
0068 !((measurement).updatedState().isValid()));
0069 }
0070 };
0071
0072 private:
0073 edm::EDGetTokenT<VectorHitCollection> vhProducerToken_;
0074 const TrackerTopology* tkTopo_;
0075 const MeasurementTracker* measurementTracker_;
0076 std::unique_ptr<LayerMeasurements> layerMeasurements_;
0077 const MeasurementEstimator* estimator_;
0078 const Propagator* propagator_;
0079 const MagneticField* magField_;
0080 const TrajectoryStateUpdator* updator_;
0081 const edm::EDGetTokenT<MeasurementTrackerEvent> tkMeasEventToken_;
0082 edm::EDGetTokenT<reco::BeamSpot> beamSpotToken_;
0083 const reco::BeamSpot* beamSpot_;
0084 std::string updatorName_;
0085
0086 edm::ESGetToken<TrackerTopology, TrackerTopologyRcd> topoToken_;
0087 edm::ESGetToken<Propagator, TrackingComponentsRecord> propagatorToken_;
0088 edm::ESGetToken<MagneticField, IdealMagneticFieldRecord> magFieldToken_;
0089 edm::ESGetToken<TrajectoryStateUpdator, TrackingComponentsRecord> updatorToken_;
0090 edm::ESGetToken<MeasurementTracker, CkfComponentsRecord> measurementTrackerToken_;
0091 edm::ESGetToken<Chi2MeasurementEstimatorBase, TrackingComponentsRecord> estToken_;
0092 edm::EDPutTokenT<TrajectorySeedCollection> putToken_;
0093 };
0094
0095 SeedingOTEDProducer::SeedingOTEDProducer(edm::ParameterSet const& conf)
0096 : tkMeasEventToken_(consumes<MeasurementTrackerEvent>(conf.getParameter<edm::InputTag>("trackerEvent"))),
0097 topoToken_(esConsumes()),
0098 propagatorToken_(esConsumes(edm::ESInputTag("", "PropagatorWithMaterial"))),
0099 magFieldToken_(esConsumes()),
0100 updatorToken_(esConsumes(edm::ESInputTag("", "KFUpdator"))),
0101 measurementTrackerToken_(esConsumes()),
0102 estToken_(esConsumes(edm::ESInputTag("", "Chi2"))) {
0103 vhProducerToken_ = consumes<VectorHitCollection>(edm::InputTag(conf.getParameter<edm::InputTag>("src")));
0104 beamSpotToken_ = consumes<reco::BeamSpot>(conf.getParameter<edm::InputTag>("beamSpotLabel"));
0105 updatorName_ = conf.getParameter<std::string>("updator");
0106 putToken_ = produces<TrajectorySeedCollection>();
0107 }
0108
0109 SeedingOTEDProducer::~SeedingOTEDProducer() {}
0110
0111 void SeedingOTEDProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0112 edm::ParameterSetDescription desc;
0113 desc.add<edm::InputTag>("src", edm::InputTag("siPhase2VectorHits", "accepted"));
0114 desc.add<edm::InputTag>("trackerEvent", edm::InputTag("MeasurementTrackerEvent"));
0115 desc.add<edm::InputTag>("beamSpotLabel", edm::InputTag("offlineBeamSpot"));
0116 desc.add<std::string>("updator", std::string("KFUpdator"));
0117 descriptions.add("SeedingOTEDProducer", desc);
0118 }
0119
0120 void SeedingOTEDProducer::produce(edm::Event& event, const edm::EventSetup& es) {
0121 tkTopo_ = &es.getData(topoToken_);
0122
0123 edm::ESHandle<MeasurementTracker> measurementTrackerHandle = es.getHandle(measurementTrackerToken_);
0124 measurementTracker_ = measurementTrackerHandle.product();
0125
0126 auto const& measurementTrackerEvent = event.get(tkMeasEventToken_);
0127
0128 layerMeasurements_ = std::make_unique<LayerMeasurements>(*measurementTrackerHandle, measurementTrackerEvent);
0129
0130 estimator_ = &es.getData(estToken_);
0131
0132 propagator_ = &es.getData(propagatorToken_);
0133
0134 magField_ = &es.getData(magFieldToken_);
0135
0136 updator_ = &es.getData(updatorToken_);
0137
0138 beamSpot_ = &event.get(beamSpotToken_);
0139
0140
0141 auto vhs = event.getHandle(vhProducerToken_);
0142
0143 event.emplace(putToken_, run(vhs));
0144 }
0145
0146 TrajectorySeedCollection SeedingOTEDProducer::run(edm::Handle<VectorHitCollection> vHs) {
0147 TrajectorySeedCollection result;
0148
0149 std::vector<const VectorHit*> vhSeedsL1 = collectVHsOnLayer(*vHs.product(), 1);
0150 std::vector<const VectorHit*> vhSeedsL2 = collectVHsOnLayer(*vHs.product(), 2);
0151 std::vector<const VectorHit*> vhSeedsL3 = collectVHsOnLayer(*vHs.product(), 3);
0152 if (vhSeedsL1.empty() || vhSeedsL2.empty() || vhSeedsL3.empty()) {
0153 return result;
0154 }
0155
0156
0157 const BarrelDetLayer* barrelOTLayer2 = measurementTracker_->geometricSearchTracker()->tobLayers().at(1);
0158
0159
0160 Propagator* searchingPropagator = &*propagator_->clone();
0161 Propagator* buildingPropagator = &*propagator_->clone();
0162 buildingPropagator->setPropagationDirection(alongMomentum);
0163
0164 for (const auto& hitL3 : vhSeedsL3) {
0165
0166 const TrajectoryStateOnSurface initialTSOS = buildInitialTSOS(hitL3);
0167 float signZ = copysign(1.0, initialTSOS.globalPosition().z());
0168 float signPz = copysign(1.0, initialTSOS.globalMomentum().z());
0169
0170
0171 if (signZ * signPz > 0.0)
0172 searchingPropagator->setPropagationDirection(oppositeToMomentum);
0173 else
0174 searchingPropagator->setPropagationDirection(alongMomentum);
0175
0176
0177 std::vector<TrajectoryMeasurement> measurementsL2 =
0178 layerMeasurements_->measurements(*barrelOTLayer2, initialTSOS, *searchingPropagator, *estimator_);
0179
0180 std::vector<TrajectoryMeasurement>::iterator measurementsL2end =
0181 std::remove_if(measurementsL2.begin(), measurementsL2.end(), isInvalid());
0182 measurementsL2.erase(measurementsL2end, measurementsL2.end());
0183
0184 if (!measurementsL2.empty()) {
0185
0186 const DetLayer* barrelOTLayer1 = measurementTracker_->geometricSearchTracker()->tobLayers().at(0);
0187
0188 for (const auto& mL2 : measurementsL2) {
0189 const TrackingRecHit* hitL2 = mL2.recHit().get();
0190
0191
0192 std::pair<bool, TrajectoryStateOnSurface> updatedTSOS =
0193 propagateAndUpdate(initialTSOS, *searchingPropagator, *hitL2);
0194 if (!updatedTSOS.first)
0195 continue;
0196
0197
0198 std::vector<TrajectoryMeasurement> measurementsL1 =
0199 layerMeasurements_->measurements(*barrelOTLayer1, updatedTSOS.second, *searchingPropagator, *estimator_);
0200 std::vector<TrajectoryMeasurement>::iterator measurementsL1end =
0201 std::remove_if(measurementsL1.begin(), measurementsL1.end(), isInvalid());
0202 measurementsL1.erase(measurementsL1end, measurementsL1.end());
0203
0204 if (!measurementsL1.empty()) {
0205 for (const auto& mL1 : measurementsL1) {
0206 const TrackingRecHit* hitL1 = mL1.recHit().get();
0207
0208
0209 std::pair<bool, TrajectoryStateOnSurface> updatedTSOSL1 =
0210 propagateAndUpdate(updatedTSOS.second, *searchingPropagator, *hitL1);
0211 if (!updatedTSOSL1.first)
0212 continue;
0213
0214
0215 if (searchingPropagator->propagationDirection() == alongMomentum) {
0216 buildingPropagator->setPropagationDirection(oppositeToMomentum);
0217 } else {
0218 buildingPropagator->setPropagationDirection(alongMomentum);
0219 }
0220
0221 updatedTSOSL1.second.rescaleError(100);
0222
0223 TrajectoryStateOnSurface updatedTSOSL1_final = updator_->update(updatedTSOSL1.second, *hitL1);
0224 if UNLIKELY (!updatedTSOSL1_final.isValid())
0225 continue;
0226 std::pair<bool, TrajectoryStateOnSurface> updatedTSOSL2_final =
0227 propagateAndUpdate(updatedTSOSL1_final, *buildingPropagator, *hitL2);
0228 if (!updatedTSOSL2_final.first)
0229 continue;
0230 std::pair<bool, TrajectoryStateOnSurface> updatedTSOSL3_final =
0231 propagateAndUpdate(updatedTSOSL2_final.second, *buildingPropagator, *hitL3);
0232 if (!updatedTSOSL3_final.first)
0233 continue;
0234
0235 edm::OwnVector<TrackingRecHit> container;
0236 container.push_back(hitL1->clone());
0237 container.push_back(hitL2->clone());
0238 container.push_back(hitL3->clone());
0239
0240 TrajectorySeed ts =
0241 createSeed(updatedTSOSL3_final.second, container, hitL3->geographicalId(), *buildingPropagator);
0242 result.push_back(ts);
0243 }
0244 }
0245 }
0246 }
0247 }
0248 result.shrink_to_fit();
0249 return result;
0250 }
0251
0252 unsigned int SeedingOTEDProducer::checkLayer(unsigned int iidd) {
0253 StripSubdetector strip = StripSubdetector(iidd);
0254 unsigned int subid = strip.subdetId();
0255 if (subid == StripSubdetector::TIB || subid == StripSubdetector::TOB) {
0256 return tkTopo_->layer(iidd);
0257 }
0258 return 0;
0259 }
0260
0261 std::vector<const VectorHit*> SeedingOTEDProducer::collectVHsOnLayer(const edmNew::DetSetVector<VectorHit>& input,
0262 unsigned int layerNumber) {
0263 std::vector<const VectorHit*> vHsOnLayer;
0264 if (!input.empty()) {
0265 for (const auto& DSViter : input) {
0266 if (checkLayer(DSViter.id()) == layerNumber) {
0267 for (const auto& vh : DSViter) {
0268 vHsOnLayer.push_back(&vh);
0269 }
0270 }
0271 }
0272 }
0273
0274 return vHsOnLayer;
0275 }
0276
0277 void SeedingOTEDProducer::printVHsOnLayer(const edmNew::DetSetVector<VectorHit>& input, unsigned int layerNumber) {
0278 if (!input.empty()) {
0279 for (const auto& DSViter : input) {
0280 for (const auto& vh : DSViter) {
0281 if (checkLayer(DSViter.id()) == layerNumber)
0282 LogTrace("SeedingOTEDProducer") << " VH in layer " << layerNumber << " >> " << vh;
0283 }
0284 }
0285 } else {
0286 LogTrace("SeedingOTEDProducer") << " No VHs in layer " << layerNumber << ".";
0287 }
0288 }
0289
0290 const TrajectoryStateOnSurface SeedingOTEDProducer::buildInitialTSOS(const VectorHit* vHit) const {
0291
0292 Global3DVector gv(vHit->globalPosition().x(), vHit->globalPosition().y(), vHit->globalPosition().z());
0293 float theta = gv.theta();
0294
0295 const Local3DVector lv(vHit->det()->surface().toLocal(gv));
0296
0297
0298 GlobalPoint center(0.0, 0.0, 0.0);
0299 int charge = 1;
0300
0301 float mom = vHit->momentum(magField_->inTesla(center).z());
0302 float xPos = vHit->localPosition().x();
0303 float yPos = vHit->localPosition().y();
0304 float dx = vHit->localDirection().x();
0305
0306 float dy = lv.y() / lv.z();
0307
0308
0309 float signPz = copysign(1.0, vHit->globalPosition().z());
0310
0311 LocalTrajectoryParameters ltpar2(charge / mom, dx, dy, xPos, yPos, signPz);
0312 AlgebraicSymMatrix55 mat = assign44To55(vHit->covMatrix());
0313
0314 mat[0][0] = pow(computeInverseMomentumError(
0315 vHit, theta, beamSpot_->sigmaZ(), vHit->transverseMomentum(magField_->inTesla(center).z())),
0316 2);
0317
0318
0319 LocalTrajectoryError lterr(mat);
0320 const TrajectoryStateOnSurface tsos(ltpar2, lterr, vHit->det()->surface(), magField_);
0321
0322 return tsos;
0323 }
0324
0325 AlgebraicSymMatrix55 SeedingOTEDProducer::assign44To55(const AlgebraicSymMatrix44& mat44) const {
0326 AlgebraicSymMatrix55 result;
0327 for (int i = 1; i < 5; i++) {
0328 for (int j = 1; j < 5; j++) {
0329 result[i][j] = mat44[i - 1][j - 1];
0330 }
0331 }
0332 return result;
0333 }
0334
0335 std::pair<bool, TrajectoryStateOnSurface> SeedingOTEDProducer::propagateAndUpdate(
0336 const TrajectoryStateOnSurface initialTSOS, const Propagator& prop, const TrackingRecHit& hit) const {
0337 TrajectoryStateOnSurface propTSOS = prop.propagate(initialTSOS, hit.det()->surface());
0338 if UNLIKELY (!propTSOS.isValid())
0339 return std::make_pair(false, propTSOS);
0340 TrajectoryStateOnSurface updatedTSOS = updator_->update(propTSOS, hit);
0341 if UNLIKELY (!updatedTSOS.isValid())
0342 return std::make_pair(false, updatedTSOS);
0343 return std::make_pair(true, updatedTSOS);
0344 }
0345
0346 float SeedingOTEDProducer::computeGlobalThetaError(const VectorHit* vh, const double sigmaZ_beamSpot) const {
0347 double derivative = vh->globalPosition().perp() / vh->globalPosition().mag2();
0348 double derivative2 = pow(derivative, 2);
0349 return pow(derivative2 * vh->lowerGlobalPosErr().czz() + derivative2 * pow(sigmaZ_beamSpot, 2), 0.5);
0350 }
0351
0352 float SeedingOTEDProducer::computeInverseMomentumError(const VectorHit* vh,
0353 const float globalTheta,
0354 const double sigmaZ_beamSpot,
0355 const double transverseMomentum) const {
0356
0357 float varianceInverseTransvMomentum = 1. / 12;
0358 float derivativeTheta2 = pow(cos(globalTheta) / transverseMomentum, 2);
0359 float derivativeInverseTransvMomentum2 = pow(sin(globalTheta), 2);
0360 float thetaError = computeGlobalThetaError(vh, sigmaZ_beamSpot);
0361 return pow(derivativeTheta2 * pow(thetaError, 2) + derivativeInverseTransvMomentum2 * varianceInverseTransvMomentum,
0362 0.5);
0363 }
0364
0365 TrajectorySeed SeedingOTEDProducer::createSeed(const TrajectoryStateOnSurface& tsos,
0366 const edm::OwnVector<TrackingRecHit>& container,
0367 const DetId& id,
0368 const Propagator& prop) const {
0369 PTrajectoryStateOnDet seedTSOS = trajectoryStateTransform::persistentState(tsos, id.rawId());
0370 return TrajectorySeed(seedTSOS, container, prop.propagationDirection());
0371 }
0372 DEFINE_FWK_MODULE(SeedingOTEDProducer);