def __init__(self, name: str, *, bounds: BaseBounds, uids: Optional[Dict[str, str]] = None, description: Optional[str] = None, tags: Optional[List[str]] = None): if uids is None: uids = dict() DataConcepts.__init__(self, GEMDPropertyTemplate.typ) GEMDPropertyTemplate.__init__(self, name=name, bounds=bounds, tags=tags, uids=uids, description=description)
def test_invalid_assignment(caplog): """Test that invalid assignments throw the appropriate errors.""" with pytest.raises(TypeError): Property(value=NominalReal(10, '')) with pytest.raises(TypeError): Property(name="property", value=10) with pytest.raises(TypeError): Property(name="property", template=ProcessTemplate("wrong kind of template")) with pytest.raises(ValueError): Property(name="property", origin=None) valid_prop = Property(name="property", value=NominalReal(10, ''), template=PropertyTemplate("template", bounds=RealBounds( 0, 100, ''))) good_val = valid_prop.value bad_val = NominalReal(-10.0, '') assert len(caplog.records ) == 0, "Warning caught before logging tests were reached." with validation_level(WarningLevel.IGNORE): valid_prop.value = bad_val assert len(caplog.records ) == 0, "Validation warned even though level is IGNORE." assert valid_prop.value == bad_val, "IGNORE allowed the bad value to be set." valid_prop.value = good_val assert len(caplog.records ) == 0, "Validation warned even though level is IGNORE." with validation_level(WarningLevel.WARNING): valid_prop.value = bad_val assert len(caplog.records ) == 1, "Validation didn't warn on out of bounds value." assert valid_prop.value == bad_val, "WARNING allowed the bad value to be set." valid_prop.value = good_val assert len( caplog.records) == 1, "Validation DID warn on a valid value." with validation_level(WarningLevel.FATAL): with pytest.raises(ValueError): valid_prop.value = bad_val assert valid_prop.value == good_val, "FATAL didn't allow the bad value to be set." with validation_level(WarningLevel.FATAL): with pytest.raises(ValueError): valid_prop.template = PropertyTemplate("template", bounds=RealBounds(0, 1, '')) assert valid_prop.value == good_val, "FATAL didn't allow the bad value to be set."
def test_dependencies(): """Test that dependency lists make sense.""" targets = [ PropertyTemplate(name="name", bounds=RealBounds(0, 1, '')), ConditionTemplate(name="name", bounds=RealBounds(0, 1, '')), ParameterTemplate(name="name", bounds=RealBounds(0, 1, '')), ] for target in targets: assert len(target.all_dependencies()) == 0, f"{type(target)} had dependencies"
def test_attribute_serde(): """An attribute with a link to an attribute template should be copy-able.""" prop_tmpl = PropertyTemplate(name='prop_tmpl', bounds=RealBounds(0, 2, 'm')) prop = Property(name='prop', template=prop_tmpl, value=NominalReal(1, 'm')) meas_spec = MeasurementSpec("a spec") meas = MeasurementRun("a measurement", spec=meas_spec, properties=[prop]) assert loads(dumps(prop)) == prop assert loads(dumps(meas)) == meas assert isinstance(prop.template, PropertyTemplate)
def test_fields_from_property(): """Test that several fields of the attribute are derived from the property.""" prop_template = PropertyTemplate(name="cookie eating template", bounds=IntegerBounds(0, 1000)) cond_template = ConditionTemplate(name="Hunger template", bounds=CategoricalBounds(["hungry", "full", "peckish"])) prop = Property(name="number of cookies eaten", template=prop_template, origin='measured', value=NominalInteger(27)) cond = Condition(name="hunger level", template=cond_template, origin='specified', value=NominalCategorical("hungry")) prop_and_conds = PropertyAndConditions(property=prop, conditions=[cond]) assert prop_and_conds.name == prop.name assert prop_and_conds.template == prop.template assert prop_and_conds.origin == prop.origin assert prop_and_conds.value == prop.value
def test_recursive_foreach(): """Test that recursive foreach will actually walk through a material history.""" mat_run = MaterialRun("foo") process_run = ProcessRun("bar") IngredientRun(process=process_run, material=mat_run) output = MaterialRun("material", process=process_run) # property templates are trickier than templates because they are referenced in attributes template = PropertyTemplate("prop", bounds=RealBounds(0, 1, "")) prop = Property("prop", value=NominalReal(1.0, ""), template=template) MeasurementRun("check", material=output, properties=prop) types = [] recursive_foreach(output, lambda x: types.append(x.typ)) expected = [ "ingredient_run", "material_run", "material_run", "process_run", "measurement_run", "property_template" ] assert sorted(types) == sorted(expected)
from gemd.entity.bounds.real_bounds import RealBounds from gemd.entity.object import MeasurementRun, MaterialRun, ProcessRun, ProcessSpec,\ MeasurementSpec, MaterialSpec from gemd.entity.template.condition_template import ConditionTemplate from gemd.entity.template.material_template import MaterialTemplate from gemd.entity.template.measurement_template import MeasurementTemplate from gemd.entity.template.process_template import ProcessTemplate from gemd.entity.template.property_template import PropertyTemplate from gemd.entity.value.discrete_categorical import DiscreteCategorical from gemd.entity.value.nominal_composition import NominalComposition from gemd.entity.value.nominal_real import NominalReal from gemd.entity.value.normal_real import NormalReal from gemd.entity.value.uniform_real import UniformReal density_template = PropertyTemplate(name="Density", bounds=RealBounds(lower_bound=0, upper_bound=1.0e9, default_units='')) firing_temperature_template = ConditionTemplate(name="Firing Temperature", bounds=RealBounds( lower_bound=0, upper_bound=1.0e9, default_units='degC')) measurement_template = MeasurementTemplate("Density Measurement", properties=density_template) firing_template = ProcessTemplate(name="Firing in a kiln", conditions=(firing_temperature_template, RealBounds( lower_bound=500, upper_bound=1000, default_units='degC')))
def test_json(): """Test that json serialization round robins to the identity.""" template = PropertyTemplate(name="foo", bounds=RealBounds(0, 1, "")) copy = loads(dumps(template)) assert copy == template
from gemd.entity.attribute.condition import Condition from gemd.entity.attribute.parameter import Parameter from gemd.entity.attribute.property import Property from gemd.entity.bounds.categorical_bounds import CategoricalBounds from gemd.entity.bounds.real_bounds import RealBounds from gemd.entity.object import MaterialRun, MeasurementRun from gemd.entity.template.condition_template import ConditionTemplate from gemd.entity.template.parameter_template import ParameterTemplate from gemd.entity.template.property_template import PropertyTemplate from gemd.entity.value.discrete_categorical import DiscreteCategorical from gemd.entity.value.nominal_real import NominalReal from gemd.entity.value.normal_real import NormalReal known_properties = { "density": PropertyTemplate( name="density", bounds=RealBounds(lower_bound=0.0, upper_bound=1000.0, default_units='g / cm^3') ), "kinematic viscosity": PropertyTemplate( name="kinematic viscosity", bounds=RealBounds(lower_bound=0.0, upper_bound=10.0**40, default_units="m^2 / s") ) } known_conditions = { "temperature": ConditionTemplate( name="temperature", bounds=RealBounds(lower_bound=0.0, upper_bound=1000.0, default_units='K') ) } known_parameters = {