diff --git a/pyDataverse/models.py b/pyDataverse/models.py index 2a835e2..b955af9 100644 --- a/pyDataverse/models.py +++ b/pyDataverse/models.py @@ -320,6 +320,12 @@ class Dataset(DVObject): __attr_import_dv_up_journal_fields_arrays : dict Attributes of Dataverse API Upload Dataset JSON metadata standard inside [\'datasetVersion\'][\'metadataBlocks\'][\'journal\'][\'fields\']. + __attr_import_dv_up_astrophysics_fields_values : list + Attributes of Dataverse API Upload Dataset JSON metadata standard inside + [\'datasetVersion\'][\'metadataBlocks\'][\'astrophysics\'][\'fields\']. + __attr_import_dv_up_astrophysics_fields_arrays : dict + Attributes of Dataverse API Upload Dataset JSON metadata standard inside + [\'datasetVersion\'][\'metadataBlocks\'][\'astrophysics\'][\'fields\'] __attr_dict_dv_up_required :list Required attributes for valid `dv_up` metadata dict creation. __attr_dict_dv_up_type_class_primitive : list @@ -446,6 +452,31 @@ class Dataset(DVObject): __attr_import_dv_up_journal_fields_arrays = { "journalVolumeIssue": ["journalVolume", "journalIssue", "journalPubDate"] } + + __attr_import_dv_up_astrophysics_fields_values = [ + "astroType", + "astroFacility", + "astroInstrumnet", + "astroObject", + "resolution.Spatial", + "resolution.Temporal", + "coverage.Spectral.Bandpass", + "coverage.Spectral.CentralWavelength", + "coverage.Spatial", + "coverage.Depth", + "coverage.ObjectDensity", + "coverage.ObjectCount", + "coverage.SkyFraction", + "coverage.Polarization", + "redshiftType", + "resolution.Redshift" + ] + + __attr_import_dv_up_astrophysics_fields_arrays = { + "coverage.Spectral.Wavelength": ["coverage.Spectral.MinimumWavelength", "coverage.Spectral.MaximumWavelength"], + "coverage.Temporal": ["coverage.Temporal.StartTime", "coverage.Temporal.StopTime"], + "coverage.RedshiftValue": ["coverage.Redshift.MinimumValue", "coverage.Redshift.MaximumValue"] + } __attr_dict_dv_up_required = [ "author", "datasetContact", @@ -461,9 +492,21 @@ class Dataset(DVObject): "authorAffiliation", "authorIdentifier", "authorName", + "astroType", + "astroFacility", + "astroInstrumnet", + "astroObject", "characteristicOfSources", "city", "contributorName", + "coverage.Spectral.Bandpass", + "coverage.Spectral.CentralWavelength", + "coverage.Spatial", + "coverage.Depth", + "coverage.ObjectDensity", + "coverage.ObjectCount", + "coverage.SkyFraction", + "coverage.Polarization", "dateOfDeposit", "dataSources", "depositor", @@ -501,6 +544,10 @@ class Dataset(DVObject): + __attr_import_dv_up_geospatial_fields_arrays["geographicBoundingBox"] + __attr_import_dv_up_socialscience_fields_values + __attr_import_dv_up_journal_fields_arrays["journalVolumeIssue"] + + __attr_import_dv_up_astrophysics_fields_values + + __attr_import_dv_up_astrophysics_fields_arrays["coverage.Temporal"] + + __attr_import_dv_up_astrophysics_fields_arrays["coverage.Spectral.Wavelength"] + + __attr_import_dv_up_astrophysics_fields_arrays["coverage.RedshiftValue"] + [ "socialScienceNotesType", "socialScienceNotesSubject", @@ -512,10 +559,12 @@ class Dataset(DVObject): list(__attr_import_dv_up_citation_fields_arrays.keys()) + list(__attr_import_dv_up_geospatial_fields_arrays.keys()) + list(__attr_import_dv_up_journal_fields_arrays.keys()) + + list(__attr_import_dv_up_astrophysics_fields_arrays.keys()) + ["series", "socialScienceNotes", "targetSampleSize"] ) __attr_dict_dv_up_type_class_controlled_vocabulary = [ "authorIdentifierScheme", + "astroType", "contributorType", "country", "journalArticleType", @@ -529,6 +578,7 @@ class Dataset(DVObject): "geospatial_displayName", "socialscience_displayName", "journal_displayName", + "astrophysics_displayName" ] def __init__(self, data=None): @@ -637,6 +687,26 @@ def __init__(self, data=None): "journal_displayName", "journalVolumeIssue", "journalArticleType", + "astrophysics_displayName", + "astroType", + "astroFacility", + "astroInstrument", + "astroObject", + "resolution.Spatial", + "resolution.Temporal", + "coverage.Spectral.Bandpass", + "coverage.Spectral.CentralWavelength", + "coverage.Spatial", + "coverage.Depth", + "coverage.ObjectDensity", + "coverage.ObjectCount", + "coverage.SkyFraction", + "coverage.Polarization", + "redshiftType", + "resolution.Redshift", + "coverage.Spectral.Wavelength", + "coverage.Temporal", + "coverage.RedshiftValue" ] def validate_json(self, filename_schema=None): @@ -1032,6 +1102,41 @@ def from_json( else: # TODO: Exception pass + + #astrophysics + if "astrophysics" in json_dict["datasetVersion"]["metadataBlocks"]: + astrophysics = json_dict["datasetVersion"]["metadataBlocks"]["astrophysics"] + + if "displayName" in astrophysics: + self.__setattr__("astrophysics_displayName", astrophysics["displayName"]) + + for field in astrophysics["fields"]: + if ( + field["typeName"] + in self.__attr_import_dv_up_astrophysics_fields_values + ): + data[field["typeName"]] = field["value"] + elif( + field["typeName"] + in self.__attr_import_dv_up_astrophysics_fields_arrays + ): + data[field["typeName"]] = self.__parse_field_array( + field["value"], + self.__attr_import_dv_up_astrophysics_fields_arrays[ + field["typeName"] + ], + ) + else: + print( + "Attribute {0} not valid for import (dv_up).".format( + field["typeName"] + ) + ) + + else: + # TODO: Exception + pass + elif data_format == "dataverse_download": print("INFO: Not implemented yet.") elif data_format == "dspace": @@ -1170,7 +1275,7 @@ def json(self, data_format=None, validate=True, filename_schema=None): # dataset # Generate first level attributes for attr in self.__attr_import_dv_up_datasetVersion_values: - if attr in data_dict: + if attr in data_dict and data_dict[attr] is not None: data["datasetVersion"][attr] = data_dict[attr] # citation @@ -1179,19 +1284,14 @@ def json(self, data_format=None, validate=True, filename_schema=None): # Generate first level attributes for attr in self.__attr_import_dv_up_citation_fields_values: - if attr in data_dict: + if attr in data_dict and data_dict[attr] is not None: v = data_dict[attr] - if isinstance(v, list): - multiple = True - else: - multiple = False + multiple = isinstance(v, list) if attr in self.__attr_dict_dv_up_type_class_primitive: type_class = "primitive" elif attr in self.__attr_dict_dv_up_type_class_compound: type_class = "compound" - elif ( - attr in self.__attr_dict_dv_up_type_class_controlled_vocabulary - ): + elif attr in self.__attr_dict_dv_up_type_class_controlled_vocabulary: type_class = "controlledVocabulary" citation["fields"].append( { @@ -1203,12 +1303,8 @@ def json(self, data_format=None, validate=True, filename_schema=None): ) # Generate fields attributes - for ( - key, - val, - ) in self.__attr_import_dv_up_citation_fields_arrays.items(): - if key in data_dict: - v = data_dict[key] + for key, val in self.__attr_import_dv_up_citation_fields_arrays.items(): + if key in data_dict and data_dict[key] is not None: citation["fields"].append( { "typeName": key, @@ -1254,59 +1350,50 @@ def json(self, data_format=None, validate=True, filename_schema=None): + ["geospatial_displayName"] ): if attr in data_dict: - geospatial = {} - if attr != "geospatial_displayName": - geospatial["fields"] = [] - break + geospatial = {"fields": []} + break if "geospatial_displayName" in data_dict: geospatial["displayName"] = data_dict["geospatial_displayName"] - # Generate first level attributes - for attr in self.__attr_import_dv_up_geospatial_fields_values: - if attr in data_dict: - v = data_dict[attr] - if isinstance(v, list): - multiple = True - else: - multiple = False - if attr in self.__attr_dict_dv_up_type_class_primitive: - type_class = "primitive" - elif attr in self.__attr_dict_dv_up_type_class_compound: - type_class = "compound" - elif ( - attr in self.__attr_dict_dv_up_type_class_controlled_vocabulary - ): - type_class = "controlledVocabulary" - geospatial["fields"].append( - { - "typeName": attr, - "multiple": multiple, - "typeClass": type_class, - "value": v, - } - ) + # Generate first level attributes + for attr in self.__attr_import_dv_up_geospatial_fields_values: + if attr in data_dict and data_dict[attr] is not None: + v = data_dict[attr] + multiple = isinstance(v, list) + if attr in self.__attr_dict_dv_up_type_class_primitive: + type_class = "primitive" + elif attr in self.__attr_dict_dv_up_type_class_compound: + type_class = "compound" + elif attr in self.__attr_dict_dv_up_type_class_controlled_vocabulary: + type_class = "controlledVocabulary" + geospatial["fields"].append( + { + "typeName": attr, + "multiple": multiple, + "typeClass": type_class, + "value": v, + } + ) - # Generate fields attributes - for ( - key, - val, - ) in self.__attr_import_dv_up_geospatial_fields_arrays.items(): - if key in data_dict: - geospatial["fields"].append( - { - "typeName": key, - "multiple": True, - "typeClass": "compound", - "value": self.__generate_field_arrays(key, val), - } - ) + # Generate fields attributes + for key, val in self.__attr_import_dv_up_geospatial_fields_arrays.items(): + if key in data_dict and data_dict[key] is not None: + geospatial["fields"].append( + { + "typeName": key, + "multiple": True, + "typeClass": "compound", + "value": self.__generate_field_arrays(key, val), + } + ) # socialscience + socialscience = None for attr in self.__attr_import_dv_up_socialscience_fields_values + [ "socialscience_displayName" ]: - if attr in data_dict: + if attr in data_dict: socialscience = {} if attr != "socialscience_displayName": socialscience["fields"] = [] @@ -1317,19 +1404,14 @@ def json(self, data_format=None, validate=True, filename_schema=None): # Generate first level attributes for attr in self.__attr_import_dv_up_socialscience_fields_values: - if attr in data_dict: + if attr in data_dict and data_dict[attr] is not None: v = data_dict[attr] - if isinstance(v, list): - multiple = True - else: - multiple = False + multiple = isinstance(v, list) if attr in self.__attr_dict_dv_up_type_class_primitive: type_class = "primitive" elif attr in self.__attr_dict_dv_up_type_class_compound: type_class = "compound" - elif ( - attr in self.__attr_dict_dv_up_type_class_controlled_vocabulary - ): + elif attr in self.__attr_dict_dv_up_type_class_controlled_vocabulary: type_class = "controlledVocabulary" socialscience["fields"].append( { @@ -1340,6 +1422,8 @@ def json(self, data_format=None, validate=True, filename_schema=None): } ) + + # Generate targetSampleSize attributes if "targetSampleSize" in data_dict: target_sample_size = data_dict["targetSampleSize"] @@ -1433,6 +1517,7 @@ def json(self, data_format=None, validate=True, filename_schema=None): journal["fields"] = [] break + if "journal_displayName" in data_dict: journal["displayName"] = data_dict["journal_displayName"] @@ -1448,9 +1533,7 @@ def json(self, data_format=None, validate=True, filename_schema=None): type_class = "primitive" elif attr in self.__attr_dict_dv_up_type_class_compound: type_class = "compound" - elif ( - attr in self.__attr_dict_dv_up_type_class_controlled_vocabulary - ): + elif attr in self.__attr_dict_dv_up_type_class_controlled_vocabulary: type_class = "controlledVocabulary" journal["fields"].append( { @@ -1462,10 +1545,7 @@ def json(self, data_format=None, validate=True, filename_schema=None): ) # Generate fields attributes - for ( - key, - val, - ) in self.__attr_import_dv_up_journal_fields_arrays.items(): + for key, val in self.__attr_import_dv_up_journal_fields_arrays.items(): if key in data_dict: journal["fields"].append( { @@ -1475,16 +1555,73 @@ def json(self, data_format=None, validate=True, filename_schema=None): "value": self.__generate_field_arrays(key, val), } ) + + + # astrophysics + for attr in ( + self.__attr_import_dv_up_astrophysics_fields_values + + list(self.__attr_import_dv_up_astrophysics_fields_arrays.keys()) + + ["astrophysics_displayName"] + ): + if attr in data_dict: + astrophysics = {} + if attr != "astrophysics_displayName": + astrophysics["fields"] = [] + break + + + if "astrophysics_displayName" in data_dict: + astrophysics["displayName"] = data_dict["astrophysics_displayName"] + + # Generate first level attributes + for attr in self.__attr_import_dv_up_astrophysics_fields_values: + if attr in data_dict: + v = data_dict[attr] + if isinstance(v, list): + multiple = True + else: + multiple = False + if attr in self.__attr_dict_dv_up_type_class_primitive: + type_class = "primitive" + elif attr in self.__attr_dict_dv_up_type_class_compound: + type_class = "compound" + elif attr in self.__attr_dict_dv_up_type_class_controlled_vocabulary: + type_class = "controlledVocabulary" + astrophysics["fields"].append( + { + "typeName": attr, + "multiple": multiple, + "typeClass": type_class, + "value": v, + } + ) + + # Generate fields attributes + for key, val in self.__attr_import_dv_up_astrophysics_fields_arrays.items(): + if key in data_dict: + astrophysics["fields"].append( + { + "typeName": key, + "multiple": True, + "typeClass": "compound", + "value": self.__generate_field_arrays(key, val), + } + ) data["datasetVersion"]["metadataBlocks"]["citation"] = citation + data["datasetVersion"]["metadataBlocks"]["astrophysics"] = astrophysics if "socialscience" in locals(): data["datasetVersion"]["metadataBlocks"]["socialscience"] = ( socialscience - ) + ) if "geospatial" in locals(): data["datasetVersion"]["metadataBlocks"]["geospatial"] = geospatial if "journal" in locals(): + print("'Journal' matadata added to dataset") data["datasetVersion"]["metadataBlocks"]["journal"] = journal + #if "astrophysics" in locals(): + # print("'Astrophysics' metadata added to dataset") + # data["datasetVersion"]["metadataBlocks"]["astrophysics"] = astrophysics elif data_format == "dspace": data = None print("INFO: Not implemented yet.") @@ -1499,6 +1636,7 @@ def json(self, data_format=None, validate=True, filename_schema=None): return json_str + class Datafile(DVObject): """Base class for the Dataverse data type `Datafile`. diff --git a/pyDataverse/schemas/json/dataset_upload_default_schema.json b/pyDataverse/schemas/json/dataset_upload_default_schema.json index 398e51e..75eb4d6 100644 --- a/pyDataverse/schemas/json/dataset_upload_default_schema.json +++ b/pyDataverse/schemas/json/dataset_upload_default_schema.json @@ -431,10 +431,136 @@ } } } + }, + "astrophysics": { + "$id": "#/properties/datasetVersion/properties/metadataBlocks/properties/astrophysics", + "type": "object", + "properties": { + "displayName": { + "$id": "#/properties/datasetVersion/properties/metadataBlocks/properties/astrophysics/properties/displayName", + "type": "string" + }, + "fields": { + "$id": "#/properties/datasetVersion/properties/metadataBlocks/properties/astrophysics/properties/fields", + "type": "array", + "items": { + "anyOf": [ + { + "$id": "#/properties/datasetVersion/properties/metadataBlocks/properties/astrophysics/properties/fields/items/anyOf/0", + "type": "object", + "properties": { + "typeName": { + "$id": "#/properties/datasetVersion/properties/metadataBlocks/properties/astrophysics/properties/fields/items/anyOf/0/properties/typeName", + "type": "string" + }, + "multiple": { + "$id": "#/properties/datasetVersion/properties/metadataBlocks/properties/astrophysics/properties/fields/items/anyOf/0/properties/multiple", + "type": "boolean" + }, + "typeClass": { + "$id": "#/properties/datasetVersion/properties/metadataBlocks/properties/astrophysics/properties/fields/items/anyOf/0/properties/typeClass", + "type": "string" + }, + "value": { + "anyOf": [ + { + "$id": "#/properties/datasetVersion/properties/metadataBlocks/properties/astrophysics/properties/fields/items/anyOf/0/properties/value", + "type": "array", + "items": { + "anyOf": [ + { + "$id": "#/properties/datasetVersion/properties/metadataBlocks/properties/astrophysics/properties/fields/items/anyOf/0/properties/value/items/anyOf/0", + "type": "object", + "properties":{ + "coverage.Spectral.Wavelength": { + "$id": "#/properties/datasetVersion/properties/metadataBlocks/properties/astrophysics/properties/fields/items/anyOf/0/properties/value/items/anyOf/0/properties/coverage.Spectral.Wavelength", + "type": "object", + "properties": { + "typeName": { + "$id": "#/properties/datasetVersion/properties/metadataBlocks/properties/astrophysics/properties/fields/items/anyOf/0/properties/value/items/anyOf/0/properties/coverage.Spectral.Wavelength/properties/typeName", + "type": "string" + }, + "multiple": { + "$id": "#/properties/datasetVersion/properties/metadataBlocks/properties/astrophysics/properties/fields/items/anyOf/0/properties/value/items/anyOf/0/properties/coverage.Spectral.Wavelength/properties/multiple", + "type": "boolean" + }, + "typeClass": { + "$id": "#/properties/datasetVersion/properties/metadataBlocks/properties/astrophysics/properties/fields/items/anyOf/0/properties/value/items/anyOf/0/properties/coverage.Spectral.Wavelength/properties/typeClass", + "type": "string" + }, + "value":{ + "$id": "#/properties/datasetVersion/properties/metadataBlocks/properties/astrophysics/properties/fields/items/anyOf/0/properties/value/items/anyOf/0/properties/coverage.Spectral.Wavelength/properties/value", + "type": "string" + } + } + }, + "coverage.Temporal": { + "$id": "#/properties/datasetVersion/properties/metadataBlocks/properties/astrophysics/properties/fields/items/anyOf/0/properties/value/items/anyOf/0/properties/coverage.Temporal", + "type": "object", + "properties": { + "typeName": { + "$id": "#/properties/datasetVersion/properties/metadataBlocks/properties/astrophysics/properties/fields/items/anyOf/0/properties/value/items/anyOf/0/properties/coverage.Temporal/properties/typeName", + "type": "string" + }, + "multiple": { + "$id": "#/properties/datasetVersion/properties/metadataBlocks/properties/astrophysics/properties/fields/items/anyOf/0/properties/value/items/anyOf/0/properties/coverage.Temporal/properties/multiple", + "type": "boolean" + }, + "typeClass": { + "$id": "#/properties/datasetVersion/properties/metadataBlocks/properties/astrophysics/properties/fields/items/anyOf/0/properties/value/items/anyOf/0/properties/coverage.Temporal/properties/typeClass", + "type": "string" + }, + "value":{ + "$id": "#/properties/datasetVersion/properties/metadataBlocks/properties/astrophysics/properties/fields/items/anyOf/0/properties/value/items/anyOf/0/properties/coverage.Temporal/properties/value", + "type": "string" + } + } + }, + "coverage.RedshiftValue": { + "$id": "#/properties/datasetVersion/properties/metadataBlocks/properties/astrophysics/properties/fields/items/anyOf/0/properties/value/items/anyOf/0/properties/coverage.RedshiftValue", + "type": "object", + "properties": { + "typeName": { + "$id": "#/properties/datasetVersion/properties/metadataBlocks/properties/astrophysics/properties/fields/items/anyOf/0/properties/value/items/anyOf/0/properties/coverage.RedshiftValue/properties/typeName", + "type": "string" + }, + "multiple": { + "$id": "#/properties/datasetVersion/properties/metadataBlocks/properties/astrophysics/properties/fields/items/anyOf/0/properties/value/items/anyOf/0/properties/coverage.RedshiftValue/properties/multiple", + "type": "boolean" + }, + "typeClass": { + "$id": "#/properties/datasetVersion/properties/metadataBlocks/properties/astrophysics/properties/fields/items/anyOf/0/properties/value/items/anyOf/0/properties/coverage.RedshiftValue/properties/typeClass", + "type": "string" + }, + "value": { + "$id": "#/properties/datasetVersion/properties/metadataBlocks/properties/astrophysics/properties/fields/items/anyOf/0/properties/value/items/anyOf/0/properties/coverage.RedshiftValue/properties/value", + "type": "string" + } + } + } + } + } + ] + } + }, + { + "$id": "#/properties/datasetVersion/properties/metadataBlocks/properties/astrophysics/properties/fields/items/anyOf/0/properties/value", + "type": "string" + } + ], + "$id": "#/properties/datasetVersion/properties/metadataBlocks/properties/astrophysics/properties/fields/items/anyOf/0/properties/value/items" + } + } + } + ], + "$id": "#/properties/datasetVersion/properties/metadataBlocks/properties/astrophysics/properties/fields/items" + } + } + } } } } } } } -} +} \ No newline at end of file