Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

extra metadata dict, initialized inside from_owl_uri #697

Merged
merged 7 commits into from
Aug 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 65 additions & 33 deletions cdci_data_analysis/analysis/parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,8 @@
allowed_values=None,
min_value = None,
max_value = None,

extra_metadata=None,
**kwargs
):

Expand Down Expand Up @@ -261,6 +263,7 @@
self._max_value = max_value
self._bound_units = self.units
self.value = value
self.extra_metadata = extra_metadata


self._arg_list = [self.name]
Expand Down Expand Up @@ -463,6 +466,8 @@
restrictions['schema'] = self.schema
if restrictions:
reprjson[0]['restrictions'] = restrictions
if getattr(self, 'extra_metadata', None) is not None:
reprjson[0]['extra_metadata'] = self.extra_metadata

Check warning on line 470 in cdci_data_analysis/analysis/parameters.py

View check run for this annotation

Codecov / codecov/patch

cdci_data_analysis/analysis/parameters.py#L470

Added line #L470 was not covered by tests
if getattr(self, 'owl_uris', None):
if isinstance(self.owl_uris, str):
reprjson[0]['owl_uri'] = [ self.owl_uris ]
Expand All @@ -487,14 +492,16 @@
**kwargs):
from oda_api.ontology_helper import Ontology

metadata_keys = ['label', 'description', 'group']

if ontology_path is not None and ontology_object is not None:
raise RuntimeError("Both ontology_path and ontology_object parameters are set.")
elif ontology_path is None and ontology_object is None:
logger.warning('Ontology path/object not set in Parameter.from_owl_uri(). '
'Trying to find parameter which have %s directly set. '
'extra_ttl will be ignored ', owl_uri)
parameter_hierarchy = [ owl_uri ]
par_format = par_unit = allowed_values = min_value = max_value = None
par_format = par_unit = allowed_values = min_value = max_value = label = description = group = None
else:
if ontology_path is not None:
if isinstance(ontology_path, (str, os.PathLike)):
Expand All @@ -514,13 +521,18 @@
par_unit = onto.get_parameter_unit(owl_uri)
min_value, max_value = onto.get_limits(owl_uri)
allowed_values = onto.get_allowed_values(owl_uri)

label = onto.get_direct_annotation(owl_uri, "label")
description = onto.get_direct_annotation(owl_uri, "description")
group = onto.get_direct_annotation(owl_uri, "group")

for owl_superclass_uri in parameter_hierarchy:
for python_subclass in subclasses_recursive(cls):
logger.debug("searching for class with owl_uri=%s, found %s", owl_superclass_uri, python_subclass)
if python_subclass.matches_owl_uri(owl_superclass_uri):
logger.info("will construct %s by owl_uri %s", python_subclass, owl_superclass_uri)
call_kwargs = {}
call_kwargs = {
'extra_metadata': {key: val for key, val in zip(metadata_keys, [label, description, group]) if
val is not None}}
call_signature = signature(python_subclass)
var_kw_signature = call_parameter.VAR_KEYWORD in [x.kind for x in call_signature.parameters.values()]

Expand Down Expand Up @@ -566,15 +578,16 @@
class String(Parameter):
owl_uris = ("http://www.w3.org/2001/XMLSchema#str", "http://odahub.io/ontology#String")

def __init__(self, value=None, name_format='str', name=None, allowed_values = None):
def __init__(self, value=None, name_format='str', name=None, allowed_values = None, extra_metadata = None):

_allowed_units = ['str']
super().__init__(value=value,
units=name_format,
check_value=self.check_name_value,
name=name,
allowed_units=_allowed_units,
allowed_values=allowed_values)
allowed_values=allowed_values,
extra_metadata=extra_metadata)

@staticmethod
def check_name_value(value, units=None, name=None, par_format=None):
Expand Down Expand Up @@ -671,7 +684,8 @@
check_value=None,
min_value= None,
max_value = None,
units_name = None):
units_name = None,
extra_metadata=None):

super().__init__(value=value,
units=units,
Expand All @@ -684,7 +698,8 @@
allowed_units=allowed_units,
min_value=min_value,
max_value=max_value,
units_name = units_name)
units_name = units_name,
extra_metadata=extra_metadata)



