Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ class InputSpec;
class OutputSpec;
} // namespace o2::framework

namespace o2::ccdb
{
class BasicCCDBManager;
} // namespace o2::ccdb

namespace o2::tpc
{

Expand All @@ -42,6 +47,11 @@ class PressureTemperatureHelper
/// trigger checking for CCDB objects
void extractCCDBInputs(o2::framework::ProcessingContext& pc) const;

/// fetch pressure/temperature directly via a BasicCCDBManager (e.g. from O2Physics analysis tasks, outside of a
/// DPL device) and refit them. The (comparably expensive) refit is skipped if the CCDB objects did not change
/// since the last call.
void extractCCDBInputs(o2::ccdb::BasicCCDBManager& ccdb, long timestampMS);

// add required inputs
static void requestCCDBInputs(std::vector<o2::framework::InputSpec>& inputs);

Expand Down Expand Up @@ -98,7 +108,10 @@ class PressureTemperatureHelper
std::pair<std::vector<float>, std::vector<ULong64_t>> mTemperatureC; ///< temperature values C-side
int mFitIntervalMS{5 * 60 * 1000}; ///< fit interval for the temperature

ClassDefNV(PressureTemperatureHelper, 1);
const void* mLastPressureObj{}; //! last pressure object accounted for via BasicCCDBManager, for dedup only, not streamed
const void* mLastTemperatureObj{}; //! last temperature object accounted for via BasicCCDBManager, for dedup only, not streamed

ClassDefNV(PressureTemperatureHelper, 2);
};
} // namespace o2::tpc
#endif
12 changes: 12 additions & 0 deletions Detectors/TPC/calibration/include/TPCCalibration/VDriftHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ class ConcreteDataMatcher;
class InputSpec;
} // namespace o2::framework

namespace o2::ccdb
{
class BasicCCDBManager;
} // namespace o2::ccdb

namespace o2::tpc
{
class LtrCalibData;
Expand Down Expand Up @@ -63,9 +68,16 @@ class VDriftHelper
void extractCCDBInputs(o2::framework::ProcessingContext& pc, bool laser = true, bool itstpcTgl = true);
static void requestCCDBInputs(std::vector<o2::framework::InputSpec>& inputs, bool laser = true, bool itstpcTgl = true);

/// Fetch calibration objects via a BasicCCDBManager and update the VDrift accordingly (for use outside a DPL
/// device, e.g. O2Physics). Objects are only re-accounted if they actually changed since the last call.
void extractCCDBInputs(o2::ccdb::BasicCCDBManager& ccdb, long timestampMS, bool laser = false, bool itstpcTgl = true);

protected:
static void addInput(std::vector<o2::framework::InputSpec>& inputs, o2::framework::InputSpec&& isp);
bool extractTPForVDrift(VDriftCorrFact& vdrift, int64_t tsStepMS = 100 * 1000);

/// Combine the previously accounted laser/ITS-TPC-Tgl inputs, applying T/P scaling if possible, into mVD.
void updateVDrift(long currentTimeMS);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The timestamps in O2Physics that we get from the table are unsigned long (uint64_t). Might be good to change this so there isn't a problem where some values go to overflow of signed longs and switch sign.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The type used by the CCDB API is anyway long (signed), there is no point in correcting intermediate types.
But we will not have an overflow till February 2106.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Oh okay, then it's a bit weird, that the timestamp table return unsigned long, but okay.

VDriftCorrFact mVDLaser{};
VDriftCorrFact mVDTPCITSTgl{};
VDriftCorrFact mVD{};
Expand Down
22 changes: 22 additions & 0 deletions Detectors/TPC/calibration/src/PressureTemperatureHelper.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
#include "Framework/InputRecord.h"
#include "Framework/CCDBParamSpec.h"
#include "Framework/DataAllocator.h"
#include "Framework/ConcreteDataMatcher.h"
#include "CCDB/BasicCCDBManager.h"

using namespace o2::tpc;
using namespace o2::framework;
Expand All @@ -30,6 +32,26 @@ void PressureTemperatureHelper::extractCCDBInputs(ProcessingContext& pc) const
pc.inputs().get<dcs::Temperature*>("temperature");
}

void PressureTemperatureHelper::extractCCDBInputs(o2::ccdb::BasicCCDBManager& ccdb, long timestampMS)
{
// getForTimeStamp() is cheap to call every time; compare the returned pointer, not ccdb's own TTL-based cache
// validity, since ccdb only swaps in a new pointer once the content actually changes.
const auto pressurePath = CDBTypeMap.at(CDBType::CalPressure);
if (auto* pressure = ccdb.getForTimeStamp<dcs::Pressure>(pressurePath, timestampMS)) {
if (pressure != mLastPressureObj) {
accountCCDBInputs(ConcreteDataMatcher(o2::header::gDataOriginTPC, "PRESSURECCDB", 0), const_cast<dcs::Pressure*>(pressure));
mLastPressureObj = pressure;
}
}
const auto temperaturePath = CDBTypeMap.at(CDBType::CalTemperature);
if (auto* temperature = ccdb.getForTimeStamp<dcs::Temperature>(temperaturePath, timestampMS)) {
if (temperature != mLastTemperatureObj) {
accountCCDBInputs(ConcreteDataMatcher(o2::header::gDataOriginTPC, "TEMPERATURECCDB", 0), const_cast<dcs::Temperature*>(temperature));
mLastTemperatureObj = temperature;
}
}
}

