示例#1
0
 def __init__(self,
              name: str,
              uids: Optional[Dict[str, str]] = None,
              tags: Optional[List[str]] = None,
              notes: Optional[str] = None,
              conditions: Optional[List[Condition]] = None,
              parameters: Optional[List[Parameter]] = None,
              template: Optional[TaurusMeasurementTemplate] = None,
              file_links: Optional[List[FileLink]] = None):
     DataConcepts.__init__(self, TaurusMeasurementSpec.typ)
     TaurusMeasurementSpec.__init__(self,
                                    name=name,
                                    uids=set_default_uid(uids),
                                    tags=tags,
                                    conditions=conditions,
                                    parameters=parameters,
                                    template=template,
                                    file_links=file_links,
                                    notes=notes)
示例#2
0
def test_template_access():
    """A measurement run's template should be equal to its spec's template."""
    template = MeasurementTemplate("measurement template",
                                   uids={'id': str(uuid4())})
    spec = MeasurementSpec("A spec",
                           uids={'id': str(uuid4())},
                           template=template)
    meas = MeasurementRun("A run", uids={'id': str(uuid4())}, spec=spec)
    assert meas.template == template

    meas.spec = LinkByUID.from_entity(spec)
    assert meas.template is None
示例#3
0
def test_measurement_spec():
    """Test the measurement spec/run connection survives ser/de."""
    condition = Condition(name="Temp condition",
                          value=NominalReal(nominal=298, units='kelvin'))
    parameter = Parameter(name="Important parameter")
    spec = MeasurementSpec(name="Precise way to do a measurement",
                           parameters=parameter,
                           conditions=condition)

    # Create a measurement run from this measurement spec
    measurement = MeasurementRun(conditions=condition, spec=spec)

    copy = loads(dumps(measurement))
    assert dumps(copy.spec) == dumps(measurement.spec), \
        "Measurement spec should be preserved if measurement run is serialized"
示例#4
0
def test_make_instance():
    """Build up several linked objects and test their properties."""
    msr_spec = MeasurementSpec()
    assert isinstance(make_instance(msr_spec), MeasurementRun)

    mat_spec = MaterialSpec(name='Mat name')
    mat_spec.process = ProcessSpec(name='Pro name')
    IngredientSpec(name='Ing label', process=mat_spec.process)
    mat_spec.process.ingredients[0].material = MaterialSpec(name='Baby mat name')

    mat_run = make_instance(mat_spec)
    assert isinstance(mat_run, MaterialRun)
    assert isinstance(mat_run.process, ProcessRun)
    assert isinstance(mat_run.process.ingredients[0], IngredientRun)
    assert isinstance(mat_run.process.ingredients[0].material, MaterialRun)

    assert mat_run.process.spec == mat_run.spec.process
    ingredient = mat_run.process.ingredients[0]
    assert ingredient.spec == mat_run.spec.process.ingredients[0]
    assert ingredient.material.spec == mat_run.spec.process.ingredients[0].material
