Project
Loading...
Searching...
No Matches
TPCIntegrateClusterSpec.cxx
Go to the documentation of this file.
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
16
17#include "Framework/Task.h"
18#include "Framework/Logger.h"
24#include "TPCBase/Mapper.h"
28
30
31#include <algorithm>
32#include <numeric>
33
34using namespace o2::framework;
35
36namespace o2
37{
38namespace tpc
39{
40
42{
43 public:
45 TPCIntegrateClusters(std::shared_ptr<o2::base::GRPGeomRequest> req, const bool disableWriter) : mCCDBRequest(req), mDisableWriter(disableWriter){};
46
48 {
50 mNSlicesTF = ic.options().get<int>("nSlicesTF");
51 mHBScaling = ic.options().get<float>("heart-beat-scaling");
52 mProcess3D = ic.options().get<bool>("process-3D-currents");
53 mNBits = ic.options().get<int>("nBits");
54 }
55
56 void run(ProcessingContext& pc) final
57 {
58 // fetch only once
59 if (mContinuousMaxTimeBin < 0) {
62 }
63
64 const auto& clusters = getWorkflowTPCInput(pc);
65 const o2::tpc::ClusterNativeAccess& clIndex = clusters->clusterIndex;
66 const auto nCL = clIndex.nClustersTotal;
67 LOGP(detail, "Processing TF {} with {} clusters", processing_helpers::getCurrentTF(pc), nCL);
68
69 // init only once
70 if (mInitICCBuffer) {
71 const int slicesNew = static_cast<int>(mNSlicesTF * mHBScaling + 0.5);
72 if (slicesNew != mNSlicesTF) {
73 LOGP(info, "Adjusting number of slices to {}", slicesNew);
74 mNSlicesTF = slicesNew;
75 }
76 mNTSPerSlice = mContinuousMaxTimeBin / mNSlicesTF;
77 mInitICCBuffer = false;
78 if (!mProcess3D) {
79 mBufferCurrents.resize(mNSlicesTF);
80 } else {
81 mBufferCurrents.resize(mNSlicesTF * Mapper::getNumberOfPadsPerSide());
82 }
83 }
84
85 // loop over clusters and integrate
86 for (int isector = 0; isector < constants::MAXSECTOR; ++isector) {
87 for (int irow = 0; irow < constants::MAXGLOBALPADROW; ++irow) {
88 const int nClusters = clIndex.nClusters[isector][irow];
89 if (!nClusters) {
90 continue;
91 }
92 const CRU cru(Sector(isector), Mapper::REGION[irow]);
93
94 for (int icl = 0; icl < nClusters; ++icl) {
95 const auto& cl = *(clIndex.clusters[isector][irow] + icl);
96 const float time = cl.getTime();
97 const unsigned int sliceInTF = time / mNTSPerSlice;
98 if (sliceInTF < mNSlicesTF) {
99 const float qMax = cl.getQmax();
100 const float qTot = cl.getQtot();
101 if (!mProcess3D) {
102 if (isector < SECTORSPERSIDE) {
103 mBufferCurrents.mIQMaxA[sliceInTF] += qMax;
104 mBufferCurrents.mIQTotA[sliceInTF] += qTot;
105 ++mBufferCurrents.mINClA[sliceInTF];
106 } else {
107 mBufferCurrents.mIQMaxC[sliceInTF] += qMax;
108 mBufferCurrents.mIQTotC[sliceInTF] += qTot;
109 ++mBufferCurrents.mINClC[sliceInTF];
110 }
111 } else {
112 const int pad = static_cast<int>(cl.getPad() + 0.5f);
113 const int region = Mapper::REGION[irow];
114 const unsigned int index = sliceInTF * Mapper::getNumberOfPadsPerSide() + (isector % SECTORSPERSIDE) * Mapper::getPadsInSector() + Mapper::GLOBALPADOFFSET[region] + Mapper::OFFSETCRUGLOBAL[irow] + pad;
115
116 if (index > mBufferCurrents.mIQMaxA.size()) {
117 LOGP(warning, "Index {} is larger than max index {}", index, mBufferCurrents.mIQMaxA.size());
118 }
119
120 if (isector < SECTORSPERSIDE) {
121 mBufferCurrents.mIQMaxA[index] += qMax;
122 mBufferCurrents.mIQTotA[index] += qTot;
123 ++mBufferCurrents.mINClA[index];
124 } else {
125 mBufferCurrents.mIQMaxC[index] += qMax;
126 mBufferCurrents.mIQTotC[index] += qTot;
127 ++mBufferCurrents.mINClC[index];
128 }
129 }
130 } else {
131 LOGP(debug, "slice in TF of ICC {} is larger than max slice {} with nTSPerSlice {}", sliceInTF, mNSlicesTF, mNTSPerSlice);
132 }
133 }
134 }
135 }
136
137 const float nTSPerSliceInv = 1. / float(mNTSPerSlice);
138 mBufferCurrents.normalize(nTSPerSliceInv);
139 sendOutput(pc);
140 }
141
142 void endOfStream(EndOfStreamContext& eos) final { eos.services().get<ControlService>().readyToQuit(QuitRequest::Me); }
143
145
146 private:
147 int mNSlicesTF = 11;
148 float mHBScaling = 1;
149 const bool mDisableWriter{false};
150 bool mProcess3D{false};
151 std::vector<int> mCounterNeighbours;
152 ITPCC mBufferCurrents;
153 std::shared_ptr<o2::base::GRPGeomRequest> mCCDBRequest;
154 int mContinuousMaxTimeBin{-1};
155 bool mInitICCBuffer{true};
156 int mNTSPerSlice{1};
157 int mNBits = 32;
158
159 void sendOutput(ProcessingContext& pc)
160 {
161 if (mNBits < 32) {
162 mBufferCurrents.compress(mNBits);
163 }
164 pc.outputs().snapshot(Output{header::gDataOriginTPC, getDataDescriptionTPCC()}, mBufferCurrents);
165 // in case of ROOT output also store the TFinfo in the TTree
166 if (!mDisableWriter) {
169 pc.outputs().snapshot(Output{header::gDataOriginTPC, getDataDescriptionTPCTFId()}, tfinfo);
170 }
171 }
172};
173
175{
176 std::vector<InputSpec> inputs;
177 inputs.emplace_back("clusTPC", ConcreteDataTypeMatcher{o2::header::gDataOriginTPC, "CLUSTERNATIVE"}, Lifetime::Timeframe);
178
179 auto ccdbRequest = std::make_shared<o2::base::GRPGeomRequest>(false, // orbitResetTime
180 true, // GRPECS=true for nHBF per TF
181 false, // GRPLHCIF
182 false, // GRPMagField
183 false, // askMatLUT
185 inputs);
186
187 std::vector<OutputSpec> outputs;
188 outputs.emplace_back(o2::header::gDataOriginTPC, getDataDescriptionTPCC(), 0, Lifetime::Timeframe);
189 if (!disableWriter) {
190 outputs.emplace_back(o2::header::gDataOriginTPC, getDataDescriptionTPCTFId(), 0, Lifetime::Timeframe);
191 }
192
193 return DataProcessorSpec{
194 "TPCIntegrateClusters",
195 inputs,
196 outputs,
197 AlgorithmSpec{adaptFromTask<TPCIntegrateClusters>(ccdbRequest, disableWriter)},
198 Options{{"nSlicesTF", VariantType::Int, 11, {"number of slices into which a TF is divided"}},
199 {"heart-beat-scaling", VariantType::Float, 1.f, {"fraction of filled TFs (1 full TFs, 0.25 TFs filled only with 25%)"}},
200 {"process-3D-currents", VariantType::Bool, false, {"Process full 3D currents instead of 1D integrated only currents"}},
201 {"nBits", VariantType::Int, 32, {"Number of bits used for compression/rounding (values >= 32 results in no compression)"}}}};
202}
203
204} // namespace tpc
205} // end namespace o2
int16_t time
Definition RawEventData.h:4
Helper for geometry and GRP related CCDB requests.
calibrator class for accumulating integrated clusters
std::ostringstream debug
Helper class to obtain TPC clusters / digits / labels from DPL.
int nClusters
void checkUpdates(o2::framework::ProcessingContext &pc)
bool finaliseCCDB(o2::framework::ConcreteDataMatcher &matcher, void *obj)
static GRPGeomHelper & instance()
void setRequest(std::shared_ptr< GRPGeomRequest > req)
void snapshot(const Output &spec, T const &object)
DataAllocator & outputs()
The data allocator is used to allocate memory for the output data.
static constexpr unsigned int GLOBALPADOFFSET[NREGIONS]
offset of number of pads for region
Definition Mapper.h:531
static constexpr unsigned short getPadsInSector()
Definition Mapper.h:414
static constexpr int getNumberOfPadsPerSide()
Definition Mapper.h:374
static constexpr unsigned int OFFSETCRUGLOBAL[PADROWS]
row offset in cru for given global pad row
Definition Mapper.h:579
static constexpr unsigned REGION[PADROWS]
region for global pad row
Definition Mapper.h:537
void endOfStream(EndOfStreamContext &eos) final
void init(framework::InitContext &ic) final
void run(ProcessingContext &pc) final
TPCIntegrateClusters(std::shared_ptr< o2::base::GRPGeomRequest > req, const bool disableWriter)
\constructor
void finaliseCCDB(o2::framework::ConcreteDataMatcher &matcher, void *obj) final
GLuint index
Definition glcorearb.h:781
constexpr o2::header::DataOrigin gDataOriginTPC
Definition DataHeader.h:576
constexpr int LHCMaxBunches
Defining PrimaryVertex explicitly as messageable.
Definition TFIDInfo.h:20
std::vector< ConfigParamSpec > Options
constexpr int LHCBCPERTIMEBIN
Definition Constants.h:38
constexpr int MAXSECTOR
Definition Constants.h:28
constexpr int MAXGLOBALPADROW
Definition Constants.h:34
uint32_t getCurrentTF(o2::framework::ProcessingContext &pc)
constexpr unsigned char SECTORSPERSIDE
Definition Defs.h:40
o2::framework::DataProcessorSpec getTPCIntegrateClusterSpec(const bool disableWriter)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
static void fillTFIDInfo(o2::framework::ProcessingContext &pc, o2::dataformats::TFIDInfo &ti)
unsigned int nClusters[constants::MAXSECTOR][constants::MAXGLOBALPADROW]
const ClusterNative * clusters[constants::MAXSECTOR][constants::MAXGLOBALPADROW]
std::vector< float > mINClA
integrated 1D-currents for NCl A-side
std::vector< float > mIQMaxC
integrated 1D-currents for QMax C-side
std::vector< float > mIQTotA
integrated 1D-currents for QTot A-side
void normalize(const float factor)
normalize currents
std::vector< float > mIQMaxA
integrated 1D-currents for QMax A-side
std::vector< float > mINClC
integrated 1D-currents for NCl A-side
std::vector< float > mIQTotC
integrated 1D-currents for QTot A-side
void resize(const unsigned int nTotal)
resize buffer for accumulated currents
std::vector< Cluster > clusters