示例#1
0
def test_simple_deserialization(valid_data):
    """Ensure that a deserialized Process Spec looks sane."""
    process_spec: ProcessSpec = ProcessSpec.build(valid_data)
    assert process_spec.uids == {'id': valid_data['uids']['id']}
    assert process_spec.tags == ['baking::cakes', 'danger::low']
    assert process_spec.parameters[0] == Parameter(name='oven temp',
                                                   value=UniformReal(
                                                       195, 205, ''),
                                                   origin='specified')
    assert process_spec.conditions == []
    assert process_spec.template == \
           ProcessTemplate('the template', uids={'id': valid_data['template']['uids']['id']},
                           parameters=[
                               [ParameterTemplate('oven temp template',
                                                  bounds=RealBounds(175, 225, ''),
                                                  uids={'id': valid_data['template']['parameters'][0][0]['uids']['id']}),
                                RealBounds(175, 225, '')]
                           ],
                           description='a long description',
                           allowed_labels=['a', 'b'],
                           allowed_names=['a name'])
    assert process_spec.name == 'Process 1'
    assert process_spec.notes == 'make sure to use oven mitts'
    assert process_spec.file_links == [
        FileLink('cake_recipe.txt', 'www.baking.com')
    ]
    assert process_spec.typ == 'process_spec'
    assert process_spec.audit_info == AuditInfo(**valid_data['audit_info'])
示例#2
0
def test_serialize():
    """Serializing a nested object should be identical to individually serializing each piece."""
    condition = Condition(name="A condition", value=NominalReal(7, ''))
    parameter = Parameter(name="A parameter",
                          value=NormalReal(mean=17, std=1, units=''))
    input_material = MaterialRun(tags="input")
    process = ProcessRun(tags="A tag on a process run")
    ingredient = IngredientRun(material=input_material, process=process)
    material = MaterialRun(tags=["A tag on a material"], process=process)
    measurement = MeasurementRun(tags="A tag on a measurement",
                                 conditions=condition,
                                 parameters=parameter,
                                 material=material)

    # serialize the root of the tree
    native_object = json.loads(dumps(measurement))
    # ingredients don't get serialized on the process
    assert (len(native_object["context"]) == 5)
    assert (native_object["object"]["type"] == LinkByUID.typ)

    # serialize all of the nodes
    native_batch = json.loads(
        dumps([material, process, measurement, ingredient]))
    assert (len(native_batch["context"]) == 5)
    assert (len(native_batch["object"]) == 4)
    assert (all(x["type"] == LinkByUID.typ for x in native_batch["object"]))
示例#3
0
def test_complex_substitutions():
    """Make sure accounting works for realistic objects."""
    root = MaterialRun("root",
                       process=ProcessRun("root", spec=ProcessSpec("root")),
                       spec=MaterialSpec("root"))
    root.spec.process = root.process.spec
    input = MaterialRun("input",
                        process=ProcessRun("input", spec=ProcessSpec("input")),
                        spec=MaterialSpec("input"))
    input.spec.process = input.process.spec
    IngredientRun(process=root.process,
                  material=input,
                  spec=IngredientSpec("ingredient",
                                      process=root.process.spec,
                                      material=input.spec))
    param = ParameterTemplate("Param", bounds=RealBounds(-1, 1, "m"))
    root.process.spec.template = ProcessTemplate("Proc", parameters=[param])
    root.process.parameters.append(
        Parameter("Param", value=NormalReal(0, 1, 'm'), template=param))

    links = flatten(root, scope="test-scope")
    index = make_index(links)
    rebuild = substitute_objects(links, index, inplace=True)
    rebuilt_root = next(x for x in rebuild
                        if x.name == root.name and x.typ == root.typ)
    all_objs = recursive_flatmap(rebuilt_root,
                                 func=lambda x: [x],
                                 unidirectional=False)
    unique = [x for i, x in enumerate(all_objs) if i == all_objs.index(x)]
    assert not any(isinstance(x, LinkByUID) for x in unique), "All are objects"
    assert len(links) == len(unique), "Objects are missing"
示例#4
0
def test_deserialize():
    """Round-trip serde should leave the object unchanged."""
    condition = Condition(name="A condition", value=NominalReal(7, ''))
    parameter = Parameter(name="A parameter", value=NormalReal(mean=17, std=1, units=''))
    measurement = MeasurementRun(tags="A tag on a measurement", conditions=condition,
                                 parameters=parameter)
    copy_meas = GEMDJson().copy(measurement)
    assert(copy_meas.conditions[0].value == measurement.conditions[0].value)
    assert(copy_meas.parameters[0].value == measurement.parameters[0].value)
    assert(copy_meas.uids["auto"] == measurement.uids["auto"])
