Skip to content

Commit 8b6f9d3

Browse files
wiechulashahor02
authored andcommitted
Workflow for Krypton Box clusterer
1 parent 658deb8 commit 8b6f9d3

8 files changed

Lines changed: 491 additions & 41 deletions

File tree

Detectors/TPC/reconstruction/include/TPCReconstruction/KrBoxClusterFinder.h

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,19 +99,39 @@ class KrBoxClusterFinder
9999
/// later filled with the recorded charges for each digit
100100
explicit KrBoxClusterFinder() = default;
101101

102+
explicit KrBoxClusterFinder(int sector) : mSector(sector){};
103+
102104
/// If a gain map exists, the map can be loaded with this function
103105
/// The function expects a CalDet file with a gain map (gain entry for each pad).
104106
void loadGainMapFromFile(const std::string_view calDetFileName, const std::string_view gainMapName = "GainMap");
105107

106108
/// Function used in macro to fill the map with all recorded digits
107109
void fillAndCorrectMap(std::vector<o2::tpc::Digit>& eventSector, const int sector);
108110

111+
/// Function to fill single digi
112+
void fillADCValue(int cru, int rowInSector, int padInRow, int timeBin, float adcValue);
113+
109114
/// After the map is created, we look for local maxima with this function:
110-
std::vector<std::tuple<int, int, int>> findLocalMaxima();
115+
std::vector<std::tuple<int, int, int>> findLocalMaxima(bool directFilling = false);
111116

112117
/// After finding the local maxima, we can now build clusters around it.
113118
/// It works according to the explanation at the beginning of the header file.
114-
KrCluster buildCluster(int clusterCenterPad, int clusterCenterRow, int clusterCenterTime);
119+
KrCluster buildCluster(int clusterCenterPad, int clusterCenterRow, int clusterCenterTime, bool directFilling = false);
120+
121+
/// reset the ADC map
122+
void resetADCMap();
123+
124+
/// reset cluster vector
125+
void resetClusters() { mClusters.clear(); }
126+
127+
std::vector<KrCluster>& getClusters() { return mClusters; }
128+
const std::vector<KrCluster>& getClusters() const { return mClusters; }
129+
130+
/// set sector of this instance
131+
void setSector(int sector) { mSector = sector; }
132+
133+
/// ger sector of this instance
134+
int getSector() const { return mSector; }
115135

116136
private:
117137
// These variables can be varied
@@ -134,20 +154,23 @@ class KrBoxClusterFinder
134154
float mQThreshold = 1.0; ///< every charge which is added to a cluster must exceed this value or it is discarded
135155
int mMinNumberOfNeighbours = 1; ///< amount of direct neighbours required for a cluster maximum
136156

157+
int mSector = -1; ///< sector being processed in this instance
137158
std::unique_ptr<CalPad> mGainMap; ///< Gain map object
138159

139160
/// Maximum Map Dimensions
140161
/// Here is room for improvements
141-
static constexpr size_t MaxPads = 138; ///< Size of the map in pad-direction
142-
static constexpr size_t MaxRows = 152; ///< Size of the map in row-direction
143-
static constexpr size_t MaxTimes = 550; ///< Size of the map in time-direction
162+
static constexpr size_t MaxPads = 138; ///< Size of the map in pad-direction
163+
static constexpr size_t MaxRows = 152; ///< Size of the map in row-direction
164+
static constexpr size_t MaxTimes = 20000; ///< Size of the map in time-direction
144165

145166
/// Values to define ROC boundaries
146167
static constexpr size_t MaxRowsIROC = 63; ///< Amount of rows in IROC
147168
static constexpr size_t MaxRowsOROC1 = 34; ///< Amount of rows in OROC1
148169
static constexpr size_t MaxRowsOROC2 = 30; ///< Amount of rows in OROC2
149170
static constexpr size_t MaxRowsOROC3 = 25; ///< Amount of rows in OROC3
150171

172+
std::vector<o2::tpc::KrCluster> mClusters;
173+
151174
/// Need an instance of Mapper to know position of pads
152175
const Mapper& mMapperInstance = o2::tpc::Mapper::instance();
153176

