Project
Loading...
Searching...
No Matches
test_ctf_io_mid.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 MIDCTFIO
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 "MIDCTF/CTFCoder.h"
25#include "DataFormatsMID/CTF.h"
26#include "Framework/Logger.h"
27#include <TFile.h>
28#include <TRandom.h>
29#include <TStopwatch.h>
30#include <TSystem.h>
31#include <cstring>
32
33using namespace o2::mid;
34namespace boost_data = boost::unit_test::data;
35
36inline std::vector<o2::ctf::ANSHeader> ANSVersions{o2::ctf::ANSVersionCompat, o2::ctf::ANSVersion1};
37
38BOOST_DATA_TEST_CASE(CTFTest, boost_data::make(ANSVersions), ansVersion)
39{
40 std::array<std::vector<ColumnData>, NEvTypes> colData{};
41 std::array<std::vector<ROFRecord>, NEvTypes> rofData{};
43 // RS: don't understand why, but this library is not loaded automatically, although the dependencies are clearly
44 // indicated. What it more weird is that for similar tests of other detectors the library is loaded!
45 // Absence of the library leads to complains about the StreamerInfo and eventually segm.faul when appending the
46 // CTH to the tree. For this reason I am loading it here manually
47 gSystem->Load("libO2DetectorsCommonDataFormats");
48 TStopwatch sw;
49 sw.Start();
51 std::array<uint16_t, 5> pattern;
52 for (int irof = 0; irof < 1000; irof++) {
53 ir += 1 + gRandom->Integer(200);
54 for (uint8_t evtyp = 0; evtyp < NEvTypes; evtyp++) {
55 if (gRandom->Rndm() > 0.8) {
56 continue; // sometimes skip some event types
57 }
58 uint8_t nch = 0;
59 while (nch == 0) {
60 nch = gRandom->Poisson(10);
61 }
62 auto start = colData[evtyp].size();
63 for (int ich = 0; ich < nch; ich++) {
64 uint8_t deId = gRandom->Integer(128);
65 uint8_t columnId = gRandom->Integer(128);
66 for (int i = 0; i < 5; i++) {
67 pattern[i] = gRandom->Integer(0x7fff);
68 }
69 colData[evtyp].emplace_back(ColumnData{deId, columnId, pattern});
70 }
71 rofData[evtyp].emplace_back(ROFRecord{ir, EventType(evtyp), start, colData[evtyp].size() - start});
72 }
73 }
74 for (uint32_t i = 0; i < NEvTypes; i++) {
75 tfData.colData[i] = {colData[i].data(), colData[i].size()};
76 tfData.rofData[i] = {rofData[i].data(), rofData[i].size()};
77 }
80
81 sw.Start();
82 std::vector<o2::ctf::BufferType> vec;
83 {
85 coder.setANSVersion(ansVersion);
86 coder.encode(vec, tfData); // compress
87 }
88 sw.Stop();
89 LOG(info) << "Compressed in " << sw.CpuTime() << " s";
90
91 // writing
92 {
93 sw.Start();
95 TFile flOut("test_ctf_mid.root", "recreate");
96 TTree ctfTree(std::string(o2::base::NameConf::CTFTREENAME).c_str(), "O2 CTF tree");
97 ctfImage->print();
98 ctfImage->appendToTree(ctfTree, "MID");
99 ctfTree.Write();
100 sw.Stop();
101 LOG(info) << "Wrote to tree in " << sw.CpuTime() << " s";
102 }
103
104 // reading
105 vec.clear();
106 {
107 sw.Start();
108 TFile flIn("test_ctf_mid.root");
109 std::unique_ptr<TTree> tree((TTree*)flIn.Get(std::string(o2::base::NameConf::CTFTREENAME).c_str()));
111 o2::mid::CTF::readFromTree(vec, *(tree.get()), "MID");
112 sw.Stop();
113 LOG(info) << "Read back from tree in " << sw.CpuTime() << " s";
114 }
115
116 std::array<std::vector<ColumnData>, NEvTypes> colDataD{};
117 std::array<std::vector<ROFRecord>, NEvTypes> rofDataD{};
118
119 sw.Start();
120 const auto ctfImage = o2::mid::CTF::getImage(vec.data());
121 {
123 coder.decode(ctfImage, rofDataD, colDataD); // decompress
124 }
125 sw.Stop();
126 LOG(info) << "Decompressed in " << sw.CpuTime() << " s";
127
128 for (uint32_t it = 0; it < NEvTypes; it++) {
129 const auto& rofsD = rofDataD[it];
130 const auto& rofs = rofData[it];
131 const auto& colsD = colDataD[it];
132 const auto& cols = colData[it];
133 LOG(info) << "Test for event type " << it;
134 BOOST_CHECK(rofsD.size() == rofs.size());
135 BOOST_CHECK(colsD.size() == cols.size());
136 LOG(info) << " BOOST_CHECK rofsD.size() " << rofsD.size() << " rofs.size() " << rofData[0].size()
137 << " BOOST_CHECK(colsD.size() " << colsD.size() << " cols.size()) " << colData[0].size();
138
139 for (size_t i = 0; i < rofs.size(); i++) {
140 const auto& dor = rofs[i];
141 const auto& ddc = rofsD[i];
142 LOG(debug) << " Orig.ROFRecord " << i << " " << dor.interactionRecord << " " << dor.firstEntry << " " << dor.nEntries;
143 LOG(debug) << " Deco.ROFRecord " << i << " " << ddc.interactionRecord << " " << ddc.firstEntry << " " << ddc.nEntries;
144
145 BOOST_CHECK(dor.interactionRecord == ddc.interactionRecord);
146 BOOST_CHECK(dor.firstEntry == ddc.firstEntry);
147 BOOST_CHECK(dor.nEntries == dor.nEntries);
148 }
149
150 for (size_t i = 0; i < cols.size(); i++) {
151 const auto& cor = cols[i];
152 const auto& cdc = colsD[i];
153 BOOST_CHECK(cor.deId == cdc.deId);
154 BOOST_CHECK(cor.columnId == cdc.columnId);
155 for (int j = 0; j < 5; j++) {
156 BOOST_CHECK(cor.patterns[j] == cdc.patterns[j]);
157 LOG(debug) << "col " << i << " pat " << j << " : " << cor.patterns[j] << " : " << cdc.patterns[j];
158 }
159 }
160 }
161}
int32_t i
Class to check if give InteractionRecord or IRFrame is selected by the external IRFrame vector.
class for entropy encoding/decoding of MID column data
Definitions for MID CTF data.
Definition of the Names Generator class.
uint32_t j
Definition RawData.h:0
uint32_t cols
std::ostringstream debug
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 CTFHelper::TFData &tfData)
entropy-encode data to buffer with CTF
Definition CTFCoder.h:60
o2::ctf::CTFIOSize decode(const CTF::base &ec, std::array< VROF, NEvTypes > &rofVec, std::array< VCOL, NEvTypes > &colVec)
entropy decode data from buffer with CTF
Definition CTFCoder.h:106
GLuint start
Definition glcorearb.h:469
constexpr ANSHeader ANSVersionCompat
Definition ANSHeader.h:54
constexpr ANSHeader ANSVersion1
Definition ANSHeader.h:55
BOOST_DATA_TEST_CASE(MID_DigitMerger, boost::unit_test::data::make(getDEList()), deId)
constexpr uint32_t NEvTypes
Definition ROFRecord.h:37
std::array< gsl::span< const o2::mid::ROFRecord >, NEvTypes > rofData
Definition CTFHelper.h:43
std::array< gsl::span< const o2::mid::ColumnData >, NEvTypes > colData
Definition CTFHelper.h:42
void buildReferences(o2::utils::IRFrameSelector &irSelector)
Definition CTFHelper.cxx:21
Column data structure for MID.
Definition ColumnData.h:29
std::vector< ROFRecord > rofsD
std::vector< o2::ctf::BufferType > vec
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::array< std::vector< ROFRecord >, NEvTypes > rofDataD
CTFHelper::TFData tfData
BOOST_CHECK(tree)
std::vector< o2::ctf::ANSHeader > ANSVersions
o2::InteractionRecord ir(0, 0)
std::array< std::vector< ROFRecord >, NEvTypes > rofData
TStopwatch sw
o2::utils::IRFrameSelector irSelector
TTree ctfTree(std::string(o2::base::NameConf::CTFTREENAME).c_str(), "O2 CTF tree")
std::array< std::vector< ColumnData >, NEvTypes > colDataD
TFile flOut("test_ctf_mid.root", "recreate")
TFile flIn("test_ctf_mid.root")
std::array< uint16_t, 5 > pattern
auto * ctfImage
std::unique_ptr< TTree > tree((TTree *) flIn.Get(std::string(o2::base::NameConf::CTFTREENAME).c_str()))