def test_recursive_foreach():
    """Test that recursive_foreach() applies a method to every object."""
    new_tag = "Extra tag"

    def func(base_ent):
        """Adds a specific tag to the object."""
        base_ent.tags.extend([new_tag])
        return

    param_template = ParameterTemplate("a param template", bounds=RealBounds(0, 100, ''))
    meas_template = MeasurementTemplate("Measurement template", parameters=[param_template])
    parameter = Parameter(name="A parameter", value=NormalReal(mean=17, std=1, units=''))
    measurement = MeasurementSpec(name="name", parameters=parameter, template=meas_template)
    test_dict = {"foo": measurement}
    recursive_foreach(test_dict, func, apply_first=True)

    for ent in [param_template, meas_template, measurement]:
        assert new_tag in ent.tags
def make_data_island(density,
                     bulk_modulus,
                     firing_temperature,
                     binders,
                     powders,
                     tag=None):
    """Helper function to create a relatively involved data island."""
    binder_specs = keymap(lambda x: MaterialSpec(name=x), binders)
    powder_specs = keymap(lambda x: MaterialSpec(name=x), powders)

    binder_runs = keymap(lambda x: MaterialRun(name=x.name, spec=x),
                         binder_specs)
    powder_runs = keymap(lambda x: MaterialRun(name=x.name, spec=x),
                         powder_specs)

    all_input_materials = keymap(lambda x: x.spec.name,
                                 merge(binder_runs, powder_runs))
    mixing_composition = Condition(
        name="composition", value=NominalComposition(all_input_materials))
    mixing_process = ProcessRun(name="Mixing",
                                tags=["mixing"],
                                conditions=[mixing_composition])
    binder_ingredients = []
    for run in binder_runs:
        binder_ingredients.append(
            IngredientRun(
                material=run,
                process=mixing_process,
                mass_fraction=NominalReal(binders[run.spec.name], ''),
            ))

    powder_ingredients = []
    for run in powder_runs:
        powder_ingredients.append(
            IngredientRun(
                material=run,
                process=mixing_process,
                mass_fraction=NominalReal(powders[run.spec.name], ''),
            ))

    green_sample = MaterialRun("Green", process=mixing_process)

    measured_firing_temperature = Condition(
        name="Firing Temperature",
        value=UniformReal(firing_temperature - 0.5, firing_temperature + 0.5,
                          'degC'),
        template=firing_temperature_template)

    specified_firing_setting = Parameter(name="Firing setting",
                                         value=DiscreteCategorical("hot"))
    firing_spec = ProcessSpec("Firing", template=firing_template)
    firing_process = ProcessRun(name=firing_spec.name,
                                conditions=[measured_firing_temperature],
                                parameters=[specified_firing_setting],
                                spec=firing_spec)
    IngredientRun(material=green_sample,
                  process=firing_process,
                  mass_fraction=NormalReal(1.0, 0.0, ''),
                  volume_fraction=NormalReal(1.0, 0.0, ''),
                  number_fraction=NormalReal(1.0, 0.0, ''))

    measured_density = Property(name="Density",
                                value=NominalReal(density, ''),
                                template=density_template)
    measured_modulus = Property(name="Bulk modulus",
                                value=NormalReal(bulk_modulus,
                                                 bulk_modulus / 100.0, ''))
    measurement_spec = MeasurementSpec("Mechanical Properties",
                                       template=measurement_template)
    measurement = MeasurementRun(
        measurement_spec.name,
        properties=[measured_density, measured_modulus],
        spec=measurement_spec)

    tags = [tag] if tag else []

    material_spec = MaterialSpec("Coupon", template=material_template)
    material_run = MaterialRun(material_spec.name,
                               process=firing_process,
                               tags=tags,
                               spec=material_spec)
    measurement.material = material_run
    return material_run
示例#7
0
def ingest_material_run(data, material_spec=None, process_run=None):
    """Ingest material run with data, a material spec, and an originating process run."""
    if isinstance(data, list):
        return [ingest_material_run(x, material_spec) for x in data]

    if not isinstance(data, dict):
        raise ValueError("This ingester operates on dict, but got {}".format(type(data)))

    material = MaterialRun()

    sample_id = data.get("sample_id")
    if sample_id:
        material.add_uid("given_sample_id", sample_id)

    tags = data.get("tags")
    if tags:
        material.tags = tags

    for experiment in data.get("experiments", []):
        measurement = MeasurementRun()

        for name in set(known_properties.keys()).intersection(experiment.keys()):
            prop = Property(
                name=name,
                template=known_properties[name],
                value=_parse_value(experiment[name])
            )
            measurement.properties.append(prop)

        for name in set(known_conditions.keys()).intersection(experiment.keys()):
            cond = Condition(
                name=name,
                template=known_conditions[name],
                value=_parse_value(experiment[name])
            )
            measurement.conditions.append(cond)

        for name in set(known_parameters.keys()).intersection(experiment.keys()):
            param = Parameter(
                name=name,
                template=known_parameters[name],
                value=_parse_value(experiment[name])
            )
            measurement.parameters.append(param)

        scan_id = experiment.get("scan_id")
        if scan_id:
            measurement.add_uid("given_scan_id", scan_id)

        tags = experiment.get("tags")
        if tags:
            measurement.tags = tags

        measurement.material = material

    if material_spec:
        material.material_spec = material_spec

    if process_run:
        material.process = process_run

    return material