Expand All @@ -700,7 +715,8 @@
max_value = None,
units_name = None,
default_units = None,
allowed_units = None):
allowed_units = None,
extra_metadata=None):

super().__init__(value=value,
units=units,
Expand All @@ -712,7 +728,8 @@
allowed_units=allowed_units,
min_value = min_value,
max_value = max_value,
units_name = units_name)
units_name = units_name,
extra_metadata=extra_metadata)

def set_par_internal_value(self, value):
if isinstance(value, float):
Expand All @@ -725,13 +742,14 @@
owl_uris = ("http://odahub.io/ontology#TimeInstant",)
format_kw = 'T_format'

def __init__(self, value=None, T_format='isot', name=None, Time_format_name='T_format', par_default_format='isot'):
def __init__(self, value=None, T_format='isot', name=None, Time_format_name='T_format', par_default_format='isot', extra_metadata=None):

super().__init__(value=value,
par_format=T_format,
par_format_name=Time_format_name,
par_default_format=par_default_format,
name=name)
name=name,
extra_metadata=extra_metadata)

def get_default_value(self):
return self.get_value_in_default_format()
Expand Down Expand Up @@ -776,15 +794,16 @@
owl_uris = ("http://odahub.io/ontology#TimeDeltaIsDeprecated",)
format_kw = 'delta_T_format'

def __init__(self, value=None, delta_T_format='sec', name=None, delta_T_format_name=None, par_default_format='sec'):
def __init__(self, value=None, delta_T_format='sec', name=None, delta_T_format_name=None, par_default_format='sec', extra_metadata=None):
logging.warning(('TimeDelta parameter is deprecated. '
'It derives from Time, which is confusing. '
'Consider using TimeInterval parameter.'))
super().__init__(value=value,
T_format=delta_T_format,
Time_format_name=delta_T_format_name,
par_default_format=par_default_format,
name=name)
name=name,
extra_metadata=extra_metadata)

def get_value_in_format(self, units):
return getattr(self._astropy_time_delta, units)
Expand Down Expand Up @@ -816,7 +835,8 @@
default_units='s',
min_value=None,
max_value=None,
units_name = None):
units_name = None,
extra_metadata=None):

_allowed_units = ['s', 'minute', 'hour', 'day', 'year']
super().__init__(value=value,
Expand All @@ -826,13 +846,14 @@
min_value=min_value,
max_value=max_value,
units_name = units_name,
allowed_units=_allowed_units)
allowed_units=_allowed_units,
extra_metadata=extra_metadata)

class InputProdList(Parameter):
owl_uris = ('http://odahub.io/ontology#InputProdList',)

# TODO removal of the leading underscore cannot be done for compatibility with the plugins
def __init__(self, value=None, _format='names_list', name: str = None):
def __init__(self, value=None, _format='names_list', name: str = None, extra_metadata=None):
_allowed_units = ['names_list']

if value is None:
Expand All @@ -842,7 +863,8 @@
par_format=_format,
check_value=self.check_list_value,
name=name,
allowed_units=_allowed_units)
allowed_units=_allowed_units,
extra_metadata=extra_metadata)

@staticmethod
def _split(str_list):
Expand Down Expand Up @@ -903,7 +925,8 @@
name=None,
min_value = None,
max_value = None,
units_name = None):
units_name = None,
extra_metadata=None):

super().__init__(value=value,
units=units,
Expand All @@ -913,7 +936,8 @@
allowed_units=None,
min_value = min_value,
max_value = max_value,
units_name = units_name)
units_name = units_name,
extra_metadata=extra_metadata)


class Energy(Float):
Expand All @@ -928,7 +952,8 @@
check_value=None,
min_value = None,
max_value = None,
units_name = None):
units_name = None,
extra_metadata=None):

_allowed_units = ['keV', 'eV', 'MeV', 'GeV', 'TeV', 'Hz', 'MHz', 'GHz']

Expand All @@ -940,7 +965,8 @@
allowed_units=_allowed_units,
min_value = min_value,
max_value = max_value,
units_name = units_name)
units_name = units_name,
extra_metadata=extra_metadata)

class SpectralBoundary(Energy):
def __init__(self,
Expand All @@ -951,7 +977,8 @@
check_value=None,
min_value=None,
max_value=None,
units_name=None):
units_name=None,
extra_metadata=None):

