diff --git a/CITATION.cff b/CITATION.cff index 2d899b4f..be273e38 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -65,19 +65,19 @@ authors: - affiliation: SMHI family-names: Raspaud given-names: Martin -- affiliation: Excalibur Laboratories Inc - family-names: Horne - given-names: Randy - affiliation: University of Reading family-names: Blower given-names: Jon +- affiliation: Excalibur Laboratories Inc + family-names: Horne + given-names: Randy - affiliation: University of Texas family-names: Whiteaker given-names: Timothy - affiliation: USGS family-names: Blodgett given-names: David -- affiliation: UC Irvine +- affiliation: University of California, Irvine family-names: Zender given-names: Charlie - affiliation: EUMETSAT @@ -112,7 +112,7 @@ authors: - affiliation: Puertos del Estado, Madrid family-names: Manzano given-names: Fernando -- affiliation: SMHI +- affiliation: SMHI Rossby Centre, Swedish Meteorological and Hydrological Institute family-names: "B\xE4rring" given-names: Lars orcid: 0000-0001-7280-2502 diff --git a/Makefile b/Makefile index 2612f79c..a8af2434 100644 --- a/Makefile +++ b/Makefile @@ -80,6 +80,9 @@ about-authors.adoc: authors.adoc scripts/update_authors.py zenodo.json: authors.adoc scripts/update_authors.py python3 scripts/update_authors.py --authors-adoc=authors.adoc --update-zenodo=zenodo.json + +CITATION.cff: authors.adoc scripts/update_authors.py + python3 scripts/update_authors.py --authors-adoc=authors.adoc --update-citation=CITATION.cff $(BUILD_DIR): mkdir -vp $(BUILD_DIR) diff --git a/scripts/update_authors.py b/scripts/update_authors.py index bb1bda02..75ef74c3 100755 --- a/scripts/update_authors.py +++ b/scripts/update_authors.py @@ -2,11 +2,12 @@ """ This script parses the authors.adoc file to extract author metadata, update the -"creators" section in the zenodo.json file, and generate the about-authors.adoc file. +"creators" section in the zenodo.json file, update CITATION.cff and generate the about-authors.adoc file. Purpose: 1. Extracts authors' names, affiliations, and ORCID from authors.adoc. 2. Updates the "creators" section in the zenodo.json file with formatted author names. + 2. Updates the CITATION.cff file. 3. Generates the about-authors.adoc file to list original and additional authors. Authors.adoc Format: @@ -36,13 +37,15 @@ import sys import os import argparse +import yaml def parse_authors_adoc(authors_adoc_path): """Parses the authors.adoc file to extract author metadata.""" print(f"Parsing authors from: {authors_adoc_path}") authors = {"original": [], "additional": []} creators = [] - + citation_authors = [] + if not os.path.exists(authors_adoc_path): print(f"Error: {authors_adoc_path} does not exist.") sys.exit(1) @@ -60,16 +63,20 @@ def parse_authors_adoc(authors_adoc_path): name_parts = name_match.group(1).split('{nbsp}') if len(name_parts) == 2: # FirstName LastName first_name, last_name = name_parts + given_names = first_name full_name = f"{first_name} {last_name}" zenodo_name = f"{last_name}, {first_name}" elif len(name_parts) == 3: # FirstName MiddleName LastName first_name, middle_name, last_name = name_parts + given_names = f"{first_name} {middle_name}" full_name = f"{first_name} {middle_name} {last_name}" zenodo_name = f"{last_name}, {first_name} {middle_name}" else: full_name = name_match.group(1).replace('{nbsp}', ' ') zenodo_name = name_match.group(1).replace('{nbsp}', ' ') + author_data['family-names'] = last_name + author_data['given-names'] = given_names author_data['name'] = full_name author_data['zenodo_name'] = zenodo_name @@ -93,11 +100,18 @@ def parse_authors_adoc(authors_adoc_path): author_entry = f"{author_data['name']}, {author_data['affiliation']}" authors['original' if re.search(rf':author_{author_id}_type: original', content) else 'additional'].append(author_entry) + + citation_authors.append({ + "affiliation": author_data['affiliation'], + "family-names": author_data['family-names'], + "given-names": author_data['given-names'], + **({"orcid": author_data['orcid']} if 'orcid' in author_data else {}) + }) else: print(f"Warning: Missing name or affiliation for author_{author_id}") - print(f"Total authors processed: {len(creators)} (Original: {len(authors['original'])}, Additional: {len(authors['additional'])})") - return authors, creators + #print(f"Total authors processed: {len(creators)} (Original: {len(authors['original'])}, Additional: {len(authors['additional'])})") + return authors, creators, citation_authors def generate_about_authors(adoc_output_path, authors): @@ -110,10 +124,10 @@ def generate_about_authors(adoc_output_path, authors): for author in authors['additional']: content += f"* {author}\n" - print(f"Writing about-authors.adoc to: {adoc_output_path}") + #print(f"Writing about-authors.adoc to: {adoc_output_path}") with open(adoc_output_path, 'w') as file: file.write(content) - print(f"about-authors.adoc file written successfully with {len(authors['original'])} original authors and {len(authors['additional'])} additional authors.") + print(f"{adoc_output_path} file written successfully with {len(authors['original'])} original authors and {len(authors['additional'])} additional authors.") def update_zenodo_json(zenodo_json_path, creators): @@ -122,7 +136,7 @@ def update_zenodo_json(zenodo_json_path, creators): print(f"Error: {zenodo_json_path} does not exist.") sys.exit(1) - print(f"Updating zenodo.json file: {zenodo_json_path}") + #print(f"Updating zenodo.json file: {zenodo_json_path}") with open(zenodo_json_path, 'r') as file: zenodo_data = json.load(file) @@ -130,8 +144,24 @@ def update_zenodo_json(zenodo_json_path, creators): with open(zenodo_json_path, 'w') as file: json.dump(zenodo_data, file, indent=2) - print(f"zenodo.json file updated successfully with {len(creators)} authors.") + print(f"{zenodo_json_path} file updated successfully with {len(creators)} authors.") +def update_citation_cff(citation_cff_path, citation_authors): + """Updates the authors section of the CITATION.cff file.""" + if not os.path.exists(citation_cff_path): + print(f"Error: {citation_cff_path} does not exist.") + sys.exit(1) + + #print(f"Updating CITATION.cff file: {citation_cff_path}") + with open(citation_cff_path, 'r') as file: + citation_data = yaml.safe_load(file) + + citation_data['authors'] = citation_authors + + with open(citation_cff_path, 'w') as file: + yaml.dump(citation_data, file, default_flow_style=False, sort_keys=False, indent=2) + + print(f"{citation_cff_path} file updated successfully with {len(citation_authors)} authors.") def main(): parser = argparse.ArgumentParser( @@ -141,15 +171,17 @@ def main(): parser.add_argument('--authors-adoc', default='authors.adoc', metavar='AUTHORS_ADOC_FILE', help='Path to the authors.adoc file (default: authors.adoc)') parser.add_argument('--update-zenodo', nargs='?', const='zenodo.json', metavar='ZENODO_FILE', help='Path to the zenodo.json file (default: zenodo.json)') parser.add_argument('--write-about-authors', nargs='?', const='about-authors.adoc', metavar='ABOUT_AUTHORS_FILE', help='Path to the about-authors.adoc file (default: about-authors.adoc)') + parser.add_argument('--update-citation', nargs='?', const='CITATION.cff', metavar='CITATION_FILE', help='Path to the CITATION.cff file (default: CITATION.cff)') args = parser.parse_args() - print("Starting author update process...") - print(f"Authors file: {args.authors_adoc}") - print(f"Zenodo JSON file: {args.update_zenodo}") - print(f"About Authors file: {args.write_about_authors}") +# print("Starting author update process...") +# print(f"Authors file: {args.authors_adoc}") +# print(f"Zenodo JSON file: {args.update_zenodo}") +# print(f"About-Authors file: {args.write_about_authors}") +# print(f"Citation CFF file: {args.write_about_authors}") - authors, creators = parse_authors_adoc(args.authors_adoc) + authors, creators, citation_authors = parse_authors_adoc(args.authors_adoc) if args.write_about_authors: generate_about_authors(args.write_about_authors, authors) @@ -157,16 +189,20 @@ def main(): if args.update_zenodo: update_zenodo_json(args.update_zenodo, creators) - print("\n--- Summary of Changes ---") - print(f"Total authors processed: {len(creators)}") - print(f"Original Authors: {len(authors['original'])}") - print(f"Additional Authors: {len(authors['additional'])}") - if args.write_about_authors: - print(f"about-authors.adoc updated at: {args.write_about_authors}") - if args.update_zenodo: - print(f"zenodo.json updated at: {args.update_zenodo}") - print("\n--- End of Summary ---") - + if args.update_citation: + update_citation_cff(args.update_citation, citation_authors) + +# print("\n--- Summary of Changes ---") +# print(f"Total authors processed: {len(creators)}") +# print(f"Original Authors: {len(authors['original'])}") +# print(f"Additional Authors: {len(authors['additional'])}") +# if args.write_about_authors: +# print(f"About-Authors updated at: {args.write_about_authors}") +# if args.update_zenodo: +# print(f"Zenodo JSON updated at: {args.update_zenodo}") +# if args.update_citation: +# print(f"Citation CFF updated at: {args.update_zenodo}") +# print("\n--- End of Summary ---") if __name__ == "__main__": main() diff --git a/zenodo.json b/zenodo.json index 66deaa0f..fb1cbfd1 100644 --- a/zenodo.json +++ b/zenodo.json @@ -4,44 +4,149 @@ "description": "

This document describes the CF conventions for climate and forecast metadata designed to promote the processing and sharing of files created with the netCDF Application Programmer Interface. The conventions define metadata that provide a definitive description of what the data in each variable represents, and of the spatial and temporal properties of the data. This enables users of data from different sources to decide which quantities are comparable, and facilitates building applications with powerful extraction, regridding, and display capabilities.

The CF conventions generalize and extend the COARDS conventions. The extensions include metadata that provides a precise definition of each variable via specification of a standard name, describes the vertical locations corresponding to dimensionless vertical coordinate values, and provides the spatial coordinates of non-rectilinear gridded data. Since climate and forecast data are often not simply representative of points in space/time, other extensions provide for the description of coordinate intervals, multidimensional cells and climatological time coordinates, and indicate how a data value is representative of an interval or cell. This standard also relaxes the COARDS constraints on dimension order and specifies methods for reducing the size of datasets.

", "license": "CC0-1.0", "imprint_publisher": "CF Community", - "communities": [{"identifier": "cfconventions"}], + "communities": [ + { + "identifier": "cfconventions" + } + ], "upload_type": "publication", "publication_type": "standard", "version": "1.12", "publication_date": "2024-12-04", "creators": [ - { "name": "Eaton, Brian", "affiliation": "NCAR" }, - { "name": "Gregory, Jonathan", "affiliation": "University of Reading and UK Met Office Hadley Centre", "orcid": "0000-0003-1296-8644" }, - { "name": "Drach, Bob", "affiliation": "PCMDI, LLNL" }, - { "name": "Taylor, Karl", "affiliation": "PCMDI, LLNL", "orcid": "0000-0002-6491-2135" }, - { "name": "Hankin, Steve", "affiliation": "PMEL, NOAA" }, - { "name": "Caron, John", "affiliation": "Unidata" }, - { "name": "Signell, Rich", "affiliation": "USGS" }, - { "name": "Bentley, Phil", "affiliation": "UK Met Office" }, - { "name": "Rappa, Greg", "affiliation": "MIT" }, - { "name": "Höck, Heinke", "affiliation": "DKRZ", "orcid": "0000-0002-0131-1404" }, - { "name": "Pamment, Alison", "affiliation": "NCAS and CEDA", "orcid": "0000-0001-5040-4626"}, - { "name": "Juckes, Martin", "affiliation": "NCAS" }, - { "name": "Raspaud, Martin", "affiliation": "SMHI" }, - { "name": "Blower, Jon", "affiliation": "University of Reading" }, - { "name": "Horne, Randy", "affiliation": "Excalibur Laboratories Inc" }, - { "name": "Whiteaker, Timothy", "affiliation": "University of Texas" }, - { "name": "Blodgett, David", "affiliation": "USGS" }, - { "name": "Zender, Charlie", "affiliation": "University of California, Irvine" }, - { "name": "Lee, Daniel", "affiliation": "EUMETSAT", "orcid": "0000-0002-1041-232X" }, - { "name": "Hassell, David", "affiliation": "NCAS and University of Reading", "orcid": "0000-0001-5106-7502" }, - { "name": "Snow, Alan D.", "affiliation": "Corteva Agriscience" }, - { "name": "Kölling, Tobias", "affiliation": "Max Planck Institute for Meteorology" }, - { "name": "Allured, Dave", "affiliation": "NOAA/CIRES/University of Colorado" }, - { "name": "Jelenak, Aleksandar", "affiliation": "HDF Group" }, - { "name": "Soerensen, Anders Meier", "affiliation": "EUMETSAT" }, - { "name": "Gaultier, Lucile", "affiliation": "OceanDataLab" }, - { "name": "Herlédan, Sylvain", "affiliation": "OceanDataLab" }, - { "name": "Manzano, Fernando", "affiliation": "Puertos del Estado, Madrid" }, - { "name": "Bärring, Lars", "affiliation": "SMHI Rossby Centre, Swedish Meteorological and Hydrological Institute", "orcid": "0000-0001-7280-2502" }, - { "name": "Barker, Christopher", "affiliation": "NOAA" }, - { "name": "Bartholomew, Sadie L.", "affiliation": "National Centre for Atmospheric Science and University of Reading", "orcid": "0000-0002-6180-3603" } - ], + { + "name": "Eaton, Brian", + "affiliation": "NCAR" + }, + { + "name": "Gregory, Jonathan", + "affiliation": "University of Reading and UK Met Office Hadley Centre", + "orcid": "0000-0003-1296-8644" + }, + { + "name": "Drach, Bob", + "affiliation": "PCMDI, LLNL" + }, + { + "name": "Taylor, Karl", + "affiliation": "PCMDI, LLNL", + "orcid": "0000-0002-6491-2135" + }, + { + "name": "Hankin, Steve", + "affiliation": "PMEL, NOAA" + }, + { + "name": "Caron, John", + "affiliation": "Unidata" + }, + { + "name": "Signell, Rich", + "affiliation": "USGS" + }, + { + "name": "Bentley, Phil", + "affiliation": "UK Met Office" + }, + { + "name": "Rappa, Greg", + "affiliation": "MIT" + }, + { + "name": "H\u00f6ck, Heinke", + "affiliation": "DKRZ", + "orcid": "0000-0002-0131-1404" + }, + { + "name": "Pamment, Alison", + "affiliation": "NCAS and CEDA", + "orcid": "0000-0001-5040-4626" + }, + { + "name": "Juckes, Martin", + "affiliation": "NCAS" + }, + { + "name": "Raspaud, Martin", + "affiliation": "SMHI" + }, + { + "name": "Blower, Jon", + "affiliation": "University of Reading" + }, + { + "name": "Horne, Randy", + "affiliation": "Excalibur Laboratories Inc" + }, + { + "name": "Whiteaker, Timothy", + "affiliation": "University of Texas" + }, + { + "name": "Blodgett, David", + "affiliation": "USGS" + }, + { + "name": "Zender, Charlie", + "affiliation": "University of California, Irvine" + }, + { + "name": "Lee, Daniel", + "affiliation": "EUMETSAT", + "orcid": "0000-0002-1041-232X" + }, + { + "name": "Hassell, David", + "affiliation": "NCAS and University of Reading", + "orcid": "0000-0001-5106-7502" + }, + { + "name": "Snow, Alan D.", + "affiliation": "Corteva Agriscience" + }, + { + "name": "K\u00f6lling, Tobias", + "affiliation": "Max Planck Institute for Meteorology" + }, + { + "name": "Allured, Dave", + "affiliation": "NOAA/CIRES/University of Colorado" + }, + { + "name": "Jelenak, Aleksandar", + "affiliation": "HDF Group" + }, + { + "name": "Soerensen, Anders Meier", + "affiliation": "EUMETSAT" + }, + { + "name": "Gaultier, Lucile", + "affiliation": "OceanDataLab" + }, + { + "name": "Herl\u00e9dan, Sylvain", + "affiliation": "OceanDataLab" + }, + { + "name": "Manzano, Fernando", + "affiliation": "Puertos del Estado, Madrid" + }, + { + "name": "B\u00e4rring, Lars", + "affiliation": "SMHI Rossby Centre, Swedish Meteorological and Hydrological Institute", + "orcid": "0000-0001-7280-2502" + }, + { + "name": "Barker, Christopher", + "affiliation": "NOAA" + }, + { + "name": "Bartholomew, Sadie L.", + "affiliation": "National Centre for Atmospheric Science and University of Reading", + "orcid": "0000-0002-6180-3603" + } + ], "related_identifiers": [ { "relation": "isDocumentedBy", @@ -73,11 +178,18 @@ "scheme": "url", "identifier": "https://cfconventions.org/Data/cf-documents/requirements-recommendations/conformance-1.12.html" } - ] }, "files": [ - {"filename": "cf-conventions.pdf", "size": 6135749, "checksum": "md5:2763f464f2ac9e5c44c02c5343a3b384"}, - {"filename": "conformance.pdf", "size": 362748, "checksum": "md5:97af0bb9601bf67deaf4f7aaad5c75d8"} - ] -} + { + "filename": "cf-conventions.pdf", + "size": 6135749, + "checksum": "md5:2763f464f2ac9e5c44c02c5343a3b384" + }, + { + "filename": "conformance.pdf", + "size": 362748, + "checksum": "md5:97af0bb9601bf67deaf4f7aaad5c75d8" + } + ] +} \ No newline at end of file