00001 #include "RecoTracker/ConversionSeedGenerators/interface/SeedForPhotonConversion1Leg.h"
00002
00003 #include "TrackingTools/KalmanUpdators/interface/KFUpdator.h"
00004 #include "RecoTracker/TkSeedGenerator/interface/FastHelix.h"
00005 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
00006 #include "Geometry/Records/interface/TrackerDigiGeometryRecord.h"
00007 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00008 #include "MagneticField/Engine/interface/MagneticField.h"
00009 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
00010 #include "TrackingTools/Records/interface/TrackingComponentsRecord.h"
00011 #include "TrackingTools/Records/interface/TransientRecHitRecord.h"
00012 #include "TrackingTools/MaterialEffects/interface/PropagatorWithMaterial.h"
00013 #include "FWCore/Framework/interface/ESHandle.h"
00014 #include "TrackingTools/GeomPropagators/interface/PropagationExceptions.h"
00015 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h"
00016 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateOnSurface.h"
00017 #include "RecoTracker/TransientTrackingRecHit/interface/TSiStripRecHit2DLocalPos.h"
00018
00019
00020 template <class T> T sqr( T t) {return t*t;}
00021
00022 const TrajectorySeed * SeedForPhotonConversion1Leg::trajectorySeed(
00023 TrajectorySeedCollection & seedCollection,
00024 const SeedingHitSet & hits,
00025 const GlobalPoint & vertex,
00026 const GlobalVector & vertexBounds,
00027 float ptmin,
00028 const edm::EventSetup& es,
00029 float cotTheta, std::stringstream& ss)
00030 {
00031 pss = &ss;
00032 if ( hits.size() < 2) return 0;
00033
00034 GlobalTrajectoryParameters kine = initialKinematic(hits, vertex, es, cotTheta);
00035 float sinTheta = sin(kine.momentum().theta());
00036
00037 CurvilinearTrajectoryError error = initialError(vertexBounds, ptmin, sinTheta);
00038 FreeTrajectoryState fts(kine, error);
00039
00040 return buildSeed(seedCollection,hits,fts,es);
00041 }
00042
00043
00044 GlobalTrajectoryParameters SeedForPhotonConversion1Leg::initialKinematic(
00045 const SeedingHitSet & hits,
00046 const GlobalPoint & vertexPos,
00047 const edm::EventSetup& es,
00048 const float cotTheta) const
00049 {
00050 GlobalTrajectoryParameters kine;
00051
00052 TransientTrackingRecHit::ConstRecHitPointer tth1 = hits[0];
00053 TransientTrackingRecHit::ConstRecHitPointer tth2 = hits[1];
00054
00055
00056 FastHelix helix(tth2->globalPosition(), tth1->globalPosition(), vertexPos, es, vertexPos);
00057 kine = helix.stateAtVertex().parameters();
00058
00059
00060 if(fabs(cotTheta)<cotTheta_Max)
00061 kine = GlobalTrajectoryParameters(kine.position(),
00062 GlobalVector(kine.momentum().x(),kine.momentum().y(),kine.momentum().perp()*cotTheta),
00063 kine.charge(),
00064 & kine.magneticField()
00065 );
00066 else
00067 kine = GlobalTrajectoryParameters(kine.position(),
00068 GlobalVector(kine.momentum().x(),kine.momentum().y(),kine.momentum().perp()*cotTheta_Max),
00069 kine.charge(),
00070 & kine.magneticField()
00071 );
00072
00073 #ifdef mydebug_seed
00074 uint32_t detid;
00075 (*pss) << "[SeedForPhotonConversion1Leg] initialKinematic tth1 " ;
00076 detid=tth1->geographicalId().rawId();
00077 po.print(*pss, detid );
00078 (*pss) << " \t " << detid << " " << tth1->localPosition() << " " << tth1->globalPosition() ;
00079 detid= tth2->geographicalId().rawId();
00080 (*pss) << " \n\t tth2 ";
00081 po.print(*pss, detid );
00082 (*pss) << " \t " << detid << " " << tth2->localPosition() << " " << tth2->globalPosition()
00083 << "\nhelix momentum " << kine.momentum() << " pt " << kine.momentum().perp() << " radius " << 1/kine.transverseCurvature();
00084 #endif
00085
00086 edm::ESHandle<MagneticField> bfield;
00087 es.get<IdealMagneticFieldRecord>().get(bfield);
00088 bool isBOFF = ( std::abs(bfield->inTesla(GlobalPoint(0,0,0)).z()) < 1e-3 );
00089 if (isBOFF && (theBOFFMomentum > 0)) {
00090 kine = GlobalTrajectoryParameters(kine.position(),
00091 kine.momentum().unit() * theBOFFMomentum,
00092 kine.charge(),
00093 &*bfield);
00094 }
00095 return kine;
00096 }
00097
00098
00099
00100 CurvilinearTrajectoryError SeedForPhotonConversion1Leg::
00101 initialError(
00102 const GlobalVector& vertexBounds,
00103 float ptMin,
00104 float sinTheta) const
00105 {
00106
00107
00108 GlobalError vertexErr( sqr(vertexBounds.x()), 0,
00109 sqr(vertexBounds.y()), 0, 0,
00110 sqr(vertexBounds.z())
00111 );
00112
00113
00114 AlgebraicSymMatrix55 C = ROOT::Math::SMatrixIdentity();
00115
00116
00117
00118
00119 float sin2th = sqr(sinTheta);
00120 float minC00 = 1.0;
00121 C[0][0] = std::max(sin2th/sqr(ptMin), minC00);
00122 float zErr = vertexErr.czz();
00123 float transverseErr = vertexErr.cxx();
00124 C[3][3] = transverseErr;
00125 C[4][4] = zErr*sin2th + transverseErr*(1-sin2th);
00126
00127 return CurvilinearTrajectoryError(C);
00128 }
00129
00130 const TrajectorySeed * SeedForPhotonConversion1Leg::buildSeed(
00131 TrajectorySeedCollection & seedCollection,
00132 const SeedingHitSet & hits,
00133 const FreeTrajectoryState & fts,
00134 const edm::EventSetup& es) const
00135 {
00136
00137 edm::ESHandle<TrackerGeometry> tracker;
00138 es.get<TrackerDigiGeometryRecord>().get(tracker);
00139
00140
00141 edm::ESHandle<Propagator> propagatorHandle;
00142 es.get<TrackingComponentsRecord>().get(thePropagatorLabel, propagatorHandle);
00143 const Propagator* propagator = &(*propagatorHandle);
00144
00145
00146 KFUpdator updator;
00147
00148
00149
00150 TrajectoryStateOnSurface updatedState;
00151 edm::OwnVector<TrackingRecHit> seedHits;
00152
00153 const TrackingRecHit* hit = 0;
00154 for ( unsigned int iHit = 0; iHit < hits.size() && iHit<1; iHit++) {
00155 hit = hits[iHit]->hit();
00156 TrajectoryStateOnSurface state = (iHit==0) ?
00157 propagator->propagate(fts,tracker->idToDet(hit->geographicalId())->surface())
00158 : propagator->propagate(updatedState, tracker->idToDet(hit->geographicalId())->surface());
00159 if (!state.isValid()) return 0;
00160
00161 TransientTrackingRecHit::ConstRecHitPointer tth = hits[iHit];
00162
00163 TransientTrackingRecHit::RecHitPointer newtth = refitHit( tth, state);
00164
00165
00166 if (!checkHit(state,newtth,es)) return 0;
00167
00168 updatedState = updator.update(state, *newtth);
00169 if (!updatedState.isValid()) return 0;
00170
00171 seedHits.push_back(newtth->hit()->clone());
00172 #ifdef mydebug_seed
00173 uint32_t detid = hit->geographicalId().rawId();
00174 (*pss) << "\n[SeedForPhotonConversion1Leg] hit " << iHit;
00175 po.print(*pss, detid);
00176 (*pss) << " " << detid << "\t lp " << hit->localPosition()
00177 << " tth " << tth->localPosition() << " newtth " << newtth->localPosition() << " state " << state.globalMomentum().perp();
00178 #endif
00179 }
00180
00181
00182 PTrajectoryStateOnDet const & PTraj =
00183 trajectoryStateTransform::persistentState(updatedState, hit->geographicalId().rawId());
00184
00185 seedCollection.push_back( TrajectorySeed(PTraj,seedHits,alongMomentum));
00186 return &seedCollection.back();
00187 }
00188
00189 TransientTrackingRecHit::RecHitPointer SeedForPhotonConversion1Leg::refitHit(
00190 const TransientTrackingRecHit::ConstRecHitPointer &hit,
00191 const TrajectoryStateOnSurface &state) const
00192 {
00193
00194
00195
00196
00197
00198
00199
00200 return hit->clone(state);
00201 }