LDMX Software
Public Member Functions | List of all members
tracking::sim::SeedToTrackParamMaker Class Reference

Public Member Functions

template<typename external_spacepoint_t >
bool KarimakiFit (const std::vector< external_spacepoint_t * > &sp, std::array< double, 9 > &data, const Acts::Vector2 refPoint)
 
bool transformRhoPhid (const Acts::Vector2 &r1, const Acts::Vector2 &r2, double &phi, double &rho, double &d)
 
template<typename external_spacepoint_t >
bool FitSeedAtlas (const Acts::Seed< external_spacepoint_t > &seed, std::array< double, 9 > &data, const Acts::Transform3 &Tp, const double &bFieldZ)
 This resembles the method used in ATLAS for the seed fitting L811 https://acode-browser.usatlas.bnl.gov/lxr/source/athena/InnerDetector/InDetRecTools/SiTrackMakerTool_xk/src/SiTrackMaker_xk.cxx.
 
template<typename external_spacepoint_t >
bool FitSeedAtlas (const std::vector< external_spacepoint_t > &sp, std::array< double, 9 > &data, const Acts::Transform3 &Tp, const double &bFieldZ)
 
template<typename external_spacepoint_t >
bool FitSeedLinPar (const Acts::Seed< external_spacepoint_t > &seed, std::vector< double > &data)
 This is a simple Line and Parabola fit (from HPS reconstruction by Robert Johnson)
 
template<typename spacepoint_iterator_t >
std::optional< Acts::BoundVector > estimateTrackParamsFromSeed (const Acts::Transform3 &Tp, spacepoint_iterator_t spBegin, spacepoint_iterator_t spEnd, Acts::Vector3 bField, Acts::ActsScalar bFieldMin, Acts::ActsScalar mass=139.57018 *Acts::UnitConstants::MeV)
 Estimate the full track parameters from three space points.
 

Detailed Description

Definition at line 15 of file SeedToTrackParamMaker.h.

Constructor & Destructor Documentation

◆ SeedToTrackParamMaker()

tracking::sim::SeedToTrackParamMaker::SeedToTrackParamMaker ( )
inline

Definition at line 17 of file SeedToTrackParamMaker.h.

17{};

Member Function Documentation

◆ estimateTrackParamsFromSeed()

template<typename spacepoint_iterator_t >
std::optional< Acts::BoundVector > tracking::sim::SeedToTrackParamMaker::estimateTrackParamsFromSeed ( const Acts::Transform3 &  Tp,
spacepoint_iterator_t  spBegin,
spacepoint_iterator_t  spEnd,
Acts::Vector3  bField,
Acts::ActsScalar  bFieldMin,
Acts::ActsScalar  mass = 139.57018 * Acts::UnitConstants::MeV 
)
inline

Estimate the full track parameters from three space points.

This method is based on the conformal map transformation. It estimates the full bound track parameters, i.e. (loc0, loc1, phi, theta, q/p, t) at the bottom space point. The bottom space is assumed to be the first element in the range defined by the iterators. The magnetic field (which might be along any direction) is also necessary for the momentum estimation.

It resembles the method used in ATLAS for the track parameters estimated from seed, i.e. the function InDet::SiTrackMaker_xk::getAtaPlane here: https://acode-browser.usatlas.bnl.gov/lxr/source/athena/InnerDetector/InDetRecTools/SiTrackMakerTool_xk/src/SiTrackMaker_xk.cxx

Template Parameters
spacepoint_iterator_tThe type of space point iterator
Parameters
tpthe local to global transformation
spBeginis the begin iterator for the space points
spEndis the end iterator for the space points
surfaceis the surface of the bottom space point. The estimated bound track parameters will be represented also at this surface
bFieldis the magnetic field vector
bFieldMinis the minimum magnetic field required to trigger the estimation of q/pt
massis the estimated particle mass
Returns
optional bound parameters

Definition at line 92 of file SeedToTrackParamMaker.h.

