Skip to content

Commit d189c73

Browse files
authored
ALICE3: TRK and FT3 topology dictionaries per layer, their builder an… (#16039)
Signed-off-by: Felix Schlepper <felix.schlepper@cern.ch>
1 parent 59a8763 commit d189c73

9 files changed

Lines changed: 1034 additions & 0 deletions

File tree

‎Detectors/Upgrades/ALICE3/TRKFT3/common/CMakeLists.txt‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@
1212
add_subdirectory(simulation)
1313
add_subdirectory(reconstruction)
1414
add_subdirectory(workflow)
15+
add_subdirectory(macros)
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2+
# See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
# All rights not expressly granted are reserved.
4+
#
5+
# This software is distributed under the terms of the GNU General Public
6+
# License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
#
8+
# In applying this license CERN does not waive the privileges and immunities
9+
# granted to it by virtue of its status as an Intergovernmental Organization
10+
# or submit itself to any jurisdiction.
11+
12+
13+
o2_add_test_root_macro(CheckTopologyDictionary.C
14+
PUBLIC_LINK_LIBRARIES O2::TRKReconstruction
15+
O2::DetectorsBase
16+
O2::SimulationDataFormat
17+
LABELS alice3 COMPILE_ONLY)

‎Detectors/Upgrades/ALICE3/TRKFT3/common/macros/CheckTopologyDictionary.C‎

Lines changed: 343 additions & 0 deletions
Large diffs are not rendered by default.

‎Detectors/Upgrades/ALICE3/TRKFT3/common/reconstruction/CMakeLists.txt‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ endif()
1616
o2_add_library(TRKReconstruction
1717
TARGETVARNAME targetName
1818
SOURCES src/Clusterer.cxx
19+
src/TopologyDictionary.cxx
20+
src/BuildTopologyDictionary.cxx
1921
$<$<BOOL:${Acts_FOUND}>:src/ClustererACTS.cxx>
2022
PUBLIC_LINK_LIBRARIES
2123
Microsoft.GSL::GSL
@@ -30,3 +32,8 @@ o2_add_library(TRKReconstruction
3032
if(Acts_FOUND)
3133
target_compile_definitions(${targetName} PUBLIC O2_WITH_ACTS)
3234
endif()
35+
36+
o2_target_root_dictionary(TRKReconstruction
37+
HEADERS include/TRKReconstruction/TopologyDictionary.h
38+
include/TRKReconstruction/BuildTopologyDictionary.h
39+
LINKDEF src/TRKReconstructionLinkDef.h)
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// Copyright 2019-2026 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
12+
/// \file BuildTopologyDictionary.h
13+
/// \brief Builds the TRK and FT3 topology dictionaries from MC clusters and their particles' crossings
14+
///
15+
/// Each cluster is accounted with its particle's crossing of the chip: the
16+
/// ends of its path through the silicon. Per layer, build first scans the
17+
/// depth: the local y, on a grid of depthStep, at which the residuals'
18+
/// widths across and along, added in quadrature, are smallest. It then cuts
19+
/// every crossing at that depth: a pattern with at least minCount residuals
20+
/// gets its own entry; a group takes the widths of its rare patterns, else of
21+
/// the rare patterns with the same span class on the axis, else of the layer.
22+
23+
#ifndef ALICEO2_TRKFT3_BUILDTOPOLOGYDICTIONARY_H
24+
#define ALICEO2_TRKFT3_BUILDTOPOLOGYDICTIONARY_H
25+
26+
#include "TRKReconstruction/TopologyDictionary.h"
27+
#include <cstdint>
28+
#include <string>
29+
#include <unordered_map>
30+
#include <vector>
31+
32+
namespace o2::trkft3
33+
{
34+
35+
template <int DetID>
36+
class BuildTopologyDictionary
37+
{
38+
public:
39+
using Dictionary = TopologyDictionary<DetID>;
40+
using ClusterType = typename Dictionary::ClusterType;
41+
42+
struct Settings {
43+
uint32_t minCount = 137; ///< residuals for an entry of its own: the width to 10 %
44+
float depthStep = 0.5e-4f; ///< [cm]
45+
int nThreads = 1; ///< for the depth scan
46+
};
47+
48+
BuildTopologyDictionary(int nLayers, const Settings& settings);
49+
50+
/// A cluster and its particle's crossing of the chip, in O2's local frame [cm].
51+
void accountCluster(const ClusterType& cluster, const unsigned char* pattern, const math_utils::Point3D<float>& start, const math_utils::Point3D<float>& end);
52+
53+
/// Builds every layer; throws std::runtime_error for a layer with too few residuals.
54+
void build();
55+
56+
void setApplyOffsets(bool apply) noexcept { mDictionary.setApplyOffsets(apply); }
57+
[[nodiscard]] const Dictionary& getDictionary() const noexcept { return mDictionary; }
58+
/// Writes the dictionary as "ccdb_object".
59+
void saveDictionaryRoot(const std::string& fileName) const;
60+
61+
private:
62+
/// A cluster's crossing relative to its centre of gravity in the layer's flat frame [cm].
63+
struct Crossing {
64+
uint32_t pattern = 0; ///< index among the layer's patterns
65+
float x0 = 0.f; ///< start - centre of gravity, across
66+
float y0 = 0.f; ///< start, depth
67+
float z0 = 0.f; ///< start - centre of gravity, along
68+
float dx = 0.f; ///< end - start
69+
float dy = 0.f;
70+
float dz = 0.f;
71+
};
72+
struct LayerInput {
73+
std::unordered_map<std::string, uint32_t> patternIndex; ///< the pattern's bytes -> index
74+
std::vector<std::string> patterns;
75+
std::vector<Crossing> crossings;
76+
};
77+
78+
[[nodiscard]] float measureDepth(int layer, const LayerInput& input) const;
79+
void makeEntries(int layer, const LayerInput& input, LayerDictionary& data) const;
80+
81+
Settings mSettings; //!
82+
std::vector<LayerInput> mInput; //!
83+
Dictionary mDictionary; //!
84+
};
85+
86+
using TRKBuildTopologyDictionary = BuildTopologyDictionary<o2::detectors::DetID::TRK>;
87+
using FT3BuildTopologyDictionary = BuildTopologyDictionary<o2::detectors::DetID::FT3>;
88+
89+
} // namespace o2::trkft3
90+
91+
#endif
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
// Copyright 2019-2026 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
12+
/// \file TopologyDictionary.h
13+
/// \brief Positions and errors of TRK and FT3 clusters per layer and pixel pattern
14+
///
15+
/// As the ITS's topology dictionary, measured from MC, but per layer: the
16+
/// layer's depth (the local y positions are taken at) and, per common pattern
17+
/// and per group of rare ones, the width (normalised median absolute
18+
/// deviation) and median of the residuals hit - centre of gravity across
19+
/// (local x) and along (local z). Every pattern finds an entry: its own, else
20+
/// its group's. On the VD the dictionary works in the flat frame of
21+
/// SegmentationChip::curvedToFlat; getClusterCoordinates returns O2's curved
22+
/// local coordinates.
23+
24+
#ifndef ALICEO2_TRKFT3_TOPOLOGYDICTIONARY_H
25+
#define ALICEO2_TRKFT3_TOPOLOGYDICTIONARY_H
26+
27+
#include "DataFormatsTRKFT3/Cluster.h"
28+
#include "DetectorsCommonDataFormats/DetID.h"
29+
#include "MathUtils/Cartesian.h"
30+
#include <Rtypes.h>
31+
#include <algorithm>
32+
#include <string>
33+
#include <unordered_map>
34+
#include <vector>
35+
36+
namespace o2::trkft3
37+
{
38+
39+
template <int DetID>
40+
class BuildTopologyDictionary;
41+
42+
/// A common pattern, or the group of the rare patterns with the same span
43+
/// classes (spans 1 to 5, 6 or more) on both axes.
44+
struct DictionaryEntry {
45+
std::vector<unsigned char> pattern; ///< row span, column span, pixel bits as the clusteriser streams them; empty for a group
46+
float xCOG = 0.f; ///< centre of gravity from the reference pixel across [pitches]
47+
float zCOG = 0.f; ///< along [pitches]
48+
float xWidth = 0.f; ///< the residuals' width across [cm]
49+
float zWidth = 0.f; ///< along [cm]
50+
float xOffset = 0.f; ///< the residuals' median across [cm]
51+
float zOffset = 0.f; ///< along [cm]
52+
bool isGroup = false;
53+
54+
ClassDefNV(DictionaryEntry, 1);
55+
};
56+
57+
struct LayerDictionary {
58+
float depth = 0.f; ///< the local y positions are taken at [cm]
59+
std::vector<DictionaryEntry> entries; ///< the common patterns, most frequent first, then the groups
60+
std::unordered_multimap<unsigned long, int> hashMap; ///< itsmft::ClusterTopology hash -> common pattern's entry
61+
62+
ClassDefNV(LayerDictionary, 1);
63+
};
64+
65+
template <int DetID>
66+
class TopologyDictionary
67+
{
68+
static_assert(DetID == o2::detectors::DetID::TRK || DetID == o2::detectors::DetID::FT3, "only TRK and FT3 dictionaries are supported");
69+
70+
public:
71+
using ClusterType = Cluster<DetID>;
72+
73+
static constexpr int NSpanClasses = 6; ///< spans 1 to 5, 6 or more
74+
static constexpr int NGroups = NSpanClasses * NSpanClasses; ///< one group per pair of span classes, row class major
75+
76+
static constexpr int spanClass(int span) noexcept { return std::min(span, NSpanClasses) - 1; }
77+
static constexpr int groupOf(int rowSpan, int colSpan) noexcept { return spanClass(rowSpan) * NSpanClasses + spanClass(colSpan); }
78+
79+
/// A cluster's layer: TRK's VD layers, then ML/OT (GeometryTGeo::getLayerTRK); FT3's discs. -1 for none (a VD disc).
80+
static int layerOf(const ClusterType& cluster) noexcept;
81+
/// A point from O2's local frame to the layer's flat frame (the VD's unrolled; elsewhere the same).
82+
static math_utils::Point3D<float> localToFlat(const ClusterType& cluster, const math_utils::Point3D<float>& local) noexcept;
83+
/// The cluster's centre of gravity in the flat frame at y = 0. \a pattern: row span, column span, pixel bits.
84+
static math_utils::Point3D<float> centreOfGravity(const ClusterType& cluster, const unsigned char* pattern) noexcept;
85+
86+
[[nodiscard]] int getNumberOfLayers() const noexcept { return static_cast<int>(mLayers.size()); }
87+
[[nodiscard]] const LayerDictionary& getLayer(int layer) const { return mLayers.at(layer); }
88+
[[nodiscard]] const DictionaryEntry& getEntry(int layer, int id) const { return mLayers.at(layer).entries.at(id); }
89+
90+
/// The pattern's entry on the layer: its own if it is common, else its group's.
91+
[[nodiscard]] int findID(int layer, const unsigned char* pattern) const;
92+
93+
/// The position in the flat frame: the entry's centre of gravity, plus its offsets if applied, at the layer's depth.
94+
[[nodiscard]] math_utils::Point3D<float> getFlatCoordinates(const ClusterType& cluster, const unsigned char* pattern, int id) const;
95+
/// The same in O2's local frame: curved on the VD.
96+
[[nodiscard]] math_utils::Point3D<float> getClusterCoordinates(const ClusterType& cluster, const unsigned char* pattern, int id) const;
97+
[[nodiscard]] math_utils::Point3D<float> getClusterCoordinates(const ClusterType& cluster, const unsigned char* pattern) const
98+
{
99+
return getClusterCoordinates(cluster, pattern, findID(layerOf(cluster), pattern));
100+
}
101+
102+
[[nodiscard]] bool getApplyOffsets() const noexcept { return mApplyOffsets; }
103+
void setApplyOffsets(bool apply) noexcept { mApplyOffsets = apply; }
104+
105+
void print() const;
106+
107+
static TopologyDictionary* loadFrom(const std::string& fileName, const std::string& objName = "ccdb_object");
108+
109+
private:
110+
friend class BuildTopologyDictionary<DetID>;
111+
112+
std::vector<LayerDictionary> mLayers;
113+
bool mApplyOffsets = false;
114+
115+
ClassDefNV(TopologyDictionary, 1);
116+
};
117+
118+
using TRKTopologyDictionary = TopologyDictionary<o2::detectors::DetID::TRK>;
119+
using FT3TopologyDictionary = TopologyDictionary<o2::detectors::DetID::FT3>;
120+
121+
} // namespace o2::trkft3
122+
123+
#endif

0 commit comments

Comments
 (0)