1 |
#include "TrackingTools/PatternTools/interface/TSCPBuilderNoMaterial.h"
|
2 |
#include "DataFormats/GeometrySurface/interface/Surface.h"
|
3 |
#include "TrackingTools/TrajectoryState/interface/FreeTrajectoryState.h"
|
4 |
#include "TrackingTools/AnalyticalJacobians/interface/AnalyticalCurvilinearJacobian.h"
|
5 |
#include "DataFormats/GeometrySurface/interface/BoundPlane.h"
|
6 |
#include "TrackingTools/GeomPropagators/interface/HelixBarrelPlaneCrossingByCircle.h"
|
7 |
#include "TrackingTools/TrajectoryParametrization/interface/TrajectoryStateExceptions.h"
|
8 |
#include "MagneticField/Engine/interface/MagneticField.h"
|
9 |
#include "FWCore/MessageLogger/interface/MessageLogger.h"
|
10 |
|
11 |
TrajectoryStateClosestToPoint
|
12 |
TSCPBuilderNoMaterial::operator() (const FTS& originalFTS,
|
13 |
const GlobalPoint& referencePoint) const
|
14 |
{
|
15 |
if (positionEqual(referencePoint, originalFTS.position()))
|
16 |
return constructTSCP(originalFTS, referencePoint);
|
17 |
|
18 |
// Now do the propagation or whatever...
|
19 |
|
20 |
PairBoolFTS newStatePair =
|
21 |
createFTSatTransverseImpactPoint(originalFTS, referencePoint);
|
22 |
if (newStatePair.first) {
|
23 |
return constructTSCP(newStatePair.second, referencePoint);
|
24 |
} else {
|
25 |
return TrajectoryStateClosestToPoint();
|
26 |
}
|
27 |
}
|
28 |
|
29 |
TrajectoryStateClosestToPoint
|
30 |
TSCPBuilderNoMaterial::operator() (const TSOS& originalTSOS,
|
31 |
const GlobalPoint& referencePoint) const
|
32 |
{
|
33 |
if (positionEqual(referencePoint, originalTSOS.globalPosition()))
|
34 |
return constructTSCP(*originalTSOS.freeState(), referencePoint);
|
35 |
|
36 |
// Now do the propagation
|
37 |
|
38 |
PairBoolFTS newStatePair =
|
39 |
createFTSatTransverseImpactPoint(*originalTSOS.freeState(), referencePoint);
|
40 |
if (newStatePair.first) {
|
41 |
return constructTSCP(newStatePair.second, referencePoint);
|
42 |
} else {
|
43 |
return TrajectoryStateClosestToPoint();
|
44 |
}
|
45 |
}
|
46 |
|
47 |
TSCPBuilderNoMaterial::PairBoolFTS
|
48 |
TSCPBuilderNoMaterial::createFTSatTransverseImpactPoint(
|
49 |
const FTS& originalFTS, const GlobalPoint& referencePoint) const
|
50 |
{
|
51 |
//
|
52 |
// Straight line approximation? |rho|<1.e-10 equivalent to ~ 1um
|
53 |
// difference in transversal position at 10m.
|
54 |
//
|
55 |
if( fabs(originalFTS.transverseCurvature())<1.e-10 ) {
|
56 |
return createFTSatTransverseImpactPointNeutral(originalFTS, referencePoint);
|
57 |
} else {
|
58 |
return createFTSatTransverseImpactPointCharged(originalFTS, referencePoint);
|
59 |
}
|
60 |
}
|
61 |
|
62 |
TSCPBuilderNoMaterial::PairBoolFTS
|
63 |
TSCPBuilderNoMaterial::createFTSatTransverseImpactPointCharged(
|
64 |
const FTS& originalFTS, const GlobalPoint& referencePoint) const
|
65 |
{
|
66 |
|
67 |
GlobalVector pvecOrig = originalFTS.momentum();
|
68 |
GlobalPoint xvecOrig = originalFTS.position();
|
69 |
double kappa = originalFTS.transverseCurvature();
|
70 |
double pxOrig = pvecOrig.x();
|
71 |
double pyOrig = pvecOrig.y();
|
72 |
double pzOrig = pvecOrig.z();
|
73 |
double xOrig = xvecOrig.x();
|
74 |
double yOrig = xvecOrig.y();
|
75 |
double zOrig = xvecOrig.z();
|
76 |
|
77 |
// double fac = 1./originalFTS.charge()/MagneticField::inInverseGeV(referencePoint).z();
|
78 |
double fac = 1./originalFTS.charge()/
|
79 |
(originalFTS.parameters().magneticField().inInverseGeV(referencePoint).z());
|
80 |
GlobalVectorDouble xOrig2Centre = GlobalVectorDouble(fac * pyOrig, -fac * pxOrig, 0.);
|
81 |
GlobalVectorDouble xOrigProj = GlobalVectorDouble(xOrig, yOrig, 0.);
|
82 |
GlobalVectorDouble xRefProj = GlobalVectorDouble(referencePoint.x(), referencePoint.y(), 0.);
|
83 |
GlobalVectorDouble deltax = xRefProj-xOrigProj-xOrig2Centre;
|
84 |
GlobalVectorDouble ndeltax = deltax.unit();
|
85 |
|
86 |
PropagationDirection direction = anyDirection;
|
87 |
Surface::PositionType pos(referencePoint);
|
88 |
// Need to define plane with orientation as the
|
89 |
// ImpactPointSurface
|
90 |
GlobalVector X(ndeltax.x(), ndeltax.y(), ndeltax.z());
|
91 |
GlobalVector Y(0.,0.,1.);
|
92 |
Surface::RotationType rot(X,Y);
|
93 |
BoundPlane* plane = new BoundPlane(pos,rot);
|
94 |
// Using Teddy's HelixBarrelPlaneCrossingByCircle for general barrel planes.
|
95 |
// A large variety of other,
|
96 |
// direct solutions turned out to be not so stable numerically.
|
97 |
HelixBarrelPlaneCrossingByCircle
|
98 |
planeCrossing(HelixPlaneCrossing::PositionType(xOrig, yOrig, zOrig),
|
99 |
HelixPlaneCrossing::DirectionType(pxOrig, pyOrig, pzOrig),
|
100 |
kappa, direction);
|
101 |
std::pair<bool,double> propResult = planeCrossing.pathLength(*plane);
|
102 |
if ( !propResult.first ) {
|
103 |
edm::LogWarning ("TSCPBuilderNoMaterial") << "Propagation to perigee plane failed!";
|
104 |
return PairBoolFTS(false, FreeTrajectoryState() );
|
105 |
}
|
106 |
double s = propResult.second;
|
107 |
HelixPlaneCrossing::PositionType xGen = planeCrossing.position(s);
|
108 |
GlobalPoint xPerigee = GlobalPoint(xGen.x(),xGen.y(),xGen.z());
|
109 |
// direction (reconverted to GlobalVector, renormalised)
|
110 |
HelixPlaneCrossing::DirectionType pGen = planeCrossing.direction(s);
|
111 |
pGen *= pvecOrig.mag()/pGen.mag();
|
112 |
GlobalVector pPerigee = GlobalVector(pGen.x(),pGen.y(),pGen.z());
|
113 |
delete plane;
|
114 |
|
115 |
if (originalFTS.hasError()) {
|
116 |
const AlgebraicSymMatrix55 &errorMatrix = originalFTS.curvilinearError().matrix();
|
117 |
AnalyticalCurvilinearJacobian curvilinJacobian(originalFTS.parameters(), xPerigee,
|
118 |
pPerigee, s);
|
119 |
const AlgebraicMatrix55 &jacobian = curvilinJacobian.jacobian();
|
120 |
CurvilinearTrajectoryError cte( ROOT::Math::Similarity(jacobian, errorMatrix) );
|
121 |
|
122 |
return PairBoolFTS(true,
|
123 |
FreeTrajectoryState(GlobalTrajectoryParameters(xPerigee, pPerigee, originalFTS.charge(),
|
124 |
&(originalFTS.parameters().magneticField())), cte) );
|
125 |
}
|
126 |
else {
|
127 |
return PairBoolFTS(true,
|
128 |
FreeTrajectoryState(GlobalTrajectoryParameters(xPerigee, pPerigee, originalFTS.charge(),
|
129 |
&(originalFTS.parameters().magneticField()))) );
|
130 |
}
|
131 |
|
132 |
}
|
133 |
|
134 |
|
135 |
TSCPBuilderNoMaterial::PairBoolFTS
|
136 |
TSCPBuilderNoMaterial::createFTSatTransverseImpactPointNeutral(const FTS& originalFTS,
|
137 |
const GlobalPoint& referencePoint) const
|
138 |
{
|
139 |
|
140 |
GlobalPoint xvecOrig = originalFTS.position();
|
141 |
double phi = originalFTS.momentum().phi();
|
142 |
double theta = originalFTS.momentum().theta();
|
143 |
double xOrig = xvecOrig.x();
|
144 |
double yOrig = xvecOrig.y();
|
145 |
double zOrig = xvecOrig.z();
|
146 |
double xR = referencePoint.x();
|
147 |
double yR = referencePoint.y();
|
148 |
|
149 |
double s2D = (xR - xOrig) * cos(phi) + (yR - yOrig) * sin(phi);
|
150 |
double s = s2D / sin(theta);
|
151 |
double xGen = xOrig + s2D*cos(phi);
|
152 |
double yGen = yOrig + s2D*sin(phi);
|
153 |
double zGen = zOrig + s2D/tan(theta);
|
154 |
GlobalPoint xPerigee = GlobalPoint(xGen, yGen, zGen);
|
155 |
|
156 |
GlobalVector pPerigee = originalFTS.momentum();
|
157 |
|
158 |
if (originalFTS.hasError()) {
|
159 |
const AlgebraicSymMatrix55 &errorMatrix = originalFTS.curvilinearError().matrix();
|
160 |
AnalyticalCurvilinearJacobian curvilinJacobian(originalFTS.parameters(), xPerigee,
|
161 |
pPerigee, s);
|
162 |
const AlgebraicMatrix55 &jacobian = curvilinJacobian.jacobian();
|
163 |
CurvilinearTrajectoryError cte( ROOT::Math::Similarity(jacobian, errorMatrix) );
|
164 |
|
165 |
return PairBoolFTS(true,
|
166 |
FreeTrajectoryState(GlobalTrajectoryParameters(xPerigee, pPerigee, originalFTS.charge(),
|
167 |
&(originalFTS.parameters().magneticField())), cte));
|
168 |
}
|
169 |
else {
|
170 |
return PairBoolFTS(true,
|
171 |
FreeTrajectoryState(GlobalTrajectoryParameters(xPerigee, pPerigee, originalFTS.charge(),
|
172 |
&(originalFTS.parameters().magneticField()))) );
|
173 |
}
|
174 |
|
175 |
}
|