CbmRoot
Loading...
Searching...
No Matches
CbmMCPointSource.cxx
Go to the documentation of this file.
1/* Copyright (C) 2019-2020 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Florian Uhlig [committer] */
4
11
12#include "CbmMCPointSource.h"
13
14#include "CbmMQDefs.h"
15#include "CbmMuchPoint.h"
16#include "CbmMvdPoint.h"
17#include "CbmRichPoint.h"
18#include "CbmStsPoint.h"
19#include "CbmTofPoint.h"
20#include "CbmTrdPoint.h"
21#include "CbmPsdPoint.h"
22
23#include "FairFileSource.h"
24#include "FairMQLogger.h"
25#include "FairMQProgOptions.h" // device->fConfig
26#include "FairRootManager.h"
27#include "FairRunAna.h"
28
29#include "TClonesArray.h"
30
31//#include <boost/archive/binary_oarchive.hpp>
32// include this header to serialize vectors
33//#include <boost/serialization/vector.hpp>
34
35#include <thread> // this_thread::sleep_for
36
37#include <chrono>
38#include <ctime>
39#include <stdexcept>
40
41#include <stdio.h>
42
43using namespace std;
44
45struct InitTaskError : std::runtime_error {
46 using std::runtime_error::runtime_error;
47};
48
49
51try {
52 // Get the values from the command line options (via fConfig)
53 fFileName = fConfig->GetValue<string>("filename");
54 fMaxEvents = fConfig->GetValue<uint64_t>("max-events");
55
56
57 LOG(info) << "Filename: " << fFileName;
58 LOG(info) << "MaxEvents: " << fMaxEvents;
59
60 // Check if the defined channels from the topology (by name)
61 // are in the list of channels which are allowed
62 fChan.CheckChannels(this);
63 fComponentsToSend = fChan.GetComponentsToSend();
64 fChannelsToSend = fChan.GetChannelsToSend();
65
66 for (auto const& value : fComponentsToSend) {
67 if (value > 1) {
68 throw InitTaskError("Sending same data to more than one output channel "
69 "not implemented yet.");
70 }
71 }
72
73 // Here we need to create an instance of FairRunAna to avoid a crash when creating the FairRootmanager
74 // This is only a workaround since we actually don't need FairRunAna and the underlying problem has to
75 // be fixed in FairRoot. The command ana->SetContainerStatic() is only
76 // used to silence a compiler warning
77 FairRunAna* ana = new FairRunAna();
78 ana->SetContainerStatic();
79 FairRootManager* rootman = FairRootManager::Instance();
80
81 if (0 != fFileName.size()) {
82 LOG(info) << "Open the ROOT input file " << fFileName;
83 // Check if the input file exist
84 FILE* inputFile = fopen(fFileName.c_str(), "r");
85 if (!inputFile) { throw InitTaskError("Input file doesn't exist."); }
86 fclose(inputFile);
87 FairFileSource* source = new FairFileSource(fFileName);
88 if (!source) { throw InitTaskError("Could not open input file."); }
89 rootman->SetSource(source);
90 rootman->InitSource();
91
92
93 for (unsigned i = 0; i < fComponentsToSend.size(); i++) {
94 if (1 == fComponentsToSend.at(i)) { // there is a device connected which consumes data of this type
95 std::vector<std::string> channel_name = fChannelsToSend.at(i);
96 LOG(info) << channel_name.at(0);
97 ConnectChannelIfNeeded(i, channel_name.at(0), "MvdPoint", rootman);
98 ConnectChannelIfNeeded(i, channel_name.at(0), "StsPoint", rootman);
99 ConnectChannelIfNeeded(i, channel_name.at(0), "RichPoint", rootman);
100 ConnectChannelIfNeeded(i, channel_name.at(0), "MuchPoint", rootman);
101 ConnectChannelIfNeeded(i, channel_name.at(0), "TrdPoint", rootman);
102 ConnectChannelIfNeeded(i, channel_name.at(0), "TofPoint", rootman);
103 ConnectChannelIfNeeded(i, channel_name.at(0), "PsdPoint", rootman);
104 }
105 else {
106 fArrays.at(i) = nullptr;
107 }
108 }
109 }
110 else {
111 throw InitTaskError("No input file specified");
112 }
113
114 Int_t MaxAllowed = FairRootManager::Instance()->CheckMaxEventNo(fMaxEvents);
115 if (MaxAllowed != -1) {
116 if (fMaxEvents == 0) { fMaxEvents = MaxAllowed; }
117 else {
118 if (static_cast<Int_t>(fMaxEvents) > MaxAllowed) {
119 LOG(warn) << "-------------------Warning---------------------------";
120 LOG(warn) << " File has less events than requested!!";
121 LOG(warn) << " File contains : " << MaxAllowed << " Events";
122 LOG(warn) << " Requested number of events = " << fMaxEvents << " Events";
123 LOG(warn) << " The number of events is set to " << MaxAllowed << " Events";
124 LOG(warn) << "-----------------------------------------------------";
125 fMaxEvents = MaxAllowed;
126 }
127 }
128 LOG(info) << "After checking, the run will run from event 0 "
129 << " to " << fMaxEvents << ".";
130 }
131 else {
132 LOG(info) << "continue running without stop";
133 }
134
135
136 fTime = std::chrono::steady_clock::now();
137}
138catch (InitTaskError& e) {
139 LOG(error) << e.what();
140 // Wrapper defined in CbmMQDefs.h to support different FairMQ versions
142}
143
144void CbmMCPointSource::ConnectChannelIfNeeded(int chan_number, std::string channel_name, std::string branchname,
145 FairRootManager* rootman)
146{
147 if (0 == channel_name.compare(branchname)) {
148 LOG(info) << "Found expected data type " << branchname;
149 TClonesArray* arr = static_cast<TClonesArray*>(rootman->GetObject(branchname.c_str()));
150 if (!arr) {
151 LOG(info) << "Consuming device connected but no " << branchname << " array in input file!";
152 fComponentsToSend.at(chan_number) = 0; // Don't send to connected device since needed data is not in input
153 }
154 fArrays.at(chan_number) = arr;
155 }
156}
157
158
160{
161
162 Int_t readEventReturn = FairRootManager::Instance()->ReadEvent(fEventCounter);
163 // LOG(info) <<"Return value: " << readEventReturn;
164
165 if (readEventReturn != 0) {
166 LOG(warn) << "FairRootManager::Instance()->ReadEvent(" << fEventCounter << ") returned " << readEventReturn
167 << ". Breaking the event loop";
168 CalcRuntime();
169 return false;
170 }
171
172 for (unsigned i = 0; i < fComponentsToSend.size(); i++) {
173 bool result = true;
174 if (1 == fComponentsToSend.at(i)) { // there is a device connected which consumes data of this type
175
176 if (0 == fChannelsToSend.at(i).at(0).compare("MvdPoint")) {
177 result = ConvertAndSend<CbmMvdPoint>(fArrays.at(i), i);
178 }
179 if (0 == fChannelsToSend.at(i).at(0).compare("StsPoint")) {
180 result = ConvertAndSend<CbmStsPoint>(fArrays.at(i), i);
181 }
182 if (0 == fChannelsToSend.at(i).at(0).compare("RichPoint")) {
183 result = ConvertAndSend<CbmRichPoint>(fArrays.at(i), i);
184 }
185 if (0 == fChannelsToSend.at(i).at(0).compare("MuchPoint")) {
186 result = ConvertAndSend<CbmMuchPoint>(fArrays.at(i), i);
187 }
188 if (0 == fChannelsToSend.at(i).at(0).compare("TrdPoint")) {
189 result = ConvertAndSend<CbmTrdPoint>(fArrays.at(i), i);
190 }
191 if (0 == fChannelsToSend.at(i).at(0).compare("TofPoint")) {
192 result = ConvertAndSend<CbmTofPoint>(fArrays.at(i), i);
193 }
194 if (0 == fChannelsToSend.at(i).at(0).compare("PsdPoint")) {
195 result = ConvertAndSend<CbmPsdPoint>(fArrays.at(i), i);
196 }
197
198 if (!result) {
199 LOG(error) << "Problem sending data";
200 return false;
201 }
202 }
203 }
204
205 if (fEventCounter % 10000 == 0) LOG(info) << "Analyse Event " << fEventCounter;
207
208
209 // LOG(info) << "Counter: " << fEventCounter << " Events: " << fMaxEvents;
210 if (fEventCounter < fMaxEvents) { return true; }
211 else {
212 CalcRuntime();
213 return false;
214 }
215}
216
218
220{
221 std::chrono::duration<double> run_time = std::chrono::steady_clock::now() - fTime;
222
223 LOG(info) << "Runtime: " << run_time.count();
224 LOG(info) << "No more input data";
225}
int Int_t
CbmMQChannels fChan
virtual bool ConditionalRun()
std::string fFileName
std::chrono::steady_clock::time_point fTime
bool ConvertAndSend(TClonesArray *arr, int i)
virtual void InitTask()
void ConnectChannelIfNeeded(int, std::string, std::string, FairRootManager *)
std::vector< int > fComponentsToSend
std::vector< TClonesArray * > fArrays
std::vector< std::vector< std::string > > fChannelsToSend
void ChangeState(FairMQDevice *device, cbm::mq::Transition transition)
Definition CbmMQDefs.h:26
Hash for CbmL1LinkKey.