From 47e27a8e29d11337f03bcf16b500052eafca0d3e Mon Sep 17 00:00:00 2001 From: Jordan <21129425+ItIsJordan@users.noreply.github.com> Date: Tue, 9 Jan 2024 14:31:14 +0000 Subject: [PATCH 01/24] Add optional licence argument to add_additional_resource Adds support for adding an optional licence to the add_additional_resource function in additional resource objects --- hepdata_lib/__init__.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/hepdata_lib/__init__.py b/hepdata_lib/__init__.py index f9cd4ae5..0be3357b 100644 --- a/hepdata_lib/__init__.py +++ b/hepdata_lib/__init__.py @@ -55,7 +55,7 @@ def __init__(self): self.files_to_copy = [] self.additional_resources = [] - def add_additional_resource(self, description, location, copy_file=False, file_type=None): + def add_additional_resource(self, description, location, copy_file=False, file_type=None, licence=None): """ Add any kind of additional resource. If copy_file is set to False, the location and description will be added as-is. @@ -80,6 +80,9 @@ def add_additional_resource(self, description, location, copy_file=False, file_t :param file_type: Type of the resource file. Currently, only "HistFactory" has any effect. :type file_type: string + + :param licence: Licence information for the resource + :type licence: string """ resource = {} @@ -94,6 +97,9 @@ def add_additional_resource(self, description, location, copy_file=False, file_t if file_type: resource["type"] = file_type + + if licence: + resource["licence"] = licence self.additional_resources.append(resource) @@ -306,6 +312,7 @@ def __init__(self, name): self.location = "Example location" self.keywords = {} self.image_files = set() + self.licence = {} @property def name(self): From 14ccd11fd60608066604a5cd214cd64712cf1587 Mon Sep 17 00:00:00 2001 From: Jordan <21129425+ItIsJordan@users.noreply.github.com> Date: Tue, 9 Jan 2024 14:32:06 +0000 Subject: [PATCH 02/24] Add licence function to Table class Adds a function to add licence information to the Table class --- hepdata_lib/__init__.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/hepdata_lib/__init__.py b/hepdata_lib/__init__.py index 0be3357b..7496d236 100644 --- a/hepdata_lib/__init__.py +++ b/hepdata_lib/__init__.py @@ -369,7 +369,35 @@ def add_related_doi(self, doi): self.related_tables.append(to_string) else: raise ValueError(f"DOI does not match the correct pattern: {pattern}.") + + def add_data_licence(self, name, url, description=None): + """ + Verify and store the given licence data. + + :param name: The licence name + :type name: string + :param url: + :type url: string + :param description: + :type description: string + """ + licence_data = {} + + if name: + licence_data["name"] = name + else: + raise ValueError("You must insert a value for the licence's name.") + + if url: + licence_data["url"] = url + else: + raise ValueError("You must insert a value for the licence's url.") + + if description: + licence_data["description"] = description + self.licence = licence_data + def write_output(self, outdir): """ Write the table files into the output directory. From de8661acca69176bfa856efea609bb817ff20e71 Mon Sep 17 00:00:00 2001 From: Jordan <21129425+ItIsJordan@users.noreply.github.com> Date: Tue, 9 Jan 2024 14:32:39 +0000 Subject: [PATCH 03/24] Add test for Table data licence function Adds a test for the new add_data_licence function in the Table class --- tests/test_submission.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/tests/test_submission.py b/tests/test_submission.py index f86b05be..a19a34e1 100644 --- a/tests/test_submission.py +++ b/tests/test_submission.py @@ -156,7 +156,7 @@ def test_nested_files_to_copy(self): def test_add_related_doi(self): """Test insertion and retrieval of recid values in the Table object""" - # Possibly unneccessary boundary testing + # Possibly unnecessary boundary testing test_data = [ {"doi": "10.17182/hepdata.1.v1/t1", "error": False}, {"doi": "10.17182/hepdata.1", "error": ValueError}, @@ -190,3 +190,22 @@ def test_add_related_recid(self): sub.add_related_recid(test["recid"]) assert int(test["recid"]) == sub.related_records[-1] assert len(sub.related_records) == 2 + + def test_add_data_licence(self): + """Test addition of data licence entries to the table class""" + test_data = [ + {"expected_err": None, "licence": ["name", "url", "desc"]}, # Valid, full + {"expected_err": None, "licence": ["name", "url", None]}, # Valid, no desc + {"expected_err": ValueError, "licence": ["name", None, "desc"]}, # Error, no url + {"expected_err": ValueError, "licence": [None, "url", "desc"]} # Error, no name + ] + tab = Table("Table") # Test table class + for test in test_data: + # Check if an error is expected here or not + if test["expected_err"]: + self.assertRaises(test["expected_err"], tab.add_data_licence, *test["licence"]) + else: + # Check data exists and is correct + tab.add_data_licence(*test["licence"]) + assert tab.licence["name"] == test["licence"][0] + assert tab.licence["url"] == test["licence"][1] From 04464bf3881276b5c25ebd9bd52839ee0f96ef64 Mon Sep 17 00:00:00 2001 From: Jordan <21129425+ItIsJordan@users.noreply.github.com> Date: Wed, 10 Jan 2024 10:22:08 +0000 Subject: [PATCH 04/24] Fix incorrect type AdditionalResource docs Fixed incorrect docstring type added to the AdditionalResourceMixin object --- hepdata_lib/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hepdata_lib/__init__.py b/hepdata_lib/__init__.py index 7496d236..5d443db4 100644 --- a/hepdata_lib/__init__.py +++ b/hepdata_lib/__init__.py @@ -82,7 +82,7 @@ def add_additional_resource(self, description, location, copy_file=False, file_t :type file_type: string :param licence: Licence information for the resource - :type licence: string + :type licence: dict """ resource = {} From ea1335f8eb8a0a324f3bcecb17924df3afa00adf Mon Sep 17 00:00:00 2001 From: Jordan <21129425+ItIsJordan@users.noreply.github.com> Date: Wed, 10 Jan 2024 10:25:31 +0000 Subject: [PATCH 05/24] Update add_additional_resource test Completes and updates the test_add_additional_resource test. --- tests/test_table.py | 39 ++++++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/tests/test_table.py b/tests/test_table.py index 6989c7c7..aa5610a7 100644 --- a/tests/test_table.py +++ b/tests/test_table.py @@ -169,14 +169,43 @@ def test_write_images_multiple_executions(self): self.assertTrue(modified_time_main < os.path.getmtime(expected_main_file)) self.assertTrue(modified_time_thumbnail < os.path.getmtime(expected_thumbnail_file)) - - - - def test_add_additional_resource(self): # pylint: disable=no-self-use """Test the add_additional_resource function.""" test_table = Table("Some Table") - test_table.add_additional_resource("some link","www.cern.ch") + test_data = [ + { + "description": "SomeLink", + "location": "www.cern.ch", + "type": None, + "licence": None + }, + { + "description": "SomeLink", + "location": "www.cern.ch", + "type": "HistFactory", + "licence": {"name": "LicenceName", "url": "www.cern.ch", "description": "LicenceDesc"} + } + ] + + for test in test_data: + test_table.add_additional_resource( + test["description"], + test["location"], + file_type=test["type"], + licence=test["licence"] + ) + + # Check resource and mandatory arguments + resource = test_table.additional_resources[-1] + assert resource["description"] == test["description"] + assert resource["location"] == test["location"] + + # Check optional arguments type and licence + if test["type"]: + assert resource["type"] == test["type"] + + if test["licence"]: + assert resource["licence"] == test["licence"] def test_copy_files(self): """Test the copy_files function.""" From 1383a3c816bdf5762f2940297e5a2045c74f4bfd Mon Sep 17 00:00:00 2001 From: Jordan <21129425+ItIsJordan@users.noreply.github.com> Date: Wed, 10 Jan 2024 11:16:40 +0000 Subject: [PATCH 06/24] Complete test_copy_files Completes implementation of incomplete test_copy_files function --- tests/test_table.py | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/tests/test_table.py b/tests/test_table.py index aa5610a7..56ae49ef 100644 --- a/tests/test_table.py +++ b/tests/test_table.py @@ -4,7 +4,7 @@ import shutil from unittest import TestCase -from hepdata_lib import Table, Variable, Uncertainty +from hepdata_lib import Table, Variable, Uncertainty, helpers from .test_utilities import tmp_directory_name class TestTable(TestCase): @@ -194,9 +194,10 @@ def test_add_additional_resource(self): # pylint: disable=no-self-use file_type=test["type"], licence=test["licence"] ) + resource = test_table.additional_resources[-1] # Check resource and mandatory arguments - resource = test_table.additional_resources[-1] + assert resource assert resource["description"] == test["description"] assert resource["location"] == test["location"] @@ -214,6 +215,23 @@ def test_copy_files(self): testdir = tmp_directory_name() self.addCleanup(shutil.rmtree, testdir) os.makedirs(testdir) + test_table.add_additional_resource("a plot", some_pdf, copy_file=True) - test_table.add_additional_resource("a plot",some_pdf, copy_file=True) - test_table.copy_files(testdir) + # Check that the file has been created + assert helpers.check_file_existence(some_pdf) + + # Explicitly test for lack of an error + try: + # No boundaries + helpers.check_file_size(some_pdf) + # Between boundaries + helpers.check_file_size(some_pdf, upper_limit=1, lower_limit=0.001) + except Exception as e: + self.fail(f"check_file_size() raised an Exception: {e}.") + + # Check that both boundaries function correctly + with self.assertRaises(RuntimeError): + helpers.check_file_size(some_pdf, upper_limit=0.001) + + with self.assertRaises(RuntimeError): + helpers.check_file_size(some_pdf, lower_limit=1) From b83359c2e100989fc742a9e8bf687503fcfc9c28 Mon Sep 17 00:00:00 2001 From: Jordan <21129425+ItIsJordan@users.noreply.github.com> Date: Fri, 12 Jan 2024 13:04:05 +0000 Subject: [PATCH 07/24] Add validation check to additional resource licence add Adds validation of licence additions to the add_additional_resource function for AdditionalResource objects. --- hepdata_lib/__init__.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/hepdata_lib/__init__.py b/hepdata_lib/__init__.py index 5d443db4..8b3bb21f 100644 --- a/hepdata_lib/__init__.py +++ b/hepdata_lib/__init__.py @@ -97,9 +97,23 @@ def add_additional_resource(self, description, location, copy_file=False, file_t if file_type: resource["type"] = file_type - + + # Confirm that licence does not contain extra keys, and has the mandatory name and description values if licence: - resource["licence"] = licence + # Get the licence dict keys as a set + licence_keys = set(licence.keys()) + + # Create sets for both possibilities + mandatory_keys = {"name", "description"} + all_keys = mandatory_keys.union(["url"]) + + # If licence matches either of the correct values + if licence_keys == mandatory_keys or licence_keys == all_keys: + resource["licence"] = licence + else: + raise ValueError("Incorrect licence format: \ + Licence must be a dictionary containing a \ + name, description and optional URL value.") self.additional_resources.append(resource) From 63f820d42ca49a3b3158a85cc330540153657ecd Mon Sep 17 00:00:00 2001 From: Jordan <21129425+ItIsJordan@users.noreply.github.com> Date: Fri, 12 Jan 2024 13:15:49 +0000 Subject: [PATCH 08/24] Update error in TestTable Updates error check in TestTable.test_copy_files --- tests/test_table.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_table.py b/tests/test_table.py index 56ae49ef..6f613c88 100644 --- a/tests/test_table.py +++ b/tests/test_table.py @@ -226,8 +226,8 @@ def test_copy_files(self): helpers.check_file_size(some_pdf) # Between boundaries helpers.check_file_size(some_pdf, upper_limit=1, lower_limit=0.001) - except Exception as e: - self.fail(f"check_file_size() raised an Exception: {e}.") + except RuntimeError: + self.fail("Table.check_file_size raised an unexpected RuntimeError.") # Check that both boundaries function correctly with self.assertRaises(RuntimeError): From efedcaf48726c91e639ae2f38c949085d5a19150 Mon Sep 17 00:00:00 2001 From: Jordan <21129425+ItIsJordan@users.noreply.github.com> Date: Fri, 12 Jan 2024 13:18:18 +0000 Subject: [PATCH 09/24] Add additional resource licence check test Adds a test to check licence validation in TestTable.add_additional_resource. --- tests/test_table.py | 64 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/tests/test_table.py b/tests/test_table.py index 6f613c88..09144e7a 100644 --- a/tests/test_table.py +++ b/tests/test_table.py @@ -208,6 +208,70 @@ def test_add_additional_resource(self): # pylint: disable=no-self-use if test["licence"]: assert resource["licence"] == test["licence"] + def test_add_additional_resource_licence_check(self): + """ Test the licence value check in Table.add_additional_resource """ + # First two pass, last two fail + licence_data = [ + { + "error": None, + "licence_data": { + "name": "Name", + "description": "Desc" + } + }, + { + "error": None, + "licence_data": { + "name": "Name", + "description": "Desc", + "url": "URL" + } + }, + { + "error": ValueError, + "licence_data": { + "name": "Name", + "description": "Desc", + "shouldnotbehere": "shouldnotbehere" + } + }, + { + "error": ValueError, + "licence_data": { + "name": "Name", + "description": "Desc", + "url": "URL", + "toomany": "toomany" + } + }] + + # Create test table and get the test pdf + test_table = Table("Some Table") + some_pdf = "%s/minimal.pdf" % os.path.dirname(__file__) + + # Set default description, location and type arguments for a table object + resource_args = ["Description", some_pdf, "Type"] + + for data in licence_data: + # If error is expected, we check for the error + # Otherwise, just add and check length later + if data["error"]: + with self.assertRaises(ValueError): + test_table.add_additional_resource( + *resource_args, + licence=data["licence_data"] + ) + else: + # Check for lack of failure + try: + test_table.add_additional_resource( + *resource_args, + licence=data["licence_data"] + ) + except ValueError: + self.fail("Table.add_additional_resource raised an unexpected ValueError.") + + def test_copy_files(self): """Test the copy_files function.""" test_table = Table("Some Table") From d8807847ddf818ca900cb04fcc2bb2002dece13f Mon Sep 17 00:00:00 2001 From: Jordan <21129425+ItIsJordan@users.noreply.github.com> Date: Wed, 24 Jan 2024 15:52:42 +0000 Subject: [PATCH 10/24] Update usage documentation to include licences Updates the usage documentation in USAGE.rst to include adding licences to additional resource and table objects. --- docs/usage.rst | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docs/usage.rst b/docs/usage.rst index 8d450e32..23466285 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -124,11 +124,14 @@ Additional resources, hosted either externally or locally, can be linked with th sub.add_additional_resource("Web page with auxiliary material", "https://atlas.web.cern.ch/Atlas/GROUPS/PHYSICS/PAPERS/STDM-2012-02/") sub.add_additional_resource("Some file", "root_file.root", copy_file=True) sub.add_additional_resource("Archive of full likelihoods in the HistFactory JSON format", "Likelihoods.tar.gz", copy_file=True, file_type="HistFactory") + sub.add_additional_resource("Some file", "root_file.root", licence={"name": "CC BY 4.0", "url": "https://creativecommons.org/licenses/by/4.0/", "description": "This license enables reusers to distribute, remix, adapt, and build upon the material in any medium or format, so long as attribution is given to the creator."}) The first argument is a ``description`` and the second is the ``location`` of the external link or local resource file. The optional argument ``copy_file=True`` (default value of ``False``) will copy a local file into the output directory. The optional argument ``file_type="HistFactory"`` (default value of ``None``) can be used to identify statistical models provided in the HistFactory JSON format rather than relying on certain trigger words in the ``description`` (see `pyhf section of submission documentation`_). +The optional argument ``licence`` can be used to define a data licence for an additional resource. +The ``licence`` is in the form of a dictionary with mandatory string ``name`` and ``url`` values, and an optional ``description``. The ``add_link`` function can alternatively be used to add a link to an external resource: @@ -316,6 +319,17 @@ The documentation for this feature can be found here: `Linking tables`_. .. _`Linking tables`: https://hepdata-submission.readthedocs.io/en/latest/bidirectional.html#linking-tables +Adding a Data Licence +^^^^^^^^^^^^^^^^^^^^^ + +You can add data licence information to a table using the ``add_data_licence`` function of the Table class. +This function takes mandatory ``name`` and ``url`` string arguments, as well as an optional ``description``. + +:: + + table.add_data_licence("CC BY 4.0", "https://creativecommons.org/licences/by/4.0/") + table.add_data_licence("CC BY 4.0", "https://creativecommons.org/licences/by/4.0/", "This license enables reusers to distribute, remix, adapt, and build upon the material in any medium or format, so long as attribution is given to the creator.") + Uncertainties +++++++++++++ From 919a5ca59f5f863ab4b49c2592e3ae01e25c5956 Mon Sep 17 00:00:00 2001 From: Graeme Watt Date: Wed, 14 Feb 2024 17:44:39 +0000 Subject: [PATCH 11/24] Some fixes and cleaning up for pylint * Use spelling "license" rather than "licence" consistently. * Rename argument "license" as "resource_license" to avoid pylint issue. * Rename Table "license" as "data_license" and write to YAML. * Check that "resource_license" is a dict and correct mandatory keys. --- docs/usage.rst | 14 ++++---- hepdata_lib/__init__.py | 74 +++++++++++++++++++++++----------------- tests/test_submission.py | 20 +++++------ tests/test_table.py | 43 +++++++++++------------ 4 files changed, 81 insertions(+), 70 deletions(-) diff --git a/docs/usage.rst b/docs/usage.rst index 23466285..3ffb3292 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -123,15 +123,15 @@ Additional resources, hosted either externally or locally, can be linked with th sub.add_additional_resource("Web page with auxiliary material", "https://atlas.web.cern.ch/Atlas/GROUPS/PHYSICS/PAPERS/STDM-2012-02/") sub.add_additional_resource("Some file", "root_file.root", copy_file=True) + sub.add_additional_resource("Some file", "root_file.root", copy_file=True, resource_license={"name": "CC BY 4.0", "url": "https://creativecommons.org/licenses/by/4.0/", "description": "This license enables reusers to distribute, remix, adapt, and build upon the material in any medium or format, so long as attribution is given to the creator."}) sub.add_additional_resource("Archive of full likelihoods in the HistFactory JSON format", "Likelihoods.tar.gz", copy_file=True, file_type="HistFactory") - sub.add_additional_resource("Some file", "root_file.root", licence={"name": "CC BY 4.0", "url": "https://creativecommons.org/licenses/by/4.0/", "description": "This license enables reusers to distribute, remix, adapt, and build upon the material in any medium or format, so long as attribution is given to the creator."}) The first argument is a ``description`` and the second is the ``location`` of the external link or local resource file. The optional argument ``copy_file=True`` (default value of ``False``) will copy a local file into the output directory. +The optional argument ``resource_license`` can be used to define a data license for an additional resource. +The ``resource_license`` is in the form of a dictionary with mandatory string ``name`` and ``url`` values, and an optional ``description``. The optional argument ``file_type="HistFactory"`` (default value of ``None``) can be used to identify statistical models provided in the HistFactory JSON format rather than relying on certain trigger words in the ``description`` (see `pyhf section of submission documentation`_). -The optional argument ``licence`` can be used to define a data licence for an additional resource. -The ``licence`` is in the form of a dictionary with mandatory string ``name`` and ``url`` values, and an optional ``description``. The ``add_link`` function can alternatively be used to add a link to an external resource: @@ -319,16 +319,16 @@ The documentation for this feature can be found here: `Linking tables`_. .. _`Linking tables`: https://hepdata-submission.readthedocs.io/en/latest/bidirectional.html#linking-tables -Adding a Data Licence +Adding a data license ^^^^^^^^^^^^^^^^^^^^^ -You can add data licence information to a table using the ``add_data_licence`` function of the Table class. +You can add data license information to a table using the ``add_data_license`` function of the Table class. This function takes mandatory ``name`` and ``url`` string arguments, as well as an optional ``description``. :: - table.add_data_licence("CC BY 4.0", "https://creativecommons.org/licences/by/4.0/") - table.add_data_licence("CC BY 4.0", "https://creativecommons.org/licences/by/4.0/", "This license enables reusers to distribute, remix, adapt, and build upon the material in any medium or format, so long as attribution is given to the creator.") + table.add_data_license("CC BY 4.0", "https://creativecommons.org/licenses/by/4.0/") + table.add_data_license("CC BY 4.0", "https://creativecommons.org/licenses/by/4.0/", "This license enables reusers to distribute, remix, adapt, and build upon the material in any medium or format, so long as attribution is given to the creator.") Uncertainties +++++++++++++ diff --git a/hepdata_lib/__init__.py b/hepdata_lib/__init__.py index 8b3bb21f..1e26482a 100644 --- a/hepdata_lib/__init__.py +++ b/hepdata_lib/__init__.py @@ -55,7 +55,8 @@ def __init__(self): self.files_to_copy = [] self.additional_resources = [] - def add_additional_resource(self, description, location, copy_file=False, file_type=None, licence=None): + def add_additional_resource(self, description, location, copy_file=False, file_type=None, + resource_license=None): """ Add any kind of additional resource. If copy_file is set to False, the location and description will be added as-is. @@ -81,10 +82,12 @@ def add_additional_resource(self, description, location, copy_file=False, file_t :param file_type: Type of the resource file. Currently, only "HistFactory" has any effect. :type file_type: string - :param licence: Licence information for the resource - :type licence: dict + :param resource_license: License information comprising name, url and optional description. + :type resource_license: dict """ + #pylint: disable=too-many-arguments + resource = {} resource["description"] = description if copy_file: @@ -98,22 +101,27 @@ def add_additional_resource(self, description, location, copy_file=False, file_t if file_type: resource["type"] = file_type - # Confirm that licence does not contain extra keys, and has the mandatory name and description values - if licence: - # Get the licence dict keys as a set - licence_keys = set(licence.keys()) + # Confirm that license does not contain extra keys, + # and has the mandatory name and description values + if resource_license: + + if isinstance(resource_license) != dict: + raise ValueError("resource_license must be a dictionary.") + + # Get the license dict keys as a set + license_keys = set(resource_license.keys()) # Create sets for both possibilities - mandatory_keys = {"name", "description"} - all_keys = mandatory_keys.union(["url"]) + mandatory_keys = {"name", "url"} + all_keys = mandatory_keys.union(["description"]) - # If licence matches either of the correct values - if licence_keys == mandatory_keys or licence_keys == all_keys: - resource["licence"] = licence + # If license matches either of the correct values + if license_keys in (mandatory_keys, all_keys): + resource["license"] = resource_license else: - raise ValueError("Incorrect licence format: \ - Licence must be a dictionary containing a \ - name, description and optional URL value.") + raise ValueError("Incorrect resource_license format: " + "resource_license must be a dictionary containing a " + "name, url and optional description.") self.additional_resources.append(resource) @@ -326,7 +334,7 @@ def __init__(self, name): self.location = "Example location" self.keywords = {} self.image_files = set() - self.licence = {} + self.data_license = {} @property def name(self): @@ -383,35 +391,35 @@ def add_related_doi(self, doi): self.related_tables.append(to_string) else: raise ValueError(f"DOI does not match the correct pattern: {pattern}.") - - def add_data_licence(self, name, url, description=None): + + def add_data_license(self, name, url, description=None): """ - Verify and store the given licence data. + Verify and store the given license data. - :param name: The licence name + :param name: The license name :type name: string - :param url: + :param url: The license URL :type url: string - :param description: + :param description: The (optional) license description :type description: string """ - licence_data = {} + license_data = {} if name: - licence_data["name"] = name + license_data["name"] = name else: - raise ValueError("You must insert a value for the licence's name.") - + raise ValueError("You must insert a value for the license's name.") + if url: - licence_data["url"] = url + license_data["url"] = url else: - raise ValueError("You must insert a value for the licence's url.") - + raise ValueError("You must insert a value for the license's url.") + if description: - licence_data["description"] = description + license_data["description"] = description + + self.data_license = license_data - self.licence = licence_data - def write_output(self, outdir): """ Write the table files into the output directory. @@ -523,6 +531,8 @@ def write_yaml(self, outdir="."): submission["keywords"] = [] if self.additional_resources: submission["additional_resources"] = self.additional_resources + if self.data_license: + submission["data_license"] = self.data_license for name, values in list(self.keywords.items()): submission["keywords"].append({"name": name, "values": values}) diff --git a/tests/test_submission.py b/tests/test_submission.py index a19a34e1..77730dba 100644 --- a/tests/test_submission.py +++ b/tests/test_submission.py @@ -191,21 +191,21 @@ def test_add_related_recid(self): assert int(test["recid"]) == sub.related_records[-1] assert len(sub.related_records) == 2 - def test_add_data_licence(self): - """Test addition of data licence entries to the table class""" + def test_add_data_license(self): + """Test addition of data license entries to the Table class""" test_data = [ - {"expected_err": None, "licence": ["name", "url", "desc"]}, # Valid, full - {"expected_err": None, "licence": ["name", "url", None]}, # Valid, no desc - {"expected_err": ValueError, "licence": ["name", None, "desc"]}, # Error, no url - {"expected_err": ValueError, "licence": [None, "url", "desc"]} # Error, no name + {"expected_err": None, "data_license": ["name", "url", "desc"]}, # Valid, full + {"expected_err": None, "data_license": ["name", "url", None]}, # Valid, no desc + {"expected_err": ValueError, "data_license": ["name", None, "desc"]}, # Error, no url + {"expected_err": ValueError, "data_license": [None, "url", "desc"]} # Error, no name ] tab = Table("Table") # Test table class for test in test_data: # Check if an error is expected here or not if test["expected_err"]: - self.assertRaises(test["expected_err"], tab.add_data_licence, *test["licence"]) + self.assertRaises(test["expected_err"], tab.add_data_license, *test["data_license"]) else: # Check data exists and is correct - tab.add_data_licence(*test["licence"]) - assert tab.licence["name"] == test["licence"][0] - assert tab.licence["url"] == test["licence"][1] + tab.add_data_license(*test["data_license"]) + assert tab.data_license["name"] == test["data_license"][0] + assert tab.data_license["url"] == test["data_license"][1] diff --git a/tests/test_table.py b/tests/test_table.py index 09144e7a..bedf6c6f 100644 --- a/tests/test_table.py +++ b/tests/test_table.py @@ -177,13 +177,14 @@ def test_add_additional_resource(self): # pylint: disable=no-self-use "description": "SomeLink", "location": "www.cern.ch", "type": None, - "licence": None + "license": None }, { "description": "SomeLink", "location": "www.cern.ch", "type": "HistFactory", - "licence": {"name": "LicenceName", "url": "www.cern.ch", "description": "LicenceDesc"} + "license": {"name": "licenseName", "url": "www.cern.ch", + "description": "licenseDesc"} } ] @@ -192,7 +193,7 @@ def test_add_additional_resource(self): # pylint: disable=no-self-use test["description"], test["location"], file_type=test["type"], - licence=test["licence"] + resource_license=test["license"] ) resource = test_table.additional_resources[-1] @@ -201,46 +202,46 @@ def test_add_additional_resource(self): # pylint: disable=no-self-use assert resource["description"] == test["description"] assert resource["location"] == test["location"] - # Check optional arguments type and licence + # Check optional arguments type and license if test["type"]: assert resource["type"] == test["type"] - if test["licence"]: - assert resource["licence"] == test["licence"] + if test["license"]: + assert resource["license"] == test["license"] - def test_add_additional_resource_licence_check(self): - """ Test the licence value check in Table.add_additional_resource """ + def test_add_additional_resource_license_check(self): + """ Test the license value check in Table.add_additional_resource """ # First two pass, last two fail - licence_data = [ + license_data = [ { "error": None, - "licence_data": { + "license_data": { "name": "Name", - "description": "Desc" + "url": "URL" } }, { "error": None, - "licence_data": { + "license_data": { "name": "Name", - "description": "Desc", - "url": "URL" + "url": "URL", + "description": "Desc" } }, { "error": ValueError, - "licence_data": { + "license_data": { "name": "Name", - "description": "Desc", + "url": "URL", "shouldnotbehere": "shouldnotbehere" } }, { "error": ValueError, - "licence_data": { + "license_data": { "name": "Name", - "description": "Desc", "url": "URL", + "description": "Desc", "toomany": "toomany" } }] @@ -252,21 +253,21 @@ def test_add_additional_resource_licence_check(self): # Set default description, location and type arguments for a table object resource_args = ["Description", some_pdf, "Type"] - for data in licence_data: + for data in license_data: # If error is expected, we check for the error # Otherwise, just add and check length later if data["error"]: with self.assertRaises(ValueError): test_table.add_additional_resource( *resource_args, - licence=data["licence_data"] + resource_license=data["license_data"] ) else: # Check for lack of failure try: test_table.add_additional_resource( *resource_args, - licence=data["licence_data"] + resource_license=data["license_data"] ) except ValueError: self.fail("Table.add_additional_resource raised an unexpected ValueError.") From 2cf90464ec5a05e122504019d37b444da6890e51 Mon Sep 17 00:00:00 2001 From: Graeme Watt Date: Wed, 14 Feb 2024 17:49:32 +0000 Subject: [PATCH 12/24] Remove get_license() from Submission class * Not supported by JSON schema or HEPData web application. --- hepdata_lib/__init__.py | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/hepdata_lib/__init__.py b/hepdata_lib/__init__.py index 1e26482a..06c2c6c3 100644 --- a/hepdata_lib/__init__.py +++ b/hepdata_lib/__init__.py @@ -562,17 +562,6 @@ def __init__(self): "Created with hepdata_lib " + __version__, "https://doi.org/10.5281/zenodo.1217998") - @staticmethod - def get_license(): - """Return the default license.""" - data_license = {} - data_license["name"] = "cc-by-4.0" - data_license["url"] = "https://creativecommons.org/licenses/by/4.0/" - data_license[ - "description"] = "The content can be shared and adapted but you must\ - give appropriate credit and cannot restrict access to others." - return data_license - def add_table(self, table): """Append table to tables list. @@ -667,7 +656,6 @@ def create_files(self, outdir=".", validate=True, remove_old=False): # Write general info about submission submission = {} - submission["data_license"] = self.get_license() submission["comment"] = self.comment submission["related_to_hepdata_records"] = self.related_records From 7211f55d0a4050503b73c660d53253b5f9221118 Mon Sep 17 00:00:00 2001 From: Graeme Watt Date: Thu, 15 Feb 2024 16:15:31 +0000 Subject: [PATCH 13/24] examples: show how to add license information * Modify "Getting_started.ipynb" to add license information. * Also print out submission.yaml and YAML data file at end of notebook. --- examples/Getting_started.ipynb | 193 +++++++++++++++++++++++++++++++-- 1 file changed, 184 insertions(+), 9 deletions(-) diff --git a/examples/Getting_started.ipynb b/examples/Getting_started.ipynb index e940c44c..2a636653 100644 --- a/examples/Getting_started.ipynb +++ b/examples/Getting_started.ipynb @@ -35,7 +35,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Welcome to JupyROOT 6.28/06\n" + "Welcome to JupyROOT 6.26/06\n" ] } ], @@ -271,25 +271,50 @@ "If you want, the original data file can be attached to the table as an additional resource file." ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The default license for HEPData records is [CC0](https://creativecommons.org/publicdomain/zero/1.0/legalcode) (see [Terms of Use](https://www.hepdata.net/terms)), but it is possible to specify a different license for both additional resource files and data tables." + ] + }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ - "table.add_additional_resource(\"Original data file\", \"example_inputs/effacc_signal.txt\", copy_file=True)" + "license = {\"name\": \"CC BY 4.0\", \"url\": \"https://creativecommons.org/licenses/by/4.0/\", \"description\": \"This license enables reusers to distribute, remix, adapt, and build upon the material in any medium or format, so long as attribution is given to the creator.\"}" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "table.add_additional_resource(\"Original data file\", \"example_inputs/effacc_signal.txt\", copy_file=True, resource_license=license)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "table.add_data_license(license[\"name\"], license[\"url\"])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "This is all that's needed for the table/figure. We still need it to the submission:" + "This is all that's needed for the table/figure. We still need to add it to the submission:" ] }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 14, "metadata": {}, "outputs": [], "source": [ @@ -305,7 +330,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 15, "metadata": {}, "outputs": [], "source": [ @@ -322,7 +347,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 16, "metadata": {}, "outputs": [], "source": [ @@ -339,7 +364,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 17, "metadata": {}, "outputs": [ { @@ -363,7 +388,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 18, "metadata": {}, "outputs": [ { @@ -378,6 +403,156 @@ "source": [ "!ls example_output" ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "---\n", + "additional_resources:\n", + "- description: Created with hepdata_lib 0.14.0\n", + " location: https://doi.org/10.5281/zenodo.1217998\n", + "- description: Webpage with all figures and tables\n", + " location: https://cms-results.web.cern.ch/cms-results/public-results/publications/B2G-16-029/\n", + "- description: arXiv\n", + " location: http://arxiv.org/abs/arXiv:1802.09407\n", + "- description: Original abstract file\n", + " location: abstract.txt\n", + "comment: A search for a new heavy particle decaying to a pair of vector bosons (WW\n", + " or WZ) is presented using data from the CMS detector corresponding to an integrated\n", + " luminosity of $35.9~\\mathrm{fb}^{-1}$ collected in proton-proton collisions at a\n", + " centre-of-mass energy of 13~TeV in 2016. One of the bosons is required to be a W\n", + " boson decaying to $e\\nu$ or $mu\\nu$, while the other boson is required to be reconstructed\n", + " as a single massive jet with substructure compatible with that of a highly-energetic\n", + " quark pair from a W or Z boson decay. The search is performed in the resonance mass\n", + " range between 1.0 and 4.5~TeV. The largest deviation from the background-only hypothesis\n", + " is observed for a mass near 1.4~TeV and corresponds to a local significance of 2.5\n", + " standard deviations. The result is interpreted as an upper bound on the resonance\n", + " production cross section. Comparing the excluded cross section values and the expectations\n", + " from theoretical calculations in the bulk graviton and heavy vector triplet models,\n", + " spin-2 WW resonances with mass smaller than 1.07~TeV and spin-1 WZ resonances lighter\n", + " than 3.05~TeV, respectively, are excluded at 95\\% confidence level.\n", + "record_ids:\n", + "- id: 1657397\n", + " type: inspire\n", + "---\n", + "additional_resources:\n", + "- description: Original data file\n", + " license:\n", + " description: This license enables reusers to distribute, remix, adapt, and build\n", + " upon the material in any medium or format, so long as attribution is given to\n", + " the creator.\n", + " name: CC BY 4.0\n", + " url: https://creativecommons.org/licenses/by/4.0/\n", + " location: effacc_signal.txt\n", + "- description: Image file\n", + " location: signalEffVsMass.png\n", + "- description: Thumbnail image file\n", + " location: thumb_signalEffVsMass.png\n", + "data_file: additional_figure_1.yaml\n", + "data_license:\n", + " name: CC BY 4.0\n", + " url: https://creativecommons.org/licenses/by/4.0/\n", + "description: Signal selection efficiency times acceptance as a function of resonance\n", + " mass for a spin-2 bulk graviton decaying to WW and a spin-1 W' decaying to WZ.\n", + "keywords:\n", + "- name: observables\n", + " values:\n", + " - ACC\n", + " - EFF\n", + "- name: reactions\n", + " values:\n", + " - P P --> GRAVITON --> W+ W-\n", + " - P P --> WPRIME --> W+/W- Z0\n", + "- name: cmenergies\n", + " values:\n", + " - 13000\n", + "location: Data from additional Figure 1\n", + "name: Additional Figure 1\n" + ] + } + ], + "source": [ + "!cat example_output/submission.yaml" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "dependent_variables:\n", + "- header:\n", + " name: Efficiency times acceptance\n", + " qualifiers:\n", + " - name: Efficiency times acceptance\n", + " value: Bulk graviton --> WW\n", + " - name: SQRT(S)\n", + " units: TeV\n", + " value: 13\n", + " values:\n", + " - value: 0.4651\n", + " - value: 0.50336\n", + " - value: 0.5126\n", + " - value: 0.52474\n", + " - value: 0.531\n", + " - value: 0.5391\n", + " - value: 0.54943\n", + " - value: 0.55378\n", + " - value: 0.56216\n", + " - value: 0.56454\n", + " - value: 0.56682\n", + "- header:\n", + " name: Efficiency times acceptance\n", + " qualifiers:\n", + " - name: Efficiency times acceptance\n", + " value: Wprime --> WZ\n", + " - name: SQRT(S)\n", + " units: TeV\n", + " value: 13\n", + " values:\n", + " - value: 0.45136\n", + " - value: 0.5109\n", + " - value: 0.54016\n", + " - value: 0.5513\n", + " - value: 0.56724\n", + " - value: 0.5728\n", + " - value: 0.5856\n", + " - value: 0.58952\n", + " - value: 0.60324\n", + " - value: .nan\n", + " - value: 0.59978\n", + "independent_variables:\n", + "- header:\n", + " name: Resonance mass\n", + " units: GeV\n", + " values:\n", + " - value: 1000.0\n", + " - value: 1200.0\n", + " - value: 1400.0\n", + " - value: 1600.0\n", + " - value: 1800.0\n", + " - value: 2000.0\n", + " - value: 2500.0\n", + " - value: 3000.0\n", + " - value: 3500.0\n", + " - value: 4000.0\n", + " - value: 4500.0\n" + ] + } + ], + "source": [ + "!cat example_output/additional_figure_1.yaml" + ] } ], "metadata": { @@ -396,7 +571,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.6" + "version": "3.10.12" } }, "nbformat": 4, From 3918d70ec7ce565c082823efb52c26c2838fb89f Mon Sep 17 00:00:00 2001 From: Graeme Watt Date: Thu, 15 Feb 2024 16:21:53 +0000 Subject: [PATCH 14/24] tests: fix isinstance, add test, suppress keys * Fix incorrect use of isinstance added in 919a5ca59f5f863ab4b49c2592e3ae01e25c5956. * Add a test for resource_license not a dictionary to increase coverage. * Suppress empty "related_records" and "related_to_table_dois" keys. --- hepdata_lib/__init__.py | 8 +++++--- tests/test_table.py | 8 ++++++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/hepdata_lib/__init__.py b/hepdata_lib/__init__.py index 06c2c6c3..29765cb1 100644 --- a/hepdata_lib/__init__.py +++ b/hepdata_lib/__init__.py @@ -105,7 +105,7 @@ def add_additional_resource(self, description, location, copy_file=False, file_t # and has the mandatory name and description values if resource_license: - if isinstance(resource_license) != dict: + if not isinstance(resource_license, dict): raise ValueError("resource_license must be a dictionary.") # Get the license dict keys as a set @@ -526,7 +526,8 @@ def write_yaml(self, outdir="."): submission["name"] = self.name submission["description"] = self.description submission["location"] = self.location - submission["related_to_table_dois"] = self.related_tables + if self.related_tables: + submission["related_to_table_dois"] = self.related_tables submission["data_file"] = f'{shortname}.yaml' submission["keywords"] = [] if self.additional_resources: @@ -657,7 +658,8 @@ def create_files(self, outdir=".", validate=True, remove_old=False): # Write general info about submission submission = {} submission["comment"] = self.comment - submission["related_to_hepdata_records"] = self.related_records + if self.related_records: + submission["related_to_hepdata_records"] = self.related_records if self.additional_resources: submission["additional_resources"] = self.additional_resources diff --git a/tests/test_table.py b/tests/test_table.py index bedf6c6f..03f63555 100644 --- a/tests/test_table.py +++ b/tests/test_table.py @@ -244,14 +244,18 @@ def test_add_additional_resource_license_check(self): "description": "Desc", "toomany": "toomany" } + }, + { + "error": ValueError, + "license_data": "a string not a dictionary" }] # Create test table and get the test pdf test_table = Table("Some Table") some_pdf = "%s/minimal.pdf" % os.path.dirname(__file__) - # Set default description, location and type arguments for a table object - resource_args = ["Description", some_pdf, "Type"] + # Set default description, location, copy_file and file_type arguments for a resource file + resource_args = ["Description", some_pdf, True, "Type"] for data in license_data: # If error is expected, we check for the error From d84bef6221d9a37d66906370bd8488b967a81d5b Mon Sep 17 00:00:00 2001 From: Jordan <21129425+ItIsJordan@users.noreply.github.com> Date: Mon, 25 Mar 2024 08:25:11 +0000 Subject: [PATCH 15/24] Update test data Updates test data in TestTable.test_write_yaml to test missed lines. --- tests/test_table.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/test_table.py b/tests/test_table.py index 03f63555..38079d2e 100644 --- a/tests/test_table.py +++ b/tests/test_table.py @@ -61,6 +61,12 @@ def test_write_yaml(self): test_table = Table("Some Table") test_variable = Variable("Some Variable") test_table.add_variable(test_variable) + test_table.add_related_doi("10.17182/hepdata.1.v1/t1") + test_table.add_data_license( + name="data_license", + url="test_url" + ) + test_table.keywords = {"name": "keywords", "values": "1"} testdir = tmp_directory_name() self.addCleanup(shutil.rmtree, testdir) try: From 14f65e3896c25d188e1614676db793cfecea54a1 Mon Sep 17 00:00:00 2001 From: Jordan <21129425+ItIsJordan@users.noreply.github.com> Date: Tue, 16 Apr 2024 15:25:03 +0100 Subject: [PATCH 16/24] Update test for coverage Updates test_create_files function in test_submission.py to cover missing lines --- tests/test_submission.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/tests/test_submission.py b/tests/test_submission.py index f7fe367c..ed30b5a9 100644 --- a/tests/test_submission.py +++ b/tests/test_submission.py @@ -71,11 +71,26 @@ def test_additional_resource_size(self): def test_create_files(self): """Test create_files() for Submission.""" + # Set test directory/file pat testdir = tmp_directory_name() + testpath = "./testfile.txt" + + # Create test file and set cleanup + f = open(testpath, "a") + f.close() + self.addCleanup(os.remove, testpath) + + # Create submission and set values for testing test_submission = Submission() test_submission.add_record_id(1657397, "inspire") - tab = Table("test") - test_submission.add_table(tab) + test_submission.add_related_recid(111) + test_submission.add_additional_resource("Some description", testpath, + copy_file=True, file_type="HistFactory") + # Create table and set test values + test_table = Table("test") + test_table.add_related_doi("10.17182/hepdata.1.v1/t1") + test_submission.add_table(test_table) + test_submission.create_files(testdir) self.doCleanups() From edcf9162a3e7576825703d7c5a44afe1962d1e42 Mon Sep 17 00:00:00 2001 From: Jordan <21129425+ItIsJordan@users.noreply.github.com> Date: Tue, 16 Apr 2024 15:26:00 +0100 Subject: [PATCH 17/24] Pylint fixes Fixed some issues output by pylint in the actions output --- tests/test_table.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_table.py b/tests/test_table.py index 67e32382..1fa434f9 100644 --- a/tests/test_table.py +++ b/tests/test_table.py @@ -179,7 +179,7 @@ def test_write_images_multiple_executions(self): self.assertTrue(modified_time_main < os.path.getmtime(expected_main_file)) self.assertTrue(modified_time_thumbnail < os.path.getmtime(expected_thumbnail_file)) - def test_add_additional_resource(self): # pylint: disable=no-self-use + def test_add_additional_resource(self): """Test the add_additional_resource function.""" test_table = Table("Some Table") test_data = [ @@ -262,7 +262,7 @@ def test_add_additional_resource_license_check(self): # Create test table and get the test pdf test_table = Table("Some Table") - some_pdf = "%s/minimal.pdf" % os.path.dirname(__file__) + some_pdf = f"{os.path.dirname(__file__)}/minimal.pdf" # Set default description, location, copy_file and file_type arguments for a resource file resource_args = ["Description", some_pdf, True, "Type"] From c579a96fccd62ba5386af0197beb0289d06c708a Mon Sep 17 00:00:00 2001 From: Jordan <21129425+ItIsJordan@users.noreply.github.com> Date: Tue, 16 Apr 2024 15:26:27 +0100 Subject: [PATCH 18/24] Update usage.rst Updates usage documentation to note default licence --- docs/usage.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/usage.rst b/docs/usage.rst index 48a23ba5..48147fac 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -133,6 +133,11 @@ The ``resource_license`` is in the form of a dictionary with mandatory string `` The optional argument ``file_type="HistFactory"`` (default value of ``None``) can be used to identify statistical models provided in the HistFactory JSON format rather than relying on certain trigger words in the ``description`` (see `pyhf section of submission documentation`_). +**Please note:** The default license applied to records uploaded to HEPData is `CC0`_. You do not +need to specify a license by default. + +.. _`CC0`: https://creativecommons.org/public-domain/cc0/ + The ``add_link`` function can alternatively be used to add a link to an external resource: :: @@ -329,6 +334,11 @@ Adding a data license You can add data license information to a table using the ``add_data_license`` function of the Table class. This function takes mandatory ``name`` and ``url`` string arguments, as well as an optional ``description``. +**Please note:** The default license applied to records uploaded to HEPData is `CC0`_. You do not +need to specify a license by default. + +.. _`CC0`: https://creativecommons.org/public-domain/cc0/ + :: table.add_data_license("CC BY 4.0", "https://creativecommons.org/licenses/by/4.0/") From 60bcbe05e3c6ae1bb6bc7b1837387d4e30cfdd50 Mon Sep 17 00:00:00 2001 From: Jordan <21129425+ItIsJordan@users.noreply.github.com> Date: Wed, 17 Apr 2024 12:54:55 +0100 Subject: [PATCH 19/24] Pylint fix Fixes pylint error around use of open() for files --- tests/test_submission.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_submission.py b/tests/test_submission.py index ed30b5a9..6bee2c01 100644 --- a/tests/test_submission.py +++ b/tests/test_submission.py @@ -75,9 +75,9 @@ def test_create_files(self): testdir = tmp_directory_name() testpath = "./testfile.txt" - # Create test file and set cleanup - f = open(testpath, "a") - f.close() + with open(testpath, "a", encoding="utf-8") as f: + f.close() + self.addCleanup(os.remove, testpath) # Create submission and set values for testing From 1968670ffbab9b15f164298a383d0ddc029fc9ae Mon Sep 17 00:00:00 2001 From: Jordan <21129425+ItIsJordan@users.noreply.github.com> Date: Wed, 17 Apr 2024 15:16:58 +0100 Subject: [PATCH 20/24] Update usage documentation Updates the documentation for usage in usage.rst to improve licence notice clarity. Now mentions that a licence does not need to be specified if it is CC0. --- docs/usage.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/usage.rst b/docs/usage.rst index 48147fac..c6d2e7d5 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -133,8 +133,8 @@ The ``resource_license`` is in the form of a dictionary with mandatory string `` The optional argument ``file_type="HistFactory"`` (default value of ``None``) can be used to identify statistical models provided in the HistFactory JSON format rather than relying on certain trigger words in the ``description`` (see `pyhf section of submission documentation`_). -**Please note:** The default license applied to records uploaded to HEPData is `CC0`_. You do not -need to specify a license by default. +**Please note:** The default license applied to all data uploaded to HEPData is `CC0`_. You do not +need to specify a license for a resource file unless it differs from `CC0`_. .. _`CC0`: https://creativecommons.org/public-domain/cc0/ @@ -334,8 +334,8 @@ Adding a data license You can add data license information to a table using the ``add_data_license`` function of the Table class. This function takes mandatory ``name`` and ``url`` string arguments, as well as an optional ``description``. -**Please note:** The default license applied to records uploaded to HEPData is `CC0`_. You do not -need to specify a license by default. +**Please note:** The default license applied to all data uploaded to HEPData is `CC0`_. You do not +need to specify a license for a data table unless it differs from `CC0`_. .. _`CC0`: https://creativecommons.org/public-domain/cc0/ From e4d7e7e3968762a9f1b98b5961212d34c19dcaaa Mon Sep 17 00:00:00 2001 From: Jordan <21129425+ItIsJordan@users.noreply.github.com> Date: Wed, 17 Apr 2024 15:23:36 +0100 Subject: [PATCH 21/24] Remove duplicate ref in usage.rst Removes duplicate reference for `CC0` URL in usage.rst. --- docs/usage.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/usage.rst b/docs/usage.rst index c6d2e7d5..410f0002 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -337,8 +337,6 @@ This function takes mandatory ``name`` and ``url`` string arguments, as well as **Please note:** The default license applied to all data uploaded to HEPData is `CC0`_. You do not need to specify a license for a data table unless it differs from `CC0`_. -.. _`CC0`: https://creativecommons.org/public-domain/cc0/ - :: table.add_data_license("CC BY 4.0", "https://creativecommons.org/licenses/by/4.0/") From 3742535fa647befa2f3fcda21f254998eede777b Mon Sep 17 00:00:00 2001 From: Graeme Watt Date: Thu, 18 Apr 2024 12:02:46 +0100 Subject: [PATCH 22/24] Remove license addition from Getting_started.ipynb * A license will usually not be needed, so remove for clarity. --- examples/Getting_started.ipynb | 58 +++++++--------------------------- 1 file changed, 12 insertions(+), 46 deletions(-) diff --git a/examples/Getting_started.ipynb b/examples/Getting_started.ipynb index 0934890a..1b323b1d 100644 --- a/examples/Getting_started.ipynb +++ b/examples/Getting_started.ipynb @@ -27,8 +27,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "Welcome to JupyROOT 6.26/06\n", - "hepdata_lib version 0.14.1\n" + "Welcome to JupyROOT 6.30/04\n", + "hepdata_lib version 0.15.0\n" ] } ], @@ -265,38 +265,13 @@ "If you want, the original data file can be attached to the table as an additional resource file." ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The default license for HEPData records is [CC0](https://creativecommons.org/publicdomain/zero/1.0/legalcode) (see [Terms of Use](https://www.hepdata.net/terms)), but it is possible to specify a different license for both additional resource files and data tables." - ] - }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ - "license = {\"name\": \"CC BY 4.0\", \"url\": \"https://creativecommons.org/licenses/by/4.0/\", \"description\": \"This license enables reusers to distribute, remix, adapt, and build upon the material in any medium or format, so long as attribution is given to the creator.\"}" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [], - "source": [ - "table.add_additional_resource(\"Original data file\", \"example_inputs/effacc_signal.txt\", copy_file=True, resource_license=license)" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [], - "source": [ - "table.add_data_license(license[\"name\"], license[\"url\"])" + "table.add_additional_resource(\"Original data file\", \"example_inputs/effacc_signal.txt\", copy_file=True)" ] }, { @@ -308,7 +283,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 12, "metadata": {}, "outputs": [], "source": [ @@ -324,7 +299,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 13, "metadata": {}, "outputs": [], "source": [ @@ -341,7 +316,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 14, "metadata": {}, "outputs": [], "source": [ @@ -358,7 +333,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 15, "metadata": {}, "outputs": [ { @@ -382,7 +357,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 16, "metadata": {}, "outputs": [ { @@ -400,7 +375,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 17, "metadata": {}, "outputs": [ { @@ -409,7 +384,7 @@ "text": [ "---\n", "additional_resources:\n", - "- description: Created with hepdata_lib 0.14.0\n", + "- description: Created with hepdata_lib 0.15.0\n", " location: https://doi.org/10.5281/zenodo.1217998\n", "- description: Webpage with all figures and tables\n", " location: https://cms-results.web.cern.ch/cms-results/public-results/publications/B2G-16-029/\n", @@ -437,21 +412,12 @@ "---\n", "additional_resources:\n", "- description: Original data file\n", - " license:\n", - " description: This license enables reusers to distribute, remix, adapt, and build\n", - " upon the material in any medium or format, so long as attribution is given to\n", - " the creator.\n", - " name: CC BY 4.0\n", - " url: https://creativecommons.org/licenses/by/4.0/\n", " location: effacc_signal.txt\n", "- description: Image file\n", " location: signalEffVsMass.png\n", "- description: Thumbnail image file\n", " location: thumb_signalEffVsMass.png\n", "data_file: additional_figure_1.yaml\n", - "data_license:\n", - " name: CC BY 4.0\n", - " url: https://creativecommons.org/licenses/by/4.0/\n", "description: Signal selection efficiency times acceptance as a function of resonance\n", " mass for a spin-2 bulk graviton decaying to WW and a spin-1 W' decaying to WZ.\n", "keywords:\n", @@ -477,7 +443,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 18, "metadata": {}, "outputs": [ { @@ -565,7 +531,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.12" + "version": "3.12.2" } }, "nbformat": 4, From d87017d9bf1eaefb6d728c7d1743b55291cad2d5 Mon Sep 17 00:00:00 2001 From: Graeme Watt Date: Thu, 18 Apr 2024 12:04:14 +0100 Subject: [PATCH 23/24] Revert "Remove get_license() from Submission class" This reverts commit 2cf90464ec5a05e122504019d37b444da6890e51. --- hepdata_lib/__init__.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/hepdata_lib/__init__.py b/hepdata_lib/__init__.py index 3bcc6b01..7e565d0e 100644 --- a/hepdata_lib/__init__.py +++ b/hepdata_lib/__init__.py @@ -565,6 +565,17 @@ def __init__(self): "Created with hepdata_lib " + __version__, "https://doi.org/10.5281/zenodo.1217998") + @staticmethod + def get_license(): + """Return the default license.""" + data_license = {} + data_license["name"] = "cc-by-4.0" + data_license["url"] = "https://creativecommons.org/licenses/by/4.0/" + data_license[ + "description"] = "The content can be shared and adapted but you must\ + give appropriate credit and cannot restrict access to others." + return data_license + def add_table(self, table): """Append table to tables list. @@ -659,6 +670,7 @@ def create_files(self, outdir=".", validate=True, remove_old=False): # Write general info about submission submission = {} + submission["data_license"] = self.get_license() submission["comment"] = self.comment if self.related_records: submission["related_to_hepdata_records"] = self.related_records From 2ce00358975563b445005a924106bbbe73b55374 Mon Sep 17 00:00:00 2001 From: Graeme Watt Date: Thu, 18 Apr 2024 13:04:32 +0100 Subject: [PATCH 24/24] Change default license from "CC BY 4.0" to "CC0" * Written in the first document of the submission.yaml file, although it is not supported by the JSON schema or the HEPData web application. --- examples/Getting_started.ipynb | 5 +++++ hepdata_lib/__init__.py | 10 +++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/examples/Getting_started.ipynb b/examples/Getting_started.ipynb index 1b323b1d..767d57f1 100644 --- a/examples/Getting_started.ipynb +++ b/examples/Getting_started.ipynb @@ -406,6 +406,11 @@ " from theoretical calculations in the bulk graviton and heavy vector triplet models,\n", " spin-2 WW resonances with mass smaller than 1.07~TeV and spin-1 WZ resonances lighter\n", " than 3.05~TeV, respectively, are excluded at 95\\% confidence level.\n", + "data_license:\n", + " description: CC0 enables reusers to distribute, remix, adapt, and build upon the\n", + " material in any medium or format, with no conditions.\n", + " name: CC0\n", + " url: https://creativecommons.org/publicdomain/zero/1.0/\n", "record_ids:\n", "- id: 1657397\n", " type: inspire\n", diff --git a/hepdata_lib/__init__.py b/hepdata_lib/__init__.py index 7e565d0e..e919b5f7 100644 --- a/hepdata_lib/__init__.py +++ b/hepdata_lib/__init__.py @@ -569,11 +569,11 @@ def __init__(self): def get_license(): """Return the default license.""" data_license = {} - data_license["name"] = "cc-by-4.0" - data_license["url"] = "https://creativecommons.org/licenses/by/4.0/" - data_license[ - "description"] = "The content can be shared and adapted but you must\ - give appropriate credit and cannot restrict access to others." + data_license["name"] = "CC0" + data_license["url"] = "https://creativecommons.org/publicdomain/zero/1.0/" + data_license["description"] = ( + "CC0 enables reusers to distribute, remix, adapt, and build upon the material " + "in any medium or format, with no conditions.") return data_license def add_table(self, table):