Example #1
0
    def dumps(self, obj, **kwargs):
        """
        Serialize a gemd object, or container of them, into a json-formatting string.

        Parameters
        ----------
        obj: DictSerializable or List[DictSerializable]
            The object(s) to serialize to a string.
        **kwargs: keyword args, optional
            Optional keyword arguments to pass to `json.dumps()`.

        Returns
        -------
        str
            A string version of the serialized objects.

        """
        # create a top level list of [flattened_objects, link-i-fied return value]
        res = {"object": obj}
        additional = flatten(res)
        res = substitute_links(res)
        res["context"] = additional
        return json_builtin.dumps(res,
                                  cls=GEMDEncoder,
                                  sort_keys=True,
                                  **kwargs)
Example #2
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"
Example #3
0
def test_flatten_bounds():
    """Test that flatten works when the objects contain other objects."""
    bounds = CategoricalBounds(categories=["foo", "bar"])
    template = ProcessTemplate(
        "spam",
        conditions=[(ConditionTemplate(name="eggs", bounds=bounds), bounds)]
    )
    spec = ProcessSpec(name="spec", template=template)

    flat = flatten(spec, 'test-scope')
    assert len(flat) == 2, "Expected 2 flattened objects"
def test_flatten():
    """Test that gemd utility methods can be applied to citrine-python objects.
    Citrine-python resources extend the gemd data model, so the gemd operations
    should work on them.
    """

    bounds = CategoricalBounds(categories=["foo", "bar"])
    template = ProcessTemplate(
        "spam",
        conditions=[(ConditionTemplate(name="eggs", bounds=bounds), bounds)]
    )
    spec = ProcessSpec(name="spec", template=template)

    flat = flatten(spec, scope='testing')
    assert len(flat) == 3, "Expected 3 flattened objects"
Example #5
0
def test_equality():
    """Test that equality check works as expected."""
    spec = ProcessSpec("A spec", tags=["a tag"])
    run1 = ProcessRun("A process", spec=spec)

    run2 = deepcopy(run1)
    assert run1 == run2, "Copy somehow failed"
    IngredientRun(process=run2)
    assert run1 != run2

    run3 = deepcopy(run2)
    assert run3 == run2, "Copy somehow failed"
    run3.ingredients[0].tags.append('A tag')
    assert run3 != run2

    run4 = next(x for x in flatten(run3, 'test-scope')
                if isinstance(x, ProcessRun))
    assert run4 == run3, "Flattening removes measurement references, but that's okay"
def test_flatten_empty_history():
    """Test that flatten works when the objects are empty and go through a whole history."""
    procured = ProcessSpec(name="procured")
    input = MaterialSpec(name="foo", process=procured)
    transform = ProcessSpec(name="transformed")
    ingredient = IngredientSpec(name="input", material=input, process=transform)

    procured_run = ProcessRun(name="procured", spec=procured)
    input_run = MaterialRun(name="foo", process=procured_run, spec=input)
    transform_run = ProcessRun(name="transformed", spec=transform)
    ingredient_run = IngredientRun(material=input_run, process=transform_run, spec=ingredient)

    assert len(flatten(procured)) == 1
    assert len(flatten(input)) == 1
    assert len(flatten(ingredient)) == 3
    assert len(flatten(transform)) == 3

    assert len(flatten(procured_run)) == 3
    assert len(flatten(input_run)) == 3
    assert len(flatten(ingredient_run)) == 7
    assert len(flatten(transform_run)) == 7
Example #7
0
def test_equality():
    """Test that equality check works as expected."""
    spec1 = ProcessSpec("A spec")
    spec2 = ProcessSpec("A spec", tags=["a tag"])

    assert spec1 != spec2
    spec3 = deepcopy(spec1)
    assert spec1 == spec3, "Copy somehow failed"
    IngredientSpec("An ingredient", process=spec3)
    assert spec1 != spec3

    spec4 = deepcopy(spec3)
    assert spec4 == spec3, "Copy somehow failed"
    spec4.ingredients[0].tags.append('A tag')
    assert spec4 != spec3

    spec5 = next(x for x in flatten(spec4, 'test-scope')
                 if isinstance(x, ProcessSpec))
    assert spec5 == spec4, "Flattening removes measurement references, but that's okay"
Example #8
0
def test_default_scope():
    """Test flatten exceptions around providing a scope."""
    ps_one = ProcessSpec(name="one")

    with pytest.raises(ValueError):
        flatten(ps_one)

    pr_one = ProcessRun(name="one", uids={'my': 'outer'}, spec=ps_one)

    with pytest.raises(ValueError):
        flatten(pr_one)

    ps_one.uids['my'] = 'id'
    assert len(flatten(pr_one)) == 2

    two = ProcessRun(name="two", spec=ProcessSpec(name="two"))
    assert len(flatten(two, scope="my")) == 2
def test_equality():
    """Test that equality check works as expected."""
    spec = MaterialSpec("A spec",
                        properties=PropertyAndConditions(
                            property=Property("a property", value=NominalReal(3, ''))),
                        tags=["a tag"])
    mat1 = MaterialRun("A material", spec=spec)
    mat2 = MaterialRun("A material", spec=spec, tags=["A tag"])
    assert mat1 == deepcopy(mat1)
    assert mat1 != mat2
    assert mat1 != "A material"

    mat3 = deepcopy(mat1)
    assert mat1 == mat3, "Copy somehow failed"
    MeasurementRun("A measurement", material=mat3)
    assert mat1 != mat3

    mat4 = deepcopy(mat3)
    assert mat4 == mat3, "Copy somehow failed"
    mat4.measurements[0].tags.append('A tag')
    assert mat4 != mat3

    mat5 = next(x for x in flatten(mat4, 'test-scope') if isinstance(x, MaterialRun))
    assert mat5 == mat4, "Flattening removes measurement references, but that's okay"