# retro-compatibility with integral plugin
if check_value is None:
Expand All @@ -964,7 +991,8 @@
check_value=check_value,
min_value=min_value,
max_value=max_value,
units_name=units_name)
units_name=units_name,
extra_metadata=extra_metadata)

@staticmethod
def check_energy_value(value, units, name):
Expand All @@ -973,7 +1001,7 @@

class DetectionThreshold(Float):
owl_uris = ("http://odahub.io/ontology#DetectionThreshold",)
def __init__(self, value=None, units='sigma', name=None, min_value = None, max_value = None):
def __init__(self, value=None, units='sigma', name=None, min_value = None, max_value = None, extra_metadata=None):
_allowed_units = ['sigma']

super().__init__(value=value,
Expand All @@ -982,7 +1010,8 @@
name=name,
allowed_units=_allowed_units,
min_value = min_value,
max_value = max_value)
max_value = max_value,
extra_metadata=extra_metadata)

# 'sigma' is not astropy unit, so need to override methods
def get_value_in_units(self, units):
Expand All @@ -995,24 +1024,26 @@
self._value = None

class UserCatalog(Parameter):
def __init__(self, value=None, name_format='str', name=None):
def __init__(self, value=None, name_format='str', name=None, extra_metadata=None):
_allowed_units = ['str']
super().__init__(value=value,
par_format=name_format,
check_value=None,
name=name,
allowed_units=_allowed_units)
allowed_units=_allowed_units,
extra_metadata=extra_metadata)

class Boolean(Parameter):
owl_uris = ('http://www.w3.org/2001/XMLSchema#bool',"http://odahub.io/ontology#Boolean")

def __init__(self, value=None, name=None):
def __init__(self, value=None, name=None, extra_metadata=None):

self._true_rep = ['True', 'true', 'yes', '1', True]
self._false_rep = ['False', 'false', 'no', '0', False]
super().__init__(value=value,
name=name,
allowed_values=self._true_rep+self._false_rep
allowed_values=self._true_rep+self._false_rep,
extra_metadata = extra_metadata
)

@property
Expand All @@ -1031,15 +1062,16 @@
class StructuredParameter(Parameter):
owl_uris = ("http://odahub.io/ontology#StructuredParameter")

def __init__(self, value=None, name=None, schema={"oneOf": [{"type": "object"}, {"type": "array"}]}):
def __init__(self, value=None, name=None, schema={"oneOf": [{"type": "object"}, {"type": "array"}]}, extra_metadata=None):

self.schema = schema

if self.schema is None:
logger.warning("Parameter %s: Schema is not defined, will allow any structure.", name)

super().__init__(value=value,
name=name)
name=name,
extra_metadata=extra_metadata)

def check_schema(self):
if self.schema is not None:
Expand All @@ -1065,7 +1097,7 @@
class PhosphorosFiltersTable(StructuredParameter):
owl_uris = ('http://odahub.io/ontology#PhosphorosFiltersTable')

def __init__(self, value=None, name=None):
def __init__(self, value=None, name=None, extra_metadata=None):

# TODO: either list or the whole schema may be loaded from the external file, purely based on URI.
# If there is no additional check, this would allow to avoid even having the class.
Expand Down Expand Up @@ -1102,7 +1134,7 @@
"required": ["filter", "flux", "flux_error"]
}

super().__init__(value=value, name=name, schema=schema)
super().__init__(value=value, name=name, schema=schema, extra_metadata=extra_metadata)

def additional_check(self):
assert len(self._value['filter']) == len(self._value['flux']) == len(self._value['flux_error'])
Expand Down
3 changes: 2 additions & 1 deletion tests/test_parameters.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import pytest
import os

from cdci_data_analysis.analysis.instrument import Instrument
from cdci_data_analysis.analysis.queries import (
Expand Down Expand Up @@ -422,7 +423,7 @@ def test_boolean_parameter(inval, iswrong, expected):
True, 100, Energy),
])
def test_parameter_class_from_owl_uri(uri, extra_ttl, use_ontology, value, param_type):
ontology_path = 'tests/oda-ontology.ttl' if use_ontology else None
ontology_path = os.path.join(os.path.dirname(__file__), 'oda-ontology.ttl') if use_ontology else None
param = Parameter.from_owl_uri(uri,
value=value,
extra_ttl = extra_ttl,
Expand Down
Loading