From 5958bb133e02378b9f2fbb54f7794d5844558252 Mon Sep 17 00:00:00 2001 From: jose-luis-rs Date: Fri, 30 Aug 2024 23:16:06 +0200 Subject: [PATCH] Changed CI-CD compilation to jan24p1 Update list of Authors Added zenodo DOI Minor Added zenodo DOI gROOT->Reset() for create_califa_geo.C Changed CMakeLists.txt --- .github/actions/pre-build/action.yml | 4 +- .github/workflows/check_metadata.yaml | 29 ++++ .zenodo.json | 189 ++++++++++++++++++++++++++ AUTHORS | 8 +- CONTRIBUTORS | 1 - README.md | 2 +- califa/geobase/CMakeLists.txt | 12 +- califa/geobase/create_califa_geo.C | 1 + codemeta.json | 26 ++-- codemeta_update.py | 81 ----------- meta_update.py | 156 +++++++++++++++++++++ 11 files changed, 406 insertions(+), 103 deletions(-) create mode 100644 .github/workflows/check_metadata.yaml create mode 100644 .zenodo.json delete mode 100755 codemeta_update.py create mode 100755 meta_update.py diff --git a/.github/actions/pre-build/action.yml b/.github/actions/pre-build/action.yml index a35c9a7de..fb8b40e80 100644 --- a/.github/actions/pre-build/action.yml +++ b/.github/actions/pre-build/action.yml @@ -8,9 +8,9 @@ runs: run: | git config --global --add safe.directory $GITHUB_WORKSPACE echo "UCESB_DIR=$GITHUB_WORKSPACE/ucesb/" >> $GITHUB_ENV - export SIMPATH=${CVMDIR}/debian10/fairsoft/nov22p1 + export SIMPATH=${CVMDIR}/debian10/fairsoft/jan24p1 echo "SIMPATH=${SIMPATH}" >> $GITHUB_ENV - echo "FAIRROOTPATH=${CVMDIR}/debian10/fairroot/v18.8.0_fs_nov22p1" >> $GITHUB_ENV + echo "FAIRROOTPATH=${CVMDIR}/debian10/fairroot/v18.8.2_jan24p1" >> $GITHUB_ENV echo "${SIMPATH}/bin" >> $GITHUB_PATH # variables for ccache echo "CCACHE_BASEDIR=${GITHUB_WORKSPACE}" >> $GITHUB_ENV diff --git a/.github/workflows/check_metadata.yaml b/.github/workflows/check_metadata.yaml new file mode 100644 index 000000000..024d4cc89 --- /dev/null +++ b/.github/workflows/check_metadata.yaml @@ -0,0 +1,29 @@ +# SPDX-FileCopyrightText: 2024 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH, Darmstadt, Germany +# +# SPDX-License-Identifier: CC0-1.0 + +name: Check AUTHORS and CONTRIBUTORS in metadata + +on: + push: + paths: + - AUTHORS + - CONTRIBUTORS + - codemeta.json + - .zenodo.json + pull_request: + paths: + - AUTHORS + - CONTRIBUTORS + - codemeta.json + - .zenodo.json + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Try updating metadata + run: python meta_update.py + - name: Check for Updates + run: git diff --exit-code diff --git a/.zenodo.json b/.zenodo.json new file mode 100644 index 000000000..40a3fbe8d --- /dev/null +++ b/.zenodo.json @@ -0,0 +1,189 @@ +{ + "creators": [ + { + "name": "Al-Turany, Mohammad", + "orcid": "0000-0002-8071-4497" + }, + { + "name": "Alvarez Pol, Hector", + "orcid": "0000-0001-9643-6252" + }, + { + "name": "Heil, Michael" + }, + { + "name": "Kresan, Dmytro", + "orcid": "0000-0002-7537-2875" + }, + { + "name": "Mayer, Jan" + }, + { + "name": "Rodriguez Sanchez, Jose Luis", + "orcid": "0000-0002-4702-5294" + }, + { + "name": "Wagner, Vadim" + } + ], + "contributors": [ + { + "type": "Other", + "name": "Boretzky, Konstanze" + }, + { + "type": "Other", + "name": "Cabanelas, Pablo" + }, + { + "type": "Other", + "name": "Chatillon, Audrey" + }, + { + "type": "Other", + "name": "Douma, Christiaan" + }, + { + "type": "Other", + "name": "Falduto, Ashton" + }, + { + "type": "Other", + "name": "Feijoo, Martina" + }, + { + "type": "Other", + "name": "Galiana, Elisabet" + }, + { + "type": "Other", + "name": "Garcia, Gabriel" + }, + { + "type": "Other", + "name": "Gasparic, Igor" + }, + { + "type": "Other", + "name": "Gra\u00f1a, Antia" + }, + { + "type": "Other", + "name": "Johansson, H\u00e5kan" + }, + { + "type": "Other", + "name": "Heiss, Benjamin" + }, + { + "type": "Other", + "name": "Horvat, Andrea" + }, + { + "type": "Other", + "name": "Inglessi, Alexander" + }, + { + "type": "Other", + "name": "Kelic-Heil, Aleksandra" + }, + { + "type": "Other", + "name": "Klenze, Philipp" + }, + { + "type": "Other", + "name": "Kripko, Aron" + }, + { + "type": "Other", + "name": "Kudaibergenova, Eleonora" + }, + { + "type": "Other", + "name": "Labiche, Marc" + }, + { + "type": "Other", + "name": "Lagni, Andrea" + }, + { + "type": "Other", + "name": "Lihtar, Ivana" + }, + { + "type": "Other", + "name": "Loeher, Bastian" + }, + { + "type": "Other", + "name": "Milhomens da Fonseca, Leandro" + }, + { + "type": "Other", + "name": "Mozumdar, Nikhil" + }, + { + "type": "Other", + "name": "Panin, Valerii" + }, + { + "type": "Other", + "name": "Plag, Ralf" + }, + { + "type": "Other", + "name": "Ponnath, Lukas" + }, + { + "type": "Other", + "name": "Rybalchenko, Alexey" + }, + { + "type": "Other", + "name": "Storck, Sonja" + }, + { + "type": "Other", + "name": "Syndikus, Ina" + }, + { + "type": "Other", + "name": "Taniuchi, Ryo" + }, + { + "type": "Other", + "name": "Tscheuschner, Joachim" + }, + { + "type": "Other", + "name": "Wang, Yanzhao" + }, + { + "type": "Other", + "name": "Whitehead, Matthew" + }, + { + "type": "Other", + "name": "Wongel, Alicia" + }, + { + "type": "Other", + "name": "Xarepe, Manuel" + }, + { + "type": "Other", + "name": "Zanetti, Lorenzo" + } + ], + "description": "The R3BRoot software is based on the FairRoot framework and can be used to perform Monte Carlo simulations and experimental data analysis of the R3B (Reactions with Relativistic Radioactive Beams) nuclear physics experiments at the GSI-FAIR research center (Facility for Antiproton and Ion Research). The user can create simulated data and/or perform analysis with the same framework. Geant3 and Geant4 transport engines are supported, however, the implemented tasks that create simulated data do not depend on a particular Monte Carlo engine. The framework delivers base classes which enable the users to construct their detectors and/or analysis tasks in a simple way, it also delivers some general functionality like track visualization. Moreover, an interface for reading experimental and/or simulated magnetic field maps is also implemented.", + "related_identifiers": [ + { + "identifier": "https://github.com/R3BRootGroup/R3BRoot/", + "relation": "isSupplementTo", + "resource_type": "software", + "scheme": "url" + } + ], + "title": "R3BRoot" +} diff --git a/AUTHORS b/AUTHORS index ee7a26c3a..e074a2a82 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,7 +1,7 @@ -Al-Turany, Mohammad -Alvarez Pol, Hector +Al-Turany, Mohammad [https://orcid.org/0000-0002-8071-4497] +Alvarez Pol, Hector [https://orcid.org/0000-0001-9643-6252] Heil, Michael -Kresan, Dmytro +Kresan, Dmytro [https://orcid.org/0000-0002-7537-2875] Mayer, Jan -Rodriguez Sanchez, Jose Luis +Rodriguez Sanchez, Jose Luis [https://orcid.org/0000-0002-4702-5294] Wagner, Vadim diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 62948dbd1..2e5069324 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -35,4 +35,3 @@ Whitehead, Matthew Wongel, Alicia Xarepe, Manuel Zanetti, Lorenzo - diff --git a/README.md b/README.md index a106d4366..e66d60096 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# R3BRoot Software [![license](https://alfa-ci.gsi.de/shields/badge/license-GPL--3.0-orange.svg)](COPYRIGHT) +# R3BRoot Software [![license](https://alfa-ci.gsi.de/shields/badge/license-GPL--3.0-orange.svg)](COPYRIGHT) [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.3896282.svg)](https://doi.org/10.5281/zenodo.12193515) [![CI-CD](https://github.com/R3BRootGroup/R3BRoot/actions/workflows/main.yml/badge.svg)](https://github.com/R3BRootGroup/R3BRoot/actions/workflows/main.yml) [![Static Analysis](https://github.com/R3BRootGroup/R3BRoot/actions/workflows/static_analysis.yml/badge.svg)](https://github.com/R3BRootGroup/R3BRoot/actions/workflows/static_analysis.yml) [![Validate Codemeta](https://github.com/R3BRootGroup/R3BRoot/actions/workflows/codemeta_validate.yaml/badge.svg)](https://github.com/R3BRootGroup/R3BRoot/actions/workflows/codemeta_validate.yaml) [![Cleanup Caches on PR Close](https://github.com/R3BRootGroup/R3BRoot/actions/workflows/cleanup_cache.yml/badge.svg)](https://github.com/R3BRootGroup/R3BRoot/actions/workflows/cleanup_cache.yml) diff --git a/califa/geobase/CMakeLists.txt b/califa/geobase/CMakeLists.txt index 7e9d546a6..b1c4bf4ca 100644 --- a/califa/geobase/CMakeLists.txt +++ b/califa/geobase/CMakeLists.txt @@ -11,6 +11,12 @@ # or submit itself to any jurisdiction. # ############################################################################## +generate_root_test_script(${R3BROOT_SOURCE_DIR}/califa/geobase/create_califa_geo.C) +add_test(NAME CalifaRootGeometry COMMAND ${R3BROOT_BINARY_DIR}/califa/geobase/create_califa_geo.sh) +set_tests_properties(CalifaRootGeometry PROPERTIES TIMEOUT "2000") +set_tests_properties(CalifaRootGeometry PROPERTIES PASS_REGULAR_EXPRESSION + "Macro finished successfully.") + if(NOT EXISTS "${R3BROOT_SOURCE_DIR}/geometry/califa_v2019.11.geo.root") message(STATUS "Starting to generate the standard root geometry v2019.11 for CALIFA") execute_process(COMMAND root -l -q -x "${R3BROOT_SOURCE_DIR}/califa/geobase/create_califa_geo.C(1)") @@ -42,9 +48,3 @@ message(STATUS "${BYellow}Full CALIFA standard root geometry has been created${C else(NOT EXISTS "${R3BROOT_SOURCE_DIR}/geometry/califa_full.geo.root") message(STATUS "${BYellow}Full CALIFA standard root geometry already exists${CR} ") endif(NOT EXISTS "${R3BROOT_SOURCE_DIR}/geometry/califa_full.geo.root") - -generate_root_test_script(${R3BROOT_SOURCE_DIR}/califa/geobase/create_califa_geo.C) -add_test(NAME CalifaRootGeometry COMMAND ${R3BROOT_BINARY_DIR}/califa/geobase/create_califa_geo.sh) -set_tests_properties(CalifaRootGeometry PROPERTIES TIMEOUT "2000") -set_tests_properties(CalifaRootGeometry PROPERTIES PASS_REGULAR_EXPRESSION - "Macro finished successfully.") diff --git a/califa/geobase/create_califa_geo.C b/califa/geobase/create_califa_geo.C index 7e62d4ff3..dcd5bc407 100644 --- a/califa/geobase/create_califa_geo.C +++ b/califa/geobase/create_califa_geo.C @@ -1575,6 +1575,7 @@ Bool_t isCrystalInstalled(Int_t alvType, Int_t alveolusCopy, Int_t instCry[]) void create_califa_geo(const int index = 0) { + gROOT->Reset(); if (index == 1) { create_califa_geo_selector("s467"); diff --git a/codemeta.json b/codemeta.json index 9d7346594..04a7b6f33 100644 --- a/codemeta.json +++ b/codemeta.json @@ -6,11 +6,11 @@ "contIntegration": "https://github.com/R3BRootGroup/R3BRoot/actions", "dateCreated": "2009-04-14", "datePublished": "2009-08-01", - "dateModified": "2023-11-04", - "downloadUrl": "https://github.com/R3BRootGroup/R3BRoot/archive/refs/tags/nov23.tar.gz", + "dateModified": "2024-12-05", + "downloadUrl": "https://github.com/R3BRootGroup/R3BRoot/archive/refs/tags/dec24.tar.gz", "issueTracker": "https://github.com/R3BRootGroup/R3BRoot/issues", "name": "R3BRoot", - "softwareVersion": "nov23", + "softwareVersion": "dec24", "description": "Software for simulations and data analysis of Reactions with Relativistic Radioactive Beams experiment at FAIR", "readme": "https://github.com/R3BRootGroup/R3BRoot/blob/dev/README.md", "releaseNotes": "", @@ -43,13 +43,15 @@ "maintainer": { "@type": "Person", "givenName": "Jose Luis", - "familyName": "Rodriguez Sanchez" + "familyName": "Rodriguez Sanchez", + "@id": "https://orcid.org/0000-0002-4702-5294" }, "author": [ { "@type": "Person", "givenName": "Hector", - "familyName": "Alvarez Pol" + "familyName": "Alvarez Pol", + "@id": "https://orcid.org/0000-0001-9643-6252" }, { "@type": "Person", @@ -59,7 +61,8 @@ { "@type": "Person", "givenName": "Dmytro", - "familyName": "Kresan" + "familyName": "Kresan", + "@id": "https://orcid.org/0000-0002-7537-2875" }, { "@type": "Person", @@ -69,7 +72,8 @@ { "@type": "Person", "givenName": "Jose Luis", - "familyName": "Rodriguez Sanchez" + "familyName": "Rodriguez Sanchez", + "@id": "https://orcid.org/0000-0002-4702-5294" }, { "@type": "Person", @@ -79,7 +83,8 @@ { "@type": "Person", "givenName": "Mohammad", - "familyName": "Al-Turany" + "familyName": "Al-Turany", + "@id": "https://orcid.org/0000-0002-8071-4497" } ], "contributor": [ @@ -248,6 +253,11 @@ "givenName": "Lorenzo", "familyName": "Zanetti" }, + { + "@type": "Person", + "givenName": "Matthew", + "familyName": "Whitehead" + }, { "@type": "Person", "givenName": "Konstanze", diff --git a/codemeta_update.py b/codemeta_update.py deleted file mode 100755 index d7c98eb7d..000000000 --- a/codemeta_update.py +++ /dev/null @@ -1,81 +0,0 @@ -#! /usr/bin/env python3 -# Copyright (C) 2019 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH -# -# SPDX-License-Identifier: LGPL-3.0-or-later - -import argparse -import json -import re -from collections import OrderedDict - -class CodeMetaManipulator(object): - def load(self, filename='codemeta.json'): - with open(filename, 'rb') as fp: - self.data = json.load(fp, object_pairs_hook=OrderedDict) - - @staticmethod - def _dict_entry_cmp(dict1, dict2, field): - if (field in dict1) and (field in dict2): - return dict1[field] == dict2[field] - else: - return False - - @classmethod - def find_person_entry(cls, person_list, matchdict): - for entry in person_list: - if cls._dict_entry_cmp(entry, matchdict, 'email'): - return entry - if cls._dict_entry_cmp(entry, matchdict, 'familyName') \ - and cls._dict_entry_cmp(entry, matchdict, 'givenName'): - return entry - return None - - @staticmethod - def update_person_entry(entry, matchdict): - if entry is None: - entry = OrderedDict() - entry['@type'] = 'Person' - for field in ('givenName', 'familyName', 'email'): - val = matchdict.get(field, None) - if val is not None: - entry[field] = val - return entry - - def handle_person_list_file(self, filename, cm_field_name): - fp = open(filename, 'r', encoding='utf8') - findregex = re.compile(r'^(?P[-\w\s]*[-\w]),\s*' - r'(?P[-\w\s]*[-\w])\s*' - r'(?:<(?P\S+@\S+)>)?$') - person_list = self.data.setdefault(cm_field_name, []) - for line in fp: - line = line.strip() - m = findregex.match(line) - if m is None: - raise RuntimeError("Could not analyze line %r" % line) - found_entry = self.find_person_entry(person_list, m.groupdict()) - entry = self.update_person_entry(found_entry, m.groupdict()) - if found_entry is None: - person_list.append(entry) - - def save(self, filename='codemeta.json'): - with open('codemeta.json', 'w', encoding='utf8') as fp: - json.dump(self.data, fp, indent=2) - fp.write('\n') - - -def main(): - parser = argparse.ArgumentParser(description='Update codemeta.json') - parser.add_argument('--set-version', dest='newversion') - args = parser.parse_args() - - cm = CodeMetaManipulator() - cm.load() - if args.newversion is not None: - cm.data['softwareVersion'] = args.newversion - cm.handle_person_list_file('AUTHORS', 'author') - cm.handle_person_list_file('CONTRIBUTORS', 'contributor') - cm.save() - - -if __name__ == '__main__': - main() diff --git a/meta_update.py b/meta_update.py new file mode 100755 index 000000000..b4a76d96e --- /dev/null +++ b/meta_update.py @@ -0,0 +1,156 @@ +#! /usr/bin/env python3 +# Copyright (C) 2019-2024 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH +# +# SPDX-License-Identifier: LGPL-3.0-or-later + +from argparse import ArgumentParser +import json +import re +from collections import OrderedDict + + +class Manipulator(object): + def __str__(self): + return self.__class__.__name__ + + def load(self, filename=None): + if filename is None: + filename = self.default_filename + with open(filename, 'rb') as fp: + self.data = json.load(fp, object_pairs_hook=OrderedDict) + + def save(self, filename=None, indent=2): + if filename is None: + filename = self.default_filename + with open(filename, 'w', encoding='utf8') as fp: + json.dump(self.data, fp, indent=indent) + fp.write('\n') + + @staticmethod + def _dict_entry_cmp(dict1, dict2, field1, field2=None): + if field2 is None: + field2 = field1 + if (field1 in dict1) and (field2 in dict2): + return dict1[field1] == dict2[field2] + else: + return False + + def _handle_person_list_file(self, filename, field_name, **kwargs): + fp = open(filename, 'r', encoding='utf8') + person_list = self.data.setdefault(field_name, []) + for i, line in enumerate(fp, start=0): + line = line.strip() + m = self.findregex.match(line) + if m is None: + raise RuntimeError("Could not analyze line %r" % line) + found_entry = self._find_person_entry(person_list, m.groupdict()) + entry = self.update_person_entry(found_entry, m.groupdict(), + **kwargs) + if found_entry is None: + person_list.insert(i, entry) + + +class CodeMetaManipulator(Manipulator): + default_filename = 'codemeta.json' + findregex = re.compile(r'^(?P[-\w\s]*[-\w]),\s*' + r'(?P[-\w\s]*[-\w])\s*' + r'(?:<(?P\S+@\S+)>)?\s*' + r'(\[(?P\S+)\])?$') + + @classmethod + def _find_person_entry(cls, person_list, matchdict): + # orcid is unique + for entry in person_list: + if cls._dict_entry_cmp(entry, matchdict, '@id', 'orcid'): + return entry + for entry in person_list: + if cls._dict_entry_cmp(entry, matchdict, 'email'): + return entry + if cls._dict_entry_cmp(entry, matchdict, 'familyName') \ + and cls._dict_entry_cmp(entry, matchdict, 'givenName'): + return entry + return None + + @staticmethod + def update_person_entry(entry, matchdict): + if entry is None: + entry = OrderedDict() + entry['@type'] = 'Person' + for field in ('orcid', 'givenName', 'familyName', 'email'): + val = matchdict.get(field, None) + if val is not None: + if field == 'orcid': + entry['@id'] = val + else: + entry[field] = val + return entry + + def update_authors(self): + self._handle_person_list_file('AUTHORS', 'author') + self._handle_person_list_file('CONTRIBUTORS', 'contributor') + + def version(self, new_version): + self.data['softwareVersion'] = new_version + + +class ZenodoManipulator(Manipulator): + default_filename = '.zenodo.json' + findregex = re.compile(r'^(?P[-\w\s,]*[-\w])\s*' + r'(?:<(?P\S+@\S+)>)?\s*' + r'(\[https://orcid\.org/(?P\S+)\])?$') + + @classmethod + def _find_person_entry(cls, person_list, matchdict): + # Match on orcid first + for entry in person_list: + if cls._dict_entry_cmp(entry, matchdict, 'orcid'): + return entry + for entry in person_list: + if cls._dict_entry_cmp(entry, matchdict, 'name'): + return entry + return None + + @staticmethod + def update_person_entry(entry, matchdict, contributor_type=None): + if entry is None: + entry = OrderedDict() + if contributor_type: + entry['type'] = contributor_type + for field in ('name', 'orcid'): + val = matchdict.get(field, None) + if val is not None: + entry[field] = val + return entry + + def update_authors(self): + self._handle_person_list_file('AUTHORS', 'creators') + self._handle_person_list_file('CONTRIBUTORS', 'contributors', + contributor_type='Other') + + def save(self, filename=None): + super().save(filename, 4) + + def version(self, new_version): + self.data['version'] = new_version + + +def main(): + parser = ArgumentParser(description='Update codemeta.json and ' + '.zenodo.json') + parser.add_argument('--set-version', dest='newversion') + args = parser.parse_args() + + for manipulator in (CodeMetaManipulator(), ZenodoManipulator()): + try: + manipulator.load() + except FileNotFoundError as e: + print('*** Skipping {}: {}'.format(manipulator, e)) + continue + if args.newversion is not None: + manipulator.version(args.newversion) + manipulator.update_authors() + manipulator.save() + + +if __name__ == '__main__': + main()