12 template <
typename fitter_t>
13 template <
typename source_link_t,
typename start_parameters_t,
14 typename fit_options_t>
18 const std::vector<source_link_t>& sourcelinks,
19 const start_parameters_t& sParameters,
const fit_options_t& fitOptions,
20 const std::unordered_map<const Acts::Surface*, size_t>& idxedAlignSurfaces,
30 auto fitRes = m_fitter.fit(
begin,
end, sParameters, fitOptions,
tracks);
32 if (not fitRes.ok()) {
34 return fitRes.error();
37 const auto& track = fitRes.value();
39 const auto& globalTrackParamsCov =
41 tracks.trackStateContainer(), track.tipIndex());
44 gctx,
tracks.trackStateContainer(), track.tipIndex(),
45 globalTrackParamsCov, idxedAlignSurfaces, alignMask);
46 if (alignState.alignmentDof == 0) {
48 return AlignmentError::NoAlignmentDofOnTrack;
53 template <
typename fitter_t>
54 template <
typename trajectory_container_t,
55 typename start_parameters_container_t,
typename fit_options_t>
57 const trajectory_container_t& trajectoryCollection,
58 const start_parameters_container_t& startParametersCollection,
59 const fit_options_t& fitOptions,
64 assert(trajectoryCollection.size() == startParametersCollection.size());
76 fit_options_t fitOptionsWithRefSurface = fitOptions;
81 alignResult.
numTracks = trajectoryCollection.size();
82 double sumChi2ONdf = 0;
83 for (
unsigned int iTraj = 0; iTraj < trajectoryCollection.size(); iTraj++) {
84 const auto& sourcelinks = trajectoryCollection.at(iTraj);
85 const auto& sParameters = startParametersCollection.at(iTraj);
87 fitOptionsWithRefSurface.referenceSurface = &sParameters.referenceSurface();
89 auto evaluateRes = evaluateTrackAlignmentState(
90 fitOptions.geoContext, sourcelinks, sParameters,
92 if (not evaluateRes.ok()) {
93 ACTS_DEBUG(
"Evaluation of alignment state for track " << iTraj
97 const auto& alignState = evaluateRes.value();
98 for (
const auto& [rowSurface,
rows] : alignState.alignedSurfaces) {
99 const auto& [dstRow, srcRow] =
rows;
103 alignState.alignmentToChi2Derivative.segment(
106 for (
const auto& [colSurface, cols] : alignState.alignedSurfaces) {
107 const auto& [dstCol, srcCol] = cols;
108 sumChi2SecondDerivative
111 alignState.alignmentToChi2SecondDerivative.block(
112 srcRow * Acts::eAlignmentSize, srcCol * Acts::eAlignmentSize,
113 Acts::eAlignmentSize, Acts::eAlignmentSize);
116 alignResult.
chi2 += alignState.chi2;
118 sumChi2ONdf += alignState.chi2 / alignState.measurementDim;
127 Acts::ActsDynamicMatrix::Zero(alignDof, alignDof);
128 sumChi2SecondDerivativeInverse = sumChi2SecondDerivative.inverse();
129 if (sumChi2SecondDerivativeInverse.hasNaN()) {
130 ACTS_DEBUG(
"Chi2 second derivative inverse has NaN");
136 Acts::ActsDynamicVector::Zero(alignDof);
138 Acts::ActsDynamicMatrix::Zero(alignDof, alignDof);
141 -sumChi2SecondDerivative.fullPivLu().solve(sumChi2Derivative);
142 ACTS_VERBOSE(
"sumChi2SecondDerivative = \n" << sumChi2SecondDerivative);
143 ACTS_VERBOSE(
"sumChi2Derivative = \n" << sumChi2Derivative);
144 ACTS_VERBOSE(
"alignResult.deltaAlignmentParameters \n");
149 alignResult.
deltaChi2 = 0.5 * sumChi2Derivative.transpose() *
153 template <
typename fitter_t>
157 const std::vector<Acts::DetectorElementBase*>& alignedDetElements,
168 const Acts::Vector3& oldEulerAngles = oldRotation.eulerAngles(2, 1, 0);
184 Acts::Vector3::UnitZ());
187 Acts::Vector3::UnitY());
190 Acts::Vector3::UnitX());
191 Eigen::Quaternion<Acts::ActsScalar> newRotation = rotZ * rotY * rotX;
198 ACTS_VERBOSE(
"Delta of alignment parameters at element "
200 << deltaAlignmentParam);
201 bool updated = alignedTransformUpdater(alignedDetElements.at(index),
gctx,
204 ACTS_ERROR(
"Update alignment parameters for detector element failed");
205 return AlignmentError::AlignmentParametersUpdateFailure;
212 template <
typename fitter_t>
213 template <
typename trajectory_container_t,
214 typename start_parameters_container_t,
typename fit_options_t>
217 const trajectory_container_t& trajectoryCollection,
218 const start_parameters_container_t& startParametersCollection,
224 for (
unsigned int iDetElement = 0;
231 <<
" detector elements to be aligned");
234 bool converged =
false;
235 bool alignmentParametersUpdated =
false;
236 std::queue<double> recentChi2ONdf;
238 for (
unsigned int iIter = 0; iIter < alignOptions.
maxIterations; iIter++) {
245 alignMask = iter_it->second;
248 calculateAlignmentParameters(
249 trajectoryCollection, startParametersCollection,
250 alignOptions.
fitOptions, alignResult, alignMask);
252 ACTS_INFO(
"iIter = " << iIter <<
", total chi2 = " << alignResult.
chi2
253 <<
", total measurementDim = "
255 <<
" and average chi2/ndf = "
260 if (recentChi2ONdf.size() >=
265 "Alignment has converged with change of chi2/ndf < "
268 <<
" after " << iIter <<
" iteration(s)");
272 recentChi2ONdf.pop();
276 ACTS_INFO(
"Alignment has converged with average chi2/ndf < "
286 ACTS_INFO(
"The solved delta of alignmentParameters = \n "
289 auto updateRes = updateAlignmentParameters(
292 if (not updateRes.ok()) {
293 ACTS_ERROR(
"Update alignment parameters failed: " << updateRes.error());
294 return updateRes.error();
296 alignmentParametersUpdated =
true;
302 alignResult.
result = AlignmentError::ConvergeFailure;
307 if (alignmentParametersUpdated) {
309 const auto&
surface = &det->surface();
311 det->transform(alignOptions.
fitOptions.geoContext);
315 const auto& rotation =
transform.rotation();
316 const Acts::Vector3 rotAngles = rotation.eulerAngles(2, 1, 0);
319 <<
" has aligned geometry position as below:");
322 "Euler angles (rotZ, rotY, rotX) = " << rotAngles.transpose());
326 ACTS_DEBUG(
"Alignment parameters is not updated.");