Project
Loading...
Searching...
No Matches
TPCFourierTransformEPNSpec.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_TPCFOURIERTRANSFORMEPNSPEC_H
18#define O2_TPCFOURIERTRANSFORMEPNSPEC_H
19
20#include <vector>
21#include <fmt/format.h>
22#include "Framework/Task.h"
24#include "Framework/Logger.h"
28#include "Headers/DataHeader.h"
31#include "TPCBase/CRU.h"
32
33using namespace o2::framework;
35using namespace o2::tpc;
36
37namespace o2::tpc
38{
39
41{
42 public:
44
45 TPCFourierTransformEPNSpec(const std::vector<uint32_t>& crus, const unsigned int nFourierCoefficientsSend, const unsigned int rangeIDC, const std::vector<o2::tpc::Side>& sides) : mCRUs{crus}, mIDCFourierTransform{rangeIDC, nFourierCoefficientsSend}, mSides{sides} {};
46
48 {
49 mDumpFFT = ic.options().get<bool>("dump-coefficients-epn");
50 }
51
53 {
54 for (auto const& ref : InputRecordWalker(pc.inputs(), mFilter)) {
55 const auto currTF = processing_helpers::getCurrentTF(pc);
56 if (mReceivedCRUs == 0) {
57 mCurrentTF = currTF;
58 } else if (mCurrentTF != currTF) {
59 LOGP(error, "Received TF {} expected TF {}", currTF, mCurrentTF);
60 continue;
61 }
62
63 ++mReceivedCRUs;
64 auto const* tpcCRUHeader = o2::framework::DataRefUtils::getHeader<o2::header::DataHeader*>(ref);
65 const int cru = tpcCRUHeader->subSpecification >> 7;
66 const o2::tpc::CRU cruTmp(cru);
67 const auto descr = tpcCRUHeader->dataDescription;
68
70 LOGP(debug, "Receiving IDC1 for TF {} for CRU {}", currTF, cru);
71 mIDCOneAggregator.aggregate1DIDCs(cruTmp.side(), pc.inputs().get<std::vector<float>>(ref));
72 } else {
73 LOGP(debug, "Receiving IDC1 weights for TF {} for CRU {}", currTF, cru);
74 mIDCOneAggregator.aggregate1DIDCsWeights(cruTmp.side(), pc.inputs().get<std::vector<unsigned int>>(ref));
75 }
76 }
77
78 LOGP(debug, "Received data {} of a total of {}", mReceivedCRUs, 2 * mCRUs.size());
79 if (mReceivedCRUs != 2 * mCRUs.size()) {
80 return;
81 } else {
82 mReceivedCRUs = 0;
83 }
84
85 // perform fourier transform of 1D-IDCs
86 LOGP(debug, "normalize IDCs");
87 mIDCOneAggregator.normalizeIDCOne();
88 for (const auto side : mSides) {
89 mIDCFourierTransform.setIDCs(std::move(mIDCOneAggregator).get(side));
90 LOGP(debug, "calculate fourier coefficients");
91 mIDCFourierTransform.calcFourierCoefficients();
92
93 if (mDumpFFT) {
94 LOGP(info, "dumping FT to file");
95 mIDCFourierTransform.dumpToFile(fmt::format("FourierEPN_{:02}_side{}.root", pc.services().get<o2::framework::TimingInfo>().tfCounter, static_cast<int>(side)).data());
96 }
97
98 sendOutput(pc.outputs(), side);
99 }
100 }
101
103 {
104 ec.services().get<ControlService>().readyToQuit(QuitRequest::Me);
105 }
106
108 static constexpr header::DataDescription getDataDescription() { return header::DataDescription{"FOURIERCOEFF"}; }
109
110 private:
111 const std::vector<uint32_t> mCRUs{};
113 std::vector<Side> mSides{};
114 IDCOneAggregator mIDCOneAggregator{};
115 bool mDumpFFT{false};
116 int mReceivedCRUs = 0;
117 uint32_t mCurrentTF{0};
118 const std::vector<InputSpec> mFilter = {{"1didcepn", ConcreteDataTypeMatcher{o2::header::gDataOriginTPC, TPCFLPIDCDevice::getDataDescription1DIDCEPN()}, Lifetime::Timeframe},
120
121 void sendOutput(DataAllocator& output, const Side side)
122 {
123 output.snapshot(Output{gDataOriginTPC, getDataDescription(), header::DataHeader::SubSpecificationType{side}}, mIDCFourierTransform.getFourierCoefficients().getFourierCoefficients());
124 }
125};
126
127DataProcessorSpec getTPCFourierTransformEPNSpec(const std::vector<uint32_t>& crus, const unsigned int rangeIDC, const unsigned int nFourierCoefficientsSend)
128{
129 const auto sides = o2::tpc::IDCFactorization::getSides(crus);
130
131 std::vector<InputSpec> inputSpecs{InputSpec{"1didcepn", ConcreteDataTypeMatcher{gDataOriginTPC, TPCFLPIDCDevice::getDataDescription1DIDCEPN()}, Lifetime::Timeframe},
132 InputSpec{"1didcepnweights", ConcreteDataTypeMatcher{gDataOriginTPC, TPCFLPIDCDevice::getDataDescription1DIDCEPNWeights()}, Lifetime::Timeframe}};
133
134 std::vector<OutputSpec> outputSpecs;
135 for (const auto side : sides) {
137 }
138
139 return DataProcessorSpec{
140 "tpc-epn-ft",
141 inputSpecs,
142 outputSpecs,
143 AlgorithmSpec{adaptFromTask<TPCFourierTransformEPNSpec>(crus, nFourierCoefficientsSend, rangeIDC, sides)},
144 Options{
145 {"dump-coefficients-epn", VariantType::Bool, false, {"Dump fourier coefficients to file"}}}}; // end DataProcessorSpec
146}
147
148} // namespace o2::tpc
149
150#endif
class for calculating the fourier coefficients from 1D-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 device for processing on FLPs.
std::ostringstream debug
A helper class to iteratate over all parts of all input routes.
Side side() const
Definition CRU.h:62
const std::vector< Side > & getSides() const
void dumpToFile(const char *outFileName="Fourier.root", const char *outName="FourierCoefficients") const
const auto & getFourierCoefficients() const
void calcFourierCoefficients(const unsigned int timeFrames=2000)
calculate fourier coefficients for one TPC side
Helper class for aggregation of 1D-IDCs from different CRUs.
void aggregate1DIDCsWeights(const o2::tpc::Side side, const std::vector< unsigned int > &idcCount)
void aggregate1DIDCs(const o2::tpc::Side side, const std::vector< float > &idc)
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 endOfStream(o2::framework::EndOfStreamContext &ec) final
This is invoked whenever we have an EndOfStream event.
static constexpr header::DataDescription getDataDescription()
void init(o2::framework::InitContext &ic) final
TPCFourierTransformEPNSpec(const std::vector< uint32_t > &crus, const unsigned int nFourierCoefficientsSend, const unsigned int rangeIDC, const std::vector< o2::tpc::Side > &sides)
void run(o2::framework::ProcessingContext &pc) final
constexpr o2::header::DataOrigin gDataOriginTPC
Definition DataHeader.h:576
Defining PrimaryVertex explicitly as messageable.
Definition TFIDInfo.h:20
std::vector< ConfigParamSpec > Options
uint32_t getCurrentTF(o2::framework::ProcessingContext &pc)
Global TPC definitions and constants.
Definition SimTraits.h:167
DataProcessorSpec getTPCFourierTransformEPNSpec(const std::vector< uint32_t > &crus, const unsigned int rangeIDC, const unsigned int nFourierCoefficientsSend)
Side
TPC readout sidE.
Definition Defs.h:35
uint32_t tfCounter
the orbit the TF begins
Definition TimingInfo.h:32
uint32_t SubSpecificationType
Definition DataHeader.h:620