Project
Loading...
Searching...
No Matches
testDigitizer.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.
14
15#define BOOST_TEST_MODULE Test MCHSimulation Digitization
16#define BOOST_TEST_DYN_LINK
17
18#include <boost/test/unit_test.hpp>
19
28#include "MCHSimulation/Hit.h"
31#include "Field/MagneticField.h"
32#include "TGeoManager.h"
33#include "TGeoGlobalMagField.h"
34#include "boost/format.hpp"
35#include <boost/test/data/test_case.hpp>
36#include <boost/property_tree/ptree.hpp>
37#include <algorithm>
38#include <unordered_map>
39
41using o2::mch::Digit;
42using o2::mch::Hit;
45
46struct GEOMETRY {
48 {
49 if (!gGeoManager) {
51 }
52 }
53};
54
55void initField(float l3Current, float dipoleCurrent)
56{
58 if (TGeoGlobalMagField::Instance()->GetField()) {
59 return;
60 }
61
62 auto field =
64 "A-A", "$(O2_ROOT)/share/Common/maps/mfchebKGI_sym.root");
65 TGeoGlobalMagField::Instance()->SetField(field);
66 TGeoGlobalMagField::Instance()->Lock();
67}
68
69namespace
70{
71short detElemId1 = 101;
72o2::math_utils::Point3D<float> entrancePoint1(-17.7993, 8.929883, -522.201); // x,y,z coordinates in cm
73o2::math_utils::Point3D<float> exitPoint1(-17.8136, 8.93606, -522.62);
74short detElemId2 = 1012;
75o2::math_utils::Point3D<float> entrancePoint2(-49.2793, 28.8673, -1441.25);
76o2::math_utils::Point3D<float> exitPoint2(-49.2965, 28.8806, -1441.75);
77short detElemId3 = 1012;
78o2::math_utils::Point3D<float> entrancePoint3(-50.1793, 28.2673, -1441.25);
79o2::math_utils::Point3D<float> exitPoint3(-50.1965, 28.2806, -1441.75);
80
82{
83 int padid = digit.getPadID();
84 bool check = seg.isValid(padid);
85 if (!check) {
86 BOOST_FAIL(" digit-pad not belonging to hit det-element-ID ");
87 return 0;
88 }
89 double padposX = seg.padPositionX(padid);
90 double padsizeX = seg.padSizeX(padid);
91 double padposY = seg.padPositionY(padid);
92 double padsizeY = seg.padSizeY(padid);
93 auto t = transformation(digit.getDetID());
94
95 o2::math_utils::Point3D<float> pos(hit.GetX(), hit.GetY(), hit.GetZ());
97 t.MasterToLocal(pos, lpos);
98
99 // very loose check : check that digit position is within 10 pads of the
100 // hit center in both directions
101 BOOST_CHECK(std::abs(lpos.x() - padposX) < padsizeX * 10);
102 BOOST_CHECK(std::abs(lpos.y() - padposY) < padsizeY * 10);
103 return 1;
104}
105} // namespace
106
110
111BOOST_FIXTURE_TEST_SUITE(digitization, GEOMETRY)
112
114{
116 o2::conf::ConfigurableParam::setValue("MCHDigitizer", "seed", 123);
118
119 initField(-30000.0, -6000.0);
120
121 int trackId1 = 0;
122 int trackId2 = 1;
123 int trackId3 = 2;
124 IR collisionTime1(3, 1);
125 IR collisionTime2(5, 1);
126 float eloss = 1.e-6;
127 float length = 0.f;
128 float tof = 0.f;
129 float energ = 10.0;
130
131 std::vector<o2::mch::Hit> hits1(2);
132 hits1.at(0) = o2::mch::Hit(trackId1, detElemId1, entrancePoint1, exitPoint1, eloss, length, tof, energ);
133 hits1.at(1) = o2::mch::Hit(trackId2, detElemId2, entrancePoint2, exitPoint2, eloss, length, tof, energ);
134
135 std::vector<o2::mch::Hit> hits2(1);
136 hits2.at(0) = o2::mch::Hit(trackId3, detElemId3, entrancePoint3, exitPoint3, eloss, length, tof, energ);
137
138 digitizer.processHits(hits1, collisionTime1, 0, 0);
139 digitizer.processHits(hits2, collisionTime2, 0, 0);
140
141 auto firstIR = IR::long2IR(std::max(int64_t(0), collisionTime1.toLong() - 100));
142 auto lastIR = collisionTime2 + 100;
143 digitizer.addNoise(firstIR, lastIR);
144
145 std::vector<ROFRecord> rofs{};
146 std::vector<Digit> digits{};
148 digitizer.digitize(rofs, digits, labels);
149
150 Segmentation seg1{detElemId1};
151 Segmentation seg2{detElemId2};
152 int digitcounter1 = 0;
153 int digitcounter2 = 0;
154 int digitcounter3 = 0;
155 int64_t previousROFtime = -1;
156 std::unordered_map<int, Digit> digitsMap{};
157
158 for (const auto& rof : rofs) {
159
160 // check ROF alignment on 4 BC
161 if (rof.getBCData().bc % 4 != 0) {
162 BOOST_FAIL(" ROF IR not aligned on 4 BC ");
163 }
164
165 // check ROFs ordering in ascending IR
166 auto rofTime = rof.getBCData().toLong();
167 if (rofTime < previousROFtime) {
168 BOOST_FAIL(" ROF not ordered in ascending IR ");
169 } else if (rofTime == previousROFtime) {
170 BOOST_FAIL(" 2 ROFs with the same IR ");
171 }
172 previousROFtime = rofTime;
173
174 for (int iDigit = rof.getFirstIdx(); iDigit <= rof.getLastIdx(); ++iDigit) {
175 const auto& digit = digits[iDigit];
176
177 // check hit-digit association
178 for (const auto& label : labels.getLabels(iDigit)) {
179 int trackID = label.getTrackID();
180 if (trackID == trackId1) {
181 digitcounter1 += check(hits1.at(0), digit, seg1, transformation);
182 } else if (trackID == trackId2) {
183 digitcounter2 += check(hits1.at(1), digit, seg2, transformation);
184 } else if (trackID == trackId3) {
185 digitcounter3 += check(hits2.at(0), digit, seg2, transformation);
186 } else if (!label.isNoise()) {
187 BOOST_FAIL(" MC-labels not matching between hit and digit ");
188 }
189 }
190
191 // check pileup handling within the readout window
192 auto itDigit = digitsMap.emplace((digit.getDetID() << 16) + digit.getPadID(), digit);
193 if (!itDigit.second &&
194 digit.getTime() - itDigit.first->second.getTime() < 4 * (itDigit.first->second.getNofSamples() + 2)) {
195 BOOST_FAIL(" same pad has multiple digits in overlapping readout windows ");
196 }
197 }
198 }
199
200 BOOST_TEST(digitcounter1 > 0);
201 BOOST_TEST(digitcounter1 < 20);
202 BOOST_TEST(digitcounter2 > 0);
203 BOOST_TEST(digitcounter2 < 10);
204 BOOST_TEST(digitcounter3 > 0);
205 BOOST_TEST(digitcounter3 < 10);
206}
207BOOST_AUTO_TEST_SUITE_END()
o2::mch::mapping::CathodeSegmentation seg
Definition of a container to keep Monte Carlo truth external to simulation objects.
Interface for MCH geometry creation.
Definition of the MagF class.
uint16_t pos
Definition RawData.h:3
T GetZ() const
Definition BaseHits.h:66
T GetY() const
Definition BaseHits.h:65
T GetX() const
Definition BaseHits.h:64
static void setValue(std::string const &mainkey, std::string const &subkey, T x)
static MagneticField * createFieldMap(float l3Current=-30000., float diCurrent=-6000., Int_t convention=0, Bool_t uniform=kFALSE, float beamenergy=7000, const Char_t *btype="pp", const std::string path=std::string(gSystem->Getenv("VMCWORKDIR"))+std::string("/Common/maps/mfchebKGI_sym.root"))
MCH digit implementation.
Definition Digit.h:31
int getPadID() const
Definition Digit.h:54
int getDetID() const
Definition Digit.h:52
int32_t getTime() const
Definition Digit.h:44
void addNoise(const InteractionRecord &firstIR, const InteractionRecord &lastIR)
Definition Digitizer.cxx:42
void processHits(gsl::span< const Hit > hits, const InteractionRecord &collisionTime, int evID, int srcID)
Definition Digitizer.cxx:35
size_t digitize(std::vector< ROFRecord > &rofs, std::vector< Digit > &digits, dataformats::MCLabelContainer &labels)
Definition Digitizer.cxx:49
double padSizeY(int catPadIndex) const
double padSizeX(int catPadIndex) const
double padPositionY(int catPadIndex) const
double padPositionX(int catPadIndex) const
bool isValid(int catPadIndex) const
Not every integer is a valid catPadIndex. This method will tell if catPadIndex is a valid one.
A Segmentation lets you find pads of a detection element and then inspect those pads.
GLuint GLsizei GLsizei * length
Definition glcorearb.h:790
GLuint GLsizei const GLchar * label
Definition glcorearb.h:2519
void check(const std::vector< std::string > &arguments, const std::vector< ConfigParamSpec > &workflowOptions, const std::vector< DeviceSpec > &deviceSpecs, CheckMatrix &matrix)
TransformationCreator transformationFromTGeoManager(const TGeoManager &geo)
std::function< o2::math_utils::Transform3D(int detElemId)> TransformationCreator
void createStandaloneGeometry()
Definition Helpers.cxx:112
static InteractionRecord long2IR(int64_t l)
BOOST_AUTO_TEST_CASE(DigitizerTest)
Test of the Digitization A couple of values are filled into Hits and we check whether we get reproduc...
void initField(float l3Current, float dipoleCurrent)
auto transformation
BOOST_CHECK(tree)
BOOST_TEST(digits==digitsD, boost::test_tools::per_element())
std::vector< Digit > digits