00001 #include <cmath>
00002 #include "RecoTracker/TkTrackingRegions/interface/RectangularEtaPhiTrackingRegion.h"
00003 #include "RecoTracker/TkTrackingRegions/interface/OuterEstimator.h"
00004
00005 #include "TrackingTools/TrajectoryParametrization/interface/GlobalTrajectoryParameters.h"
00006 #include "TrackingTools/TrajectoryParametrization/interface/LocalTrajectoryParameters.h"
00007 #include "TrackingTools/TrajectoryState/interface/FreeTrajectoryState.h"
00008 #include "TrackingTools/GeomPropagators/interface/StraightLinePropagator.h"
00009 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateOnSurface.h"
00010
00011 #include "TrackingTools/DetLayers/interface/BarrelDetLayer.h"
00012 #include "TrackingTools/DetLayers/interface/ForwardDetLayer.h"
00013 #include "TrackingTools/DetLayers/interface/DetLayer.h"
00014 #include "RecoTracker/TkTrackingRegions/interface/HitRCheck.h"
00015 #include "RecoTracker/TkTrackingRegions/interface/HitZCheck.h"
00016 #include "RecoTracker/TkTrackingRegions/interface/HitEtaCheck.h"
00017 #include "DataFormats/TrackingRecHit/interface/TrackingRecHit.h"
00018 #include "RecoTracker/TkMSParametrization/interface/PixelRecoUtilities.h"
00019 #include "RecoTracker/TkMSParametrization/interface/MultipleScatteringParametrisation.h"
00020 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
00021 #include "Geometry/Records/interface/TrackerDigiGeometryRecord.h"
00022
00023 #include "MagneticField/Engine/interface/MagneticField.h"
00024 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
00025
00026 #include "RecoTracker/Record/interface/CkfComponentsRecord.h"
00027 #include "RecoTracker/MeasurementDet/interface/MeasurementTracker.h"
00028 #include "TrackingTools/MeasurementDet/interface/LayerMeasurements.h"
00029 #include "TrackingTools/PatternTools/interface/TrajectoryMeasurement.h"
00030 #include "DataFormats/GeometrySurface/interface/BoundPlane.h"
00031 #include "TrackingTools/TransientTrackingRecHit/interface/TransientTrackingRecHit.h"
00032
00033
00034 template <class T> T sqr( T t) {return t*t;}
00035
00036
00037 using namespace PixelRecoUtilities;
00038 using namespace std;
00039 using namespace ctfseeding;
00040
00041 void RectangularEtaPhiTrackingRegion::
00042 initEtaRange( const GlobalVector & dir, const Margin& margin)
00043 {
00044 float eta = dir.eta();
00045 theEtaRange = Range(eta-margin.left(), eta+margin.right());
00046 }
00047
00048 HitRZCompatibility* RectangularEtaPhiTrackingRegion::
00049 checkRZ(const DetLayer* layer, const TrackingRecHit *outerHit,const edm::EventSetup& iSetup) const
00050 {
00051 edm::ESHandle<TrackerGeometry> tracker;
00052 iSetup.get<TrackerDigiGeometryRecord>().get(tracker);
00053
00054 bool isBarrel = (layer->location() == GeomDetEnumerators::barrel);
00055 GlobalPoint ohit = tracker->idToDet(outerHit->geographicalId())->surface().toGlobal(outerHit->localPosition());
00056 PixelRecoPointRZ outer(ohit.perp(), ohit.z());
00057
00058 float zMinOrigin = origin().z() - originZBound();
00059 float zMaxOrigin = origin().z() + originZBound();
00060
00061 if (!thePrecise) {
00062 double vcotMin = (outer.z() > zMaxOrigin) ?
00063 (outer.z()-zMaxOrigin)/(outer.r()+originRBound())
00064 : (outer.z()-zMaxOrigin)/(outer.r()-originRBound());
00065 double vcotMax = (outer.z() > zMinOrigin) ?
00066 (outer.z()-zMinOrigin)/(outer.r()-originRBound())
00067 : (outer.z()-zMinOrigin)/(outer.r()+originRBound());
00068 float cotRight = max(vcotMin,(double) sinh(theEtaRange.min()));
00069 float cotLeft = min(vcotMax, (double) sinh(theEtaRange.max()));
00070 return new HitEtaCheck( isBarrel, outer, cotLeft, cotRight);
00071 }
00072 float hitZErr = hitErrZ(layer);
00073 float hitRErr = hitErrR(layer);
00074
00075 PixelRecoPointRZ outerL, outerR;
00076 if (layer->location() == GeomDetEnumerators::barrel) {
00077 outerL = PixelRecoPointRZ(outer.r(), outer.z()-hitZErr);
00078 outerR = PixelRecoPointRZ(outer.r(), outer.z()+hitZErr);
00079 } else if (outer.z() > 0) {
00080 outerL = PixelRecoPointRZ(outer.r()+hitRErr, outer.z());
00081 outerR = PixelRecoPointRZ(outer.r()-hitRErr, outer.z());
00082 } else {
00083 outerL = PixelRecoPointRZ(outer.r()-hitRErr, outer.z());
00084 outerR = PixelRecoPointRZ(outer.r()+hitRErr, outer.z());
00085 }
00086
00087 MultipleScatteringParametrisation oSigma(layer,iSetup);
00088 float cotThetaOuter = sinh(theEtaRange.mean());
00089 float sinThetaOuter = 1/sqrt(1+sqr(cotThetaOuter));
00090 float outerZscatt = 3*oSigma(ptMin(),cotThetaOuter) / sinThetaOuter;
00091
00092 PixelRecoLineRZ boundL(outerL, sinh(theEtaRange.max()));
00093 PixelRecoLineRZ boundR(outerR, sinh(theEtaRange.min()));
00094 float zMinLine = boundL.zAtR(0.)-outerZscatt;
00095 float zMaxLine = boundR.zAtR(0.)+outerZscatt;
00096 PixelRecoPointRZ vtxL(0.,max(zMinLine, zMinOrigin));
00097 PixelRecoPointRZ vtxR(0.,min(zMaxLine, zMaxOrigin));
00098 PixelRecoPointRZ vtxMean(0.,(vtxL.z()+vtxR.z())/2.);
00099
00100 MultipleScatteringParametrisation iSigma(layer,iSetup);
00101 float innerScatt = 3 * iSigma(ptMin(),vtxMean, outer);
00102
00103 PixelRecoLineRZ leftLine( vtxL, outerL);
00104 PixelRecoLineRZ rightLine( vtxR, outerR);
00105
00106 HitRZConstraint rzConstraint(leftLine, rightLine);
00107 float cotTheta = fabs(leftLine.cotLine()+rightLine.cotLine())/2;
00108
00109
00110
00111 if (isBarrel) {
00112 float sinTheta = 1/sqrt(1+sqr(cotTheta));
00113 float corrZ = innerScatt/sinTheta + hitZErr;
00114 return new HitZCheck(rzConstraint, HitZCheck::Margin(corrZ,corrZ));
00115 } else {
00116 float cosTheta = 1/sqrt(1+sqr(1/cotTheta));
00117 float corrR = innerScatt/cosTheta + hitRErr;
00118 return new HitRCheck( rzConstraint, HitRCheck::Margin(corrR,corrR));
00119 }
00120 }
00121
00122 OuterEstimator *
00123 RectangularEtaPhiTrackingRegion::estimator(const BarrelDetLayer* layer,const edm::EventSetup& iSetup) const
00124 {
00125
00126
00127 float halfLength = layer->surface().bounds().length()/2;
00128 float halfThickness = layer->surface().bounds().thickness()/2;
00129 float z0 = layer->position().z();
00130 float radius = layer->specificSurface().radius();
00131
00132
00133 Range detRWindow (radius-halfThickness, radius+halfThickness);
00134 Range detZWindow(z0-halfLength,z0+halfLength);
00135
00136
00137 HitZCheck zPrediction(rzConstraint());
00138 Range hitZWindow = zPrediction.range(detRWindow.min()).
00139 intersection(detZWindow);
00140 if (hitZWindow.empty()) return 0;
00141
00142
00143 OuterHitPhiPrediction phiPrediction = phiWindow(iSetup);
00144
00145
00146
00147
00148 OuterHitPhiPrediction::Range phiRange;
00149 if (thePrecise) {
00150 float cotTheta = (hitZWindow.mean()-origin().z()) / radius;
00151 float sinTheta = 1/sqrt(1+sqr(cotTheta));
00152 MultipleScatteringParametrisation msSigma(layer,iSetup);
00153 float scatt = 3 * msSigma(ptMin(), cotTheta);
00154 float bendR = longitudinalBendingCorrection(radius,ptMin(),iSetup);
00155
00156 float corrPhi = (scatt+ hitErrRPhi(layer))/radius;
00157 float corrZ = scatt/sinTheta + bendR*fabs(cotTheta) + hitErrZ(layer);
00158
00159 phiPrediction.setTolerance(OuterHitPhiPrediction::Margin(corrPhi,corrPhi));
00160 zPrediction.setTolerance(HitZCheck::Margin(corrZ,corrZ));
00161
00162
00163
00164
00165 OuterHitPhiPrediction::Range phi1 = phiPrediction(detRWindow.min());
00166 OuterHitPhiPrediction::Range phi2 = phiPrediction(detRWindow.max());
00167 phiRange = Range( min(phi1.min(),phi2.min()), max(phi1.max(),phi2.max()));
00168 Range w1 = zPrediction.range(detRWindow.min());
00169 Range w2 = zPrediction.range(detRWindow.max());
00170 hitZWindow = Range(
00171 min(w1.min(),w2.min()), max(w1.max(),w2.max())).intersection(detZWindow);
00172 }
00173 else {
00174 phiRange = phiPrediction(detRWindow.mean());
00175 }
00176
00177 return new OuterEstimator(
00178 OuterDetCompatibility( layer, phiRange, detRWindow, hitZWindow),
00179 OuterHitCompatibility( phiPrediction, zPrediction ),
00180 iSetup);
00181 }
00182
00183 OuterEstimator *
00184 RectangularEtaPhiTrackingRegion::estimator(const ForwardDetLayer* layer,const edm::EventSetup& iSetup) const
00185 {
00186
00187
00188 float halfThickness = layer->surface().bounds().thickness()/2;
00189 float zLayer = layer->position().z() ;
00190 Range detZWindow( zLayer-halfThickness, zLayer+halfThickness);
00191 Range detRWindow( layer->specificSurface().innerRadius(),
00192 layer->specificSurface().outerRadius());
00193
00194
00195 HitRCheck rPrediction(rzConstraint());
00196 Range hitRWindow = rPrediction.range(zLayer).intersection(detRWindow);
00197 if (hitRWindow.empty()) return 0;
00198
00199
00200 OuterHitPhiPrediction phiPrediction = phiWindow(iSetup);
00201 OuterHitPhiPrediction::Range phiRange = phiPrediction(detRWindow.max());
00202
00203
00204
00205
00206 if (thePrecise) {
00207 float cotTheta = (detZWindow.mean()-origin().z())/hitRWindow.mean();
00208 float cosTheta = cotTheta/sqrt(1+sqr(cotTheta));
00209 MultipleScatteringParametrisation msSigma(layer,iSetup);
00210 float scatt = 3 * msSigma(ptMin(),cotTheta);
00211 float bendR = longitudinalBendingCorrection(hitRWindow.max(),ptMin(),iSetup);
00212 float corrPhi = (scatt+hitErrRPhi(layer))/detRWindow.min();
00213 float corrR = scatt/fabs(cosTheta) + bendR + hitErrR(layer);
00214
00215 phiPrediction.setTolerance(OuterHitPhiPrediction::Margin(corrPhi,corrPhi));
00216 rPrediction.setTolerance(HitRCheck::Margin(corrR,corrR));
00217
00218
00219
00220
00221 Range w1,w2;
00222 if (zLayer > 0) {
00223 w1 = rPrediction.range(detZWindow.min());
00224 w2 = rPrediction.range(detZWindow.max());
00225 } else {
00226 w1 = rPrediction.range(detZWindow.max());
00227 w2 = rPrediction.range(detZWindow.min());
00228 }
00229 hitRWindow = Range(w1.min(),w2.max()).intersection(detRWindow);
00230 }
00231
00232 return new OuterEstimator(
00233 OuterDetCompatibility( layer, phiRange, hitRWindow, detZWindow),
00234 OuterHitCompatibility( phiPrediction, rPrediction),iSetup );
00235 }
00236
00237
00238
00239 OuterHitPhiPrediction
00240 RectangularEtaPhiTrackingRegion::phiWindow(const edm::EventSetup& iSetup) const
00241 {
00242 float phi0 = direction().phi();
00243 return OuterHitPhiPrediction(
00244 OuterHitPhiPrediction::Range( phi0-thePhiMargin.left(),
00245 phi0+thePhiMargin.left()),
00246 OuterHitPhiPrediction::Range( curvature(invPtRange().min(),iSetup),
00247 curvature(invPtRange().max(),iSetup)),
00248 originRBound());
00249 }
00250
00251
00252 HitRZConstraint
00253 RectangularEtaPhiTrackingRegion::rzConstraint() const
00254 {
00255 HitRZConstraint::LineOrigin pLeft,pRight;
00256 float zMin = origin().z() - originZBound();
00257 float zMax = origin().z() + originZBound();
00258 float rMin = -originRBound();
00259 float rMax = originRBound();
00260 if(theEtaRange.max() > 0) {
00261 pRight = HitRZConstraint::LineOrigin(rMin,zMax);
00262 } else {
00263 pRight = HitRZConstraint::LineOrigin(rMax,zMax);
00264 }
00265 if (theEtaRange.min() > 0.) {
00266 pLeft = HitRZConstraint::LineOrigin(rMax, zMin);
00267 } else {
00268 pLeft = HitRZConstraint::LineOrigin(rMin, zMin);
00269 }
00270 return HitRZConstraint(pLeft, sinh(theEtaRange.min()),
00271 pRight, sinh(theEtaRange.max()) );
00272 }
00273
00274 std::vector< SeedingHit> RectangularEtaPhiTrackingRegion::hits(
00275 const edm::Event& ev,
00276 const edm::EventSetup& es,
00277 const SeedingLayer* layer) const
00278 {
00279
00280
00281
00282
00283 std::vector< SeedingHit> result;
00284 const DetLayer * detLayer = layer->detLayer();
00285 OuterEstimator * est = 0;
00286 if (detLayer->location() == GeomDetEnumerators::barrel) {
00287 const BarrelDetLayer& bl = dynamic_cast<const BarrelDetLayer&>(*detLayer);
00288 est = estimator(&bl,es);
00289 } else {
00290 const ForwardDetLayer& fl = dynamic_cast<const ForwardDetLayer&>(*detLayer);
00291 est = estimator(&fl,es);
00292 }
00293 if (!est) return result;
00294
00295 bool measurementMethod = false;
00296 if ( theTemporaryFix > 0.5) measurementMethod = true;
00297 if ( theTemporaryFix > -0.5 &&
00298 !(detLayer->subDetector() == GeomDetEnumerators::PixelBarrel ||
00299 detLayer->subDetector() == GeomDetEnumerators::PixelEndcap) ) measurementMethod = true;
00300
00301 if(measurementMethod) {
00302 edm::ESHandle<MagneticField> field;
00303 es.get<IdealMagneticFieldRecord>().get(field);
00304 const MagneticField * magField = field.product();
00305
00306 const GlobalPoint vtx = origin();
00307 GlobalVector dir = est->center() - vtx;
00308
00309
00310 float phi = dir.phi();
00311 Surface::RotationType rot( sin(phi), -cos(phi), 0,
00312 0, 0, -1,
00313 cos(phi), sin(phi), 0);
00314
00315 Plane::PlanePointer surface = Plane::build(GlobalPoint(0.,0.,0.), rot);
00316
00317
00318 FreeTrajectoryState fts( GlobalTrajectoryParameters(vtx, dir, 1, magField) );
00319 TrajectoryStateOnSurface tsos(fts, *surface);
00320
00321
00322 StraightLinePropagator prop( magField, alongMomentum);
00323
00324 edm::ESHandle<MeasurementTracker> measurementTrackerESH;
00325 es.get<CkfComponentsRecord>().get(measurementTrackerESH);
00326 const MeasurementTracker * measurementTracker = measurementTrackerESH.product();
00327 measurementTracker->update(ev);
00328
00329 LayerMeasurements lm(measurementTracker);
00330
00331 vector<TrajectoryMeasurement> meas = lm.measurements(*detLayer, tsos, prop, *est);
00332 typedef vector<TrajectoryMeasurement>::const_iterator IM;
00333 for (IM im = meas.begin(); im != meas.end(); im++) {
00334 TrajectoryMeasurement::ConstRecHitPointer ptrHit = im->recHit();
00335 if (ptrHit->isValid()) {
00336 result.push_back( SeedingHit( ptrHit, *layer));
00337 }
00338 }
00339 } else {
00340
00341
00342
00343 typedef std::vector< SeedingHit> Hits;
00344 Hits layerHits = layer->hits(ev,es);
00345 for (Hits::const_iterator ih= layerHits.begin(); ih != layerHits.end(); ih++) {
00346 const TrackingRecHit * hit = *ih;
00347 if ( est->hitCompatibility()(hit,es) ) {
00348 result.push_back( *ih );
00349 }
00350 }
00351 }
00352
00353 delete est;
00354 return result;
00355 }
00356
00357 std::string RectangularEtaPhiTrackingRegion::print() const {
00358 std::ostringstream str;
00359 str << TrackingRegionBase::print()
00360 <<" eta: "<<theEtaRange<<" phi:"<<thePhiMargin
00361 << "precise: "<<thePrecise;
00362 return str.str();
00363 }
00364