Detectors/TPC/reconstruction/include/TPCReconstruction/KrCluster.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ struct KrCluster {
3030
float maxCharge = 0; ///< Maximum charge of the cluster (ADC counts)
3131
float meanPad = 0; ///< Center of gravity (Pad number)
3232
float meanRow = 0; ///< Center of gravity (Row number)
33-
float meanTime = 0; ///< Center of gravity (Time)
3433
float sigmaPad = 0; ///< RMS of cluster in pad direction
3534
float sigmaRow = 0; ///< RMS of cluster in row direction
36-
float sigmaTime = 0; ///< RMS of cluster in time direction
35+
double meanTime = 0; ///< Center of gravity (Time)
36+
double sigmaTime = 0; ///< RMS of cluster in time direction
3737

3838
/// Used to set all Cluster variables to zero.
3939
void reset()
@@ -52,7 +52,7 @@ struct KrCluster {
5252
sigmaTime = 0;
5353
}
5454

55-
ClassDefNV(KrCluster, 2);
55+
ClassDefNV(KrCluster, 3);
5656
};
5757

5858
} // namespace tpc

Detectors/TPC/reconstruction/src/KrBoxClusterFinder.cxx

Lines changed: 63 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -37,19 +37,26 @@ void KrBoxClusterFinder::loadGainMapFromFile(const std::string_view calDetFileNa
3737
LOGP(info, "Loaded gain map object '{}' from file '{}'", calDetFileName, gainMapName);
3838
}
3939

40-
// Fill the map with all digits.
41-
// You can pass a CalDet file to it so that the cluster finder can already correct for gain inhomogeneities
42-
// The CalDet File should contain the relative Gain of each Pad.
43-
void KrBoxClusterFinder::fillAndCorrectMap(std::vector<o2::tpc::Digit>& eventSector, const int sector)
40+
void KrBoxClusterFinder::resetADCMap()
4441
{
4542
// Reset whole map:
4643
for (int iTime = 0; iTime < MaxTimes; iTime++) {
4744
for (int iRow = 0; iRow < MaxRows; iRow++) {
48-
for (int iPad = 0; iPad < MaxPads; iPad++) {
49-
mMapOfAllDigits[iTime][iRow][iPad] = 0;
50-
}
45+
std::fill(mMapOfAllDigits[iTime][iRow].begin(), mMapOfAllDigits[iTime][iRow].end(), 0.);
46+
//for (int iPad = 0; iPad < MaxPads; iPad++) {
47+
//mMapOfAllDigits[iTime][iRow][iPad] = 0;
48+
//}
5149
}
5250
}
51+
}
52+
53+
// Fill the map with all digits.
54+
// You can pass a CalDet file to it so that the cluster finder can already correct for gain inhomogeneities
55+
// The CalDet File should contain the relative Gain of each Pad.
56+
void KrBoxClusterFinder::fillAndCorrectMap(std::vector<o2::tpc::Digit>& eventSector, const int sector)
57+
{
58+
mSector = sector;
59+
resetADCMap();
5360

5461
if (eventSector.size() == 0) {
5562
// prevents a segementation fault if the envent contains no data
@@ -62,34 +69,49 @@ void KrBoxClusterFinder::fillAndCorrectMap(std::vector<o2::tpc::Digit>& eventSec
6269
return;
6370
}
6471

65-
const auto correctionFactorCalDet = mGainMap.get();
66-
6772
// Fill digits map
6873
for (const auto& digit : eventSector) {
74+
const int cru = digit.getCRU();
6975
const int time = digit.getTimeStamp();
7076
const int row = digit.getRow();
7177
const int pad = digit.getPad();
78+
const float adcValue = digit.getChargeFloat();
7279

73-
float correctionFactor = 1.0;
80+
fillADCValue(cru, row, pad, time, adcValue);
81+
}
82+
}
7483

75-
if (correctionFactorCalDet) {
76-
int padNum = mMapperInstance.globalPadNumber(PadPos(row, pad));
77-
correctionFactor = correctionFactorCalDet->getValue(sector, padNum);
78-
}
79-
// Every row starts at pad zero. But the number of pads in a row is not a constant.
80-
// If we would just fill the map naively, we would put pads next to each other, which are not neighbours on the pad plane.
81-
// Hence, we need to correct for this:
82-
const int pads = mMapperInstance.getNumberOfPadsInRowSector(row);
83-
const int corPad = pad - (pads / 2) + (MaxPads / 2);
84-
85-
if (correctionFactor == 0) {
86-
LOGP(warning, "Encountered correction factor which is zero.");
87-
LOGP(warning, "Digit will be set to 0!");
88-
mMapOfAllDigits[time][row][corPad] = 0;
89-
} else {
90-
mMapOfAllDigits[time][row][corPad] = digit.getChargeFloat() / correctionFactor;
91-
}
84+
void KrBoxClusterFinder::fillADCValue(int cru, int rowInSector, int padInRow, int timeBin, float adcValue)
85+
{
86+
if (timeBin >= MaxTimes) {
87+
return;
9288
}
89+
90+
// Every row starts at pad zero. But the number of pads in a row is not a constant.
91+
// If we would just fill the map naively, we would put pads next to each other, which are not neighbours on the pad plane.
92+
// Hence, we need to correct for this:
93+
mSector = cru / CRU::CRUperSector;
94+
const int pads = mMapperInstance.getNumberOfPadsInRowSector(rowInSector);
95+
const int corPad = padInRow - (pads / 2) + (MaxPads / 2);
96+
97+
const auto correctionFactorCalDet = mGainMap.get();
98+
if (!correctionFactorCalDet) {
99+
mMapOfAllDigits[timeBin][rowInSector][corPad] = adcValue;
100+
return;
101+
}
102+
103+
int padNum = mMapperInstance.globalPadNumber(PadPos(rowInSector, padInRow));
104+
float correctionFactor = correctionFactorCalDet->getValue(mSector, padNum);
105+
106+
if (correctionFactor == 0) {
107+
LOGP(warning, "Encountered correction factor which is zero.");
108+
LOGP(warning, "Digit will be set to 0!");
109+
adcValue = 0;
110+
} else {
111+
adcValue /= correctionFactor;
112+
}
113+
114+
mMapOfAllDigits[timeBin][rowInSector][corPad] = adcValue;
93115
}
94116

95117
//#################################################
@@ -114,6 +136,7 @@ void KrBoxClusterFinder::updateTempClusterFinal()
114136
// Since every padrow is shifted such that neighbouring pads are indeed neighbours, we have to shift once back:
115137
mTempCluster.meanPad = mTempCluster.meanPad + (corPadsMean / 2.0) - (MaxPads / 2.0);
116138
mTempCluster.maxChargePad = mTempCluster.maxChargePad + (corPadsMaxCharge / 2.0) - (MaxPads / 2.0);
139+
mTempCluster.sector = (decltype(mTempCluster.sector))mSector;
117140
}
118141

