Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AggregatedRunInfo can be requested via GRPGeomHelper + related fixes #13586

Merged
merged 4 commits into from
Oct 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CCDB/include/CCDB/BasicCCDBManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ class CCDBManagerInstance
/// On error it fatals (if fatal == true) or else returns the pair -1, -1.
std::pair<int64_t, int64_t> getRunDuration(int runnumber, bool fatal = true);
static std::pair<int64_t, int64_t> getRunDuration(o2::ccdb::CcdbApi const& api, int runnumber, bool fatal = true);

static std::pair<int64_t, int64_t> getRunDuration(const MD& headers);
std::string getSummaryString() const;

size_t getFetchedSize() const { return mFetchedSize; }
Expand Down
45 changes: 24 additions & 21 deletions CCDB/src/BasicCCDBManager.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -32,44 +32,47 @@ void CCDBManagerInstance::reportFatal(std::string_view err)
LOG(fatal) << err;
}

std::pair<int64_t, int64_t> CCDBManagerInstance::getRunDuration(o2::ccdb::CcdbApi const& api, int runnumber, bool fatal)
std::pair<int64_t, int64_t> CCDBManagerInstance::getRunDuration(const std::map<std::string, std::string>& headers)
{
auto response = api.retrieveHeaders("RCT/Info/RunInformation", std::map<std::string, std::string>(), runnumber);
if (response.size() != 0) {
if (headers.size() != 0) {
std::string report{};
auto strt = response.find("STF");
auto stop = response.find("ETF");
long valStrt = (strt == response.end()) ? -1L : boost::lexical_cast<int64_t>(strt->second);
long valStop = (stop == response.end()) ? -1L : boost::lexical_cast<int64_t>(stop->second);
auto strt = headers.find("STF");
auto stop = headers.find("ETF");
long valStrt = (strt == headers.end()) ? -1L : boost::lexical_cast<int64_t>(strt->second);
long valStop = (stop == headers.end()) ? -1L : boost::lexical_cast<int64_t>(stop->second);
if (valStrt < 0 || valStop < 0) {
report += "Missing STF/EFT -> use SOX/EOX;";
strt = response.find("SOX");
valStrt = (strt == response.end()) ? -1L : boost::lexical_cast<int64_t>(strt->second);
strt = headers.find("SOX");
valStrt = (strt == headers.end()) ? -1L : boost::lexical_cast<int64_t>(strt->second);
if (valStrt < 1) {
report += fmt::format(" Missing/invalid SOX -> use SOR");
strt = response.find("SOR");
valStrt = (strt == response.end()) ? -1L : boost::lexical_cast<int64_t>(strt->second);
strt = headers.find("SOR");
valStrt = (strt == headers.end()) ? -1L : boost::lexical_cast<int64_t>(strt->second);
}
stop = response.find("EOX");
valStop = (stop == response.end()) ? -1L : boost::lexical_cast<int64_t>(stop->second);
stop = headers.find("EOX");
valStop = (stop == headers.end()) ? -1L : boost::lexical_cast<int64_t>(stop->second);
if (valStop < 1) {
report += fmt::format(" | Missing/invalid EOX -> use EOR");
stop = response.find("EOR");
valStop = (stop == response.end()) ? -1L : boost::lexical_cast<int64_t>(stop->second);
stop = headers.find("EOR");
valStop = (stop == headers.end()) ? -1L : boost::lexical_cast<int64_t>(stop->second);
}
if (!report.empty()) {
LOGP(warn, "{}", report);
}
}
if (valStrt > 0 && valStop >= valStrt) {
return std::make_pair(valStrt, valStop);
}
return std::make_pair(valStrt, valStop);
}
// failure
if (fatal) {
return std::make_pair(-1L, -1L);
}

std::pair<int64_t, int64_t> CCDBManagerInstance::getRunDuration(o2::ccdb::CcdbApi const& api, int runnumber, bool fatal)
{
auto headers = api.retrieveHeaders("RCT/Info/RunInformation", std::map<std::string, std::string>(), runnumber);
auto response = getRunDuration(headers);
if ((response.first <= 0 || response.second < response.first) && fatal) {
LOG(fatal) << "Empty, missing or invalid response from query to RCT/Info/RunInformation for run " << runnumber;
}
return std::make_pair(-1L, -1L);
return response;
}

std::pair<int64_t, int64_t> CCDBManagerInstance::getRunDuration(int runnumber, bool fatal)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,20 @@ class GRPECSObject;
/// Also offers the authoritative algorithms to collect these information for easy reuse
/// across various algorithms (anchoredMC, analysis, ...)
struct AggregatedRunInfo {
int runNumber; // run number
int64_t sor; // best known timestamp for the start of run
int64_t eor; // best known timestamp for end of run
int64_t orbitsPerTF; // number of orbits per TF
int64_t orbitReset; // timestamp of orbit reset before run
int64_t orbitSOR; // orbit when run starts after orbit reset
int64_t orbitEOR; // orbit when run ends after orbit reset
int runNumber = 0; // run number
int64_t sor = 0; // best known timestamp for the start of run
int64_t eor = 0; // best known timestamp for end of run
int64_t orbitsPerTF = 0; // number of orbits per TF
int64_t orbitReset = 0; // timestamp of orbit reset before run
int64_t orbitSOR = 0; // orbit when run starts after orbit reset
int64_t orbitEOR = 0; // orbit when run ends after orbit reset

// we may have pointers to actual data source objects GRPECS, ...
const o2::parameters::GRPECSObject* grpECS = nullptr; // pointer to GRPECSobject (fetched during struct building)

// fills and returns AggregatedRunInfo for a given run number.
static AggregatedRunInfo buildAggregatedRunInfo(o2::ccdb::CCDBManagerInstance& ccdb, int runnumber);
static AggregatedRunInfo buildAggregatedRunInfo(int runnumber, long sorMS, long eorMS, long orbitResetMUS, const o2::parameters::GRPECSObject* grpecs, const std::vector<Long64_t>* ctfFirstRunOrbitVec);
};

} // namespace o2::parameters
Expand Down
56 changes: 26 additions & 30 deletions DataFormats/Parameters/src/AggregatedRunInfo.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -41,47 +41,43 @@ o2::parameters::AggregatedRunInfo AggregatedRunInfo::buildAggregatedRunInfo(o2::
std::map<std::string, std::string> metadata;
metadata["runNumber"] = Form("%d", runnumber);
auto grpecs = ccdb.getSpecific<o2::parameters::GRPECSObject>("GLO/Config/GRPECS", run_mid_timestamp, metadata);
auto nOrbitsPerTF = grpecs->getNHBFPerTF();

// calculate SOR orbit
int64_t orbitSOR = (sor * 1000 - tsOrbitReset) / o2::constants::lhc::LHCOrbitMUS;
int64_t orbitEOR = (eor * 1000 - tsOrbitReset) / o2::constants::lhc::LHCOrbitMUS;

// adjust to the nearest TF edge to satisfy condition (orbitSOR % nOrbitsPerTF == 0)
orbitSOR = (orbitSOR / nOrbitsPerTF + 1) * nOrbitsPerTF; // +1 to choose the safe boundary ... towards run middle
orbitEOR = orbitEOR / nOrbitsPerTF * nOrbitsPerTF;

// fetch SOR directly from CTP entry on CCDB
bool oldFatalState = ccdb.getFatalWhenNull();
ccdb.setFatalWhenNull(false);
auto ctp_first_run_orbit = ccdb.getForTimeStamp<std::vector<int64_t>>("CTP/Calib/FirstRunOrbit", run_mid_timestamp);
auto ctp_first_run_orbit = ccdb.getForTimeStamp<std::vector<Long64_t>>("CTP/Calib/FirstRunOrbit", run_mid_timestamp);
ccdb.setFatalWhenNull(oldFatalState);
if (ctp_first_run_orbit && ctp_first_run_orbit->size() >= 3) {
// if we have CTP first run orbit available, we should use it

// int64_t creation_time = (*ctp_first_run_orbit)[0];
int64_t ctp_run_number = (*ctp_first_run_orbit)[1];
int64_t ctp_orbitSOR = (*ctp_first_run_orbit)[2];
return buildAggregatedRunInfo(runnumber, sor, eor, tsOrbitReset, grpecs, ctp_first_run_orbit);
}

if (ctp_run_number == runnumber) {
// overwrite orbitSOR
o2::parameters::AggregatedRunInfo AggregatedRunInfo::buildAggregatedRunInfo(int runnumber, long sorMS, long eorMS, long orbitResetMUS, const o2::parameters::GRPECSObject* grpecs, const std::vector<Long64_t>* ctfFirstRunOrbitVec)
{
auto nOrbitsPerTF = grpecs->getNHBFPerTF();
// calculate SOR/EOR orbits
int64_t orbitSOR = (sorMS * 1000 - orbitResetMUS) / o2::constants::lhc::LHCOrbitMUS;
int64_t orbitEOR = (eorMS * 1000 - orbitResetMUS) / o2::constants::lhc::LHCOrbitMUS;
// adjust to the nearest TF edge to satisfy condition (orbitSOR % nOrbitsPerTF == 0)
orbitSOR = (orbitSOR / nOrbitsPerTF + 1) * nOrbitsPerTF; // +1 to choose the safe boundary ... towards run middle
orbitEOR = orbitEOR / nOrbitsPerTF * nOrbitsPerTF;
if (ctfFirstRunOrbitVec && ctfFirstRunOrbitVec->size() >= 3) { // if we have CTP first run orbit available, we should use it
int64_t creation_timeIGNORED = (*ctfFirstRunOrbitVec)[0]; // do not use CTP start of run time!
int64_t ctp_run_number = (*ctfFirstRunOrbitVec)[1];
int64_t ctp_orbitSOR = (*ctfFirstRunOrbitVec)[2];
if (creation_timeIGNORED == -1 && ctp_run_number == -1 && ctp_orbitSOR == -1) {
LOGP(warn, "Default dummy CTP/Calib/FirstRunOrbit was provide, ignoring");
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In case the of the CTP/Calib/FirstRunOrbit corresponds to the newly uploaded default object https://its.cern.ch/jira/browse/O2-5422 no error will be produced, just a warning.

} else if (ctp_run_number == runnumber) { // overwrite orbitSOR
if (ctp_orbitSOR != orbitSOR) {
LOG(warn) << "The calculated orbitSOR " << orbitSOR << " differs from CTP orbitSOR " << ctp_orbitSOR;
LOGP(warn, "The calculated orbitSOR {} differs from CTP orbitSOR {}", orbitSOR, ctp_orbitSOR);
// reasons for this is different unit of time storage in RunInformation (ms) and orbitReset (us), etc.

// so we need to adjust the SOR timings to be consistent
auto sor_new = (int64_t)((tsOrbitReset + ctp_orbitSOR * o2::constants::lhc::LHCOrbitMUS) / 1000.);
if (sor_new != sor) {
LOG(warn) << "Adjusting SOR from " << sor << " to " << sor_new;
sor = sor_new;
auto sor_new = (int64_t)((orbitResetMUS + ctp_orbitSOR * o2::constants::lhc::LHCOrbitMUS) / 1000.);
if (sor_new != sorMS) {
LOGP(warn, "Adjusting SOR from {} to {}", sorMS, sor_new);
sorMS = sor_new;
}
}
orbitSOR = ctp_orbitSOR;
} else {
LOG(error) << "AggregatedRunInfo: run number inconsistency found (asked: " << runnumber << " vs CTP found: " << ctp_run_number << ")";
LOG(error) << " ... not using CTP info";
LOGP(error, "AggregatedRunInfo: run number inconsistency found (asked: {} vs CTP found: {}, ignoring", runnumber, ctp_run_number);
}
}

return AggregatedRunInfo{runnumber, sor, eor, nOrbitsPerTF, tsOrbitReset, orbitSOR, orbitEOR, grpecs};
return AggregatedRunInfo{runnumber, sorMS, eorMS, nOrbitsPerTF, orbitResetMUS, orbitSOR, orbitEOR, grpecs};
}
12 changes: 9 additions & 3 deletions Detectors/Base/include/DetectorsBase/GRPGeomHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "DataFormatsParameters/GRPLHCIFData.h"
#include "DataFormatsParameters/GRPECSObject.h"
#include "DataFormatsParameters/GRPMagField.h"
#include "DataFormatsParameters/AggregatedRunInfo.h"

namespace o2::framework
{
Expand Down Expand Up @@ -92,6 +93,7 @@ struct GRPGeomRequest {
Ideal,
Alignments };

bool askAggregateRunInfo = false;
bool askGRPECS = false;
bool askGRPLHCIF = false;
bool askGRPMagField = false;
Expand All @@ -105,6 +107,7 @@ struct GRPGeomRequest {

GRPGeomRequest() = delete;
GRPGeomRequest(bool orbitResetTime, bool GRPECS, bool GRPLHCIF, bool GRPMagField, bool askMatLUT, GeomRequest geom, std::vector<o2::framework::InputSpec>& inputs, bool askOnce = false, bool needPropD = false, std::string detMaskString = "all");
void requireAggregateRunInfo(std::vector<o2::framework::InputSpec>& inputs);
void addInput(const o2::framework::InputSpec&& isp, std::vector<o2::framework::InputSpec>& inputs);
};

Expand All @@ -121,14 +124,16 @@ class GRPGeomHelper
}
void setRequest(std::shared_ptr<GRPGeomRequest> req);
bool finaliseCCDB(o2::framework::ConcreteDataMatcher& matcher, void* obj);
void checkUpdates(o2::framework::ProcessingContext& pc) const;
void checkUpdates(o2::framework::ProcessingContext& pc);

auto getAlignment(o2::detectors::DetID det) const { return mAlignments[det]; }
auto getMatLUT() const { return mMatLUT; }
auto getGRPECS() const { return mGRPECS; }
auto getGRPLHCIF() const { return mGRPLHCIF; }
auto getGRPMagField() const { return mGRPMagField; }
auto getOrbitResetTimeMS() const { return mOrbitResetTimeMS; }
auto getOrbitResetTimeMS() const { return mOrbitResetTimeMUS / 1000; }
auto getOrbitResetTimeMUS() const { return mOrbitResetTimeMUS; }
const o2::parameters::AggregatedRunInfo& getAggregatedRunInfo() const { return mAggregatedRunInfo; }
static int getNHBFPerTF();

private:
Expand All @@ -141,7 +146,8 @@ class GRPGeomHelper
const o2::parameters::GRPECSObject* mGRPECS = nullptr;
const o2::parameters::GRPLHCIFData* mGRPLHCIF = nullptr;
const o2::parameters::GRPMagField* mGRPMagField = nullptr;
long mOrbitResetTimeMS = 0; // orbit reset time in milliseconds
o2::parameters::AggregatedRunInfo mAggregatedRunInfo{};
long mOrbitResetTimeMUS = 0; // orbit reset time in microseconds
};

} // namespace base
Expand Down
32 changes: 28 additions & 4 deletions Detectors/Base/src/GRPGeomHelper.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ GRPGeomRequest::GRPGeomRequest(bool orbitResetTime, bool GRPECS, bool GRPLHCIF,
addInput({"orbitReset", "CTP", "ORBITRESET", 0, Lifetime::Condition, ccdbParamSpec("CTP/Calib/OrbitReset")}, inputs);
}
if (askGRPECS) {
addInput({"grpecs", "GLO", "GRPECS", 0, Lifetime::Condition, ccdbParamSpec("GLO/Config/GRPECS", true)}, inputs); // Run dependent !!!
addInput({"grpecs", "GLO", "GRPECS", 0, Lifetime::Condition, ccdbParamSpec("GLO/Config/GRPECS", 1)}, inputs); // Run dependent !!!
}
if (askGRPLHCIF) {
addInput({"grplhcif", "GLO", "GRPLHCIF", 0, Lifetime::Condition, ccdbParamSpec("GLO/Config/GRPLHCIF")}, inputs);
Expand All @@ -73,6 +73,22 @@ GRPGeomRequest::GRPGeomRequest(bool orbitResetTime, bool GRPECS, bool GRPLHCIF,
}
}

void GRPGeomRequest::requireAggregateRunInfo(std::vector<o2::framework::InputSpec>& inputs)
{
askAggregateRunInfo = true;
// require dependencies
if (!askGRPECS) {
askGRPECS = true;
addInput({"grpecs", "GLO", "GRPECS", 0, Lifetime::Condition, ccdbParamSpec("GLO/Config/GRPECS", 1)}, inputs);
}
if (!askTime) {
askTime = true;
addInput({"orbitReset", "CTP", "ORBITRESET", 0, Lifetime::Condition, ccdbParamSpec("CTP/Calib/OrbitReset")}, inputs);
}
addInput({"RCTRunInfo", "RCT", "RunInfo", 0, Lifetime::Condition, ccdbParamSpec("RCT/Info/RunInformation", 2)}, inputs);
addInput({"CTPRunOrbit", "CTP", "RunOrbit", 0, Lifetime::Condition, ccdbParamSpec("CTP/Calib/FirstRunOrbit")}, inputs); // TODO: should become run-depenendent (1) object
}

void GRPGeomRequest::addInput(const o2::framework::InputSpec&& isp, std::vector<o2::framework::InputSpec>& inputs)
{
if (std::find(inputs.begin(), inputs.end(), isp) == inputs.end()) {
Expand Down Expand Up @@ -124,8 +140,8 @@ bool GRPGeomHelper::finaliseCCDB(ConcreteDataMatcher& matcher, void* obj)
return true;
}
if (mRequest->askTime && matcher == ConcreteDataMatcher("CTP", "ORBITRESET", 0)) {
mOrbitResetTimeMS = (*(std::vector<Long64_t>*)obj)[0] / 1000;
LOG(info) << "orbit reset time updated to " << mOrbitResetTimeMS;
mOrbitResetTimeMUS = (*(std::vector<Long64_t>*)obj)[0];
LOG(info) << "orbit reset time updated to " << mOrbitResetTimeMUS;
return true;
}
if (mRequest->askMatLUT && matcher == ConcreteDataMatcher("GLO", "MATLUT", 0)) {
Expand Down Expand Up @@ -159,7 +175,7 @@ bool GRPGeomHelper::finaliseCCDB(ConcreteDataMatcher& matcher, void* obj)
return false;
}

void GRPGeomHelper::checkUpdates(ProcessingContext& pc) const
void GRPGeomHelper::checkUpdates(ProcessingContext& pc)
{
// request input just to trigger finaliseCCDB if there was an update

Expand Down Expand Up @@ -225,6 +241,14 @@ void GRPGeomHelper::checkUpdates(ProcessingContext& pc) const
}
}
}
if (mRequest->askAggregateRunInfo) {
const auto hmap = pc.inputs().get<o2::framework::CCDBMetadataExtractor>("RCTRunInfo"); // metadata only!
auto rl = o2::ccdb::BasicCCDBManager::getRunDuration(hmap);
auto ctfFirstRunOrbitVec = pc.inputs().get<std::vector<Long64_t>*>("CTPRunOrbit");
mAggregatedRunInfo = o2::parameters::AggregatedRunInfo::buildAggregatedRunInfo(pc.services().get<o2::framework::TimingInfo>().runNumber, rl.first, rl.second, mOrbitResetTimeMUS, mGRPECS, ctfFirstRunOrbitVec.get());
LOGP(debug, "Extracted AggregateRunInfo: runNumber:{}, sor:{}, eor:{}, orbitsPerTF:{}, orbitReset:{}, orbitSOR:{}, orbitEOR:{}",
mAggregatedRunInfo.runNumber, mAggregatedRunInfo.sor, mAggregatedRunInfo.eor, mAggregatedRunInfo.orbitsPerTF, mAggregatedRunInfo.orbitReset, mAggregatedRunInfo.orbitSOR, mAggregatedRunInfo.orbitEOR);
}
}
}

Expand Down
Loading
Loading