-
Notifications
You must be signed in to change notification settings - Fork 438
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[EMCAL-1136] Unit tests for trigger reconstruction
- Unit test for TRUDataHandler - Unit test for FastORTimeSeries - Move unit tests for EMCALReconstruction in correct group
- Loading branch information
Showing
8 changed files
with
277 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
168 changes: 168 additions & 0 deletions
168
Detectors/EMCAL/reconstruction/test/testFastORTimeSeries.cxx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
// Copyright 2019-2020 CERN and copyright holders of ALICE O2. | ||
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. | ||
// All rights not expressly granted are reserved. | ||
// | ||
// This software is distributed under the terms of the GNU General Public | ||
// License v3 (GPL Version 3), copied verbatim in the file "COPYING". | ||
// | ||
// In applying this license CERN does not waive the privileges and immunities | ||
// granted to it by virtue of its status as an Intergovernmental Organization | ||
// or submit itself to any jurisdiction. | ||
#define BOOST_TEST_MODULE Test EMCAL Reconstruction | ||
#define BOOST_TEST_MAIN | ||
#define BOOST_TEST_DYN_LINK | ||
#include <boost/test/unit_test.hpp> | ||
#include <vector> | ||
#include <tuple> | ||
#include <TRandom.h> | ||
#include <EMCALReconstruction/FastORTimeSeries.h> | ||
|
||
namespace o2 | ||
{ | ||
|
||
namespace emcal | ||
{ | ||
|
||
void printBunch(const gsl::span<const uint16_t> adcs) | ||
{ | ||
bool first = true; | ||
for (auto& adc : adcs) { | ||
if (!first) { | ||
std::cout << ", "; | ||
} else { | ||
first = false; | ||
} | ||
std::cout << adc; | ||
} | ||
std::cout << " (size " << adcs.size() << ")" << std::endl; | ||
} | ||
|
||
std::vector<uint16_t> getReversed(const std::vector<uint16_t>& original) | ||
{ | ||
std::vector<uint16_t> reversed(13); | ||
for (std::size_t sample = 0; sample < 13; sample++) { | ||
reversed[12 - sample] = original[sample]; | ||
} | ||
return reversed; | ||
} | ||
|
||
std::tuple<uint8_t, std::vector<uint16_t>, std::vector<uint16_t>> generatePulseTimeReversed() | ||
{ | ||
std::vector<uint16_t> pulse(13); | ||
std::fill(pulse.begin(), pulse.end(), 0); | ||
// calculate forward pulse | ||
auto peak_signal = static_cast<uint16_t>(gRandom->Uniform(0, 1024)); | ||
pulse[4] = peak_signal; | ||
auto last = peak_signal; | ||
for (std::size_t sample = 5; sample < 13; sample++) { | ||
if (last == 0) { | ||
break; | ||
} | ||
auto current = static_cast<uint16_t>(gRandom->Uniform(0, last)); | ||
pulse[sample] = current; | ||
last = current; | ||
} | ||
last = peak_signal; | ||
for (std::size_t sample = 3; sample > 0; sample--) { | ||
if (last == 0) { | ||
break; | ||
} | ||
auto current = static_cast<uint16_t>(gRandom->Uniform(0, last)); | ||
pulse[sample] = current; | ||
last = current; | ||
} | ||
// find start time | ||
uint8_t starttime = 12; | ||
for (std::size_t currenttime = 12; currenttime > 0; currenttime--) { | ||
starttime = currenttime; | ||
if (pulse[currenttime]) { | ||
break; | ||
} | ||
} | ||
// time-reverse pulse | ||
auto reversed = getReversed(pulse); | ||
// zero-suppress time series | ||
std::vector<uint16_t> zerosuppressed; | ||
bool bunchstart = false; | ||
for (std::size_t sample = 0; sample < 13; sample++) { | ||
if (reversed[sample] == 0) { | ||
if (!bunchstart) { | ||
continue; | ||
} | ||
break; | ||
} | ||
bunchstart = true; | ||
zerosuppressed.push_back(reversed[sample]); | ||
} | ||
return std::make_tuple(starttime, zerosuppressed, pulse); | ||
} | ||
|
||
uint16_t calculateTimesum(const std::vector<uint16_t> samplesOrdered, uint8_t l0time) | ||
{ | ||
uint16_t timesum = 0; | ||
uint8_t starttime = l0time - 4; | ||
for (uint8_t sample = starttime; sample < starttime + 4; sample++) { | ||
timesum += samplesOrdered[sample]; | ||
} | ||
return timesum; | ||
} | ||
|
||
std::vector<uint16_t> generateSmallBunch(uint8_t bunchlength) | ||
{ | ||
std::vector<uint16_t> bunch(bunchlength); | ||
auto peak_signal = static_cast<uint16_t>(gRandom->Uniform(0, 1024)); | ||
bunch[bunchlength - 2] = peak_signal; | ||
bunch[bunchlength - 1] = static_cast<uint16_t>(gRandom->Uniform(0, peak_signal)); | ||
auto last = peak_signal; | ||
for (int sample = bunchlength - 3; sample >= 0; sample--) { | ||
auto current = static_cast<uint16_t>(gRandom->Uniform(0, last)); | ||
bunch[sample] = current; | ||
last = current; | ||
} | ||
return bunch; | ||
} | ||
|
||
void add_bunch_to_buffer(std::vector<uint16_t>& buffer, const std::vector<uint16_t>& bunch, uint8_t starttime) | ||
{ | ||
for (int sample = 0; sample < bunch.size(); sample++) { | ||
buffer[starttime - sample] = bunch[bunch.size() - 1 - sample]; | ||
} | ||
} | ||
|
||
BOOST_AUTO_TEST_CASE(FastORTimeSeries_test) | ||
{ | ||
// test fill and integral | ||
for (int itest = 0; itest < 500; itest++) { | ||
auto [starttime, zerosuppressed, reference] = generatePulseTimeReversed(); | ||
FastORTimeSeries testcase(13, zerosuppressed, starttime); | ||
auto adcs = testcase.getADCs(); | ||
BOOST_CHECK_EQUAL_COLLECTIONS(adcs.begin(), adcs.end(), reference.begin(), reference.end()); | ||
BOOST_CHECK_EQUAL(testcase.calculateL1TimeSum(8), calculateTimesum(reference, 8)); | ||
} | ||
return; | ||
|
||
// test adding 2 bunches | ||
for (int itest = 0; itest < 500; itest++) { | ||
auto length_bunch1 = static_cast<int>(gRandom->Uniform(3, 5)), | ||
length_bunch2 = static_cast<int>(gRandom->Uniform(3, 5)); | ||
auto sumbunchlength = length_bunch1 + length_bunch2; | ||
auto offset_bunch1 = static_cast<int>(gRandom->Uniform(0, 13 - sumbunchlength)), | ||
offset_bunch2 = static_cast<int>(gRandom->Uniform(0, 13 - sumbunchlength - offset_bunch1)); | ||
auto bunch1 = generateSmallBunch(length_bunch1), | ||
bunch2 = generateSmallBunch(length_bunch2); | ||
auto starttime_bunch1 = offset_bunch1 + length_bunch1, | ||
starttime_bunch2 = starttime_bunch1 + offset_bunch2 + length_bunch2; | ||
std::vector<uint16_t> buffer_reversed{13}; | ||
add_bunch_to_buffer(buffer_reversed, bunch2, starttime_bunch2); | ||
add_bunch_to_buffer(buffer_reversed, bunch1, starttime_bunch1); | ||
FastORTimeSeries testcase(13, bunch2, starttime_bunch2); | ||
testcase.setTimeSamples(bunch1, starttime_bunch1); | ||
auto adcs_timeordered = getReversed(buffer_reversed); | ||
auto adcs_timeseries_reversed = testcase.getADCs(); | ||
BOOST_CHECK_EQUAL_COLLECTIONS(adcs_timeseries_reversed.begin(), adcs_timeseries_reversed.end(), adcs_timeordered.begin(), adcs_timeordered.end()); | ||
} | ||
} | ||
|
||
} // namespace emcal | ||
|
||
} // namespace o2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
92 changes: 92 additions & 0 deletions
92
Detectors/EMCAL/reconstruction/test/testTRUDataHandler.cxx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
// Copyright 2019-2020 CERN and copyright holders of ALICE O2. | ||
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. | ||
// All rights not expressly granted are reserved. | ||
// | ||
// This software is distributed under the terms of the GNU General Public | ||
// License v3 (GPL Version 3), copied verbatim in the file "COPYING". | ||
// | ||
// In applying this license CERN does not waive the privileges and immunities | ||
// granted to it by virtue of its status as an Intergovernmental Organization | ||
// or submit itself to any jurisdiction. | ||
#define BOOST_TEST_MODULE Test EMCAL Reconstruction | ||
#define BOOST_TEST_MAIN | ||
#define BOOST_TEST_DYN_LINK | ||
#include <boost/test/unit_test.hpp> | ||
#include <set> | ||
#include <TRandom.h> | ||
#include <EMCALBase/TriggerMappingV2.h> | ||
#include <EMCALReconstruction/TRUDataHandler.h> | ||
|
||
namespace o2 | ||
{ | ||
namespace emcal | ||
{ | ||
|
||
BOOST_AUTO_TEST_CASE(TRUDataHandler_test) | ||
{ | ||
o2::emcal::TRUDataHandler testhandler; | ||
|
||
// no patch set | ||
BOOST_CHECK_EQUAL(testhandler.hasAnyPatch(), false); | ||
for (int ipatch = 0; ipatch < o2::emcal::TriggerMappingV2::PATCHESINTRU; ipatch++) { | ||
BOOST_CHECK_EQUAL(testhandler.hasPatch(ipatch), false); | ||
} | ||
|
||
// set all patches with L0 time 8 | ||
for (int ipatch = 0; ipatch < o2::emcal::TriggerMappingV2::PATCHESINTRU; ipatch++) { | ||
testhandler.setPatch(ipatch, 8); | ||
} | ||
BOOST_CHECK_EQUAL(testhandler.hasAnyPatch(), true); | ||
for (int ipatch = 0; ipatch < o2::emcal::TriggerMappingV2::PATCHESINTRU; ipatch++) { | ||
BOOST_CHECK_EQUAL(testhandler.hasPatch(ipatch), true); | ||
BOOST_CHECK_EQUAL(testhandler.getPatchTime(ipatch), 8); | ||
} | ||
|
||
// test reset | ||
testhandler.reset(); | ||
BOOST_CHECK_EQUAL(testhandler.hasAnyPatch(), false); | ||
for (int ipatch = 0; ipatch < o2::emcal::TriggerMappingV2::PATCHESINTRU; ipatch++) { | ||
BOOST_CHECK_EQUAL(testhandler.hasPatch(ipatch), false); | ||
} | ||
|
||
// test error handling | ||
for (int8_t index = o2::emcal::TriggerMappingV2::PATCHESINTRU; index < CHAR_MAX; index++) { | ||
BOOST_CHECK_EXCEPTION(testhandler.hasPatch(index), o2::emcal::TRUDataHandler::PatchIndexException, [index](const o2::emcal::TRUDataHandler::PatchIndexException& e) { return e.getIndex() == index; }); | ||
BOOST_CHECK_EXCEPTION(testhandler.setPatch(index, 8), o2::emcal::TRUDataHandler::PatchIndexException, [index](const o2::emcal::TRUDataHandler::PatchIndexException& e) { return e.getIndex() == index; }); | ||
} | ||
|
||
for (int iiter = 0; iiter < 100; iiter++) { | ||
// For 100 iterations simulate patch index and time | ||
std::map<uint8_t, uint8_t> patchtimes; | ||
int npatches_expect = static_cast<int>(gRandom->Uniform(0, o2::emcal::TriggerMappingV2::PATCHESINTRU)); | ||
while (patchtimes.size() < npatches_expect) { | ||
auto patchindex = static_cast<int>(gRandom->Uniform(0, o2::emcal::TriggerMappingV2::PATCHESINTRU)); | ||
if (patchtimes.find(patchindex) == patchtimes.end()) { | ||
auto patchtime = static_cast<int>(gRandom->Gaus(8, 1)); | ||
if (patchtime >= 12) { | ||
patchtime = 11; | ||
} | ||
patchtimes[patchindex] = patchtime; | ||
} | ||
} | ||
o2::emcal::TRUDataHandler iterhandler; | ||
iterhandler.setFired(npatches_expect > 0); | ||
for (auto [patchindex, patchtime] : patchtimes) { | ||
iterhandler.setPatch(patchindex, patchtime); | ||
} | ||
|
||
BOOST_CHECK_EQUAL(iterhandler.isFired(), npatches_expect > 0); | ||
BOOST_CHECK_EQUAL(iterhandler.hasAnyPatch(), npatches_expect > 0); | ||
for (auto ipatch = 0; ipatch < o2::emcal::TriggerMappingV2::PATCHESINTRU; ipatch++) { | ||
auto hasPatch = patchtimes.find(ipatch) != patchtimes.end(); | ||
BOOST_CHECK_EQUAL(iterhandler.hasPatch(ipatch), hasPatch); | ||
if (hasPatch) { | ||
BOOST_CHECK_EQUAL(iterhandler.getPatchTime(ipatch), patchtimes[ipatch]); | ||
} | ||
} | ||
} | ||
} | ||
|
||
} // namespace emcal | ||
|
||
} // namespace o2 |