Project
Loading...
Searching...
No Matches
testStack.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 MCStack class
13#define BOOST_TEST_MAIN
14#define BOOST_TEST_DYN_LINK
15#include <boost/test/unit_test.hpp>
17#include "DetectorsBase/Stack.h"
19#include "TFile.h"
20#include "TMCProcess.h"
21#include "TRefArray.h"
22#include <map>
23#include <string>
24#include <vector>
25
26using namespace o2;
27
28// unit tests on MC stack
30{
32 int a;
33 TMCProcess proc{kPPrimary};
34 // add a 2 primary particles
35 st.PushTrack(1, -1, 0, 0, 0., 0., 10., 5., 5., 5., 0.1, 0., 0., 0., proc, a, 1., 1);
36 st.PushTrack(1, -1, 0, 0, 0., 0., 10., 5., 5., 5., 0.1, 0., 0., 0., proc, a, 1., 1);
37 BOOST_CHECK(st.getPrimaries().size() == 2);
38
39 {
40 // serialize it
41 TFile f("StackOut.root", "RECREATE");
42 f.WriteObject(&st, "Stack");
43 f.Close();
44 }
45
46 {
47 o2::data::Stack* inst = nullptr;
48 TFile f("StackOut.root", "OPEN");
49 f.GetObject("Stack", inst);
50 BOOST_CHECK(inst->getPrimaries().size() == 2);
51 }
52}
53
54// convenience wrapper to push a track and return the assigned trackID
55static int pushTrack(o2::data::Stack& st, int parentId, TMCProcess proc)
56{
57 int trackId;
58 st.PushTrack(1, parentId, 0, 0., 0., 0., 10., 5., 5., 5., 0.1, 0., 0., 0., proc, trackId, 1., 1);
59 return trackId;
60}
61
62// unit test for the radioactive-decay ancestry query
63BOOST_AUTO_TEST_CASE(Stack_isFromRadDecay_test)
64{
66
67 // two primaries; note that primaries do not enter mParticles, only secondaries do
68 const auto prim0 = pushTrack(st, -1, kPPrimary);
69 const auto prim1 = pushTrack(st, -1, kPPrimary);
70
71 // a radioactive decay product of the second primary, and its descendants.
72 // this is deliberately the *first* secondary of the primary, so that it lands
73 // in the first entry of the particle buffer
74 const auto radDecay = pushTrack(st, prim1, kPRadDecay);
75 const auto radChild = pushTrack(st, radDecay, kPHadronic);
76 const auto radGrandChild = pushTrack(st, radChild, kPHadronic);
77
78 // a plain secondary of the second primary: no radioactive decay anywhere in its history
79 const auto ordinary = pushTrack(st, prim1, kPHadronic);
80
81 // primaries can never come from a radioactive decay
82 BOOST_CHECK(!st.isFromRadDecay(prim0));
83 BOOST_CHECK(!st.isFromRadDecay(prim1));
84
85 // a secondary whose ancestry ends in a primary must terminate the search with false
86 BOOST_CHECK(!st.isFromRadDecay(ordinary));
87
88 // directly and indirectly from a radioactive decay
89 BOOST_CHECK(st.isFromRadDecay(radDecay));
90 BOOST_CHECK(st.isFromRadDecay(radChild));
91 BOOST_CHECK(st.isFromRadDecay(radGrandChild));
92
93 // out-of-range track IDs are rejected rather than looked up
94 BOOST_CHECK(!st.isFromRadDecay(-1));
95 BOOST_CHECK(!st.isFromRadDecay(1000000000));
96}
97
98namespace
99{
100// A test detector to exercise hit creation and its interaction with the MCStack
101class TestDetector : public o2::base::Detector
102{
103 public:
104 // the name is turned into a DetID, so it has to be one of the real detectors
105 TestDetector() : o2::base::Detector("ITS", true) {}
106
107 void updateHitTrackIndices(std::map<int, int> const& indexmapping) override
108 {
109 for (auto& hit : mHits) {
110 hit.SetTrackID(updatedTrackIndex(indexmapping, hit.GetTrackID()));
111 }
112 }
113
114 std::vector<o2::BaseHit> mHits;
115
116 // rest of the interface, unused here
117 std::string getHitBranchNames(int) const override { return {}; }
118 void attachHits(fair::mq::Channel&, fair::mq::Parts&) override {}
119 void fillHitBranch(TTree&, fair::mq::Parts&, int&) override {}
120 void collectHits(int, fair::mq::Parts&, int&) override {}
121 void mergeHitEntriesAndFlush(int, TTree&, std::vector<int> const&, std::vector<int> const&,
122 std::vector<int> const&) override {}
123 void mergeHitEntries(TTree&, TTree&, std::vector<int> const&, std::vector<int> const&,
124 std::vector<int> const&) override {}
125 void InitializeO2Detector() override {}
126 void initializeLate() override {}
127 Bool_t ProcessHits(FairVolume* = nullptr) override { return kFALSE; }
128 void Register() override {}
129 void Reset() override {}
130 void ConstructGeometry() override {}
131};
132
133// Transport one primary with n secondaries, so that the stack builds its mapping
134void transportOnePrimary(o2::data::Stack& st, int nsecondaries)
135{
136 int ntr = 0;
137 st.PushTrack(1, -1, 11, 0., 0., 1., 1., 0., 0., 0., 0., 0., 0., 0., kPPrimary, ntr, 1., 1);
138 st.SetCurrentTrack(0);
139 for (int i = 0; i < nsecondaries; ++i) {
140 st.PushTrack(1, 0, 11, 0., 0., 0.1, 0.1, 0., 0., 0., 0., 0., 0., 0., kPHadronic, ntr, 1., 1);
141 }
142 st.FinishPrimary();
143}
144} // namespace
145
146// A pruned track has no entry in the mapping
147BOOST_AUTO_TEST_CASE(Unmapped_trackID_yields_invalid_index)
148{
149 const std::map<int, int> indexmapping{{0, 0}, {1, 1}};
150
153}
154
155// The mapping is per event and must not survive Reset()
156BOOST_AUTO_TEST_CASE(Stack_does_not_reuse_index_map_of_previous_event)
157{
158 TestDetector det;
159 TRefArray detlist;
160 detlist.Add(&det);
161
163 transportOnePrimary(st, 20); // event 1: trackIDs 0 to 20
164 st.UpdateTrackIndex(&detlist);
165 st.Reset();
166
167 transportOnePrimary(st, 1); // event 2: trackIDs 0 and 1 only
168 det.mHits.emplace_back(15); // only valid in event 1
169 st.UpdateTrackIndex(&detlist);
170
171 BOOST_CHECK_EQUAL(det.mHits[0].GetTrackID(), -1);
172}
173
174// An invalid index must not be offset when sub-events are merged
175BOOST_AUTO_TEST_CASE(Offsetting_keeps_an_invalid_index_invalid)
176{
177 const int nprimaries = 5, primaryOffset = 10, secondaryOffset = 100;
178
179 BOOST_CHECK_EQUAL(o2::base::Detector::offsetTrackIndex(3, nprimaries, primaryOffset, secondaryOffset), 13);
180 BOOST_CHECK_EQUAL(o2::base::Detector::offsetTrackIndex(7, nprimaries, primaryOffset, secondaryOffset), 107);
181 BOOST_CHECK_EQUAL(o2::base::Detector::offsetTrackIndex(-1, nprimaries, primaryOffset, secondaryOffset), -1);
182}
Definition of the Detector class.
Definition of the Stack class.
int32_t i
benchmark::State & st
virtual std::string getHitBranchNames(int probe) const =0
virtual void initializeLate()=0
virtual void attachHits(fair::mq::Channel &, fair::mq::Parts &)=0
static int updatedTrackIndex(std::map< int, int > const &indexmapping, int trackID)
Definition Detector.h:168
virtual void updateHitTrackIndices(std::map< int, int > const &)=0
virtual void mergeHitEntries(TTree &origin, TTree &target, std::vector< int > const &trackoffsets, std::vector< int > const &nprimaries, std::vector< int > const &subevtsOrdered)=0
virtual void fillHitBranch(TTree &tr, fair::mq::Parts &parts, int &index)=0
virtual void mergeHitEntriesAndFlush(int eventID, TTree &target, std::vector< int > const &trackoffsets, std::vector< int > const &nprimaries, std::vector< int > const &subevtsOrdered)=0
static int offsetTrackIndex(int trackID, int nprimaries, int primaryOffset, int secondaryOffset)
Definition Detector.h:177
virtual void InitializeO2Detector()=0
Definition Detector.cxx:98
virtual void collectHits(int eventID, fair::mq::Parts &parts, int &index)=0
void PushTrack(Int_t toBeDone, Int_t parentID, Int_t pdgCode, Double_t px, Double_t py, Double_t pz, Double_t e, Double_t vx, Double_t vy, Double_t vz, Double_t time, Double_t polx, Double_t poly, Double_t polz, TMCProcess proc, Int_t &ntr, Double_t weight, Int_t is) override
Definition Stack.cxx:176
const std::vector< TParticle > & getPrimaries() const
Definition Stack.h:187
GLdouble f
Definition glcorearb.h:310
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
return true
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
BOOST_AUTO_TEST_CASE(FlatHisto)
BOOST_CHECK(tree)
BOOST_CHECK_EQUAL(triggersD.size(), triggers.size())