-
Notifications
You must be signed in to change notification settings - Fork 508
Expand file tree
/
Copy pathTPCDistributeSACSpec.h
More file actions
133 lines (114 loc) · 5.2 KB
/
Copy pathTPCDistributeSACSpec.h
File metadata and controls
133 lines (114 loc) · 5.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
// All rights not expressly granted are reserved.
//
// This software is distributed under the terms of the GNU General Public
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
//
// In applying this license CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.
/// \file TPCDistributeSACspec.h
/// \brief TPC distribution of SACs for factorization
/// \author Matthias Kleiner <mkleiner@ikf.uni-frankfurt.de>
/// \date Jul 6, 2022
#ifndef O2_TPCDISTRIBUTESACSPEC_H
#define O2_TPCDISTRIBUTESACSPEC_H
#include <vector>
#include "Framework/Task.h"
#include "Framework/ControlService.h"
#include "Framework/Logger.h"
#include "Framework/DataProcessorSpec.h"
#include "Headers/DataHeader.h"
#include "Framework/ConfigParamRegistry.h"
#include "DataFormatsTPC/Defs.h"
#include "TPCCalibration/SACDecoder.h"
using namespace o2::framework;
using o2::header::gDataOriginTPC;
using namespace o2::tpc;
namespace o2::tpc
{
class TPCDistributeSACSpec : public o2::framework::Task
{
public:
TPCDistributeSACSpec(const unsigned int timeframes, const unsigned int outlanes)
: mTimeFrames{timeframes}, mOutLanes{outlanes}
{
// pre calculate data description for output
mDataDescrOut.reserve(mOutLanes);
for (int i = 0; i < mOutLanes; ++i) {
mDataDescrOut.emplace_back(getDataDescriptionSACVec(i));
}
};
void run(o2::framework::ProcessingContext& pc) final
{
const auto& sacPoint = pc.inputs().get<std::vector<o2::tpc::sac::DataPoint>>("sac");
for (const auto& val : sacPoint) {
for (int stack = 0; stack < o2::tpc::GEMSTACKS; ++stack) {
const auto sac = val.currents[stack];
mSACs[stack].emplace_back(sac);
}
}
if (mCCDBTimeStamp == 0 && !sacPoint.empty()) {
const auto reftime = pc.inputs().get<double>("reftime");
mCCDBTimeStamp = static_cast<uint64_t>(reftime + sacPoint.front().time * o2::tpc::sac::Decoder::SampleDistanceTimeMS);
}
++mProcessedTFs;
if (mProcessedTFs == mTimeFrames) {
sendOutput(pc);
mProcessedTFs = 0;
mCurrentOutLane = ++mCurrentOutLane % mOutLanes;
mCCDBTimeStamp = 0;
for (auto& sac : mSACs) {
sac.clear();
}
}
}
void endOfStream(o2::framework::EndOfStreamContext& ec) final
{
ec.services().get<ControlService>().readyToQuit(QuitRequest::Me);
}
static constexpr header::DataDescription getDataDescriptionSACCCDB() { return header::DataDescription{"SACCCDB"}; }
/// return data description for aggregated SACs for given lane
static header::DataDescription getDataDescriptionSACVec(const int lane)
{
const std::string name = fmt::format("SACVEC{}", lane).data();
header::DataDescription description;
description.runtimeInit(name);
return description;
}
private:
const unsigned int mTimeFrames{}; ///< number of TFs per aggregation interval
const unsigned int mOutLanes{}; ///< number of output lanes
int mProcessedTFs{0}; ///< number of processed time frames to keep track of when the writing to CCDB will be done
std::array<std::vector<int32_t>, o2::tpc::GEMSTACKS> mSACs{}; ///< vector containing the sacs
unsigned int mCurrentOutLane{0}; ///< index for keeping track of the current output lane
uint64_t mCCDBTimeStamp{0}; ///< time stamp of first SACs which are received for the current aggreagtion interval, which is used for setting the time when writing to the CCDB
std::vector<header::DataDescription> mDataDescrOut{}; ///< data description for the different output lanes
void sendOutput(o2::framework::ProcessingContext& pc)
{
LOGP(info, "Sending SACs on lane: {} for {} TFs", mCurrentOutLane, mProcessedTFs);
pc.outputs().snapshot(Output{gDataOriginTPC, getDataDescriptionSACCCDB(), 0}, mCCDBTimeStamp);
for (unsigned int i = 0; i < o2::tpc::GEMSTACKS; ++i) {
pc.outputs().snapshot(Output{gDataOriginTPC, mDataDescrOut[mCurrentOutLane], header::DataHeader::SubSpecificationType{i}}, mSACs[i]);
}
}
};
DataProcessorSpec getTPCDistributeSACSpec(const unsigned int timeframes, const unsigned int outlanes)
{
std::vector<InputSpec> inputSpecs;
inputSpecs.emplace_back(InputSpec{"sac", gDataOriginTPC, "DECODEDSAC", 0, Lifetime::Sporadic});
inputSpecs.emplace_back(InputSpec{"reftime", gDataOriginTPC, "REFTIMESAC", 0, Lifetime::Sporadic});
std::vector<OutputSpec> outputSpecs;
for (unsigned int lane = 0; lane < outlanes; ++lane) {
outputSpecs.emplace_back(ConcreteDataTypeMatcher{gDataOriginTPC, TPCDistributeSACSpec::getDataDescriptionSACVec(lane)}, Lifetime::Sporadic);
}
outputSpecs.emplace_back(gDataOriginTPC, TPCDistributeSACSpec::getDataDescriptionSACCCDB(), 0, Lifetime::Sporadic);
return DataProcessorSpec{
"tpc-distribute-sac",
inputSpecs,
outputSpecs,
AlgorithmSpec{adaptFromTask<TPCDistributeSACSpec>(timeframes, outlanes)}};
}
} // namespace o2::tpc
#endif