Project
Loading...
Searching...
No Matches
GRPDCSDPsSpec.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
13
16#include "Framework/Logger.h"
19#include "CCDB/CcdbApi.h"
20#include "CCDB/CcdbObjectInfo.h"
22#include "CCDB/CcdbApi.h"
25#include "CommonTypes/Units.h"
30#include <TStopwatch.h>
31
32namespace o2
33{
34namespace grp
35{
36
38using namespace o2::ccdb;
42using Duration = std::chrono::duration<double, std::ratio<1, 1>>;
43
45{
46
47 std::vector<DPID> vect;
48 mDPsUpdateInterval = ic.options().get<int64_t>("DPs-update-interval");
49 mWarnEmptyCycles = ic.options().get<int>("warn-empty-cycles");
50 if (mDPsUpdateInterval == 0) {
51 LOG(error) << "GRP DPs update interval set to zero seconds --> changed to 60";
52 mDPsUpdateInterval = 60;
53 }
54 bool useCCDBtoConfigure = ic.options().get<bool>("use-ccdb-to-configure");
55 if (useCCDBtoConfigure) {
56 LOG(info) << "Configuring via CCDB";
57 std::string ccdbpath = ic.options().get<std::string>("ccdb-path");
58 auto& mgr = CcdbManager::instance();
59 mgr.setURL(ccdbpath);
60 CcdbApi api;
61 api.init(mgr.getURL());
62 long ts = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
63 std::unordered_map<DPID, std::string>* dpid2DataDesc = mgr.getForTimeStamp<std::unordered_map<DPID, std::string>>("GRP/Config/DCSDPconfig", ts);
64 for (auto& i : *dpid2DataDesc) {
65 vect.push_back(i.first);
66 }
67 } else {
68 LOG(info) << "Configuring via hardcoded strings";
69 std::vector<std::string> aliasesBFieldDouble = {"L3Current", "DipoleCurrent"};
70 std::vector<std::string> aliasesBFieldBool = {"L3Polarity", "DipolePolarity"};
71 std::vector<std::string> aliasesEnvVar = {"CavernTemperature", "CavernAtmosPressure", "SurfaceAtmosPressure", "CavernAtmosPressure2"};
72 std::vector<std::string> compactAliasesLHCIFDouble = {"LHC_IntensityBeam[1..2]_totalIntensity", "ALI_Background[1..3]",
73 "ALI_Lumi_Total_Inst",
74 "BPTX_deltaT_B1_B2", "BPTX_deltaTRMS_B1_B2",
75 "BPTX_Phase_B[1..2]", "BPTX_PhaseRMS_B[1..2]", "BPTX_Phase_Shift_B[1..2]"};
76 std::vector<std::string> aliasesLHCIFDouble = o2::dcs::expandAliases(compactAliasesLHCIFDouble);
77 std::vector<std::string> aliasesLHCIFString = {"ALI_Lumi_Source_Name", "MACHINE_MODE", "BEAM_MODE"};
78 std::vector<std::string> aliasesLHCIFCollimators = {"LHC_CollimatorPos_TCLIA_4R2_lvdt_gap_downstream", "LHC_CollimatorPos_TCLIA_4R2_lvdt_gap_upstream",
79 "LHC_CollimatorPos_TCLIA_4R2_lvdt_left_downstream", "LHC_CollimatorPos_TCLIA_4R2_lvdt_left_upstream",
80 "LHC_CollimatorPos_TCLIA_4R2_lvdt_right_downstream", "LHC_CollimatorPos_TCLIA_4R2_lvdt_right_upstream"};
81
82 for (const auto& i : aliasesBFieldDouble) {
83 vect.emplace_back(i, o2::dcs::DPVAL_DOUBLE);
84 }
85 for (const auto& i : aliasesBFieldBool) {
86 vect.emplace_back(i, o2::dcs::DPVAL_BOOL);
87 }
88 for (const auto& i : aliasesEnvVar) {
89 vect.emplace_back(i, o2::dcs::DPVAL_DOUBLE);
90 }
91 for (const auto& i : aliasesLHCIFDouble) {
92 vect.emplace_back(i, o2::dcs::DPVAL_DOUBLE);
93 }
94 for (const auto& i : aliasesLHCIFCollimators) {
95 vect.emplace_back(i, o2::dcs::DPVAL_DOUBLE);
96 }
97 for (const auto& i : aliasesLHCIFString) {
98 vect.emplace_back(i, o2::dcs::DPVAL_STRING);
99 }
100 }
101
102 LOG(info) << "Listing Data Points for GRP:";
103 for (auto& i : vect) {
104 LOG(info) << i;
105 }
106
107 mProcessor = std::make_unique<o2::grp::GRPDCSDPsProcessor>();
108 mVerbose = ic.options().get<bool>("use-verbose-mode");
109 LOG(info) << " ************************* Verbose?" << mVerbose;
110 bool clearVectors = ic.options().get<bool>("clear-vectors");
111 LOG(info) << " ************************* Clear vectors?" << clearVectors;
112 if (mVerbose) {
113 mProcessor->useVerboseMode();
114 }
115 if (clearVectors) {
116 mProcessor->clearVectors();
117 }
118 mProcessor->init(vect);
119 mTimer = HighResClock::now();
120 mReportTiming = ic.options().get<bool>("report-timing") || mVerbose;
121}
122//__________________________________________________________________
123
125{
126 mLHCIFupdated = false;
127 TStopwatch sw;
128 auto startValidity = (long)(pc.services().get<o2::framework::TimingInfo>().creation);
129 auto dps = pc.inputs().get<gsl::span<DPCOM>>("input");
130 auto timeNow = HighResClock::now();
131 if (startValidity == 0xffffffffffffffff) { // it means it is not set
132 startValidity = std::chrono::duration_cast<std::chrono::milliseconds>(timeNow.time_since_epoch()).count(); // in ms
133 }
134 mProcessor->setStartValidityMagFi(startValidity);
135 if (mProcessor->getStartValidityLHCIF() == o2::ccdb::CcdbObjectInfo::INFINITE_TIMESTAMP) {
136 if (mVerbose) {
137 LOG(info) << "Change start validity for LHCIF to " << startValidity;
138 }
139 mProcessor->setStartValidityLHCIF(startValidity);
140 }
141 if (mProcessor->getStartValidityEnvVa() == o2::ccdb::CcdbObjectInfo::INFINITE_TIMESTAMP) {
142 if (mVerbose) {
143 LOG(info) << "Change start validity for Env Variables to " << startValidity;
144 }
145 mProcessor->setStartValidityEnvVa(startValidity);
146 }
147 if (mProcessor->getStartValidityColli() == o2::ccdb::CcdbObjectInfo::INFINITE_TIMESTAMP) {
148 if (mVerbose) {
149 LOG(info) << "Change start validity for Collimators to " << startValidity;
150 }
151 mProcessor->setStartValidityColli(startValidity);
152 }
153 mProcessor->process(dps);
154 Duration elapsedTime = timeNow - mTimer; // in seconds
155 if (elapsedTime.count() >= mDPsUpdateInterval || mProcessor->isLHCIFInfoUpdated()) {
156 // after enough time or after something changed, we store the LHCIF part of the DPs:
157 if (elapsedTime.count() >= mDPsUpdateInterval) {
158 if (mVerbose) {
159 LOG(info) << "enough time passed (" << elapsedTime.count() << " s), sending to CCDB LHCIFDPs";
160 }
161 } else {
162 if (mVerbose) {
163 LOG(info) << "sending to CCDB LHCIFDPs since something changed";
164 }
165 }
166 mProcessor->updateLHCIFInfoCCDB();
167 sendLHCIFDPsoutput(pc.outputs());
168 mProcessor->resetAndKeepLastLHCIFDPs();
169 mLHCIFupdated = true;
170 mProcessor->resetPIDsLHCIF();
171 }
172 if (elapsedTime.count() >= mDPsUpdateInterval) {
173 // after enough time, we store:
174 // collimators:
175 if (mVerbose) {
176 LOG(info) << "enough time passed (" << elapsedTime.count() << " s), sending to CCDB Env and Coll";
177 }
178 mProcessor->updateCollimatorsCCDB();
179 sendCollimatorsDPsoutput(pc.outputs());
180 mProcessor->resetAndKeepLast(mProcessor->getCollimatorsObj().mCollimators);
181 // env vars:
182 mProcessor->updateEnvVarsCCDB();
183 sendEnvVarsDPsoutput(pc.outputs());
184 mProcessor->resetAndKeepLast(mProcessor->getEnvVarsObj().mEnvVars);
185 mTimer = timeNow;
186 mProcessor->resetPIDs();
187 }
188 if (mProcessor->isMagFieldUpdated()) {
189 sendMagFieldDPsoutput(pc.outputs());
190 }
191 sw.Stop();
192 if (mReportTiming) {
193 LOGP(info, "Timing CPU:{:.3e} Real:{:.3e} at slice {}", sw.CpuTime(), sw.RealTime(), pc.services().get<o2::framework::TimingInfo>().timeslice);
194 }
195}
196//________________________________________________________________
197
199{
200
201 LOG(info) << " ********** End of Stream **********";
202 // we force writing to CCDB the entries for which we accumulate values in vectors (we don't do it for the B field
203 // because this is updated every time on change of any of the 4 DPs related to it)
204 if (!mLHCIFupdated) { // the last TF did not update the LHCIF CCDB entry, let's force it
205 mProcessor->updateLHCIFInfoCCDB();
206 sendLHCIFDPsoutput(ec.outputs());
207 }
208 mProcessor->updateCollimatorsCCDB();
209 sendCollimatorsDPsoutput(ec.outputs());
210
211 mProcessor->updateEnvVarsCCDB();
212 sendEnvVarsDPsoutput(ec.outputs());
213}
214
215//________________________________________________________________
216
217void GRPDCSDPsDataProcessor::sendLHCIFDPsoutput(DataAllocator& output)
218{
219 // filling CCDB with LHCIF DPs object
220
221 const auto& payload = mProcessor->getLHCIFObj();
222 auto& info = mProcessor->getccdbLHCIFInfo();
223 auto image = o2::ccdb::CcdbApi::createObjectImage(&payload, &info);
224 LOG(info) << "Sending object " << info.getPath() << "/" << info.getFileName() << " of size " << image->size()
225 << " bytes, valid for " << info.getStartValidityTimestamp() << " : " << info.getEndValidityTimestamp();
226 output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBPayload, "GRP_LHCIF_DPs", 0}, *image.get());
227 output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBWrapper, "GRP_LHCIF_DPs", 0}, info);
228 mProcessor->resetStartValidityLHCIF();
229}
230//________________________________________________________________
231
232void GRPDCSDPsDataProcessor::sendMagFieldDPsoutput(DataAllocator& output)
233{
234 // filling CCDB with B field object
235
236 const auto& payload = mProcessor->getMagFieldObj();
237 auto& info = mProcessor->getccdbMagFieldInfo();
238 auto image = o2::ccdb::CcdbApi::createObjectImage(&payload, &info);
239 LOG(info) << "Sending object " << info.getPath() << "/" << info.getFileName() << " of size " << image->size()
240 << " bytes, valid for " << info.getStartValidityTimestamp() << " : " << info.getEndValidityTimestamp();
241 output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBPayload, "GRP_Bfield", 0}, *image.get());
242 output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBWrapper, "GRP_Bfield", 0}, info);
243}
244
245//________________________________________________________________
246
247void GRPDCSDPsDataProcessor::sendCollimatorsDPsoutput(DataAllocator& output)
248{
249 // filling CCDB with Collimators object
250
251 const auto& payload = mProcessor->getCollimatorsObj();
252 if (payload.totalEntries() == 0) {
253 if ((mEmptyCyclesCollimators % size_t(mWarnEmptyCycles)) == 0) {
254 LOGP(alarm, "No Collimator DPs were received after {} {}-s cycles", mEmptyCyclesCollimators, mDPsUpdateInterval);
255 }
256 mEmptyCyclesCollimators++;
257 } else {
258 mEmptyCyclesCollimators = 0;
259 }
260 auto& info = mProcessor->getccdbCollimatorsInfo();
261 auto image = o2::ccdb::CcdbApi::createObjectImage(&payload, &info);
262 LOG(info) << "Sending object " << info.getPath() << "/" << info.getFileName() << " of size " << image->size()
263 << " bytes, valid for " << info.getStartValidityTimestamp() << " : " << info.getEndValidityTimestamp();
264 output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBPayload, "GRP_COLLIM_DPs", 0}, *image.get());
265 output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBWrapper, "GRP_COLLIM_DPs", 0}, info);
266 mProcessor->resetStartValidityColli();
267}
268
269//________________________________________________________________
270
271void GRPDCSDPsDataProcessor::sendEnvVarsDPsoutput(DataAllocator& output)
272{
273 // filling CCDB with EnvVars object
274
275 const auto& payload = mProcessor->getEnvVarsObj();
276 if (payload.totalEntries() == 0) {
277 if ((mEmptyCyclesEnvVars % size_t(mWarnEmptyCycles)) == 0) {
278 LOGP(alarm, "No EnvVar DPs were received after {} {}-s cycles", mEmptyCyclesEnvVars, mDPsUpdateInterval);
279 }
280 mEmptyCyclesEnvVars++;
281 } else {
282 mEmptyCyclesEnvVars = 0;
283 }
284 auto& info = mProcessor->getccdbEnvVarsInfo();
285 auto image = o2::ccdb::CcdbApi::createObjectImage(&payload, &info);
286 LOG(info) << "Sending object " << info.getPath() << "/" << info.getFileName() << " of size " << image->size()
287 << " bytes, valid for " << info.getStartValidityTimestamp() << " : " << info.getEndValidityTimestamp();
288 output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBPayload, "GRP_EVARS_DPs", 0}, *image.get());
289 output.snapshot(Output{o2::calibration::Utils::gDataOriginCDBWrapper, "GRP_EVARS_DPs", 0}, info);
290 mProcessor->resetStartValidityEnvVa();
291}
292
293} // namespace grp
294
295namespace framework
296{
297
298DataProcessorSpec getGRPDCSDPsDataProcessorSpec()
299{
301
302 std::vector<OutputSpec> outputs;
303 outputs.emplace_back(ConcreteDataTypeMatcher{o2::calibration::Utils::gDataOriginCDBPayload, "GRP_Bfield"}, Lifetime::Sporadic);
304 outputs.emplace_back(ConcreteDataTypeMatcher{o2::calibration::Utils::gDataOriginCDBWrapper, "GRP_Bfield"}, Lifetime::Sporadic);
305
306 outputs.emplace_back(ConcreteDataTypeMatcher{o2::calibration::Utils::gDataOriginCDBPayload, "GRP_LHCIF_DPs"}, Lifetime::Sporadic);
307 outputs.emplace_back(ConcreteDataTypeMatcher{o2::calibration::Utils::gDataOriginCDBWrapper, "GRP_LHCIF_DPs"}, Lifetime::Sporadic);
308
309 outputs.emplace_back(ConcreteDataTypeMatcher{o2::calibration::Utils::gDataOriginCDBPayload, "GRP_COLLIM_DPs"}, Lifetime::Sporadic);
310 outputs.emplace_back(ConcreteDataTypeMatcher{o2::calibration::Utils::gDataOriginCDBWrapper, "GRP_COLLIM_DPs"}, Lifetime::Sporadic);
311
312 outputs.emplace_back(ConcreteDataTypeMatcher{o2::calibration::Utils::gDataOriginCDBPayload, "GRP_EVARS_DPs"}, Lifetime::Sporadic);
313 outputs.emplace_back(ConcreteDataTypeMatcher{o2::calibration::Utils::gDataOriginCDBWrapper, "GRP_EVARS_DPs"}, Lifetime::Sporadic);
314
315 return DataProcessorSpec{
316 "grp-dcs-data-processor",
317 Inputs{{"input", "DCS", "GRPDATAPOINTS"}},
318 outputs,
319 AlgorithmSpec{adaptFromTask<o2::grp::GRPDCSDPsDataProcessor>()},
320 Options{{"ccdb-path", VariantType::String, "http://localhost:8080", {"Path to CCDB"}},
321 {"use-ccdb-to-configure", VariantType::Bool, false, {"Use CCDB to configure"}},
322 {"use-verbose-mode", VariantType::Bool, false, {"Use verbose mode"}},
323 {"report-timing", VariantType::Bool, false, {"Report timing for every slice"}},
324 {"DPs-update-interval", VariantType::Int64, 600ll, {"Interval (in s) after which to update the DPs CCDB entry"}},
325 {"warn-empty-cycles", VariantType::Int, 1, {"Warn about empty object after this number of cycles"}},
326 {"clear-vectors", VariantType::Bool, false, {"Clear vectors when starting processing for a new CCDB entry (latest value will not be kept)"}}}};
327}
328
329} // namespace framework
330} // namespace o2
Utils and constants for calibration and related workflows.
int32_t i
void output(const std::map< std::string, ChannelStat > &channels)
Definition rawdump.cxx:197
Header to collect definitions for different units.
static BasicCCDBManager & instance()
void init(std::string const &hosts)
Definition CcdbApi.cxx:165
static std::unique_ptr< std::vector< char > > createObjectImage(const T *obj, CcdbObjectInfo *info=nullptr)
Definition CcdbApi.h:103
static constexpr long INFINITE_TIMESTAMP
ConfigParamRegistry const & options()
Definition InitContext.h:33
decltype(auto) get(R binding, int part=0) const
DataAllocator & outputs()
The data allocator is used to allocate memory for the output data.
InputRecord & inputs()
The inputs associated with this processing context.
ServiceRegistryRef services()
The services registry associated with this processing context.
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::vector< InputSpec > Inputs
std::chrono::duration< double, std::ratio< 1, 1 > > Duration
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