Project
Loading...
Searching...
No Matches
test_ctf_io_emcal.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 EMCCTFIO
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>
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::emcal;
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::vector<TriggerRecord> triggers;
41 std::vector<Cell> cells;
42 // gSystem->Load("libO2DetectorsCommonDataFormats");
43 TStopwatch sw;
44 sw.Start();
46 for (int irof = 0; irof < 1000; irof++) {
47 ir += 1 + gRandom->Integer(200);
48
49 auto start = cells.size();
50 short tower = gRandom->Poisson(10);
51 while (tower < 17665) {
52 float timeCell = gRandom->Rndm() * 1500 - 600.;
53 float en = gRandom->Rndm() * 250.;
54 // In case of cell type 3 cases must be distinguished (FEE, LEDMON, TRU)
55 // In case the cell is a FEE cell the cell type is correlated with the energy
56 int readoutsource = gRandom->Integer(3); //
57 ChannelType_t chantype = ChannelType_t::HIGH_GAIN;
58 switch (readoutsource) {
59 case 0: {
60 // Cell is a FEE cell, determine cell type according to HGLG transition
61 const auto ENHGLG = o2::emcal::constants::EMCAL_HGLGTRANSITION * o2::emcal::constants::EMCAL_ADCENERGY;
62 if (en >= ENHGLG) {
63 chantype = ChannelType_t::LOW_GAIN;
64 } else {
65 chantype = ChannelType_t::HIGH_GAIN;
66 }
67 break;
68 }
69 case 1:
70 chantype = ChannelType_t::LEDMON;
71 break;
72 case 2:
73 chantype = ChannelType_t::TRU;
74 break;
75
76 default:
77 std::cerr << "Unknown type" << std::endl;
78 break;
79 }
80 cells.emplace_back(tower, en, timeCell, chantype);
81 tower += 1 + gRandom->Integer(100);
82 }
83 uint32_t trigBits = gRandom->Integer(0xFFFFFFFF); // will be converted internally to uint16_t by the coder
84 triggers.emplace_back(ir, trigBits, start, cells.size() - start);
85 }
86
87 sw.Start();
88 std::vector<o2::ctf::BufferType> vec;
89 {
91 coder.setANSVersion(ansVersion);
92 coder.encode(vec, triggers, cells); // compress
93 }
94 sw.Stop();
95 LOG(info) << "Compressed in " << sw.CpuTime() << " s";
96
97 // writing
98 {
99 sw.Start();
101 TFile flOut("test_ctf_emcal.root", "recreate");
102 TTree ctfTree(std::string(o2::base::NameConf::CTFTREENAME).c_str(), "O2 CTF tree");
103 ctfImage->print();
104 ctfImage->appendToTree(ctfTree, "EMC");
105 ctfTree.Write();
106 sw.Stop();
107 LOG(info) << "Wrote to tree in " << sw.CpuTime() << " s";
108 }
109
110 // reading
111 vec.clear();
112 {
113 sw.Start();
114 TFile flIn("test_ctf_emcal.root");
115 std::unique_ptr<TTree> tree((TTree*)flIn.Get(std::string(o2::base::NameConf::CTFTREENAME).c_str()));
117 o2::emcal::CTF::readFromTree(vec, *(tree.get()), "EMC");
118 sw.Stop();
119 LOG(info) << "Read back from tree in " << sw.CpuTime() << " s";
120 }
121
122 std::vector<TriggerRecord> triggersD;
123 std::vector<Cell> cellsD;
124
125 sw.Start();
126 const auto ctfImage = o2::emcal::CTF::getImage(vec.data());
127 {
129 coder.decode(ctfImage, triggersD, cellsD); // decompress
130 }
131 sw.Stop();
132 LOG(info) << "Decompressed in " << sw.CpuTime() << " s";
133
134 BOOST_CHECK_EQUAL(triggersD.size(), triggers.size());
136 LOG(info) << " BOOST_CHECK triggersD.size() " << triggersD.size() << " triggers.size() " << triggers.size()
137 << " BOOST_CHECK(cellsD.size() " << cellsD.size() << " cells.size()) " << cells.size();
138
139 for (size_t i = 0; i < triggers.size(); i++) {
140 const auto& dor = triggers[i];
141 const auto& ddc = triggersD[i];
142 LOG(debug) << " Orig.TriggerRecord " << i << " " << dor.getBCData() << " " << dor.getFirstEntry() << " " << dor.getNumberOfObjects();
143 LOG(debug) << " Deco.TriggerRecord " << i << " " << ddc.getBCData() << " " << ddc.getFirstEntry() << " " << ddc.getNumberOfObjects();
144
145 BOOST_CHECK_EQUAL(dor.getBCData(), ddc.getBCData());
146 BOOST_CHECK_EQUAL(dor.getNumberOfObjects(), ddc.getNumberOfObjects());
147 BOOST_CHECK_EQUAL(dor.getFirstEntry(), ddc.getFirstEntry());
148 BOOST_CHECK_EQUAL(dor.getTriggerBitsCompressed(), ddc.getTriggerBitsCompressed()); // Need to be compared to the filtered trigger bit set
149 // Check for the function getTriggerBits
150 // As the compessed version has trigger bits discarded,
151 // reference must be constructed again from compressed
152 // trigger bits. Otherwise the reconstructed object is
153 // compared to the uncompressed version and the test will
154 // obviously fail due to the bits which are removed.
155 // Therefore a copy is needed to modify the trigger bits
156 // storing only the compressed one
157 auto triggerbittest = triggers[i];
158 triggerbittest.setTriggerBitsCompressed(triggerbittest.getTriggerBitsCompressed());
159 BOOST_CHECK_EQUAL(triggerbittest.getTriggerBits(), ddc.getTriggerBits());
160 }
161
162 for (size_t i = 0; i < cells.size(); i++) {
163 const auto& cor = cells[i];
164 const auto& cdc = cellsD[i];
165 BOOST_CHECK_EQUAL(cor.getTowerIDEncoded(), cdc.getTowerIDEncoded());
166 BOOST_CHECK_EQUAL(cor.getTimeStampEncoded(), cdc.getTimeStampEncoded());
167 BOOST_CHECK_EQUAL(cor.getEnergyEncoded(), cdc.getEnergyEncoded());
168 BOOST_CHECK_EQUAL(cor.getCellTypeEncoded(), cdc.getCellTypeEncoded());
169 }
170}
Definitions for EMC CTF data.
class for entropy encoding/decoding of EMCAL data
int32_t i
BOOST_DATA_TEST_CASE(DefaultConstructorNofSamplesIsInvariant, boost::unit_test::data::make(nsamples), nofSamples)
Definition testDigit.cxx:50
Definition of the Names Generator class.
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 decode(const CTF::base &ec, VTRG &trigVec, VCELL &cellVec)
entropy decode data from buffer with CTF
Definition CTFCoder.h:134
o2::ctf::CTFIOSize encode(VEC &buff, const gsl::span< const TriggerRecord > &trigData, const gsl::span< const Cell > &cellData)
entropy-encode data to buffer with CTF
Definition CTFCoder.h:63
GLuint start
Definition glcorearb.h:469
constexpr ANSHeader ANSVersionCompat
Definition ANSHeader.h:54
constexpr ANSHeader ANSVersion1
Definition ANSHeader.h:55
ChannelType_t
Type of a raw data channel.
Definition Constants.h:33
std::vector< Cell > cells
std::vector< o2::ctf::BufferType > vec
TFile flIn("test_ctf_emcal.root")
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
BOOST_CHECK(tree)
std::vector< o2::ctf::ANSHeader > ANSVersions
o2::InteractionRecord ir(0, 0)
TStopwatch sw
std::vector< TriggerRecord > triggersD
TTree ctfTree(std::string(o2::base::NameConf::CTFTREENAME).c_str(), "O2 CTF tree")
TFile flOut("test_ctf_emcal.root", "recreate")
auto * ctfImage
std::vector< Cell > cellsD
BOOST_CHECK_EQUAL(triggersD.size(), triggers.size())
std::unique_ptr< TTree > tree((TTree *) flIn.Get(std::string(o2::base::NameConf::CTFTREENAME).c_str()))