|
| 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 | +#include "Framework/Logger.h" |
| 13 | +#include "Framework/ControlService.h" |
| 14 | +#include "Framework/ConfigParamRegistry.h" |
| 15 | +#include "Framework/InputSpec.h" |
| 16 | +#include "Framework/Task.h" |
| 17 | +#include "CommonUtils/ConfigurableParam.h" |
| 18 | + |
| 19 | +using namespace o2::framework; |
| 20 | + |
| 21 | +void customize(std::vector<o2::framework::ConfigParamSpec>& workflowOptions) |
| 22 | +{ |
| 23 | + std::vector<o2::framework::ConfigParamSpec> options{{"configKeyValues", o2::framework::VariantType::String, "", {"Semicolon separated key=value strings ..."}}}; |
| 24 | + std::swap(workflowOptions, options); |
| 25 | +} |
| 26 | + |
| 27 | +#include "DetectorsBase/GRPGeomHelper.h" |
| 28 | +#include "CCDB/CcdbApi.h" |
| 29 | +#include "DataFormatsParameters/GRPECSObject.h" |
| 30 | + |
| 31 | +namespace o2::rct |
| 32 | +{ |
| 33 | +class RCTUpdaterSpec : public o2::framework::Task |
| 34 | +{ |
| 35 | + public: |
| 36 | + RCTUpdaterSpec(std::shared_ptr<o2::base::GRPGeomRequest> gr) : mGGCCDBRequest(gr) {} |
| 37 | + ~RCTUpdaterSpec() final = default; |
| 38 | + |
| 39 | + void init(InitContext& ic) final |
| 40 | + { |
| 41 | + o2::base::GRPGeomHelper::instance().setRequest(mGGCCDBRequest); |
| 42 | + mUpdateInterval = std::max(0.1f, ic.options().get<float>("update-interval")); |
| 43 | + auto ccdb = ic.options().get<std::string>("ccdb-server"); |
| 44 | + if (!ccdb.empty() && ccdb != "none") { |
| 45 | + mCCDBApi = std::make_unique<o2::ccdb::CcdbApi>(); |
| 46 | + mCCDBApi->init(ic.options().get<std::string>("ccdb-server")); |
| 47 | + } else { |
| 48 | + LOGP(warn, "No ccdb server provided, no RCT update will be done"); |
| 49 | + } |
| 50 | + } |
| 51 | + |
| 52 | + void run(ProcessingContext& pc) final |
| 53 | + { |
| 54 | + o2::base::GRPGeomHelper::instance().checkUpdates(pc); |
| 55 | + auto tinfo = pc.services().get<o2::framework::TimingInfo>(); |
| 56 | + if (tinfo.globalRunNumberChanged) { // do we have RCT object? |
| 57 | + const auto* grp = o2::base::GRPGeomHelper::instance().getGRPECS(); |
| 58 | + mNHBFPerTF = grp->getNHBFPerTF(); |
| 59 | + if (mNHBFPerTF < 1) { |
| 60 | + mNHBFPerTF = 32; |
| 61 | + } |
| 62 | + mRunNumber = tinfo.runNumber; |
| 63 | + mUpdateIntervalTF = uint32_t(mUpdateInterval / (mNHBFPerTF * o2::constants::lhc::LHCOrbitMUS * 1e-6)); // convert update interval in seconds to interval in TFs |
| 64 | + LOGP(info, "Will update RCT after {} TFs of {} HBFs ({}s was requested)", mUpdateIntervalTF, mNHBFPerTF, mUpdateInterval); |
| 65 | + mOrbitReset = o2::base::GRPGeomHelper::instance().getOrbitResetTimeMS(); |
| 66 | + mMinOrbit = 0xffffffff; |
| 67 | + mMaxOrbit = 0; |
| 68 | + if (grp->getRunType() == o2::parameters::GRPECS::PHYSICS || grp->getRunType() == o2::parameters::GRPECS::COSMICS) { |
| 69 | + mEnabled = true; |
| 70 | + } else { |
| 71 | + LOGP(warning, "Run {} type is {}, disabling RCT update", mRunNumber, o2::parameters::GRPECS::RunTypeNames[mRunNumber]); |
| 72 | + mEnabled = false; |
| 73 | + } |
| 74 | + if (mEnabled) { |
| 75 | + if (mCCDBApi) { |
| 76 | + auto md = mCCDBApi->retrieveHeaders("RCT/Info/RunInformation", {}, grp->getRun()); |
| 77 | + if (md.empty()) { |
| 78 | + mEnabled = false; |
| 79 | + LOGP(alarm, "RCT object is missing for {} run {}, disabling RCT updater", o2::parameters::GRPECS::RunTypeNames[grp->getRunType()], grp->getRun()); |
| 80 | + } |
| 81 | + } |
| 82 | + } |
| 83 | + } |
| 84 | + if (mEnabled) { |
| 85 | + if (tinfo.firstTForbit < mMinOrbit) { |
| 86 | + mMinOrbit = tinfo.firstTForbit; |
| 87 | + } |
| 88 | + if (tinfo.firstTForbit > mMaxOrbit) { |
| 89 | + mMaxOrbit = tinfo.firstTForbit; |
| 90 | + } |
| 91 | + if (tinfo.tfCounter > mLastTFUpdate + mUpdateIntervalTF) { // need to update |
| 92 | + mLastTFUpdate = tinfo.tfCounter; |
| 93 | + updateRCT(); |
| 94 | + } |
| 95 | + } |
| 96 | + } |
| 97 | + |
| 98 | + void endOfStream(framework::EndOfStreamContext& ec) final |
| 99 | + { |
| 100 | + if (mEnabled) { |
| 101 | + updateRCT(); |
| 102 | + mEnabled = false; |
| 103 | + } |
| 104 | + } |
| 105 | + |
| 106 | + void stop() final |
| 107 | + { |
| 108 | + if (mEnabled) { |
| 109 | + updateRCT(); |
| 110 | + mEnabled = false; |
| 111 | + } |
| 112 | + } |
| 113 | + |
| 114 | + void finaliseCCDB(framework::ConcreteDataMatcher& matcher, void* obj) final |
| 115 | + { |
| 116 | + if (o2::base::GRPGeomHelper::instance().finaliseCCDB(matcher, obj)) { |
| 117 | + return; |
| 118 | + } |
| 119 | + } |
| 120 | + |
| 121 | + void updateRCT() |
| 122 | + { |
| 123 | + std::map<std::string, std::string> mdRCT; |
| 124 | + if (mMinOrbit > mMaxOrbit) { |
| 125 | + return; |
| 126 | + } |
| 127 | + mdRCT["STF"] = std::to_string(long(mMinOrbit * o2::constants::lhc::LHCOrbitMUS * 1e-3) + mOrbitReset); |
| 128 | + mdRCT["ETF"] = std::to_string(long((mMaxOrbit + mNHBFPerTF - 1) * o2::constants::lhc::LHCOrbitMUS * 1e-3) + mOrbitReset); |
| 129 | + long startValRCT = (long)mRunNumber; |
| 130 | + long endValRCT = (long)(mRunNumber + 1); |
| 131 | + if (mCCDBApi) { |
| 132 | + int retValRCT = mCCDBApi->updateMetadata("RCT/Info/RunInformation", mdRCT, startValRCT); |
| 133 | + if (retValRCT == 0) { |
| 134 | + LOGP(info, "Updated RCT object for run {} with TF start:{} end:{}", mRunNumber, mdRCT["STF"], mdRCT["ETF"]); |
| 135 | + } else { |
| 136 | + LOGP(alarm, "Update of RCT object for run {} with TF start:{} end:{} FAILED, returned with code {}", mRunNumber, mdRCT["STF"], mdRCT["ETF"], retValRCT); |
| 137 | + } |
| 138 | + } else { |
| 139 | + LOGP(info, "CCDB update disabled, TF timestamp range is {}:{}", mdRCT["STF"], mdRCT["ETF"]); |
| 140 | + } |
| 141 | + } |
| 142 | + |
| 143 | + private: |
| 144 | + bool mEnabled = true; |
| 145 | + float mUpdateInterval = 1.; |
| 146 | + int mUpdateIntervalTF = 1; |
| 147 | + uint32_t mMinOrbit = 0xffffffff; |
| 148 | + uint32_t mMaxOrbit = 0; |
| 149 | + uint32_t mLastTFUpdate = 0; |
| 150 | + long mOrbitReset = 0; |
| 151 | + int mRunNumber = 0; |
| 152 | + int mNHBFPerTF = 32; |
| 153 | + std::shared_ptr<o2::base::GRPGeomRequest> mGGCCDBRequest; |
| 154 | + std::unique_ptr<o2::ccdb::CcdbApi> mCCDBApi; |
| 155 | +}; |
| 156 | +} // namespace o2::rct |
| 157 | + |
| 158 | +// ------------------------------------------------------------------ |
| 159 | +#include "Framework/runDataProcessing.h" |
| 160 | +#include "Framework/DataProcessorSpec.h" |
| 161 | + |
| 162 | +WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) |
| 163 | +{ |
| 164 | + WorkflowSpec specs; |
| 165 | + o2::conf::ConfigurableParam::updateFromString(configcontext.options().get<std::string>("configKeyValues")); |
| 166 | + std::vector<InputSpec> inputs{{"ctfdone", "CTF", "DONE", 0, Lifetime::Timeframe}}; |
| 167 | + auto ggRequest = std::make_shared<o2::base::GRPGeomRequest>(true, // orbitResetTime |
| 168 | + true, // GRPECS=true |
| 169 | + false, // GRPLHCIF |
| 170 | + false, // GRPMagField |
| 171 | + false, // askMatLUT |
| 172 | + o2::base::GRPGeomRequest::None, // geometry |
| 173 | + inputs, |
| 174 | + true); // query only once all objects except mag.field |
| 175 | + specs.push_back(DataProcessorSpec{ |
| 176 | + "rct-updater", |
| 177 | + inputs, |
| 178 | + {}, |
| 179 | + AlgorithmSpec{adaptFromTask<o2::rct::RCTUpdaterSpec>(ggRequest)}, |
| 180 | + Options{ |
| 181 | + {"update-interval", VariantType::Float, 1.f, {"update every ... seconds"}}, |
| 182 | + {"ccdb-server", VariantType::String, "http://ccdb-test.cern.ch:8080", {"CCDB to update"}}}}); |
| 183 | + return specs; |
| 184 | +} |
0 commit comments