Project
Loading...
Searching...
No Matches
test_ctf_io_ft0.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 FT0CTFIO
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 "FT0Base/FT0DigParam.h"
25#include "Framework/Logger.h"
26#include <TFile.h>
27#include <TRandom.h>
28#include <TStopwatch.h>
29#include <cstring>
30
31using namespace o2::ft0;
32namespace boost_data = boost::unit_test::data;
33
34inline std::vector<o2::ctf::ANSHeader> ANSVersions{o2::ctf::ANSVersionCompat, o2::ctf::ANSVersion1};
35
36BOOST_DATA_TEST_CASE(CTFTest, boost_data::make(ANSVersions), ansVersion)
37{
38 std::vector<Digit> digits;
39 std::vector<ChannelData> channels;
40 TStopwatch sw;
41 sw.Start();
43
44 int trg_gate = FT0DigParam::Instance().mTime_trg_gate;
46 for (int idig = 0; idig < 1000; idig++) {
47 ir += 1 + gRandom->Integer(200);
48 uint8_t ich = gRandom->Poisson(10);
49 auto start = channels.size();
50 int16_t tMeanA = 0, tMeanC = 0;
51 int32_t ampTotA = 0, ampTotC = 0;
52 int8_t nChanA = 0, nChanC = 0;
53 uint8_t eventFlag = 10;
54 while (ich < MAXChan) {
55 int16_t t = -2048 + gRandom->Integer(2048 * 2);
56 uint16_t q = gRandom->Integer(4096);
57 uint8_t chain = gRandom->Rndm() > 0.5 ? 0 : 1;
58 channels.emplace_back(ich, t, q, chain);
59 if (std::abs(t) < trg_gate) {
60 if (ich < 4 * uint8_t(Geometry::NCellsA)) {
61 nChanA++;
62 ampTotA += q;
63 tMeanA += t;
64 } else {
65 nChanC++;
66 ampTotC += q;
67 tMeanC += t;
68 }
69 }
70 ich += 1 + gRandom->Poisson(10);
71 }
72 if (nChanA) {
73 tMeanA /= nChanA;
74 ampTotA *= 0.125;
75 } else {
78 }
79 if (nChanC) {
80 tMeanC /= nChanC;
81 ampTotC *= 0.125; // sum/8
82 } else {
85 }
86 Triggers trig;
87 trig.setTriggers(gRandom->Integer(128), nChanA, nChanC, ampTotA, ampTotC, tMeanA, tMeanC);
88 auto end = channels.size();
89 digits.emplace_back(start, end - start, ir, trig, idig);
90 digits[idig].setEventStatus(eventFlag);
91 }
92
93 LOG(info) << "Generated " << channels.size() << " channels in " << digits.size() << " digits " << sw.CpuTime() << " s";
94
95 sw.Start();
96 std::vector<o2::ctf::BufferType> vec;
97 {
99 coder.setANSVersion(ansVersion);
100 coder.encode(vec, digits, channels); // compress
101 }
102 sw.Stop();
103 LOG(info) << "Compressed in " << sw.CpuTime() << " s";
104
105 // writing
106 {
107 sw.Start();
108 TFile flOut("test_ctf_ft0.root", "recreate");
109 TTree ctfTree(std::string(o2::base::NameConf::CTFTREENAME).c_str(), "O2 CTF tree");
111 ctfImage->print();
112 ctfImage->appendToTree(ctfTree, "FT0");
113 ctfTree.Write();
114 sw.Stop();
115 LOG(info) << "Wrote to tree in " << sw.CpuTime() << " s";
116 }
117
118 // reading
119 vec.clear();
120 {
121 sw.Start();
122 TFile flIn("test_ctf_ft0.root");
123 std::unique_ptr<TTree> tree((TTree*)flIn.Get(std::string(o2::base::NameConf::CTFTREENAME).c_str()));
125 o2::ft0::CTF::readFromTree(vec, *(tree.get()), "FT0");
126 sw.Stop();
127 LOG(info) << "Read back from tree in " << sw.CpuTime() << " s";
128 }
129
130 std::vector<Digit> digitsD;
131 std::vector<ChannelData> channelsD;
132
133 sw.Start();
134 const auto ctfImage = o2::ft0::CTF::getImage(vec.data());
135 {
137 coder.decode(ctfImage, digitsD, channelsD); // decompress
138 }
139 sw.Stop();
140 LOG(info) << "Decompressed in " << sw.CpuTime() << " s";
141
142 BOOST_CHECK(digitsD.size() == digits.size());
143 BOOST_CHECK(channelsD.size() == channels.size());
144 LOG(info) << " BOOST_CHECK digitsD.size() " << digitsD.size() << " digits.size() " << digits.size() << " BOOST_CHECK(channelsD.size() " << channelsD.size() << " channels.size()) " << channels.size();
145
146 for (int i = digits.size(); i--;) {
147 const auto& dor = digits[i];
148 const auto& ddc = digitsD[i];
149 LOG(debug) << " dor " << dor.mTriggers.print();
150 LOG(debug) << " ddc " << ddc.mTriggers.print();
151
152 BOOST_CHECK(dor.mIntRecord == ddc.mIntRecord);
153 BOOST_CHECK(dor.mTriggers.getNChanA() == ddc.mTriggers.getNChanA());
154 BOOST_CHECK(dor.mTriggers.getNChanC() == ddc.mTriggers.getNChanC());
155 BOOST_CHECK(dor.mTriggers.getAmplA() == ddc.mTriggers.getAmplA());
156 BOOST_CHECK(dor.mTriggers.getAmplC() == ddc.mTriggers.getAmplC());
157 BOOST_CHECK(dor.mTriggers.getTimeA() == ddc.mTriggers.getTimeA());
158 BOOST_CHECK(dor.mTriggers.getTimeC() == ddc.mTriggers.getTimeC());
159 BOOST_CHECK(dor.mTriggers.getTriggersignals() == ddc.mTriggers.getTriggersignals());
160 }
161 for (int i = channels.size(); i--;) {
162 const auto& cor = channels[i];
163 const auto& cdc = channelsD[i];
164 BOOST_CHECK(cor.ChId == cdc.ChId);
165 BOOST_CHECK(cor.ChainQTC == cdc.ChainQTC);
166 BOOST_CHECK(cor.CFDTime == cdc.CFDTime);
167 BOOST_CHECK(cor.QTCAmpl == cdc.QTCAmpl);
168 }
169}
class for entropy encoding/decoding of FT0 digits data
uint64_t nChanC
uint64_t nChanA
Configurable digitization parameters.
int32_t i
GPUChain * chain
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
static const int16_t DEFAULT_AMP
Definition Triggers.h:51
static const int16_t DEFAULT_TIME
Definition Triggers.h:50
void setTriggers(uint8_t trgsig, uint8_t chanA, uint8_t chanC, int32_t aamplA, int32_t aamplC, int16_t atimeA, int16_t atimeC)
Definition Triggers.h:97
o2::ctf::CTFIOSize encode(VEC &buff, const gsl::span< const Digit > &digitVec, const gsl::span< const ChannelData > &channelVec)
entropy-encode digits to buffer with CTF
Definition CTFCoder.h:70
o2::ctf::CTFIOSize decode(const CTF::base &ec, VDIG &digitVec, VCHAN &channelVec)
entropy decode clusters from buffer with CTF
Definition CTFCoder.h:127
static constexpr int NCellsA
Definition Geometry.h:52
static constexpr int NCellsC
Definition Geometry.h:53
GLuint GLuint end
Definition glcorearb.h:469
GLuint start
Definition glcorearb.h:469
constexpr ANSHeader ANSVersionCompat
Definition ANSHeader.h:54
constexpr ANSHeader ANSVersion1
Definition ANSHeader.h:55
std::vector< o2::ctf::BufferType > vec
std::vector< ChannelData > channelsD
std::vector< ChannelData > channels
BOOST_CHECK(tree)
std::vector< o2::ctf::ANSHeader > ANSVersions
TFile flOut("test_ctf_ft0.root", "recreate")
o2::InteractionRecord ir(0, 0)
constexpr int MAXChan
TStopwatch sw
TTree ctfTree(std::string(o2::base::NameConf::CTFTREENAME).c_str(), "O2 CTF tree")
auto * ctfImage
TFile flIn("test_ctf_ft0.root")
int trg_gate
std::vector< Digit > digitsD
std::unique_ptr< TTree > tree((TTree *) flIn.Get(std::string(o2::base::NameConf::CTFTREENAME).c_str()))
LOG(info)<< "Generated "<< channels.size()<< " channels in "<< digits.size()<< " digits "<< sw.CpuTime()<< " s"
std::vector< Digit > digits