Skip to content

Commit 6f6f2c3

Browse files
committed
Added documentation
1 parent ee59676 commit 6f6f2c3

File tree

9 files changed

+784
-0
lines changed

9 files changed

+784
-0
lines changed

run/SimExamples/HepMC/README.md

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
<!-- doxy
2+
\page refrunSimExamplesHepMC Example reading HepMC events
3+
/doxy -->
4+
5+
Here are pointers on how to use `GeneratorHepMC` selected by the
6+
option `-g hepmc` for `o2-sim`.
7+
8+
## Reading HepMC files
9+
10+
The generator `GeneratorHepMC` can read events from a
11+
[HepMC(3)](http://hepmc.web.cern.ch/hepmc/) formatted file. These files
12+
can be produced by a standalone event generator program (EG).
13+
Examples of such programs are
14+
15+
- [Pythia8](https://pythia.org)
16+
- The [CRMC](https://gitlab.iap.kit.edu/AirShowerPhysics/crmc) suite
17+
- [Herwig](https://herwig.hepforge.org/)
18+
- [SMASH](https://smash-transport.github.io/)
19+
- ... and many others
20+
21+
Please refer to the documentation of these for more on how to make
22+
event files in the HepMC format.
23+
24+
To make a simulation reading from the file `events.hepmc`, do
25+
26+
o2-sim -g hepmc --configKeyValues "HepMC.fileName=events.hepmc" ...
27+
28+
See also [`read.sh`](read.sh)
29+
30+
## Reading HepMC events from child process
31+
32+
`GeneratorHepMC` can not only read HepMC events from a file, but can
33+
also spawn an child EG to produce events. Suppose we have a program
34+
named `eg` which is some EG that writes HepMC event records to the
35+
standard output. Then we can execute a simulation using this external
36+
EG by
37+
38+
o2-sim -g hepmc --configKeyValues "HepMC.progCmd=eg"
39+
40+
See also [`child.sh`](child.sh)
41+
42+
There are some requirements on the program `eg`:
43+
44+
- It _must_ write the HepMC event structures to standard output
45+
(`/dev/stdout`).
46+
- It may _not_ write other information to standard output.
47+
- It _must_ accept the option `-n n-events` to set the number of
48+
events to produce to `n-events`.
49+
50+
If a program does not adhere to these requirements, it will often be
51+
simple enough to make a small wrapper script that enforce this. For
52+
example, `crmc` will write a lot of information to standard output.
53+
We can filter that out via a shell script ([`crmc.sh`](crmc.sh)) like
54+
55+
#!/bin/sh
56+
57+
crmc $@ -o hepmc3 -f /dev/stdout | sed -n 's/^\(HepMC::\|[EAUWVP] \)/\1/p'
58+
59+
The `sed` command selects lines that begin with `HepMC::`, or one
60+
of single characters `E` (event), `A` (attribute), `U` (units), `W`
61+
(weight), `V` (vertex), or `P` (particle) followed by a space. This
62+
should in most cases be enough to filter out extra stuff written on
63+
standard output.
64+
65+
The script above also passes any additional command line options on to
66+
`crmc` via `$@`. We can utilise this with `o2-sim` to set options to
67+
the CRMC suite. For example, if we want to simulate p-Pb collisions
68+
using DpmJET, we can do
69+
70+
o2-sim -g hepmc --configKeyValues "HepMC.progCmd=crmc.sh -m 12 -i2212 -I 1002080820"
71+
72+
73+
### Implementation details
74+
75+
Internally `GeneratorHepMC`
76+
77+
1. creates a unique temporary file name in the working directory,
78+
2. then creates a FIFO (or named pipe, see
79+
[Wikipedia](https://en.wikipedia.org/wiki/Named_pipe)),
80+
3. builds a command line, e.g.,
81+
82+
eg options > fifo-name &
83+
84+
4. and executes that command line
85+
86+
## The future
87+
88+
The `GeneratorHepMC` (and sister generator `GeneratorTParticle`) will
89+
in the not so distant future be upgraded with new functionality to
90+
more easily customise reading files and executing a child process. In
91+
particular
92+
93+
- HepMC event structures can be read from any file format supported by
94+
HepMC it self (see
95+
[here](http://hepmc.web.cern.ch/hepmc/group__IO.html) and
96+
[here](http://hepmc.web.cern.ch/hepmc/group__factory.html).
97+
98+
- New options that can be specified in `--configKeyValues`
99+
100+
- `HepMC.eventsToSkip=number` a number events to skip at the
101+
beginning of each file read.
102+
103+
- `FileOrCmd.fileNames=list` a comma separated list of HepMC files
104+
to read
105+
106+
- `FileOrCmd.cmd=command line` a command line to execute as a
107+
background child process. If this is set (not the empty string),
108+
then `FileOrCmd.fileNames` is ignored.
109+
110+
- A number of keys that specifies the command line option switch
111+
that the child program accepts for certain things. If any of
112+
these are set to the empty string, then that switch and
113+
corresponding option value is not passed to the child program.
114+
115+
- `FileOrCmd.outputSwitch=switch` (default `>`) to specify output
116+
file. The default of `>` assumes that the program write HepMC
117+
events, and _only_ those, to standard output.
118+
119+
- `FileOrCmd.seedSwitch=switch` (default `-s`) to specify the
120+
random number generator seed. The value passed is selected by
121+
the `o2-sim` option `--seed`
122+
123+
- `FileOrCmd.bMaxSwitch=switch` (default `-b`) to specify the
124+
upper limit on the impact parameters sampled. The value passed
125+
is selected by the `o2-sim` option `--bMax`
126+
127+
- `FileOrCmd.nEventsSwitch=switch` (default `-n`) to specify the
128+
number of events to generate. The value passed is selected by
129+
the `o2-sim` option `--nEvents` or (`-n`)
130+
131+
- `FileOrCmd.backgroundSwitch=switch` (default `&`) to specify how
132+
the program is put in the background. Typically this should be
133+
`&`, but a program may itself fork to the background.
134+
135+
- Some options are no longer available
136+
137+
- `HepMC.fileName` - use `FileOrCmd.fileNames`
138+
- `HepMC.progCmd` - use `FileOrCmd.cmd`
139+
140+
The command line build will now be
141+
142+
> _commandLine_ _nEventsSwitch_ _nEvents_ _seedSwitch_ _seed_
143+
> _bMaxSwitch_ _bMax_ _outputSwitch_ _output_ _backgroundSwitch_
144+
145+
If any of the `Switch` keys are empty, then the corresponding option
146+
is not propagated to the command line. For example, if _bMaxSwitch_
147+
is empty, then the build command line will be
148+
149+
> _commandLine_ _nEventsSwitch_ _nEvents_ _seedSwitch_ _seed_
150+
> _outputSwitch_ _output_ _backgroundSwitch_
151+

run/SimExamples/HepMC/child.sh

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#!/bin/bash
2+
3+
cmd="./crmc.sh"
4+
seed=$RANDOM
5+
nev=1
6+
out=
7+
8+
usage()
9+
{
10+
cat <<-EOF
11+
Usage: $0 [OPTIONS]
12+
13+
Options:
14+
15+
-c,--cmdline COMMAND Command line
16+
-s,--seed SEED Random number seed ($seed)
17+
-n,--nevents EVENTS Number of events ($nev)
18+
-o,--output OUTPUT Output prefix ($out)
19+
-- Rest of command line sent to o2-sim
20+
21+
COMMAND must be quoted if it contains spaces or other special
22+
characters
23+
24+
Below follows the help output of o2-sim
25+
26+
EOF
27+
}
28+
29+
while test $# -gt 0 ; do
30+
case $1 in
31+
-c|--cmdline) cmd="$2" ; shift ;;
32+
-s|--seed) seed=$2 ; shift ;;
33+
-n|--nevents) nev=$2 ; shift ;;
34+
-o|--output) out=$2 ; shift ;;
35+
-h|--help) usage; o2-sim --help full ; exit 0 ;;
36+
--) shift ; break ;;
37+
*) echo "Unknown option '$1', did you forget '--'?" >/dev/stderr
38+
exit 1
39+
;;
40+
esac
41+
shift
42+
done
43+
44+
if test "x$out" = "x" ; then
45+
out=`echo $cmd | sed 's,^\./,,' | tr '[$/. ]' '_'`
46+
fi
47+
out=`echo "$out" | tr ' ' '_'`
48+
49+
export VMCWORKDIR=${O2_ROOT}/share
50+
o2-sim -g hepmc --configKeyValues "HepMC.progCmd=$cmd" \
51+
--outPrefix "$out" --seed $seed --nEvents $nev $@
52+
53+

run/SimExamples/HepMC/crmc.sh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#!/bin/sh
2+
# This script _may not_ write to standard out, except for the HepMC
3+
# event record.
4+
5+
crmcParam=$(dirname $(dirname `which crmc`))/etc/crmc.param
6+
exec crmc -c $crmcParam $@ -o hepmc3 -f /dev/stdout | \
7+
sed -n 's/^\(HepMC::\|[EAUWVP] \)/\1/p'

run/SimExamples/HepMC/read.sh

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#!/bin/bash
2+
3+
inp=events.hepmc
4+
seed=$RANDOM
5+
nev=1
6+
out=
7+
8+
usage()
9+
{
10+
cat <<-EOF
11+
Usage: $0 [OPTIONS]
12+
13+
Options:
14+
15+
-i,--input FILENAME Input HepMC file ($inp)
16+
-s,--seed SEED Random number seed ($seed)
17+
-n,--nevents EVENTS Number of events ($nev)
18+
-o,--output NAME Ouptut name
19+
-- Rest of command line sent to o2-sim
20+
21+
Below follows the help output of o2-sim
22+
23+
EOF
24+
}
25+
26+
while test $# -gt 0 ; do
27+
case $1 in
28+
-i|--input) inp=$2 ; shift ;;
29+
-s|--seed) seed=$2 ; shift ;;
30+
-n|--nevents) nev=$2 ; shift ;;
31+
-o|--output) out=$2 ; shift ;;
32+
-h|--help) usage; o2-sim --help full ; exit 0 ;;
33+
--) shift ; break ;;
34+
*) echo "Unknown option '$1', did you forget '--'?" >/dev/stderr
35+
exit 1
36+
;;
37+
esac
38+
shift
39+
done
40+
41+
if test "x$out" = "x" ; then
42+
out=`basename $inp .hepmc`
43+
fi
44+
out=`echo "$out" | tr ' ' '_'`
45+
46+
export VMCWORKDIR=${O2_ROOT}/share
47+
o2-sim -g hepmc --configKeyValues "HepMC.fileName=$inp" \
48+
--outPrefix "$out" --seed $seed --nEvents $nev $@
49+
50+