119142
// Function to update the temporal cluster.
@@ -145,7 +168,7 @@ void KrBoxClusterFinder::updateTempCluster(float tempCharge, int tempPad, int te
145168

146169
// This function finds and evaluates all clusters in a 3D mMapOfAllDigits generated by the
147170
// mMapOfAllDigitsCreator function, this function also updates the cluster tree
148-
std::vector<std::tuple<int, int, int>> KrBoxClusterFinder::findLocalMaxima()
171+
std::vector<std::tuple<int, int, int>> KrBoxClusterFinder::findLocalMaxima(bool directFilling)
149172
{
150173
std::vector<std::tuple<int, int, int>> localMaximaCoords;
151174
// loop over whole mMapOfAllDigits the find clusters
@@ -222,7 +245,11 @@ std::vector<std::tuple<int, int, int>> KrBoxClusterFinder::findLocalMaxima()
222245
if (!thisIsMax) {
223246
continue;
224247
} else {
225-
localMaximaCoords.emplace_back(std::make_tuple(iPad, iRow, iTime));
248+
if (directFilling) {
249+
buildCluster(iPad, iRow, iTime, directFilling);
250+
} else {
251+
localMaximaCoords.emplace_back(std::make_tuple(iPad, iRow, iTime));
252+
}
226253
}
227254
}
228255
}
@@ -247,9 +274,8 @@ std::vector<std::tuple<int, int, int>> KrBoxClusterFinder::findLocalMaxima()
247274
// for loop over whole cluster, to determine if a charge should be added
248275
// conditions are extrapolation of the 5x5 cluster case to arbitrary
249276
// cluster sizes in 3 dimensions
250-
KrCluster KrBoxClusterFinder::buildCluster(int clusterCenterPad, int clusterCenterRow, int clusterCenterTime)
277+
KrCluster KrBoxClusterFinder::buildCluster(int clusterCenterPad, int clusterCenterRow, int clusterCenterTime, bool directFilling)
251278
{
252-
mTempCluster = KrCluster();
253279
mTempCluster.reset();
254280

255281
setMaxClusterSize(clusterCenterRow);
@@ -346,6 +372,11 @@ KrCluster KrBoxClusterFinder::buildCluster(int clusterCenterPad, int clusterCent
346372
// At the end, out mTempCluster should contain all digits that were assigned to the cluster.
347373
// So before returning it, we update it one last time to calculate the correct means and sigmas.
348374
updateTempClusterFinal();
375+
376+
if (directFilling) {
377+
mClusters.emplace_back(mTempCluster);
378+
}
379+
349380
return mTempCluster;
350381
}
351382

@@ -365,4 +396,4 @@ void KrBoxClusterFinder::setMaxClusterSize(int row)
365396
mMaxClusterSizePad = mMaxClusterSizePadOROC3;
366397
mMaxClusterSizeRow = mMaxClusterSizeRowOROC3;
367398
}
368-
}
399+
}