bool PressureTemperatureHelper::accountCCDBInputs(const ConcreteDataMatcher& matcher, void* obj)
{
if (matcher == ConcreteDataMatcher(o2::header::gDataOriginTPC, "PRESSURECCDB", 0)) {
Expand Down
48 changes: 45 additions & 3 deletions Detectors/TPC/calibration/src/VDriftHelper.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
#include "Framework/InputRecord.h"
#include "Framework/ConcreteDataMatcher.h"
#include "Framework/TimingInfo.h"
#include "CCDB/BasicCCDBManager.h"
#include <cmath>

using namespace o2::tpc;
using namespace o2::framework;
Expand Down Expand Up @@ -147,13 +149,47 @@ void VDriftHelper::extractCCDBInputs(ProcessingContext& pc, bool laser, bool its
pc.inputs().get<o2::tpc::VDriftCorrFact*>("vdriftTgl");
}
mPTHelper.extractCCDBInputs(pc);
updateVDrift(pc.services().get<o2::framework::TimingInfo>().creation);
}

//________________________________________________________
void VDriftHelper::extractCCDBInputs(o2::ccdb::BasicCCDBManager& ccdb, long timestampMS, bool laser, bool itstpcTgl)
{
if (mForceParamDrift && mForceParamOffset) { // fixed from the command line
return;
}
if (laser && !mForceParamDrift) {
if (auto* calib = ccdb.getForTimeStamp<o2::tpc::LtrCalibData>(CDBTypeMap.at(CDBType::CalLaserTracks), timestampMS)) {
if (calib->creationTime != mVDLaser.creationTime) { // account only if this is a genuinely new object
accountLaserCalibration(calib);
}
}
}
if (itstpcTgl) {
if (auto* calib = ccdb.getForTimeStamp<o2::tpc::VDriftCorrFact>(CDBTypeMap.at(CDBType::CalVDriftTgl), timestampMS)) {
if (calib->creationTime != mVDTPCITSTgl.creationTime) { // account only if this is a genuinely new object
accountDriftCorrectionITSTPCTgl(calib);
}
}
}
mPTHelper.extractCCDBInputs(ccdb, timestampMS);
updateVDrift(timestampMS);
// unlike the ProcessingContext overload above, callers here have no isUpdated()/acknowledgeUpdate() cycle of
// their own, so consume the update ourselves -- otherwise mUpdated (set once, e.g. in the constructor, and never
// cleared) would keep re-triggering the full block above, and its logging, on every call, even with an unchanged
// CCDB object.
acknowledgeUpdate();
}

//________________________________________________________
void VDriftHelper::updateVDrift(long currentTimeMS)
{
if (mUpdated || mIsTPScalingPossible) { // there was a change
// prefer among laser and tgl VDrift the one with the latest update time
auto saveVD = mVD;

// apply TP scaling of mVD if possible
if (float tp = mPTHelper.getTP(pc.services().get<o2::framework::TimingInfo>().creation); tp > 0) {
if (float tp = mPTHelper.getTP(currentTimeMS); tp > 0) {
// try to extract refTP if needed
auto& vd = (mVDTPCITSTgl.creationTime < mVDLaser.creationTime) ? mVDLaser : mVDTPCITSTgl;
if (mForceTPScaling) {
Expand All @@ -167,7 +203,11 @@ void VDriftHelper::extractCCDBInputs(ProcessingContext& pc, bool laser, bool its
mUpdated = true;
vd.normalizeTP(tp); // keep refVDrift constant, fold the T/P scaling into the correction factor
if (vd.creationTime == saveVD.creationTime) {
LOGP(info, "VDriftHelper: Scaling VDrift from {} to {} with T/P from {} to {}", saveVD.getVDrift(), vd.getVDrift(), saveVD.refTP, vd.refTP);
// log only on a meaningful change
constexpr float RelChangeToLog = 1e-3f; // 0.1%
if (std::abs(vd.getVDrift() - saveVD.getVDrift()) > RelChangeToLog * std::abs(saveVD.getVDrift())) {
LOGP(info, "VDriftHelper: Scaling VDrift from {} to {} with T/P from {} to {}", saveVD.getVDrift(), vd.getVDrift(), saveVD.refTP, vd.refTP);
}
} else {
LOGP(info, "VDriftHelper: Init new VDrift of {} with T/P {}", vd.getVDrift(), vd.refTP);
}
Expand Down Expand Up @@ -200,7 +240,9 @@ void VDriftHelper::extractCCDBInputs(ProcessingContext& pc, bool laser, bool its
}
rep += fmt::format(" but {} imposed from command line", impos);
}
LOGP(info, "{}", rep);
if (mVD.creationTime != saveVD.creationTime) { // only log which source was (re-)selected when that choice actually changed
LOGP(info, "{}", rep);
}
}
}

Expand Down
Loading