CbmRoot
Loading...
Searching...
No Matches
CbmMCInputSet.cxx
Go to the documentation of this file.
1/* Copyright (C) 2018-2020 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Volker Friese [committer] */
4
10#include "CbmMCInputSet.h"
11
12#include "FairRootManager.h"
13#include <Logger.h>
14
15#include <cassert>
16
18
19
20// ----- Default constructor ---------------------------------------------
22// ---------------------------------------------------------------------------
23
24
25// ----- Constructor -----------------------------------------------------
26CbmMCInputSet::CbmMCInputSet(TimeDist dist, Double_t eventRate)
27 : TObject()
28 , fTimeDist(dist)
29 , fEventRate(eventRate)
30 , fInputs()
31 , fInputHandle()
32 , fBranches()
33 , fDeltaDist(nullptr)
34{
35
36 if (fTimeDist == TimeDist::Poisson && eventRate > 0.) {
37 Double_t mean = 1.e9 / eventRate; // mean time between events in ns
38 fDeltaDist = new TF1("DeltaDist", "exp(-x/[0])/[0]", 0., 10. * mean, "NL");
39 fDeltaDist->SetParameter(0, mean);
40 }
41 fInputHandle = fInputs.begin();
42}
43// ---------------------------------------------------------------------------
44
45
46// ----- Destructor ------------------------------------------------------
48{
49 if (fDeltaDist) delete fDeltaDist;
50 for (auto const& entry : fInputs)
51 if (entry.second) delete entry.second;
52}
53// ---------------------------------------------------------------------------
54
55
56// ----- Set the branch address of an input branch -----------------------
57Bool_t CbmMCInputSet::ActivateObject(TObject** object, const char* branchName)
58{
59
60 // The branch address has to be set for each input chain
61 for (auto const& mapEntry : fInputs) {
62 CbmMCInput* input = mapEntry.second;
63 assert(input);
64 input->GetChain()->SetBranchStatus(branchName, 1);
65 input->GetChain()->SetBranchAddress(branchName, object);
66 }
67
68 return kTRUE;
69}
70// ---------------------------------------------------------------------------
71
72
73// ----- Add an input to the set -----------------------------------------
74void CbmMCInputSet::AddInput(UInt_t inputId, TChain* chain, ECbmTreeAccess mode)
75{
76
77 // Catch invalid chain pointer.
78 if (!chain) {
79 LOG(fatal) << "MCInputSet: invalid chain for input ID " << inputId << "!";
80 return;
81 } //? No valid input chain
82
83 // Catch input ID already being used.
84 if (fInputs.find(inputId) != fInputs.end()) {
85 LOG(fatal) << "MCInputSet: input ID " << inputId << " is already defined!";
86 return;
87 } //? Input ID already used
88
89 // Create CbmMCInput object
90 CbmMCInput* input = new CbmMCInput(chain, mode);
91
92 // The first input defines the reference branch list.
93 if (fInputs.empty()) { fBranches = input->GetBranchList(); } //? First input
94
95 // Check compatibility of the input branch list with the reference list.
96 else {
97 if (!CheckBranchList(input)) {
98 LOG(fatal) << "MCInputSet: Incompatible branch list!";
99 return;
100 } //? Branch list not compatible
101 } //? Not first input
102
103 // Register input and set input handle
104 fInputs[inputId] = input;
105 fInputHandle = fInputs.begin();
106}
107// ---------------------------------------------------------------------------
108
109
110// ----- Check the branch list of an input -------------------------------
112{
113
114 assert(input);
115 Bool_t success = kTRUE;
116 for (auto const& entry : fBranches) {
117 auto it = input->GetBranchList().find(entry);
118 if (it == input->GetBranchList().end()) {
119 LOG(debug) << "MCInputSet: Required branch " << entry << " not present in input!";
120 success = kFALSE;
121 break;
122 } //? Global branch not in input
123 } //# Global branches
124
125 if (!success) {
126 std::stringstream ss;
127 ss << "MCInputSet: Reference branch list is ";
128 for (auto const& entry : fBranches)
129 ss << entry << " ";
130 LOG(info) << ss.str();
131 std::stringstream ss1;
132 ss1 << "MCInputSet: Input branch list is ";
133 for (auto const& entry : input->GetBranchList())
134 ss1 << entry << " ";
135 LOG(info) << ss1.str();
136 } //? Branches not compatible
137
138 return success;
139}
140// ---------------------------------------------------------------------------
141
142
143// ----- Time difference to next event -----------------------------------
145{
146
147 // --- Poisson distribution: delta_t sampled from exponential distribution
148 if (fTimeDist == TimeDist::Poisson) {
149 assert(fDeltaDist);
150 return fDeltaDist->GetRandom();
151 }
152
153 // --- Uniform distribution: delta_t is the inverse event rate
154 else if (fTimeDist == TimeDist::Uniform) {
155 return 1.e9 / fEventRate; // rate is in 1/s, delta_t in ns
156 }
157
158 // --- Just in case: catch unknown distribution models
159 else
160 return 0.;
161}
162// ---------------------------------------------------------------------------
163
164
165// ----- Maximal number of events to be read from the input --------------
167{
168
169 Int_t minimum = -1;
170
171 for (auto const& entry : fInputs) {
172 Int_t test = entry.second->GetMaxNofEvents();
173 LOG(info) << "MCInputSet: Max. number of events for input " << entry.first << " is " << test;
174 if (test >= 0 && (minimum == -1 || test < minimum)) minimum = test;
175 } //# Inputs
176
177 minimum *= fInputs.size();
178 LOG(info) << "MCInputSet: Maximal number of events is " << minimum;
179
180 return minimum;
181}
182// ---------------------------------------------------------------------------
183
184
185// ----- Get next entry from chain ---------------------------------------
186std::tuple<Bool_t, UInt_t, Int_t> CbmMCInputSet::GetNextEntry()
187{
188
189 // Flag for having reached the last input
190 Bool_t allInputsUsed = kFALSE;
191
192 // The input handle points to the input to be used
193 Int_t entry = fInputHandle->second->GetNextEntry();
194 Int_t inputId = fInputHandle->first;
195
196 // Increment input handle. If end of set reached, signal that and
197 // reset the handle to the begin.
198 fInputHandle++;
199 if (fInputHandle == fInputs.end()) {
200 allInputsUsed = kTRUE;
201 fInputHandle = fInputs.begin();
202 }
203
204 return std::make_tuple(allInputsUsed, inputId, entry);
205}
206// ---------------------------------------------------------------------------
207
208
209// ----- Register input chains to FairRootManager ------------------------
211{
212 for (auto const& mapEntry : fInputs) {
213 FairRootManager::Instance()->SetInChain(mapEntry.second->GetChain(), mapEntry.first);
214 }
215}
216// ---------------------------------------------------------------------------
217
218
ClassImp(CbmConverterManager)
ECbmTreeAccess
Mode to read entries from a ROOT TTree.
Definition CbmDefs.h:152
A MC transport input to digitisation in CBM.
Double_t GetDeltaT()
Time difference to next event @value Time difference to next event [ns].
void AddInput(UInt_t inputId, TChain *chain, ECbmTreeAccess mode=ECbmTreeAccess::kRegular)
Add an input to the set.
virtual ~CbmMCInputSet()
Destructor.
std::tuple< Bool_t, UInt_t, Int_t > GetNextEntry()
Get the next entry from the inputs @value Status tuple.
void RegisterChains()
register all input chains to the FairRootManager
cbm::sim::TimeDist fTimeDist
Bool_t CheckBranchList(CbmMCInput *input)
Compare an input branch list with the reference branch list.
virtual Bool_t ActivateObject(TObject **object, const char *branchName)
Activate and connect all input chains.
std::set< TString > fBranches
Int_t GetMaxNofEvents() const
Maximal number of events to be read from the input set @value Maximal number of events.
CbmMCInputSet()
Default constructor.
std::map< UInt_t, CbmMCInput * >::iterator fInputHandle
Double_t fEventRate
std::map< UInt_t, CbmMCInput * > fInputs
An MC (transport) input to digitisation in CBM.
Definition CbmMCInput.h:33
std::set< TString > & GetBranchList()
List of branches @value Reference to branch list.
TChain * GetChain() const
Pointer to chain @value Pointer to TChain object.
Definition CbmMCInput.h:60
TimeDist
Definition Defs.h:29