2626namespace
2727{
2828
29- // / Return whether cluster-decoding systematic errors are configured for `DetId`.
30- // / ITS is a no-op; MFT reads its live tracker configuration.
31- template <o2::detectors::DetID::ID DetId>
32- bool shouldApplySysErrors ()
33- {
34- if constexpr (DetId == o2::detectors::DetID::ITS ) {
35- return false ;
36- } else {
37- const auto & conf = o2::itsmft::tracking::TrackerParamRef<DetId>::get ();
38- for (int il = 0 ; il < o2::itsmft::tracking::TrackerParamRef<DetId>::nLayers (); il++) {
39- if (conf.sysErr2Row [il] > 0 .f || conf.sysErr2Col [il] > 0 .f ) {
40- return true ;
41- }
42- }
43- return false ;
44- }
45- }
46-
47- // / Add configured systematic-error corrections to `sigma2Row` and `sigma2Col`.
48- // / ITS is a no-op.
49- template <o2::detectors::DetID::ID DetId>
50- void addSysErrors (int layerId, float & sigma2Row, float & sigma2Col)
51- {
52- if constexpr (DetId == o2::detectors::DetID::ITS ) {
53- (void )layerId;
54- (void )sigma2Row;
55- (void )sigma2Col;
56- } else {
57- const auto & conf = o2::itsmft::tracking::TrackerParamRef<DetId>::get ();
58- sigma2Row += conf.sysErr2Row [layerId];
59- sigma2Col += conf.sysErr2Col [layerId];
60- }
61- }
62-
6329template <o2::detectors::DetID::ID DetId, typename GeomT>
6430o2::itsmft::tracking::DecodedCluster decodeCluster (
6531 GeomT* geom, const o2::itsmft::CompClusterExt& cluster,
6632 gsl::span<const unsigned char >::iterator& patterns,
67- const o2::itsmft::TopologyDictionary* dict, bool applySysErrors )
33+ const o2::itsmft::TopologyDictionary* dict)
6834{
6935 o2::itsmft::tracking::DecodedCluster result;
7036 if (dict == nullptr ) {
@@ -84,11 +50,8 @@ o2::itsmft::tracking::DecodedCluster decodeCluster(
8450 }
8551
8652 const auto clusterData = o2::itsmft::ioutils::extractClusterData (cluster, patterns, dict);
87- float sigma2Row = clusterData.sig2Row ;
88- float sigma2Col = clusterData.sig2Col ;
89- if (applySysErrors && shouldApplySysErrors<DetId>()) {
90- addSysErrors<DetId>(layer, sigma2Row, sigma2Col);
91- }
53+ const float sigma2Row = clusterData.sig2Row ;
54+ const float sigma2Col = clusterData.sig2Col ;
9255
9356 if constexpr (DetId == o2::detectors::DetID::ITS ) {
9457 const auto trkXYZ = geom->getMatrixT2L (sensorID) ^ clusterData.coordinates ;
@@ -118,7 +81,7 @@ void decodeDetectorSource(const o2::itsmft::tracking::ClusterSourceInput& source
11881 geometry->fillMatrixCache (o2::math_utils::bit2Mask (o2::math_utils::TransformType::T2L , o2::math_utils::TransformType::L2G ));
11982 }
12083 consume ([&](const auto & cluster, auto & patterns) {
121- return decodeCluster<DetId>(geometry, cluster, patterns, source.dictionary , source. applySysErrors );
84+ return decodeCluster<DetId>(geometry, cluster, patterns, source.dictionary );
12285 });
12386}
12487
@@ -342,14 +305,21 @@ void appendCluster(TimeFrame& frame, const SurfaceCatalogView& catalog,
342305 const auto expectedSurface = src.layerToSurface [decoded.layer ];
343306 const auto & surfaceDescriptor = catalog.getSurface (expectedSurface);
344307 const auto localClusterId = static_cast <uint32_t >(frame.getGlobalMeasurements (expectedSurface).size ());
308+ // Apply alignment systematics once, for both detectors, before projecting
309+ // either covariance. Use the same resolved configuration as search windows,
310+ // indexed by the mapped surface (not the detector-local layer).
311+ auto corrected = decoded;
312+ const auto & configuration = frame.getDetectorConfiguration ();
313+ corrected.rowColumnCovariance .uu += configuration.systError2Row .empty () ? 0 .f : configuration.systError2Row .at (expectedSurface.value ());
314+ corrected.rowColumnCovariance .vv += configuration.systError2Col .empty () ? 0 .f : configuration.systError2Col .at (expectedSurface.value ());
345315 GlobalMeasurement global;
346316 SurfaceMeasurement measurement;
347317 if (surfaceDescriptor.kind == SurfaceKind::Cylinder) {
348- global = makeCylinderGlobalMeasurement (decoded , localClusterId);
349- measurement = makeCylinderSurfaceMeasurement (decoded );
318+ global = makeCylinderGlobalMeasurement (corrected , localClusterId);
319+ measurement = makeCylinderSurfaceMeasurement (corrected );
350320 } else {
351- global = makeDiskGlobalMeasurement (decoded , localClusterId);
352- measurement = makeDiskSurfaceMeasurement (decoded );
321+ global = makeDiskGlobalMeasurement (corrected , localClusterId);
322+ measurement = makeDiskSurfaceMeasurement (corrected );
353323 }
354324 if (!decodedMeasurementIsValid (global, measurement)) {
355325 throw std::runtime_error (std::format (" Malformed cluster loading input source={} rof={} clusterIndex={}" , src.id .value (), r, externalIndex));
0 commit comments