Project
Loading...
Searching...
No Matches
TPCFLPIDCSpec.h
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#ifndef O2_TPCFLPIDCSPEC_H
18#define O2_TPCFLPIDCSPEC_H
19
20#include <vector>
21#include <deque>
22#include <fmt/format.h>
23#include "Framework/Task.h"
25#include "Framework/Logger.h"
29#include "Headers/DataHeader.h"
35
36using namespace o2::framework;
38using namespace o2::tpc;
39
40namespace o2::tpc
41{
42
44{
45 public:
46 TPCFLPIDCDevice(const int lane, const std::vector<uint32_t>& crus, const unsigned int rangeIDC, const bool loadStatusMap, const std::string idc0File, const bool loadIDC0CCDB, const bool enableSynchProc, const int nTFsBuffer)
47 : mLane{lane}, mCRUs{crus}, mRangeIDC{rangeIDC}, mLoadPadMapCCDB{loadStatusMap}, mLoadIDC0CCDB{loadIDC0CCDB}, mEnableSynchProc{enableSynchProc}, mNTFsBuffer{nTFsBuffer}, mOneDIDCs{std::vector<float>(rangeIDC), std::vector<unsigned int>(rangeIDC)}
48 {
49 const auto nSizeDeque = std::ceil(static_cast<float>(mRangeIDC) / mMinIDCsPerTF);
50 for (const auto& cru : mCRUs) {
51 mBuffer1DIDCs.emplace(cru, std::deque<std::pair<std::vector<float>, std::vector<unsigned int>>>(nSizeDeque, {std::vector<float>(mMinIDCsPerTF, 0), std::vector<unsigned int>(mMinIDCsPerTF, 1)}));
52 }
53
54 // loading IDC0
55 if (!idc0File.empty()) {
56 TFile f(idc0File.data(), "READ");
57 IDCZero* idcs = nullptr;
58 f.GetObject("IDC0", idcs);
59 if (idcs) {
60 LOGP(info, "Setting IDC0 from file {}", idc0File);
61 mIDCZero = *idcs;
62 delete idcs;
63 }
64 } else if (!mLoadIDC0CCDB) {
65 LOGP(info, "setting standard IDC0 values");
66 mIDCZero.mIDCZero = std::vector<float>(Mapper::getNumberOfPadsPerSide(), 1);
67 }
68 }
69
71 {
72 mDumpIDCs = ic.options().get<bool>("dump-idcs-flp");
73 }
74
76 {
77 LOGP(debug, "Processing IDCs for TF {} for CRUs {} to {}", processing_helpers::getCurrentTF(pc), mCRUs.front(), mCRUs.back());
78
79 // retrieving map containing the status flags for the static outlier
80 if (mLoadPadMapCCDB) {
81 updateTimeDependentParams(pc);
82 }
83
84 if (mLoadIDC0CCDB) {
85 LOGP(debug, "Loading IDC0 from CCDB as reference for calculating IDC1");
86 auto idc = pc.inputs().get<o2::tpc::IDCZero*>("idczero");
87 mIDCZero = *idc;
88 // load IDC0 only once TODO use correct time stamp for CCDB access?
89 mLoadIDC0CCDB = false;
90 }
91
92 for (auto& ref : InputRecordWalker(pc.inputs(), mFilter)) {
93 ++mCountTFsForBuffer;
94 auto const* tpcCRUHeader = o2::framework::DataRefUtils::getHeader<o2::header::DataHeader*>(ref);
95 const int cru = tpcCRUHeader->subSpecification >> 7;
96 auto vecIDCs = pc.inputs().get<o2::pmr::vector<float>>(ref);
97 mIDCs[cru].insert(mIDCs[cru].end(), vecIDCs.begin(), vecIDCs.end());
98
99 if (mEnableSynchProc) {
100 sendOutputSync(pc.outputs(), vecIDCs, cru);
101 }
102 }
103
104 // check if the condition for sending the data is met
105 if (mCountTFsForBuffer >= mNTFsBuffer) {
106 mCountTFsForBuffer = 0;
107 for (const auto cru : mCRUs) {
108 LOGP(debug, "Sending IDCs of size {} for TF {}", mIDCs[cru].size(), processing_helpers::getCurrentTF(pc));
109 sendOutput(pc.outputs(), cru);
110 }
111 }
112
113 if (mDumpIDCs) {
114 TFile fOut(fmt::format("IDCs_{}_tf_{}.root", mLane, processing_helpers::getCurrentTF(pc)).data(), "RECREATE");
115 for (auto& ref : InputRecordWalker(pc.inputs(), mFilter)) {
116 auto const* tpcCRUHeader = o2::framework::DataRefUtils::getHeader<o2::header::DataHeader*>(ref);
117 const int cru = tpcCRUHeader->subSpecification >> 7;
118 auto vec = pc.inputs().get<std::vector<float>>(ref);
119 fOut.WriteObject(&vec, fmt::format("CRU_{}", cru).data());
120 }
121 }
122 }
123
124 void finaliseCCDB(ConcreteDataMatcher& matcher, void* obj) final
125 {
126 if (matcher == ConcreteDataMatcher(gDataOriginTPC, "PADSTATUSMAP", 0)) {
127 LOGP(debug, "Updating pad status from CCDB");
128 mPadFlagsMap = static_cast<o2::tpc::CalDet<PadFlags>*>(obj);
129 }
130 }
131
132 void endOfStream(o2::framework::EndOfStreamContext& ec) final { ec.services().get<ControlService>().readyToQuit(QuitRequest::Me); }
133
135
138
141
144
147
150 static void setMinIDCsPerTF(const unsigned int nMinIDCsPerTF) { mMinIDCsPerTF = nMinIDCsPerTF; }
151
153 static unsigned int getMinIDCsPerTF() { return mMinIDCsPerTF; }
154
155 private:
156 inline static unsigned int mMinIDCsPerTF{10};
157 const int mLane{};
158 const std::vector<uint32_t> mCRUs{};
159 const unsigned int mRangeIDC{};
160 const bool mLoadPadMapCCDB{};
161 bool mLoadIDC0CCDB{};
162 const bool mEnableSynchProc{};
163 int mNTFsBuffer{1};
164 bool mDumpIDCs{};
165 int mCountTFsForBuffer{0};
166 std::pair<std::vector<float>, std::vector<unsigned int>> mOneDIDCs{};
167 std::unordered_map<unsigned int, o2::pmr::vector<float>> mIDCs{};
168 std::unordered_map<unsigned int, std::deque<std::pair<std::vector<float>, std::vector<unsigned int>>>> mBuffer1DIDCs{};
169 CalDet<PadFlags>* mPadFlagsMap{nullptr};
170 IDCZero mIDCZero{};
171 const std::vector<InputSpec> mFilter = {{"idcs", ConcreteDataTypeMatcher{gDataOriginTPC, TPCIntegrateIDCDevice::getDataDescription(TPCIntegrateIDCDevice::IDCFormat::Sim)}, Lifetime::Timeframe}};
172
174 void updateTimeDependentParams(ProcessingContext& pc) { pc.inputs().get<o2::tpc::CalDet<PadFlags>*>("tpcpadmap").get(); }
175
176 void sendOutputSync(DataAllocator& output, const o2::pmr::vector<float>& idc, const uint32_t cru)
177 {
178 const header::DataHeader::SubSpecificationType subSpec{cru << 7};
179 const CRU cruTmp(cru);
180 const int integrationIntervalOffset = 0;
181 const auto region = cruTmp.region();
182 const unsigned int indexOffset = (cruTmp.sector() % SECTORSPERSIDE) * Mapper::getPadsInSector() + Mapper::GLOBALPADOFFSET[region]; // TODO get correct offset for TPCFLPIDCDeviceGroup case
183 const auto nIDCsPerIntegrationInterval = Mapper::PADSPERREGION[region];
184 const auto integrationIntervals = idc.size() / nIDCsPerIntegrationInterval;
185 std::vector<std::vector<float>> idcOneTmp(integrationIntervals);
186 for (auto& vec : idcOneTmp) {
187 vec.reserve(nIDCsPerIntegrationInterval);
188 }
189 IDCFactorization::calcIDCOne(idc, nIDCsPerIntegrationInterval, integrationIntervalOffset, indexOffset, cruTmp, idcOneTmp, &mIDCZero, mPadFlagsMap);
190
191 // calculate 1D-IDCs
192 std::pair<std::vector<float>, std::vector<unsigned int>> idcOne;
193 idcOne.first.resize(integrationIntervals);
194 idcOne.second.resize(integrationIntervals);
195 for (int i = 0; i < integrationIntervals; ++i) {
196 idcOne.first[i] = std::accumulate(idcOneTmp[i].begin(), idcOneTmp[i].end(), 0);
197 idcOne.second[i] = idcOneTmp[i].size();
198 }
199
200 // normalize to pad size
201 std::transform(idcOne.first.begin(), idcOne.first.end(), idcOne.first.begin(), [normVal = Mapper::INVPADAREA[region]](auto& val) { return val * normVal; });
202
203 mBuffer1DIDCs[cru].emplace_back(std::move(idcOne));
204 mBuffer1DIDCs[cru].pop_front(); // removing oldest 1D-IDCs
205
206 fill1DIDCs(cru);
207 LOGP(debug, "Sending 1D-IDCs to EPNs of size {} and weights of size {}", mOneDIDCs.first.size(), mOneDIDCs.second.size());
208 output.snapshot(Output{gDataOriginTPC, getDataDescription1DIDCEPN(), subSpec}, mOneDIDCs.first);
209 output.snapshot(Output{gDataOriginTPC, getDataDescription1DIDCEPNWeights(), subSpec}, mOneDIDCs.second);
210 }
211
212 void sendOutput(DataAllocator& output, const uint32_t cru)
213 {
214 const header::DataHeader::SubSpecificationType subSpec{cru << 7};
215 output.adoptContainer(Output{gDataOriginTPC, getDataDescriptionIDCGroup(CRU(cru).side()), subSpec}, std::move(mIDCs[cru]));
216 }
217
218 void fill1DIDCs(const uint32_t cru)
219 {
220 // fill 1D-IDC vector with mRangeIDC buffered values
221 unsigned int i = mRangeIDC;
222 for (int indexDeque = mBuffer1DIDCs[cru].size() - 1; indexDeque >= 0; --indexDeque) {
223 for (int indexIDCs = mBuffer1DIDCs[cru][indexDeque].first.size() - 1; indexIDCs >= 0; --indexIDCs) {
224 mOneDIDCs.first[--i] = mBuffer1DIDCs[cru][indexDeque].first[indexIDCs];
225 mOneDIDCs.second[i] = mBuffer1DIDCs[cru][indexDeque].second[indexIDCs];
226 if (i == 0) {
227 return;
228 }
229 }
230 }
231 }
232};
233
234DataProcessorSpec getTPCFLPIDCSpec(const int ilane, const std::vector<uint32_t>& crus, const unsigned int rangeIDC, const bool loadStatusMap, const std::string idc0File, const bool disableIDC0CCDB, const bool enableSynchProc, const int nTFsBuffer = 1)
235{
236 std::vector<OutputSpec> outputSpecs;
237 std::vector<InputSpec> inputSpecs;
238 outputSpecs.reserve(crus.size());
239 inputSpecs.reserve(crus.size());
240
241 for (const auto& cru : crus) {
242 const header::DataHeader::SubSpecificationType subSpec{cru << 7};
243 inputSpecs.emplace_back(InputSpec{"idcs", gDataOriginTPC, TPCIntegrateIDCDevice::getDataDescription(TPCIntegrateIDCDevice::IDCFormat::Sim), subSpec, Lifetime::Timeframe});
244
245 const Side side = CRU(cru).side();
246 outputSpecs.emplace_back(ConcreteDataMatcher{gDataOriginTPC, TPCFLPIDCDevice::getDataDescriptionIDCGroup(side), subSpec}, Lifetime::Sporadic);
247 if (enableSynchProc) {
248 outputSpecs.emplace_back(ConcreteDataMatcher{gDataOriginTPC, TPCFLPIDCDevice::getDataDescription1DIDCEPN(), subSpec});
249 outputSpecs.emplace_back(ConcreteDataMatcher{gDataOriginTPC, TPCFLPIDCDevice::getDataDescription1DIDCEPNWeights(), subSpec});
250 }
251 }
252
253 const Side side = CRU(crus.front()).side();
254 if (loadStatusMap) {
255 LOGP(info, "Using pad status map from CCDB");
256 inputSpecs.emplace_back("tpcpadmap", gDataOriginTPC, "PADSTATUSMAP", 0, Lifetime::Condition, ccdbParamSpec((side == Side::A) ? CDBTypeMap.at(CDBType::CalIDCPadStatusMapA) : CDBTypeMap.at(CDBType::CalIDCPadStatusMapC)));
257 }
258
259 const bool loadIDC0CCDB = !disableIDC0CCDB && idc0File.empty();
260 if (loadIDC0CCDB) {
261 inputSpecs.emplace_back("idczero", gDataOriginTPC, "IDC0", 0, Lifetime::Condition, ccdbParamSpec((side == Side::A) ? CDBTypeMap.at(CDBType::CalIDC0A) : CDBTypeMap.at(CDBType::CalIDC0C)));
262 }
263
264 const auto id = fmt::format("tpc-flp-idc-{:02}", ilane);
265 return DataProcessorSpec{
266 id.data(),
267 inputSpecs,
268 outputSpecs,
269 AlgorithmSpec{adaptFromTask<TPCFLPIDCDevice>(ilane, crus, rangeIDC, loadStatusMap, idc0File, loadIDC0CCDB, enableSynchProc, nTFsBuffer)},
270 Options{{"dump-idcs-flp", VariantType::Bool, false, {"Dump IDCs to file"}}}}; // end DataProcessorSpec
271}
272
273} // namespace o2::tpc
274
275#endif
Simple interface to the CDB manager.
int32_t i
class for aggregating IDCs for the full TPC (all sectors) and factorization of aggregated IDCs
A helper class to iteratate over all parts of all input routes.
void output(const std::map< std::string, ChannelStat > &channels)
Definition rawdump.cxx:197
uint32_t side
Definition RawData.h:0
TPC integration of IDCs processor.
std::ostringstream debug
A helper class to iteratate over all parts of all input routes.
decltype(auto) get(R binding, int part=0) const
InputRecord & inputs()
The inputs associated with this processing context.
Side side() const
Definition CRU.h:62
void calcIDCOne()
calculate I_1(t) = <I(r,\phi,t) / I_0(r,\phi)>_{r,\phi}
static constexpr unsigned int GLOBALPADOFFSET[NREGIONS]
offset of number of pads for region
Definition Mapper.h:531
static constexpr float INVPADAREA[NREGIONS]
inverse size of the pad area padwidth*padLength
Definition Mapper.h:536
static constexpr unsigned short getPadsInSector()
Definition Mapper.h:414
static constexpr int getNumberOfPadsPerSide()
Definition Mapper.h:374
static constexpr unsigned int PADSPERREGION[NREGIONS]
number of pads per CRU
Definition Mapper.h:530
void finaliseCCDB(ConcreteDataMatcher &matcher, void *obj) final
static constexpr header::DataDescription getDataDescriptionIDCGroupA()
return data description for IDC Group on A Side
static constexpr header::DataDescription getDataDescription1DIDCEPNWeights()
return data description for buffered weights for 1D IDCs for EPNs
static constexpr header::DataDescription getDataDescription1DIDCEPN()
return data description for buffered 1D IDCs for EPNs
void run(o2::framework::ProcessingContext &pc) final
static constexpr header::DataDescription getDataDescriptionIDCGroup(const Side side)
void endOfStream(o2::framework::EndOfStreamContext &ec) final
This is invoked whenever we have an EndOfStream event.
void init(o2::framework::InitContext &ic) final
static unsigned int getMinIDCsPerTF()
static void setMinIDCsPerTF(const unsigned int nMinIDCsPerTF)
static constexpr header::DataDescription getDataDescriptionIDCGroupC()
return data description for IDC Group on C Side
TPCFLPIDCDevice(const int lane, const std::vector< uint32_t > &crus, const unsigned int rangeIDC, const bool loadStatusMap, const std::string idc0File, const bool loadIDC0CCDB, const bool enableSynchProc, const int nTFsBuffer)
static constexpr header::DataDescription getDataDescription(const IDCFormat idcFormat)
GLsizeiptr size
Definition glcorearb.h:659
GLuint GLuint end
Definition glcorearb.h:469
GLdouble f
Definition glcorearb.h:310
GLboolean * data
Definition glcorearb.h:298
GLuint GLfloat * val
Definition glcorearb.h:1582
GLint ref
Definition glcorearb.h:291
constexpr o2::header::DataOrigin gDataOriginTPC
Definition DataHeader.h:576
Defining PrimaryVertex explicitly as messageable.
Definition TFIDInfo.h:20
std::vector< ConfigParamSpec > ccdbParamSpec(std::string const &path, int runDependent, std::vector< CCDBMetadata > metadata={}, int qrate=0)
std::vector< ConfigParamSpec > Options
auto get(const std::byte *buffer, size_t=0)
Definition DataHeader.h:454
std::vector< T, o2::pmr::polymorphic_allocator< T > > vector
uint32_t getCurrentTF(o2::framework::ProcessingContext &pc)
Global TPC definitions and constants.
Definition SimTraits.h:167
const std::unordered_map< CDBType, const std::string > CDBTypeMap
Storage name in CCDB for each calibration and parameter type.
Definition CDBTypes.h:94
constexpr unsigned char SECTORSPERSIDE
Definition Defs.h:40
DataProcessorSpec getTPCFLPIDCSpec(const int ilane, const std::vector< uint32_t > &crus, const unsigned int rangeIDC, const bool loadStatusMap, const std::string idc0File, const bool disableIDC0CCDB, const bool enableSynchProc, const int nTFsBuffer=1)
Enum< T >::Iterator begin(Enum< T >)
Definition Defs.h:173
Side
TPC readout sidE.
Definition Defs.h:35
@ A
Definition Defs.h:35
@ CalIDCPadStatusMapA
Status map of the pads (dead etc. obatined from CalIDC0)
@ CalIDC0C
I_0(r,\phi) = <I(r,\phi,t)>_t.
@ CalIDC0A
I_0(r,\phi) = <I(r,\phi,t)>_t.
@ CalIDCPadStatusMapC
Status map of the pads (dead etc. obatined from CalIDC0)
Defining DataPointCompositeObject explicitly as copiable.
uint32_t SubSpecificationType
Definition DataHeader.h:620
struct containing the ITPC0 values (integrated TPC clusters)
std::vector< float > mIDCZero
I_0(r,\phi) = <I(r,\phi,t)>_t.
std::vector< o2::ctf::BufferType > vec