Project
Loading...
Searching...
No Matches
test_ctf_io_cpv.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 CPVCTFIO
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 "DataFormatsCPV/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 <TMath.h>
32#include <cstring>
33
34using namespace o2::cpv;
35namespace boost_data = boost::unit_test::data;
36
37inline std::vector<o2::ctf::ANSHeader> ANSVersions{o2::ctf::ANSVersionCompat, o2::ctf::ANSVersion1};
38
39BOOST_DATA_TEST_CASE(CTFTest, boost_data::make(ANSVersions), ansVersion)
40{
41 std::vector<TriggerRecord> triggers;
42 std::vector<Cluster> clusters;
43 TStopwatch sw;
44 sw.Start();
47 for (int irof = 0; irof < 1000; irof++) {
48 ir += 1 + gRandom->Integer(200);
49
50 auto start = clusters.size();
51 int n = 1 + gRandom->Poisson(100);
52 for (int i = n; i--;) {
53 char mult = gRandom->Integer(30);
54 char mod = 2 + gRandom->Integer(3); // there are M2, M3 and M4
55 char exMax = gRandom->Integer(3);
56 float x = 72.3 * 2. * (gRandom->Rndm() - 0.5);
57 float z = 63.3 * 2. * (gRandom->Rndm() - 0.5);
58 float e = 10000. * gRandom->Rndm(); // we need high energy range
59 clusters.emplace_back(mult, mod, exMax, x, z, e);
60 }
61 triggers.emplace_back(ir, start, clusters.size() - start);
62 }
63
64 sw.Start();
65 std::vector<o2::ctf::BufferType> vec;
66 {
68 coder.setANSVersion(ansVersion);
69 coder.encode(vec, triggers, clusters); // compress
70 }
71 sw.Stop();
72 LOG(info) << "Compressed in " << sw.CpuTime() << " s";
73
74 // writing
75 {
76 sw.Start();
78 TFile flOut("test_ctf_cpv.root", "recreate");
79 TTree ctfTree(std::string(o2::base::NameConf::CTFTREENAME).c_str(), "O2 CTF tree");
80 ctfImage->print();
81 ctfImage->appendToTree(ctfTree, "CPV");
82 ctfTree.Write();
83 sw.Stop();
84 LOG(info) << "Wrote to tree in " << sw.CpuTime() << " s";
85 }
86
87 // reading
88 vec.clear();
89 LOG(info) << "Start reading from tree ";
90 {
91 sw.Start();
92 TFile flIn("test_ctf_cpv.root");
93 std::unique_ptr<TTree> tree((TTree*)flIn.Get(std::string(o2::base::NameConf::CTFTREENAME).c_str()));
95 o2::cpv::CTF::readFromTree(vec, *(tree.get()), "CPV");
96 sw.Stop();
97 LOG(info) << "Read back from tree in " << sw.CpuTime() << " s";
98 }
99
100 std::vector<TriggerRecord> triggersD;
101 std::vector<Cluster> clustersD;
102
103 sw.Start();
104 const auto ctfImage = o2::cpv::CTF::getImage(vec.data());
105 {
107 coder.decode(ctfImage, triggersD, clustersD); // decompress
108 }
109 sw.Stop();
110 LOG(info) << "Decompressed in " << sw.CpuTime() << " s";
111
112 BOOST_CHECK(triggersD.size() == triggers.size());
113 BOOST_CHECK(clustersD.size() == clusters.size());
114 LOG(info) << " BOOST_CHECK triggersD.size() " << triggersD.size() << " triggers.size() " << triggers.size()
115 << " BOOST_CHECK(clustersD.size() " << clustersD.size() << " clusters.size()) " << clusters.size();
116
117 for (size_t i = 0; i < triggers.size(); i++) {
118 const auto& dor = triggers[i];
119 const auto& ddc = triggersD[i];
120 LOG(debug) << " Orig.TriggerRecord " << i << " " << dor.getBCData() << " " << dor.getFirstEntry() << " " << dor.getNumberOfObjects();
121 LOG(debug) << " Deco.TriggerRecord " << i << " " << ddc.getBCData() << " " << ddc.getFirstEntry() << " " << ddc.getNumberOfObjects();
122
123 BOOST_CHECK(dor.getBCData() == ddc.getBCData());
124 BOOST_CHECK(dor.getNumberOfObjects() == ddc.getNumberOfObjects());
125 BOOST_CHECK(dor.getFirstEntry() == dor.getFirstEntry());
126 }
127
128 for (size_t i = 0; i < clusters.size(); i++) {
129 const auto& cor = clusters[i];
130 const auto& cdc = clustersD[i];
131 BOOST_CHECK(cor.getMultiplicity() == cdc.getMultiplicity());
132 BOOST_CHECK(cor.getModule() == cdc.getModule());
133 if (cor.getEnergy() < 100.) {
134 BOOST_CHECK(TMath::Abs(cor.getEnergy() - cdc.getEnergy()) < 1.);
135 } else {
136 float eTr = cor.getEnergy();
137 BOOST_CHECK(TMath::Abs(eTr - cdc.getEnergy()) <= eTr * (exp(kStepE * eTr) - 1.)); // increasing discretisation step size
138 }
139 float xCor, zCor, xCdc, zCdc;
140 cor.getLocalPosition(xCor, zCor);
141 cdc.getLocalPosition(xCdc, zCdc);
142 BOOST_CHECK(TMath::Abs(xCor - xCdc) < 0.004);
143 BOOST_CHECK(TMath::Abs(zCor - zCdc) < 0.004);
144 }
145}
Definitions for CPV CTF data.
class for entropy encoding/decoding of CPV data
uint64_t exp(uint64_t base, uint8_t exp) noexcept
std::ostringstream debug
int32_t i
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error First event to Number of events to Number of iterations to Number of iterations to Number of initial iterations excluded from const char e
BOOST_DATA_TEST_CASE(DefaultConstructorNofSamplesIsInvariant, boost::unit_test::data::make(nsamples), nofSamples)
Definition testDigit.cxx:50
Definition of the Names Generator class.
static constexpr std::string_view CTFTREENAME
Definition NameConf.h:95
o2::ctf::CTFIOSize decode(const CTF::base &ec, VTRG &trigVec, VCLUSTER &cluVec)
entropy decode data from buffer with CTF
Definition CTFCoder.h:130
o2::ctf::CTFIOSize encode(VEC &buff, const gsl::span< const TriggerRecord > &trigData, const gsl::span< const Cluster > &cluData)
entropy-encode data to buffer with CTF
Definition CTFCoder.h:63
Contains CPV cluster parameters.
Definition Cluster.h:33
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
GLdouble n
Definition glcorearb.h:1982
GLint GLenum GLint x
Definition glcorearb.h:403
GLuint start
Definition glcorearb.h:469
GLdouble GLdouble GLdouble z
Definition glcorearb.h:843
constexpr float kStepE
Definition Cluster.h:30
constexpr ANSHeader ANSVersionCompat
Definition ANSHeader.h:54
constexpr ANSHeader ANSVersion1
Definition ANSHeader.h:55
std::vector< o2::ctf::BufferType > vec
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
TFile flIn("test_ctf_cpv.root")
Cluster clu
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")
std::vector< Cluster > clusters
std::vector< Cluster > clustersD
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")