Line data Source code
1 : /**************************************************************************
2 : * Copyright(c) 1998-2015, ALICE Experiment at CERN, All rights reserved. *
3 : * *
4 : * Author: The ALICE Off-line Project. *
5 : * Contributors are mentioned in the code where appropriate. *
6 : * *
7 : * Permission to use, copy, modify and distribute this software and its *
8 : * documentation strictly for non-commercial purposes is hereby granted *
9 : * without fee, provided that the above copyright notice appears in all *
10 : * copies and that both the copyright notice and this permission notice *
11 : * appear in the supporting documentation. The authors make no claims *
12 : * about the suitability of this software for any purpose. It is *
13 : * provided "as is" without express or implied warranty. *
14 : **************************************************************************/
15 :
16 : // Event generator that can runs an external executable
17 : // to produce events which are read in HepMC or ROOT format.
18 : //
19 : // Author: Jochen Klein <Jochen.Klein@cern.ch>
20 :
21 : #include <sys/types.h>
22 : #include <sys/stat.h>
23 :
24 : #include "TSystem.h"
25 :
26 : #include "AliLog.h"
27 : #include "AliGenReaderHepMC.h"
28 : #include "AliGenEposReader.h"
29 :
30 : #include "AliGenExtExec.h"
31 :
32 : AliGenExtExec::AliGenExtExec(const TString &scriptpath) :
33 0 : AliGenExtFile(),
34 0 : fPathScript(scriptpath),
35 0 : fPathFIFO("gen.hepmc"),
36 0 : fPathFile1("gen1.root"),
37 0 : fPathFile2("gen2.root"),
38 0 : fEventNumberInFileMax(100),
39 0 : fMode(kFIFO),
40 0 : fInput(kHepMC),
41 0 : fPID(0),
42 0 : fFileConnected(0),
43 0 : fEventNumberInFile(0)
44 0 : {
45 : // default constructor
46 :
47 0 : gSystem->ExpandPathName(fPathScript);
48 0 : }
49 :
50 : AliGenExtExec::AliGenExtExec(Int_t npart, const TString &scriptpath) :
51 0 : AliGenExtFile(npart),
52 0 : fPathScript(scriptpath),
53 0 : fPathFIFO("gen.hepmc"),
54 0 : fPathFile1("gen1.root"),
55 0 : fPathFile2("gen2.root"),
56 0 : fEventNumberInFileMax(100),
57 0 : fMode(kFIFO),
58 0 : fInput(kHepMC),
59 0 : fPID(0),
60 0 : fFileConnected(0),
61 0 : fEventNumberInFile(0)
62 0 : {
63 : // constructor
64 :
65 0 : gSystem->ExpandPathName(fPathScript);
66 0 : }
67 :
68 0 : AliGenExtExec::~AliGenExtExec()
69 0 : {
70 : // destructor
71 :
72 0 : StopGen();
73 0 : }
74 :
75 : void AliGenExtExec::SetPathScript(const TString &path)
76 : {
77 : // set and expand path to executable script
78 :
79 0 : fPathScript = path;
80 0 : gSystem->ExpandPathName(fPathScript);
81 0 : }
82 :
83 : void AliGenExtExec::SetPathFIFO(const TString &path)
84 : {
85 : // set and expand path used for FIFO
86 :
87 0 : fPathFIFO = path;
88 0 : gSystem->ExpandPathName(fPathFIFO);
89 0 : }
90 :
91 : void AliGenExtExec::SetPathFile1(const TString &path)
92 : {
93 : // set and expand path used for file 1
94 :
95 0 : fPathFile1 = path;
96 0 : gSystem->ExpandPathName(fPathFile1);
97 0 : }
98 :
99 : void AliGenExtExec::SetPathFile2(const TString &path)
100 : {
101 : // set and expand path used for file 2
102 :
103 0 : fPathFile2 = path;
104 0 : gSystem->ExpandPathName(fPathFile2);
105 0 : }
106 :
107 : void AliGenExtExec::Init()
108 : {
109 : // initialization:
110 : // start generator, setup reader, and initialize AliGenExtFile
111 :
112 : // setup and run the generator
113 0 : StartGen();
114 :
115 : // create and set HepMC reader
116 0 : if (fInput == kHepMC) {
117 0 : AliGenReaderHepMC *reader = new AliGenReaderHepMC();
118 0 : SetReader(reader);
119 0 : } else if (fInput == kEPOSroot) {
120 0 : AliGenEposReader *reader = new AliGenEposReader();
121 0 : SetReader(reader);
122 0 : } else {
123 0 : AliFatal(Form("Invalid input type: %i", fInput));
124 : }
125 :
126 0 : if (fMode == kFIFO) {
127 0 : Reader()->SetFileName(fPathFIFO);
128 0 : AliGenExtFile::Init();
129 0 : }
130 0 : }
131 :
132 : void AliGenExtExec::Generate()
133 : {
134 : // generate next event
135 : // depending on mode read from FIFO or files
136 :
137 0 : switch (fMode) {
138 : case kFIFO:
139 0 : AliGenExtFile::Generate();
140 0 : break;
141 :
142 : case kAlternatingFiles:
143 : // connect a new file if needed
144 : // (i.e. no file yet or reached the end)
145 0 : while ((fFileConnected == 0) ||
146 0 : (fEventNumberInFile == fEventNumberInFileMax)) {
147 :
148 0 : if ((fFileConnected != 1) &&
149 0 : !gSystem->AccessPathName(fPathFile1)) {
150 0 : if (fInput == kEPOSroot)
151 0 : ((AliGenEposReader*) Reader())->ChangeFile(fPathFile1);
152 : else
153 0 : AliFatal(Form("Alternating files not supported for input type: %i", fInput));
154 :
155 0 : if (fFileConnected == 2)
156 0 : gSystem->Unlink(fPathFile2);
157 0 : fFileConnected = 1;
158 0 : fEventNumberInFile = 0;
159 0 : } else if ((fFileConnected != 2) &&
160 0 : !gSystem->AccessPathName(fPathFile2)) {
161 0 : if (fInput == kEPOSroot)
162 0 : ((AliGenEposReader*) Reader())->ChangeFile(fPathFile2);
163 : else
164 0 : AliFatal(Form("Alternating files not supported for input type: %i", fInput));
165 :
166 0 : if (fFileConnected == 1)
167 0 : gSystem->Unlink(fPathFile1);
168 0 : fFileConnected = 2;
169 0 : fEventNumberInFile = 0;
170 0 : } else {
171 : // wait for further input to become available
172 0 : sleep(1);
173 : }
174 : }
175 :
176 0 : fEventNumberInFile++;
177 :
178 0 : AliGenExtFile::Generate();
179 :
180 0 : break;
181 :
182 : default:
183 0 : AliFatal(Form("Unknown mode for external generator: %i", fMode));
184 0 : }
185 0 : }
186 :
187 : Bool_t AliGenExtExec::StartGen()
188 : {
189 : // prepare FIFO and start the generator (if not yet running)
190 : // by forking the script provided at fPathScript
191 :
192 0 : if (fPID != 0) {
193 0 : AliError(Form("generator already running with PID %i", fPID));
194 0 : return kFALSE;
195 : }
196 :
197 0 : switch (fMode) {
198 : case kFIFO:
199 : // create FIFO and attach reader to it
200 0 : mkfifo(fPathFIFO, 0666);
201 :
202 : // fork generator
203 0 : fPID = fork();
204 0 : if (fPID < 0) {
205 0 : AliError("forking generator failed");
206 0 : return kFALSE;
207 0 : } else if (fPID == 0) {
208 0 : execl("/bin/bash", "bash", "-c", (fPathScript + " " + fPathFIFO + " > gen.log 2>&1").Data(), (char *) 0);
209 0 : } else {
210 0 : AliInfo(Form("running generator with PID %i", fPID));
211 : }
212 : break;
213 :
214 : case kAlternatingFiles:
215 : // fork generator
216 0 : fPID = fork();
217 0 : if (fPID < 0) {
218 0 : AliError("forking generator failed");
219 0 : return kFALSE;
220 0 : } else if (fPID == 0) {
221 0 : execl("/bin/bash", "bash", "-c", (fPathScript + " " + fPathFile1 + " " + fPathFile2 + " > gen.log 2>&1").Data(), (char *) 0);
222 0 : } else {
223 0 : AliInfo(Form("running generator with PID %i", fPID));
224 : }
225 : break;
226 :
227 : default:
228 0 : AliFatal(Form("Unknown mode for external generator: %i", fMode));
229 0 : }
230 :
231 0 : return kTRUE;
232 0 : }
233 :
234 : Bool_t AliGenExtExec::StopGen()
235 : {
236 : // kill generator if running
237 :
238 0 : if (fPID == 0) {
239 0 : AliError("generator not running, nothing killed");
240 0 : return kFALSE;
241 : }
242 :
243 0 : gSystem->Exec(Form("kill %i", fPID));
244 0 : gSystem->Unlink(fPathFIFO);
245 :
246 0 : fPID = 0;
247 :
248 0 : return kTRUE;
249 0 : }
|