Skip to content

Commit 6009787

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

File tree

8 files changed

+326
-19
lines changed

8 files changed

+326
-19
lines changed

Generators/include/Generators/GeneratorFileOrCmd.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ 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
*

Generators/src/GeneratorFileOrCmd.cxx

Lines changed: 33 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()
130-
{
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;
129+
bool GeneratorFileOrCmd::makeTemp(const bool& fromName)
130+
{
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);
138162
}
139-
mTemporary = std::string(buf);
140-
mFileNames.push_back(mTemporary);
141-
close(fp);
142163
return true;
143164
}
144165
// -----------------------------------------------------------------

Generators/src/GeneratorHepMC.cxx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -574,9 +574,16 @@ Bool_t GeneratorHepMC::Init()
574574
// All of this can conviniently be achieved via a wrapper script
575575
// around the actual EG program.
576576
if (not mCmd.empty()) {
577-
// Set filename to be a temporary name
578-
if (not makeTemp()) {
579-
return false;
577+
if (mFileNames.empty()) {
578+
// Set filename to be a temporary name
579+
if (not makeTemp(false)) {
580+
return false;
581+
}
582+
} else {
583+
// Use the first filename as output for cmd line
584+
if (not makeTemp(true)) {
585+
return false;
586+
}
580587
}
581588

582589
// 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>
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#!/usr/bin/env bash
2+
#
3+
# This is a simple simulation example showing how to
4+
# start JETSCAPE generation automatically using cmd with hepmc output on FIFO
5+
# and simultaneosly use o2-sim for transport
6+
7+
# JETSCAPE and O2 must be loaded
8+
set -x
9+
if [ ! "${JETSCAPE_ROOT}" ]; then
10+
echo "This needs EPOS4 loaded; alienv enter ..."
11+
exit 1
12+
fi
13+
14+
[ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 2
15+
16+
cmd="$PWD/jetscape.sh"
17+
NEV=-1
18+
more=""
19+
xml="example"
20+
JOBS=2
21+
22+
usage()
23+
{
24+
cat <<EOF
25+
Usage: $0 [OPTIONS]
26+
27+
Options:
28+
29+
-m,--more CONFIG More configurations ($more)
30+
-n,--nevents EVENTS Number of events ($nev)
31+
-i,--input INPUT Options file fed to EPOS4 ($xml)
32+
-j,--jobs JOBS Number of jobs ($JOBS)
33+
-h,--help Print these instructions
34+
-- Rest of command line sent to o2-sim
35+
36+
COMMAND must be quoted if it contains spaces or other special
37+
characters
38+
39+
Below follows the help output of o2-sim
40+
41+
EOF
42+
}
43+
44+
if [ "$#" -lt 2 ]; then
45+
echo "Running with default values"
46+
fi
47+
48+
while test $# -gt 0 ; do
49+
case $1 in
50+
-m|--more) more="$2" ; shift ;;
51+
-n|--nevents) NEV=$2 ; shift ;;
52+
-i|--input) xml=$2 ; shift ;;
53+
-j|--jobs) JOBS=$2 ; shift ;;
54+
-h|--help) usage; o2-sim --help full ; exit 0 ;;
55+
--) shift ; break ;;
56+
*) echo "Unknown option '$1', did you forget '--'?" >/dev/stderr
57+
exit 3
58+
;;
59+
esac
60+
shift
61+
done
62+
63+
echo "XML User file: $xml"
64+
65+
if [ ! -f $xml.xml ]; then
66+
echo "Error: Options file $xml.xml not found"
67+
exit 4
68+
fi
69+
70+
# Set number of events in the XML file
71+
if [ ! $NEV -eq -1 ]; then
72+
echo "Setting number of events to $NEV"
73+
if grep -Fq "<nEvents>" $xml.xml; then
74+
sed -i "/<nEvents>/c\ <nEvents>$NEV</nEvents>" $xml.xml
75+
else
76+
sed -i "/<jetscape>/a\ <nEvents>$NEV</nEvents>" $xml.xml
77+
fi
78+
else
79+
echo "Number of events not set, checking xml file..."
80+
if grep -Fq "<nEvents>" $xml.xml; then
81+
NEV=$(grep -F "<nEvents>" $xml.xml | awk '{print $2}')
82+
echo "Number of events set to $NEV"
83+
else
84+
echo "Error: Number of events not set in JETSCAPE"
85+
exit 5
86+
fi
87+
fi
88+
89+
# Starting simulation => seed is fed automatically to epos with the --seed flag
90+
o2-sim -j $JOBS -n ${NEV} -g hepmc --seed $RANDOM \
91+
--configKeyValues "GeneratorFileOrCmd.cmd=$cmd -i $xml;GeneratorFileOrCmd.fileNames=test_out.hepmc;GeneratorFileOrCmd.outputSwitch=-o;GeneratorFileOrCmd.bMaxSwitch=none;GeneratorFileOrCmd.nEventsSwitch=none;${more}"

0 commit comments

Comments
 (0)