示例#5
0
def make_strehlow_objects(table=None):
    """Make a table with Strehlow & Cook data."""
    tmpl = make_templates()

    if table is None:
        table = import_table()

    # Specs
    msr_spec = MeasurementSpec(name='Band gap',
                               template=tmpl["Band gap measurement"])

    def real_mapper(prop):
        """Mapping methods for RealBounds."""
        if 'uncertainty' in prop['scalars'][0]:
            val = NormalReal(mean=float(prop['scalars'][0]['value']),
                             units=prop['units'],
                             std=float(prop['scalars'][0]['uncertainty']))
        else:
            val = NominalReal(nominal=float(prop['scalars'][0]['value']),
                              units=prop['units'])
        return val

    content_map = {
        RealBounds:
        real_mapper,
        CategoricalBounds:
        lambda prop: NominalCategorical(category=prop['scalars'][0]['value']),
        type(None):
        lambda bnd: 'Label'
    }

    datapoints = []
    compounds = dict()
    for row in table:
        formula = formula_clean(row['chemicalFormula'])
        spec = compounds.get(
            formula,
            MaterialSpec(name=formula_latex(formula),
                         template=tmpl["Chemical"],
                         process=ProcessSpec(
                             name="Sample preparation",
                             template=tmpl["Sample preparation"])))
        run = make_instance(spec)
        datapoints.append(run)

        if not spec.properties:
            spec.properties.append(
                PropertyAndConditions(property=Property(
                    name=spec.template.properties[0][0].name,
                    value=EmpiricalFormula(formula=formula),
                    template=spec.template.properties[0][0])))

        msr = make_instance(msr_spec)
        msr.material = run

        # 2 categories in the PIF need to be split to avoid repeat Attribute Templates in a Run
        name_map = {'Phase': 'Crystal system', 'Transition': 'Bands'}
        origin_map = {
            'EXPERIMENTAL': Origin.MEASURED,
            'COMPUTATIONAL': Origin.COMPUTED
        }
        seen = set(
        )  # Some conditions come in from multiple properties on the same object
        for prop in row['properties']:
            origin = origin_map.get(prop.get('dataType', None), Origin.UNKNOWN)
            if 'method' in prop:
                method = 'Method: ' + prop['method']['name']
            else:
                method = 'Method: unreported'
            for attr in [prop] + prop.get('conditions', []):
                if attr['name'] in seen:
                    # Early return if it's a repeat
                    continue
                seen.add(attr['name'])

                template = tmpl[attr['name']]
                # Figure out if we need to split this column
                if attr['name'] in name_map:
                    value = attr['scalars'][0]['value']
                    if value not in template.bounds.categories:
                        template = tmpl[name_map[attr['name']]]

                # Move into GEMD structure
                if type(template) == PropertyTemplate:
                    msr.properties.append(
                        Property(name=template.name,
                                 template=template,
                                 value=content_map[type(
                                     template.bounds)](attr),
                                 origin=origin,
                                 notes=method))
                elif type(template) == ConditionTemplate:
                    msr.conditions.append(
                        Condition(name=template.name,
                                  template=template,
                                  value=content_map[type(
                                      template.bounds)](attr),
                                  origin=origin,
                                  notes=method))

    return datapoints
