Project
Loading...
Searching...
No Matches
test_ctf_io_tpc.cxx
Go to the documentation of this file.
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#define BOOST_TEST_MODULE Test TPCCTFIO
13#define BOOST_TEST_MAIN
14#define BOOST_TEST_DYN_LINK
15
16#undef NDEBUG
17#include <cassert>
18
19#include <boost/test/unit_test.hpp>
20#include <boost/test/data/test_case.hpp>
21#include <boost/test/data/dataset.hpp>
24#include "DataFormatsTPC/CTF.h"
27#include "Framework/Logger.h"
28#include <TFile.h>
29#include <TRandom.h>
30#include <TStopwatch.h>
31#include <cstring>
32
33using namespace o2::tpc;
34namespace boost_data = boost::unit_test::data;
35
36inline std::vector<o2::ctf::ANSHeader> ANSVersions{o2::ctf::ANSVersionCompat, o2::ctf::ANSVersion1};
37inline std::vector<bool> CombineColumns(true, false);
38
39BOOST_DATA_TEST_CASE(CTFTest, boost_data::make(ANSVersions) ^ boost_data::make(CombineColumns), ansVersion, combineColumns)
40{
41 std::vector<o2::tpc::TriggerInfoDLBZS> triggers, triggersR;
44 c.nUnattachedClusters = 88;
45 c.nAttachedClustersReduced = 77;
46 c.nTracks = 66;
47
48 triggers.emplace_back();
49 triggers.back().orbit = 1234;
50 triggers.back().triggerWord.triggerEntries[0] = (10 & 0xFFF) | ((o2::tpc::TriggerWordDLBZS::TriggerType::PhT & 0x7) << 12) | 0x8000;
51 triggers.back().triggerWord.triggerEntries[1] = (30 & 0xFFF) | ((o2::tpc::TriggerWordDLBZS::TriggerType::PP & 0x7) << 12) | 0x8000;
52 triggers.emplace_back();
53 triggers.back().orbit = 1236;
54 triggers.back().triggerWord.triggerEntries[0] = (40 & 0xFFF) | ((o2::tpc::TriggerWordDLBZS::TriggerType::Cal & 0x7) << 12) | 0x8000;
55
56 std::vector<char> bVec;
57 CompressedClustersFlat* ccFlat = nullptr;
58 size_t sizeCFlatBody = CTFCoder::alignSize(ccFlat);
59 size_t sz = sizeCFlatBody + CTFCoder::estimateSize(c);
60 bVec.resize(sz);
61 ccFlat = reinterpret_cast<CompressedClustersFlat*>(bVec.data());
62 auto buff = reinterpret_cast<void*>(reinterpret_cast<char*>(bVec.data()) + sizeCFlatBody);
63 {
65 coder.setCompClusAddresses(c, buff);
66 coder.setCombineColumns(combineColumns);
67 }
68 ccFlat->set(sz, c);
69
70 // fill some data
71 for (int i = 0; i < c.nUnattachedClusters; i++) {
72 c.qTotU[i] = i;
73 c.qMaxU[i] = i;
74 c.flagsU[i] = i;
75 c.padDiffU[i] = i;
76 c.timeDiffU[i] = i;
77 c.sigmaPadU[i] = i;
78 c.sigmaTimeU[i] = i;
79 }
80 for (int i = 0; i < c.nAttachedClusters; i++) {
81 c.qTotA[i] = i;
82 c.qMaxA[i] = i;
83 c.flagsA[i] = i;
84 c.sigmaPadA[i] = i;
85 c.sigmaTimeA[i] = i;
86 }
87 for (int i = 0; i < c.nAttachedClustersReduced; i++) {
88 c.rowDiffA[i] = i;
89 c.sliceLegDiffA[i] = i;
90 c.padResA[i] = i;
91 c.timeResA[i] = i;
92 }
93 for (int i = 0; i < c.nTracks; i++) {
94 c.qPtA[i] = i;
95 c.rowA[i] = i;
96 c.sliceA[i] = i;
97 c.timeA[i] = i;
98 c.padA[i] = i;
99 c.nTrackClusters[i] = i;
100 }
101 for (int i = 0; i < c.nSliceRows; i++) {
102 c.nSliceRowClusters[i] = i;
103 }
104
105 TStopwatch sw;
106 sw.Start();
107 std::vector<o2::ctf::BufferType> vecIO;
108 {
110 coder.setCombineColumns(combineColumns);
111 coder.setANSVersion(ansVersion);
112 // prepare trigger info
114 for (const auto& trig : triggers) {
115 for (int it = 0; it < o2::tpc::TriggerWordDLBZS::MaxTriggerEntries; it++) {
116 if (trig.triggerWord.isValid(it)) {
117 trigComp.deltaOrbit.push_back(trig.orbit);
118 trigComp.deltaBC.push_back(trig.triggerWord.getTriggerBC(it));
119 trigComp.triggerType.push_back(trig.triggerWord.getTriggerType(it));
120 } else {
121 break;
122 }
123 }
124 }
125 // transform trigger info to differential form
126 uint32_t prevOrbit = -1;
127 uint16_t prevBC = -1;
128 if (trigComp.triggerType.size()) {
129 prevOrbit = trigComp.firstOrbit = trigComp.deltaOrbit[0];
130 prevBC = trigComp.deltaBC[0];
131 trigComp.deltaOrbit[0] = 0;
132 for (size_t it = 1; it < trigComp.triggerType.size(); it++) {
133 if (trigComp.deltaOrbit[it] == prevOrbit) {
134 auto bc = trigComp.deltaBC[it];
135 trigComp.deltaBC[it] -= prevBC;
136 prevBC = bc;
137 trigComp.deltaOrbit[it] = 0;
138 } else {
139 auto orb = trigComp.deltaOrbit[it];
140 trigComp.deltaOrbit[it] -= prevOrbit;
141 prevOrbit = orb;
142 }
143 }
144 }
145 coder.encode(vecIO, c, c, trigComp); // compress
146 }
147 sw.Stop();
148 LOG(info) << "Compressed in " << sw.CpuTime() << " s";
149
150 // writing
151 {
152 sw.Start();
153 TFile flOut("test_ctf_tpc.root", "recreate");
154 TTree ctfTree(std::string(o2::base::NameConf::CTFTREENAME).c_str(), "O2 CTF tree");
155 auto* ctfImage = o2::tpc::CTF::get(vecIO.data());
156 ctfImage->print();
157 ctfImage->appendToTree(ctfTree, "TPC");
158 ctfTree.Write();
159 sw.Stop();
160 LOG(info) << "Wrote to tree in " << sw.CpuTime() << " s";
161 }
162
163 // reading
164 vecIO.clear();
165 {
166 sw.Start();
167 TFile flIn("test_ctf_tpc.root");
168 std::unique_ptr<TTree> tree((TTree*)flIn.Get(std::string(o2::base::NameConf::CTFTREENAME).c_str()));
170 o2::tpc::CTF::readFromTree(vecIO, *(tree.get()), "TPC");
171 sw.Stop();
172 LOG(info) << "Read back from tree in " << sw.CpuTime() << " s";
173 }
174
175 std::vector<char> vecIn;
176 sw.Start();
177 const auto ctfImage = o2::tpc::CTF::getImage(vecIO.data());
178 {
180 coder.setCombineColumns(true);
181 coder.decode(ctfImage, vecIn, triggersR); // decompress
182 }
183 sw.Stop();
184 LOG(info) << "Decompressed in " << sw.CpuTime() << " s";
185 //
186 // compare with original flat clusters
187 BOOST_CHECK(vecIn.size() == bVec.size());
188 const CompressedClustersCounters* countOrig = reinterpret_cast<const CompressedClustersCounters*>(bVec.data());
189 const CompressedClustersCounters* countDeco = reinterpret_cast<const CompressedClustersCounters*>(vecIn.data());
190 BOOST_CHECK(countOrig->nTracks == countDeco->nTracks);
191 BOOST_CHECK(countOrig->nAttachedClusters == countDeco->nAttachedClusters);
192 BOOST_CHECK(countOrig->nUnattachedClusters == countDeco->nUnattachedClusters);
194 BOOST_CHECK(countOrig->nSliceRows == countDeco->nSliceRows);
195 BOOST_CHECK(countOrig->nComppressionModes == countDeco->nComppressionModes);
196 BOOST_CHECK(countOrig->solenoidBz == countDeco->solenoidBz);
197 BOOST_CHECK(countOrig->maxTimeBin == countDeco->maxTimeBin);
198 BOOST_CHECK(memcmp(vecIn.data() + sizeof(o2::tpc::CompressedClustersCounters), bVec.data() + sizeof(o2::tpc::CompressedClustersCounters), bVec.size() - sizeof(o2::tpc::CompressedClustersCounters)) == 0);
199 BOOST_CHECK(triggers.size() == triggersR.size());
200 BOOST_CHECK(memcmp(triggers.data(), triggersR.data(), triggers.size() * sizeof(o2::tpc::TriggerInfoDLBZS)) == 0);
201}
Container to store compressed TPC cluster data.
uint64_t bc
Definition RawEventData.h:5
int32_t i
Definition of the Names Generator class.
uint32_t c
Definition RawData.h:2
Definitions for TPC CTF data.
class for entropy encoding/decoding of TPC compressed clusters data
Definitions of TPC Zero Suppression Data Headers.
static constexpr std::string_view CTFTREENAME
Definition NameConf.h:95
void setANSVersion(const ctf::ANSHeader &ansVersion) noexcept
void readFromTree(TTree &tree, const std::string &name, int ev=0)
read from tree to non-flat object
static auto get(void *head)
cast arbitrary buffer head to container class. Head is supposed to respect the alignment
static auto getImage(const void *newHead)
get const image of the container wrapper, with pointers in the image relocated to new head
o2::ctf::CTFIOSize encode(VEC &buff, const CompressedClusters &ccl, const CompressedClusters &cclFiltered, const detail::TriggerInfo &trigComp, std::vector< bool > *rejectHits=nullptr, std::vector< bool > *rejectTracks=nullptr, std::vector< bool > *rejectTrackHits=nullptr, std::vector< bool > *rejectTrackHitsReduced=nullptr)
entropy-encode compressed clusters to flat buffer
Definition CTFCoder.h:184
o2::ctf::CTFIOSize decode(const CTF::base &ec, VEC &buff, TRIGVEC &buffTrig)
decode entropy-encoded bloks to TPC CompressedClusters into the externally provided vector (e....
Definition CTFCoder.h:325
void setCombineColumns(bool v)
Definition CTFCoder.h:162
static size_t alignSize(T *&var, size_t n=1)
Definition CTFCoder.h:144
static size_t estimateSize(CompressedClusters &c)
estimate size needed to store in the flat buffer the payload of the CompressedClusters (here only the...
Definition CTFCoder.cxx:22
static void setCompClusAddresses(CompressedClusters &c, void *&buff)
set addresses of the CompressedClusters fields to point on already reserved memory region
Definition CTFCoder.cxx:58
constexpr ANSHeader ANSVersionCompat
Definition ANSHeader.h:54
constexpr ANSHeader ANSVersion1
Definition ANSHeader.h:55
Global TPC definitions and constants.
Definition SimTraits.h:167
void set(size_t bufferSize, const CompressedClusters &v)
Trigger info including the orbit.
static constexpr uint16_t MaxTriggerEntries
Maximum number of trigger information.
@ Cal
Laser (Calibration trigger)
@ PP
Pre Pulse for calibration.
std::vector< int32_t > deltaOrbit
Definition CTFCoder.h:45
std::vector< int16_t > deltaBC
Definition CTFCoder.h:46
std::vector< uint8_t > triggerType
Definition CTFCoder.h:47
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
TFile flIn("test_ctf_cpv.root")
BOOST_CHECK(tree)
TStopwatch sw
TTree ctfTree(std::string(o2::base::NameConf::CTFTREENAME).c_str(), "O2 CTF tree")
auto * ctfImage
std::unique_ptr< TTree > tree((TTree *) flIn.Get(std::string(o2::base::NameConf::CTFTREENAME).c_str()))
TFile flOut("test_ctf_cpv.root", "recreate")
BOOST_DATA_TEST_CASE(CTFTest, boost_data::make(ANSVersions) ^ boost_data::make(CombineColumns), ansVersion, combineColumns)
std::vector< bool > CombineColumns(true, false)
std::vector< o2::ctf::ANSHeader > ANSVersions