class ContinuousDimension(Serializable['ContinuousDimension'], Dimension): """Continuous dimension that is defined by a template ID, material descriptor, lower bound, and upper bound. Parameters ---------- descriptor: RealDescriptor a descriptor of the single dimension lower_bound: float inclusive lower bound upper_bound: float inclusive upper bound template_id: UUID UUID that corresponds to the template in DC """ descriptor = properties.Object(RealDescriptor, 'descriptor') lower_bound = properties.Float('lower_bound') upper_bound = properties.Float('upper_bound') typ = properties.String('type', default='ContinuousDimension', deserializable=False) template_id = properties.UUID('template_id', default=uuid4()) def __init__(self, descriptor: RealDescriptor, lower_bound: Optional[float] = None, upper_bound: Optional[float] = None, template_id: Optional[UUID] = None): self.descriptor: RealDescriptor = descriptor self.lower_bound: float = lower_bound or descriptor.lower_bound self.upper_bound: float = upper_bound or descriptor.upper_bound self.template_id: UUID = template_id or uuid4()
class DummyDescriptor(object): dummy_map = properties.Mapping(properties.Float(), properties.String) dummy_list = properties.List(properties.Float, properties.String) dummy_set = properties.Set(type(properties.Float())) link_or_else = properties.LinkOrElse() map_collection_key = properties.Mapping( properties.Optional(properties.String), properties.Integer) specified_mixed_list = properties.SpecifiedMixedList( [properties.Integer(default=100)])
class RealDescriptor(Serializable['RealDescriptor'], Descriptor): """A descriptor to hold real-valued numbers. Parameters ---------- key: str the key corresponding to a descriptor lower_bound: float inclusive lower bound for valid real values upper_bound: float inclusive upper bound for valid real values """ lower_bound = properties.Float('lower_bound') upper_bound = properties.Float('upper_bound') units = properties.Optional(properties.String, 'units', default='') typ = properties.String('type', default='Real', deserializable=False) def __eq__(self, other): try: attrs = ["key", "lower_bound", "upper_bound", "units", "typ"] return all([ self.__getattribute__(key) == other.__getattribute__(key) for key in attrs ]) except AttributeError: return False def __init__(self, key: str, lower_bound: float, upper_bound: float, units: Optional[str] = None): self.key: str = key self.lower_bound: float = lower_bound self.upper_bound: float = upper_bound if units is None: msg = "Default of dimensionless is deprecated; \ please specify an empty string explicitly." warnings.warn(msg, category=DeprecationWarning) self.units = "" else: self.units = units def __str__(self): return "<RealDescriptor {!r}>".format(self.key) def __repr__(self): return "RealDescriptor({}, {}, {}, {})".format(self.key, self.lower_bound, self.upper_bound, self.units)
class MeanAndStd(Serializable["MeanAndStd"], DesignVariable): """The mean and standard deviation of a continuous distribution. This does not imply that the distribution is Normal. """ mean = properties.Float('m') """:float: mean of the continuous distribution""" std = properties.Float('s') """:float: standard deviation of the continuous distribution""" def __init__(self): pass # pragma: no cover
class RealDescriptor(Serializable['RealDescriptor'], Descriptor): """[ALPHA] A descriptor to hold real-valued numbers. Parameters ---------- key: str the key corresponding to a descriptor lower_bound: float inclusive lower bound for valid real values upper_bound: float inclusive upper bound for valid real values """ key = properties.String('descriptor_key') lower_bound = properties.Float('lower_bound') upper_bound = properties.Float('upper_bound') units = properties.Optional(properties.String, 'units', default='') typ = properties.String('type', default='Real', deserializable=False) def __eq__(self, other): try: attrs = ["key", "lower_bound", "upper_bound", "units", "typ"] return all([ self.__getattribute__(key) == other.__getattribute__(key) for key in attrs ]) except AttributeError: return False def __init__(self, key: str, lower_bound: float, upper_bound: float, units: str = ''): self.key: str = key self.lower_bound: float = lower_bound self.upper_bound: float = upper_bound self.units: Optional[str] = units def __str__(self): return "<RealDescriptor {!r}>".format(self.key) def __repr__(self): return "RealDescriptor({}, {}, {}, {})".format(self.key, self.lower_bound, self.upper_bound, self.units)
class RealMetricValue(Serializable["RealMetricValue"], MetricValue): """Mean and standard error computed for a real-valued metric.""" mean = properties.Float("mean") """:float: Mean value""" standard_error = properties.Optional(properties.Float(), "standard_error") """:Optional[float]: Standard error of the mean""" typ = properties.String('type', default='RealMetricValue', deserializable=False) def __eq__(self, other): if isinstance(other, RealMetricValue): return self.mean == other.mean and self.standard_error == other.standard_error else: return False
class InorganicDescriptor(Serializable['InorganicDescriptor'], Descriptor): """Captures domain-specific context about the chemical formula for an inorganic compound. Parameters ---------- key: str the key corresponding to a descriptor threshold: float the threshold for valid chemical formulae. Users can think of this as a level of tolerance for typos and/or loss in interpreting a string input as a parseable chemical formula. """ key = properties.String('descriptor_key') threshold = properties.Float('threshold') type = properties.String('type', default='Inorganic', deserializable=False) def __eq__(self, other): try: attrs = ["key", "type"] return all([ self.__getattribute__(key) == other.__getattribute__(key) for key in attrs ]) except Exception: return False def __init__(self, key: str, threshold: float = 1.0): self.key: str = key self.threshold = threshold
class RealDescriptor(Serializable['RealDescriptor'], Descriptor): """Captures domain-specific context about the bounds of an integer-valued datum. Parameters ---------- key: str the key corresponding to a descriptor lower_bound: float inclusive lower bound for valid real values upper_bound: float inclusive upper bound for valid real values """ key = properties.String('descriptor_key') lower_bound = properties.Float('lower_bound') upper_bound = properties.Float('upper_bound') units = properties.Optional(properties.String, 'units', default='') type = properties.String('type', default='Real', deserializable=False) def __eq__(self, other): try: attrs = ["key", "lower_bound", "upper_bound", "units", "type"] return all([ self.__getattribute__(key) == other.__getattribute__(key) for key in attrs ]) except Exception: return False def __init__(self, key: str, lower_bound: float, upper_bound: float, units: str = ''): self.key: str = key self.lower_bound: float = lower_bound self.upper_bound: float = upper_bound self.units: Optional[str] = units
class ContinuousDimension(Serializable['ContinuousDimension'], Dimension): """A continuous, real-valued dimension. Parameters ---------- descriptor: RealDescriptor a descriptor of the single dimension lower_bound: float inclusive lower bound upper_bound: float inclusive upper bound template_id: UUID UUID that corresponds to the template in DC """ descriptor = properties.Object(RealDescriptor, 'descriptor') lower_bound = properties.Float('lower_bound') upper_bound = properties.Float('upper_bound') typ = properties.String('type', default='ContinuousDimension', deserializable=False) template_id = properties.Optional(properties.UUID, 'template_id', default=uuid4()) def __init__(self, descriptor: RealDescriptor, lower_bound: Optional[float] = None, upper_bound: Optional[float] = None, template_id: Optional[UUID] = None): self.descriptor: RealDescriptor = descriptor if lower_bound is not None: self.lower_bound: float = lower_bound else: self.lower_bound: float = descriptor.lower_bound if upper_bound is not None: self.upper_bound: float = upper_bound else: self.upper_bound: float = descriptor.upper_bound self.template_id: Optional[UUID] = template_id
class QuantileColumn(Serializable["QuantileColumn"], Column): """[ALPHA] Column containing a quantile of the variable. The column is populated with the quantile function of the distribution evaluated at "quantile". For example, for a uniform distribution parameterized by a lower and upper bound, the value in the column would be: .. math:: lower + (upper - lower) * quantile while for a normal distribution parameterized by a mean and stddev, the value would be: .. math:: mean + stddev * \\sqrt{2} * erf^{-1}(2 * quantile - 1) Parameters ---------- data_source: str name of the variable to use when populating the column quantile: float the quantile to use for the column, defined between 0.0 and 1.0 target_units: Optional[str] units to convert the real variable into """ data_source = properties.String('data_source') quantile = properties.Float("quantile") target_units = properties.Optional(properties.String, "target_units") typ = properties.String('type', default="quantile_column", deserializable=False) def _attrs(self) -> List[str]: return ["data_source", "quantile", "target_units", "typ"] def __init__(self, *, data_source: str, quantile: float, target_units: Optional[str] = None): self.data_source = data_source self.quantile = quantile self.target_units = target_units
class DesignCandidate(Serializable["DesignCandidate"]): """A Citrine Predictor Evaluation Result. This class represents the candidate computed by a design execution. """ material_id = properties.UUID('material_id') """:UUID: unique Citrine id of the material""" identifiers = properties.List(properties.String(), 'identifiers') """:List[str]: globally unique identifiers assigned to the material""" primary_score = properties.Float('primary_score') """:float: numerical score describing how well the candidate satisfies the objectives and constraints (higher is better)""" material = properties.Object(DesignMaterial, 'material') """:DesignMaterial: the material returned by the design workflow""" def __init__(self): pass # pragma: no cover
class ChemicalFormulaDescriptor(Serializable['ChemicalFormulaDescriptor'], Descriptor): """[ALPHA] Captures domain-specific context about a stoichiometric chemical formula. Parameters ---------- key: str the key corresponding to a descriptor """ key = properties.String('descriptor_key') # `threshold` exists in the backend but is not configurable through this client. It is fixed # to 1.0 which means that chemical formula string parsing is strict with regards to typos. threshold = properties.Float('threshold', deserializable=False, default=1.0) typ = properties.String('type', default='Inorganic', deserializable=False) def __eq__(self, other): try: attrs = ["key", "threshold", "typ"] return all([ self.__getattribute__(key) == other.__getattribute__(key) for key in attrs ]) except AttributeError: return False def __init__(self, key: str): self.key: str = key def __str__(self): return "<ChemicalFormulaDescriptor {!r}>".format(self.key) def __repr__(self): return "ChemicalFormulaDescriptor(key={})".format(self.key)
class FormulationDesignSpace(Resource['FormulationDesignSpace'], DesignSpace, AIResourceMetadata): """Design space composed of mixtures of ingredients. Parameters ---------- name: str the name of the design space description: str the description of the design space formulation_descriptor: FormulationDescriptor descriptor used to store formulations sampled from the design space ingredients: Set[str] set of ingredient names that can be used in a formulation constraints: Set[IngredientConstraint] set of constraints that restricts formulations sampled from the space. This must include an :class:`~io.citrine.informatics.constraints.ingredient_count_constraint.IngredientCountConstraint` with maximum count of 32 or fewer. labels: Optional[Mapping[str, Set[str]]] map from a label to each ingredient that should given that label when it's included in a formulation, e.g., ``{'solvent': {'water', 'alcohol'}}`` resolution: float, optional Minimum increment used to specify ingredient quantities. Default is 0.0001. """ _resource_type = ResourceTypeEnum.MODULE formulation_descriptor = properties.Object( FormulationDescriptor, 'config.formulation_descriptor') ingredients = properties.Set(properties.String, 'config.ingredients') labels = properties.Optional( properties.Mapping(properties.String, properties.Set(properties.String)), 'config.labels') constraints = properties.Set(properties.Object(Constraint), 'config.constraints') resolution = properties.Float('config.resolution') typ = properties.String('config.type', default='FormulationDesignSpace', deserializable=False) module_type = properties.String('module_type', default='DESIGN_SPACE', deserializable=False) def __init__(self, *, name: str, description: str, formulation_descriptor: FormulationDescriptor, ingredients: Set[str], constraints: Set[Constraint], labels: Optional[Mapping[str, Set[str]]] = None, resolution: float = 0.0001, session: Session = Session()): self.name: str = name self.description: str = description self.formulation_descriptor: FormulationDescriptor = formulation_descriptor self.ingredients: Set[str] = ingredients self.constraints: Set[Constraint] = constraints self.labels: Optional[Mapping[str, Set[str]]] = labels self.resolution: float = resolution self.session: Session = session def _post_dump(self, data: dict) -> dict: data['display_name'] = data['config']['name'] return data def __str__(self): return '<FormulationDesignSpace {!r}>'.format(self.name)