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 #include "TrackingTools/KalmanUpdators/interface/EtaPhiMeasurementEstimator.h"
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 checkRZOld(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 float outerred_r = sqrt( sqr(ohit.x()-origin().x())+sqr(ohit.y()-origin().y()) );
00057
00058 PixelRecoPointRZ outer(outerred_r, ohit.z());
00059
00060 float zMinOrigin = origin().z() - originZBound();
00061 float zMaxOrigin = origin().z() + originZBound();
00062
00063 if (!thePrecise) {
00064 double vcotMin = (outer.z() > zMaxOrigin) ?
00065 (outer.z()-zMaxOrigin)/(outer.r()+originRBound())
00066 : (outer.z()-zMaxOrigin)/(outer.r()-originRBound());
00067 double vcotMax = (outer.z() > zMinOrigin) ?
00068 (outer.z()-zMinOrigin)/(outer.r()-originRBound())
00069 : (outer.z()-zMinOrigin)/(outer.r()+originRBound());
00070 float cotRight = max(vcotMin,(double) sinh(theEtaRange.min()));
00071 float cotLeft = min(vcotMax, (double) sinh(theEtaRange.max()));
00072 return new HitEtaCheck( isBarrel, outer, cotLeft, cotRight);
00073 }
00074 float hitZErr = 0.;
00075 float hitRErr = 0.;
00076
00077 PixelRecoPointRZ outerL, outerR;
00078 if (layer->location() == GeomDetEnumerators::barrel) {
00079 outerL = PixelRecoPointRZ(outer.r(), outer.z()-hitZErr);
00080 outerR = PixelRecoPointRZ(outer.r(), outer.z()+hitZErr);
00081 } else if (outer.z() > 0) {
00082 outerL = PixelRecoPointRZ(outer.r()+hitRErr, outer.z());
00083 outerR = PixelRecoPointRZ(outer.r()-hitRErr, outer.z());
00084 } else {
00085 outerL = PixelRecoPointRZ(outer.r()-hitRErr, outer.z());
00086 outerR = PixelRecoPointRZ(outer.r()+hitRErr, outer.z());
00087 }
00088
00089 MultipleScatteringParametrisation oSigma(layer,iSetup);
00090 float cotThetaOuter = sinh(theEtaRange.mean());
00091 float sinThetaOuter = 1/sqrt(1+sqr(cotThetaOuter));
00092 float outerZscatt = 3*oSigma(ptMin(),cotThetaOuter) / sinThetaOuter;
00093
00094 PixelRecoLineRZ boundL(outerL, sinh(theEtaRange.max()));
00095 PixelRecoLineRZ boundR(outerR, sinh(theEtaRange.min()));
00096 float zMinLine = boundL.zAtR(0.)-outerZscatt;
00097 float zMaxLine = boundR.zAtR(0.)+outerZscatt;
00098 PixelRecoPointRZ vtxL(0.,max(zMinLine, zMinOrigin));
00099 PixelRecoPointRZ vtxR(0.,min(zMaxLine, zMaxOrigin));
00100 PixelRecoPointRZ vtxMean(0.,(vtxL.z()+vtxR.z())/2.);
00101
00102 MultipleScatteringParametrisation iSigma(layer,iSetup);
00103 float innerScatt = 3 * iSigma(ptMin(),vtxMean, outer);
00104
00105 PixelRecoLineRZ leftLine( vtxL, outerL);
00106 PixelRecoLineRZ rightLine( vtxR, outerR);
00107
00108 HitRZConstraint rzConstraint(leftLine, rightLine);
00109 float cotTheta = fabs(leftLine.cotLine()+rightLine.cotLine())/2;
00110
00111
00112
00113 if (isBarrel) {
00114 float sinTheta = 1/sqrt(1+sqr(cotTheta));
00115 float corrZ = innerScatt/sinTheta + hitZErr;
00116 return new HitZCheck(rzConstraint, HitZCheck::Margin(corrZ,corrZ));
00117 } else {
00118 float cosTheta = 1/sqrt(1+sqr(1/cotTheta));
00119 float corrR = innerScatt/cosTheta + hitRErr;
00120 return new HitRCheck( rzConstraint, HitRCheck::Margin(corrR,corrR));
00121 }
00122 }
00123
00124 OuterEstimator *
00125 RectangularEtaPhiTrackingRegion::estimator(const BarrelDetLayer* layer,const edm::EventSetup& iSetup) const
00126 {
00127
00128
00129 float halfLength = layer->surface().bounds().length()/2;
00130 float halfThickness = layer->surface().bounds().thickness()/2;
00131 float z0 = layer->position().z();
00132 float radius = layer->specificSurface().radius();
00133
00134
00135 Range detRWindow (radius-halfThickness, radius+halfThickness);
00136 Range detZWindow(z0-halfLength,z0+halfLength);
00137
00138
00139 HitZCheck zPrediction(rzConstraint());
00140 Range hitZWindow = zPrediction.range(detRWindow.min()).
00141 intersection(detZWindow);
00142 if (hitZWindow.empty()) return 0;
00143
00144
00145 OuterHitPhiPrediction phiPrediction = phiWindow(iSetup);
00146
00147
00148
00149
00150 OuterHitPhiPrediction::Range phiRange;
00151 if (thePrecise) {
00152 float cotTheta = (hitZWindow.mean()-origin().z()) / radius;
00153 float sinTheta = 1/sqrt(1+sqr(cotTheta));
00154 MultipleScatteringParametrisation msSigma(layer,iSetup);
00155 float scatt = 3 * msSigma(ptMin(), cotTheta);
00156 float bendR = longitudinalBendingCorrection(radius,ptMin(),iSetup);
00157
00158 float hitErrRPhi = 0.;
00159 float hitErrZ = 0.;
00160 float corrPhi = (scatt+ hitErrRPhi)/radius;
00161 float corrZ = scatt/sinTheta + bendR*fabs(cotTheta) + hitErrZ;
00162
00163 phiPrediction.setTolerance(OuterHitPhiPrediction::Margin(corrPhi,corrPhi));
00164 zPrediction.setTolerance(HitZCheck::Margin(corrZ,corrZ));
00165
00166
00167
00168
00169 OuterHitPhiPrediction::Range phi1 = phiPrediction(detRWindow.min());
00170 OuterHitPhiPrediction::Range phi2 = phiPrediction(detRWindow.max());
00171 phiRange = Range( min(phi1.min(),phi2.min()), max(phi1.max(),phi2.max()));
00172 Range w1 = zPrediction.range(detRWindow.min());
00173 Range w2 = zPrediction.range(detRWindow.max());
00174 hitZWindow = Range(
00175 min(w1.min(),w2.min()), max(w1.max(),w2.max())).intersection(detZWindow);
00176 }
00177 else {
00178 phiRange = phiPrediction(detRWindow.mean());
00179 }
00180
00181 return new OuterEstimator(
00182 OuterDetCompatibility( layer, phiRange, detRWindow, hitZWindow),
00183 OuterHitCompatibility( phiPrediction, zPrediction ),
00184 iSetup);
00185 }
00186
00187 OuterEstimator *
00188 RectangularEtaPhiTrackingRegion::estimator(const ForwardDetLayer* layer,const edm::EventSetup& iSetup) const
00189 {
00190
00191
00192 float halfThickness = layer->surface().bounds().thickness()/2;
00193 float zLayer = layer->position().z() ;
00194 Range detZWindow( zLayer-halfThickness, zLayer+halfThickness);
00195 Range detRWindow( layer->specificSurface().innerRadius(),
00196 layer->specificSurface().outerRadius());
00197
00198
00199 HitRCheck rPrediction(rzConstraint());
00200 Range hitRWindow = rPrediction.range(zLayer).intersection(detRWindow);
00201 if (hitRWindow.empty()) return 0;
00202
00203
00204 OuterHitPhiPrediction phiPrediction = phiWindow(iSetup);
00205 OuterHitPhiPrediction::Range phiRange = phiPrediction(detRWindow.max());
00206
00207
00208
00209
00210 if (thePrecise) {
00211 float cotTheta = (detZWindow.mean()-origin().z())/hitRWindow.mean();
00212 float cosTheta = cotTheta/sqrt(1+sqr(cotTheta));
00213 MultipleScatteringParametrisation msSigma(layer,iSetup);
00214 float scatt = 3 * msSigma(ptMin(),cotTheta);
00215 float bendR = longitudinalBendingCorrection(hitRWindow.max(),ptMin(),iSetup);
00216 float hitErrRPhi = 0.;
00217 float hitErrR = 0.;
00218 float corrPhi = (scatt+hitErrRPhi)/detRWindow.min();
00219 float corrR = scatt/fabs(cosTheta) + bendR + hitErrR;
00220
00221 phiPrediction.setTolerance(OuterHitPhiPrediction::Margin(corrPhi,corrPhi));
00222 rPrediction.setTolerance(HitRCheck::Margin(corrR,corrR));
00223
00224
00225
00226
00227 Range w1,w2;
00228 if (zLayer > 0) {
00229 w1 = rPrediction.range(detZWindow.min());
00230 w2 = rPrediction.range(detZWindow.max());
00231 } else {
00232 w1 = rPrediction.range(detZWindow.max());
00233 w2 = rPrediction.range(detZWindow.min());
00234 }
00235 hitRWindow = Range(w1.min(),w2.max()).intersection(detRWindow);
00236 }
00237
00238 return new OuterEstimator(
00239 OuterDetCompatibility( layer, phiRange, hitRWindow, detZWindow),
00240 OuterHitCompatibility( phiPrediction, rPrediction),iSetup );
00241 }
00242
00243
00244
00245 OuterHitPhiPrediction
00246 RectangularEtaPhiTrackingRegion::phiWindow(const edm::EventSetup& iSetup) const
00247 {
00248 float phi0 = direction().phi();
00249 return OuterHitPhiPrediction(
00250 OuterHitPhiPrediction::Range( phi0-thePhiMargin.left(),
00251 phi0+thePhiMargin.left()),
00252 OuterHitPhiPrediction::Range( curvature(invPtRange().min(),iSetup),
00253 curvature(invPtRange().max(),iSetup)),
00254 originRBound());
00255 }
00256
00257
00258 HitRZConstraint
00259 RectangularEtaPhiTrackingRegion::rzConstraint() const
00260 {
00261 HitRZConstraint::LineOrigin pLeft,pRight;
00262 float zMin = origin().z() - originZBound();
00263 float zMax = origin().z() + originZBound();
00264 float rMin = -originRBound();
00265 float rMax = originRBound();
00266 if(theEtaRange.max() > 0) {
00267 pRight = HitRZConstraint::LineOrigin(rMin,zMax);
00268 } else {
00269 pRight = HitRZConstraint::LineOrigin(rMax,zMax);
00270 }
00271 if (theEtaRange.min() > 0.) {
00272 pLeft = HitRZConstraint::LineOrigin(rMax, zMin);
00273 } else {
00274 pLeft = HitRZConstraint::LineOrigin(rMin, zMin);
00275 }
00276 return HitRZConstraint(pLeft, sinh(theEtaRange.min()),
00277 pRight, sinh(theEtaRange.max()) );
00278 }
00279
00280 TrackingRegion::Hits RectangularEtaPhiTrackingRegion::hits(
00281 const edm::Event& ev,
00282 const edm::EventSetup& es,
00283 const SeedingLayer* layer) const
00284 {
00285
00286
00287
00288 TrackingRegion::Hits result;
00289
00290 const DetLayer * detLayer = layer->detLayer();
00291 OuterEstimator * est = 0;
00292
00293 bool measurementMethod = false;
00294 if ( theMeasurementTrackerUsage > 0.5) measurementMethod = true;
00295 if ( theMeasurementTrackerUsage > -0.5 &&
00296 !(detLayer->subDetector() == GeomDetEnumerators::PixelBarrel ||
00297 detLayer->subDetector() == GeomDetEnumerators::PixelEndcap) ) measurementMethod = true;
00298
00299 if(measurementMethod) {
00300 edm::ESHandle<MagneticField> field;
00301 es.get<IdealMagneticFieldRecord>().get(field);
00302 const MagneticField * magField = field.product();
00303
00304 const GlobalPoint vtx = origin();
00305 GlobalVector dir = direction();
00306
00307 if (detLayer->subDetector() == GeomDetEnumerators::PixelBarrel || (!theUseEtaPhi && detLayer->location() == GeomDetEnumerators::barrel)){
00308 const BarrelDetLayer& bl = dynamic_cast<const BarrelDetLayer&>(*detLayer);
00309 est = estimator(&bl,es);
00310 } else if (detLayer->subDetector() == GeomDetEnumerators::PixelEndcap || (!theUseEtaPhi && detLayer->location() == GeomDetEnumerators::endcap)) {
00311 const ForwardDetLayer& fl = dynamic_cast<const ForwardDetLayer&>(*detLayer);
00312 est = estimator(&fl,es);
00313 }
00314
00315 EtaPhiMeasurementEstimator etaPhiEstimator ((theEtaRange.second-theEtaRange.first)/2.,
00316 (thePhiMargin.left()+thePhiMargin.right())/2.);
00317 MeasurementEstimator & findDetAndHits = etaPhiEstimator;
00318 if (est){
00319 LogDebug("RectangularEtaPhiTrackingRegion")<<"use pixel specific estimator.";
00320 findDetAndHits =*est;
00321 }
00322 else{
00323 LogDebug("RectangularEtaPhiTrackingRegion")<<"use generic etat phi estimator.";
00324 }
00325
00326
00327 float phi = dir.phi();
00328 Surface::RotationType rot( sin(phi), -cos(phi), 0,
00329 0, 0, -1,
00330 cos(phi), sin(phi), 0);
00331
00332 Plane::PlanePointer surface = Plane::build(GlobalPoint(0.,0.,0.), rot);
00333
00334
00335 FreeTrajectoryState fts( GlobalTrajectoryParameters(vtx, dir, 1, magField) );
00336 TrajectoryStateOnSurface tsos(fts, *surface);
00337
00338
00339 StraightLinePropagator prop( magField, alongMomentum);
00340
00341 edm::ESHandle<MeasurementTracker> measurementTrackerESH;
00342 es.get<CkfComponentsRecord>().get(theMeasurementTrackerName, measurementTrackerESH);
00343 const MeasurementTracker * measurementTracker = measurementTrackerESH.product();
00344 measurementTracker->update(ev);
00345
00346 LayerMeasurements lm(measurementTracker);
00347
00348 vector<TrajectoryMeasurement> meas = lm.measurements(*detLayer, tsos, prop, findDetAndHits);
00349 typedef vector<TrajectoryMeasurement>::const_iterator IM;
00350 for (IM im = meas.begin(); im != meas.end(); im++) {
00351 TrajectoryMeasurement::ConstRecHitPointer ptrHit = im->recHit();
00352 if (ptrHit->isValid()) result.push_back( ptrHit );
00353 }
00354
00355 LogDebug("RectangularEtaPhiTrackingRegion")<<" found "<< meas.size()<<" minus one measurements on layer: "<<detLayer->subDetector();
00356
00357 } else {
00358
00359
00360
00361 if (detLayer->location() == GeomDetEnumerators::barrel) {
00362 const BarrelDetLayer& bl = dynamic_cast<const BarrelDetLayer&>(*detLayer);
00363 est = estimator(&bl,es);
00364 } else {
00365 const ForwardDetLayer& fl = dynamic_cast<const ForwardDetLayer&>(*detLayer);
00366 est = estimator(&fl,es);
00367 }
00368 if (!est) return result;
00369
00370 TrackingRegion::Hits layerHits = layer->hits(ev,es);
00371 for (TrackingRegion::Hits::const_iterator ih= layerHits.begin(); ih != layerHits.end(); ih++) {
00372 const TrackingRecHit * hit = (*ih)->hit();
00373 if ( est->hitCompatibility()(hit,es) ) {
00374 result.push_back( *ih );
00375 }
00376 }
00377 }
00378
00379 delete est;
00380 return result;
00381 }
00382
00383 std::string RectangularEtaPhiTrackingRegion::print() const {
00384 std::ostringstream str;
00385 str << TrackingRegionBase::print()
00386 <<" eta: "<<theEtaRange<<" phi:"<<thePhiMargin
00387 << "precise: "<<thePrecise;
00388 return str.str();
00389 }
00390