Skip to content

Commit 940e41c

Browse files
committed
Added CMVContainer.cxx, fixed missing links and includes
1 parent 33e2fd0 commit 940e41c

File tree

5 files changed

+155
-111
lines changed

5 files changed

+155
-111
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/DigitAdd.cxx
5959
src/CorrectdEdxDistortions.cxx
6060
src/PressureTemperatureHelper.cxx
61+
src/CMVContainer.cxx
6162
PUBLIC_LINK_LIBRARIES O2::DataFormatsTPC O2::TPCBaseRecSim
6263
O2::TPCReconstruction ROOT::Minuit
6364
Microsoft.GSL::GSL
@@ -115,7 +116,8 @@ o2_target_root_dictionary(TPCCalibration
115116
include/TPCCalibration/TPCMShapeCorrection.h
116117
include/TPCCalibration/DigitAdd.h
117118
include/TPCCalibration/CorrectdEdxDistortions.h
118-
include/TPCCalibration/PressureTemperatureHelper.h)
119+
include/TPCCalibration/PressureTemperatureHelper.h
120+
include/TPCCalibration/CMVContainer.h)
119121

120122
o2_add_test_root_macro(macro/comparePedestalsAndNoise.C
121123
PUBLIC_LINK_LIBRARIES O2::TPCBaseRecSim

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

Lines changed: 11 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,8 @@
1919
#include <vector>
2020
#include <string>
2121
#include <memory>
22-
#include <stdexcept>
23-
24-
#include <fmt/format.h>
2522

2623
#include "TTree.h"
27-
#include "TFile.h"
28-
29-
#include "DataFormatsTPC/CMV.h"
3024

3125
namespace o2::tpc
3226
{
@@ -44,127 +38,35 @@ struct CMVContainer {
4438
std::vector<uint32_t> tf{}; ///< TF counters
4539

4640
/// Pre-allocate storage for the expected number of entries: expectedTFs × expectedCRUs × NTimeBinsPerTF
47-
void reserve(uint32_t expectedTFs, uint32_t expectedCRUs)
48-
{
49-
const std::size_t n = static_cast<std::size_t>(expectedTFs) * expectedCRUs * o2::tpc::cmv::NTimeBinsPerTF;
50-
cmvValues.reserve(n);
51-
cru.reserve(n);
52-
timebin.reserve(n);
53-
tf.reserve(n);
54-
}
41+
void reserve(uint32_t expectedTFs, uint32_t expectedCRUs);
5542

5643
/// Append one (cmv, cru, timebin, tf) tuple
57-
void addEntry(float cmvVal, uint32_t cruID, uint32_t tb, uint32_t tfCounter)
58-
{
59-
cmvValues.push_back(cmvVal);
60-
cru.push_back(cruID);
61-
timebin.push_back(tb);
62-
tf.push_back(tfCounter);
63-
}
44+
void addEntry(float cmvVal, uint32_t cruID, uint32_t tb, uint32_t tfCounter);
6445

6546
/// Append one full CRU packet (NTimeBinsPerPacket consecutive timebins)
6647
/// \param packet pointer to NTimeBinsPerPacket floats
6748
/// \param cruID CRU index
6849
/// \param tbOffset absolute timebin of the first sample in this packet
6950
/// \param tfCounter TF counter
70-
void addPacket(const float* packet, uint32_t cruID, uint32_t tbOffset, uint32_t tfCounter)
71-
{
72-
for (uint32_t tb = 0; tb < o2::tpc::cmv::NTimeBinsPerPacket; ++tb) {
73-
addEntry(packet[tb], cruID, tbOffset + tb, tfCounter);
74-
}
75-
}
51+
void addPacket(const float* packet, uint32_t cruID, uint32_t tbOffset, uint32_t tfCounter);
7652

77-
std::size_t size() const { return cmvValues.size(); }
78-
bool empty() const { return cmvValues.empty(); }
53+
std::size_t size() const;
54+
bool empty() const;
7955

8056
/// Clear all data and reset counters
81-
void clear()
82-
{
83-
cmvValues.clear();
84-
cru.clear();
85-
timebin.clear();
86-
tf.clear();
87-
nTFs = 0;
88-
nCRUs = 0;
89-
firstTF = 0;
90-
}
91-
92-
std::string summary() const
93-
{
94-
return fmt::format("CMVContainer: {} entries, {} TFs, {} CRUs, firstTF={}",
95-
size(), nTFs, nCRUs, firstTF);
96-
}
57+
void clear();
58+
59+
std::string summary() const;
9760

9861
/// Build an in-memory TTree with one branch per field and one entry per tuple
99-
std::unique_ptr<TTree> toTTree() const
100-
{
101-
const std::size_t n = size();
102-
if (n == 0) {
103-
throw std::runtime_error("CMVContainer::toTTree() called on empty container");
104-
}
105-
106-
auto tree = std::make_unique<TTree>("CMVTree", "TPC common mode values");
107-
tree->SetAutoSave(0);
108-
109-
// Point branches directly at the vector data — single Fill() call writes all rows
110-
float* pCmv = const_cast<float*>(cmvValues.data());
111-
uint32_t* pCru = const_cast<uint32_t*>(cru.data());
112-
uint32_t* pTimebin = const_cast<uint32_t*>(timebin.data());
113-
uint32_t* pTf = const_cast<uint32_t*>(tf.data());
114-
115-
tree->Branch("cmv", pCmv, fmt::format("cmv[{}]/F", n).c_str());
116-
tree->Branch("cru", pCru, fmt::format("cru[{}]/i", n).c_str());
117-
tree->Branch("timebin", pTimebin, fmt::format("timebin[{}]/i", n).c_str());
118-
tree->Branch("tf", pTf, fmt::format("tf[{}]/i", n).c_str());
119-
120-
tree->Fill();
121-
return tree;
122-
}
62+
std::unique_ptr<TTree> toTTree() const;
12363

12464
/// Write the container as a TTree inside a TFile on disk
12565
/// \param filename path to the output ROOT file
126-
void writeToFile(const std::string& filename) const
127-
{
128-
TFile f(filename.c_str(), "RECREATE");
129-
if (f.IsZombie()) {
130-
throw std::runtime_error(fmt::format("CMVContainer::writeToFile: cannot open '{}'", filename));
131-
}
132-
auto tree = toTTree();
133-
tree->Write();
134-
f.Close();
135-
}
66+
void writeToFile(const std::string& filename) const;
13667

13768
/// Restore a CMVContainer from a TTree previously written by toTTree()
138-
static CMVContainer fromTTree(TTree* tree)
139-
{
140-
if (!tree) {
141-
throw std::runtime_error("CMVContainer::fromTTree: null TTree pointer");
142-
}
143-
144-
CMVContainer c;
145-
const Long64_t nEntries = tree->GetEntries();
146-
if (nEntries <= 0) {
147-
return c;
148-
}
149-
150-
// Read the array branches back into vectors in one GetEntry() call
151-
std::vector<float> bCmv(nEntries);
152-
std::vector<uint32_t> bCru(nEntries), bTimebin(nEntries), bTf(nEntries);
153-
154-
tree->SetBranchAddress("cmv", bCmv.data());
155-
tree->SetBranchAddress("cru", bCru.data());
156-
tree->SetBranchAddress("timebin", bTimebin.data());
157-
tree->SetBranchAddress("tf", bTf.data());
158-
159-
tree->GetEntry(0);
160-
161-
c.cmvValues = std::move(bCmv);
162-
c.cru = std::move(bCru);
163-
c.timebin = std::move(bTimebin);
164-
c.tf = std::move(bTf);
165-
166-
return c;
167-
}
69+
static CMVContainer fromTTree(TTree* tree, int entry = 0);
16870

16971
ClassDefNV(CMVContainer, 1)
17072
};
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
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 CMVContainer.cxx
13+
/// @author Tuba Gündem, tuba.gundem@cern.ch
14+
15+
#include <stdexcept>
16+
#include <fmt/format.h>
17+
18+
#include "TFile.h"
19+
20+
#include "TPCCalibration/CMVContainer.h"
21+
#include "DataFormatsTPC/CMV.h"
22+
23+
namespace o2::tpc
24+
{
25+
26+
void CMVContainer::reserve(uint32_t expectedTFs, uint32_t expectedCRUs)
27+
{
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);
47+
}
48+
}
49+
50+
std::size_t CMVContainer::size() const { return cmvValues.size(); }
51+
52+
bool CMVContainer::empty() const { return cmvValues.empty(); }
53+
54+
void CMVContainer::clear()
55+
{
56+
cmvValues.clear();
57+
cru.clear();
58+
timebin.clear();
59+
tf.clear();
60+
nTFs = 0;
61+
nCRUs = 0;
62+
firstTF = 0;
63+
}
64+
65+
std::string CMVContainer::summary() const
66+
{
67+
return fmt::format("CMVContainer: {} entries, {} TFs, {} CRUs, firstTF={}",
68+
size(), nTFs, nCRUs, firstTF);
69+
}
70+
71+
std::unique_ptr<TTree> CMVContainer::toTTree() const
72+
{
73+
const std::size_t n = size();
74+
if (n == 0) {
75+
throw std::runtime_error("CMVContainer::toTTree() called on empty container");
76+
}
77+
78+
auto tree = std::make_unique<TTree>("CMVTree", "TPC common mode values");
79+
tree->SetAutoSave(0);
80+
81+
// Point branches directly at the vector data — single Fill() call writes all rows
82+
float* pCmv = const_cast<float*>(cmvValues.data());
83+
uint32_t* pCru = const_cast<uint32_t*>(cru.data());
84+
uint32_t* pTimebin = const_cast<uint32_t*>(timebin.data());
85+
uint32_t* pTf = const_cast<uint32_t*>(tf.data());
86+
87+
tree->Branch("cmv", pCmv, fmt::format("cmv[{}]/F", n).c_str());
88+
tree->Branch("cru", pCru, fmt::format("cru[{}]/i", n).c_str());
89+
tree->Branch("timebin", pTimebin, fmt::format("timebin[{}]/i", n).c_str());
90+
tree->Branch("tf", pTf, fmt::format("tf[{}]/i", n).c_str());
91+
92+
tree->Fill();
93+
return tree;
94+
}
95+
96+
void CMVContainer::writeToFile(const std::string& filename) const
97+
{
98+
TFile f(filename.c_str(), "RECREATE");
99+
if (f.IsZombie()) {
100+
throw std::runtime_error(fmt::format("CMVContainer::writeToFile: cannot open '{}'", filename));
101+
}
102+
auto tree = toTTree();
103+
tree->Write();
104+
f.Close();
105+
}
106+
107+
CMVContainer CMVContainer::fromTTree(TTree* tree, int entry)
108+
{
109+
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;
117+
}
118+
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+
128+
tree->GetEntry(entry);
129+
130+
c.cmvValues = std::move(bCmv);
131+
c.cru = std::move(bCru);
132+
c.timebin = std::move(bTimebin);
133+
c.tf = std::move(bTf);
134+
135+
return c;
136+
}
137+
138+
} // namespace o2::tpc

Detectors/TPC/calibration/src/TPCCalibrationLinkDef.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,4 +123,6 @@
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 + ;
127+
126128
#endif

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ class TPCFactorizeCMVDevice : public o2::framework::Task
155155

156156
void endOfStream(o2::framework::EndOfStreamContext& ec) final
157157
{
158-
LOGP(info, "End of stream flushing CMV container ({} entries, lane {})", mContainer.size(), mLaneId);
158+
LOGP(info, "End of stream, flushing CMV container ({} entries, lane {})", mContainer.size(), mLaneId);
159159
mContainer.nTFs = static_cast<uint32_t>(mTimeFrames);
160160
mContainer.nCRUs = static_cast<uint32_t>(mCRUs.size());
161161
sendOutput(ec.outputs());

0 commit comments

Comments
 (0)