Source code for dachs.metaclasses

#!/usr/bin/env python
# coding: utf-8

"""
A dataclass for specifying metaclasses, superclasses that consist of collections of the end classes.
ExperimentalSetup: a collection of equipment that make up an experimental setup.
"""

__author__ = "Brian R. Pauw"
__contact__ = "brian@stack.nl"
__license__ = "GPLv3+"
__date__ = "2022/11/15"
__status__ = "beta"

import logging

# import logging
from typing import List, Optional  # , Optional

from attrs import Factory, define, field, validators

from dachs.additemstoattrs import addItemsToAttrs
from dachs.equipment import Equipment
from dachs.helpers import whitespaceCleanup
from dachs.reagent import Mixture, Product, Reagent  # , ReagentMixture
from dachs.synthesis import SynthesisClass


[docs] @define class ExperimentalSetupClass(addItemsToAttrs): ID: str = field( default="ExperimentalSetup", validator=validators.instance_of(str), converter=str, ) ExperimentalSetupID: str = field( default="AMSET_", validator=validators.instance_of(str), converter=str, ) SetupName: str = field( default=None, validator=validators.instance_of(str), converter=str, ) Description: str = field( default=None, validator=validators.instance_of(str), converter=whitespaceCleanup, ) EquipmentList: List[Equipment] = field( default=None, validator=validators.instance_of(list), converter=list, ) # internals, don't need a lot of validation: _excludeKeys: list = ["_excludeKeys", "_storeKeys"] # exclude from HDF storage _storeKeys: list = [] # store these keys (will be filled in later) _loadKeys: list = [] # load these keys from file if reconstructing
# def __attrs_post_init__(self): # # auto-generate the store and load key lists: # super().__attrs_post_init__() # @define # class EnvironmentClass(addItemsToAttrs): # """Calss for storing environmental parameters including stirring speed""" # ID: str = field( # default=None, # validator=validators.instance_of(str), # converter=str, # ) # Name: str = field( # default=None, # validator=validators.instance_of(str), # converter=str, # ) # Temperature: Optional[ureg.Quantity] = field( # default=None, # validator=validators.instance_of(ureg.Quantity), # converter=ureg.Quantity, # ) # Humidity: Optional[ureg.Quantity] = field( # default=None, # validator=validators.instance_of(ureg.Quantity), # converter=ureg.Quantity, # ) # Pressure: Optional[ureg.Quantity] = field( # default=None, # validator=validators.instance_of(ureg.Quantity), # converter=ureg.Quantity, # ) # # internals, don't need a lot of validation: # _excludeKeys: list = ["_excludeKeys", "_storeKeys"] # exclude from HDF storage # _storeKeys: list = [] # store these keys (will be filled in later) # _loadKeys: list = [] # load these keys from file if reconstructing
[docs] @define class ChemicalsClass(addItemsToAttrs): StartingCompounds: List[Reagent] = field( default=Factory(list), validator=validators.instance_of(list), ) Mixtures: List[Mixture] = field( default=Factory(list), validator=validators.instance_of(list), ) PotentialProducts: List[Product] = field( default=Factory(list), validator=validators.instance_of(list), ) TargetProduct: Product = field( default=Factory(Product), validator=validators.instance_of(Product), ) FinalProduct: Optional[Product] = field( # probably could use an "evidence" too. default=None, validator=validators.optional(validators.instance_of(Product)), ) # internals, don't need a lot of validation: _excludeKeys: list = ["_excludeKeys", "_storeKeys"] # exclude from HDF storage _storeKeys: list = [] # store these keys (will be filled in later) _loadKeys: list = [] # load these keys from file if reconstructing @property def SynthesisYield(self): assert (self.TargetProduct.Mass is not None) and (self.FinalProduct.Mass is not None), logging.warning( "Yield can only be calculated when both target mass and actual mass are set" ) assert self.TargetProduct.Chemical == self.FinalProduct.Chemical, logging.warning( "Yield can only be calculated when target and final Chemicals are the same " ) return self.FinalProduct.Mass / self.TargetProduct.Mass
# @define # class DocumentationClass(addItemsToAttrs): # RoboticSetup = field( # default=None, # ) # ChemicalReaction = field( # default=None, # )
[docs] @define class Experiment(addItemsToAttrs): ID: str = field( default=None, validator=validators.instance_of(str), converter=str, ) ExperimentName: str = field( default=None, validator=validators.instance_of(str), converter=str, ) Description: str = field( default=None, validator=validators.instance_of(str), converter=whitespaceCleanup, ) Chemicals: Optional[ChemicalsClass] = field( default=None, validator=validators.optional(validators.instance_of(ChemicalsClass)), ) Synthesis: Optional[SynthesisClass] = field( default=None, validator=validators.optional(validators.instance_of(SynthesisClass)), ) # Characterizations: Optional[List] = field( # default=None, # validator=validators.optional(validators.instance_of(list)), # ) ExperimentalSetup: Optional[ExperimentalSetupClass] = field( default=None, validator=validators.optional(validators.instance_of(ExperimentalSetupClass)), ) # Documentation: Optional[DocumentationClass] = field( # default=None, # validator=validators.optional(validators.instance_of(DocumentationClass)), # ) # internals, don't need a lot of validation: _excludeKeys: list = ["_excludeKeys", "_storeKeys"] # exclude from HDF storage _storeKeys: list = [] # store these keys (will be filled in later) _loadKeys: list = [] # load these keys from file if reconstructing