96 {
97 // Check the number of provided space points
98 size_t numSP = std::distance(spBegin, spEnd);
99 if (numSP != 3) {
100 std::cout << "ERROR::less than 3 point provided" << std::endl;
101 return std::nullopt;
102 }
103
104 // Convert bField to Tesla
105 Acts::ActsScalar bFieldInTesla = bField.norm() / Acts::UnitConstants::T;
106 Acts::ActsScalar bFieldMinInTesla = bFieldMin / Acts::UnitConstants::T;
107 // Check if magnetic field is too small
108 if (bFieldInTesla < bFieldMinInTesla) {
109 // @todo shall we use straight-line estimation and use default q/pt in
110 // such case?
111 std::cout << "The magnetic field at the bottom space point: B = "
112 << bFieldInTesla
113 << " T is smaller than |B|_min = " << bFieldMinInTesla
114 << " T. Estimation is not performed." << std::endl;
115 return std::nullopt;
116 }
117
118 // The global positions of the bottom, middle and space points
119 std::array<Acts::Vector3, 3> spGlobalPositions = {
120 Acts::Vector3::Zero(), Acts::Vector3::Zero(), Acts::Vector3::Zero()};
121 // The first, second and third space point are assumed to be bottom, middle
122 // and top space point, respectively
123 for (size_t isp = 0; isp < 3; ++isp) {
124 spacepoint_iterator_t it = std::next(spBegin, isp);
125 if (*it == nullptr) {
126 std::cout << "Empty space point found. This should not happen."
127 << std::endl;
128 return std::nullopt;
129 }
130 const auto& sp = *it;
131 spGlobalPositions[isp] = Acts::Vector3(sp->x(), sp->y(), sp->z());
132 }
133
134 // Define a new coordinate frame with its origin at the bottom space point,
135 // z axis along the magnetic field direction and y axis perpendicular to
136 // vector from the bottom to middle space point. Hence, the projection of
137 // the middle space point on the tranverse plane will be located at the x
138 // axis of the new frame.
139 Acts::Vector3 relVec = spGlobalPositions[1] - spGlobalPositions[0];
140 Acts::Vector3 newZAxis = bField.normalized();
141 Acts::Vector3 newYAxis = newZAxis.cross(relVec).normalized();
142 Acts::Vector3 newXAxis = newYAxis.cross(newZAxis);
143 Acts::RotationMatrix3 rotation;
144 rotation.col(0) = newXAxis;
145 rotation.col(1) = newYAxis;
146 rotation.col(2) = newZAxis;
147 // The center of the new frame is at the bottom space point
148 Acts::Translation3 trans(spGlobalPositions[0]);
149 // The transform which constructs the new frame
150 Acts::Transform3 transform(trans * rotation);
151
152 // The coordinate of the middle and top space point in the new frame
153 Acts::Vector3 local1 = transform.inverse() * spGlobalPositions[1];
154 Acts::Vector3 local2 = transform.inverse() * spGlobalPositions[2];
155
156 // Lambda to transform the coordinates to the (u, v) space
157 auto uvTransform = [](const Acts::Vector3& local) -> Acts::Vector2 {
158 Acts::Vector2 uv;
159 Acts::ActsScalar denominator =
160 local.x() * local.x() + local.y() * local.y();
161 uv.x() = local.x() / denominator;
162 uv.y() = local.y() / denominator;
163 return uv;
164 };
165 // The uv1.y() should be zero
166 Acts::Vector2 uv1 = uvTransform(local1);
167 Acts::Vector2 uv2 = uvTransform(local2);
168
169 // A,B are slope and intercept of the straight line in the u,v plane
170 // connecting the three points
171 Acts::ActsScalar A = (uv2.y() - uv1.y()) / (uv2.x() - uv1.x());
172 Acts::ActsScalar B = uv2.y() - A * uv2.x();
173 // Curvature (with a sign) estimate
174 Acts::ActsScalar rho = -2.0 * B / std::hypot(1., A);
175 // The projection of the top space point on the transverse plane of the new
176 // frame
177 Acts::ActsScalar rn = local2.x() * local2.x() + local2.y() * local2.y();
178 // The (1/tanTheta) of momentum in the new frame,
179 Acts::ActsScalar invTanTheta =
180 local2.z() * std::sqrt(1. / rn) / (1. + rho * rho * rn);
181 // The momentum direction in the new frame (the center of the circle has the
182 // coordinate (-1.*A/(2*B), 1./(2*B)))
183 Acts::Vector3 transDirection(1., A, std::hypot(1, A) * invTanTheta);
184 // Transform it back to the original frame
185 [[maybe_unused]] Acts::Vector3 direction =
186 rotation * transDirection.normalized();
187
188 // Initialize the bound parameters vector
189 Acts::BoundVector params = Acts::BoundVector::Zero();
190
191 // The estimated phi and theta
192 // params[Acts::eBoundPhi] = Acts::VectorHelpers::phi(direction);
193 // params[Acts::eBoundTheta] = Acts::VectorHelpers::theta(direction);
194
195 Acts::Vector3 bottomLocalPos = Tp.inverse() * spGlobalPositions[0];
196
197 // The estimated loc0 and loc1
198 params[Acts::eBoundLoc0] = bottomLocalPos.x();
199 params[Acts::eBoundLoc1] = bottomLocalPos.y();
200
201 // The estimated q/pt in [GeV/c]^-1 (note that the pt is the projection of
202 // momentum on the transverse plane of the new frame)
203 Acts::ActsScalar qOverPt =
204 rho * (Acts::UnitConstants::m) / (0.3 * bFieldInTesla);
205 // The estimated q/p in [GeV/c]^-1
206 params[Acts::eBoundQOverP] = qOverPt / std::hypot(1., invTanTheta);
207
208 // The estimated momentum, and its projection along the magnetic field
209 // diretion
210 Acts::ActsScalar pInGeV = std::abs(1.0 / params[Acts::eBoundQOverP]);
211 Acts::ActsScalar pzInGeV = 1.0 / std::abs(qOverPt) * invTanTheta;
212 Acts::ActsScalar massInGeV = mass / Acts::UnitConstants::GeV;
213 // The estimated velocity, and its projection along the magnetic field
214 // diretion
215 Acts::ActsScalar v = pInGeV / std::hypot(pInGeV, massInGeV);
216 Acts::ActsScalar vz = pzInGeV / std::hypot(pInGeV, massInGeV);
217 // The z coordinate of the bottom space point along the magnetic field
218 // direction
219 Acts::ActsScalar pathz = spGlobalPositions[0].dot(bField) / bField.norm();
220 // The estimated time (use path length along magnetic field only if it's not
221 // zero)
222 if (pathz != 0) {
223 params[Acts::eBoundTime] = pathz / vz;
224 } else {
225 params[Acts::eBoundTime] = spGlobalPositions[0].norm() / v;
226 }
227
228 return params;
229 }

◆ transformRhoPhid()

bool tracking::sim::SeedToTrackParamMaker::transformRhoPhid ( const Acts::Vector2 &  r1,
const Acts::Vector2 &  r2,
double &  phi,
double &  rho,
double &  d 
)
inline

Definition at line 29 of file SeedToTrackParamMaker.h.

30 {
31 float trackDir = cos(phi) * (r1[0] - r2[0]) + sin(phi) * (r1[1] - r2[1]);
32
33 if (trackDir < 0) {
34 phi = M_PI + phi;
35 rho = -rho;
36 d = -d;
37 return true;
38 }
39
40 else
41 return false;
42 }

The documentation for this class was generated from the following file: