Project
Loading...
Searching...
No Matches
testFastORTimeSeries.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#define BOOST_TEST_MODULE Test EMCAL Reconstruction
12#define BOOST_TEST_MAIN
13#define BOOST_TEST_DYN_LINK
14#include <boost/test/unit_test.hpp>
15#include <vector>
16#include <tuple>
17#include <TRandom.h>
20
21namespace o2
22{
23
24namespace emcal
25{
26
27void printBunch(const gsl::span<const uint16_t> adcs)
28{
29 bool first = true;
30 for (auto& adc : adcs) {
31 if (!first) {
32 std::cout << ", ";
33 } else {
34 first = false;
35 }
36 std::cout << adc;
37 }
38 std::cout << " (size " << adcs.size() << ")" << std::endl;
39}
40
41std::vector<uint16_t> getReversed(const std::vector<uint16_t>& original)
42{
43 std::vector<uint16_t> reversed(13);
44 for (std::size_t sample = 0; sample < 13; sample++) {
45 reversed[12 - sample] = original[sample];
46 }
47 return reversed;
48}
49
50std::tuple<uint8_t, std::vector<uint16_t>, std::vector<uint16_t>> generatePulseTimeReversed()
51{
52 std::vector<uint16_t> pulse(13);
53 std::fill(pulse.begin(), pulse.end(), 0);
54 // calculate forward pulse
55 auto peak_signal = static_cast<uint16_t>(gRandom->Uniform(0, 1024));
56 pulse[4] = peak_signal;
57 auto last = peak_signal;
58 for (std::size_t sample = 5; sample < 13; sample++) {
59 if (last == 0) {
60 break;
61 }
62 auto current = static_cast<uint16_t>(gRandom->Uniform(0, last));
63 pulse[sample] = current;
64 last = current;
65 }
66 last = peak_signal;
67 for (std::size_t sample = 3; sample > 0; sample--) {
68 if (last == 0) {
69 break;
70 }
71 auto current = static_cast<uint16_t>(gRandom->Uniform(0, last));
72 pulse[sample] = current;
73 last = current;
74 }
75 // find start time
76 uint8_t starttime = 12;
77 for (std::size_t currenttime = 12; currenttime > 0; currenttime--) {
78 starttime = currenttime;
79 if (pulse[currenttime]) {
80 break;
81 }
82 }
83 // time-reverse pulse
84 auto reversed = getReversed(pulse);
85 // zero-suppress time series
86 std::vector<uint16_t> zerosuppressed;
87 bool bunchstart = false;
88 for (std::size_t sample = 0; sample < 13; sample++) {
89 if (reversed[sample] == 0) {
90 if (!bunchstart) {
91 continue;
92 }
93 break;
94 }
95 bunchstart = true;
96 zerosuppressed.push_back(reversed[sample]);
97 }
98 return std::make_tuple(starttime, zerosuppressed, pulse);
99}
100
101uint16_t calculateTimesum(const std::vector<uint16_t> samplesOrdered, uint8_t l0time)
102{
103 uint16_t timesum = 0;
104 uint8_t starttime = l0time - 4;
105 for (uint8_t sample = starttime; sample < starttime + 4; sample++) {
106 timesum += samplesOrdered[sample];
107 }
108 return timesum;
109}
110
111std::vector<uint16_t> generateSmallBunch(uint8_t bunchlength)
112{
113 std::vector<uint16_t> bunch(bunchlength);
114 auto peak_signal = static_cast<uint16_t>(gRandom->Uniform(0, 1024));
115 bunch[bunchlength - 2] = peak_signal;
116 bunch[bunchlength - 1] = static_cast<uint16_t>(gRandom->Uniform(0, peak_signal));
117 auto last = peak_signal;
118 for (int sample = bunchlength - 3; sample >= 0; sample--) {
119 auto current = static_cast<uint16_t>(gRandom->Uniform(0, last));
120 bunch[sample] = current;
121 last = current;
122 }
123 return bunch;
124}
125
126void add_bunch_to_buffer(std::vector<uint16_t>& buffer, const std::vector<uint16_t>& bunch, uint8_t starttime)
127{
128 for (int sample = 0; sample < bunch.size(); sample++) {
129 buffer[starttime - sample] = bunch[bunch.size() - 1 - sample];
130 }
131}
132
133BOOST_AUTO_TEST_CASE(FastORTimeSeries_test)
134{
135 // test fill and integral
136 for (int itest = 0; itest < 500; itest++) {
137 auto [starttime, zerosuppressed, reference] = generatePulseTimeReversed();
138 FastORTimeSeries testcase(13, zerosuppressed, starttime);
139 auto adcs = testcase.getADCs();
140 BOOST_CHECK_EQUAL_COLLECTIONS(adcs.begin(), adcs.end(), reference.begin(), reference.end());
142 }
143
144 // test case where a normal FEC channel is identified as TRU channel. FEC channel can have lenght of 15 and would therefore cause an overflow in the FEC channel (max lenght 14)
145 auto starttime = 14;
146 auto bunch = generateSmallBunch(14);
147 BOOST_CHECK_EXCEPTION(FastORTimeSeries(14, bunch, starttime), FastOrStartTimeInvalidException, [starttime](const FastOrStartTimeInvalidException& e) { return e.getStartTime() == starttime; });
148
149 return;
150
151 // test adding 2 bunches
152 for (int itest = 0; itest < 500; itest++) {
153 auto length_bunch1 = static_cast<int>(gRandom->Uniform(3, 5)),
154 length_bunch2 = static_cast<int>(gRandom->Uniform(3, 5));
155 auto sumbunchlength = length_bunch1 + length_bunch2;
156 auto offset_bunch1 = static_cast<int>(gRandom->Uniform(0, 13 - sumbunchlength)),
157 offset_bunch2 = static_cast<int>(gRandom->Uniform(0, 13 - sumbunchlength - offset_bunch1));
158 auto bunch1 = generateSmallBunch(length_bunch1),
159 bunch2 = generateSmallBunch(length_bunch2);
160 auto starttime_bunch1 = offset_bunch1 + length_bunch1,
161 starttime_bunch2 = starttime_bunch1 + offset_bunch2 + length_bunch2;
162 std::vector<uint16_t> buffer_reversed{13};
163 add_bunch_to_buffer(buffer_reversed, bunch2, starttime_bunch2);
164 add_bunch_to_buffer(buffer_reversed, bunch1, starttime_bunch1);
165 FastORTimeSeries testcase(13, bunch2, starttime_bunch2);
166 testcase.setTimeSamples(bunch1, starttime_bunch1);
167 auto adcs_timeordered = getReversed(buffer_reversed);
168 auto adcs_timeseries_reversed = testcase.getADCs();
169 BOOST_CHECK_EQUAL_COLLECTIONS(adcs_timeseries_reversed.begin(), adcs_timeseries_reversed.end(), adcs_timeordered.begin(), adcs_timeordered.end());
170 }
171}
172
173} // namespace emcal
174
175} // namespace o2
Container for FastOR time series.
void setTimeSamples(const gsl::span< const uint16_t > timesamples, uint8_t starttime)
uint16_t calculateL1TimeSum(uint8_t l0time) const
Calculate L0 timesum (4-integral of the ADC series) with respect to a given L0 time.
const gsl::span< const uint16_t > getADCs() const
Access raw ADC values (in forward time order)
Handling of error if starttime is to large (>=14). This is most likely caused by a corrupted channel ...
int getStartTime() const noexcept
Get the size of the L0 patch.
GLuint buffer
Definition glcorearb.h:655
GLint reference
Definition glcorearb.h:5487
BOOST_AUTO_TEST_CASE(asynch_schedule_test)
std::vector< uint16_t > generateSmallBunch(uint8_t bunchlength)
std::tuple< uint8_t, std::vector< uint16_t >, std::vector< uint16_t > > generatePulseTimeReversed()
uint16_t calculateTimesum(const std::vector< uint16_t > samplesOrdered, uint8_t l0time)
std::vector< uint16_t > getReversed(const std::vector< uint16_t > &original)
void add_bunch_to_buffer(std::vector< uint16_t > &buffer, const std::vector< uint16_t > &bunch, uint8_t starttime)
void printBunch(const gsl::span< const uint16_t > adcs)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
BOOST_CHECK_EQUAL(triggersD.size(), triggers.size())
ArrayADC adc