Skip to content

Commit a06cb61

Browse files
adding helper to extract pressure and temperature from CCDB
1 parent 7c34061 commit a06cb61

File tree

6 files changed

+221
-98
lines changed

6 files changed

+221
-98
lines changed

Detectors/TPC/calibration/CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ o2_add_library(TPCCalibration
5858
src/TPCMShapeCorrection.cxx
5959
src/DigitAdd.cxx
6060
src/CorrectdEdxDistortions.cxx
61+
src/PressureTemperatureHelper.cxx
6162
PUBLIC_LINK_LIBRARIES O2::DataFormatsTPC O2::TPCBase
6263
O2::TPCReconstruction ROOT::Minuit
6364
Microsoft.GSL::GSL
@@ -115,7 +116,8 @@ o2_target_root_dictionary(TPCCalibration
115116
include/TPCCalibration/CorrMapParam.h
116117
include/TPCCalibration/TPCMShapeCorrection.h
117118
include/TPCCalibration/DigitAdd.h
118-
include/TPCCalibration/CorrectdEdxDistortions.h)
119+
include/TPCCalibration/CorrectdEdxDistortions.h
120+
include/TPCCalibration/PressureTemperatureHelper.h)
119121

120122
o2_add_test_root_macro(macro/comparePedestalsAndNoise.C
121123
PUBLIC_LINK_LIBRARIES O2::TPCBase
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
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+
/// \file PressureTemperatureHelper.h
13+
/// \brief Helper class to extract pressure and temperature
14+
/// \author Matthias Kleiner <mkleiner@ikf.uni-frankfurt.de>
15+
16+
#ifndef PRESSURETEMPERATUREHELPER_H_
17+
#define PRESSURETEMPERATUREHELPER_H_
18+
19+
#include "GPUCommonRtypes.h"
20+
#include "Headers/DataHeader.h"
21+
#include "CommonDataFormat/Pair.h"
22+
23+
namespace o2::framework
24+
{
25+
class ProcessingContext;
26+
class ConcreteDataMatcher;
27+
class InputSpec;
28+
class OutputSpec;
29+
} // namespace o2::framework
30+
31+
namespace o2::tpc
32+
{
33+
34+
class PressureTemperatureHelper
35+
{
36+
public:
37+
PressureTemperatureHelper() = default;
38+
39+
/// check for new CCDB objects
40+
bool accountCCDBInputs(const o2::framework::ConcreteDataMatcher& matcher, void* obj);
41+
42+
/// trigger checking for CCDB objects
43+
void extractCCDBInputs(o2::framework::ProcessingContext& pc) const;
44+
45+
// add required inputs
46+
static void requestCCDBInputs(std::vector<o2::framework::InputSpec>& inputs);
47+
48+
/// define outputs in case pressure and temperature will be send
49+
static void setOutputs(std::vector<o2::framework::OutputSpec>& outputs);
50+
51+
/// send temperature and pressure for given time stamp
52+
void sendPTForTS(o2::framework::ProcessingContext& pc, const uint64_t timestamp) const;
53+
54+
/// set fit interval range for temperature in ms
55+
void setFitIntervalTemp(const int fitIntervalMS) { mFitIntervalMS = fitIntervalMS; }
56+
57+
/// \brief interpolate input values for given timestamp
58+
/// \param timestamps time stamps of the data
59+
/// \param values data points
60+
/// \param timestamp time where to interpolate the values
61+
float interpolate(const std::vector<uint64_t>& timestamps, const std::vector<float>& values, uint64_t timestamp) const;
62+
63+
/// get pressure for given time stamp in ms
64+
float getPressure(const uint64_t timestamp) const { return interpolate(mPressure.second, mPressure.first, timestamp); }
65+
66+
/// get temperature for given time stamp in ms
67+
dataformats::Pair<float, float> getTemperature(const uint64_t timestamp) const { return dataformats::Pair<float, float>{interpolate(mTemperatureA.second, mTemperatureA.first, timestamp), interpolate(mTemperatureC.second, mTemperatureC.first, timestamp)}; }
68+
69+
static constexpr o2::header::DataDescription getDataDescriptionPressure() { return o2::header::DataDescription{"pressure"}; }
70+
static constexpr o2::header::DataDescription getDataDescriptionTemperature() { return o2::header::DataDescription{"temperature"}; }
71+
72+
protected:
73+
static void addInput(std::vector<o2::framework::InputSpec>& inputs, o2::framework::InputSpec&& isp);
74+
static void addOutput(std::vector<o2::framework::OutputSpec>& outputs, o2::framework::OutputSpec&& osp);
75+
76+
std::pair<std::vector<float>, std::vector<uint64_t>> mPressure; ///< pressure values for both measurements
77+
std::pair<std::vector<float>, std::vector<uint64_t>> mTemperatureA; ///< temperature values A-side
78+
std::pair<std::vector<float>, std::vector<uint64_t>> mTemperatureC; ///< temperature values C-side
79+
int mFitIntervalMS{5 * 60 * 1000}; ///< fit interval for the temperature
80+
81+
ClassDefNV(PressureTemperatureHelper, 1);
82+
};
83+
} // namespace o2::tpc
84+
#endif
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
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+
/// \file PressureTemperatureHelper.cxx
13+
/// \brief Helper class to extract pressure and temperature
14+
/// \author Matthias Kleiner <mkleiner@ikf.uni-frankfurt.de>
15+
16+
#include "TPCCalibration/PressureTemperatureHelper.h"
17+
#include "TPCBase/CDBInterface.h"
18+
#include "Framework/ProcessingContext.h"
19+
#include "DataFormatsTPC/DCS.h"
20+
#include "Framework/InputRecord.h"
21+
#include "Framework/CCDBParamSpec.h"
22+
#include "Framework/DataAllocator.h"
23+
24+
using namespace o2::tpc;
25+
using namespace o2::framework;
26+
27+
void PressureTemperatureHelper::extractCCDBInputs(ProcessingContext& pc) const
28+
{
29+
pc.inputs().get<dcs::Pressure*>("pressure");
30+
pc.inputs().get<dcs::Temperature*>("temperature");
31+
}
32+
33+
bool PressureTemperatureHelper::accountCCDBInputs(const ConcreteDataMatcher& matcher, void* obj)
34+
{
35+
if (matcher == ConcreteDataMatcher(o2::header::gDataOriginTPC, "PRESSURECCDB", 0)) {
36+
LOGP(info, "Updating pressure");
37+
const auto& pressure = ((dcs::Pressure*)obj);
38+
mPressure.second = pressure->robustPressure.time;
39+
mPressure.first = pressure->robustPressure.robustPressure;
40+
return true;
41+
}
42+
43+
if (matcher == ConcreteDataMatcher(o2::header::gDataOriginTPC, "TEMPERATURECCDB", 0)) {
44+
LOGP(info, "Updating temperature");
45+
auto temp = *(dcs::Temperature*)obj;
46+
temp.fitTemperature(o2::tpc::Side::A, mFitIntervalMS, false);
47+
temp.fitTemperature(o2::tpc::Side::C, mFitIntervalMS, false);
48+
49+
mTemperatureA.first.clear();
50+
mTemperatureC.first.clear();
51+
mTemperatureA.second.clear();
52+
mTemperatureC.second.clear();
53+
54+
for (const auto& dp : temp.statsA.data) {
55+
mTemperatureA.first.emplace_back(dp.value.mean);
56+
mTemperatureA.second.emplace_back(dp.time);
57+
}
58+
59+
for (const auto& dp : temp.statsC.data) {
60+
mTemperatureC.first.emplace_back(dp.value.mean);
61+
mTemperatureC.second.emplace_back(dp.time);
62+
}
63+
return true;
64+
}
65+
return false;
66+
}
67+
68+
void PressureTemperatureHelper::requestCCDBInputs(std::vector<InputSpec>& inputs)
69+
{
70+
addInput(inputs, {"pressure", o2::header::gDataOriginTPC, "PRESSURECCDB", 0, Lifetime::Condition, ccdbParamSpec(CDBTypeMap.at(CDBType::CalPressure), {}, 1)});
71+
addInput(inputs, {"temperature", o2::header::gDataOriginTPC, "TEMPERATURECCDB", 0, Lifetime::Condition, ccdbParamSpec(CDBTypeMap.at(CDBType::CalTemperature), {}, 1)});
72+
}
73+
74+
void PressureTemperatureHelper::addInput(std::vector<InputSpec>& inputs, InputSpec&& isp)
75+
{
76+
if (std::find(inputs.begin(), inputs.end(), isp) == inputs.end()) {
77+
inputs.emplace_back(isp);
78+
}
79+
}
80+
81+
void PressureTemperatureHelper::setOutputs(std::vector<OutputSpec>& outputs)
82+
{
83+
addOutput(outputs, {o2::header::gDataOriginTPC, o2::tpc::PressureTemperatureHelper::getDataDescriptionPressure(), 0, Lifetime::Timeframe});
84+
addOutput(outputs, {o2::header::gDataOriginTPC, o2::tpc::PressureTemperatureHelper::getDataDescriptionTemperature(), 0, Lifetime::Timeframe});
85+
}
86+
87+
void PressureTemperatureHelper::addOutput(std::vector<OutputSpec>& outputs, OutputSpec&& osp)
88+
{
89+
if (std::find(outputs.begin(), outputs.end(), osp) == outputs.end()) {
90+
outputs.emplace_back(osp);
91+
}
92+
}
93+
94+
float PressureTemperatureHelper::interpolate(const std::vector<uint64_t>& timestamps, const std::vector<float>& values, uint64_t timestamp) const
95+
{
96+
if (auto idxClosest = o2::math_utils::findClosestIndices(timestamps, timestamp)) {
97+
auto [idxLeft, idxRight] = *idxClosest;
98+
if (idxRight > idxLeft) {
99+
const uint64_t x0 = timestamps[idxLeft];
100+
const uint64_t x1 = timestamps[idxRight];
101+
const float y0 = values[idxLeft];
102+
const float y1 = values[idxRight];
103+
const float y = (y0 * (x1 - timestamp) + y1 * (timestamp - x0)) / (x1 - x0);
104+
return y;
105+
} else {
106+
return values[idxLeft];
107+
}
108+
}
109+
return 0; // this should never happen
110+
}
111+
112+
void PressureTemperatureHelper::sendPTForTS(o2::framework::ProcessingContext& pc, const uint64_t timestamp) const
113+
{
114+
const float pressure = getPressure(timestamp);
115+
const auto temp = getTemperature(timestamp);
116+
LOGP(info, "Sending pressure {}, temperature A {} and temperature C {} for timestamp {}", pressure, temp.first, temp.second, timestamp);
117+
pc.outputs().snapshot(Output{o2::header::gDataOriginTPC, o2::tpc::PressureTemperatureHelper::getDataDescriptionTemperature()}, temp);
118+
pc.outputs().snapshot(Output{o2::header::gDataOriginTPC, o2::tpc::PressureTemperatureHelper::getDataDescriptionPressure()}, pressure);
119+
}

Detectors/TPC/calibration/src/TPCCalibrationLinkDef.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,4 +122,5 @@
122122
#pragma link C++ struct o2::tpc::BoundaryPotentialIFC + ;
123123
#pragma link C++ class o2::tpc::DigitAdd + ;
124124
#pragma link C++ class std::vector < o2::tpc::DigitAdd> + ;
125+
#pragma link C++ class o2::tpc::PressureTemperatureHelper + ;
125126
#endif

Detectors/TPC/workflow/include/TPCWorkflow/TPCPressureTemperatureSpec.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ namespace o2
1919
{
2020
namespace tpc
2121
{
22-
static constexpr header::DataDescription getDataDescriptionPressure() { return header::DataDescription{"pressure"}; }
23-
static constexpr header::DataDescription getDataDescriptionTemperature() { return header::DataDescription{"temperature"}; }
2422

2523
o2::framework::DataProcessorSpec getTPCPressureTemperatureSpec();
2624

Detectors/TPC/workflow/src/TPCPressureTemperatureSpec.cxx

Lines changed: 14 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,11 @@
1616

1717
#include "TPCWorkflow/TPCPressureTemperatureSpec.h"
1818
#include "Framework/Task.h"
19-
#include "Framework/Logger.h"
2019
#include "Framework/DataProcessorSpec.h"
21-
#include "Framework/CCDBParamSpec.h"
22-
#include "TPCBase/CDBInterface.h"
2320
#include "Framework/ConfigParamRegistry.h"
2421
#include "DetectorsBase/GRPGeomHelper.h"
25-
#include "CommonDataFormat/Pair.h"
26-
#include "DataFormatsTPC/DCS.h"
2722
#include "CommonUtils/TreeStreamRedirector.h"
23+
#include "TPCCalibration/PressureTemperatureHelper.h"
2824

2925
using namespace o2::framework;
3026

@@ -41,7 +37,7 @@ class PressureTemperatureDevice : public o2::framework::Task
4137
{
4238
o2::base::GRPGeomHelper::instance().setRequest(mCCDBRequest);
4339
const int intInterval = ic.options().get<int>("fit-interval");
44-
mFitIntervalMS = intInterval * 1000;
40+
mPTHelper.setFitIntervalTemp(intInterval * 1000);
4541
const bool enableDebugTree = ic.options().get<bool>("enable-root-output");
4642
if (enableDebugTree) {
4743
mStreamer = std::make_unique<o2::utils::TreeStreamRedirector>("pt.root", "recreate");
@@ -55,111 +51,37 @@ class PressureTemperatureDevice : public o2::framework::Task
5551
}
5652
}
5753

58-
/// \brief interpolate input values for given timestamp
59-
/// \param timestamps time stamps of the data
60-
/// \param values data points
61-
/// \param timestamp time where to interpolate the values
62-
float interpolate(const std::vector<uint64_t>& timestamps, const std::vector<float>& values, uint64_t timestamp)
63-
{
64-
if (auto idxClosest = o2::math_utils::findClosestIndices(timestamps, timestamp)) {
65-
auto [idxLeft, idxRight] = *idxClosest;
66-
if (idxRight > idxLeft) {
67-
const uint64_t x0 = timestamps[idxLeft];
68-
const uint64_t x1 = timestamps[idxRight];
69-
const float y0 = values[idxLeft];
70-
const float y1 = values[idxRight];
71-
const float y = (y0 * (x1 - timestamp) + y1 * (timestamp - x0)) / (x1 - x0);
72-
return y;
73-
} else {
74-
return values[idxLeft];
75-
}
76-
}
77-
return 0; // this should never happen
78-
}
79-
8054
void run(o2::framework::ProcessingContext& pc) final
8155
{
8256
o2::base::GRPGeomHelper::instance().checkUpdates(pc);
83-
pc.inputs().get<dcs::Pressure*>("pressure");
84-
pc.inputs().get<dcs::Temperature*>("temperature");
57+
mPTHelper.extractCCDBInputs(pc);
8558
const auto orbitResetTimeMS = o2::base::GRPGeomHelper::instance().getOrbitResetTimeMS();
8659
const auto firstTFOrbit = pc.services().get<o2::framework::TimingInfo>().firstTForbit;
8760
const uint64_t timestamp = orbitResetTimeMS + firstTFOrbit * o2::constants::lhc::LHCOrbitMUS * 0.001;
88-
89-
// find closest temperature and pressure
90-
const float pressure = interpolate(mPressure.second, mPressure.first, timestamp);
91-
const float tempA = interpolate(mTemperatureA.second, mTemperatureA.first, timestamp);
92-
const float tempC = interpolate(mTemperatureC.second, mTemperatureC.first, timestamp);
61+
mPTHelper.sendPTForTS(pc, timestamp);
9362

9463
if (mStreamer) {
64+
const float pressure = mPTHelper.getPressure(timestamp);
65+
const auto temp = mPTHelper.getTemperature(timestamp);
9566
(*mStreamer) << "pt"
9667
<< "pressure=" << pressure
97-
<< "temperatureA=" << tempA
98-
<< "temperatureC=" << tempC
68+
<< "temperatureA=" << temp.first
69+
<< "temperatureC=" << temp.second
9970
<< "time=" << timestamp
10071
<< "\n";
10172
}
102-
103-
LOGP(info, "Sending pressure {}, temperature A {} and temperature C {} for timestamp {}", pressure, tempA, tempC, timestamp);
104-
pc.outputs().snapshot(Output{o2::header::gDataOriginTPC, o2::tpc::getDataDescriptionTemperature()}, dataformats::Pair<float, float>{tempA, tempC});
105-
pc.outputs().snapshot(Output{o2::header::gDataOriginTPC, o2::tpc::getDataDescriptionPressure()}, pressure);
10673
}
10774

10875
void finaliseCCDB(o2::framework::ConcreteDataMatcher& matcher, void* obj) final
10976
{
11077
o2::base::GRPGeomHelper::instance().finaliseCCDB(matcher, obj);
111-
if (matcher == ConcreteDataMatcher(o2::header::gDataOriginTPC, "PRESSURECCDB", 0)) {
112-
LOGP(info, "Updating pressure");
113-
const auto& pressure = ((dcs::Pressure*)obj);
114-
mPressure.second = pressure->robustPressure.time;
115-
mPressure.first = pressure->robustPressure.robustPressure;
116-
117-
if (mStreamer) {
118-
(*mStreamer) << "p"
119-
<< "pressureCCDB=" << pressure
120-
<< "pressure=" << mPressure
121-
<< "\n";
122-
}
123-
}
124-
125-
if (matcher == ConcreteDataMatcher(o2::header::gDataOriginTPC, "TEMPERATURECCDB", 0)) {
126-
LOGP(info, "Updating temperature");
127-
auto temp = *(dcs::Temperature*)obj;
128-
temp.fitTemperature(o2::tpc::Side::A, mFitIntervalMS, false);
129-
temp.fitTemperature(o2::tpc::Side::C, mFitIntervalMS, false);
130-
131-
mTemperatureA.first.clear();
132-
mTemperatureC.first.clear();
133-
mTemperatureA.second.clear();
134-
mTemperatureC.second.clear();
135-
136-
for (const auto& dp : temp.statsA.data) {
137-
mTemperatureA.first.emplace_back(dp.value.mean);
138-
mTemperatureA.second.emplace_back(dp.time);
139-
}
140-
141-
for (const auto& dp : temp.statsC.data) {
142-
mTemperatureC.first.emplace_back(dp.value.mean);
143-
mTemperatureC.second.emplace_back(dp.time);
144-
}
145-
146-
if (mStreamer) {
147-
(*mStreamer) << "t"
148-
<< "temperatureCCDB=" << temp
149-
<< "temperatureA=" << mTemperatureA
150-
<< "temperatureC=" << mTemperatureC
151-
<< "\n";
152-
}
153-
}
78+
mPTHelper.accountCCDBInputs(matcher, obj);
15479
}
15580

15681
private:
157-
std::shared_ptr<o2::base::GRPGeomRequest> mCCDBRequest; ///< info for CCDB request
158-
std::pair<std::vector<float>, std::vector<uint64_t>> mPressure; ///< pressure values for both measurements
159-
std::pair<std::vector<float>, std::vector<uint64_t>> mTemperatureA; ///< temperature values A-side
160-
std::pair<std::vector<float>, std::vector<uint64_t>> mTemperatureC; ///< temperature values C-side
161-
std::unique_ptr<o2::utils::TreeStreamRedirector> mStreamer; ///< debug streamer
162-
int mFitIntervalMS{5 * 60 * 1000}; ///< fit interval for the temperature
82+
PressureTemperatureHelper mPTHelper;
83+
std::shared_ptr<o2::base::GRPGeomRequest> mCCDBRequest; ///< info for CCDB request
84+
std::unique_ptr<o2::utils::TreeStreamRedirector> mStreamer; ///< debug streamer
16385
};
16486

16587
o2::framework::DataProcessorSpec getTPCPressureTemperatureSpec()
@@ -168,11 +90,8 @@ o2::framework::DataProcessorSpec getTPCPressureTemperatureSpec()
16890
std::vector<OutputSpec> outputs;
16991
o2::header::DataDescription dataDescription;
17092

171-
inputs.emplace_back("pressure", o2::header::gDataOriginTPC, "PRESSURECCDB", 0, Lifetime::Condition, ccdbParamSpec(o2::tpc::CDBTypeMap.at(o2::tpc::CDBType::CalPressure), {}, 1)); // time-dependent
172-
inputs.emplace_back("temperature", o2::header::gDataOriginTPC, "TEMPERATURECCDB", 0, Lifetime::Condition, ccdbParamSpec(o2::tpc::CDBTypeMap.at(o2::tpc::CDBType::CalTemperature), {}, 1)); // time-dependent
173-
174-
outputs.emplace_back(o2::header::gDataOriginTPC, o2::tpc::getDataDescriptionPressure(), 0, Lifetime::Timeframe);
175-
outputs.emplace_back(o2::header::gDataOriginTPC, o2::tpc::getDataDescriptionTemperature(), 0, Lifetime::Timeframe);
93+
PressureTemperatureHelper::requestCCDBInputs(inputs);
94+
PressureTemperatureHelper::setOutputs(outputs);
17695

17796
auto ccdbRequest = std::make_shared<o2::base::GRPGeomRequest>(true, // orbitResetTime
17897
false, // GRPECS=true for nHBF per TF

0 commit comments

Comments
 (0)