Skip to content

Commit 97228a8

Browse files
shahor02claude
andcommitted
Add the ClustersPerLayer helper for the per-layer ITS/MFT clusters
Stores the clusters of all layers in a single vector with the per-layer offsets and gives access by the composed ID of ClusterID.h, so that the same code works for the monolithic and the per-layer input. Detector agnostic: the filling is left to the caller, since the spacepoint conversion needs the detector geometry and dictionary. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent fb9931a commit 97228a8

1 file changed

Lines changed: 109 additions & 0 deletions

File tree

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
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+
/// \file ClustersPerLayer.h
13+
/// \brief Container of the ITS/MFT clusters addressed by the composed (layer,index) ID
14+
/// \author ruben.shahoyan@cern.ch
15+
16+
#ifndef ALICEO2_ITSMFT_CLUSTERSPERLAYER_H
17+
#define ALICEO2_ITSMFT_CLUSTERSPERLAYER_H
18+
19+
#include "DataFormatsITSMFT/ClusterID.h"
20+
#include "Framework/Logger.h"
21+
#include <array>
22+
#include <vector>
23+
24+
namespace o2::itsmft
25+
{
26+
27+
///< Container of the ITS/MFT clusters supplied either as a single (monolithic) array or per layer
28+
///< (staggered readout). The clusters of all layers are kept in a single vector, layer by layer,
29+
///< with the per-layer starting offsets recorded, so that a cluster referred to by the composed ID
30+
///< (layer << ClusLayerShift) + index_in_layer can be looked up directly. With the monolithic input
31+
///< only the layer slot 0 is filled and the composed ID coincides with the flat cluster index, hence
32+
///< the same lookup works for both cases.
33+
///<
34+
///< The conversion of the compact clusters to the stored objects is detector specific (and needs the
35+
///< geometry), so it is left to the caller: the container only records where each layer starts.
36+
///< Expected usage (nLr == 1 for the monolithic input):
37+
///< cont.init(nLr);
38+
///< for (int lr = 0; lr < nLr; lr++) {
39+
///< cont.beginLayer(lr);
40+
///< auto pattIt = recoData.getITSClustersPatterns(lr).begin();
41+
///< o2::its::ioutils::convertCompactClusters(recoData.getITSClusters(lr), pattIt, cont.getClusters(), dict);
42+
///< }
43+
///< cont.finalize();
44+
///< after which cont[composedID] gives the cluster referred to by a track cluster reference.
45+
template <typename T>
46+
class ClustersPerLayer
47+
{
48+
public:
49+
///< prepare for filling nLr layer slots, discarding the previous content
50+
void init(int nLr)
51+
{
52+
if (nLr < 1 || nLr > MaxClusLayers) {
53+
LOGP(fatal, "Clusters container cannot be initialized for {} layers, must be within 1:{}", nLr, MaxClusLayers);
54+
}
55+
mClusters.clear();
56+
mLrFirst.fill(0);
57+
mNLayers = nLr;
58+
}
59+
60+
///< record the start of the layer lr data, the layers must be filled in the increasing order
61+
void beginLayer(int lr)
62+
{
63+
if (lr < 0 || lr >= mNLayers) {
64+
LOGP(fatal, "Clusters container was initialized for {} layers, cannot fill the layer {}", mNLayers, lr);
65+
}
66+
mLrFirst[lr] = int(mClusters.size());
67+
}
68+
69+
///< to be called once all the layers were filled
70+
void finalize()
71+
{
72+
for (int lr = mNLayers; lr <= MaxClusLayers; lr++) { // the slots above the filled ones are empty
73+
mLrFirst[lr] = int(mClusters.size());
74+
}
75+
}
76+
77+
void clear()
78+
{
79+
mClusters.clear();
80+
mLrFirst.fill(0);
81+
mNLayers = 1;
82+
}
83+
84+
///< the clusters of all layers, to be appended to by the caller between beginLayer and finalize
85+
auto& getClusters() { return mClusters; }
86+
const auto& getClusters() const { return mClusters; }
87+
88+
auto getNLayers() const { return mNLayers; }
89+
auto getFirstIndex(int lr) const { return mLrFirst[lr]; }
90+
auto getNClusters(int lr) const { return mLrFirst[lr + 1] - mLrFirst[lr]; }
91+
auto size() const { return mClusters.size(); }
92+
bool empty() const { return mClusters.empty(); }
93+
94+
///< flat index of the cluster referred to by its composed ID
95+
int flatIndex(int composedID) const
96+
{
97+
return mLrFirst[clusID2Layer(composedID)] + clusID2Index(composedID);
98+
}
99+
const T& operator[](int composedID) const { return mClusters[flatIndex(composedID)]; }
100+
101+
private:
102+
std::vector<T> mClusters{}; ///< clusters of all layers, layer by layer
103+
std::array<int, MaxClusLayers + 1> mLrFirst{}; ///< 1st cluster of every layer, + the total in the last slot
104+
int mNLayers = 1; ///< number of filled layer slots
105+
};
106+
107+
} // namespace o2::itsmft
108+
109+
#endif

0 commit comments

Comments
 (0)