class IngredientQuantityByProcessAndName( Serializable['IngredientQuantityByProcessAndName'], Variable): """[ALPHA] Get the quantity of an ingredient associated with a process template and a name. Parameters --------- name: str a short human-readable name to use when referencing the variable headers: list[str] sequence of column headers process_template: LinkByUID process template associated with this ingredient identifier ingredient_name: str name of ingredient quantity_dimension: IngredientQuantityDimension dimension of the ingredient quantity: absolute quantity, number, mass, or volume fraction. valid options are defined by :class:`~citrine.gemtables.variables.IngredientQuantityDimension` type_selector: DataObjectTypeSelector strategy for selecting data object types to consider when matching, defaults to PREFER_RUN """ name = properties.String('name') headers = properties.List(properties.String, 'headers') process_template = properties.Object(LinkByUID, 'process_template') ingredient_name = properties.String('ingredient_name') quantity_dimension = properties.Enumeration(IngredientQuantityDimension, 'quantity_dimension') type_selector = properties.Enumeration(DataObjectTypeSelector, "type_selector") typ = properties.String('type', default="ing_quantity_by_process_and_name", deserializable=False) def _attrs(self) -> List[str]: return ["name", "headers", "process_template", "ingredient_name", "quantity_dimension", "type_selector", "typ"] def __init__(self, *, name: str, headers: List[str], process_template: LinkByUID, ingredient_name: str, quantity_dimension: IngredientQuantityDimension, type_selector: DataObjectTypeSelector = DataObjectTypeSelector.PREFER_RUN): self.name = name self.headers = headers self.process_template = process_template self.ingredient_name = ingredient_name self.quantity_dimension = quantity_dimension self.type_selector = type_selector
class MolecularStructureColumn(Serializable['MolecularStructureColumn'], Column): """[ALPHA] Column containing a representation of a molecular structure. Parameters ---------- data_source: str name of the variable to use when populating the column format: ChemicalDisplayFormat the format in which to display the molecular structure """ data_source = properties.String('data_source') format = properties.Enumeration(ChemicalDisplayFormat, 'format') typ = properties.String('type', default="molecular_structure_column", deserializable=False) def _attrs(self) -> List[str]: return ["data_source", "format", "typ"] def __init__(self, *, data_source: str, format: ChemicalDisplayFormat): self.data_source = data_source self.format = format
class FlatCompositionColumn(Serializable["FlatCompositionColumn"], Column): """[ALPHA] Column that flattens the composition into a string of names and quantities. The numeric formatting tries to be human readable. For example, if all of the quantities are round numbers like ``{"spam": 4.0, "eggs": 1.0}`` then the result omit the decimal points like ``"(spam)4(eggs)1"`` (if sort_order is by quantity). Parameters ---------- data_source: str name of the variable to use when populating the column sort_order: CompositionSortOrder order with which to sort the components when generating the flat string """ data_source = properties.String('data_source') sort_order = properties.Enumeration(CompositionSortOrder, 'sort_order') typ = properties.String('type', default="flat_composition_column", deserializable=False) def _attrs(self) -> List[str]: return ["data_source", "sort_order", "typ"] def __init__(self, *, data_source: str, sort_order: CompositionSortOrder): self.data_source = data_source self.sort_order = sort_order
class IngredientLabelByProcessAndName( Serializable['IngredientLabelByProcessAndName'], Variable): """[ALPHA] A boolean variable indicating whether a given label is applied. Matches by process template, ingredient name, and the label string to check. For example, a column might indicate whether or not the ingredient "ethanol" is labeled as a "solvent" in the "second mixing" process. Many such columns would then support the downstream analysis "get the volumetric average density of the solvents". Parameters --------- name: str a short human-readable name to use when referencing the variable headers: list[str] sequence of column headers process_template: LinkByUID process template associated with this ingredient identifier ingredient_name: str name of ingredient label: str label to test type_selector: DataObjectTypeSelector strategy for selecting data object types to consider when matching, defaults to PREFER_RUN """ name = properties.String('name') headers = properties.List(properties.String, 'headers') process_template = properties.Object(LinkByUID, 'process_template') ingredient_name = properties.String('ingredient_name') label = properties.String('label') type_selector = properties.Enumeration(DataObjectTypeSelector, "type_selector") typ = properties.String('type', default="ing_label_by_process_and_name", deserializable=False) def _attrs(self) -> List[str]: return [ "name", "headers", "process_template", "ingredient_name", "label", "type_selector", "typ" ] def __init__( self, *, name: str, headers: List[str], process_template: LinkByUID, ingredient_name: str, label: str, type_selector: DataObjectTypeSelector = DataObjectTypeSelector. PREFER_RUN): self.name = name self.headers = headers self.process_template = process_template self.ingredient_name = ingredient_name self.label = label self.type_selector = type_selector
class AttributeByTemplateAndObjectTemplate( Serializable['AttributeByTemplateAndObjectTemplate'], Variable): """[ALPHA] Attribute marked by an attribute template and an object template. For example, one property may be measured by two different measurement techniques. In this case, that property would have the same attribute template. Filtering by measurement templates, which identify the measurement techniques, disambiguates the technique used to measure that otherwise ambiguous property. Parameters --------- name: str a short human-readable name to use when referencing the variable headers: list[str] sequence of column headers attribute_template: LinkByUID attribute template that identifies the attribute to assign to the variable object_template: LinkByUID template that identifies the associated object attribute_constraints: list[(LinkByUID, Bounds)] constraints on object attributes in the target object that must be satisfied. Constraints are expressed as Bounds. Attributes are expressed with links. The attribute that the variable is being set to may be the target of a constraint as well. type_selector: DataObjectTypeSelector strategy for selecting data object types to consider when matching, defaults to PREFER_RUN """ name = properties.String('name') headers = properties.List(properties.String, 'headers') attribute_template = properties.Object(LinkByUID, 'attribute_template') object_template = properties.Object(LinkByUID, 'object_template') attribute_constraints = properties.Optional( properties.List( properties.SpecifiedMixedList( [properties.Object(LinkByUID), properties.Object(BaseBounds)] ) ), 'attribute_constraints') type_selector = properties.Enumeration(DataObjectTypeSelector, "type_selector") typ = properties.String('type', default="attribute_by_object", deserializable=False) def _attrs(self) -> List[str]: return ["name", "headers", "attribute_template", "object_template", "attribute_constraints", "type_selector", "typ"] def __init__(self, *, name: str, headers: List[str], attribute_template: LinkByUID, object_template: LinkByUID, attribute_constraints: List[List[Union[LinkByUID, BaseBounds]]] = None, type_selector: DataObjectTypeSelector = DataObjectTypeSelector.PREFER_RUN): self.name = name self.headers = headers self.attribute_template = attribute_template self.object_template = object_template self.attribute_constraints = attribute_constraints self.type_selector = type_selector
class AttributeByTemplate(Serializable['AttributeByTemplate'], Variable): """[ALPHA] Attribute marked by an attribute template. Parameters ---------- name: str a short human-readable name to use when referencing the variable headers: list[str] sequence of column headers template: LinkByUID attribute template that identifies the attribute to assign to the variable attribute_constraints: list[list[LinkByUID, Bounds]] constraints on object attributes in the target object that must be satisfied. Constraints are expressed as Bounds. Attributes are expressed with links. The attribute that the variable is being set to may be the target of a constraint as well. type_selector: DataObjectTypeSelector strategy for selecting data object types to consider when matching, defaults to PREFER_RUN """ name = properties.String('name') headers = properties.List(properties.String, 'headers') template = properties.Object(LinkByUID, 'template') attribute_constraints = properties.Optional( properties.List( properties.SpecifiedMixedList( [properties.Object(LinkByUID), properties.Object(BaseBounds)])), 'attribute_constraints') type_selector = properties.Enumeration(DataObjectTypeSelector, "type_selector") typ = properties.String('type', default="attribute_by_template", deserializable=False) def _attrs(self) -> List[str]: return [ "name", "headers", "template", "attribute_constraints", "type_selector", "typ" ] def __init__( self, *, name: str, headers: List[str], template: LinkByUID, attribute_constraints: Optional[List[List[Union[LinkByUID, BaseBounds]]]] = None, type_selector: DataObjectTypeSelector = DataObjectTypeSelector. PREFER_RUN): self.name = name self.headers = headers self.template = template self.attribute_constraints = attribute_constraints self.type_selector = type_selector
class IngredientIdentifierByProcessTemplateAndName( Serializable['IngredientIdentifierByProcessAndName'], Variable): """[ALPHA] Ingredient identifier associated with a process template and a name. Parameters --------- name: str a short human-readable name to use when referencing the variable headers: list[str] sequence of column headers process_template: LinkByUID process template associated with this ingredient identifier ingredient_name: str name of ingredient scope: str scope of the identifier (default: the Citrine scope) type_selector: DataObjectTypeSelector strategy for selecting data object types to consider when matching, defaults to PREFER_RUN """ name = properties.String('name') headers = properties.List(properties.String, 'headers') process_template = properties.Object(LinkByUID, 'process_template') ingredient_name = properties.String('ingredient_name') scope = properties.String('scope') type_selector = properties.Enumeration(DataObjectTypeSelector, "type_selector") typ = properties.String('type', default="ing_id_by_process_and_name", deserializable=False) def _attrs(self) -> List[str]: return [ "name", "headers", "process_template", "ingredient_name", "scope", "type_selector", "typ" ] def __init__( self, *, name: str, headers: List[str], process_template: LinkByUID, ingredient_name: str, scope: str, type_selector: DataObjectTypeSelector = DataObjectTypeSelector. PREFER_RUN): self.name = name self.headers = headers self.process_template = process_template self.ingredient_name = ingredient_name self.scope = scope self.type_selector = type_selector
class IngredientQuantityInOutput(Serializable['IngredientQuantityInOutput'], Variable): """[ALPHA] Ingredient identifier in the trunk of a material history tree. The search for an identifier starts at the terminal material and proceeds until any of the given process templates are reached. Those templates block the search from continuing but are inclusive: a match is extracted if an ingredient with the specified ingredient name is found at or before a cutoff. This variable definition allows an identifier to be extracted when an ingredient is used in multiple processes. As an example, consider a paint formed by mixing red and yellow pigments, where the red pigment is formed by mixing yellow and magenta. This variable could be used represent yellow in both mixing processes (red and the final paint) in a single column provided the process templates that mixed red and the final paint are included as cutoffs. In general, this variable should be preferred over an :class:`~citrine.gemtables.variables.IngredientIdentifierByProcessTemplateAndName` when mixtures are hierarchical (i.e. blends of blends). It allows an ingredient with a single name to be used in multiple processes without defining additional variables that manifest as additional columns in your table, and must be used in place of the former if the same process template is used to represent mixing at multiple levels in the material history hierarchy. Going back to the previous example, this variable must be used in place of an :class:`~citrine.gemtables.variables.IngredientIdentifierByProcessTemplateAndName` if the same process template was used to represent the process that mixed red and the final paint. Using :class:`~citrine.gemtables.variables.IngredientIdentifierByProcessTemplateAndName` would result in an ambiguous match because yellow would be found twice in the material history, once when mixing red and again when mixing the final paint. Parameters --------- name: str a short human-readable name to use when referencing the variable headers: list[str] sequence of column headers ingredient_name: str Name of the ingredient to search for quantity_dimension: IngredientQuantityDimension dimension of the ingredient quantity: absolute quantity, number, mass, or volume fraction. valid options are defined by :class:`~citrine.gemtables.variables.IngredientQuantityDimension` process_templates: list[LinkByUID] Process templates halt the search for a matching ingredient name. These process templates are inclusive. The ingredient may be present in these processes but not after. type_selector: DataObjectTypeSelector strategy for selecting data object types to consider when matching, defaults to PREFER_RUN """ name = properties.String('name') headers = properties.List(properties.String, 'headers') ingredient_name = properties.String('ingredient_name') quantity_dimension = properties.Enumeration(IngredientQuantityDimension, 'quantity_dimension') process_templates = properties.List(properties.Object(LinkByUID), 'process_templates') type_selector = properties.Enumeration(DataObjectTypeSelector, "type_selector") typ = properties.String('type', default="ing_quantity_in_output", deserializable=False) def _attrs(self) -> List[str]: return ["name", "headers", "ingredient_name", "process_templates", "type_selector", "typ"] def __init__(self, *, name: str, headers: List[str], ingredient_name: str, quantity_dimension: IngredientQuantityDimension, process_templates: List[LinkByUID], type_selector: DataObjectTypeSelector = DataObjectTypeSelector.PREFER_RUN): self.name = name self.headers = headers self.ingredient_name = ingredient_name self.quantity_dimension = quantity_dimension self.process_templates = process_templates self.type_selector = type_selector
class AttributeInOutput(Serializable['AttributeInOutput'], Variable): """[ALPHA] Attribute marked by an attribute template in the trunk of the history tree. The search for an attribute that marks the given attribute template starts at the root of the material history tree and proceeds until any of the given process templates are reached. Those templates block the search from continuing into their ingredients but do not halt the search entirely. This variable definition allows attributes that are present both in output and the inputs of a process to be distinguished. For example, a material "paint" might be produced by mixing and then resting "pigments" and a "base". The color of the pigments and base could be measured and recorded as attributes in addition to the color of the resulting paint. To define a variable as the color of the resulting paint, AttributeInOutput can be used with the mixing process included in the list of process templates. Then, when the platform looks for colors, it won't traverse through the mixing process and hit the colors of the pigments and base as well, which would result in an ambiguous variable match. Unlike "AttributeByTemplateAfterProcess", AttributeInOutput will also match on the color attribute of the pigments in the rows that correspond to those pigments. This way, all the colors can be assigned to the same variable and rendered into the same columns in the GEM table. Parameters --------- name: str a short human-readable name to use when referencing the variable headers: list[str] sequence of column headers attribute_template: LinkByUID attribute template that identifies the attribute to assign to the variable process_templates: list[LinkByUID] process templates that should not be traversed through when searching for a matching attribute. The attribute may be present in these processes but not their ingredients. attribute_constraints: Optional[list[(LinkByUID, Bounds)]] constraints on object attributes in the target object that must be satisfied. Constraints are expressed as Bounds. Attributes are expressed with links. The attribute that the variable is being set to may be the target of a constraint as well. type_selector: DataObjectTypeSelector strategy for selecting data object types to consider when matching, defaults to PREFER_RUN """ name = properties.String('name') headers = properties.List(properties.String, 'headers') attribute_template = properties.Object(LinkByUID, 'attribute_template') process_templates = properties.List(properties.Object(LinkByUID), 'process_templates') attribute_constraints = properties.Optional( properties.List( properties.SpecifiedMixedList( [properties.Object(LinkByUID), properties.Object(BaseBounds)] ) ), 'attribute_constraints') type_selector = properties.Enumeration(DataObjectTypeSelector, "type_selector") typ = properties.String('type', default="attribute_in_trunk", deserializable=False) def _attrs(self) -> List[str]: return ["name", "headers", "attribute_template", "process_templates", "attribute_constraints", "type_selector", "typ"] def __init__(self, *, name: str, headers: List[str], attribute_template: LinkByUID, process_templates: List[LinkByUID], attribute_constraints: Optional[List[List[Union[LinkByUID, BaseBounds]]]] = None, type_selector: DataObjectTypeSelector = DataObjectTypeSelector.PREFER_RUN): self.name = name self.headers = headers self.attribute_template = attribute_template self.process_templates = process_templates self.attribute_constraints = attribute_constraints self.type_selector = type_selector
class IngredientQuantityByProcessAndName( Serializable['IngredientQuantityByProcessAndName'], Variable): """[ALPHA] The quantity of an ingredient associated with a process template and a name. Parameters --------- name: str a short human-readable name to use when referencing the variable headers: list[str] sequence of column headers process_template: LinkByUID process template associated with this ingredient identifier ingredient_name: str name of ingredient quantity_dimension: IngredientQuantityDimension Dimension of the ingredient quantity: absolute quantity, number, mass, or volume fraction. Valid options are defined by :class:`~citrine.gemtables.variables.IngredientQuantityDimension` type_selector: DataObjectTypeSelector strategy for selecting data object types to consider when matching, defaults to PREFER_RUN unit: str An optional unit: only ingredient quantities that are convertible to this unit will be matched. Note that this parameter is mandatory when quantity_dimension is IngredientQuantityDimension.ABSOLUTE. """ name = properties.String('name') headers = properties.List(properties.String, 'headers') process_template = properties.Object(LinkByUID, 'process_template') ingredient_name = properties.String('ingredient_name') quantity_dimension = properties.Enumeration(IngredientQuantityDimension, 'quantity_dimension') type_selector = properties.Enumeration(DataObjectTypeSelector, "type_selector") typ = properties.String('type', default="ing_quantity_by_process_and_name", deserializable=False) unit = properties.Optional(properties.String, "unit") def _attrs(self) -> List[str]: return [ "name", "headers", "process_template", "ingredient_name", "quantity_dimension", "type_selector", "typ" ] def __init__( self, *, name: str, headers: List[str], process_template: LinkByUID, ingredient_name: str, quantity_dimension: IngredientQuantityDimension, type_selector: DataObjectTypeSelector = DataObjectTypeSelector. PREFER_RUN, unit: Optional[str] = None): self.name = name self.headers = headers self.process_template = process_template self.ingredient_name = ingredient_name self.type_selector = type_selector # Cast to make sure the string is valid if not isinstance(quantity_dimension, IngredientQuantityDimension): quantity_dimension = IngredientQuantityDimension.get_enum( quantity_dimension) self.quantity_dimension = quantity_dimension if quantity_dimension == IngredientQuantityDimension.ABSOLUTE: if unit is None: raise ValueError( "Absolute Quantity variables require that 'unit' is set") else: if unit is not None and unit != "": raise ValueError("Fractional variables cannot take a 'unit'") self.unit = unit