FairRoot
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
FairMQTransportDevice.cxx
Go to the documentation of this file.
1 /********************************************************************************
2  * Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
3  * *
4  * This software is distributed under the terms of the *
5  * GNU Lesser General Public Licence version 3 (LGPL) version 3, *
6  * copied verbatim in the file "LICENSE" *
7  ********************************************************************************/
15 #include "FairMQTransportDevice.h"
16 
17 #include "FairGenericStack.h"
18 #include "FairMCApplication.h"
19 #include "FairMCSplitEventHeader.h"
20 #include "FairModule.h"
21 #include "FairParSet.h"
22 #include "FairRunSim.h"
23 #include "FairRuntimeDb.h"
24 #include "FairTask.h"
25 #include "RootSerializer.h"
26 
27 #include <FairMQLogger.h>
28 #include <FairMQMessage.h>
29 #include <TClonesArray.h>
30 #include <TCollection.h>
31 #include <TList.h>
32 #include <TObjArray.h>
33 #include <TObject.h>
34 #include <TVirtualMC.h>
35 #include <cstring> // for strcmp
36 #include <dlfcn.h> // dlopen
37 #include <iostream>
38 #include <vector>
39 
40 using namespace std;
41 
43  : FairMQRunDevice()
44  , fRunId(0)
45  , fTransportDeviceId(0)
46  , fGeneratorChannelName("primariesChannel")
47  , fRunConditional(false)
48  , fRunInitialized(false)
49  , fVMC(nullptr)
50  , fStack(nullptr)
51  , fMCApplication(nullptr)
52  , fRunSim(nullptr)
53  , fNofEvents(1)
54  , fTransportName("TGeant3")
55  , fMaterialsFile("")
56  , fMagneticField(nullptr)
57  , fDetectorArray(nullptr)
58  , fStoreTrajFlag(false)
59  , fTaskArray(nullptr)
60  , fFirstParameter(nullptr)
61  , fSecondParameter(nullptr)
62  , fSink(nullptr)
63  , fMCSplitEventHeader(nullptr)
64 {}
65 
67 {
68  if (!fRunConditional)
69  OnData(fGeneratorChannelName, &FairMQTransportDevice::TransportData);
70 }
71 
73 {
74  fRunSim = new FairRunSim();
75 
76  fMCSplitEventHeader = new FairMCSplitEventHeader(fRunId, 0, 0, 0);
77  fRunSim->SetMCEventHeader(fMCSplitEventHeader);
78  fRunSim->SetRunId(fRunSim->GetMCEventHeader()->GetRunID());
79 
80  fRunSim->SetSink(fSink);
81 
82  if (fFirstParameter || fSecondParameter) {
83  FairRuntimeDb* rtdb = fRunSim->GetRuntimeDb();
84  if (fFirstParameter)
85  rtdb->setFirstInput(fFirstParameter);
86  if (fSecondParameter)
87  rtdb->setSecondInput(fSecondParameter);
88  }
89 
90  fRunSim->SetName(fTransportName.data());
91 
92  if (fUserConfig.Length() > 0)
93  fRunSim->SetUserConfig(fUserConfig);
94  if (fUserCuts.Length() > 0)
95  fRunSim->SetUserCuts(fUserCuts);
96 
97  // ----- Create media -------------------------------------------------
98  fRunSim->SetMaterials(fMaterialsFile.data());
99 
100  // ----- Magnetic field -------------------------------------------
101  if (fMagneticField)
102  fRunSim->SetField(fMagneticField);
103 
104  // ----- Create geometry ----------------------------------------------
105  for (int idet = 0; idet < fDetectorArray->GetEntries(); idet++) {
106  fRunSim->AddModule(dynamic_cast<FairModule*>(fDetectorArray->At(idet)));
107  }
108 
109  std::vector<std::string> detectorLibraries = fConfig->GetValue<std::vector<std::string>>("detector-library");
110 
111  for (unsigned int ilib = 0; ilib < detectorLibraries.size(); ilib++) {
112  LOG(info) << " -----> library \"" << detectorLibraries.at(ilib) << "\"";
113 
114  void* handle = dlopen(detectorLibraries.at(ilib).c_str(), RTLD_LAZY);
115 
116  if (!handle) {
117  LOG(fatal) << "Cannot open library: " << dlerror();
118  return;
119  }
120 
121  // load the symbol
122  LOG(info) << "Loading symbol ...";
123  typedef void (*det_t)();
124 
125  // reset errors
126  dlerror();
127  det_t ExternCreateDetector = (det_t)dlsym(handle, "ExternCreateDetector");
128  const char* dlsym_error = dlerror();
129  if (dlsym_error) {
130  LOG(fatal) << "Cannot load symbol 'ExternCreateDetector': " << dlsym_error;
131  dlclose(handle);
132  return;
133  }
134 
135  // run the function, where detector should be added to FairRunSim
137 
138  // close the library
139  LOG(info) << "NOT closing library...";
140  // dlclose(handle);
141  }
142 }
143 
145 {
146 
147  // ----- Negotiate the run number -------------------------------------
148  // ----- via the fUpdateChannelName --------------------------------
149  // ----- ask the fParamMQServer ------------------------------------
150  // ----- receive the run number and sampler id ---------------------
151  std::string* askForRunNumber = new string("ReportSimDevice");
152  FairMQMessagePtr req(NewMessage(
153  const_cast<char*>(askForRunNumber->c_str()),
154  askForRunNumber->length(),
155  [](void* /*data*/, void* object) { delete static_cast<string*>(object); },
156  askForRunNumber));
157  FairMQMessagePtr rep(NewMessage());
158 
159  if (Send(req, fUpdateChannelName) > 0) {
160  if (Receive(rep, fUpdateChannelName) > 0) {
161  std::string repString = string(static_cast<char*>(rep->GetData()), rep->GetSize());
162  LOG(info) << " -> " << repString.data();
163  fRunId = stoi(repString);
164  fMCSplitEventHeader->SetRunID(fRunId);
165  repString = repString.substr(repString.find_first_of('_') + 1, repString.length());
166  fTransportDeviceId = stoi(repString);
167  LOG(info) << "runId = " << fRunId << " /// fTransportDeviceId = " << fTransportDeviceId;
168  }
169  }
170 
171  fRunSim->SetStoreTraj(fStoreTrajFlag);
172 
173  // ----- Set tasks ----------------------------------------------------
174  if (fTaskArray) {
175  for (int itask = 0; itask < fTaskArray->GetEntries(); itask++) {
176  fRunSim->AddTask(dynamic_cast<FairTask*>(fTaskArray->At(itask)));
177  }
178  }
179 
180  // ----- Initialize simulation run ------------------------------------
181  // fRunSim->SetRunId(fRunId); // run n simulations with same run id - offset the event number
182  fRunSim->Init();
183 
184  fVMC = TVirtualMC::GetMC();
185  fMCApplication = FairMCApplication::Instance();
186  fStack = fMCApplication->GetStack();
187  fStack->Register();
188  // fRunSim->Run(0);
189  UpdateParameterServer();
190  LOG(info) << "end of FairMQTransportDevice::InitTask() run id = " << fRunSim->GetMCEventHeader()->GetRunID();
191  LOG(info) << " name/title/classname = " << fRunSim->GetMCEventHeader()->GetName() << "/"
192  << fRunSim->GetMCEventHeader()->GetTitle() << "/" << fRunSim->GetMCEventHeader()->ClassName();
193 
194  fRunInitialized = true;
195 }
196 
198 {
199  if (!fRunInitialized) {
200  InitializeRun();
201  }
202 }
203 
205 {
206  if (!fRunConditional)
207  return false;
208 
209  std::string* requestString = new string("RequestData");
210  FairMQMessagePtr req(NewMessage(
211  const_cast<char*>(requestString->c_str()),
212  requestString->length(),
213  [](void* /*data*/, void* object) { delete static_cast<string*>(object); },
214  requestString));
215  FairMQParts parts;
216  // FairMQMessagePtr rep(NewMessage());
217 
218  if (Send(req, fGeneratorChannelName) > 0) {
219  if (Receive(parts, fGeneratorChannelName) > 0) {
220  return TransportData(parts, 0);
221  }
222  }
223  return false;
224 }
225 
226 // bool FairMQTransportDevice::TransportData(FairMQMessagePtr& mPtr, int /*index*/)
227 // {
228 // TClonesArray* chunk = nullptr;
229 // Deserialize<RootSerializer>(*mPtr, chunk);
230 // fStack->SetParticleArray(chunk);
231 // fVMC->ProcessRun(1);
232 
233 // return true;
234 // }
235 
236 bool FairMQTransportDevice::TransportData(FairMQParts& mParts, int /*index*/)
237 {
238  TClonesArray* chunk = nullptr;
239  FairMCSplitEventHeader* meh = nullptr;
240  for (int ipart = 0; ipart < mParts.Size(); ipart++) {
241  TObject* obj = nullptr;
242  Deserialize<RootSerializer>(*mParts.At(ipart), obj);
243  if (strcmp(obj->GetName(), "MCEvent") == 0)
244  meh = dynamic_cast<FairMCSplitEventHeader*>(obj);
245  else if (strcmp(obj->GetName(), "TParticles") == 0)
246  chunk = dynamic_cast<TClonesArray*>(obj);
247  }
248  if (chunk != nullptr) {
249  fStack->SetParticleArray(chunk, meh->GetChunkStart(), meh->GetNPrim());
250  fMCSplitEventHeader->SetRECC(fRunId, meh->GetEventID(), meh->GetNofChunks(), meh->GetChunkStart());
251  fVMC->ProcessRun(1);
252  }
253 
254  return true;
255 }
256 
257 void FairMQTransportDevice::UpdateParameterServer()
258 {
259  FairRuntimeDb* rtdb = fRunSim->GetRuntimeDb();
260 
261  LOG(info) << "FairMQTransportDevice::UpdateParameterServer() (" << rtdb->getListOfContainers()->GetEntries()
262  << " containers)";
263 
264  // send the parameters to be saved
265  TIter next(rtdb->getListOfContainers());
266  FairParSet* cont;
267  while ((cont = static_cast<FairParSet*>(next()))) {
268  std::string ridString = std::string("RUNID") + std::to_string(fRunSim->GetRunId()) + std::string("RUNID")
269  + std::string(cont->getDescription());
270  cont->setDescription(ridString.data());
271  SendObject(cont, fUpdateChannelName);
272  }
273 
274  LOG(info) << "FairMQTransportDevice::UpdateParameterServer() finished";
275 }
276 
278 
list of container factories
Definition: FairRuntimeDb.h:24
UInt_t GetRunID() const
void SetField(FairField *field)
Definition: FairRunSim.cxx:308
FairMCEventHeader * GetMCEventHeader()
Definition: FairRunSim.cxx:357
Bool_t setSecondInput(FairParIo *)
void SetRunId(UInt_t runId)
Definition: FairRun.h:102
virtual void SetParticleArray(__attribute__((unused)) TClonesArray *partArray)
FairGenericStack * GetStack()
void SetSink(FairSink *tempSink)
Definition: FairRun.h:84
TList * getListOfContainers()
void SendObject(TObject *obj, const std::string &chan)
static FairMCApplication * Instance()
Int_t GetNPrim() const
impact parameter [fm]
virtual void Register()
void SetUserCuts(const TString &Cuts)
Definition: FairRunSim.h:153
virtual void Init()
Definition: FairRunSim.cxx:143
void SetRunID(UInt_t runId)
FairRuntimeDb * GetRuntimeDb(void)
Definition: FairRun.h:80
void SetMaterials(const char *MatFileName)
Definition: FairRunSim.cxx:312
void SetUserConfig(const TString &Config)
Definition: FairRunSim.h:150
virtual void AddTask(FairTask *t)
Definition: FairRun.cxx:70
void ExternCreateDetector()
Definition: Pixel.cxx:190
void AddModule(FairModule *Mod)
Definition: FairRunSim.cxx:118
void SetRECC(UInt_t i1, UInt_t i2, UInt_t i3, UInt_t i4)
Bool_t setFirstInput(FairParIo *)
void SetMCEventHeader(FairMCEventHeader *McHeader)
Definition: FairRunSim.h:86
void setDescription(const char *s)
Definition: FairParSet.h:80
Int_t GetRunId()
Definition: FairRun.h:97
UInt_t GetEventID() const
run identifier
bool TransportData(FairMQParts &, int)
void SetStoreTraj(Bool_t storeTraj=kTRUE)
Definition: FairRunSim.h:92