diff --git a/DaVinciExamples/python/DaVinciExamples/debugging/example-PrintDecayTree.py b/DaVinciExamples/python/DaVinciExamples/debugging.py similarity index 50% rename from DaVinciExamples/python/DaVinciExamples/debugging/example-PrintDecayTree.py rename to DaVinciExamples/python/DaVinciExamples/debugging.py index f5f079a0bb8bea25e10fcda86e07473be517e408..a3821b472a654de66ccbbe38291953a4f66afdcf 100644 --- a/DaVinciExamples/python/DaVinciExamples/debugging/example-PrintDecayTree.py +++ b/DaVinciExamples/python/DaVinciExamples/debugging.py @@ -1,5 +1,5 @@ ############################################################################### -# (c) Copyright 2021 CERN for the benefit of the LHCb Collaboration # +# (c) Copyright 2021-2022 CERN for the benefit of the LHCb Collaboration # # # # This software is distributed under the terms of the GNU General Public # # Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # @@ -11,34 +11,38 @@ """ Example of a DaVinci job printing decay trees via `PrintDecayTree`. """ - -__author__ = "Eduardo Rodrigues" -__date__ = "2021-03-02" - from PyConf.application import configure, configure_input +from PyConf.application import default_raw_event, make_odin from PyConf.control_flow import CompositeNode, NodeLogic -from PyConf.Algorithms import PrintDecayTree +from PyConf.Algorithms import PrintDecayTree, PrintHeader -from DaVinci import options from DaVinci.reco_objects_from_file import upfront_reconstruction from DaVinci.common_particles_from_file import make_std_loose_jpsi2mumu -# Following line sets options data_type, simulation and DB tags, and the inputs -options.set_input_and_conds_from_testfiledb("Upgrade_Bd2KstarMuMu") -options.evt_max = 100 -options.print_freq = 1 -options.msg_svc_format = "% F%40W%S%7W%R%T %0W%M" -jpsis = make_std_loose_jpsi2mumu() +def print_decay_tree(options): + jpsis = make_std_loose_jpsi2mumu() + + pdt = PrintDecayTree(name="PrintJpsis", Input=jpsis) + + # the "upfront_reconstruction" is what unpacks reconstruction objects, particles and primary vertices + # from file and creates protoparticles. + algs = upfront_reconstruction() + [jpsis, pdt] + + node = CompositeNode( + "PrintJpsiNode", children=algs, combine_logic=NodeLogic.NONLAZY_AND) + + config = configure_input(options) + config.update(configure(options, node)) + return config -pdt = PrintDecayTree(name="PrintJpsis", Input=jpsis) -# the "upfront_reconstruction" is what unpacks reconstruction objects, particles and primary vertices -# from file and creates protoparticles. -algs = upfront_reconstruction() + [jpsis, pdt] +def print_header(options): + with default_raw_event.bind(raw_event_format=options.input_raw_format): + ph = PrintHeader(ODINLocation=make_odin()) -node = CompositeNode( - "PrintJpsiNode", children=algs, combine_logic=NodeLogic.NONLAZY_AND) + node = CompositeNode("PHNode", children=[ph]) -config = configure_input(options) -config.update(configure(options, node)) + config = configure_input(options) + config.update(configure(options, node)) + return config diff --git a/DaVinciExamples/python/DaVinciExamples/debugging/example-PrintHeader.py b/DaVinciExamples/python/DaVinciExamples/debugging/example-PrintHeader.py deleted file mode 100644 index c14de0442e3345d97db92962020676a05b9c7805..0000000000000000000000000000000000000000 --- a/DaVinciExamples/python/DaVinciExamples/debugging/example-PrintHeader.py +++ /dev/null @@ -1,34 +0,0 @@ -############################################################################## -# (c) Copyright 2020-2021 CERN for the benefit of the LHCb Collaboration # -# # -# This software is distributed under the terms of the GNU General Public # -# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # -# # -# In applying this licence, CERN does not waive the privileges and immunities # -# granted to it by virtue of its status as an Intergovernmental Organization # -# or submit itself to any jurisdiction. # -############################################################################### -""" -Example of a DaVinci job printing run and event numbers on every read event. -""" - -__author__ = "Eduardo Rodrigues" -__date__ = "2021-02-25" - -from PyConf.application import configure, configure_input -from PyConf.application import default_raw_event, make_odin -from PyConf.control_flow import CompositeNode -from PyConf.Algorithms import PrintHeader -from DaVinci import options - -options.set_input_and_conds_from_testfiledb('Upgrade_Bd2KstarMuMu') -options.evt_max = 7 -options.input_raw_format = 4.3 - -with default_raw_event.bind(raw_event_format=options.input_raw_format): - ph = PrintHeader(ODINLocation=make_odin()) - -node = CompositeNode("PHNode", children=[ph]) - -config = configure_input(options) -config.update(configure(options, node)) diff --git a/DaVinciExamples/tests/qmtest/debugging.qms/test_example-PrintDecayTree.qmt b/DaVinciExamples/tests/qmtest/debugging.qms/test_example-PrintDecayTree.qmt index 9988de25dc4c4668390b3b4dbd67bf2c85c4fe96..4599bba33073790d2bf7144c9f14dcd8e0ba5bca 100755 --- a/DaVinciExamples/tests/qmtest/debugging.qms/test_example-PrintDecayTree.qmt +++ b/DaVinciExamples/tests/qmtest/debugging.qms/test_example-PrintDecayTree.qmt @@ -11,10 +11,16 @@ --> <!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> <extension class="GaudiTest.GaudiExeTest" kind="test"> -<argument name="program"><text>gaudirun.py</text></argument> +<argument name="program"><text>lbexec</text></argument> +<argument name="test_file_db_options_yaml"><text>Upgrade_Bd2KstarMuMu</text></argument> +<argument name="extra_options_yaml"><text> + evt_max: 100 + print_freq: 1 + msg_svc_format: "% F%40W%S%7W%R%T %0W%M" +</text></argument> <argument name="timeout"><integer>3600</integer></argument> <argument name="args"><set> - <text>../../python/DaVinciExamples/debugging/example-PrintDecayTree.py</text> + <text>DaVinciExamples.debugging:print_decay_tree</text> </set></argument> <argument name="validator"><text> findReferenceBlock("""PrintJpsis INFO Number of counters : 2 diff --git a/DaVinciExamples/tests/qmtest/debugging.qms/test_example-PrintHeader.qmt b/DaVinciExamples/tests/qmtest/debugging.qms/test_example-PrintHeader.qmt index 0f468500a193a72cd2dcfe326220e44b614fd34a..c77570ea9bc94ca4ab6cca8db03ca6ce35f21919 100755 --- a/DaVinciExamples/tests/qmtest/debugging.qms/test_example-PrintHeader.qmt +++ b/DaVinciExamples/tests/qmtest/debugging.qms/test_example-PrintHeader.qmt @@ -11,10 +11,15 @@ --> <!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> <extension class="GaudiTest.GaudiExeTest" kind="test"> -<argument name="program"><text>gaudirun.py</text></argument> +<argument name="program"><text>lbexec</text></argument> +<argument name="test_file_db_options_yaml"><text>Upgrade_Bd2KstarMuMu</text></argument> +<argument name="extra_options_yaml"><text> + evt_max: 7 + input_raw_format: 4.3 +</text></argument> <argument name="timeout"><integer>3600</integer></argument> <argument name="args"><set> - <text>../../python/DaVinciExamples/debugging/example-PrintHeader.py</text> + <text>DaVinciExamples.debugging:print_header</text> </set></argument> <argument name="validator"><text> findReferenceBlock(""" diff --git a/DaVinciTutorials/README.md b/DaVinciTutorials/README.md index 4a9f3cea677fcab86d62058a7012105b1b0bcff4..ea5674452621c401681ebbdd4031c6002c423dcf 100644 --- a/DaVinciTutorials/README.md +++ b/DaVinciTutorials/README.md @@ -1,44 +1,28 @@ -# About +# DaVinci Tutorials The tutorials have originally been developed for the LHCb [starter-kit](https://indico.cern.ch/event/1124730/timetable/#20220316) that took place in March 2022. The tutorials are accompanied by [slides](https://indico.cern.ch/event/1124730/timetable/#20220316) and [recordings](https://videos.cern.ch/record/2295643). Note that in the slides and recordings, the tutorials have been labelled differently to what is present here (the slides and recordings will be updated for the next `starterkit` lesson). -# Setup +## Setup -To setup, either build your own [stack](https://gitlab.cern.ch/rmatev/lb-stack-setup) for DaVinci (WARNING: Takes a very long time to build. Only recommended if you are doing development work) +To setup using the nightlies use: ```bash -#Go to home or any directory of your choice -cd $HOME -#set up the stack -curl https://gitlab.cern.ch/rmatev/lb-stack-setup/raw/master/setup.py | python3 - stack -#compile DaVinci (DV) master -cd stack && make DaVinci +lb-run --nightly=lhcb-master/Today DaVinci/v60r3 bash ``` -or use the `lb-dev` command i.e. +Alternatively, if you need to make non-trivial changes build your own [stack](https://gitlab.cern.ch/rmatev/lb-stack-setup) for DaVinci (WARNING: Takes a very long time to build and is not suited to virtual machines like lxplus) ```bash -#Go to home or any directory of your choice +# Go to home or any directory of your choice cd $HOME -#Note that you might run into trouble if DaVinci hasn't yet been built in the latest lhcb-head slot. -# You can check if it has been built or not here: https://lhcb-nightlies.web.cern.ch/nightly/ -# In which case you can simply use the previous slot number e.g. "--nightly lhcb-head/3270". -lb-dev -c x86_64_v2-centos7-gcc11-opt --nightly lhcb-head DaVinci/HEAD --name DV -cd DV -git lb-use DaVinci -git lb-checkout DaVinci/master DaVinciTutorials -make -``` - -Let us setup the required paths to the DaVinci tutorials directory using the `stack` method (for `lb-dev` method change `DVPATH` accordingly) - -```bash -#path to DaVinci (using stack method, for lb-dev method DVPATH="$HOME/DV") -DVPATH="$HOME/stack/DaVinci" -#path to starterkit examples -TUTORIALSPATH="$DVPATH/DaVinciTutorials/python" +# Setup the "stack/" folder +curl https://gitlab.cern.ch/rmatev/lb-stack-setup/raw/master/setup.py | python3 - stack +# compile DaVinci (DV) master +cd stack +make DaVinci +DaVinci/run bash ``` In the lesson, we will be using the `Turbo` upgrade simulation sample analysing the decays of `Bs0->J/psi (-> mu+ mu-) phi (-> K+ K-)`. @@ -47,23 +31,21 @@ Here our example DST file (`hlt2_passthrough_thor_lines.dst`) and accompanying c <!--For the hands-on session, we will be using a 'Spruce' upgrade simulation sample analysing the decays of `Bc -> Bs0 pi+`. Simulation sample obtained from Spruce line output (`spruce_exclusive_BcToBspi.dst`) and configuration file (`spruce_exclusive.tck.json`) are also at CERN EOS (see `jobopts_spruce.yaml` file).--> -# Tutorial0: Running a simple DaVinci job +## Tutorial0: Running a simple DaVinci job Objectives: -- Running the basic example using the [`click`](https://click.palletsprojects.com/en/8.0.x/) based DaVinci configuration. -- Creating templates for `jobopts.yaml` and `dataprops.yaml`. -- Configuring DV job with `jobopts.yaml` and data properties using `dataprops.yaml`. -- Function that returns a sequence of user defined algorithms. +- Creating an `options.yaml` file that configures the job +- Create a function that returns a sequence of user defined algorithms +- Running the example using `lbexec` Command to run the tutorial: ```bash -cd $TUTORIALSPATH -$DVPATH/run davinci run-mc -i bs2jpsiphi_turbo dataprops.yaml -j jobopts.yaml --user_algorithms tutorial0_basic_DVjob:main +lbexec DaVinciTutorials.tutorial0_basic_DVjob:main "$DAVINCITUTORIALSROOT/options.yaml" ``` -# Tutorial1: FunTuple basic ThOr functors and special field name +## Tutorial1: FunTuple basic ThOr functors and special field name Objectives: @@ -75,40 +57,43 @@ Objectives: - Loading particles in the event from `.dst` onto Transient Event Store (TES) location. - Usage of event filter (mainly to get over a technical hurdle). -Command to run the tutorial: +To see particle properties (for names, properties, etc): ```bash -cd $TUTORIALSPATH +dump_ParticleProperties -t Upgrade | tee ParticleTable.txt +``` -#see particle properties (for names, properties, etc) -$DVPATH/run dump_ParticleProperties -t Upgrade | tee ParticleTable.txt +Command to run the tutorial: -#run example -$DVPATH/run davinci -i bs2jpsiphi_turbo dataprops.yaml -j jobopts.yaml --user_algorithms tutorial1_functors_specialfield:main +```bash +lbexec DaVinciTutorials.tutorial1_functors_specialfield:main "$DAVINCITUTORIALSROOT/options.yaml" ``` External links: + - Decay descriptors: https://twiki.cern.ch/twiki/bin/view/LHCb/FAQ/LoKiNewDecayFinders - `ThOr` documentation: https://lhcbdoc.web.cern.ch/lhcbdoc/moore/master/selection/thor_functors.html - [List](https://gitlab.cern.ch/lhcb/Rec/-/blob/master/Phys/FunctorCore/python/Functors/__init__.py) of available `ThOr` functors. -# Tutorial2: LoKi functors +## Tutorial2: LoKi functors Objectives: + - Defining a collection of `LoKi` functors together with `ThOr` functors. - Defining a LoKi preamble for a complex LoKi functor to be used in `FunctorCollection`. Command to run the tutorial: + ```bash -#run example -$DVPATH/run davinci -i bs2jpsiphi_turbo dataprops.yaml -j jobopts.yaml --user_algorithms tutorial2_LoKi:main +lbexec DaVinciTutorials.tutorial2_LoKi:main "$DAVINCITUTORIALSROOT/options.yaml" ``` External links: + - `LoKi` official page: http://lhcb-comp.web.cern.ch/Analysis/Loki/index.html - `LoKi` starter-kit page: https://lhcb.github.io/starterkit-lessons/first-analysis-steps/loki-functors.html -# Tutorial3: ThOr functors (Data dependence, arguments and return types) +## Tutorial3: ThOr functors (Data dependence, arguments and return types) Objectives: @@ -118,24 +103,25 @@ Objectives: - Basic maths operators with functor returning scalars e.g. `CHILD_2(F.END_VZ) - F.END_VZ`, which returns difference in end vertex of child and mother. Command to run the tutorial: + ```bash -#run example -$DVPATH/run davinci -i bs2jpsiphi_turbo dataprops.yaml -j jobopts.yaml --user_algorithms tutorial3_ThOrfunctors:main +lbexec DaVinciTutorials.tutorial3_ThOrfunctors:main "$DAVINCITUTORIALSROOT/options.yaml" ``` -# Tutorial4: Usage of pre-defined `functorcollections`, storing trigger and event-level information +## Tutorial4: Usage of pre-defined `functorcollections`, storing trigger and event-level information Objectives: + - Usage of pre-defined `functorcollections`, inspecting and manipulating them before loading it onto `FunTuple`. - Exploring few simple methods of `FunctorCollection` class. - Storing event-level information with `functorcollection` e.g. RunNumber, EventNumber, etc. - Storing trigger (`Hlt1`, `Hlt2` and `Sprucing`) information with `functorcollection` e.g. line decisions, Trigger Configuration Key (TCK). Command to run the tutorial: + ```bash -#run example -$DVPATH/run davinci -i bs2jpsiphi_turbo dataprops.yaml -j jobopts.yaml --user_algorithms tutorial4_trigger_eventinfo:main +lbexec DaVinciTutorials.tutorial4_trigger_eventinfo:main "$DAVINCITUTORIALSROOT/options.yaml" ``` External links: @@ -144,46 +130,50 @@ External links: - List of currently available `functorcollections` are [here](https://gitlab.cern.ch/lhcb/Analysis/-/blob/master/Phys/FunTuple/python/FunTuple/functorcollections.py) and the planned ones are [here](https://gitlab.cern.ch/lhcb-dpa/project/-/issues/178). -# Tutorial5: MC truth association and background category algorithm +## Tutorial5: MC truth association and background category algorithm Objectives: + - Configuring the MC association and background category algorithm (`MCTruthAndBkgCatAlg`) to build a relation table. For MC association, the table is essentially a map between reconstructed particles and "truth" particles (MCParticle). - Usage of the relations table and `ThOr` functor handling such table (e.g. `F.MAP_INPUT(func, RelTable`) to get truth information and background category. - Also explore `functorcollections` such as `MCKinematics`, `MCHierarchy`, etc. Command to run the tutorial: + ```bash -#run example -$DVPATH/run davinci -i bs2jpsiphi_turbo dataprops.yaml -j jobopts.yaml --user_algorithms tutorial5_MCTruth:main +lbexec DaVinciTutorials.tutorial5_MCTruth:main "$DAVINCITUTORIALSROOT/options.yaml" ``` -# Tutorial6: Decay Tree Fitter (DTF) algorithm +## Tutorial6: Decay Tree Fitter (DTF) algorithm Objectives: + - Configuring the Decay Tree Fitter algorithm (`DecayTreeFitterAlg`) to build a relation table i.e. map between the candidate and the refitted candidate. - Usage of the relations table and `ThOr` functor (e.g. `F.MAP_INPUT(func, RelTable`) to get refitted information of the candidate. - Defining different instances of DTF algorithm with mass constraints, primary vertex constraint. Command to run the tutorial: + ```bash -#run example -$DVPATH/run davinci -i bs2jpsiphi_turbo dataprops.yaml -j jobopts.yaml --user_algorithms tutorial6_DecayTreeFit:main +lbexec DaVinciTutorials.tutorial6_DecayTreeFit:main "$DAVINCITUTORIALSROOT/options.yaml" ``` External links on decay tree fitter: - - Paper: https://inspirehep.net/literature/679286 - - Twiki : https://twiki.cern.ch/twiki/bin/view/LHCb/DecayTreeFitter - - Starter-kit: https://lhcb.github.io/starterkit-lessons/first-analysis-steps/decay-tree-fitter.html - - Slides by Wouter: https://www.nikhef.nl/~wouterh/topicallectures/TrackingAndVertexing/part6.pdf -# Tutorial7: Defining different instances of FunTuple when analysing outputs of multiple selection lines +- Paper: https://inspirehep.net/literature/679286 +- Twiki : https://twiki.cern.ch/twiki/bin/view/LHCb/DecayTreeFitter +- Starter-kit: https://lhcb.github.io/starterkit-lessons/first-analysis-steps/decay-tree-fitter.html +- Slides by Wouter: https://www.nikhef.nl/~wouterh/topicallectures/TrackingAndVertexing/part6.pdf + +## Tutorial7: Defining different instances of FunTuple when analysing outputs of multiple selection lines Objectives: + - Defining different instances of FunTuple to return different `TDirectory` in the output ROOT file. - Changes to the function returning user algorithm "sequence" to allow for this. Command to run the tutorial: + ```bash -#run example Turbo but with two decays -$DVPATH/run davinci -i bs2jpsiphi_turbo dataprops.yaml -j jobopts_turbo.yaml --user_algorithms tutorial7_multiple_sel_lines:main -``` \ No newline at end of file +lbexec DaVinciTutorials.tutorial7_multiple_sel_lines:main "$DAVINCITUTORIALSROOT/options.yaml" +``` diff --git a/DaVinciTutorials/options.yaml b/DaVinciTutorials/options.yaml new file mode 100644 index 0000000000000000000000000000000000000000..48dd2fd5eba08215fa0c4fd9648342bdf7e78a0d --- /dev/null +++ b/DaVinciTutorials/options.yaml @@ -0,0 +1,13 @@ +input_files: + - 'root://eoslhcb.cern.ch//eos/lhcb/wg/dpa/wp3/tests/hlt2_passthrough_thor_lines.dst' +annsvc_config: 'root://eoslhcb.cern.ch//eos/lhcb/wg/dpa/wp3/tests/hlt2_passthrough_thor_lines.tck.json' +input_type: ROOT +evt_max: 100 +ntuple_file: davinci_ntuple.root +enable_unpack: True +process: 'Turbo' +print_freq: 1 +data_type: Upgrade +simulation: true +conddb_tag: sim-20180530-vc-md100 +dddb_tag: dddb-20180815 diff --git a/DaVinciTutorials/python/DaVinciTutorials/__init__.py b/DaVinciTutorials/python/DaVinciTutorials/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/DaVinciTutorials/python/DaVinciTutorials/tutorial0_basic_DVjob.py b/DaVinciTutorials/python/DaVinciTutorials/tutorial0_basic_DVjob.py new file mode 100644 index 0000000000000000000000000000000000000000..59b83804223c732f1d66b304a542829bece8242f --- /dev/null +++ b/DaVinciTutorials/python/DaVinciTutorials/tutorial0_basic_DVjob.py @@ -0,0 +1,42 @@ +############################################################################### +# (c) Copyright 2021-2022 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the GNU General Public # +# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # +# # +# In applying this licence, CERN does not waive the privileges and immunities # +# granted to it by virtue of its status as an Intergovernmental Organization # +# or submit itself to any jurisdiction. # +############################################################################### +from DaVinci import make_config +from DaVinci.algorithms import add_filter +from PyConf.Algorithms import PrintDecayTree +from PyConf.dataflow import force_location + + +def main(options): + # Load data from dst onto a "temporary" TES (Transient Event Store) location for a given event cycle. + # We loop over the algorithms event-by-event, so for given event cycle, TES maps "path" to an "object". + # For the TES path checkout spruce_passthrough.tck.json or you can do a dst dump + # (see https://lhcb.github.io/starterkit-lessons/first-analysis-steps/interactive-dst.html) + # + # The TES location input to the algorithms must of type "PyConf.DataHandle" and not pure strings. + # Therefore we wrap the TES location string below with "force_location" wrapper class. + turbo_line = "Hlt2BsToJpsiPhi_JPsi2MuMu_PhiToKK_Line" + input_data = force_location(f"/Event/HLT2/{turbo_line}/Particles") + + #Add a filter: We are not really filtering over particles, we are getting over a technical hurdle here. + # The hurdle being that if the event hasn't fired a HLT2 line then no TES location exists + # and therefore if any algorithm tries to look for this location, we run into a problem. + # Side step this issue with a filter, where: + # - 1st argument is a user defined name. + # - 2nd argument is the line decision (simply append "Decision" to your HLT2 line name (or inspect hlt2_starterkit.tck.json)) + my_filter = add_filter(options, "HDRFilter_SeeNoEvil", + f"HLT_PASS('{turbo_line}')") + + # Defining an algorithm. The alorithm here prints the decaytree + pdt = PrintDecayTree(name="PrintBsToJpsiPhi", Input=input_data) + + user_algorithms = [my_filter, pdt] + + return make_config(options, user_algorithms) diff --git a/DaVinciTutorials/python/DaVinciTutorials/tutorial1_functors_specialfield.py b/DaVinciTutorials/python/DaVinciTutorials/tutorial1_functors_specialfield.py new file mode 100644 index 0000000000000000000000000000000000000000..6c97886a0f88901c20a5ce062b23d2da5544cb0a --- /dev/null +++ b/DaVinciTutorials/python/DaVinciTutorials/tutorial1_functors_specialfield.py @@ -0,0 +1,83 @@ +############################################################################### +# (c) Copyright 2021-2022 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the GNU General Public # +# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # +# # +# In applying this licence, CERN does not waive the privileges and immunities # +# granted to it by virtue of its status as an Intergovernmental Organization # +# or submit itself to any jurisdiction. # +############################################################################### +import Functors as F +from DaVinci import make_config +from DaVinci.algorithms import add_filter +from FunTuple import FunctorCollection as FC +from FunTuple import FunTuple_Particles as Funtuple +from PyConf.dataflow import force_location + + +def main(options): + # Define a dictionary of "field name" -> "decay descriptor component". + # - For particle properties, names, etc checkout "ParticleTable.txt" + # that can be obtained via command "$DVPATH/run dump_ParticleProperties -t Upgrade | tee ParticleTable.txt". + # - For decay descriptor info see for example https://twiki.cern.ch/twiki/bin/view/LHCb/FAQ/LoKiNewDecayFinders + # If your decay is self-tagged (which is the most common case) then you will need "[<decay-descriptor>]CC" + fields = { + "Bs": "B_s0 -> (J/psi(1S) -> mu+ mu-) (phi(1020) ->K+ K-)", + "Jpsi": "B_s0 -> ^(J/psi(1S) -> mu+ mu-) (phi(1020) ->K+ K-)", + "Phi": "B_s0 -> (J/psi(1S) -> mu+ mu-) ^(phi(1020) ->K+ K-)", + "Mup": "B_s0 -> (J/psi(1S) ->^mu+ mu-) (phi(1020) ->K+ K-)", + "Mum": "B_s0 -> (J/psi(1S) -> mu+ ^mu-) (phi(1020) ->K+ K-)", + "Kp": "B_s0 -> (J/psi(1S) -> mu+ mu-) (phi(1020) ->^K+ K-)", + "Km": "B_s0 -> (J/psi(1S) -> mu+ mu-) (phi(1020) ->K+ ^K-)", + } + + # Define a collection of functors called FunctorCollection, which takes dictionary of "variable name" -> "ThOr" functor + # (Can also be a "LoKi" functor see next tutorial). + # For more info on ThOr see https://lhcbdoc.web.cern.ch/lhcbdoc/moore/master/selection/thor_functors.html#functor-cache + # For list of ThOr functors see https://lhcbdoc.web.cern.ch/lhcbdoc/moore/master/selection/thor_functors_reference.html + # Here we define functor collection to be added to "ALL" fields (Bs, Jpsi, Phi, etc) + all_vars = FC({ + "THOR_P": F.P, #ThOr momentum functor + "ID": F. + PARTICLE_ID, #Refer to "ParticleTable.txt" for particle ID (see above on how to get this file) + }) + + # Define functors to be added only to Bs and Jpsi fields + bs_jpsi_fun = FC({"PT_THOR": F.PT, "PX": F.PX, "PY": F.PY}) + + #Define variables dictionary "field name" -> Collections of functor. + # "ALL" is a special field name that adds PT to all the fields defined above (i.e. Bs,Jpsi,Mup,Mum,Kp,Km) + variables = { + "ALL": all_vars, + "Bs": bs_jpsi_fun, + "Jpsi": bs_jpsi_fun, + } + + # Inspect string representation of ThOr Functor + # This string representation is converted to C++ object + # using gcc or FunctorCache see https://lhcbdoc.web.cern.ch/lhcbdoc/moore/master/selection/thor_functors.html#functors-in-a-selection-framework + print(F.PT.code()) + #print(F.PT.headers()) + print(F.PT.code_repr()) + + #Define the TES location (see previous example for explanation) + turbo_line = "Hlt2BsToJpsiPhi_JPsi2MuMu_PhiToKK_Line" + input_data = force_location(f"/Event/HLT2/{turbo_line}/Particles") + + #Define a filter (see previous example for explaination) + my_filter = add_filter(options, "HDRFilter_SeeNoEvil", + f"HLT_PASS('{turbo_line}')") + + #Define instance of FunTuple + mytuple = Funtuple( + "TDirectoryName", + "TTreeName", + # dictionary of particle : decay descriptor + fields=fields, + # dictionary of particle : variables to insert in TTree + variables=variables, + inputs=input_data) + + config = make_config(options, [my_filter, mytuple]) + return config diff --git a/DaVinciTutorials/python/DaVinciTutorials/tutorial2_LoKi.py b/DaVinciTutorials/python/DaVinciTutorials/tutorial2_LoKi.py new file mode 100644 index 0000000000000000000000000000000000000000..a527d5408cb6df9ac5361912e40c9b1efaf1d607 --- /dev/null +++ b/DaVinciTutorials/python/DaVinciTutorials/tutorial2_LoKi.py @@ -0,0 +1,83 @@ +############################################################################### +# (c) Copyright 2021-2022 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the GNU General Public # +# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # +# # +# In applying this licence, CERN does not waive the privileges and immunities # +# granted to it by virtue of its status as an Intergovernmental Organization # +# or submit itself to any jurisdiction. # +############################################################################### +import Functors as F +from DaVinci import make_config +from DaVinci.algorithms import add_filter +from FunTuple import FunctorCollection as FC +from FunTuple import FunTuple_Particles as Funtuple +from PyConf.dataflow import force_location + + +def main(options): + # Define a dictionary of "field name" -> "decay descriptor component". + fields = { + "Bs": "B_s0 -> (J/psi(1S) -> mu+ mu-) (phi(1020) ->K+ K-)", + "Jpsi": "B_s0 -> ^(J/psi(1S) -> mu+ mu-) (phi(1020) ->K+ K-)", + "Phi": "B_s0 -> (J/psi(1S) -> mu+ mu-) ^(phi(1020) ->K+ K-)", + "Mup": "B_s0 -> (J/psi(1S) ->^mu+ mu-) (phi(1020) ->K+ K-)", + "Mum": "B_s0 -> (J/psi(1S) -> mu+ ^mu-) (phi(1020) ->K+ K-)", + "Kp": "B_s0 -> (J/psi(1S) -> mu+ mu-) (phi(1020) ->^K+ K-)", + "Km": "B_s0 -> (J/psi(1S) -> mu+ mu-) (phi(1020) ->K+ ^K-)", + } + + # Define a collection of functors called FunctorCollection, which takes dictionary of "variable name" -> "LoKi" or "ThOr" functor + # For more info on ThOr see https://lhcbdoc.web.cern.ch/lhcbdoc/moore/master/selection/thor_functors.html#functor-cache + # For list of ThOr functors see https://lhcbdoc.web.cern.ch/lhcbdoc/moore/master/selection/thor_functors_reference.html + # For information on LoKi functor see https://lhcb.github.io/starterkit-lessons/first-analysis-steps/loki-functors.html + mom_fun = FC({ + "THOR_PT": F.PT, + "THOR_PX": F.PX, + "THOR_PY": F.PY, + "LOKI_PT": 'PT', # LoKi functor code is represented in a string + "LOKI_PX": 'PX', + "LOKI_PY": 'PY' + }) + + # Define a LoKi preamble (Note that one can define preambles in ThOr using python lambda function see next tutorial or via FunctorComposition) + # i.e. rename a complex LoKi functor to a user deinfed name (e.g. TRACK_MAX_PT) + # This helps us to use "TRACK_MAX_PT" when constructing FunctorCollection + loki_preamble = ['TRACK_MAX_PT = MAXTREE(ISBASIC & HASTRACK, PT, -1)'] + + # Define collections to be added to fields + max_pt_fun = FC({ + # With LoKi + "MAX_PT_LOKI": "TRACK_MAX_PT", + # ThOr (not equivalent, sum of pT of composites not basic). MAXTREE ThOr doesn't exist yet. + "MAX_PT_THOR": F.MAX(F.PT), + }) + + # Define variables dictionary "field name" -> Collections of functor. + variables = { + "ALL": mom_fun, + "Bs": max_pt_fun, + "Jpsi": max_pt_fun, + "Phi": max_pt_fun, + } + + #Load data from dst onto a TES + turbo_line = "Hlt2BsToJpsiPhi_JPsi2MuMu_PhiToKK_Line" + input_data = force_location(f"/Event/HLT2/{turbo_line}/Particles") + + #Add a filter + my_filter = add_filter(options, "HDRFilter_SeeNoEvil", + f"HLT_PASS('{turbo_line}')") + + #Define instance of FunTuple + mytuple = Funtuple( + "TDirectoryName", + "TTreeName", + fields=fields, + variables=variables, + loki_preamble=loki_preamble, #optional argument + inputs=input_data) + + config = make_config(options, [my_filter, mytuple]) + return config diff --git a/DaVinciTutorials/python/DaVinciTutorials/tutorial3_ThOrfunctors.py b/DaVinciTutorials/python/DaVinciTutorials/tutorial3_ThOrfunctors.py new file mode 100644 index 0000000000000000000000000000000000000000..9ca000a32e93d096ee4236d5cd3ccd801af6fa18 --- /dev/null +++ b/DaVinciTutorials/python/DaVinciTutorials/tutorial3_ThOrfunctors.py @@ -0,0 +1,107 @@ +############################################################################### +# (c) Copyright 2021-2022 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the GNU General Public # +# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # +# # +# In applying this licence, CERN does not waive the privileges and immunities # +# granted to it by virtue of its status as an Intergovernmental Organization # +# or submit itself to any jurisdiction. # +############################################################################### +import Functors as F +from DaVinci import make_config +from DaVinci.algorithms import add_filter +from DaVinci.reco_objects import make_pvs_v2 +from FunTuple import FunctorCollection as FC +from FunTuple import FunTuple_Particles as Funtuple +from PyConf.dataflow import force_location + + +def main(options): + #Define a dictionary of "field name" -> "decay descriptor component". + # Can get daughter information from the head of the decay using F.CHILD functors see below. + fields = { + "Bs": "B_s0 -> (J/psi(1S) -> mu+ mu-) (phi(1020) ->K+ K-)", + "Phi": "B_s0 -> (J/psi(1S) -> mu+ mu-) ^(phi(1020) ->K+ K-)", + "Kp": "B_s0 -> (J/psi(1S) -> mu+ mu-) (phi(1020) ->^K+ K-)", + "Km": "B_s0 -> (J/psi(1S) -> mu+ mu-) (phi(1020) ->K+ ^K-)", + } + + #Load PVs onto TES from data, like we did with input_data below + # Creating v2 reconstructed vertices to be used in the following functor + # For the time being there's a mix of legacy and v2 event classes. That will eventually be cleaned once the + # event model is fixed. In the meantime there are helper functions in DaVinci. + pvs = make_pvs_v2(process=options.process) + + #Evaluate the impact parameter + all_vars = {} + #The ThOr functor F.BPVIPCHI2 is data dependent. It takes as input list of pvs. + #It calculates impact parameter chisq wrt best PV. + # - best PV is the PV which fits best the FD of the B candidate. + # - impact parameter chisq is the difference in the vertex-fit chisq of a given PV reconstructed with and w/o the track under consideration. + all_vars['BPVIPCHI2'] = F.BPVIPCHI2(pvs) + + #define dictionary + bs_vars = {} + + #Tupling vector functors + # Some functors could also return std::map<std::string, std::any> (e.g. F.DECISIONS(Lines=line_names, DecReports=dec_report)) + bs_vars['BPVFDVEC_'] = F.BPVFDVEC(pvs) #Returns 3-vector + bs_vars['FOURMOM_P'] = F.FOURMOMENTUM #Returns 4-vector + + #define some helpful lambda function to simplify syntax + # This is bit like LoKi preamble of renaming functors that we encountred in previous tutorial. + CHILD_1 = lambda func: F.CHILD(1, func) + CHILD_2 = lambda func: F.CHILD(2, func) + SUBCOMB_12 = lambda func: F.SUBCOMB(Functor=func, Indices=(1, 2)) + + #Store the ID of the two daughters of B_s0 + bs_vars['jpsi_ID'] = CHILD_1(F.PARTICLE_ID) + bs_vars['phi_ID'] = CHILD_2(F.PARTICLE_ID) + bs_vars['Kp_ID'] = CHILD_2(CHILD_1(F.PARTICLE_ID)) + + #Calculate sum of pT of jpsi daughter tracks + bs_vars['jpsi_TRACKSUMPT'] = CHILD_1(F.SUM(F.PT)) + + #Calculate impact parameter of K+ + bs_vars['Kp_BPVIP'] = CHILD_2(CHILD_1(F.BPVIP(pvs))) + + #Calculate invariant mass of K+ and K- combination + bs_vars['phi_M_comb'] = CHILD_2(SUBCOMB_12(F.MASS)) + + #Calculate the difference in end vertex between phi and Bs + bs_vars['Delta_END_VZ_PhiBs0'] = CHILD_2(F.END_VZ) - F.END_VZ + + #Calculate inv mass of K+pi- where the K- is given the mass hypothesis of pi- + bs_vars['phi_mass_kpi'] = CHILD_2(F.MASSWITHHYPOTHESES(('K+', 'pi-'))) + + #Calculate inv mass of K+K- + # There three functors for computing this i.e. F.MASS, CHILD_2(SUBCOMB_12(F.MASS)) and CHILD_2(F.MASSWITHHYPOTHESES(('K+', 'K-'))) but why? + # (see issue: https://gitlab.cern.ch/lhcb/Rec/-/issues/307) + bs_vars['phi_mass_kk'] = CHILD_2(F.MASSWITHHYPOTHESES(('K+', 'K-'))) + all_vars['M'] = F.MASS + + #Define variables dictionary "field name" -> Collections of functor + variables = { + "ALL": FC(all_vars), + "Bs": FC(bs_vars), + } + + #Load data from dst onto a TES + turbo_line = "Hlt2BsToJpsiPhi_JPsi2MuMu_PhiToKK_Line" + input_data = force_location(f"/Event/HLT2/{turbo_line}/Particles") + + #Add a filter + my_filter = add_filter(options, "HDRFilter_SeeNoEvil", + f"HLT_PASS('{turbo_line}')") + + #Define instance of FunTuple + mytuple = Funtuple( + "TDirectoryName", + "TTreeName", + fields=fields, + variables=variables, + inputs=input_data) + + config = make_config(options, [my_filter, mytuple]) + return config diff --git a/DaVinciTutorials/python/DaVinciTutorials/tutorial4_trigger_eventinfo.py b/DaVinciTutorials/python/DaVinciTutorials/tutorial4_trigger_eventinfo.py new file mode 100644 index 0000000000000000000000000000000000000000..209e4cf86fec2517d38f712a43d25845647abf90 --- /dev/null +++ b/DaVinciTutorials/python/DaVinciTutorials/tutorial4_trigger_eventinfo.py @@ -0,0 +1,109 @@ +############################################################################### +# (c) Copyright 2021-2022 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the GNU General Public # +# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # +# # +# In applying this licence, CERN does not waive the privileges and immunities # +# granted to it by virtue of its status as an Intergovernmental Organization # +# or submit itself to any jurisdiction. # +############################################################################### +import Functors as F +from DaVinci import make_config +from DaVinci.algorithms import add_filter +from FunTuple import FunctorCollection as FC +from FunTuple import FunTuple_Particles as Funtuple +from PyConf.dataflow import force_location + + +def main(options): + #Define a dictionary of "field name" -> "decay descriptor component". + fields = {"Bs": "B_s0 -> (J/psi(1S) -> mu+ mu-) (phi(1020) ->K+ K-)"} + + #To help users, there are pre-defined FunctorCollections (Tuple-tool like objects for Run1/2 veterans) that you can import and inspect. + # Here we import a pre-defined FunctorCollection "Kinematics". + # One can call "print(help(Kinematics))" (you have to press "q" to exit after calling) to check the usage and their arguments. + # Functors that have data dependency will naturally induce data dependency on the functorcollections. + # + # To see what functor collections are available see: https://gitlab.cern.ch/lhcb/Analysis/-/blob/master/Phys/FunTuple/python/FunTuple/functorcollections.py + from FunTuple.functorcollections import Kinematics + + #Inspect whats in the collection by printing + kin = Kinematics() + print(kin) + + #Define new collection + coll = FC({"ID": F.PARTICLE_ID}) + + #Add to existing collections (can also subtract two collections) + kin += coll + + #Remove from collections + kin.pop(['PX', 'PT', 'PZ', 'PY', 'ENERGY']) + print(kin) + + #Can also obtain a pure dictionary from collections via + # - kin.functor_dict (Contains both LoKi and ThOr) + # - kin.get_thor_functors() + # - kin.get_loki_functors() + print(kin.functor_dict) + print(kin.get_thor_functors()) + # empty dictionary since we have no LoKi functors in the collection + print(kin.get_loki_functors()) + + #Now import two other pre-defined FunctorCollections: SelectionInfo and EventInfo + # - SelectionInfo: Contains functors related to storing Hlt1, Hlt2 or Sprucing trigger line decision and Trigger Configuration Key (TCK). + # - EventInfo: Contains functors related to storing event information EVENTNUMBER, RUNNUMBER, GPSTIME, etc. + # + #As before you can call help with "print(help(EventInfo))" or "print(help(SelectionInfo))" (you have to press "q" to exit after calling) + from FunTuple.functorcollections import SelectionInfo, EventInfo + + #Get event information like RUNNUMBER, EVENTNUMBER. + # These are stored in "LHCb::ODIN" C++ object which the ThOr functors take as input (like PVs in Example7), load it onto TES using "get_odin". + # The attribute extra_info is False by default, if set to "True" you get info on + # bunchcrossing id, ODIN TCK, GPS Time, etc + from DaVinci.algorithms import get_odin + odin = get_odin(options) + evtinfo = EventInfo(odin, extra_info=False) + print(evtinfo) + + #Get selection line decision and HlT2 TCK. + # These decisions are stored in "LHCb::HltDecReports" object, which the ThOr functors take as input (like PVs in Example7), load it onto TES using "get_decreports". + # The function "get_decreports" takes as input: + # - sel_type: Type of selection "Hlt2" or "Spruce" + # - line_names: list of line decision in this instance HLT2 line. Should return True for all since we are using the output of this line. + # + # The `Hlt1` decisions can be stored in similar way to `Hlt2` and `Spruce` + # (see example `option_trigger_decisions` in `DaVinciExamples` folder). + # For details, can also refer to the [talk](https://indico.cern.ch/event/1164051/#5-accessing-hlt1-decisions-usi) + # (The talk mentions that to persist Hlt1 decisions, one needs to add few options to the Moore script). + from DaVinci.algorithms import get_decreports + sel_type = "Hlt2" #User defined and will be used as prefix for TBranch in the root file + dec_report = get_decreports(sel_type, options) + turbo_line = "Hlt2BsToJpsiPhi_JPsi2MuMu_PhiToKK_Line" + turbo_line2 = "Hlt2BsToJpsiPhi_JPsi2ee_PhiToKK_Line" + line_names = [f'{turbo_line}Decision', f'{turbo_line2}'] + selinfo = SelectionInfo(sel_type, dec_report, line_names) + print(selinfo) + + #Define variables dictionary "field name" -> Collections of functor + variables = {"ALL": kin} + + #Load data from dst onto a TES + input_data = force_location(f"/Event/HLT2/{turbo_line}/Particles") + + #Add a filter + my_filter = add_filter(options, "HDRFilter_SeeNoEvil", + f"HLT_PASS('{turbo_line}')") + + #Define instance of FunTuple + mytuple = Funtuple( + "TDirectoryName", + "TTreeName", + fields=fields, + variables=variables, + event_variables=evtinfo + selinfo, + inputs=input_data) + + config = make_config(options, [my_filter, mytuple]) + return config diff --git a/DaVinciTutorials/python/DaVinciTutorials/tutorial5_MCTruth.py b/DaVinciTutorials/python/DaVinciTutorials/tutorial5_MCTruth.py new file mode 100644 index 0000000000000000000000000000000000000000..4a1a61c90f83b0b5f08e9610a3d095e39ad0e155 --- /dev/null +++ b/DaVinciTutorials/python/DaVinciTutorials/tutorial5_MCTruth.py @@ -0,0 +1,103 @@ +############################################################################### +# (c) Copyright 2021-2022 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the GNU General Public # +# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # +# # +# In applying this licence, CERN does not waive the privileges and immunities # +# granted to it by virtue of its status as an Intergovernmental Organization # +# or submit itself to any jurisdiction. # +############################################################################### +import Functors as F +from DaVinci import make_config +from DaVinci.algorithms import add_filter +from FunTuple import FunctorCollection as FC +from FunTuple import FunTuple_Particles as Funtuple +from PyConf.dataflow import force_location + + +def main(options): + #Define a dictionary of "field name" -> "decay descriptor component". + fields = { + "Bs": "B_s0 -> (J/psi(1S) -> mu+ mu-) (phi(1020) ->K+ K-)", + "Jpsi": "B_s0 ->^(J/psi(1S) -> mu+ mu-) (phi(1020) ->K+ K-)", + "Phi": "B_s0 -> (J/psi(1S) -> mu+ mu-) ^(phi(1020) ->K+ K-)", + "Mup": "B_s0 -> (J/psi(1S) ->^mu+ mu-) (phi(1020) ->K+ K-)", + "Mum": "B_s0 -> (J/psi(1S) -> mu+ ^mu-) (phi(1020) ->K+ K-)", + "Kp": "B_s0 -> (J/psi(1S) -> mu+ mu-) (phi(1020) ->^K+ K-)", + "Km": "B_s0 -> (J/psi(1S) -> mu+ mu-) (phi(1020) ->K+ ^K-)", + } + + #Import FunctorCollections Kinematics, MCKinematics, MCHierarchy + # There is also "MCVertexInfo" but we won't import it here. + # + # See whats available at: https://gitlab.cern.ch/lhcb/Analysis/-/blob/master/Phys/FunTuple/python/FunTuple/functorcollections.py + from FunTuple.functorcollections import Kinematics, MCKinematics, MCHierarchy + + #We can seek help on these functorcollections using following commands (if you run these commmands, press "q" to exit and continue). + # - print(help(MCKinematics)) + # - print(help(MCHierarchy)) + # + # We see that it takes an input an algorithm configured_MCTruthAndBkgCatAlg(inputdata), so lets import that. + from DaVinci.truth_matching import configured_MCTruthAndBkgCatAlg + + #Load data from dst onto a TES + turbo_line = "Hlt2BsToJpsiPhi_JPsi2MuMu_PhiToKK_Line" + input_data = force_location(f"/Event/HLT2/{turbo_line}/Particles") + #Define an algorithm that builds a map i.e. one-to-one relation b/w Reco Particle -> Truth MC Particle. + mctruth = configured_MCTruthAndBkgCatAlg(inputs=input_data) + print(mctruth.MCAssocTable) + + #Pass it to collections + kin = Kinematics() + mckin = MCKinematics(mctruth) + mchierarchy = MCHierarchy(mctruth) + print(mckin) + print(mchierarchy) + + #Loop over and keep only whats required + kin = FC({ + k: v + for k, v in kin.get_thor_functors().items() if k == 'P' or k == 'M' + }) + mckin = FC( + {k: v + for k, v in mckin.get_thor_functors().items() if k == 'TRUEP'}) + mchierarchy = FC({ + k: v + for k, v in mchierarchy.get_thor_functors().items() if k == 'TRUEID' + }) + print(kin) + print(mckin) + print(mchierarchy) + + #To get truth information with a functor that is not present in the collections + # - The 1st argument is the functor that returns the relevant information + # - The 2nd argument is relation table i.e. a one-to-one map b/w Reco Particle -> Truth MC Particle. + extra_info = { + "TRUEEID": F.MAP_INPUT(F.PARTICLE_ID, mctruth.MCAssocTable), + "TRUEEPHI": F.MAP_INPUT(F.PHI, mctruth.MCAssocTable) + } + extra_info = FC(extra_info) + + #The algorithm mctruth also outputs a map b/w particle and bkg category which can be obtained using the functor + # For more info on background category see: https://twiki.cern.ch/twiki/bin/view/LHCb/TupleToolMCBackgroundInfo + bkg_cat = FC({"BKGCAT": F.BKGCAT(Relations=mctruth.BkgCatTable)}) + + #Define variables dictionary "field name" -> Collections of functor + variables = {"ALL": kin + mckin + mchierarchy + bkg_cat, "Kp": extra_info} + + #Add a filter + my_filter = add_filter(options, "HDRFilter_SeeNoEvil", + f"HLT_PASS('{turbo_line}')") + + #Define instance of FunTuple + mytuple = Funtuple( + "TDirectoryName", + "TTreeName", + fields=fields, + variables=variables, + inputs=input_data) + + config = make_config(options, [my_filter, mytuple]) + return config diff --git a/DaVinciTutorials/python/DaVinciTutorials/tutorial6_DecayTreeFit.py b/DaVinciTutorials/python/DaVinciTutorials/tutorial6_DecayTreeFit.py new file mode 100644 index 0000000000000000000000000000000000000000..9053576c83acbe73afdc4ca9e36dabca99dccd31 --- /dev/null +++ b/DaVinciTutorials/python/DaVinciTutorials/tutorial6_DecayTreeFit.py @@ -0,0 +1,113 @@ +############################################################################### +# (c) Copyright 2021-2022 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the GNU General Public # +# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # +# # +# In applying this licence, CERN does not waive the privileges and immunities # +# granted to it by virtue of its status as an Intergovernmental Organization # +# or submit itself to any jurisdiction. # +############################################################################### +import Functors as F +from DaVinci import make_config +from DaVinci.algorithms import add_filter +from FunTuple import FunctorCollection as FC +from FunTuple import FunTuple_Particles as Funtuple +from FunTuple.functorcollections import Kinematics +from PyConf.dataflow import force_location + + +def main(options): + """ + For more information on DTF see: + - https://inspirehep.net/literature/679286 + - https://twiki.cern.ch/twiki/bin/view/LHCb/DecayTreeFitter + - https://www.nikhef.nl/~wouterh/topicallectures/TrackingAndVertexing/part6.pdf + """ + from DecayTreeFitter import DTFAlg + + #Define a dictionary of "field name" -> "decay descriptor component". + fields = { + "Bs": "B_s0 -> (J/psi(1S) -> mu+ mu-) (phi(1020) ->K+ K-)", + "Jpsi": "B_s0 ->^(J/psi(1S) -> mu+ mu-) (phi(1020) ->K+ K-)", + "Phi": "B_s0 -> (J/psi(1S) -> mu+ mu-) ^(phi(1020) ->K+ K-)", + } + + #Load data from dst onto a TES (See Example7) + turbo_line = "Hlt2BsToJpsiPhi_JPsi2MuMu_PhiToKK_Line" + input_data = force_location(f"/Event/HLT2/{turbo_line}/Particles") + + #get kinematic functors + kin = Kinematics() + + ####### Mass constraint + #For DTFAlg, as with MC Truth algorithm (previous example), this algorithm builds a relation + # table i.e. one-to-one map b/w B candidate -> Refitted B candidate. + # The relation table is output to the TES location "DTF.OutputRelations" + # Note: the Jpsi constraint is applied but the phi constraint seems not to be applied (see issue: https://gitlab.cern.ch/lhcb/Rec/-/issues/309) + DTF = DTFAlg(MassConstraints=["J/psi(1S)"], Input=input_data) + + #Define a helper lambda function that takes variable name (k) prepends it with "DTF_" and functor (v) which is functor + DTFMAP = lambda func: F.MAP_INPUT(func, DTF.OutputRelations) + + #Loop over the functors in kinematics function and create a new functor collection + dtf_kin = FC( + {'DTF_' + k: DTFMAP(v) + for k, v in kin.get_thor_functors().items()}) + print(dtf_kin) + ######### + + ####### Mass constraint + primary vertex constraint + #Load PVs onto TES from data. Note here that we call "make_pvs()" to pass to DTF algorithm and "make_pvs_v2()" is passed to ThOr functors. + # The function "make_pvs_v2()" returns v2 vertices whereas "make_pvs()" returns v1 verticies. + # The PV constraint in the Decay tree fitter currently only works with v1 + # (see https://gitlab.cern.ch/lhcb/Rec/-/issues/318 and https://gitlab.cern.ch/lhcb/Rec/-/issues/309) + from DaVinci.reco_objects import make_pvs, make_pvs_v2 + pvs = make_pvs(process=options.process) + pvs_v2 = make_pvs_v2(process=options.process) + + #Add not only mass but also constrain Bs to be coming from primary vertex + DTFpv = DTFAlg( + InputPVs=pvs, + MassConstraints=["J/psi(1S)", "phi(1020)"], + Input=input_data) + + #Helper function for decay tree fitting with PV constaint. + # We make here a lambda function that takes as input a functor + # the lambda function loads this functor into MAP_INPUT functor + # which we encountered previously and returns it. + DTFPV_MAP = lambda func: F.MAP_INPUT(func, DTFpv.OutputRelations) + + #define the functors + pv_fun = {} + pv_fun['BPVLTIME'] = F.BPVLTIME(pvs_v2) + pv_fun['BPVIPCHI2'] = F.BPVIPCHI2(pvs_v2) + pv_coll = FC(pv_fun) + + #We now take the pre-defined functor collection ("pv_fun") and add same variables to it + # but using the result of the decay tree fit (DTF). These variables will have the prefix ("DTFPV_"). + # The resolution on the B candidate lifetime post-DTF ("DTFPV_BPVLTIME") + # should have improved compared to lifetime variable pre-DTF ("BPVLTIME"). + # Below we make use of the helper function ("DTFPV_MAP") defined previously. + pv_coll += FC({ + 'DTFPV_' + k: DTFPV_MAP(v) + for k, v in pv_coll.get_thor_functors().items() + }) + + #Define variables dictionary "field name" -> Collections of functor + variables = {"ALL": kin + dtf_kin, "Bs": pv_coll} + + #Add a filter (See Example7) + my_filter = add_filter(options, "HDRFilter_SeeNoEvil", + f"HLT_PASS('{turbo_line}')") + + #Define instance of FunTuple + mytuple = Funtuple( + "TDirectoryName", + "TTreeName", + fields=fields, + variables=variables, + inputs=input_data) + + config = make_config(options, [my_filter, mytuple]) + return config diff --git a/DaVinciTutorials/python/DaVinciTutorials/tutorial7_multiple_sel_lines.py b/DaVinciTutorials/python/DaVinciTutorials/tutorial7_multiple_sel_lines.py new file mode 100644 index 0000000000000000000000000000000000000000..82828ef074bb7b821ca8b394f23ecccfca5d8bed --- /dev/null +++ b/DaVinciTutorials/python/DaVinciTutorials/tutorial7_multiple_sel_lines.py @@ -0,0 +1,62 @@ +############################################################################### +# (c) Copyright 2021-2022 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the GNU General Public # +# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # +# # +# In applying this licence, CERN does not waive the privileges and immunities # +# granted to it by virtue of its status as an Intergovernmental Organization # +# or submit itself to any jurisdiction. # +############################################################################### +from DaVinci import make_config +from DaVinci.algorithms import add_filter +from FunTuple import FunTuple_Particles as Funtuple +from FunTuple.functorcollections import Kinematics +from PyConf.dataflow import force_location + + +def main(options): + #Define a dictionary of "field name" -> "decay descriptor component". + fields1 = { + "Bs": "B_s0 -> (J/psi(1S) -> mu+ mu-) (phi(1020) ->K+ K-)", + "mup": "B_s0 -> (J/psi(1S) -> ^mu+ mu-) (phi(1020) ->K+ K-)", + "mum": "B_s0 -> (J/psi(1S) -> mu+ ^mu-) (phi(1020) ->K+ K-)", + } + fields2 = { + "Bs": "B_s0 -> (J/psi(1S) -> e+ e-) (phi(1020) ->K+ K-)", + "ep": "B_s0 -> (J/psi(1S) -> ^e+ e-) (phi(1020) ->K+ K-)", + "em": "B_s0 -> (J/psi(1S) -> e+ ^e-) (phi(1020) ->K+ K-)" + } + + #Define variables dictionary "field name" -> Collections of functor + variables = {"ALL": Kinematics()} + + #Load data from dst onto a TES + turbo_line1 = "Hlt2BsToJpsiPhi_JPsi2MuMu_PhiToKK_Line" + input_data1 = force_location(f"/Event/HLT2/{turbo_line1}/Particles") + my_filter1 = add_filter(options, "HDRFilter_SeeNoEvil1", + f"HLT_PASS('{turbo_line1}')") + mytuple1 = Funtuple( + "TDirectoryName1", + "TTreeName1", + fields=fields1, + variables=variables, + inputs=input_data1) + + # If running over several sprucing lines (e.g. for calibration) one can define multiple instances of FunTuple + turbo_line2 = "Hlt2BsToJpsiPhi_JPsi2ee_PhiToKK_Line" + input_data2 = force_location(f"/Event/HLT2/{turbo_line2}/Particles") + my_filter2 = add_filter(options, "HDRFilter_SeeNoEvil2", + f"HLT_PASS('{turbo_line2}')") + mytuple2 = Funtuple( + "TDirectoryName2", + "TTreeName2", + fields=fields2, + variables=variables, + inputs=input_data2) + + user_algorithms = { + "Alg1": [my_filter1, mytuple1], + "Alg2": [my_filter2, mytuple2], + } + return make_config(options, user_algorithms) diff --git a/DaVinciTutorials/python/dataprops.yaml b/DaVinciTutorials/python/dataprops.yaml deleted file mode 100644 index 165ed2569c04e3f63ae27d46330201173e8b8302..0000000000000000000000000000000000000000 --- a/DaVinciTutorials/python/dataprops.yaml +++ /dev/null @@ -1,20 +0,0 @@ -############################################################################### -# (c) Copyright 2021-2022 CERN for the benefit of the LHCb Collaboration # -# # -# This software is distributed under the terms of the GNU General Public # -# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # -# # -# In applying this licence, CERN does not waive the privileges and immunities # -# granted to it by virtue of its status as an Intergovernmental Organization # -# or submit itself to any jurisdiction. # -############################################################################### - -bs2jpsiphi_turbo: - filenames: - - 'root://eoslhcb.cern.ch//eos/lhcb/wg/dpa/wp3/tests/hlt2_passthrough_thor_lines.dst' - qualifiers: - data_type: Upgrade - input_type: DST - simulation: true - conddb_tag: sim-20180530-vc-md100 - dddb_tag: dddb-20180815 \ No newline at end of file diff --git a/DaVinciTutorials/python/jobopts.yaml b/DaVinciTutorials/python/jobopts.yaml deleted file mode 100644 index 42ad169c257de68a8749ccbc3bf6acab960d2f16..0000000000000000000000000000000000000000 --- a/DaVinciTutorials/python/jobopts.yaml +++ /dev/null @@ -1,20 +0,0 @@ -############################################################################### -# (c) Copyright 2021-2022 CERN for the benefit of the LHCb Collaboration # -# # -# This software is distributed under the terms of the GNU General Public # -# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # -# # -# In applying this licence, CERN does not waive the privileges and immunities # -# granted to it by virtue of its status as an Intergovernmental Organization # -# or submit itself to any jurisdiction. # -############################################################################### - -# Template job option YAML file. -# Best guesses are provided below for various options. Please adapt as per your needs. - -annsvc_config: 'root://eoslhcb.cern.ch//eos/lhcb/wg/dpa/wp3/tests/hlt2_passthrough_thor_lines.tck.json' -evt_max: -1 -ntuple_file: 'ntuple_turbo.root' -enable_unpack: True -process: 'Turbo' -print_freq: 1 \ No newline at end of file diff --git a/DaVinciTutorials/python/tutorial0_basic_DVjob.py b/DaVinciTutorials/python/tutorial0_basic_DVjob.py deleted file mode 100644 index 9b2d5f08fd876470d8b32c1ac2e962b3ce1e0c76..0000000000000000000000000000000000000000 --- a/DaVinciTutorials/python/tutorial0_basic_DVjob.py +++ /dev/null @@ -1,60 +0,0 @@ -############################################################################### -# (c) Copyright 2021-2022 CERN for the benefit of the LHCb Collaboration # -# # -# This software is distributed under the terms of the GNU General Public # -# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # -# # -# In applying this licence, CERN does not waive the privileges and immunities # -# granted to it by virtue of its status as an Intergovernmental Organization # -# or submit itself to any jurisdiction. # -############################################################################### - -#### -# tutorial0_basic_DVjob: Running simple example of a DaVinci job. -# -# Run this with (assumes TUTORIALSPATH and DVPATH are already set, see README.md): -# - cd $TUTORIALSPATH -# - $DVPATH/run davinci run-mc -i bs2jpsiphi_turbo dataprops.yaml -j jobopts.yaml --user_algorithms tutorial0_basic_DVjob:main -##### - -from PyConf.Algorithms import PrintDecayTree -from PyConf.components import force_location -from DaVinci.algorithms import add_filter - -#Import davinci options and overwrite "ntuple_file" option in "jobopts.yaml" -from DaVinci import options -options.ntuple_file = '' #no tuple written out -options.evt_max = 100 - -#Load data from dst onto a "temporary" TES (Transient Event Store) location for a given event cycle. -# We loop over the algorithms event-by-event, so for given event cycle, TES maps "path" to an "object". -# For the TES path checkout spruce_passthrough.tck.json or you can do a dst dump -# (see https://lhcb.github.io/starterkit-lessons/first-analysis-steps/interactive-dst.html) -# -# The TES location input to the algorithms must of type "PyConf.DataHandle" and not pure strings. -# Therefore we wrap the TES location string below with "force_location" wrapper class. -turbo_line = "Hlt2BsToJpsiPhi_JPsi2MuMu_PhiToKK_Line" -input_data = force_location(f"/Event/HLT2/{turbo_line}/Particles") - -#Add a filter: We are not really filtering over particles, we are getting over a technical hurdle here. -# The hurdle being that if the event hasn't fired a HLT2 line then no TES location exists -# and therefore if any algorithm tries to look for this location, we run into a problem. -# Side step this issue with a filter, where: -# - 1st argument is a user defined name. -# - 2nd argument is the line decision (simply append "Decision" to your HLT2 line name (or inspect hlt2_starterkit.tck.json)) -my_filter = add_filter(options, "HDRFilter_SeeNoEvil", - f"HLT_PASS('{turbo_line}')") - -# Defining an algorithm. The alorithm here prints the decaytree -pdt = PrintDecayTree(name="PrintBsToJpsiPhi", Input=input_data) - - -def main(): - #Define tools (no tools used here) - tools = [] - - #Define dictionary of algorithms: "algorithm sequence name" -> list of algorithms run sequentially. By default an algorithm is only run if the previous in sequence finds something. - algs = {"Alg": [my_filter, pdt]} - - #Return them - return algs, tools diff --git a/DaVinciTutorials/python/tutorial1_functors_specialfield.py b/DaVinciTutorials/python/tutorial1_functors_specialfield.py deleted file mode 100644 index ce0bf1aa040b517a4f9660a3e19dba748de42a39..0000000000000000000000000000000000000000 --- a/DaVinciTutorials/python/tutorial1_functors_specialfield.py +++ /dev/null @@ -1,101 +0,0 @@ -############################################################################### -# (c) Copyright 2021-2022 CERN for the benefit of the LHCb Collaboration # -# # -# This software is distributed under the terms of the GNU General Public # -# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # -# # -# In applying this licence, CERN does not waive the privileges and immunities # -# granted to it by virtue of its status as an Intergovernmental Organization # -# or submit itself to any jurisdiction. # -############################################################################### - -##### -# tutorial1_functors_specialfield: Tupling with LoKi and ThOr functors -# -# Run this with (assumes TUTORIALSPATH and DVPATH are already set, see README.md): -# - cd $TUTORIALSPATH -# - $DVPATH/run davinci run-mc -i bs2jpsiphi_turbo dataprops.yaml -j jobopts.yaml --user_algorithms tutorial1_functors_specialfield:main -##### - -#Import necessary packages and functions -from FunTuple import FunTuple_Particles as Funtuple -from FunTuple import FunctorCollection as FC -import Functors as F -from DaVinci.algorithms import add_filter -from PyConf.application import force_location - -#Import davinci options and overwrite "ntuple_file" option in "jobopts.yaml" -from DaVinci import options -options.ntuple_file = 'tutorial1_functors_specialfield.root' -options.evt_max = 100 - -#Define a dictionary of "field name" -> "decay descriptor component". -# - For particle properties, names, etc checkout "ParticleTable.txt" -# that can be obtained via command "$DVPATH/run dump_ParticleProperties -t Upgrade | tee ParticleTable.txt". -# - For decay descriptor info see for example https://twiki.cern.ch/twiki/bin/view/LHCb/FAQ/LoKiNewDecayFinders -# If your decay is self-tagged (which is the most common case) then you will need "[<decay-descriptor>]CC" -fields = { - "Bs": "B_s0 -> (J/psi(1S) -> mu+ mu-) (phi(1020) ->K+ K-)", - "Jpsi": "B_s0 -> ^(J/psi(1S) -> mu+ mu-) (phi(1020) ->K+ K-)", - "Phi": "B_s0 -> (J/psi(1S) -> mu+ mu-) ^(phi(1020) ->K+ K-)", - "Mup": "B_s0 -> (J/psi(1S) ->^mu+ mu-) (phi(1020) ->K+ K-)", - "Mum": "B_s0 -> (J/psi(1S) -> mu+ ^mu-) (phi(1020) ->K+ K-)", - "Kp": "B_s0 -> (J/psi(1S) -> mu+ mu-) (phi(1020) ->^K+ K-)", - "Km": "B_s0 -> (J/psi(1S) -> mu+ mu-) (phi(1020) ->K+ ^K-)", -} - -#Define a collection of functors called FunctorCollection, which takes dictionary of "variable name" -> "ThOr" functor -# (Can also be a "LoKi" functor see next tutorial). -# For more info on ThOr see https://lhcbdoc.web.cern.ch/lhcbdoc/moore/master/selection/thor_functors.html#functor-cache -# For list of ThOr functors see https://lhcbdoc.web.cern.ch/lhcbdoc/moore/master/selection/thor_functors_reference.html -# Here we define functor collection to be added to "ALL" fields (Bs, Jpsi, Phi, etc) -all_vars = FC({ - "THOR_P": F.P, #ThOr momentum functor - "ID": F. - PARTICLE_ID, #Refer to "ParticleTable.txt" for particle ID (see above on how to get this file) -}) - -#define functors to be added only to Bs and Jpsi fields -bs_jpsi_fun = FC({"PT_THOR": F.PT, "PX": F.PX, "PY": F.PY}) - -#Define variables dictionary "field name" -> Collections of functor. -# "ALL" is a special field name that adds PT to all the fields defined above (i.e. Bs,Jpsi,Mup,Mum,Kp,Km) -variables = { - "ALL": all_vars, - "Bs": bs_jpsi_fun, - "Jpsi": bs_jpsi_fun, -} - -#Inspect string representation of ThOr Functor -# This string representation is converted to C++ object -# using gcc or FunctorCache see https://lhcbdoc.web.cern.ch/lhcbdoc/moore/master/selection/thor_functors.html#functors-in-a-selection-framework -print(F.PT.code()) -#print(F.PT.headers()) -print(F.PT.code_repr()) - -#Define the TES location (see previous example for explanation) -turbo_line = "Hlt2BsToJpsiPhi_JPsi2MuMu_PhiToKK_Line" -input_data = force_location(f"/Event/HLT2/{turbo_line}/Particles") - -#Define a filter (see previous example for explaination) -my_filter = add_filter(options, "HDRFilter_SeeNoEvil", - f"HLT_PASS('{turbo_line}')") - -#Define instance of FunTuple -mytuple = Funtuple( - "TDirectoryName", # name of directory in ROOT file - "TTreeName", # name of TTree - fields=fields, # dictionary of particle : decay descriptor - variables=variables, # dictionary of particle : variables to insert in TTree - inputs=input_data) # input data - - -def main(): - #Define tools (no tools used here) - tools = [] - - #Define dictionary of algorithms: "algorithm sequence name" -> list of algorithms run sequentially - algs = {"Alg": [my_filter, mytuple]} - - #Return them - return algs, tools diff --git a/DaVinciTutorials/python/tutorial2_LoKi.py b/DaVinciTutorials/python/tutorial2_LoKi.py deleted file mode 100644 index 8adcbafa78a45f042bd4a2b9e8d2a9c4b036837b..0000000000000000000000000000000000000000 --- a/DaVinciTutorials/python/tutorial2_LoKi.py +++ /dev/null @@ -1,102 +0,0 @@ -############################################################################### -# (c) Copyright 2021-2022 CERN for the benefit of the LHCb Collaboration # -# # -# This software is distributed under the terms of the GNU General Public # -# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # -# # -# In applying this licence, CERN does not waive the privileges and immunities # -# granted to it by virtue of its status as an Intergovernmental Organization # -# or submit itself to any jurisdiction. # -############################################################################### - -##### -# tutorial2_LoKi: Usage of LoKi functors together with ThOr -# -# Run this with (assumes TUTORIALSPATH and DVPATH are already set, see README.md): -# - cd $TUTORIALSPATH -# - $DVPATH/run davinci run-mc -i bs2jpsiphi_turbo dataprops.yaml -j jobopts.yaml --user_algorithms tutorial2_LoKi:main -##### - -from FunTuple import FunTuple_Particles as Funtuple -from FunTuple import FunctorCollection as FC -import Functors as F -from DaVinci.algorithms import add_filter -from PyConf.application import force_location - -#Import davinci options and overwrite "ntuple_file" option in "jobopts.yaml" -from DaVinci import options -options.ntuple_file = 'tutorial2_LoKi.root' -options.evt_max = 100 - -#Define a dictionary of "field name" -> "decay descriptor component". -fields = { - "Bs": "B_s0 -> (J/psi(1S) -> mu+ mu-) (phi(1020) ->K+ K-)", - "Jpsi": "B_s0 -> ^(J/psi(1S) -> mu+ mu-) (phi(1020) ->K+ K-)", - "Phi": "B_s0 -> (J/psi(1S) -> mu+ mu-) ^(phi(1020) ->K+ K-)", - "Mup": "B_s0 -> (J/psi(1S) ->^mu+ mu-) (phi(1020) ->K+ K-)", - "Mum": "B_s0 -> (J/psi(1S) -> mu+ ^mu-) (phi(1020) ->K+ K-)", - "Kp": "B_s0 -> (J/psi(1S) -> mu+ mu-) (phi(1020) ->^K+ K-)", - "Km": "B_s0 -> (J/psi(1S) -> mu+ mu-) (phi(1020) ->K+ ^K-)", -} - -#Define a collection of functors called FunctorCollection, which takes dictionary of "variable name" -> "LoKi" or "ThOr" functor -# For more info on ThOr see https://lhcbdoc.web.cern.ch/lhcbdoc/moore/master/selection/thor_functors.html#functor-cache -# For list of ThOr functors see https://lhcbdoc.web.cern.ch/lhcbdoc/moore/master/selection/thor_functors_reference.html -# For information on LoKi functor see https://lhcb.github.io/starterkit-lessons/first-analysis-steps/loki-functors.html -mom_fun = FC({ - "THOR_PT": F.PT, - "THOR_PX": F.PX, - "THOR_PY": F.PY, - "LOKI_PT": 'PT', #LoKi functor code is represented in a string - "LOKI_PX": 'PX', - "LOKI_PY": 'PY' -}) - -#Define a LoKi preamble (Note that one can define preambles in ThOr using python lambda function see next tutorial or via FunctorComposition) -# i.e. rename a complex LoKi functor to a user deinfed name (e.g. TRACK_MAX_PT) -# This helps us to use "TRACK_MAX_PT" when constructing FunctorCollection -loki_preamble = ['TRACK_MAX_PT = MAXTREE(ISBASIC & HASTRACK, PT, -1)'] - -#define collections to be added to fields -max_pt_fun = FC({ - "MAX_PT_LOKI": "TRACK_MAX_PT", #LoKi - "MAX_PT_THOR": F.MAX( - F.PT - ) #ThOr (not equivalent, sum of pT of composites not basic). MAXTREE ThOr doesn't exist yet. -}) - -#Define variables dictionary "field name" -> Collections of functor. -variables = { - "ALL": mom_fun, - "Bs": max_pt_fun, - "Jpsi": max_pt_fun, - "Phi": max_pt_fun, -} - -#Load data from dst onto a TES -turbo_line = "Hlt2BsToJpsiPhi_JPsi2MuMu_PhiToKK_Line" -input_data = force_location(f"/Event/HLT2/{turbo_line}/Particles") - -#Add a filter -my_filter = add_filter(options, "HDRFilter_SeeNoEvil", - f"HLT_PASS('{turbo_line}')") - -#Define instance of FunTuple -mytuple = Funtuple( - "TDirectoryName", - "TTreeName", - fields=fields, - variables=variables, - loki_preamble=loki_preamble, #optional argument - inputs=input_data) - - -def main(): - #Define tools (no tools used here) - tools = [] - - #Define dictionary of algorithms: "algorithm sequence name" -> list of algorithms run sequentially - algs = {"Alg": [my_filter, mytuple]} - - #Return them - return algs, tools diff --git a/DaVinciTutorials/python/tutorial3_ThOrfunctors.py b/DaVinciTutorials/python/tutorial3_ThOrfunctors.py deleted file mode 100644 index 57493831e4b42123033292f1aaffafd2f108554c..0000000000000000000000000000000000000000 --- a/DaVinciTutorials/python/tutorial3_ThOrfunctors.py +++ /dev/null @@ -1,126 +0,0 @@ -############################################################################### -# (c) Copyright 2021-2022 CERN for the benefit of the LHCb Collaboration # -# # -# This software is distributed under the terms of the GNU General Public # -# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # -# # -# In applying this licence, CERN does not waive the privileges and immunities # -# granted to it by virtue of its status as an Intergovernmental Organization # -# or submit itself to any jurisdiction. # -############################################################################### - -##### -# tutorial3_ThOrfunctors: Usange of data dependent ThOr functors, arguments to ThOr functors and vector functors -# -# Run this with (assumes TUTORIALSPATH and DVPATH are already set, see README.md): -# - cd $TUTORIALSPATH -# - $DVPATH/run davinci run-mc -i bs2jpsiphi_turbo dataprops.yaml -j jobopts.yaml --user_algorithms tutorial3_ThOrfunctors:main -##### - -from FunTuple import FunTuple_Particles as Funtuple -from FunTuple import FunctorCollection as FC -import Functors as F -from DaVinci.algorithms import add_filter -from PyConf.application import force_location -from DaVinci.reco_objects import make_pvs_v2 - -#Import davinci options and overwrite "ntuple_file" option in "jobopts.yaml" -from DaVinci import options -options.ntuple_file = 'tutorial3_ThOrfunctors.root' -options.evt_max = 100 - -#Define a dictionary of "field name" -> "decay descriptor component". -# Can get daughter information from the head of the decay using F.CHILD functors see below. -fields = { - "Bs": "B_s0 -> (J/psi(1S) -> mu+ mu-) (phi(1020) ->K+ K-)", - "Phi": "B_s0 -> (J/psi(1S) -> mu+ mu-) ^(phi(1020) ->K+ K-)", - "Kp": "B_s0 -> (J/psi(1S) -> mu+ mu-) (phi(1020) ->^K+ K-)", - "Km": "B_s0 -> (J/psi(1S) -> mu+ mu-) (phi(1020) ->K+ ^K-)", -} - -#Load PVs onto TES from data, like we did with input_data below -# Creating v2 reconstructed vertices to be used in the following functor -# For the time being there's a mix of legacy and v2 event classes. That will eventually be cleaned once the -# event model is fixed. In the meantime there are helper functions in DaVinci. -pvs = make_pvs_v2(process=options.process) - -#Evaluate the impact parameter -all_vars = {} -#The ThOr functor F.BPVIPCHI2 is data dependent. It takes as input list of pvs. -#It calculates impact parameter chisq wrt best PV. -# - best PV is the PV which fits best the FD of the B candidate. -# - impact parameter chisq is the difference in the vertex-fit chisq of a given PV reconstructed with and w/o the track under consideration. -all_vars['BPVIPCHI2'] = F.BPVIPCHI2(pvs) - -#define dictionary -bs_vars = {} - -#Tupling vector functors -# Some functors could also return std::map<std::string, std::any> (e.g. F.DECISIONS(Lines=line_names, DecReports=dec_report)) -bs_vars['BPVFDVEC_'] = F.BPVFDVEC(pvs) #Returns 3-vector -bs_vars['FOURMOM_P'] = F.FOURMOMENTUM #Returns 4-vector - -#define some helpful lambda function to simplify syntax -# This is bit like LoKi preamble of renaming functors that we encountred in previous tutorial. -CHILD_1 = lambda func: F.CHILD(1, func) -CHILD_2 = lambda func: F.CHILD(2, func) -SUBCOMB_12 = lambda func: F.SUBCOMB(Functor=func, Indices=(1, 2)) - -#Store the ID of the two daughters of B_s0 -bs_vars['jpsi_ID'] = CHILD_1(F.PARTICLE_ID) -bs_vars['phi_ID'] = CHILD_2(F.PARTICLE_ID) -bs_vars['Kp_ID'] = CHILD_2(CHILD_1(F.PARTICLE_ID)) - -#Calculate sum of pT of jpsi daughter tracks -bs_vars['jpsi_TRACKSUMPT'] = CHILD_1(F.SUM(F.PT)) - -#Calculate impact parameter of K+ -bs_vars['Kp_BPVIP'] = CHILD_2(CHILD_1(F.BPVIP(pvs))) - -#Calculate invariant mass of K+ and K- combination -bs_vars['phi_M_comb'] = CHILD_2(SUBCOMB_12(F.MASS)) - -#Calculate the difference in end vertex between phi and Bs -bs_vars['Delta_END_VZ_PhiBs0'] = CHILD_2(F.END_VZ) - F.END_VZ - -#Calculate inv mass of K+pi- where the K- is given the mass hypothesis of pi- -bs_vars['phi_mass_kpi'] = CHILD_2(F.MASSWITHHYPOTHESES(('K+', 'pi-'))) - -#Calculate inv mass of K+K- -# There three functors for computing this i.e. F.MASS, CHILD_2(SUBCOMB_12(F.MASS)) and CHILD_2(F.MASSWITHHYPOTHESES(('K+', 'K-'))) but why? -# (see issue: https://gitlab.cern.ch/lhcb/Rec/-/issues/307) -bs_vars['phi_mass_kk'] = CHILD_2(F.MASSWITHHYPOTHESES(('K+', 'K-'))) -all_vars['M'] = F.MASS - -#Define variables dictionary "field name" -> Collections of functor -variables = { - "ALL": FC(all_vars), - "Bs": FC(bs_vars), -} - -#Load data from dst onto a TES -turbo_line = "Hlt2BsToJpsiPhi_JPsi2MuMu_PhiToKK_Line" -input_data = force_location(f"/Event/HLT2/{turbo_line}/Particles") - -#Add a filter -my_filter = add_filter(options, "HDRFilter_SeeNoEvil", - f"HLT_PASS('{turbo_line}')") - -#Define instance of FunTuple -mytuple = Funtuple( - "TDirectoryName", - "TTreeName", - fields=fields, - variables=variables, - inputs=input_data) - - -def main(): - #Define tools (no tools used here) - tools = [] - - #Define dictionary of algorithms: "algorithm sequence name" -> list of algorithms run sequentially - algs = {"Alg": [my_filter, mytuple]} - - #Return them - return algs, tools diff --git a/DaVinciTutorials/python/tutorial4_trigger_eventinfo.py b/DaVinciTutorials/python/tutorial4_trigger_eventinfo.py deleted file mode 100644 index 44b2c01eae1f8e8d773888e3865a47ae63c9f989..0000000000000000000000000000000000000000 --- a/DaVinciTutorials/python/tutorial4_trigger_eventinfo.py +++ /dev/null @@ -1,128 +0,0 @@ -############################################################################### -# (c) Copyright 2021-2022 CERN for the benefit of the LHCb Collaboration # -# # -# This software is distributed under the terms of the GNU General Public # -# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # -# # -# In applying this licence, CERN does not waive the privileges and immunities # -# granted to it by virtue of its status as an Intergovernmental Organization # -# or submit itself to any jurisdiction. # -############################################################################### - -##### -# tutorial4_trigger_eventinfo: Usage of pre-defined FunctorCollection, storing trigger and event level information -# -# Run this with (assumes TUTORIALSPATH and DVPATH are already set, see README.md): -# - cd $TUTORIALSPATH -# - $DVPATH/run davinci run-mc -i bs2jpsiphi_turbo dataprops.yaml -j jobopts.yaml --user_algorithms tutorial4_trigger_eventinfo:main -##### - -from FunTuple import FunTuple_Particles as Funtuple -from FunTuple import FunctorCollection as FC -import Functors as F -from DaVinci.algorithms import add_filter -from PyConf.application import force_location - -#Import davinci options and overwrite "ntuple_file" option in "jobopts.yaml" -from DaVinci import options -options.ntuple_file = 'tutorial4_trigger_eventinfo.root' -options.evt_max = 100 - -#Define a dictionary of "field name" -> "decay descriptor component". -fields = {"Bs": "B_s0 -> (J/psi(1S) -> mu+ mu-) (phi(1020) ->K+ K-)"} - -#To help users, there are pre-defined FunctorCollections (Tuple-tool like objects for Run1/2 veterans) that you can import and inspect. -# Here we import a pre-defined FunctorCollection "Kinematics". -# One can call "print(help(Kinematics))" (you have to press "q" to exit after calling) to check the usage and their arguments. -# Functors that have data dependency will naturally induce data dependency on the functorcollections. -# -# To see what functor collections are available see: https://gitlab.cern.ch/lhcb/Analysis/-/blob/master/Phys/FunTuple/python/FunTuple/functorcollections.py -from FunTuple.functorcollections import Kinematics - -#Inspect whats in the collection by printing -kin = Kinematics() -print(kin) - -#Define new collection -coll = FC({"ID": F.PARTICLE_ID}) - -#Add to existing collections (can also subtract two collections) -kin += coll - -#Remove from collections -kin.pop(['PX', 'PT', 'PZ', 'PY', 'ENERGY']) -print(kin) - -#Can also obtain a pure dictionary from collections via -# - kin.functor_dict (Contains both LoKi and ThOr) -# - kin.get_thor_functors() -# - kin.get_loki_functors() -print(kin.functor_dict) -print(kin.get_thor_functors()) -print(kin.get_loki_functors() - ) #empty dictionary since we have no LoKi functors in the collection - -#Now import two other pre-defined FunctorCollections: SelectionInfo and EventInfo -# - SelectionInfo: Contains functors related to storing Hlt1, Hlt2 or Sprucing trigger line decision and Trigger Configuration Key (TCK). -# - EventInfo: Contains functors related to storing event information EVENTNUMBER, RUNNUMBER, GPSTIME, etc. -# -#As before you can call help with "print(help(EventInfo))" or "print(help(SelectionInfo))" (you have to press "q" to exit after calling) -from FunTuple.functorcollections import SelectionInfo, EventInfo - -#Get event information like RUNNUMBER, EVENTNUMBER. -# These are stored in "LHCb::ODIN" C++ object which the ThOr functors take as input (like PVs in Example7), load it onto TES using "get_odin". -# The attribute extra_info is False by default, if set to "True" you get info on -# bunchcrossing id, ODIN TCK, GPS Time, etc -from DaVinci.algorithms import get_odin -odin = get_odin(options) -evtinfo = EventInfo(odin, extra_info=False) -print(evtinfo) - -#Get selection line decision and HlT2 TCK. -# These decisions are stored in "LHCb::HltDecReports" object, which the ThOr functors take as input (like PVs in Example7), load it onto TES using "get_decreports". -# The function "get_decreports" takes as input: -# - sel_type: Type of selection "Hlt2" or "Spruce" -# - line_names: list of line decision in this instance HLT2 line. Should return True for all since we are using the output of this line. -# -# The `Hlt1` decisions can be stored in similar way to `Hlt2` and `Spruce` -# (see example `option_trigger_decisions` in `DaVinciExamples` folder). -# For details, can also refer to the [talk](https://indico.cern.ch/event/1164051/#5-accessing-hlt1-decisions-usi) -# (The talk mentions that to persist Hlt1 decisions, one needs to add few options to the Moore script). -from DaVinci.algorithms import get_decreports -sel_type = "Hlt2" #User defined and will be used as prefix for TBranch in the root file -dec_report = get_decreports(sel_type, options) -turbo_line = "Hlt2BsToJpsiPhi_JPsi2MuMu_PhiToKK_Line" -turbo_line2 = "Hlt2BsToJpsiPhi_JPsi2ee_PhiToKK_Line" -line_names = [f'{turbo_line}Decision', f'{turbo_line2}'] -selinfo = SelectionInfo(sel_type, dec_report, line_names) -print(selinfo) - -#Define variables dictionary "field name" -> Collections of functor -variables = {"ALL": kin} - -#Load data from dst onto a TES -input_data = force_location(f"/Event/HLT2/{turbo_line}/Particles") - -#Add a filter -my_filter = add_filter(options, "HDRFilter_SeeNoEvil", - f"HLT_PASS('{turbo_line}')") - -#Define instance of FunTuple -mytuple = Funtuple( - "TDirectoryName", - "TTreeName", - fields=fields, - variables=variables, - event_variables=evtinfo + selinfo, - inputs=input_data) - - -def main(): - #Define tools (no tools used here) - tools = [] - - #Define dictionary of algorithms: "algorithm sequence name" -> list of algorithms run sequentially - algs = {"Alg": [my_filter, mytuple]} - - #Return them - return algs, tools diff --git a/DaVinciTutorials/python/tutorial5_MCTruth.py b/DaVinciTutorials/python/tutorial5_MCTruth.py deleted file mode 100644 index 00f72146d5092f3e21966d6b72bec23df1f7dc5b..0000000000000000000000000000000000000000 --- a/DaVinciTutorials/python/tutorial5_MCTruth.py +++ /dev/null @@ -1,121 +0,0 @@ -############################################################################### -# (c) Copyright 2021-2022 CERN for the benefit of the LHCb Collaboration # -# # -# This software is distributed under the terms of the GNU General Public # -# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # -# # -# In applying this licence, CERN does not waive the privileges and immunities # -# granted to it by virtue of its status as an Intergovernmental Organization # -# or submit itself to any jurisdiction. # -############################################################################### - -##### -# tutorial5_MCTruth: MC truth association example -# -# Run this with (assumes TUTORIALSPATH and DVPATH are already set, see README.md): -# - cd $TUTORIALSPATH -# - $DVPATH/run davinci run-mc -i bs2jpsiphi_turbo dataprops.yaml -j jobopts.yaml --user_algorithms tutorial5_MCTruth:main -##### - -from FunTuple import FunTuple_Particles as Funtuple -from FunTuple import FunctorCollection as FC -import Functors as F -from DaVinci.algorithms import add_filter -from PyConf.application import force_location - -#Import davinci options and overwrite "ntuple_file" option in "jobopts.yaml" -from DaVinci import options -options.ntuple_file = 'tutorial5_MCTruth.root' -options.evt_max = 100 - -#Define a dictionary of "field name" -> "decay descriptor component". -fields = { - "Bs": "B_s0 -> (J/psi(1S) -> mu+ mu-) (phi(1020) ->K+ K-)", - "Jpsi": "B_s0 ->^(J/psi(1S) -> mu+ mu-) (phi(1020) ->K+ K-)", - "Phi": "B_s0 -> (J/psi(1S) -> mu+ mu-) ^(phi(1020) ->K+ K-)", - "Mup": "B_s0 -> (J/psi(1S) ->^mu+ mu-) (phi(1020) ->K+ K-)", - "Mum": "B_s0 -> (J/psi(1S) -> mu+ ^mu-) (phi(1020) ->K+ K-)", - "Kp": "B_s0 -> (J/psi(1S) -> mu+ mu-) (phi(1020) ->^K+ K-)", - "Km": "B_s0 -> (J/psi(1S) -> mu+ mu-) (phi(1020) ->K+ ^K-)", -} - -#Import FunctorCollections Kinematics, MCKinematics, MCHierarchy -# There is also "MCVertexInfo" but we won't import it here. -# -# See whats available at: https://gitlab.cern.ch/lhcb/Analysis/-/blob/master/Phys/FunTuple/python/FunTuple/functorcollections.py -from FunTuple.functorcollections import Kinematics, MCKinematics, MCHierarchy - -#We can seek help on these functorcollections using following commands (if you run these commmands, press "q" to exit and continue). -# - print(help(MCKinematics)) -# - print(help(MCHierarchy)) -# -# We see that it takes an input an algorithm configured_MCTruthAndBkgCatAlg(inputdata), so lets import that. -from DaVinci.truth_matching import configured_MCTruthAndBkgCatAlg - -#Load data from dst onto a TES -turbo_line = "Hlt2BsToJpsiPhi_JPsi2MuMu_PhiToKK_Line" -input_data = force_location(f"/Event/HLT2/{turbo_line}/Particles") -#Define an algorithm that builds a map i.e. one-to-one relation b/w Reco Particle -> Truth MC Particle. -mctruth = configured_MCTruthAndBkgCatAlg(inputs=input_data) -print(mctruth.MCAssocTable) - -#Pass it to collections -kin = Kinematics() -mckin = MCKinematics(mctruth) -mchierarchy = MCHierarchy(mctruth) -print(mckin) -print(mchierarchy) - -#Loop over and keep only whats required -kin = FC( - {k: v - for k, v in kin.get_thor_functors().items() if k == 'P' or k == 'M'}) -mckin = FC( - {k: v - for k, v in mckin.get_thor_functors().items() if k == 'TRUEP'}) -mchierarchy = FC({ - k: v - for k, v in mchierarchy.get_thor_functors().items() if k == 'TRUEID' -}) -print(kin) -print(mckin) -print(mchierarchy) - -#To get truth information with a functor that is not present in the collections -# - The 1st argument is the functor that returns the relevant information -# - The 2nd argument is relation table i.e. a one-to-one map b/w Reco Particle -> Truth MC Particle. -extra_info = { - "TRUEEID": F.MAP_INPUT(F.PARTICLE_ID, mctruth.MCAssocTable), - "TRUEEPHI": F.MAP_INPUT(F.PHI, mctruth.MCAssocTable) -} -extra_info = FC(extra_info) - -#The algorithm mctruth also outputs a map b/w particle and bkg category which can be obtained using the functor -# For more info on background category see: https://twiki.cern.ch/twiki/bin/view/LHCb/TupleToolMCBackgroundInfo -bkg_cat = FC({"BKGCAT": F.BKGCAT(Relations=mctruth.BkgCatTable)}) - -#Define variables dictionary "field name" -> Collections of functor -variables = {"ALL": kin + mckin + mchierarchy + bkg_cat, "Kp": extra_info} - -#Add a filter -my_filter = add_filter(options, "HDRFilter_SeeNoEvil", - f"HLT_PASS('{turbo_line}')") - -#Define instance of FunTuple -mytuple = Funtuple( - "TDirectoryName", - "TTreeName", - fields=fields, - variables=variables, - inputs=input_data) - - -def main(): - #Define tools (no tools used here) - tools = [] - - #Define dictionary of algorithms: "algorithm sequence name" -> list of algorithms run sequentially - algs = {"Alg": [my_filter, mytuple]} - - #Return them - return algs, tools diff --git a/DaVinciTutorials/python/tutorial6_DecayTreeFit.py b/DaVinciTutorials/python/tutorial6_DecayTreeFit.py deleted file mode 100644 index ccad8ab5525f89adaa4e25006df9477fd9a96255..0000000000000000000000000000000000000000 --- a/DaVinciTutorials/python/tutorial6_DecayTreeFit.py +++ /dev/null @@ -1,129 +0,0 @@ -############################################################################### -# (c) Copyright 2021-2022 CERN for the benefit of the LHCb Collaboration # -# # -# This software is distributed under the terms of the GNU General Public # -# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # -# # -# In applying this licence, CERN does not waive the privileges and immunities # -# granted to it by virtue of its status as an Intergovernmental Organization # -# or submit itself to any jurisdiction. # -############################################################################### - -##### -# tutorial6_DecayTreeFit: Decay Tree Fitting -# -# Run this with (assumes TUTORIALSPATH and DVPATH are already set, see README.md): -# - cd $TUTORIALSPATH -# - $DVPATH/run davinci run-mc -i bs2jpsiphi_turbo dataprops.yaml -j jobopts.yaml --user_algorithms tutorial6_DecayTreeFit:main -##### - -from FunTuple import FunTuple_Particles as Funtuple -from FunTuple import FunctorCollection as FC -import Functors as F -from DaVinci.algorithms import add_filter -from PyConf.application import force_location -from FunTuple.functorcollections import Kinematics - -#Import DecayTreeFitter algorithm -# For more information of DTF see -# - https://inspirehep.net/literature/679286 -# - https://twiki.cern.ch/twiki/bin/view/LHCb/DecayTreeFitter -# - https://www.nikhef.nl/~wouterh/topicallectures/TrackingAndVertexing/part6.pdf -from DecayTreeFitter import DTFAlg - -#Import davinci options and overwrite "ntuple_file" option in "jobopts.yaml" -from DaVinci import options -options.ntuple_file = 'tutorial6_DecayTreeFit.root' -options.evt_max = 100 - -#Define a dictionary of "field name" -> "decay descriptor component". -fields = { - "Bs": "B_s0 -> (J/psi(1S) -> mu+ mu-) (phi(1020) ->K+ K-)", - "Jpsi": "B_s0 ->^(J/psi(1S) -> mu+ mu-) (phi(1020) ->K+ K-)", - "Phi": "B_s0 -> (J/psi(1S) -> mu+ mu-) ^(phi(1020) ->K+ K-)", -} - -#Load data from dst onto a TES (See Example7) -turbo_line = "Hlt2BsToJpsiPhi_JPsi2MuMu_PhiToKK_Line" -input_data = force_location(f"/Event/HLT2/{turbo_line}/Particles") - -#get kinematic functors -kin = Kinematics() - -####### Mass constraint -#For DTFAlg, as with MC Truth algorithm (previous example), this algorithm builds a relation -# table i.e. one-to-one map b/w B candidate -> Refitted B candidate. -# The relation table is output to the TES location "DTF.OutputRelations" -# Note: the Jpsi constraint is applied but the phi constraint seems not to be applied (see issue: https://gitlab.cern.ch/lhcb/Rec/-/issues/309) -DTF = DTFAlg(MassConstraints=["J/psi(1S)"], Input=input_data) - -#Define a helper lambda function that takes variable name (k) prepends it with "DTF_" and functor (v) which is functor -DTFMAP = lambda func: F.MAP_INPUT(func, DTF.OutputRelations) - -#Loop over the functors in kinematics function and create a new functor collection -dtf_kin = FC( - {'DTF_' + k: DTFMAP(v) - for k, v in kin.get_thor_functors().items()}) -print(dtf_kin) -######### - -####### Mass constraint + primary vertex constraint -#Load PVs onto TES from data. Note here that we call "make_pvs()" to pass to DTF algorithm and "make_pvs_v2()" is passed to ThOr functors. -# The function "make_pvs_v2()" returns v2 vertices whereas "make_pvs()" returns v1 verticies. -# The PV constraint in the Decay tree fitter currently only works with v1 -# (see https://gitlab.cern.ch/lhcb/Rec/-/issues/318 and https://gitlab.cern.ch/lhcb/Rec/-/issues/309) -from DaVinci.reco_objects import make_pvs, make_pvs_v2 -pvs = make_pvs(process=options.process) -pvs_v2 = make_pvs_v2(process=options.process) - -#Add not only mass but also constrain Bs to be coming from primary vertex -DTFpv = DTFAlg( - InputPVs=pvs, MassConstraints=["J/psi(1S)", "phi(1020)"], Input=input_data) - -#Helper function for decay tree fitting with PV constaint. -# We make here a lambda function that takes as input a functor -# the lambda function loads this functor into MAP_INPUT functor -# which we encountered previously and returns it. -DTFPV_MAP = lambda func: F.MAP_INPUT(func, DTFpv.OutputRelations) - -#define the functors -pv_fun = {} -pv_fun['BPVLTIME'] = F.BPVLTIME(pvs_v2) -pv_fun['BPVIPCHI2'] = F.BPVIPCHI2(pvs_v2) -pv_coll = FC(pv_fun) - -#We now take the pre-defined functor collection ("pv_fun") and add same variables to it -# but using the result of the decay tree fit (DTF). These variables will have the prefix ("DTFPV_"). -# The resolution on the B candidate lifetime post-DTF ("DTFPV_BPVLTIME") -# should have improved compared to lifetime variable pre-DTF ("BPVLTIME"). -# Below we make use of the helper function ("DTFPV_MAP") defined previously. -pv_coll += FC({ - 'DTFPV_' + k: DTFPV_MAP(v) - for k, v in pv_coll.get_thor_functors().items() -}) - -#Define variables dictionary "field name" -> Collections of functor -variables = {"ALL": kin + dtf_kin, "Bs": pv_coll} - -#Add a filter (See Example7) -my_filter = add_filter(options, "HDRFilter_SeeNoEvil", - f"HLT_PASS('{turbo_line}')") - -#Define instance of FunTuple -mytuple = Funtuple( - "TDirectoryName", - "TTreeName", - fields=fields, - variables=variables, - inputs=input_data) - - -def main(): - #Define tools (no tools used here) - tools = [] - - #Define dictionary of algorithms: "algorithm sequence name" -> list of algorithms run sequentially - algs = {"Alg": [my_filter, mytuple]} - - #Return them - return algs, tools diff --git a/DaVinciTutorials/python/tutorial7_multiple_sel_lines.py b/DaVinciTutorials/python/tutorial7_multiple_sel_lines.py deleted file mode 100644 index 8e40e91afa16c5bee93562f735703f78bd65c56c..0000000000000000000000000000000000000000 --- a/DaVinciTutorials/python/tutorial7_multiple_sel_lines.py +++ /dev/null @@ -1,80 +0,0 @@ -############################################################################### -# (c) Copyright 2021-2022 CERN for the benefit of the LHCb Collaboration # -# # -# This software is distributed under the terms of the GNU General Public # -# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # -# # -# In applying this licence, CERN does not waive the privileges and immunities # -# granted to it by virtue of its status as an Intergovernmental Organization # -# or submit itself to any jurisdiction. # -############################################################################### - -##### -# tutorial7_multiple_sel_lines: Multiple instances of FunTuple algorithms when running over -# ouput of two selection (Sprucing or Hlt2) lines with Bs decays -# -# Run this with (assumes TUTORIALSPATH and DVPATH are already set, see README.md): -# - cd $TUTORIALSPATH -# - $DVPATH/run davinci run-mc -i bs2jpsiphi_turbo dataprops.yaml -j jobopts.yaml --user_algorithms tutorial7_multiple_sel_lines:main -##### - -from FunTuple import FunTuple_Particles as Funtuple -from DaVinci.algorithms import add_filter -from PyConf.application import force_location -from FunTuple.functorcollections import Kinematics - -#Import davinci options and overwrite "ntuple_file" option in "jobopts.yaml" -from DaVinci import options -options.ntuple_file = 'tutorial7_multiple_sel_lines.root' -options.evt_max = 100 - -#Example1_tafa -#Define a dictionary of "field name" -> "decay descriptor component". -fields1 = { - "Bs": "B_s0 -> (J/psi(1S) -> mu+ mu-) (phi(1020) ->K+ K-)", - "mup": "B_s0 -> (J/psi(1S) -> ^mu+ mu-) (phi(1020) ->K+ K-)", - "mum": "B_s0 -> (J/psi(1S) -> mu+ ^mu-) (phi(1020) ->K+ K-)", -} -fields2 = { - "Bs": "B_s0 -> (J/psi(1S) -> e+ e-) (phi(1020) ->K+ K-)", - "ep": "B_s0 -> (J/psi(1S) -> ^e+ e-) (phi(1020) ->K+ K-)", - "em": "B_s0 -> (J/psi(1S) -> e+ ^e-) (phi(1020) ->K+ K-)" -} - -#Define variables dictionary "field name" -> Collections of functor -variables = {"ALL": Kinematics()} - -#Load data from dst onto a TES -turbo_line1 = "Hlt2BsToJpsiPhi_JPsi2MuMu_PhiToKK_Line" -input_data1 = force_location(f"/Event/HLT2/{turbo_line1}/Particles") -my_filter1 = add_filter(options, "HDRFilter_SeeNoEvil1", - f"HLT_PASS('{turbo_line1}')") -mytuple1 = Funtuple( - "TDirectoryName1", - "TTreeName1", - fields=fields1, - variables=variables, - inputs=input_data1) - -# If running over several sprucing lines (e.g. for calibration) one can define multiple instances of FunTuple -turbo_line2 = "Hlt2BsToJpsiPhi_JPsi2ee_PhiToKK_Line" -input_data2 = force_location(f"/Event/HLT2/{turbo_line2}/Particles") -my_filter2 = add_filter(options, "HDRFilter_SeeNoEvil2", - f"HLT_PASS('{turbo_line2}')") -mytuple2 = Funtuple( - "TDirectoryName2", - "TTreeName2", - fields=fields2, - variables=variables, - inputs=input_data2) - - -def main(): - #Define tools (no tools used here) - tools = [] - - #Define dictionary of algorithms: "algorithm sequence name" -> list of algorithms run sequentially - algs = {"Alg1": [my_filter1, mytuple1], "Alg2": [my_filter2, mytuple2]} - - #Return them - return algs, tools diff --git a/DaVinciTutorials/tests/qmtest/test_tutorial0_basic_DVjob.qmt b/DaVinciTutorials/tests/qmtest/test_tutorial0_basic_DVjob.qmt index 9b2d9f3f2ac01d48a41c6a4d29599180f2c62b58..a6815d045396f1a62aff2eedbb26de847449c7ee 100644 --- a/DaVinciTutorials/tests/qmtest/test_tutorial0_basic_DVjob.qmt +++ b/DaVinciTutorials/tests/qmtest/test_tutorial0_basic_DVjob.qmt @@ -12,28 +12,15 @@ ############################################################################### --> <!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<!-- -####################################################### -# SUMMARY OF THIS TEST -# ................... -# Author: Abhijit Mathad -# Purpose: Test tutorial0_basic_DVjob of DV Tutorial -# Prerequisites: None -# inputfiledb bs2jpsiphi_turbo $DAVINCITUTORIALSROOT/python/dataprops.yaml -# joboptfile $DAVINCITUTORIALSROOT/python/jobopts.yaml -# user_algorithms $DAVINCITUTORIALSROOT/python/tutorial0_basic_DVjob:main -####################################################### ---> <extension class="GaudiTest.GaudiExeTest" kind="test"> - <argument name="program"><text>davinci</text></argument> + <argument name="program"><text>lbexec</text></argument> + <argument name="options_yaml_fn"><text>$DAVINCITUTORIALSROOT/options.yaml</text></argument> + <argument name="extra_options_yaml"><text> + ntuple_file: null + </text></argument> + <argument name="timeout"><integer>3600</integer></argument> <argument name="args"><set> - <text>--inputfiledb</text> - <text>bs2jpsiphi_turbo</text> - <text>$DAVINCITUTORIALSROOT/python/dataprops.yaml</text> - <text>--joboptfile</text> - <text>$DAVINCITUTORIALSROOT/python/jobopts.yaml</text> - <text>--user_algorithms</text> - <text>$DAVINCITUTORIALSROOT/python/tutorial0_basic_DVjob:main</text> + <text>DaVinciTutorials.tutorial0_basic_DVjob:main</text> </set></argument> <argument name="reference"><text>../refs/test_tutorial0_basic_DVjob.ref</text></argument> <argument name="error_reference"><text>../refs/empty.ref</text></argument> diff --git a/DaVinciTutorials/tests/qmtest/test_tutorial1_functors_specialfield.qmt b/DaVinciTutorials/tests/qmtest/test_tutorial1_functors_specialfield.qmt index 69d917044382d19bf0bfec1fbf09bbe17d6b5525..79951d43a02c2edd06fa339f492813b2e9c8c52c 100644 --- a/DaVinciTutorials/tests/qmtest/test_tutorial1_functors_specialfield.qmt +++ b/DaVinciTutorials/tests/qmtest/test_tutorial1_functors_specialfield.qmt @@ -12,28 +12,14 @@ ############################################################################### --> <!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<!-- -####################################################### -# SUMMARY OF THIS TEST -# ................... -# Author: Abhijit Mathad -# Purpose: Test tutorial1_functors_specialfield of DV Tutorial -# Prerequisites: None -# inputfiledb bs2jpsiphi_turbo $DAVINCITUTORIALSROOT/python/dataprops.yaml -# joboptfile $DAVINCITUTORIALSROOT/python/jobopts.yaml -# user_algorithms $DAVINCITUTORIALSROOT/python/tutorial1_functors_specialfield:main -####################################################### ---> <extension class="GaudiTest.GaudiExeTest" kind="test"> - <argument name="program"><text>davinci</text></argument> + <argument name="program"><text>lbexec</text></argument> + <argument name="options_yaml_fn"><text>$DAVINCITUTORIALSROOT/options.yaml</text></argument> + <argument name="extra_options_yaml"><text> + ntuple_file: tutorial1_functors_specialfield.root + </text></argument> <argument name="args"><set> - <text>--inputfiledb</text> - <text>bs2jpsiphi_turbo</text> - <text>$DAVINCITUTORIALSROOT/python/dataprops.yaml</text> - <text>--joboptfile</text> - <text>$DAVINCITUTORIALSROOT/python/jobopts.yaml</text> - <text>--user_algorithms</text> - <text>$DAVINCITUTORIALSROOT/python/tutorial1_functors_specialfield:main</text> + <text>DaVinciTutorials.tutorial1_functors_specialfield:main</text> </set></argument> <argument name="reference"><text>../refs/test_tutorial1_Functors_specialfield.ref</text></argument> <argument name="error_reference"><text>../refs/empty.ref</text></argument> diff --git a/DaVinciTutorials/tests/qmtest/test_tutorial2_LoKi.qmt b/DaVinciTutorials/tests/qmtest/test_tutorial2_LoKi.qmt index 3e4ea110354e99cd55c2659567ca46495ee351db..2734a3797e1791bf8bfaa9f02004ffb9bf87f8b1 100644 --- a/DaVinciTutorials/tests/qmtest/test_tutorial2_LoKi.qmt +++ b/DaVinciTutorials/tests/qmtest/test_tutorial2_LoKi.qmt @@ -12,28 +12,14 @@ ############################################################################### --> <!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<!-- -####################################################### -# SUMMARY OF THIS TEST -# ................... -# Author: Abhijit Mathad -# Purpose: Test tutorial2_LoKi of DV Tutorial -# Prerequisites: None -# inputfiledb bs2jpsiphi_turbo $DAVINCITUTORIALSROOT/python/dataprops.yaml -# joboptfile $DAVINCITUTORIALSROOT/python/jobopts.yaml -# user_algorithms $DAVINCITUTORIALSROOT/python/tutorial2_LoKi:main -####################################################### ---> <extension class="GaudiTest.GaudiExeTest" kind="test"> - <argument name="program"><text>davinci</text></argument> + <argument name="program"><text>lbexec</text></argument> + <argument name="options_yaml_fn"><text>$DAVINCITUTORIALSROOT/options.yaml</text></argument> + <argument name="extra_options_yaml"><text> + ntuple_file: tutorial2_LoKi.root + </text></argument> <argument name="args"><set> - <text>--inputfiledb</text> - <text>bs2jpsiphi_turbo</text> - <text>$DAVINCITUTORIALSROOT/python/dataprops.yaml</text> - <text>--joboptfile</text> - <text>$DAVINCITUTORIALSROOT/python/jobopts.yaml</text> - <text>--user_algorithms</text> - <text>$DAVINCITUTORIALSROOT/python/tutorial2_LoKi:main</text> + <text>DaVinciTutorials.tutorial2_LoKi:main</text> </set></argument> <argument name="reference"><text>../refs/test_tutorial2_LoKi.ref</text></argument> <argument name="error_reference"><text>../refs/empty.ref</text></argument> diff --git a/DaVinciTutorials/tests/qmtest/test_tutorial3_ThOrfunctors.qmt b/DaVinciTutorials/tests/qmtest/test_tutorial3_ThOrfunctors.qmt index 5d120bad6a1e31496edf2ffb7385c2af90131ca0..b9700320ad20f92f32af75d6172ed7130beeb695 100644 --- a/DaVinciTutorials/tests/qmtest/test_tutorial3_ThOrfunctors.qmt +++ b/DaVinciTutorials/tests/qmtest/test_tutorial3_ThOrfunctors.qmt @@ -12,28 +12,14 @@ ############################################################################### --> <!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<!-- -####################################################### -# SUMMARY OF THIS TEST -# ................... -# Author: Abhijit Mathad -# Purpose: Test tutorial3_ThOrfunctors of DV Tutorial -# Prerequisites: None -# inputfiledb bs2jpsiphi_turbo $DAVINCITUTORIALSROOT/python/dataprops.yaml -# joboptfile $DAVINCITUTORIALSROOT/python/jobopts.yaml -# user_algorithms $DAVINCITUTORIALSROOT/python/tutorial3_ThOrfunctors:main -####################################################### ---> <extension class="GaudiTest.GaudiExeTest" kind="test"> - <argument name="program"><text>davinci</text></argument> + <argument name="program"><text>lbexec</text></argument> + <argument name="options_yaml_fn"><text>$DAVINCITUTORIALSROOT/options.yaml</text></argument> + <argument name="extra_options_yaml"><text> + ntuple_file: tutorial3_ThOrfunctors.root + </text></argument> <argument name="args"><set> - <text>--inputfiledb</text> - <text>bs2jpsiphi_turbo</text> - <text>$DAVINCITUTORIALSROOT/python/dataprops.yaml</text> - <text>--joboptfile</text> - <text>$DAVINCITUTORIALSROOT/python/jobopts.yaml</text> - <text>--user_algorithms</text> - <text>$DAVINCITUTORIALSROOT/python/tutorial3_ThOrfunctors:main</text> + <text>DaVinciTutorials.tutorial3_ThOrfunctors:main</text> </set></argument> <argument name="reference"><text>../refs/test_tutorial3_ThOrfunctors.ref</text></argument> <argument name="error_reference"><text>../refs/empty.ref</text></argument> diff --git a/DaVinciTutorials/tests/qmtest/test_tutorial4_trigger_eventinfo.qmt b/DaVinciTutorials/tests/qmtest/test_tutorial4_trigger_eventinfo.qmt index e9068dad8c9b83e602286ac82c27c533a40dc305..4b52ddd7791354169b3427e519e7ad54edeedeb0 100644 --- a/DaVinciTutorials/tests/qmtest/test_tutorial4_trigger_eventinfo.qmt +++ b/DaVinciTutorials/tests/qmtest/test_tutorial4_trigger_eventinfo.qmt @@ -12,28 +12,14 @@ ############################################################################### --> <!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<!-- -####################################################### -# SUMMARY OF THIS TEST -# ................... -# Author: Abhijit Mathad -# Purpose: Test tutorial4_trigger_eventinfo of DV Tutorial -# Prerequisites: None -# inputfiledb bs2jpsiphi_turbo $DAVINCITUTORIALSROOT/python/dataprops.yaml -# joboptfile $DAVINCITUTORIALSROOT/python/jobopts.yaml -# user_algorithms $DAVINCITUTORIALSROOT/python/tutorial4_trigger_eventinfo:main -####################################################### ---> <extension class="GaudiTest.GaudiExeTest" kind="test"> - <argument name="program"><text>davinci</text></argument> + <argument name="program"><text>lbexec</text></argument> + <argument name="options_yaml_fn"><text>$DAVINCITUTORIALSROOT/options.yaml</text></argument> + <argument name="extra_options_yaml"><text> + ntuple_file: tutorial4_trigger_eventinfo.root + </text></argument> <argument name="args"><set> - <text>--inputfiledb</text> - <text>bs2jpsiphi_turbo</text> - <text>$DAVINCITUTORIALSROOT/python/dataprops.yaml</text> - <text>--joboptfile</text> - <text>$DAVINCITUTORIALSROOT/python/jobopts.yaml</text> - <text>--user_algorithms</text> - <text>$DAVINCITUTORIALSROOT/python/tutorial4_trigger_eventinfo:main</text> + <text>DaVinciTutorials.tutorial4_trigger_eventinfo:main</text> </set></argument> <argument name="reference"><text>../refs/test_tutorial4_trigger_eventinfo.ref</text></argument> <argument name="error_reference"><text>../refs/empty.ref</text></argument> diff --git a/DaVinciTutorials/tests/qmtest/test_tutorial5_MCTruth.qmt b/DaVinciTutorials/tests/qmtest/test_tutorial5_MCTruth.qmt index af2e7c9c3b9c4a93be8b6c26a87076235b1ba937..6cda4f5c0a395fe4ea7553a3254e819ea252ddeb 100644 --- a/DaVinciTutorials/tests/qmtest/test_tutorial5_MCTruth.qmt +++ b/DaVinciTutorials/tests/qmtest/test_tutorial5_MCTruth.qmt @@ -12,28 +12,14 @@ ############################################################################### --> <!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<!-- -####################################################### -# SUMMARY OF THIS TEST -# ................... -# Author: Abhijit Mathad -# Purpose: Test tutorial5_MCTruth of DV Tutorial -# Prerequisites: None -# inputfiledb bs2jpsiphi_turbo $DAVINCITUTORIALSROOT/python/dataprops.yaml -# joboptfile $DAVINCITUTORIALSROOT/python/jobopts.yaml -# user_algorithms $DAVINCITUTORIALSROOT/python/tutorial5_MCTruth:main -####################################################### ---> <extension class="GaudiTest.GaudiExeTest" kind="test"> - <argument name="program"><text>davinci</text></argument> + <argument name="program"><text>lbexec</text></argument> + <argument name="options_yaml_fn"><text>$DAVINCITUTORIALSROOT/options.yaml</text></argument> + <argument name="extra_options_yaml"><text> + ntuple_file: tutorial5_MCTruth.root + </text></argument> <argument name="args"><set> - <text>--inputfiledb</text> - <text>bs2jpsiphi_turbo</text> - <text>$DAVINCITUTORIALSROOT/python/dataprops.yaml</text> - <text>--joboptfile</text> - <text>$DAVINCITUTORIALSROOT/python/jobopts.yaml</text> - <text>--user_algorithms</text> - <text>$DAVINCITUTORIALSROOT/python/tutorial5_MCTruth:main</text> + <text>DaVinciTutorials.tutorial5_MCTruth:main</text> </set></argument> <argument name="reference"><text>../refs/test_tutorial5_MCTruth.ref</text></argument> <argument name="error_reference"><text>../refs/empty.ref</text></argument> diff --git a/DaVinciTutorials/tests/qmtest/test_tutorial6_DecayTreeFit.qmt b/DaVinciTutorials/tests/qmtest/test_tutorial6_DecayTreeFit.qmt index 0ee70d2bffeaf970906d50ebb8fb7457a37ca4a3..7cbcce963c0d3bdfd7b2ac5702b707f91785943c 100644 --- a/DaVinciTutorials/tests/qmtest/test_tutorial6_DecayTreeFit.qmt +++ b/DaVinciTutorials/tests/qmtest/test_tutorial6_DecayTreeFit.qmt @@ -12,28 +12,14 @@ ############################################################################### --> <!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<!-- -####################################################### -# SUMMARY OF THIS TEST -# ................... -# Author: Abhijit Mathad -# Purpose: Test tutorial6_DecayTreeFit of DV Tutorial -# Prerequisites: None -# inputfiledb bs2jpsiphi_turbo $DAVINCITUTORIALSROOT/python/dataprops.yaml -# joboptfile $DAVINCITUTORIALSROOT/python/jobopts.yaml -# user_algorithms $DAVINCITUTORIALSROOT/python/tutorial6_DecayTreeFit:main -####################################################### ---> <extension class="GaudiTest.GaudiExeTest" kind="test"> - <argument name="program"><text>davinci</text></argument> + <argument name="program"><text>lbexec</text></argument> + <argument name="options_yaml_fn"><text>$DAVINCITUTORIALSROOT/options.yaml</text></argument> + <argument name="extra_options_yaml"><text> + ntuple_file: tutorial6_DecayTreeFit.root + </text></argument> <argument name="args"><set> - <text>--inputfiledb</text> - <text>bs2jpsiphi_turbo</text> - <text>$DAVINCITUTORIALSROOT/python/dataprops.yaml</text> - <text>--joboptfile</text> - <text>$DAVINCITUTORIALSROOT/python/jobopts.yaml</text> - <text>--user_algorithms</text> - <text>$DAVINCITUTORIALSROOT/python/tutorial6_DecayTreeFit:main</text> + <text>DaVinciTutorials.tutorial6_DecayTreeFit:main</text> </set></argument> <argument name="reference"><text>../refs/test_tutorial6_DecayTreeFit.ref</text></argument> <argument name="error_reference"><text>../refs/empty.ref</text></argument> diff --git a/DaVinciTutorials/tests/qmtest/test_tutorial7_multiple_sel_lines.qmt b/DaVinciTutorials/tests/qmtest/test_tutorial7_multiple_sel_lines.qmt index d81313ac2d0ed9d3baa2b7420b0f46bf95f118db..6ff32d44a846e646f9ec50e8f2bfe45737a68aac 100644 --- a/DaVinciTutorials/tests/qmtest/test_tutorial7_multiple_sel_lines.qmt +++ b/DaVinciTutorials/tests/qmtest/test_tutorial7_multiple_sel_lines.qmt @@ -12,28 +12,14 @@ ############################################################################### --> <!DOCTYPE extension PUBLIC '-//QM/2.3/Extension//EN' 'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'> -<!-- -####################################################### -# SUMMARY OF THIS TEST -# ................... -# Author: Abhijit Mathad -# Purpose: Test tutorial7_multiple_sel_lines of DV Tutorial -# Prerequisites: None -# inputfiledb bs2jpsiphi_turbo $DAVINCITUTORIALSROOT/python/dataprops.yaml -# joboptfile $DAVINCITUTORIALSROOT/python/jobopts.yaml -# user_algorithms $DAVINCITUTORIALSROOT/python/tutorial7_multiple_sel_lines:main -####################################################### ---> <extension class="GaudiTest.GaudiExeTest" kind="test"> - <argument name="program"><text>davinci</text></argument> + <argument name="program"><text>lbexec</text></argument> + <argument name="options_yaml_fn"><text>$DAVINCITUTORIALSROOT/options.yaml</text></argument> + <argument name="extra_options_yaml"><text> + ntuple_file: tutorial7_multiple_sel_lines.root + </text></argument> <argument name="args"><set> - <text>--inputfiledb</text> - <text>bs2jpsiphi_turbo</text> - <text>$DAVINCITUTORIALSROOT/python/dataprops.yaml</text> - <text>--joboptfile</text> - <text>$DAVINCITUTORIALSROOT/python/jobopts.yaml</text> - <text>--user_algorithms</text> - <text>$DAVINCITUTORIALSROOT/python/tutorial7_multiple_sel_lines:main</text> + <text>DaVinciTutorials.tutorial7_multiple_sel_lines:main</text> </set></argument> <argument name="reference"><text>../refs/test_tutorial7_multiple_sel_lines.ref</text></argument> <argument name="error_reference"><text>../refs/empty.ref</text></argument> diff --git a/DaVinciTutorials/tests/refs/test_tutorial0_basic_DVjob.ref b/DaVinciTutorials/tests/refs/test_tutorial0_basic_DVjob.ref index 23e7831bb1b2b6ba1d922642ac07f335610cbbfb..738d496dd1ea15f82bdcd7c7f36433b5dc1fc353 100644 --- a/DaVinciTutorials/tests/refs/test_tutorial0_basic_DVjob.ref +++ b/DaVinciTutorials/tests/refs/test_tutorial0_basic_DVjob.ref @@ -1,4 +1,3 @@ -INFO User algorithm tutorial0_basic_DVjob.main imported successfully! ApplicationMgr SUCCESS ==================================================================================================================================== ==================================================================================================================================== @@ -689,7 +688,7 @@ LAZY_AND: DaVinci #=100 Sum=12 Ef LAZY_AND: GenFSR #=100 Sum=100 Eff=|( 100.0000 +- 0.00000 )%| RecordStream/FSROutputStreamDstWriter #=100 Sum=100 Eff=|( 100.0000 +- 0.00000 )%| NONLAZY_OR: UserAnalysis #=100 Sum=12 Eff=|( 12.00000 +- 3.24962 )%| - LAZY_AND: Alg #=100 Sum=12 Eff=|( 12.00000 +- 3.24962 )%| + LAZY_AND: default #=100 Sum=12 Eff=|( 12.00000 +- 3.24962 )%| LHCb__UnpackRawEvent/LHCb__UnpackRawEvent #=100 Sum=100 Eff=|( 100.0000 +- 0.00000 )%| HltPackedBufferDecoder/HltPackedBufferDecoder #=100 Sum=100 Eff=|( 100.0000 +- 0.00000 )%| UnpackMCParticle/UnpackMCParticle #=100 Sum=100 Eff=|( 100.0000 +- 0.00000 )%| diff --git a/DaVinciTutorials/tests/refs/test_tutorial1_Functors_specialfield.ref b/DaVinciTutorials/tests/refs/test_tutorial1_Functors_specialfield.ref index 23ed4dcb05fff109731612c77ee242df0243723b..e75b1438807878d0667bd110135fb319ad5e30fc 100644 --- a/DaVinciTutorials/tests/refs/test_tutorial1_Functors_specialfield.ref +++ b/DaVinciTutorials/tests/refs/test_tutorial1_Functors_specialfield.ref @@ -1,6 +1,5 @@ Functors::chain( ::Functors::Common::Rho_Coordinate{}, ::Functors::Track::ThreeMomentum{} ) ( RHO_COORDINATE @ THREEMOMENTUM ) -INFO User algorithm tutorial1_functors_specialfield.main imported successfully! ApplicationMgr SUCCESS ==================================================================================================================================== ==================================================================================================================================== @@ -129,7 +128,7 @@ LAZY_AND: DaVinci #=100 Sum=12 Ef LAZY_AND: GenFSR #=100 Sum=100 Eff=|( 100.0000 +- 0.00000 )%| RecordStream/FSROutputStreamDstWriter #=100 Sum=100 Eff=|( 100.0000 +- 0.00000 )%| NONLAZY_OR: UserAnalysis #=100 Sum=12 Eff=|( 12.00000 +- 3.24962 )%| - LAZY_AND: Alg #=100 Sum=12 Eff=|( 12.00000 +- 3.24962 )%| + LAZY_AND: default #=100 Sum=12 Eff=|( 12.00000 +- 3.24962 )%| LHCb__UnpackRawEvent/LHCb__UnpackRawEvent #=100 Sum=100 Eff=|( 100.0000 +- 0.00000 )%| HltPackedBufferDecoder/HltPackedBufferDecoder #=100 Sum=100 Eff=|( 100.0000 +- 0.00000 )%| UnpackMCParticle/UnpackMCParticle #=100 Sum=100 Eff=|( 100.0000 +- 0.00000 )%| diff --git a/DaVinciTutorials/tests/refs/test_tutorial2_LoKi.ref b/DaVinciTutorials/tests/refs/test_tutorial2_LoKi.ref index e7dbe01ccf8220e446f17b0d0005da6e09c5adb1..56f0da422b92d07300a349ec866f102e5a15860f 100644 --- a/DaVinciTutorials/tests/refs/test_tutorial2_LoKi.ref +++ b/DaVinciTutorials/tests/refs/test_tutorial2_LoKi.ref @@ -1,4 +1,3 @@ -INFO User algorithm tutorial2_LoKi.main imported successfully! ApplicationMgr SUCCESS ==================================================================================================================================== ==================================================================================================================================== @@ -127,7 +126,7 @@ LAZY_AND: DaVinci #=100 Sum=12 Ef LAZY_AND: GenFSR #=100 Sum=100 Eff=|( 100.0000 +- 0.00000 )%| RecordStream/FSROutputStreamDstWriter #=100 Sum=100 Eff=|( 100.0000 +- 0.00000 )%| NONLAZY_OR: UserAnalysis #=100 Sum=12 Eff=|( 12.00000 +- 3.24962 )%| - LAZY_AND: Alg #=100 Sum=12 Eff=|( 12.00000 +- 3.24962 )%| + LAZY_AND: default #=100 Sum=12 Eff=|( 12.00000 +- 3.24962 )%| LHCb__UnpackRawEvent/LHCb__UnpackRawEvent #=100 Sum=100 Eff=|( 100.0000 +- 0.00000 )%| HltPackedBufferDecoder/HltPackedBufferDecoder #=100 Sum=100 Eff=|( 100.0000 +- 0.00000 )%| UnpackMCParticle/UnpackMCParticle #=100 Sum=100 Eff=|( 100.0000 +- 0.00000 )%| diff --git a/DaVinciTutorials/tests/refs/test_tutorial3_ThOrfunctors.ref b/DaVinciTutorials/tests/refs/test_tutorial3_ThOrfunctors.ref index 0842b92e93385319af23e8ec6d8ed81120ee5a0f..937c5cc046fb3cccffd2544e3799ec77bf57d51c 100644 --- a/DaVinciTutorials/tests/refs/test_tutorial3_ThOrfunctors.ref +++ b/DaVinciTutorials/tests/refs/test_tutorial3_ThOrfunctors.ref @@ -1,4 +1,3 @@ -INFO User algorithm tutorial3_ThOrfunctors.main imported successfully! ApplicationMgr SUCCESS ==================================================================================================================================== ==================================================================================================================================== @@ -127,7 +126,7 @@ LAZY_AND: DaVinci #=100 Sum=12 Ef LAZY_AND: GenFSR #=100 Sum=100 Eff=|( 100.0000 +- 0.00000 )%| RecordStream/FSROutputStreamDstWriter #=100 Sum=100 Eff=|( 100.0000 +- 0.00000 )%| NONLAZY_OR: UserAnalysis #=100 Sum=12 Eff=|( 12.00000 +- 3.24962 )%| - LAZY_AND: Alg #=100 Sum=12 Eff=|( 12.00000 +- 3.24962 )%| + LAZY_AND: default #=100 Sum=12 Eff=|( 12.00000 +- 3.24962 )%| LHCb__UnpackRawEvent/LHCb__UnpackRawEvent #=100 Sum=100 Eff=|( 100.0000 +- 0.00000 )%| HltPackedBufferDecoder/HltPackedBufferDecoder #=100 Sum=100 Eff=|( 100.0000 +- 0.00000 )%| UnpackMCParticle/UnpackMCParticle #=100 Sum=100 Eff=|( 100.0000 +- 0.00000 )%| diff --git a/DaVinciTutorials/tests/refs/test_tutorial4_trigger_eventinfo.ref b/DaVinciTutorials/tests/refs/test_tutorial4_trigger_eventinfo.ref index 63948617a76071b2ff909d57c7801960562bd585..25d1ddafbc32e11e27fea1bdae699215b0f5e428 100644 --- a/DaVinciTutorials/tests/refs/test_tutorial4_trigger_eventinfo.ref +++ b/DaVinciTutorials/tests/refs/test_tutorial4_trigger_eventinfo.ref @@ -1,4 +1,3 @@ -INFO User algorithm tutorial4_trigger_eventinfo.main imported successfully! ApplicationMgr SUCCESS ==================================================================================================================================== Welcome to DaVinci version 60.3 @@ -289,7 +288,7 @@ LAZY_AND: DaVinci #=100 Sum=12 Ef LAZY_AND: GenFSR #=100 Sum=100 Eff=|( 100.0000 +- 0.00000 )%| RecordStream/FSROutputStreamDstWriter #=100 Sum=100 Eff=|( 100.0000 +- 0.00000 )%| NONLAZY_OR: UserAnalysis #=100 Sum=12 Eff=|( 12.00000 +- 3.24962 )%| - LAZY_AND: Alg #=100 Sum=12 Eff=|( 12.00000 +- 3.24962 )%| + LAZY_AND: default #=100 Sum=12 Eff=|( 12.00000 +- 3.24962 )%| LHCb__UnpackRawEvent/LHCb__UnpackRawEvent#1 #=100 Sum=100 Eff=|( 100.0000 +- 0.00000 )%| HltPackedBufferDecoder/HltPackedBufferDecoder #=100 Sum=100 Eff=|( 100.0000 +- 0.00000 )%| UnpackMCParticle/UnpackMCParticle #=100 Sum=100 Eff=|( 100.0000 +- 0.00000 )%| diff --git a/DaVinciTutorials/tests/refs/test_tutorial5_MCTruth.ref b/DaVinciTutorials/tests/refs/test_tutorial5_MCTruth.ref index 9a94c4f3f4df5f1c6f1c55c505005d95ce0edd07..9ad5f5c849dc6819c8cfe2834ac488a7b2110be5 100644 --- a/DaVinciTutorials/tests/refs/test_tutorial5_MCTruth.ref +++ b/DaVinciTutorials/tests/refs/test_tutorial5_MCTruth.ref @@ -26,7 +26,6 @@ DataHandle('/Event/MCTruthAndBkgCatAlg#1/MCAssocTable') <FunctorCollection object at 0x########: TRUEID: ('Functors::bind( ::Functors::Adapters::MapRelInputToFunOutput( /* The functor to apply to the particle. */ ::Functors::Simulation::Particle_Id{} ), ::Functors::Common::TES<LHCb::Relation1D<LHCb::Particle,LHCb::MCParticle>>( /* List of DataHandles */ std::vector{std::string{"/Event/MCTruthAndBkgCatAlg#1/MCAssocTable"}} ), ::Functors::Common::ForwardArgs{} )', "_MAP_INPUT(Functor=PARTICLE_ID).bind( TES(DataHandles=[DataHandle('/Event/MCTruthAndBkgCatAlg#1/MCAssocTable')], DataTypes=['LHCb::Relation1D<LHCb::Particle,LHCb::MCParticle>']), FORWARDARGS )") > -INFO User algorithm tutorial5_MCTruth.main imported successfully! ApplicationMgr SUCCESS ==================================================================================================================================== ==================================================================================================================================== @@ -158,7 +157,7 @@ LAZY_AND: DaVinci #=100 Sum=12 Ef LAZY_AND: GenFSR #=100 Sum=100 Eff=|( 100.0000 +- 0.00000 )%| RecordStream/FSROutputStreamDstWriter #=100 Sum=100 Eff=|( 100.0000 +- 0.00000 )%| NONLAZY_OR: UserAnalysis #=100 Sum=12 Eff=|( 12.00000 +- 3.24962 )%| - LAZY_AND: Alg #=100 Sum=12 Eff=|( 12.00000 +- 3.24962 )%| + LAZY_AND: default #=100 Sum=12 Eff=|( 12.00000 +- 3.24962 )%| LHCb__UnpackRawEvent/LHCb__UnpackRawEvent #=100 Sum=100 Eff=|( 100.0000 +- 0.00000 )%| HltPackedBufferDecoder/HltPackedBufferDecoder #=100 Sum=100 Eff=|( 100.0000 +- 0.00000 )%| UnpackMCParticle/UnpackMCParticle #=100 Sum=100 Eff=|( 100.0000 +- 0.00000 )%| diff --git a/DaVinciTutorials/tests/refs/test_tutorial6_DecayTreeFit.ref b/DaVinciTutorials/tests/refs/test_tutorial6_DecayTreeFit.ref index 7a0b50ba318b481553082ef48cd7e3e042449c96..305fe293be2991ff9267c2872d81477d0b746a34 100644 --- a/DaVinciTutorials/tests/refs/test_tutorial6_DecayTreeFit.ref +++ b/DaVinciTutorials/tests/refs/test_tutorial6_DecayTreeFit.ref @@ -7,7 +7,6 @@ DTF_PZ: ('Functors::bind( ::Functors::Adapters::MapRelInputToFunOutput( /* The functor to apply to the particle. */ Functors::chain( ::Functors::Common::Z_Coordinate{}, ::Functors::Track::ThreeMomentum{} ) ), ::Functors::Common::TES<LHCb::Relation1D<LHCb::Particle,LHCb::Particle>>( /* List of DataHandles */ std::vector{std::string{"/Event/DecayTreeFitterAlg/OutputRelations"}} ), ::Functors::Common::ForwardArgs{} )', "_MAP_INPUT(Functor=( Z_COORDINATE @ THREEMOMENTUM )).bind( TES(DataHandles=[DataHandle('/Event/DecayTreeFitterAlg/OutputRelations')], DataTypes=['LHCb::Relation1D<LHCb::Particle,LHCb::Particle>']), FORWARDARGS )") DTF_ENERGY: ('Functors::bind( ::Functors::Adapters::MapRelInputToFunOutput( /* The functor to apply to the particle. */ Functors::chain( ::Functors::Common::E_Coordinate{}, ::Functors::Track::FourMomentum{} ) ), ::Functors::Common::TES<LHCb::Relation1D<LHCb::Particle,LHCb::Particle>>( /* List of DataHandles */ std::vector{std::string{"/Event/DecayTreeFitterAlg/OutputRelations"}} ), ::Functors::Common::ForwardArgs{} )', "_MAP_INPUT(Functor=( E_COORDINATE @ FOURMOMENTUM )).bind( TES(DataHandles=[DataHandle('/Event/DecayTreeFitterAlg/OutputRelations')], DataTypes=['LHCb::Relation1D<LHCb::Particle,LHCb::Particle>']), FORWARDARGS )") > -INFO User algorithm tutorial6_DecayTreeFit.main imported successfully! ApplicationMgr SUCCESS ==================================================================================================================================== ==================================================================================================================================== @@ -136,7 +135,7 @@ LAZY_AND: DaVinci #=100 Sum=12 Ef LAZY_AND: GenFSR #=100 Sum=100 Eff=|( 100.0000 +- 0.00000 )%| RecordStream/FSROutputStreamDstWriter #=100 Sum=100 Eff=|( 100.0000 +- 0.00000 )%| NONLAZY_OR: UserAnalysis #=100 Sum=12 Eff=|( 12.00000 +- 3.24962 )%| - LAZY_AND: Alg #=100 Sum=12 Eff=|( 12.00000 +- 3.24962 )%| + LAZY_AND: default #=100 Sum=12 Eff=|( 12.00000 +- 3.24962 )%| LHCb__UnpackRawEvent/LHCb__UnpackRawEvent #=100 Sum=100 Eff=|( 100.0000 +- 0.00000 )%| HltPackedBufferDecoder/HltPackedBufferDecoder #=100 Sum=100 Eff=|( 100.0000 +- 0.00000 )%| UnpackMCParticle/UnpackMCParticle #=100 Sum=100 Eff=|( 100.0000 +- 0.00000 )%| diff --git a/DaVinciTutorials/tests/refs/test_tutorial7_multiple_sel_lines.ref b/DaVinciTutorials/tests/refs/test_tutorial7_multiple_sel_lines.ref index d311b3af7687b012a2b776f2ab419fdcefa451a2..5f06a0edd0590645824b5d575941a1cb29076e0f 100644 --- a/DaVinciTutorials/tests/refs/test_tutorial7_multiple_sel_lines.ref +++ b/DaVinciTutorials/tests/refs/test_tutorial7_multiple_sel_lines.ref @@ -1,4 +1,3 @@ -INFO User algorithm tutorial7_multiple_sel_lines.main imported successfully! ApplicationMgr SUCCESS ==================================================================================================================================== ==================================================================================================================================== diff --git a/Phys/DaVinci/python/DaVinci/LbExec.py b/Phys/DaVinci/python/DaVinci/LbExec.py index 4fa0ba2fb21fe3e03dd00c4727fe65d4a3654e5a..fb0264a3ae417f9ba840c4657c78648760dae25f 100644 --- a/Phys/DaVinci/python/DaVinci/LbExec.py +++ b/Phys/DaVinci/python/DaVinci/LbExec.py @@ -21,10 +21,11 @@ class ProcessTypes(str, Enum): class Options(DefaultOptions): - annsvc_config: str - process: ProcessTypes - stream: str + annsvc_config: Optional[str] + process: ProcessTypes = ProcessTypes.Turbo + stream: str = "default" lumi: bool = False evt_pre_filters: Optional[str] = None enable_unpack: bool = True - write_fsr: bool = False + write_fsr: bool = True + merge_genfsr: bool = False