diff --git a/Generators/include/Generators/GeneratorFileOrCmd.h b/Generators/include/Generators/GeneratorFileOrCmd.h index f0cc54613f3d2..1ab9bbdcce219 100644 --- a/Generators/include/Generators/GeneratorFileOrCmd.h +++ b/Generators/include/Generators/GeneratorFileOrCmd.h @@ -141,7 +141,7 @@ struct GeneratorFileOrCmd { * @return true if the temporary file name was generated * successfully. */ - virtual bool makeTemp(); + virtual bool makeTemp(const bool&); /** * Remove the temporary file if it was set and it exists. * diff --git a/Generators/src/GeneratorFileOrCmd.cxx b/Generators/src/GeneratorFileOrCmd.cxx index f1fd8ade60d0b..3ac3437f4f386 100644 --- a/Generators/src/GeneratorFileOrCmd.cxx +++ b/Generators/src/GeneratorFileOrCmd.cxx @@ -126,19 +126,40 @@ bool GeneratorFileOrCmd::executeCmdLine(const std::string& cmd) const return true; } // ----------------------------------------------------------------- -bool GeneratorFileOrCmd::makeTemp() -{ - mFileNames.clear(); - char buf[] = "generatorFifoXXXXXX"; - auto fp = mkstemp(buf); - if (fp < 0) { - LOG(fatal) << "Failed to make temporary file: " - << std::strerror(errno); - return false; +bool GeneratorFileOrCmd::makeTemp(const bool& fromName) +{ + if (fromName) { + if (mFileNames.empty()) { + LOG(fatal) << "No file names to make temporary file from"; + return false; + } else if (mFileNames.size() > 1) { + LOG(warning) << "More than one file name to make temporary file from"; + LOG(warning) << "Using the first one: " << mFileNames.front(); + LOG(warning) << "Removing all the others"; + mFileNames.erase(++mFileNames.begin(), mFileNames.end()); + } else { + LOG(debug) << "Making temporary file from: " << mFileNames.front(); + } + std::ofstream ofs(mFileNames.front().c_str()); + if (!ofs) { + LOG(fatal) << "Failed to create temporary file: " << mFileNames.front(); + return false; + } + mTemporary = std::string(mFileNames.front()); + ofs.close(); + } else { + mFileNames.clear(); + char buf[] = "generatorFifoXXXXXX"; + auto fp = mkstemp(buf); + if (fp < 0) { + LOG(fatal) << "Failed to make temporary file: " + << std::strerror(errno); + return false; + } + mTemporary = std::string(buf); + mFileNames.push_back(mTemporary); + close(fp); } - mTemporary = std::string(buf); - mFileNames.push_back(mTemporary); - close(fp); return true; } // ----------------------------------------------------------------- diff --git a/Generators/src/GeneratorHepMC.cxx b/Generators/src/GeneratorHepMC.cxx index 2076910b2bf5f..edaee66761658 100644 --- a/Generators/src/GeneratorHepMC.cxx +++ b/Generators/src/GeneratorHepMC.cxx @@ -575,9 +575,16 @@ Bool_t GeneratorHepMC::Init() // All of this can conviniently be achieved via a wrapper script // around the actual EG program. if (not mCmd.empty()) { - // Set filename to be a temporary name - if (not makeTemp()) { - return false; + if (mFileNames.empty()) { + // Set filename to be a temporary name + if (not makeTemp(false)) { + return false; + } + } else { + // Use the first filename as output for cmd line + if (not makeTemp(true)) { + return false; + } } // Make a fifo diff --git a/Generators/src/GeneratorTParticle.cxx b/Generators/src/GeneratorTParticle.cxx index ab68f7f39b1bf..06b4cbc147fca 100644 --- a/Generators/src/GeneratorTParticle.cxx +++ b/Generators/src/GeneratorTParticle.cxx @@ -54,9 +54,16 @@ Bool_t GeneratorTParticle::Init() mChain->SetBranchAddress(mBranchName.c_str(), &mTParticles); if (not mCmd.empty()) { - // Set filename to be a temporary name - if (not makeTemp()) { - return false; + if (mFileNames.empty()) { + // Set filename to be a temporary name + if (not makeTemp(false)) { + return false; + } + } else { + // Use the first filename as output for cmd line + if (not makeTemp(true)) { + return false; + } } // Build command line, Assumes command line parameter diff --git a/run/SimExamples/HepMC_JETSCAPE/README.md b/run/SimExamples/HepMC_JETSCAPE/README.md new file mode 100644 index 0000000000000..34dc700ae6b28 --- /dev/null +++ b/run/SimExamples/HepMC_JETSCAPE/README.md @@ -0,0 +1,39 @@ + + +The usage of JETSCAPE with the O2 machinery is presented in this short manual. +An in-depth explanation of the mechanisms behind the HepMC(3) data handling can be found in the +HepMC_fifo folder of the MC examples. The scripts use the `cmd` parameter of `GeneratorHepMC` +to spawn the JETSCAPE generation via the `jetscape.sh` script. It is important to turn on the +HepMC3 output format in the xml configuration file, as done in jetscape_user_example.xml, otherwise +the simulation will not work. + +# Scripts description + +Two scripts are available to run the simulations +- **jetscape.sh** → starts the actual JETSCAPE generation +- **runo2sim.sh** → allows the generation of events using o2-sim + +In addition an jetscape_user_example.xml file is provided to start JETSCAPE with user parameters. +The user could easily create scripts similar to the one provided for the EPOS4 tutorial for DPL or O2DPG +based simulations. + +## jetscape.sh + +It can be run without the help of the other scripts to simply generate an .hepmc file. +This example shows all the functionalities of the script (which are implemented in a similar way inside +the generation steering scripts). In particular the `-i` flag allows to provide the .xml user configuration file to JETSCAPE, `-s` feeds the generator with a user seed, and the HepMC output filename is set using the `-o` flag. The script edits automatically some specific parts of the provided input XML file. + +## runo2sim.sh + +This script works only with O2sim versions containing the FIFO custom name creation fix (the specific build will be added here in the future) otherwise it will crash or not complete the simulation. +Few flags are available to change the settings of the generation: +- **-m , --more** → feeds the simulation with advanced parameters provided to the configuration key flags +- **-n , --nevents** → changes the number of events in the .xml file or gets the one in the file if no events are provided +- **-i , --input** → .xml filename to feed JETSCAPE, no extension must be set in the filename +- **-j , --jobs** → sets the number of workers (jobs) +- **-h , --help** → prints usage instructions + +The last few lines of the script contain the execution of o2-sim, 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 $xml;GeneratorFileOrCmd.fileNames=test_out.hepmc;GeneratorFileOrCmd.outputSwitch=-o;GeneratorFileOrCmd.bMaxSwitch=none;GeneratorFileOrCmd.nEventsSwitch=none;` because the script might not work anymore, and it would be better to provide additional configurations via the -m flag. + diff --git a/run/SimExamples/HepMC_JETSCAPE/jetscape.sh b/run/SimExamples/HepMC_JETSCAPE/jetscape.sh new file mode 100755 index 0000000000000..39c9ac80a1cf3 --- /dev/null +++ b/run/SimExamples/HepMC_JETSCAPE/jetscape.sh @@ -0,0 +1,71 @@ +#!/bin/sh +# Script based on EPOS4 example +# This script is used to run JETSCAPE with the given XML file +# setting the seed and HepMC output filename. Contrary to the +# epos example, the HepMC output is generated in a custom named file +# not passing from the stdout. + +xml="example" +seed=$RANDOM +hepmc="jetout.hepmc" + +usage() +{ + cat <" $xml.xml; then + sed -i "//c\ $seed" $xml.xml + else + sed -i "/<\/jetscape>/i\ \n $seed\n " $xml.xml + fi + echo "Seed set to $seed" +fi + +# Check if hepmc output has been set +if [ ! -z "$hepmc" ]; then + # Remove extension + newhep=$(echo $hepmc | sed 's/.hepmc//') + if grep -Fq "" $xml.xml; then + sed -i "//c\ $newhep" $xml.xml + else + sed -i "//a\ $newhep" $xml.xml + fi + echo "HepMC output file set to $hepmc" +else + echo "Error: HepMC output file not set" + exit 2 +fi + +# Master XML file pulled directly from the JETSCAPE directory +runJetscape $xml.xml $JETSCAPE_ROOT/config/jetscape_master.xml \ No newline at end of file diff --git a/run/SimExamples/HepMC_JETSCAPE/jetscape_user_example.xml b/run/SimExamples/HepMC_JETSCAPE/jetscape_user_example.xml new file mode 100644 index 0000000000000..6a5a370d7a36d --- /dev/null +++ b/run/SimExamples/HepMC_JETSCAPE/jetscape_user_example.xml @@ -0,0 +1,42 @@ + + + + + 1000 + + + 1 + + + jetscape + + + on + + + + + 235 + 1000 + 5020 + + + + + + + 1.0 + 1 + 0.25 + 0 + 0 + 0 + + + + + + colorless + + + diff --git a/run/SimExamples/HepMC_JETSCAPE/runo2sim.sh b/run/SimExamples/HepMC_JETSCAPE/runo2sim.sh new file mode 100644 index 0000000000000..3f4c38c6462ac --- /dev/null +++ b/run/SimExamples/HepMC_JETSCAPE/runo2sim.sh @@ -0,0 +1,91 @@ +#!/usr/bin/env bash +# +# This is a simple simulation example showing how to +# start JETSCAPE generation automatically using cmd with hepmc output on FIFO +# and simultaneosly use o2-sim for transport + +# JETSCAPE and O2 must be loaded +set -x +if [ ! "${JETSCAPE_ROOT}" ]; then + echo "This needs JETSCAPE loaded; alienv enter ..." + exit 1 +fi + +[ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 2 + +cmd="$PWD/jetscape.sh" +NEV=-1 +more="" +xml="example" +JOBS=2 + +usage() +{ + cat </dev/stderr + exit 3 + ;; + esac + shift +done + +echo "XML User file: $xml" + +if [ ! -f $xml.xml ]; then + echo "Error: Options file $xml.xml not found" + exit 4 +fi + +# Set number of events in the XML file +if [ ! $NEV -eq -1 ]; then + echo "Setting number of events to $NEV" + if grep -Fq "" $xml.xml; then + sed -i "//c\ $NEV" $xml.xml + else + sed -i "//a\ $NEV" $xml.xml + fi +else + echo "Number of events not set, checking xml file..." + if grep -Fq "" $xml.xml; then + NEV=$(grep -F "" $xml.xml | awk '{print $2}') + echo "Number of events set to $NEV" + else + echo "Error: Number of events not set in JETSCAPE" + exit 5 + fi +fi + +# Starting simulation +o2-sim -j $JOBS -n ${NEV} -g hepmc --seed $RANDOM \ + --configKeyValues "GeneratorFileOrCmd.cmd=$cmd -i $xml;GeneratorFileOrCmd.fileNames=test_out.hepmc;GeneratorFileOrCmd.outputSwitch=-o;GeneratorFileOrCmd.bMaxSwitch=none;GeneratorFileOrCmd.nEventsSwitch=none;${more}"