From 0721e21f0ddab0980955cacd08ea444fb2f4b4a2 Mon Sep 17 00:00:00 2001 From: Giacomo De Pietro Date: Fri, 31 Mar 2023 18:41:05 +0200 Subject: [PATCH 01/14] Slightly better basf2-related documentation --- docs/advanced/basf2-examples.rst | 2 +- examples/basf2/basf2_chain_example.py | 23 ++++++++++++----------- examples/gbasf2/example_mdst_analysis.py | 3 +-- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/advanced/basf2-examples.rst b/docs/advanced/basf2-examples.rst index ccace2ff..1e48f245 100644 --- a/docs/advanced/basf2-examples.rst +++ b/docs/advanced/basf2-examples.rst @@ -115,7 +115,7 @@ nTuple Generation # (parameters just examples) input_file_names = .. - path = basf2.create_path() + path = basf2.Path() modularAnalysis.inputMdstList('default', input_file_names, path=path) # Now fill your particle lists, just examples diff --git a/examples/basf2/basf2_chain_example.py b/examples/basf2/basf2_chain_example.py index 1634af93..9c76b1fe 100644 --- a/examples/basf2/basf2_chain_example.py +++ b/examples/basf2/basf2_chain_example.py @@ -10,7 +10,7 @@ import vertex import generators import reconstruction -from ROOT import Belle2 +import mdst class SimulationType(Enum): @@ -23,23 +23,22 @@ class SimulationTask(Basf2PathTask): event_type = luigi.EnumParameter(enum=SimulationType) def create_path(self): - path = basf2.create_path() + path = basf2.Path() modularAnalysis.setupEventInfo(self.n_events, path) if self.event_type == SimulationType.y4s: # in current main branch and release 5 the Y(4S)decay file is moved, so try old and new locations find_file_ignore_error = True - dec_file = Belle2.FileSystem.findFile('analysis/examples/tutorials/B2A101-Y4SEventGeneration.dec', - find_file_ignore_error) - if not dec_file: - dec_file = Belle2.FileSystem.findFile('analysis/examples/simulations/B2A101-Y4SEventGeneration.dec') + dec_file = basf2.find_file('analysis/examples/tutorials/B2A101-Y4SEventGeneration.dec', + silent=find_file_ignore_error) + if dec_file == '': + dec_file = basf2.find_file('analysis/examples/simulations/B2A101-Y4SEventGeneration.dec') elif self.event_type == SimulationType.continuum: - dec_file = Belle2.FileSystem.findFile('analysis/examples/simulations/B2A102-ccbarEventGeneration.dec') + dec_file = basf2.find_file('analysis/examples/simulations/B2A102-ccbarEventGeneration.dec') else: raise ValueError(f"Event type {self.event_type} is not valid. It should be either 'Y(4S)' or 'Continuum'!") generators.add_evtgen_generator(path, 'signal', dec_file) - modularAnalysis.loadGearbox(path) simulation.add_simulation(path) path.add_module('RootOutput', outputFileName=self.get_output_file_name('simulation_full_output.root')) @@ -56,10 +55,12 @@ def create_path(self): path = basf2.create_path() path.add_module('RootInput', inputFileNames=self.get_input_file_names("simulation_full_output.root")) - modularAnalysis.loadGearbox(path) + + path.add_module('Gearbox') + path.add_module('Geometry') reconstruction.add_reconstruction(path) - modularAnalysis.outputMdst(self.get_output_file_name("reconstructed_output.root"), path=path) + mdst.add_mdst_output(path=path, filename=self.get_output_file_name("reconstructed_output.root")) return path @@ -70,7 +71,7 @@ def output(self): @luigi.requires(ReconstructionTask) class AnalysisTask(Basf2PathTask): def create_path(self): - path = basf2.create_path() + path = basf2.Path() modularAnalysis.inputMdstList('default', self.get_input_file_names("reconstructed_output.root"), path=path) modularAnalysis.fillParticleLists([('K+', 'kaonID > 0.1'), ('pi+', 'pionID > 0.1')], path=path) modularAnalysis.reconstructDecay('D0 -> K- pi+', '1.7 < M < 1.9', path=path) diff --git a/examples/gbasf2/example_mdst_analysis.py b/examples/gbasf2/example_mdst_analysis.py index 528b9b44..2a23c1b0 100644 --- a/examples/gbasf2/example_mdst_analysis.py +++ b/examples/gbasf2/example_mdst_analysis.py @@ -5,7 +5,6 @@ """ import basf2 -import ROOT # noqa: F401 import modularAnalysis as mA import vertex as vx from stdCharged import stdK, stdPi @@ -22,7 +21,7 @@ def create_analysis_path( parameter, adapted from code in the ``B2T_Basics_3_FirstAnalysis.ipynb`` notebook from b2 starter kit. """ - path = basf2.create_path() + path = basf2.Path() # this local inputMdstList will only be used when this steerig file is run locally, gbasf2 overrides it local_input_files = ["/group/belle2/dataprod/MC/MC13a/prod00009434/s00/e1003/4S/r00000/mixed/mdst/sub00/mdst_000001_prod00009434_task10020000001.root"] mA.inputMdstList( From b63ed8f0f38d02562d742c55877a48c566c2f837 Mon Sep 17 00:00:00 2001 From: Giacomo De Pietro Date: Fri, 31 Mar 2023 18:42:00 +0200 Subject: [PATCH 02/14] Avoid using the Environment singleton, but set the maximum number of events to process directly via basf2.process --- b2luigi/basf2_helper/tasks.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/b2luigi/basf2_helper/tasks.py b/b2luigi/basf2_helper/tasks.py index f284e70c..09a01c27 100644 --- a/b2luigi/basf2_helper/tasks.py +++ b/b2luigi/basf2_helper/tasks.py @@ -46,21 +46,17 @@ def process(self): try: import basf2 - import ROOT except ImportError: raise ImportError("Can not find ROOT or basf2. Can not use the basf2 task.") if self.num_processes: basf2.set_nprocesses(self.num_processes) - if self.max_event: - ROOT.Belle2.Environment.Instance().setNumberEventsOverride(self.max_event) - path = self.create_path() path.add_module("Progress") basf2.print_path(path) - basf2.process(path) + basf2.process(path=path, max_event=self.max_event if self.max_event else 0) print(basf2.statistics) From 6d4efaf9897348c92007e1a1d861e3bb7f1b2b94 Mon Sep 17 00:00:00 2001 From: Giacomo De Pietro <63421990+GiacomoXT@users.noreply.github.com> Date: Fri, 31 Mar 2023 23:42:34 +0200 Subject: [PATCH 03/14] Accept suggestion about exception message Co-authored-by: Michael Eliachevitch --- b2luigi/basf2_helper/tasks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/b2luigi/basf2_helper/tasks.py b/b2luigi/basf2_helper/tasks.py index 09a01c27..07c4a187 100644 --- a/b2luigi/basf2_helper/tasks.py +++ b/b2luigi/basf2_helper/tasks.py @@ -47,7 +47,7 @@ def process(self): try: import basf2 except ImportError: - raise ImportError("Can not find ROOT or basf2. Can not use the basf2 task.") + raise ImportError("Can not find basf2. Can not use the basf2 task.") if self.num_processes: basf2.set_nprocesses(self.num_processes) From 38276b36f824fbd9ee3178916c5f2b23c3537420 Mon Sep 17 00:00:00 2001 From: Giacomo De Pietro <63421990+GiacomoXT@users.noreply.github.com> Date: Fri, 31 Mar 2023 23:43:41 +0200 Subject: [PATCH 04/14] Accept suggestion about splitting the inline if-else into separate line Co-authored-by: Michael Eliachevitch --- b2luigi/basf2_helper/tasks.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/b2luigi/basf2_helper/tasks.py b/b2luigi/basf2_helper/tasks.py index 07c4a187..04491a3e 100644 --- a/b2luigi/basf2_helper/tasks.py +++ b/b2luigi/basf2_helper/tasks.py @@ -56,7 +56,8 @@ def process(self): path.add_module("Progress") basf2.print_path(path) - basf2.process(path=path, max_event=self.max_event if self.max_event else 0) + max_event = self.max_event if self.max_event else 0 + basf2.process(path=path, max_event=max_event) print(basf2.statistics) From f2161813a1d890f09ebb5fe785630564fe35bb8d Mon Sep 17 00:00:00 2001 From: Giacomo De Pietro Date: Sat, 1 Apr 2023 00:17:09 +0200 Subject: [PATCH 05/14] Revert modification about checking empty string for dec_file --- examples/basf2/basf2_chain_example.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/basf2/basf2_chain_example.py b/examples/basf2/basf2_chain_example.py index 9c76b1fe..3f44df5d 100644 --- a/examples/basf2/basf2_chain_example.py +++ b/examples/basf2/basf2_chain_example.py @@ -31,7 +31,7 @@ def create_path(self): find_file_ignore_error = True dec_file = basf2.find_file('analysis/examples/tutorials/B2A101-Y4SEventGeneration.dec', silent=find_file_ignore_error) - if dec_file == '': + if not dec_file: dec_file = basf2.find_file('analysis/examples/simulations/B2A101-Y4SEventGeneration.dec') elif self.event_type == SimulationType.continuum: dec_file = basf2.find_file('analysis/examples/simulations/B2A102-ccbarEventGeneration.dec') From bc02d1bf50e5a533eba9a5d139c62d2677cda9b0 Mon Sep 17 00:00:00 2001 From: Giacomo De Pietro Date: Sat, 1 Apr 2023 00:54:32 +0200 Subject: [PATCH 06/14] Use same way as used by basf2 --info for returning the basf2 commit hash in case of local version --- b2luigi/basf2_helper/utils.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/b2luigi/basf2_helper/utils.py b/b2luigi/basf2_helper/utils.py index 34a0fed1..f44eea64 100644 --- a/b2luigi/basf2_helper/utils.py +++ b/b2luigi/basf2_helper/utils.py @@ -1,16 +1,18 @@ import os -import git - def get_basf2_git_hash(): basf2_release = os.getenv("BELLE2_RELEASE") if basf2_release == "head" or basf2_release is None: - basf2_release_location = os.getenv("BELLE2_LOCAL_DIR") - if basf2_release_location: - return git.Repo(basf2_release_location).head.object.hexsha - return "not_set" + try: + from basf2.version import get_version + basf2_hash = get_version + except ImportError: + from basf2.version import version + basf2_hash = version + + basf2_release = basf2_hash() return basf2_release From 297f9c6087cf49de97d618457f252b50834102d5 Mon Sep 17 00:00:00 2001 From: Michael Eliachevitch Date: Mon, 3 Apr 2023 11:12:10 +0200 Subject: [PATCH 07/14] Check for empty string implicitly and add code comment --- examples/basf2/basf2_chain_example.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/examples/basf2/basf2_chain_example.py b/examples/basf2/basf2_chain_example.py index 3f44df5d..81336f72 100644 --- a/examples/basf2/basf2_chain_example.py +++ b/examples/basf2/basf2_chain_example.py @@ -27,10 +27,15 @@ def create_path(self): modularAnalysis.setupEventInfo(self.n_events, path) if self.event_type == SimulationType.y4s: - # in current main branch and release 5 the Y(4S)decay file is moved, so try old and new locations - find_file_ignore_error = True - dec_file = basf2.find_file('analysis/examples/tutorials/B2A101-Y4SEventGeneration.dec', - silent=find_file_ignore_error) + # In current main branch and release 5 the Y(4S)decay file is moved, + # so try old and new locations. + + # With ``silent=True``, ``find_file`` returns empty string if nothing is + # found. With ``silent=False``, a ``FileNotFoundError`` exception is + # raised. + dec_file = basf2.find_file( + 'analysis/examples/tutorials/B2A101-Y4SEventGeneration.dec', silent=True + ) if not dec_file: dec_file = basf2.find_file('analysis/examples/simulations/B2A101-Y4SEventGeneration.dec') elif self.event_type == SimulationType.continuum: From ba6ec99cd4c7a6cf4e8cd87ea47f4fa10605db4f Mon Sep 17 00:00:00 2001 From: Michael Eliachevitch Date: Mon, 3 Apr 2023 11:39:53 +0200 Subject: [PATCH 08/14] Document changes from #193 in changelog --- CHANGELOG.md | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0cd9e20e..ec6e1520 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,23 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ## Unreleased +## Changed + +- For local basf2 versions, change how hash for `basf2_release` Parameter is calculated. Now use basf2 functionality to get the version, to be consistent with the output of `basf2 --version`. The new hash encodes both the local and central basf2 release, the basf2 function [`getCommitID`](https://github.com/belle2/basf2/blob/1c972b2c89ef11f38ee2f5ea8eb562dde0637155/framework/io/include/RootIOUtilities.h#L77-L84). Thanks to @GiacomoXT in [#193](https://github.com/nils-braun/b2luigi/issues/193). + + **Warning:** If you use local basf2 versions, that is your `basf2_release` is a git hash, this will change your b2luigi target output paths. This means that tasks that were marked _complete_, might suddenly not be _complete_ anymore after updating to this release. A workaround is to check for the new expected path via `python3 .py --show_output` and rename the `git_hash=<…>` directory. + +- Apply `max_events` Parameter not by changing the environment singleton, but instead forward it to `basf2.process` call. This should hopefully not affect the behaviour in practice. Also by @GiacomoXT in [#193](https://github.com/nils-braun/b2luigi/issues/193) + +- Refactor the basf2 related examples to use more idiomatic, modern basf2 code, e.g. using `basf2.Path()` instead of `basf2.create_path()`. . Also by @GiacomoXT in [#193](https://github.com/nils-braun/b2luigi/issues/193) + +## Fixed + +- Fix example `SimulationTask` task in `basf2_chain_example.py`, which probably wasn't warking as it was missing the Geometry module. Also by @GiacomoXT in [#193](https://github.com/nils-braun/b2luigi/issues/193) + + +**Full Changelog**: https://github.com/nils-braun/b2luigi/compare/v0.9.1...main + ## [0.9.1] - 2023-03-20 ### Fixed @@ -19,7 +36,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - Add the ability to pass a custom hashing function to parameters via the `hash_function` keyword argument. The function must take one argument, the value of the parameter. It is up to the user to ensure unique strings are created. [#189](https://github.com/nils-braun/b2luigi/pull/189) - **gbasf2**: Switch to the `--new` flag in `gb2_ds_get` which downloads files significantly faster than previously. Gbasf2 release v5r6 (November 2022) is required. [#190](https://github.com/nils-braun/b2luigi/pull/190). -**Full Changelog**: https://github.com/nils-braun/b2luigi/compare/v0.9.1...v0.9.0 +**Full Changelog**: https://github.com/nils-braun/b2luigi/compare/v0.9.0...v0.9.1 ## [0.9.0] - 2023-03-20 From cc4dfa217173f73a99e75399219df7607a5035e3 Mon Sep 17 00:00:00 2001 From: Michael Eliachevitch Date: Mon, 3 Apr 2023 11:42:09 +0200 Subject: [PATCH 09/14] Add Giacomo to contributors list --- docs/index.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/index.rst b/docs/index.rst index 3bb78b8a..d289a17e 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -136,6 +136,7 @@ Features, fixing, help and testing * Artur Gottmann (`ArturAkh`_) * Caspar Schmitt (`schmitca`_) * Marcel Hohmann (`MarcelHoh_`) + * Giacomo De Pietro (`GiacomoXT_`) Stolen ideas * Implementation of SGE batch system (`sge`_). @@ -159,6 +160,7 @@ Stolen ideas .. _`mschnepf`: https://github.com/mschnepf .. _`schmitca`: https://github.com/schmitca .. _`MarcelHoh`: https://github.com/MarcelHoh +.. _`GiacomoXT`: https://github.com/GiacomoXT .. _`sge`: https://github.com/spotify/luigi/blob/master/luigi/contrib/sge.py .. _`lsf`: https://github.com/spotify/luigi/pull/2373/files From 565c9ac7a727b6a896bab02d311a5418c874f0b3 Mon Sep 17 00:00:00 2001 From: Michael Eliachevitch Date: Mon, 3 Apr 2023 12:23:50 +0200 Subject: [PATCH 10/14] Revert to behaviour of returning "not_set" if basf2 is not setup Just raising errors breaks unit tests and is just a backwards incompatible behaviour. Changing it should be a separate PR, then unittests could be fixed by mocking. Also added more documentation. --- b2luigi/basf2_helper/utils.py | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/b2luigi/basf2_helper/utils.py b/b2luigi/basf2_helper/utils.py index f44eea64..6c87f87f 100644 --- a/b2luigi/basf2_helper/utils.py +++ b/b2luigi/basf2_helper/utils.py @@ -2,17 +2,24 @@ def get_basf2_git_hash(): - basf2_release = os.getenv("BELLE2_RELEASE") - - if basf2_release == "head" or basf2_release is None: + """Return name of basf2 release or if local basf2 is used its version hash. - try: - from basf2.version import get_version - basf2_hash = get_version - except ImportError: - from basf2.version import version - basf2_hash = version + The version is equivalent to the version returned by ``basf2 --version``. - basf2_release = basf2_hash() + Returns ``\"not set\"``, if no basf2 release is set and basf2 cannot be imported. + """ + basf2_release = os.getenv("BELLE2_RELEASE") - return basf2_release + if basf2_release not in ("head", None): + return basf2_release + # else if BASF2_RELEASE environment variable is not set, get version hash of + # local basf2 + try: + import basf2.version + # try both get_version method and version attribute, one of which + # should work depending on basf2 release + if hasattr(basf2.version, "get_version"): + return basf2.version.get_version() + return basf2.version.version + except ImportError: + return "not_set" From 0180a725ed8d2ee6ae7f8b2f5a5f13dbfbe39419 Mon Sep 17 00:00:00 2001 From: Michael Eliachevitch Date: Mon, 3 Apr 2023 12:33:31 +0200 Subject: [PATCH 11/14] Warn when get_basf2_git_hash returns "not_set" --- b2luigi/basf2_helper/utils.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/b2luigi/basf2_helper/utils.py b/b2luigi/basf2_helper/utils.py index 6c87f87f..662744a8 100644 --- a/b2luigi/basf2_helper/utils.py +++ b/b2luigi/basf2_helper/utils.py @@ -1,4 +1,5 @@ import os +import warnings def get_basf2_git_hash(): @@ -21,5 +22,9 @@ def get_basf2_git_hash(): if hasattr(basf2.version, "get_version"): return basf2.version.get_version() return basf2.version.version - except ImportError: + except ImportError as err: + warnings.warn( + f"No basf2 was found. Setting basf2 git hash to \"not_set\": \n {err}", + category=ImportWarning, + ) return "not_set" From 374944c69bf3d5acce702bfba89d107835aee679 Mon Sep 17 00:00:00 2001 From: Michael Eliachevitch Date: Mon, 3 Apr 2023 14:55:56 +0200 Subject: [PATCH 12/14] Add simple tests for `get_basf2_git_hash` Still didn't test the cases for local development version, where basf2 needs to be imported --- tests/basf2_helper/__init__.py | 0 tests/basf2_helper/test_utils.py | 26 ++++++++++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 tests/basf2_helper/__init__.py create mode 100644 tests/basf2_helper/test_utils.py diff --git a/tests/basf2_helper/__init__.py b/tests/basf2_helper/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/basf2_helper/test_utils.py b/tests/basf2_helper/test_utils.py new file mode 100644 index 00000000..12ab26be --- /dev/null +++ b/tests/basf2_helper/test_utils.py @@ -0,0 +1,26 @@ +import os +from unittest import TestCase +from unittest.mock import patch + +from b2luigi.basf2_helper.utils import get_basf2_git_hash + + +class TestGetBasf2GitHash(TestCase): + def test_return_no_set(self): + """ + On CI systems no basf2 is installed or set up, so ``get_basf2_git_hash`` + should return \"not set\". + """ + self.assertEqual(get_basf2_git_hash(), "not_set") + + def test_return_no_set_warning(self): + """ + On CI systems no basf2 is installed or set up, so ``get_basf2_git_hash`` + should print an ``ImportWarning``. + """ + with self.assertWarns(ImportWarning): + get_basf2_git_hash() + + @patch.dict(os.environ, {"BELLE2_RELEASE": "belle2_release_xy"}) + def test_belle2_release_env_is_set(self): + self.assertEqual(get_basf2_git_hash(), "belle2_release_xy") From beaa520f688708e74cf5f0a24726c4804af2807e Mon Sep 17 00:00:00 2001 From: Michael Eliachevitch Date: Mon, 3 Apr 2023 15:23:09 +0200 Subject: [PATCH 13/14] Add unittests mocking basf2.version --- tests/basf2_helper/test_utils.py | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/tests/basf2_helper/test_utils.py b/tests/basf2_helper/test_utils.py index 12ab26be..af9ed239 100644 --- a/tests/basf2_helper/test_utils.py +++ b/tests/basf2_helper/test_utils.py @@ -1,4 +1,7 @@ import os +import sys +import warnings + from unittest import TestCase from unittest.mock import patch @@ -11,7 +14,9 @@ def test_return_no_set(self): On CI systems no basf2 is installed or set up, so ``get_basf2_git_hash`` should return \"not set\". """ - self.assertEqual(get_basf2_git_hash(), "not_set") + with warnings.catch_warnings(): + warnings.simplefilter("ignore", category=ImportWarning) + self.assertEqual(get_basf2_git_hash(), "not_set") def test_return_no_set_warning(self): """ @@ -24,3 +29,28 @@ def test_return_no_set_warning(self): @patch.dict(os.environ, {"BELLE2_RELEASE": "belle2_release_xy"}) def test_belle2_release_env_is_set(self): self.assertEqual(get_basf2_git_hash(), "belle2_release_xy") + + def test_basf2_hash_from_get_version(self): + "In older basf2 releases we get version from ``basf2.version.get_version``." + class MockVersion: + @staticmethod + def get_version(): + return "some_basf2_version" + + class MockBasf2: + version = MockVersion + + with patch.dict(sys.modules, {"basf2": MockBasf2, "basf2.version": MockVersion}): + self.assertEqual(get_basf2_git_hash(), "some_basf2_version") + + def test_basf2_hash_from_version_property(self): + "In newer basf2 releases we get version from ``basf2.version.version``." + + class MockVersion: + version = "another_basf2_version" + + class MockBasf2: + version = MockVersion + + with patch.dict(sys.modules, {"basf2": MockBasf2, "basf2.version": MockVersion}): + self.assertEqual(get_basf2_git_hash(), "another_basf2_version") From 40d16b8a6c816532feb751f546e478c01b4611e9 Mon Sep 17 00:00:00 2001 From: Michael Eliachevitch Date: Mon, 3 Apr 2023 15:26:08 +0200 Subject: [PATCH 14/14] Update changelog --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ec6e1520..a47dd020 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ## Changed -- For local basf2 versions, change how hash for `basf2_release` Parameter is calculated. Now use basf2 functionality to get the version, to be consistent with the output of `basf2 --version`. The new hash encodes both the local and central basf2 release, the basf2 function [`getCommitID`](https://github.com/belle2/basf2/blob/1c972b2c89ef11f38ee2f5ea8eb562dde0637155/framework/io/include/RootIOUtilities.h#L77-L84). Thanks to @GiacomoXT in [#193](https://github.com/nils-braun/b2luigi/issues/193). +- For local basf2 versions, change how hash for `basf2_release` Parameter is calculated. Now use basf2 functionality to get the version, to be consistent with the output of `basf2 --version`. The new hash encodes both the local and central basf2 release, the basf2 function [`getCommitID`](https://github.com/belle2/basf2/blob/1c972b2c89ef11f38ee2f5ea8eb562dde0637155/framework/io/include/RootIOUtilities.h#L77-L84). When basf2 is not set up, print warning before returning `"not_set"`. Thanks to @GiacomoXT in [#193](https://github.com/nils-braun/b2luigi/issues/193). **Warning:** If you use local basf2 versions, that is your `basf2_release` is a git hash, this will change your b2luigi target output paths. This means that tasks that were marked _complete_, might suddenly not be _complete_ anymore after updating to this release. A workaround is to check for the new expected path via `python3 .py --show_output` and rename the `git_hash=<…>` directory. @@ -20,7 +20,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ## Fixed -- Fix example `SimulationTask` task in `basf2_chain_example.py`, which probably wasn't warking as it was missing the Geometry module. Also by @GiacomoXT in [#193](https://github.com/nils-braun/b2luigi/issues/193) +- Fix example `SimulationTask` task in `basf2_chain_example.py`, which probably wasn't working as it was missing the Geometry module. Also by @GiacomoXT in [#193](https://github.com/nils-braun/b2luigi/issues/193) **Full Changelog**: https://github.com/nils-braun/b2luigi/compare/v0.9.1...main