00001 #include "SeedFromConsecutiveHitsCreator.h"
00002 #include "RecoTracker/TkTrackingRegions/interface/TrackingRegion.h"
00003
00004 #include "TrackingTools/KalmanUpdators/interface/KFUpdator.h"
00005 #include "RecoTracker/TkSeedGenerator/interface/FastHelix.h"
00006 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
00007 #include "Geometry/Records/interface/TrackerDigiGeometryRecord.h"
00008 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00009 #include "MagneticField/Engine/interface/MagneticField.h"
00010 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
00011 #include "TrackingTools/Records/interface/TrackingComponentsRecord.h"
00012 #include "TrackingTools/Records/interface/TransientRecHitRecord.h"
00013 #include "TrackingTools/MaterialEffects/interface/PropagatorWithMaterial.h"
00014 #include "FWCore/Framework/interface/ESHandle.h"
00015 #include "TrackingTools/GeomPropagators/interface/PropagationExceptions.h"
00016 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h"
00017 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateOnSurface.h"
00018 #include "RecoTracker/TkSeedingLayers/interface/SeedComparitor.h"
00019
00020 template <class T> T sqr( T t) {return t*t;}
00021
00022 const TrajectorySeed * SeedFromConsecutiveHitsCreator::trajectorySeed(
00023 TrajectorySeedCollection & seedCollection,
00024 const SeedingHitSet & hits,
00025 const TrackingRegion & region,
00026 const edm::EventSetup& es,
00027 const SeedComparitor *filter)
00028 {
00029 if ( hits.size() < 2) return 0;
00030
00031 bool passesFilter = true;
00032 GlobalTrajectoryParameters kine = initialKinematic(hits, region, es, filter, passesFilter);
00033 if (!passesFilter) return 0;
00034
00035 float sinTheta = sin(kine.momentum().theta());
00036
00037 CurvilinearTrajectoryError error = initialError(region, sinTheta);
00038 FreeTrajectoryState fts(kine, error);
00039
00040 return buildSeed(seedCollection,hits,fts,es,filter);
00041 }
00042
00043
00044 GlobalTrajectoryParameters SeedFromConsecutiveHitsCreator::initialKinematic(
00045 const SeedingHitSet & hits,
00046 const TrackingRegion & region,
00047 const edm::EventSetup& es,
00048 const SeedComparitor *filter,
00049 bool &passesFilter) const
00050 {
00051 edm::ESHandle<MagneticField> bfield;
00052 es.get<IdealMagneticFieldRecord>().get(bfield);
00053
00054 GlobalTrajectoryParameters kine;
00055
00056 TransientTrackingRecHit::ConstRecHitPointer tth1 = hits[0];
00057 TransientTrackingRecHit::ConstRecHitPointer tth2 = hits[1];
00058 const GlobalPoint& vertexPos = region.origin();
00059
00060 FastHelix helix(tth2->globalPosition(), tth1->globalPosition(), vertexPos, es);
00061 if (helix.isValid()) {
00062 kine = helix.stateAtVertex().parameters();
00063 } else {
00064 GlobalVector initMomentum(tth2->globalPosition() - vertexPos);
00065 initMomentum *= (100./initMomentum.perp());
00066 kine = GlobalTrajectoryParameters(vertexPos, initMomentum, 1, &*bfield);
00067 }
00068
00069 bool isBOFF = ( std::abs(bfield->inTesla(GlobalPoint(0,0,0)).z()) < 1e-3 );
00070 if (isBOFF && (theBOFFMomentum > 0)) {
00071 kine = GlobalTrajectoryParameters(kine.position(),
00072 kine.momentum().unit() * theBOFFMomentum,
00073 kine.charge(),
00074 &*bfield);
00075 }
00076 passesFilter = (filter ? filter->compatible(hits, kine, helix, region) : true);
00077 return kine;
00078 }
00079
00080
00081
00082 CurvilinearTrajectoryError SeedFromConsecutiveHitsCreator::
00083 initialError( const TrackingRegion& region, float sinTheta) const
00084 {
00085
00086
00087 AlgebraicSymMatrix55 C = ROOT::Math::SMatrixIdentity();
00088
00089
00090
00091
00092
00093 float sin2th = sqr(sinTheta);
00094 float minC00 = sqr(theMinOneOverPtError);
00095 C[0][0] = std::max(sin2th/sqr(region.ptMin()), minC00);
00096 float zErr = sqr(region.originZBound());
00097 float transverseErr = sqr(theOriginTransverseErrorMultiplier*region.originRBound());
00098 C[3][3] = transverseErr;
00099 C[4][4] = zErr*sin2th + transverseErr*(1-sin2th);
00100
00101 return CurvilinearTrajectoryError(C);
00102 }
00103
00104 const TrajectorySeed * SeedFromConsecutiveHitsCreator::buildSeed(
00105 TrajectorySeedCollection & seedCollection,
00106 const SeedingHitSet & hits,
00107 const FreeTrajectoryState & fts,
00108 const edm::EventSetup& es,
00109 const SeedComparitor *filter) const
00110 {
00111
00112 edm::ESHandle<TrackerGeometry> tracker;
00113 es.get<TrackerDigiGeometryRecord>().get(tracker);
00114
00115
00116 edm::ESHandle<Propagator> propagatorHandle;
00117 es.get<TrackingComponentsRecord>().get(thePropagatorLabel, propagatorHandle);
00118 const Propagator* propagator = &(*propagatorHandle);
00119
00120
00121 KFUpdator updator;
00122
00123
00124
00125 TrajectoryStateOnSurface updatedState;
00126 edm::OwnVector<TrackingRecHit> seedHits;
00127
00128 const TrackingRecHit* hit = 0;
00129 for ( unsigned int iHit = 0; iHit < hits.size(); iHit++) {
00130 hit = hits[iHit]->hit();
00131 TrajectoryStateOnSurface state = (iHit==0) ?
00132 propagator->propagate(fts,tracker->idToDet(hit->geographicalId())->surface())
00133 : propagator->propagate(updatedState, tracker->idToDet(hit->geographicalId())->surface());
00134 if (!state.isValid()) return 0;
00135
00136 TransientTrackingRecHit::ConstRecHitPointer tth = hits[iHit];
00137
00138 TransientTrackingRecHit::RecHitPointer newtth = refitHit( tth, state);
00139
00140 if (!checkHit(state,newtth,es,filter)) return 0;
00141
00142 updatedState = updator.update(state, *newtth);
00143 if (!updatedState.isValid()) return 0;
00144
00145 seedHits.push_back(newtth->hit()->clone());
00146 }
00147
00148
00149 PTrajectoryStateOnDet const & PTraj =
00150 trajectoryStateTransform::persistentState(updatedState, hit->geographicalId().rawId());
00151 TrajectorySeed seed(PTraj,std::move(seedHits),alongMomentum);
00152 if (filter != 0 && !filter->compatible(seed)) return 0;
00153 seedCollection.push_back(seed);
00154 return &seedCollection.back();
00155 }
00156
00157 TransientTrackingRecHit::RecHitPointer SeedFromConsecutiveHitsCreator::refitHit(
00158 const TransientTrackingRecHit::ConstRecHitPointer &hit,
00159 const TrajectoryStateOnSurface &state) const
00160 {
00161 return hit->clone(state);
00162 }
00163
00164 bool
00165 SeedFromConsecutiveHitsCreator::checkHit(
00166 const TrajectoryStateOnSurface &tsos,
00167 const TransientTrackingRecHit::ConstRecHitPointer &hit,
00168 const edm::EventSetup& es,
00169 const SeedComparitor *filter) const
00170 {
00171 return (filter ? filter->compatible(tsos,hit) : true);
00172 }
00173