Detectors/TPC/workflow/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ o2_add_library(TPCWorkflow
2727
src/ClusterSharingMapSpec.cxx
2828
src/FileReaderWorkflow.cxx
2929
src/CalDetMergerPublisherSpec.cxx
30+
src/KryptonClustererSpec.cxx
3031
TARGETVARNAME targetName
3132
PUBLIC_LINK_LIBRARIES O2::Framework O2::DataFormatsTPC
3233
O2::DPLUtils O2::TPCReconstruction
@@ -58,6 +59,11 @@ o2_add_executable(file-reader
5859
SOURCES src/FileReaderWorkflow.cxx
5960
PUBLIC_LINK_LIBRARIES O2::TPCWorkflow)
6061

62+
o2_add_executable(krypton-clusterer
63+
COMPONENT_NAME tpc
64+
SOURCES src/tpc-krypton-clusterer.cxx
65+
PUBLIC_LINK_LIBRARIES O2::TPCWorkflow)
66+
6167
o2_add_test(workflow
6268
COMPONENT_NAME tpc
6369
LABELS tpc workflow
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Copyright CERN and copyright holders of ALICE O2. This software is
2+
// distributed under the terms of the GNU General Public License v3 (GPL
3+
// Version 3), copied verbatim in the file "COPYING".
4+
//
5+
// See http://alice-o2.web.cern.ch/license for full licensing information.
6+
//
7+
// In applying this license CERN does not waive the privileges and immunities
8+
// granted to it by virtue of its status as an Intergovernmental Organization
9+
// or submit itself to any jurisdiction.
10+
11+
/// @file RawToDigitsSpec.h
12+
/// @author Jens Wiechula
13+
/// @since 2021-02-26
14+
/// @brief Processor spec for running TPC Krypton cluster finder
15+
16+
#ifndef TPC_KryptonClustererSpec_H_
17+
#define TPC_KryptonClustererSpec_H_
18+
19+
#include "Framework/DataProcessorSpec.h"
20+
#include <string_view>
21+
22+
namespace o2
23+
{
24+
namespace tpc
25+
{
26+
27+
/// create a processor spec
28+
/// read simulated TPC clusters from file and publish
29+
o2::framework::DataProcessorSpec getKryptonClustererSpec(const std::string inputSpec, int ilane, std::vector<int> const& sectors);
30+
31+
} // end namespace tpc
32+
} // end namespace o2
33+
34+
#endif // TPC_RAWTODIGITSSPEC_H_

Detectors/TPC/workflow/src/CalibProcessingHelper.cxx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ uint64_t calib_processing_helper::processRawData(o2::framework::InputRecord& inp
4242

4343
for (auto const& ref : InputRecordWalker(inputs, filter)) {
4444
const auto* dh = DataRefUtils::getHeader<o2::header::DataHeader*>(ref);
45+
firstOrbit = dh->firstTForbit;
4546

4647
// ---| extract hardware information to do the processing |---
4748
const auto subSpecification = dh->subSpecification;
@@ -95,7 +96,7 @@ uint64_t calib_processing_helper::processRawData(o2::framework::InputRecord& inp
9596
}
9697
}
9798

98-
firstOrbit = RDHUtils::getHeartBeatOrbit(*rdhPtr);
99+
//firstOrbit = RDHUtils::getHeartBeatOrbit(*rdhPtr);
99100
LOGP(info, "First orbit in present TF: {}", firstOrbit);
100101
readFirst = true;
101102
}

0 commit comments

Comments
 (0)