|
| 1 | +// Copyright CERN and copyright holders of ALICE O2. This software is |
| 2 | +// distributed under the terms of the GNU General Public License v3 (GPL |
| 3 | +// Version 3), copied verbatim in the file "COPYING". |
| 4 | +// |
| 5 | +// See http://alice-o2.web.cern.ch/license for full licensing information. |
| 6 | +// |
| 7 | +// In applying this license CERN does not waive the privileges and immunities |
| 8 | +// granted to it by virtue of its status as an Intergovernmental Organization |
| 9 | +// or submit itself to any jurisdiction. |
| 10 | + |
| 11 | +#define BOOST_TEST_MODULE Test MIDCTFIO |
| 12 | +#define BOOST_TEST_MAIN |
| 13 | +#define BOOST_TEST_DYN_LINK |
| 14 | +#include <boost/test/unit_test.hpp> |
| 15 | +#include "DetectorsCommonDataFormats/NameConf.h" |
| 16 | +#include "MIDCTF/CTFCoder.h" |
| 17 | +#include "DataFormatsMID/CTF.h" |
| 18 | +#include "Framework/Logger.h" |
| 19 | +#include <TFile.h> |
| 20 | +#include <TRandom.h> |
| 21 | +#include <TStopwatch.h> |
| 22 | +#include <TSystem.h> |
| 23 | +#include <cstring> |
| 24 | + |
| 25 | +using namespace o2::mid; |
| 26 | + |
| 27 | +BOOST_AUTO_TEST_CASE(CTFTest) |
| 28 | +{ |
| 29 | + std::vector<ROFRecord> rofs; |
| 30 | + std::vector<ColumnData> cols; |
| 31 | + // RS: don't understand why, but this library is not loaded automatically, although the dependencies are clearly |
| 32 | + // indicated. What it more weird is that for similar tests of other detectors the library is loaded! |
| 33 | + // Absence of the library leads to complains about the StreamerInfo and eventually segm.faul when appending the |
| 34 | + // CTH to the tree. For this reason I am loading it here manually |
| 35 | + gSystem->Load("libO2DetectorsCommonDataFormats.so"); |
| 36 | + TStopwatch sw; |
| 37 | + sw.Start(); |
| 38 | + o2::InteractionRecord ir(0, 0); |
| 39 | + std::array<uint16_t, 5> pattern; |
| 40 | + for (int irof = 0; irof < 1000; irof++) { |
| 41 | + ir += 1 + gRandom->Integer(200); |
| 42 | + uint8_t nch = 0, evtyp = gRandom->Integer(3); |
| 43 | + while (nch == 0) { |
| 44 | + nch = gRandom->Poisson(10); |
| 45 | + } |
| 46 | + auto start = cols.size(); |
| 47 | + for (int ich = 0; ich < nch; ich++) { |
| 48 | + uint8_t deId = gRandom->Integer(128); |
| 49 | + uint8_t columnId = gRandom->Integer(128); |
| 50 | + for (int i = 0; i < 5; i++) { |
| 51 | + pattern[i] = gRandom->Integer(0x7fff); |
| 52 | + } |
| 53 | + cols.emplace_back(ColumnData{deId, columnId, pattern}); |
| 54 | + } |
| 55 | + rofs.emplace_back(ROFRecord{ir, EventType(evtyp), start, cols.size() - start}); |
| 56 | + } |
| 57 | + |
| 58 | + sw.Start(); |
| 59 | + std::vector<o2::ctf::BufferType> vec; |
| 60 | + { |
| 61 | + CTFCoder coder; |
| 62 | + coder.encode(vec, rofs, cols); // compress |
| 63 | + } |
| 64 | + sw.Stop(); |
| 65 | + LOG(INFO) << "Compressed in " << sw.CpuTime() << " s"; |
| 66 | + |
| 67 | + // writing |
| 68 | + { |
| 69 | + sw.Start(); |
| 70 | + auto* ctfImage = o2::mid::CTF::get(vec.data()); |
| 71 | + TFile flOut("test_ctf_mid.root", "recreate"); |
| 72 | + TTree ctfTree(std::string(o2::base::NameConf::CTFTREENAME).c_str(), "O2 CTF tree"); |
| 73 | + ctfImage->print(); |
| 74 | + ctfImage->appendToTree(ctfTree, "MID"); |
| 75 | + ctfTree.Write(); |
| 76 | + sw.Stop(); |
| 77 | + LOG(INFO) << "Wrote to tree in " << sw.CpuTime() << " s"; |
| 78 | + } |
| 79 | + |
| 80 | + // reading |
| 81 | + vec.clear(); |
| 82 | + { |
| 83 | + sw.Start(); |
| 84 | + TFile flIn("test_ctf_mid.root"); |
| 85 | + std::unique_ptr<TTree> tree((TTree*)flIn.Get(std::string(o2::base::NameConf::CTFTREENAME).c_str())); |
| 86 | + BOOST_CHECK(tree); |
| 87 | + o2::mid::CTF::readFromTree(vec, *(tree.get()), "MID"); |
| 88 | + sw.Stop(); |
| 89 | + LOG(INFO) << "Read back from tree in " << sw.CpuTime() << " s"; |
| 90 | + } |
| 91 | + |
| 92 | + std::vector<ROFRecord> rofsD; |
| 93 | + std::vector<ColumnData> colsD; |
| 94 | + |
| 95 | + sw.Start(); |
| 96 | + const auto ctfImage = o2::mid::CTF::getImage(vec.data()); |
| 97 | + { |
| 98 | + CTFCoder coder; |
| 99 | + coder.decode(ctfImage, rofsD, colsD); // decompress |
| 100 | + } |
| 101 | + sw.Stop(); |
| 102 | + LOG(INFO) << "Decompressed in " << sw.CpuTime() << " s"; |
| 103 | + |
| 104 | + BOOST_CHECK(rofsD.size() == rofs.size()); |
| 105 | + BOOST_CHECK(colsD.size() == cols.size()); |
| 106 | + LOG(INFO) << " BOOST_CHECK rofsD.size() " << rofsD.size() << " rofs.size() " << rofs.size() |
| 107 | + << " BOOST_CHECK(colsD.size() " << colsD.size() << " cols.size()) " << cols.size(); |
| 108 | + |
| 109 | + for (size_t i = 0; i < rofs.size(); i++) { |
| 110 | + const auto& dor = rofs[i]; |
| 111 | + const auto& ddc = rofsD[i]; |
| 112 | + LOG(DEBUG) << " Orig.ROFRecord " << i << " " << dor.interactionRecord << " " << dor.firstEntry << " " << dor.nEntries; |
| 113 | + LOG(DEBUG) << " Deco.ROFRecord " << i << " " << ddc.interactionRecord << " " << ddc.firstEntry << " " << ddc.nEntries; |
| 114 | + |
| 115 | + BOOST_CHECK(dor.interactionRecord == ddc.interactionRecord); |
| 116 | + BOOST_CHECK(dor.firstEntry == ddc.firstEntry); |
| 117 | + BOOST_CHECK(dor.nEntries == dor.nEntries); |
| 118 | + } |
| 119 | + |
| 120 | + for (size_t i = 0; i < cols.size(); i++) { |
| 121 | + const auto& cor = cols[i]; |
| 122 | + const auto& cdc = colsD[i]; |
| 123 | + BOOST_CHECK(cor.deId == cdc.deId); |
| 124 | + BOOST_CHECK(cor.columnId == cdc.columnId); |
| 125 | + for (int j = 0; j < 5; j++) { |
| 126 | + BOOST_CHECK(cor.patterns[j] == cdc.patterns[j]); |
| 127 | + LOG(DEBUG) << "col " << i << " pat " << j << " : " << cor.patterns[j] << " : " << cdc.patterns[j]; |
| 128 | + } |
| 129 | + } |
| 130 | +} |
0 commit comments