示例#6
0
文件: cake.py 项目: crleblanc/taurus
def make_cake(seed=None):
    """Define all objects that go into making a demo cake."""
    if seed is not None:
        random.seed(seed)
    ######################################################################
    # Parent Objects
    tmpl = make_cake_templates()
    cake_spec = make_cake_spec()

    ######################################################################
    # Objects
    cake = make_instance(cake_spec)
    operators = ['gwash', 'jadams', 'thomasj', 'jmadison', 'jmonroe']
    cake.process.source = PerformedSource(performed_by=random.choice(operators),
                                          performed_date='2015-03-14')
    # Replace Abstract/In General
    queue = [cake]
    while queue:
        item = queue.pop(0)
        item.name = item.name.replace('Abstract ', '').replace(', in General', '')
        if item.spec.tags is not None:
            item.tags = list(item.spec.tags)
        if item.spec.notes:  # None or empty string
            item.notes = 'The spec says "{}"'.format(item.spec.notes)

        if isinstance(item, MaterialRun):
            queue.append(item.process)
        elif isinstance(item, ProcessRun):
            queue.extend(item.ingredients)
            if item.template.name == "Procurement":
                item.source = PerformedSource(performed_by='hamilton',
                                              performed_date='2015-02-17')
            else:
                item.source = cake.process.source
        elif isinstance(item, IngredientRun):
            queue.append(item.material)
            fuzz = 0.95 + 0.1 * random.random()
            if item.spec.absolute_quantity is not None:
                item.absolute_quantity = \
                    NormalReal(mean=fuzz * item.spec.absolute_quantity.nominal,
                               std=0.05 * item.spec.absolute_quantity.nominal,
                               units=item.spec.absolute_quantity.units)
            if item.spec.volume_fraction is not None:
                item.volume_fraction = \
                    NormalReal(mean=fuzz * item.spec.volume_fraction.nominal,
                               std=0.05 * item.spec.volume_fraction.nominal,
                               units=item.spec.volume_fraction.units)
            if item.spec.mass_fraction is not None:
                item.mass_fraction = \
                    UniformReal(lower_bound=(fuzz - 0.05) * item.spec.mass_fraction.nominal,
                                upper_bound=(fuzz + 0.05) * item.spec.mass_fraction.nominal,
                                units=item.spec.mass_fraction.units)
            if item.spec.number_fraction is not None:
                item.number_fraction = \
                    NormalReal(mean=fuzz * item.spec.number_fraction.nominal,
                               std=0.05 * item.spec.number_fraction.nominal,
                               units=item.spec.number_fraction.units)

        else:
            raise TypeError("Unexpected object in the queue")

    frosting = \
        next(x.material for x in cake.process.ingredients if 'rosting' in x.name)
    baked = \
        next(x.material for x in cake.process.ingredients if 'aked' in x.name)

    # Add measurements
    cake_taste = MeasurementRun(name='Final Taste', material=cake)
    cake_appearance = MeasurementRun(name='Final Appearance', material=cake)
    frosting_taste = MeasurementRun(name='Frosting Taste', material=frosting)
    frosting_sweetness = MeasurementRun(name='Frosting Sweetness', material=frosting)

    # and spec out the measurements
    cake_taste.spec = MeasurementSpec(name='Taste')
    cake_appearance.spec = MeasurementSpec(name='Appearance')
    frosting_taste.spec = cake_taste.spec  # Taste
    frosting_sweetness.spec = MeasurementSpec(name='Sweetness')

    ######################################################################
    # Let's add some attributes
    baked.process.conditions.append(Condition(name='Cooking time',
                                              template=tmpl['Cooking time'],
                                              origin=Origin.MEASURED,
                                              value=NominalReal(nominal=48, units='min')))
    baked.spec.process.conditions.append(Condition(name='Cooking time',
                                                   template=tmpl['Cooking time'],
                                                   origin=Origin.SPECIFIED,
                                                   value=NormalReal(mean=50, std=5, units='min')))
    baked.process.conditions.append(Condition(name='Oven temperature',
                                              origin="measured",
                                              value=NominalReal(nominal=362, units='degF')))
    baked.spec.process.parameters.append(Parameter(name='Oven temperature setting',
                                                   template=tmpl['Oven temperature setting'],
                                                   origin="specified",
                                                   value=NominalReal(nominal=350, units='degF')))
    cake_taste.properties.append(Property(name='Tastiness',
                                          origin=Origin.MEASURED,
                                          template=tmpl['Tastiness'],
                                          value=NominalInteger(nominal=5)))
    cake_appearance.properties.append(Property(name='Visual Appeal',
                                               origin=Origin.MEASURED,
                                               value=NominalInteger(nominal=5)))
    frosting_taste.properties.append(Property(name='Tastiness',
                                              origin=Origin.MEASURED,
                                              template=tmpl['Tastiness'],
                                              value=NominalInteger(nominal=4)))
    frosting_sweetness.properties.append(Property(name='Sweetness (Sucrose-basis)',
                                                  origin=Origin.MEASURED,
                                                  value=NominalReal(nominal=1.7, units='')))

    baked.process.spec.template = tmpl['Baking in an oven']
    cake_taste.spec.template = tmpl['Taste test']
    frosting_taste.spec.template = tmpl['Taste test']

    cake.spec.template = tmpl['Dessert']
    frosting.spec.template = tmpl['Dessert']

    # Code to force all scopes to 'id'
    set_uuids([cake, cake_taste, cake_appearance, frosting_taste, frosting_sweetness], name='id')
    id_queue = [x for x in cake.process.ingredients]
    while id_queue:
        x = id_queue.pop(0)
        set_uuids([x], name='id')
        id_queue += x.material.process.ingredients

    return cake