Project
Loading...
Searching...
No Matches
EMCALDCSDataProcessorSpec.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
12#ifndef O2_EMCAL_DATAPROCESSORSPEC_H
13#define O2_EMCAL_DATAPROCESSORSPEC_H
14
17
18#include <unistd.h>
19#include <TRandom.h>
20#include <TStopwatch.h>
29#include "CCDB/CcdbApi.h"
35#include "Framework/Task.h"
36#include "Framework/Logger.h"
39
40using namespace o2::framework;
41
42namespace o2
43{
44namespace emcal
45{
46
50using namespace o2::ccdb;
53using HighResClock = std::chrono::high_resolution_clock;
54using Duration = std::chrono::duration<double, std::ratio<1, 1>>;
56
58{
59 public:
61 {
62 std::string ccdbpath = ic.options().get<std::string>("ccdb-path");
63 auto& mgr = CcdbManager::instance();
64 mgr.setURL(ccdbpath);
65
66 mCheckRunStartStop = ic.options().get<bool>("follow-emcal-run");
67
68 std::vector<DPID> vect;
69 mDPsUpdateInterval = ic.options().get<int64_t>("DPs-update-interval");
70 if (mDPsUpdateInterval == 0) {
71 LOG(error) << "EMC DPs update interval set to zero seconds --> changed to 60";
72 mDPsUpdateInterval = 60;
73 }
74 bool useCCDBtoConfigure = ic.options().get<bool>("use-ccdb-to-configure");
75 if (useCCDBtoConfigure) {
76 LOG(info) << "Configuring via CCDB";
77 long ts = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
78 std::unordered_map<DPID, std::string>* dpid2DataDesc = mgr.getForTimeStamp<std::unordered_map<DPID, std::string>>("EMC/Config/DCSDPconfig", ts);
79 for (auto& i : *dpid2DataDesc) {
80 vect.push_back(i.first);
81 }
82 } else {
83 LOG(info) << "Configuring via hardcoded strings";
84
85 std::vector<std::string> aliasesTEMP = {"EMC_PT_[00..83].Temperature", "EMC_PT_[88..91].Temperature", "EMC_PT_[96..159].Temperature"};
86 std::vector<std::string> aliasesUINT = {"EMC_DDL_LIST[0..1]", "EMC_SRU[00..19]_CFG", "EMC_SRU[00..19]_FMVER",
87 "EMC_TRU[00..45]_PEAKFINDER", "EMC_TRU[00..45]_L0ALGSEL", "EMC_TRU[00..45]_COSMTHRESH",
88 "EMC_TRU[00..45]_GLOBALTHRESH", "EMC_TRU[00..45]_MASK[0..5]",
89 "EMC_STU_ERROR_COUNT_TRU[0..67]", "DMC_STU_ERROR_COUNT_TRU[0..55]"};
90 std::vector<std::string> aliasesINT = {"EMC_STU_FWVERS", "EMC_STU_GA[0..1]", "EMC_STU_GB[0..1]", "EMC_STU_GC[0..1]",
91 "EMC_STU_JA[0..1]", "EMC_STU_JB[0..1]", "EMC_STU_JC[0..1]", "EMC_STU_PATCHSIZE", "EMC_STU_GETRAW",
92 "EMC_STU_MEDIAN", "EMC_STU_REGION", "DMC_STU_FWVERS", "DMC_STU_PHOS_scale[0..3]", "DMC_STU_GA[0..1]",
93 "DMC_STU_GB[0..1]", "DMC_STU_GC[0..1]", "DMC_STU_JA[0..1]", "DMC_STU_JB[0..1]", "DMC_STU_JC[0..1]",
94 "DMC_STU_PATCHSIZE", "DMC_STU_GETRAW", "DMC_STU_MEDIAN", "DMC_STU_REGION", "EMC_RUNNUMBER"};
95
96 std::vector<std::string> expaliasesTEMP = o2::dcs::expandAliases(aliasesTEMP);
97 std::vector<std::string> expaliasesUINT = o2::dcs::expandAliases(aliasesUINT);
98 std::vector<std::string> expaliasesINT = o2::dcs::expandAliases(aliasesINT);
99
100 for (const auto& i : expaliasesTEMP) {
101 vect.emplace_back(i, o2::dcs::DPVAL_DOUBLE);
102 }
103 for (const auto& i : expaliasesINT) {
104 vect.emplace_back(i, o2::dcs::DPVAL_INT);
105 }
106 for (const auto& i : expaliasesUINT) {
107 vect.emplace_back(i, o2::dcs::DPVAL_UINT);
108 }
109 }
110
111 LOG(info) << "Listing Data Points for EMC:";
112 for (auto& i : vect) {
113 LOG(info) << i;
114 }
115
116 mProcessor = std::make_unique<o2::emcal::EMCDCSProcessor>();
117 bool useVerboseMode = ic.options().get<bool>("use-verbose-mode");
118 LOG(info) << " ************************* Verbose? " << useVerboseMode;
119 if (useVerboseMode) {
120 mProcessor->useVerboseMode();
121 }
122 mProcessor->init(vect);
123 mTimer = HighResClock::now();
124 mReportTiming = ic.options().get<bool>("report-timing") || useVerboseMode;
125 }
126
128 {
129 TStopwatch sw;
130 static size_t runCount = 0;
131 const size_t logPrescale = 10;
132 if (mCheckRunStartStop) {
133 const auto* grp = mRunChecker.check(); // check if there is a run with EMC
134 // this is an example of what it will return
135 if (mRunChecker.getRunStatus() == RunStatus::NONE) {
136 if ((runCount % logPrescale) == 0) {
137 LOGP(info, "No run with is ongoing or finished");
138 }
139 } else if (mRunChecker.getRunStatus() == RunStatus::START) { // saw new run with wanted detectors
140 LOGP(info, "Run {} has started", mRunChecker.getFollowedRun());
141 grp->print();
142 mProcessor->setRunNumberFromGRP(mRunChecker.getFollowedRun());
143 } else if (mRunChecker.getRunStatus() == RunStatus::ONGOING) { // run which was already seen is still ongoing
144 if ((runCount % logPrescale) == 0) {
145 LOGP(info, "Run {} is still ongoing", mRunChecker.getFollowedRun());
146 }
147 } else if (mRunChecker.getRunStatus() == RunStatus::STOP) { // run which was already seen was stopped (EOR seen)
148 LOGP(info, "Run {} was stopped", mRunChecker.getFollowedRun());
149 }
150 runCount++;
151 } else {
152 mProcessor->setRunNumberFromGRP(-2);
153 }
154
155 // auto tfid = o2::header::get<o2::framework::DataProcessingHeader*>(pc.inputs().get("input").header)->startTime;
156 auto tfid = o2::header::get<o2::framework::DataProcessingHeader*>(pc.inputs().get("input").header)->creation;
157 auto dps = pc.inputs().get<gsl::span<DPCOM>>("input");
158 mProcessor->setTF(tfid);
159 mProcessor->process(dps);
160 auto timeNow = HighResClock::now();
161 Duration elapsedTime = timeNow - mTimer; // in seconds
162 if (elapsedTime.count() >= mDPsUpdateInterval) {
163 sendELMButput(pc.outputs());
164 mTimer = timeNow;
165 }
166 if ((mCheckRunStartStop && (mRunChecker.getRunStatus() == RunStatus::START)) || (!mCheckRunStartStop && mProcessor->isUpdateFEEcfg())) {
167 sendCFGoutput(pc.outputs());
168 }
169 sw.Stop();
170 if (mReportTiming) {
171 LOGP(info, "Timing CPU:{:.3e} Real:{:.3e} at slice {}", sw.CpuTime(), sw.RealTime(), pc.services().get<o2::framework::TimingInfo>().timeslice);
172 }
173 }
174
176 {
177 sendELMButput(ec.outputs());
178 // sendCFGoutput(ec.outputs());
179 }
180
181 private:
182 bool mReportTiming{false};
183 std::unique_ptr<EMCDCSProcessor> mProcessor;
184 HighResClock::time_point mTimer;
185 int64_t mDPsUpdateInterval;
186 bool mCheckRunStartStop = false;
188
189 //________________________________________________________________
190 void sendELMButput(DataAllocator& output)
191 {
192 // extract CCDB infos and Temperature Sensor data
193
194 mProcessor->processElmb();
195 mProcessor->updateElmbCCDBinfo();
196
197 const auto& payload = mProcessor->getELMBdata();
198 auto& info = mProcessor->getccdbELMBinfo();
199 auto image = o2::ccdb::CcdbApi::createObjectImage(&payload, &info);
200 LOG(info) << "Sending object " << info.getPath() << "/" << info.getFileName() << " of size " << image->size()
201 << " bytes, valid for " << info.getStartValidityTimestamp() << " : " << info.getEndValidityTimestamp();
202 output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBPayload, "EMC_ELMB", 0}, *image.get());
203 output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBWrapper, "EMC_ELMB", 0}, info);
204 }
205
206 //________________________________________________________________
207 void sendCFGoutput(DataAllocator& output)
208 {
209 // extract CCDB and FeeDCS info
210
211 // if (mProcessor->isUpdateFEEcfg()) {
212 mProcessor->updateFeeCCDBinfo();
213
214 const auto& payload = mProcessor->getFeeDCSdata();
215 auto& info = mProcessor->getccdbFeeDCSinfo();
216 auto image = o2::ccdb::CcdbApi::createObjectImage(&payload, &info);
217 LOG(info) << "Sending object " << info.getPath() << "/" << info.getFileName() << " of size " << image->size()
218 << " bytes, valid for " << info.getStartValidityTimestamp() << " : " << info.getEndValidityTimestamp();
219
220 output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBPayload, "EMC_FeeDCS", 0}, *image.get());
221 output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBWrapper, "EMC_FeeDCS", 0}, info);
222 // }
223 }
224
225}; // end class
226} // namespace emcal
227
228namespace framework
229{
230
231DataProcessorSpec getEMCALDCSDataProcessorSpec()
232{
233
235
236 std::vector<OutputSpec> outputs;
237 outputs.emplace_back(ConcreteDataTypeMatcher{o2::calibration::Utils::gDataOriginCDBPayload, "EMC_ELMB"}, Lifetime::Sporadic);
238 outputs.emplace_back(ConcreteDataTypeMatcher{o2::calibration::Utils::gDataOriginCDBWrapper, "EMC_ELMB"}, Lifetime::Sporadic);
239
240 outputs.emplace_back(ConcreteDataTypeMatcher{o2::calibration::Utils::gDataOriginCDBPayload, "EMC_FeeDCS"}, Lifetime::Sporadic);
241 outputs.emplace_back(ConcreteDataTypeMatcher{o2::calibration::Utils::gDataOriginCDBWrapper, "EMC_FeeDCS"}, Lifetime::Sporadic);
242
243 return DataProcessorSpec{
244 "emc-dcs-data-processor",
245 Inputs{{"input", "DCS", "EMCDATAPOINTS"}},
246 outputs,
247 AlgorithmSpec{adaptFromTask<o2::emcal::EMCALDCSDataProcessor>()},
248 Options{{"ccdb-path", VariantType::String, o2::base::NameConf::getCCDBServer(), {"Path to CCDB"}},
249 {"use-ccdb-to-configure", VariantType::Bool, false, {"Use CCDB to configure"}},
250 {"use-verbose-mode", VariantType::Bool, false, {"Use verbose mode"}},
251 {"report-timing", VariantType::Bool, false, {"Report timing for every slice"}},
252 {"follow-emcal-run", VariantType::Bool, false, {"Check EMCAL runs SOR/EOR"}},
253 {"DPs-update-interval", VariantType::Int64, 600ll, {"Interval (in s) after which to update the DPs CCDB entry"}}}};
254}
255
256} // namespace framework
257} // namespace o2
258
259#endif
Utils and constants for calibration and related workflows.
int32_t i
Header of the AggregatedRunInfo struct.
void output(const std::map< std::string, ChannelStat > &channels)
Definition rawdump.cxx:197
Definition of the Names Generator class.
static std::string getCCDBServer()
Definition NameConf.cxx:110
static BasicCCDBManager & instance()
static std::unique_ptr< std::vector< char > > createObjectImage(const T *obj, CcdbObjectInfo *info=nullptr)
Definition CcdbApi.h:103
RunStatus getRunStatus() const
const o2::parameters::GRPECSObject * check(long ts=-1)
static mask_t getMask(const std::string_view detList)
detector masks from any non-alpha-num delimiter-separated list (empty if NONE is supplied)
Definition DetID.cxx:42
void endOfStream(o2::framework::EndOfStreamContext &ec) final
This is invoked whenever we have an EndOfStream event.
void run(o2::framework::ProcessingContext &pc) final
void init(o2::framework::InitContext &ic) final
GLeglImageOES image
Definition glcorearb.h:4021
information complementary to a CCDB object (path, metadata, startTimeValidity, endTimeValidity etc)
std::vector< std::string > expandAliases(const std::vector< std::string > &patternedAliases)
std::chrono::high_resolution_clock HighResClock
std::chrono::duration< double, std::ratio< 1, 1 > > Duration
Defining PrimaryVertex explicitly as messageable.
Definition TFIDInfo.h:20
std::vector< InputSpec > Inputs
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
static constexpr o2::header::DataOrigin gDataOriginCDBWrapper
Definition Utils.h:44
static constexpr o2::header::DataOrigin gDataOriginCDBPayload
Definition Utils.h:43
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
TStopwatch sw