Skip to content

Commit e28bcea

Browse files
committed
Custom fifo feature + automatic removal + jetscape usage example
1 parent 3d3ee4d commit e28bcea

File tree

8 files changed

+358
-19
lines changed

8 files changed

+358
-19
lines changed

Generators/include/Generators/GeneratorFileOrCmd.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,13 +141,19 @@ struct GeneratorFileOrCmd {
141141
* @return true if the temporary file name was generated
142142
* successfully.
143143
*/
144-
virtual bool makeTemp();
144+
virtual bool makeTemp(const bool&);
145145
/**
146146
* Remove the temporary file if it was set and it exists.
147147
*
148148
* @return true if the temporary file was removed.
149149
*/
150150
virtual bool removeTemp() const;
151+
/**
152+
* Remove the FIFO if it was set and it exists.
153+
*
154+
* @return true if the FIFO file was removed.
155+
*/
156+
virtual bool removeFifo() const;
151157
/**
152158
* Make a fifo at the location of the first element of the list of
153159
* file names (presumably a temporary file as created by

Generators/src/GeneratorFileOrCmd.cxx

Lines changed: 56 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -126,19 +126,40 @@ bool GeneratorFileOrCmd::executeCmdLine(const std::string& cmd) const
126126
return true;
127127
}
128128
// -----------------------------------------------------------------
129-
bool GeneratorFileOrCmd::makeTemp()
129+
bool GeneratorFileOrCmd::makeTemp(const bool& fromName)
130130
{
131-
mFileNames.clear();
132-
char buf[] = "generatorFifoXXXXXX";
133-
auto fp = mkstemp(buf);
134-
if (fp < 0) {
135-
LOG(fatal) << "Failed to make temporary file: "
136-
<< std::strerror(errno);
137-
return false;
138-
}
139-
mTemporary = std::string(buf);
140-
mFileNames.push_back(mTemporary);
141-
close(fp);
131+
if (fromName) {
132+
if (mFileNames.empty()) {
133+
LOG(fatal) << "No file names to make temporary file from";
134+
return false;
135+
} else if (mFileNames.size() > 1) {
136+
LOG(warning) << "More than one file name to make temporary file from";
137+
LOG(warning) << "Using the first one: " << mFileNames.front();
138+
LOG(warning) << "Removing all the others";
139+
mFileNames.erase(++mFileNames.begin(), mFileNames.end());
140+
} else {
141+
LOG(debug) << "Making temporary file from: " << mFileNames.front();
142+
}
143+
std::ofstream ofs(mFileNames.front().c_str());
144+
if (!ofs) {
145+
LOG(fatal) << "Failed to create temporary file: " << mFileNames.front();
146+
return false;
147+
}
148+
mTemporary = std::string(mFileNames.front());
149+
ofs.close();
150+
} else {
151+
mFileNames.clear();
152+
char buf[] = "generatorFifoXXXXXX";
153+
auto fp = mkstemp(buf);
154+
if (fp < 0) {
155+
LOG(fatal) << "Failed to make temporary file: "
156+
<< std::strerror(errno);
157+
return false;
158+
}
159+
mTemporary = std::string(buf);
160+
mFileNames.push_back(mTemporary);
161+
close(fp);
162+
}
142163
return true;
143164
}
144165
// -----------------------------------------------------------------
@@ -169,6 +190,29 @@ bool GeneratorFileOrCmd::removeTemp() const
169190
return true;
170191
}
171192
// -----------------------------------------------------------------
193+
bool GeneratorFileOrCmd::removeFifo() const
194+
{
195+
if (mFileNames.empty()) {
196+
LOG(warn) << "No FIFO filename available";
197+
} else {
198+
// Check if FIFO exist and remove it from filesystem
199+
std::filesystem::path p(mFileNames.front());
200+
if (not std::filesystem::exists(p)) {
201+
LOG(warn) << "FIFO " << p << " did not exist";
202+
} else {
203+
std::error_code ec;
204+
std::filesystem::remove(p, ec);
205+
if (ec) {
206+
LOG(error) << "Error while removing" << p << ": " << ec.message();
207+
return false;
208+
} else {
209+
LOG(info) << "Removed FIFO " << p;
210+
}
211+
}
212+
}
213+
return true;
214+
}
215+
// -----------------------------------------------------------------
172216
bool GeneratorFileOrCmd::makeFifo() const
173217
{
174218
// First remove the temporary file if it exists,

Generators/src/GeneratorHepMC.cxx

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ GeneratorHepMC::~GeneratorHepMC()
6666
delete mEvent;
6767
}
6868
removeTemp();
69+
if (not mCmd.empty()) {
70+
removeFifo();
71+
}
6972
}
7073

7174
/*****************************************************************/
@@ -574,9 +577,16 @@ Bool_t GeneratorHepMC::Init()
574577
// All of this can conviniently be achieved via a wrapper script
575578
// around the actual EG program.
576579
if (not mCmd.empty()) {
577-
// Set filename to be a temporary name
578-
if (not makeTemp()) {
579-
return false;
580+
if (mFileNames.empty()) {
581+
// Set filename to be a temporary name
582+
if (not makeTemp(false)) {
583+
return false;
584+
}
585+
} else {
586+
// Use the first filename as output for cmd line
587+
if (not makeTemp(true)) {
588+
return false;
589+
}
580590
}
581591

582592
// Make a fifo

Generators/src/GeneratorTParticle.cxx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,16 @@ Bool_t GeneratorTParticle::Init()
5454
mChain->SetBranchAddress(mBranchName.c_str(), &mTParticles);
5555

5656
if (not mCmd.empty()) {
57-
// Set filename to be a temporary name
58-
if (not makeTemp()) {
59-
return false;
57+
if(mFileNames.empty()) {
58+
// Set filename to be a temporary name
59+
if (not makeTemp(false)) {
60+
return false;
61+
}
62+
} else {
63+
// Use the first filename as output for cmd line
64+
if (not makeTemp(true)) {
65+
return false;
66+
}
6067
}
6168

6269
// Build command line, Assumes command line parameter
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<!-- doxy
2+
\page refrunSimExamplesHepMC_EPOS4 Example HepMC_EPOS4
3+
/doxy -->
4+
5+
The usage of EPOS4 with the O2 machinery is presented in this short manual.
6+
An in-depth explanation of the mechanisms behind the HepMC(3) data handling can be found in the
7+
HepMC_fifo folder of the MC examples. The scripts use the `cmd` parameter of `GeneratorHepMC`
8+
to spawn the EPOS4 generation via the `epos.sh` script.
9+
10+
EPOS4 uses the outdated HepMC2 libraries, so this had to be specified in the steering scripts
11+
of the generators configuration. If `HepMC.version=2` is removed then the scripts will not work
12+
anymore. This is to say that the balance achieved with the configurations provided is easily
13+
destroyed if the user base edits parts that are not understood completely.
14+
15+
# Scripts description
16+
17+
Four scripts are available to run the simulations
18+
- **epos.sh** &rarr; starts the actual EPOS4 generation
19+
- **runo2sim.sh** &rarr; allows the generation of events using o2-sim
20+
- **rundpg.sh** &rarr; starts the DPG machinery for event generation
21+
- **rundpl.sh** &rarr; starts the event generation with DPL
22+
23+
In addition an example.optns file is provided to start EPOS4, but more can be found in the generator example folder
24+
or in the website [epos4learn.web.cern.ch](https://epos4learn.docs.cern.ch/) where an extensive tutorial on the generator is provided.
25+
26+
## epos.sh
27+
28+
It can be run without the help of the other scripts to simply generate an .hepmc file or print
29+
to the stdout the HepMC results. It it worth nothing though that EPOS4 must be loaded (via cvmfs through AliGenerators or O2sim for example) or installed. In this case the user should simply redirect the stdout to a file:
30+
```
31+
./epos.sh -i test -s 234345 > test.hepmc
32+
```
33+
This example shows all the functionalities of the script (which are implemented in a similar way inside
34+
the generation steering scripts). In particular the `-i` flag allows to provide .optns parameters to EPOS4,
35+
`-s` feeds the generator with a user seed, and the HepMC output is given by test.hepmc by redirecting the
36+
stdout which will contain only the HepMC data thanks to the `-hepstd` flag set automatically in epos.sh and
37+
the `set ihepmc 2` option which **MUST** be set in the option file (otherwise either an hepmc file will be created - ihepmc 1 - or nothing will be generated - missing ihepmc or != 1|2 ).
38+
39+
It is important to note that setting an empty/null seed in the generator out of the box makes EPOS4 crash, so a protection was added in our steering epos.sh script which now generates a random number if 0 is provided.
40+
41+
## runo2sim.sh, rundpg.sh and rundpl.sh
42+
43+
The three scripts have little differences (especially in the first part), so they will be described together. They work after loading any O2sim version after the 20/09/2024 (included), since multiple modifications had to be performed on both EPOS4 and the introduction of AliGenO2 in order to be able to load both O2sim and EPOS4 simultaneously.
44+
45+
If no parameters are provided to the scripts, they will run with default values (energy and nevents provided in the example.optns file), but few flags are available to change the settings of the generation:
46+
- **-m , --more** &rarr; feeds the simulation with advanced parameters provided to the configuration key flags
47+
- **-n , --nevents** &rarr; changes the number of events in the .optns file or gets the one in the file if no events are provided
48+
- **-i , --input** &rarr; .optns filename to feed EPOS4, no extension must be set in the filename
49+
- **-j , --jobs** &rarr; sets the number of workers (jobs)
50+
- **-h , --help** &rarr; prints usage instructions
51+
- **-e , --ecm** &rarr; sets the center-of-mass energy in the options file
52+
53+
In the `rundpg.sh` script an additional flag is available
54+
- **-t , --tf** &rarr; number of timeframes to be generated
55+
56+
In this case the options file will be copied in each tf$n folder, otherwise the epos script won't be able to run with multiple timeframes.
57+
In o2sim and DPG scripts the randomly generated seed is set directly, instead this is not feasible with the DPL one, given that the --seed option is not able to redirect this number to GeneratorHepMC. So a seed 0 is automatically given to epos.sh which generates a random number in return.
58+
59+
Now the three scripts start to differ:
60+
61+
- **runo2sim.sh** &rarr; o2-sim is launched
62+
- **rundpg.sh** &rarr; first the o2dpg_sim_workflow.py script will be launched generating the json configuration, then the o2_dpg_workflow_runner.py script will start the workflow
63+
- **rundpl.sh** &rarr; o2-sim-dpl-eventgen is executed piping its results to o2-sim-mctracks-to-aod and afterwards to o2-analysis-mctracks-to-aod-simple-task
64+
65+
The last few lines of the scripts contain the execution of o2-sim, DPG worflow creator/runner and DPL software respectively, so this part can be modified by the users following their requirements. It's important not to delete from the configuration keys `GeneratorFileOrCmd.cmd=$cmd -i $optns;GeneratorFileOrCmd.bMaxSwitch=none;HepMC.version=2;` and it would be better to provide additional configurations via the -m flag. EPOS4 cannot set a maximum impact parameter value, so it's better to leave the bMaxSwitch to none, while the others serve the sole purpose of running successfully the generator using auto generated FIFOs.
66+
67+
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
#!/bin/sh
2+
# Script based on EPOS4 example
3+
# EPOS4 option files must contain ihepmc set to 2 to print HepMC
4+
# data on stdout. -hepmc flag is not needed anymore, but -hepstd is fundamental
5+
# in order not to print useless information on stdout (a z-*optns*.mtr file will be created)
6+
7+
xml="example"
8+
seed=$RANDOM
9+
hepmc="jetout.hepmc"
10+
11+
usage()
12+
{
13+
cat <<EOF
14+
Usage: $0 [OPTIONS]
15+
16+
Options:
17+
18+
-i,--input INPUT XML user file fed to JETSCAPE ($xml)
19+
-o,--output OUTPUT HepMC output file ($hepmc)
20+
-s,--seed SEED RNG seed ($seed)
21+
-h,--help Print these instructions
22+
-- Rest of command line sent to o2-sim
23+
24+
EOF
25+
}
26+
27+
while test $# -gt 0 ; do
28+
case $1 in
29+
-i|--input) xml=$2 ; shift ;;
30+
-o|--output) hepmc=$2 ; shift ;;
31+
-s|--seed) seed=$2 ; shift ;;
32+
-h|--help) usage; exit 0 ;;
33+
esac
34+
shift
35+
done
36+
37+
if [ ! -f $xml.xml ]; then
38+
echo "Error: Options file $xml.xml not found"
39+
exit 1
40+
fi
41+
42+
if [ $seed -eq 0 ]; then
43+
echo "Seed can't be 0, random number will be used"
44+
seed=$RANDOM
45+
else
46+
if grep -Fq "<seed>" $xml.xml; then
47+
sed -i "/<seed>/c\ <seed>$seed</seed>" $xml.xml
48+
else
49+
sed -i "/<\/jetscape>/i\ <Random>\n <seed>$seed</seed>\n </Random>" $xml.xml
50+
fi
51+
echo "Seed set to $seed"
52+
fi
53+
54+
# Workaround to use the automatically generated FIFO as output file in JETSCAPE
55+
# since no support for stdout is available and a better solution needs to be found
56+
# Check if hepmc is not empty and it's a fifo
57+
if [ ! -z "$hepmc" ]; then
58+
# if $hepmc contains .hepmc remove it
59+
newhep=$(echo $hepmc | sed 's/.hepmc//')
60+
if grep -Fq "<outputFilename>" $xml.xml; then
61+
sed -i "/<outputFilename>/c\ <outputFilename>$newhep</outputFilename>" $xml.xml
62+
else
63+
sed -i "/<jetscape>/a\ <outputFilename>$newhep</outputFilename>" $xml.xml
64+
fi
65+
echo "HepMC output file set to $hepmc"
66+
else
67+
echo "Error: HepMC output file not set"
68+
exit 2
69+
fi
70+
71+
# Master XML file pulled directly from the JETSCAPE directory
72+
runJetscape $xml.xml $JETSCAPE_ROOT/config/jetscape_master.xml
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?xml version="1.0"?>
2+
3+
<jetscape>
4+
5+
<nEvents>1000</nEvents>
6+
7+
<Random>
8+
<seed>1</seed>
9+
</Random>
10+
11+
<outputFilename>jetscape</outputFilename>
12+
13+
<!--Do not delete HepMC setting-->
14+
<JetScapeWriterHepMC> on </JetScapeWriterHepMC>
15+
16+
<!-- Hard Process -->
17+
<Hard>
18+
<PythiaGun>
19+
<pTHatMin>235</pTHatMin>
20+
<pTHatMax>1000</pTHatMax>
21+
<eCM>5020</eCM>
22+
</PythiaGun>
23+
</Hard>
24+
25+
<!--Eloss Modules -->
26+
<Eloss>
27+
<Matter>
28+
<Q0> 1.0 </Q0>
29+
<in_vac> 1 </in_vac>
30+
<vir_factor> 0.25 </vir_factor>
31+
<recoil_on> 0 </recoil_on>
32+
<broadening_on> 0 </broadening_on>
33+
<brick_med> 0 </brick_med>
34+
</Matter>
35+
</Eloss>
36+
37+
<!-- Jet Hadronization Module -->
38+
<JetHadronization>
39+
<name>colorless</name>
40+
</JetHadronization>
41+
42+
</jetscape>

0 commit comments

Comments
 (0)