Skip to content

Commit 0a4d8ac

Browse files
committed
Updated the CMVContainer, corrected the timestamp range for CCDB
1 parent 5d1cc3b commit 0a4d8ac

File tree

8 files changed

+282
-187
lines changed

8 files changed

+282
-187
lines changed

Detectors/TPC/calibration/include/TPCCalibration/CMVContainer.h

Lines changed: 41 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -11,65 +11,75 @@
1111

1212
/// @file CMVContainer.h
1313
/// @author Tuba Gündem, tuba.gundem@cern.ch
14-
/// @brief Struct for storing CMVs to the CCDB
14+
/// @brief Structs for storing CMVs to the CCDB
1515

1616
#ifndef ALICEO2_TPC_CMVCONTAINER_H_
1717
#define ALICEO2_TPC_CMVCONTAINER_H_
1818

1919
#include <vector>
2020
#include <string>
2121
#include <memory>
22+
#include <stdexcept>
23+
#include <fmt/format.h>
2224

2325
#include "TTree.h"
26+
#include "DataFormatsTPC/CMV.h"
2427

2528
namespace o2::tpc
2629
{
2730

28-
/// CMVContainer: accumulator for one aggregation interval
29-
struct CMVContainer {
30-
31-
uint32_t nTFs{0}; ///< number of TFs accumulated
32-
uint32_t nCRUs{0}; ///< number of contributing CRUs
33-
long firstTF{0}; ///< first TF counter in this aggregation interval
34-
35-
std::vector<float> cmvValues{}; ///< CMV float values
36-
std::vector<uint32_t> cru{}; ///< CRU indices
37-
std::vector<uint32_t> timebin{}; ///< absolute timebins within the TF
38-
std::vector<uint32_t> tf{}; ///< TF counters
31+
/// CMV data for one TF across all CRUs
32+
struct CMVPerTF {
33+
int64_t firstOrbit{0}; ///< First orbit of this TF, from heartbeatOrbit of the first CMV packet
34+
int64_t firstBC{0}; ///< First bunch crossing of this TF, from heartbeatBC of the first CMV packet
35+
36+
/// CMV float values indexed as [CRU ID][time bin]
37+
std::vector<std::vector<float>> mDataPerTF;
38+
39+
/// Return the CMV value for a given CRU and time bin within this TF
40+
float getCMV(const int cru, const int timeBin) const
41+
{
42+
if (cru < 0 || static_cast<std::size_t>(cru) >= mDataPerTF.size()) {
43+
throw std::out_of_range(fmt::format("CMVPerTF::getCMV: cru {} out of range [0, {})", cru, mDataPerTF.size()));
44+
}
45+
if (timeBin < 0 || static_cast<uint32_t>(timeBin) >= cmv::NTimeBinsPerTF) {
46+
throw std::out_of_range(fmt::format("CMVPerTF::getCMV: timeBin {} out of range [0, {})", timeBin, cmv::NTimeBinsPerTF));
47+
}
48+
return mDataPerTF[cru][timeBin];
49+
}
50+
51+
ClassDefNV(CMVPerTF, 1)
52+
};
3953

40-
/// Pre-allocate storage for the expected number of entries: expectedTFs × expectedCRUs × NTimeBinsPerTF
41-
void reserve(uint32_t expectedTFs, uint32_t expectedCRUs);
54+
/// Container holding CMVs for one aggregation interval
55+
struct CMVPerInterval {
56+
int64_t firstTF{0}; ///< First TF counter seen in this interval
57+
int64_t lastTF{0}; ///< Last TF counter seen in this interval
4258

43-
/// Append one (cmv, cru, timebin, tf) tuple
44-
void addEntry(float cmvVal, uint32_t cruID, uint32_t tb, uint32_t tfCounter);
59+
/// CMV data, one CMVPerTF entry per TF, indexed by relative TF [0, nTimeFrames)
60+
std::vector<CMVPerTF> mCMVPerTF;
4561

46-
/// Append one full CRU packet (NTimeBinsPerPacket consecutive timebins)
47-
/// \param packet pointer to NTimeBinsPerPacket floats
48-
/// \param cruID CRU index
49-
/// \param tbOffset absolute timebin of the first sample in this packet
50-
/// \param tfCounter TF counter
51-
void addPacket(const float* packet, uint32_t cruID, uint32_t tbOffset, uint32_t tfCounter);
62+
/// Pre-allocate nTFs TF slots; each slot gets mDataPerTF resized to nCRUs entries
63+
void reserve(uint32_t nTFs, uint32_t nCRUs);
5264

53-
std::size_t size() const;
54-
bool empty() const;
65+
std::size_t size() const { return mCMVPerTF.size(); }
66+
bool empty() const { return mCMVPerTF.empty(); }
5567

5668
/// Clear all data and reset counters
5769
void clear();
5870

5971
std::string summary() const;
6072

61-
/// Build an in-memory TTree with one branch per field and one entry per tuple
73+
/// Serialise into a TTree with a single branch holding the whole CMVPerInterval object
6274
std::unique_ptr<TTree> toTTree() const;
6375

64-
/// Write the container as a TTree inside a TFile on disk
65-
/// \param filename path to the output ROOT file
66-
/// \param tree tree of the container
76+
/// Write the TTree to a ROOT file
6777
void writeToFile(const std::string& filename, const std::unique_ptr<TTree>& tree) const;
6878

69-
/// Restore a CMVContainer from a TTree previously written by toTTree()
70-
static CMVContainer fromTTree(TTree* tree, int entry = 0);
79+
/// Restore a CMVPerInterval from a TTree previously written by toTTree()
80+
static CMVPerInterval fromTTree(TTree* tree, int entry = 0);
7181

72-
ClassDefNV(CMVContainer, 1)
82+
ClassDefNV(CMVPerInterval, 1)
7383
};
7484

7585
} // namespace o2::tpc

Detectors/TPC/calibration/src/CMVContainer.cxx

Lines changed: 31 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -18,121 +18,78 @@
1818
#include "TFile.h"
1919

2020
#include "TPCCalibration/CMVContainer.h"
21-
#include "DataFormatsTPC/CMV.h"
2221

2322
namespace o2::tpc
2423
{
2524

26-
void CMVContainer::reserve(uint32_t expectedTFs, uint32_t expectedCRUs)
25+
void CMVPerInterval::reserve(uint32_t nTFs, uint32_t nCRUs)
2726
{
28-
const std::size_t n = static_cast<std::size_t>(expectedTFs) * expectedCRUs * o2::tpc::cmv::NTimeBinsPerTF;
29-
cmvValues.reserve(n);
30-
cru.reserve(n);
31-
timebin.reserve(n);
32-
tf.reserve(n);
33-
}
34-
35-
void CMVContainer::addEntry(float cmvVal, uint32_t cruID, uint32_t tb, uint32_t tfCounter)
36-
{
37-
cmvValues.push_back(cmvVal);
38-
cru.push_back(cruID);
39-
timebin.push_back(tb);
40-
tf.push_back(tfCounter);
41-
}
42-
43-
void CMVContainer::addPacket(const float* packet, uint32_t cruID, uint32_t tbOffset, uint32_t tfCounter)
44-
{
45-
for (uint32_t tb = 0; tb < o2::tpc::cmv::NTimeBinsPerPacket; ++tb) {
46-
addEntry(packet[tb], cruID, tbOffset + tb, tfCounter);
27+
mCMVPerTF.resize(nTFs);
28+
for (auto& tfData : mCMVPerTF) {
29+
tfData.mDataPerTF.resize(nCRUs);
4730
}
4831
}
4932

50-
std::size_t CMVContainer::size() const { return cmvValues.size(); }
51-
52-
bool CMVContainer::empty() const { return cmvValues.empty(); }
53-
54-
void CMVContainer::clear()
33+
void CMVPerInterval::clear()
5534
{
56-
cmvValues.clear();
57-
cru.clear();
58-
timebin.clear();
59-
tf.clear();
60-
nTFs = 0;
61-
nCRUs = 0;
35+
mCMVPerTF.clear();
6236
firstTF = 0;
37+
lastTF = 0;
6338
}
6439

65-
std::string CMVContainer::summary() const
40+
std::string CMVPerInterval::summary() const
6641
{
67-
return fmt::format("CMVContainer: {} entries, {} TFs, {} CRUs, firstTF={}",
68-
size(), nTFs, nCRUs, firstTF);
42+
const std::size_t nCRUs = empty() ? 0 : mCMVPerTF.front().mDataPerTF.size();
43+
return fmt::format("CMVPerInterval: {} TFs, {} CRU slots, firstTF={}, lastTF={}",
44+
size(), nCRUs, firstTF, lastTF);
6945
}
7046

71-
std::unique_ptr<TTree> CMVContainer::toTTree() const
47+
std::unique_ptr<TTree> CMVPerInterval::toTTree() const
7248
{
73-
const std::size_t n = size();
74-
if (n == 0) {
75-
throw std::runtime_error("CMVContainer::toTTree() called on empty container");
49+
if (empty()) {
50+
throw std::runtime_error("CMVPerInterval::toTTree() called on empty container");
7651
}
7752

7853
auto tree = std::make_unique<TTree>("ccdb_object", "ccdb_object");
7954
tree->SetAutoSave(0);
8055
tree->SetDirectory(nullptr);
8156

82-
// Point branches directly at the vector data
83-
float* pCmv = const_cast<float*>(cmvValues.data());
84-
uint32_t* pCru = const_cast<uint32_t*>(cru.data());
85-
uint32_t* pTimebin = const_cast<uint32_t*>(timebin.data());
86-
uint32_t* pTf = const_cast<uint32_t*>(tf.data());
57+
const CMVPerInterval* ptr = this;
58+
tree->Branch("CMVPerInterval", &ptr);
59+
tree->Fill();
8760

88-
tree->Branch("cmv", pCmv, fmt::format("cmv[{}]/F", n).c_str());
89-
tree->Branch("cru", pCru, fmt::format("cru[{}]/i", n).c_str());
90-
tree->Branch("timebin", pTimebin, fmt::format("timebin[{}]/i", n).c_str());
91-
tree->Branch("tf", pTf, fmt::format("tf[{}]/i", n).c_str());
61+
tree->ResetBranchAddresses();
9262

93-
tree->Fill();
9463
return tree;
9564
}
9665

97-
void CMVContainer::writeToFile(const std::string& filename, const std::unique_ptr<TTree>& tree) const
66+
void CMVPerInterval::writeToFile(const std::string& filename, const std::unique_ptr<TTree>& tree) const
9867
{
9968
TFile f(filename.c_str(), "RECREATE");
10069
if (f.IsZombie()) {
101-
throw std::runtime_error(fmt::format("CMVContainer::writeToFile: cannot open '{}'", filename));
70+
throw std::runtime_error(fmt::format("CMVPerInterval::writeToFile: cannot open '{}'", filename));
10271
}
10372
tree->Write();
10473
f.Close();
10574
}
10675

107-
CMVContainer CMVContainer::fromTTree(TTree* tree, int entry)
76+
CMVPerInterval CMVPerInterval::fromTTree(TTree* tree, int entry)
10877
{
10978
if (!tree) {
110-
throw std::runtime_error("CMVContainer::fromTTree: null TTree pointer");
111-
}
112-
113-
CMVContainer c;
114-
const Long64_t nEntries = tree->GetEntries();
115-
if (nEntries <= 0) {
116-
return c;
79+
throw std::runtime_error("CMVPerInterval::fromTTree: null TTree pointer");
11780
}
11881

119-
// Read the array branches back into vectors in one GetEntry() call
120-
std::vector<float> bCmv(nEntries);
121-
std::vector<uint32_t> bCru(nEntries), bTimebin(nEntries), bTf(nEntries);
122-
123-
tree->SetBranchAddress("cmv", bCmv.data());
124-
tree->SetBranchAddress("cru", bCru.data());
125-
tree->SetBranchAddress("timebin", bTimebin.data());
126-
tree->SetBranchAddress("tf", bTf.data());
127-
82+
CMVPerInterval* ptr = nullptr;
83+
tree->SetBranchAddress("CMVPerInterval", &ptr);
12884
tree->GetEntry(entry);
12985

130-
c.cmvValues = std::move(bCmv);
131-
c.cru = std::move(bCru);
132-
c.timebin = std::move(bTimebin);
133-
c.tf = std::move(bTf);
86+
if (!ptr) {
87+
throw std::runtime_error("CMVPerInterval::fromTTree: failed to read object from TTree");
88+
}
13489

135-
return c;
90+
CMVPerInterval result = std::move(*ptr);
91+
delete ptr;
92+
return result;
13693
}
13794

138-
} // namespace o2::tpc
95+
} // namespace o2::tpc

Detectors/TPC/calibration/src/TPCCalibrationLinkDef.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,10 @@
123123
#pragma link C++ class o2::tpc::DigitAdd + ;
124124
#pragma link C++ class std::vector < o2::tpc::DigitAdd> + ;
125125
#pragma link C++ class o2::tpc::PressureTemperatureHelper + ;
126-
#pragma link C++ class o2::tpc::CMVContainer + ;
126+
127+
#pragma link C++ class o2::tpc::CMVPerTF + ;
128+
#pragma link C++ class o2::tpc::CMVPerInterval + ;
129+
#pragma link C++ class std::vector<o2::tpc::CMVPerTF> + ;
130+
#pragma link C++ class std::vector<std::vector<float>>+;
127131

128132
#endif

0 commit comments

Comments
 (0)