Skip to content

Running Gauss

Learning objectives

  • Find the correct option files to run Gauss
  • Produce generator level Monte Carlo, print the decay tree and produce nTuples

Finding the correct files

Imagine you need to know the option files and software versions used for a simulated sample you have found in the bookkeeping, e.g.

/MC/2024/Beam6800GeV-2024.Q1.2-MagDown-Nu7.6-25ns-Pythia8/Sim10d/16104043/DIGI
First, find the ProductionID:

FindingProductionID

Search the Production ID in the Transformation Monitor to find the request, right click the result and select "Show request". Right clicking and selecting "View" in the new window will open an overview about all the individual steps of the production with their application version and option files used.

Important: the order of the option files matters!

'$DECFILESROOT/options/{eventnumber}.py' '$LBPYTHIA8ROOT/options/Pythia8.py' produces the sample using Pythia 8 while '$LBPYTHIA8ROOT/options/Pythia8.py' '$DECFILESROOT/options/{eventnumber}.py' uses Pythia 6.

Running Gauss and create a generator-only sample

The production system handles the necessary settings for initial event- and runnumber and the used database tags. In a private production, you need to set these yourself in an additional options file, containing, for example:

from Gauss.Configuration import GenInit

GaussGen = GenInit("GaussGen")
GaussGen.FirstEventNumber = 1
GaussGen.RunNumber = 1082

from Configurables import LHCbApp
LHCbApp().DDDBtag = 'dddb-20240427'
LHCbApp().CondDBtag = 'sim10-2024.Q1.2-v1.1-md100'
LHCbApp().EvtMax = 5

Assuming this is saved in a file called Gauss-Job.py and following the example above, the sample can then be produced by running

./run gaudirun.py \
        '$APPCONFIGOPTS/Gauss/EnableSpillover-25ns.py' \
        '$APPCONFIGOPTS/Gauss/Run3-detector.py' \
        '$APPCONFIGOPTS/Gauss/DataType-2024.py' \
        '$DECFILESROOT/options/@{eventType}.py' \
        '$LBPYTHIA8ROOT/options/Pythia8.py' \
        '$APPCONFIGOPTS/Gauss/G4PL_FTFP_BERT_EmOpt2.py' \
        '$APPCONFIGOPTS/Persistency/BasketSize-10.py' \
        Gauss-Job.py

where @{eventType} has to be replaced with your favorite event-type, which is how LHCb describes a particular decay chain. You will learn more about this in the DecFiles lesson.

This would take 5 to 10 minutes!!

As mentioned before, the detector simulation is slow. It is possible to make a generator level only sample which would run faster. To only run the generator phase, add '$GAUSSOPTS/GenStandAlone.py' as one of the option files. In this case, the options simplify to :

./run gaudirun.py \
        '$APPCONFIGOPTS/Gauss/DataType-2024.py' \
        '$GAUSSOPTS/GenStandAlone.py' \
        '$DECFILESROOT/options/@{eventType}.py' \
        '$LBPYTHIA8ROOT/options/Pythia8.py' \
        Gauss-Job.py

Only one option file

You can source the various options files from your 'Gauss-Job.py' by adding at its top:

from Gaudi.Configuration import *
importOptions("$APPCONFIGOPTS/Gauss/Beam6500GeV-md100-2016-nu1.6.py")
# etc ...

See if you can generate a generator level only sample for event type 27175000 \( D^{*+} \to D^{0}(\to K^{+}K^{-}\mu^{+}\mu^{-})\pi^{+} \)

Make an nTuple

The .xgen file can be processed into something more usable - processed into an nTuple using DaVinci using the following file (tupler.py).

A larger input file containing 50,000 generated events for event-type can be found on EOS: root://eosuser.cern.ch//eos/lhcb/wg/dpa/wp7/Run3SK/simulation/Gauss-27175000-50000ev-basic.xgen.

from FunTuple import FunctorCollection, FunTuple_MCParticles as FuntupleMC
import FunTuple.functorcollections as FC
from PyConf.Algorithms import PrintMCTree
import Functors as F
from Functors.math import in_range
from DaVinci import Options, make_config
from PyConf.reading import get_mc_particles, get_mc_header
from Hlt2Conf.algorithms_thor import MCParticleFilter


def main(options: Options):
    # FunTuple: define fields (branches)
    fields = {
        "D*(2010)+": "[D*(2010)+ ==> (D0 ==> K+ K- mu+ mu-) pi+]CC",
        "D0": "[D*(2010)+ ==> ^(D0 ==> K+ K- mu+ mu-) pi+]CC",
        "K+": "[D*(2010)+ ==> (D0 ==> ^K+ K- mu+ mu-) pi+]CC",
        "K-": "[D*(2010)+ ==> (D0 ==> K+ ^K- mu+ mu-) pi+]CC",
        "mu+": "[D*(2010)+ ==> (D0 ==> K+ K- ^mu+ mu-) pi+]CC",
        "mu-": "[D*(2010)+ ==> (D0 ==> K+ K- mu+ ^mu-) pi+]CC",
        "pi+": "[D*(2010)+ ==> (D0 ==> K+ K- mu+ mu-) ^pi+]CC",

    }

    # FunTuple: define variables for the D* meson
    variables_D = FunctorCollection(
        {
            "ETA": F.ETA,
            "PHI": F.PHI,
            "TAU": F.MC_LIFETIME,
            "ORIGIN_VX": F.ORIGIN_VX,
            "ORIGIN_VY": F.ORIGIN_VY,
            "ORIGIN_VZ": F.ORIGIN_VZ,
            "END_VX": F.END_VX,
            "END_VY": F.END_VY,
            "END_VZ": F.END_VZ,
        }
    )

    # FunTuple: define common variables
    variables_all = FunctorCollection({"PT": F.PT, "P": F.FOURMOMENTUM, "M": F.MASS})

    # FunTuple: associate functor collections to field (branch) name
    variables = {
        "ALL": variables_all,
        "D*(2010)+": variables_D,
    }

    # FunTuple: define input data
    all_mc_particles = get_mc_particles("/Event/MC/Particles")

    # FunTuple: define event-level variables using functor collections
    mc_header = get_mc_header()
    evt_vars = FC.MCPrimaries(mc_header=mc_header)

    printMC = PrintMCTree(
        MCParticles=all_mc_particles, ParticleNames=["D*(2010)+", "D*(2010)-"], OutputLevel=4
    )

    # now we filter that set of B particles
    cut = F.require_all(in_range(1.8, F.ETA, 5.0))
    filtered_mc_particles = MCParticleFilter(all_mc_particles, F.FILTER(cut))

    tuple_1 = FuntupleMC(
        name="Tuple",
        tuple_name="DecayTree",
        fields=fields,
        variables=variables,
        event_variables=evt_vars,
        inputs=filtered_mc_particles,
    )

    return make_config(options, {"Tuple": [printMC, tuple_1]})

The corresponding file (xgen.yaml) is:

input_files: Gauss-27175000-Xev-202XXXXX.xgen #Change this with name of your file
input_type: ROOT
data_type: 'Upgrade'
simulation: true
conddb_tag: "sim10-2024.Q1.2-v1.1-md100" # make sure it matches the tags you used
dddb_tag: "dddb-20240427" # make sure it matches the tags you used
conditions_version: master
geometry_version: run3/2024.Q1.2-v00.00
histo_file: DV_histo_xgen.root
ntuple_file: DV_tuple_xgen.root
input_raw_format: 0.5
input_process: Gen
lumi: False
write_fsr: False

And run with lb-run -c best DaVinci/v64r13 lbexec tupler.py:main xgen.yaml