run/SimExamples/TParticle/MyEG.cc

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
#include <TGenerator.h>
2+
#include <TFile.h>
3+
#include <TTree.h>
4+
#include <TClonesArray.h>
5+
#include <TRandom.h>
6+
#include <TParticle.h>
7+
8+
//--------------------------------------------------------------------
9+
// Our generator class. Really simple.
10+
class MyGenerator : public TGenerator
11+
{
12+
public:
13+
Long_t projectilePDG;
14+
Long_t targetPDG;
15+
Double_t sqrts;
16+
MyGenerator() {}
17+
void Initialize(Long_t projectile,
18+
Long_t target,
19+
Double_t sqrts)
20+
{
21+
this->projectilePDG = projectile;
22+
this->targetPDG = target;
23+
this->sqrts = sqrts;
24+
}
25+
void GenerateEvent()
26+
{ /* Do something */
27+
}
28+
TObjArray* ImportParticles(Option_t* option = "") { return 0; }
29+
Int_t ImportParticles(TClonesArray* particles, Option_t* option = "")
30+
{
31+
Int_t nParticles = 10;
32+
Int_t iParticle = 0;
33+
// Make beam particles
34+
new ((*particles)[iParticle++]) TParticle(projectilePDG, 4, -1, -1,
35+
2, nParticles - 1,
36+
0, 0, sqrts / 2,
37+
TMath::Sqrt(1 + sqrts * sqrts),
38+
0, 0, 0, 0);
39+
new ((*particles)[iParticle++]) TParticle(projectilePDG, 4, -1, -1,
40+
2, nParticles - 1,
41+
0, 0, -sqrts / 2,
42+
TMath::Sqrt(1 + sqrts * sqrts),
43+
0, 0, 0, 0);
44+
for (; iParticle < nParticles; iParticle++)
45+
new ((*particles)[iParticle])
46+
TParticle(211, 1, 0, 1,
47+
-1, -1,
48+
0.1 * iParticle,
49+
0.1 * iParticle,
50+
0.1 * iParticle,
51+
TMath::Sqrt(0.03 * iParticle * iParticle + 0.14 * 0.14),
52+
0, 0, 0, 0);
53+
54+
return nParticles;
55+
}
56+
};
57+
//--------------------------------------------------------------------
58+
// Our steering class
59+
struct MySteer {
60+
TGenerator* generator;
61+
TFile* file;
62+
TTree* tree;
63+
TClonesArray* particles;
64+
Int_t every;
65+
MySteer(TGenerator* generator, const TString& output, Int_t every)
66+
: generator(generator),
67+
file(TFile::Open(output, "RECREATE")),
68+
tree(new TTree("T", "T")),
69+
particles(new TClonesArray("TParticle")),
70+
every(every)
71+
{
72+
tree->SetDirectory(file);
73+
tree->Branch("Particles", &particles);
74+
}
75+
~MySteer()
76+
{
77+
close();
78+
}
79+
void event()
80+
{
81+
particles->Clear();
82+
generator->GenerateEvent();
83+
generator->ImportParticles(particles);
84+
tree->Fill();
85+
}
86+
void sync()
87+
{
88+
// Important so that GeneratorTParticle picks up the events as
89+
// they come.
90+
tree->AutoSave("SaveSelf FlushBaskets Overwrite");
91+
}
92+
void run(Int_t nev)
93+
{
94+
for (Int_t iev = 0; iev < nev; iev++) {
95+
event();
96+
97+
if (every > 0 and (iev % every == 0) and iev != 0)
98+
sync();
99+
}
100+
}
101+
void close()
102+
{
103+
if (not file)
104+
return;
105+
file->Write();
106+
file->Close();
107+
file = nullptr;
108+
}
109+
};
110+
111+
//--------------------------------------------------------------------
112+
// Our steering function
113+
void MyEG(Int_t nev, const TString& out, Int_t seed, Int_t every = 1)
114+
{
115+
gRandom->SetSeed(seed);
116+
117+
MyGenerator* eg = new MyGenerator();
118+
eg->Initialize(2212, 2212, 5200);
119+
120+
MySteer steer(eg, out, every);
121+
steer.run(nev);
122+
}
123+
// Local Variables:
124+
// mode: C++
125+
// End:
126+
//
127+
// EOF
128+
//

0 commit comments

Comments
 (0)