Skip to content

validation

Full documentation pages are generated for docstring reference only and may contain symbols imported from other modules. Imported symbols are not distinguished from locally defined symbols and will appear in any module that they are imported into. For better information on where symbols should be imported from, review the sourcecode on the github.

FoSpy.parsing.validation

TemplateLists module-attribute

TemplateLists = {
    "experimenters": b.TemplateList.Simple(b.Experimenter),
    "materials": b.TemplateList.Simple(b.Material),
    "treatments": b.TemplateList.Simple(b.Treatment),
    "annealings": b.TemplateList.Simple(b.Annealing),
    "anneal_sections": b.TemplateList.Simple(
        b.AnnealSection
    ),
    "cifs": b.CifList,
}

Maps alias names to TemplateList classes for use in TemplateSet blocks.

_debug module-attribute

_debug = Debug()

aliases module-attribute

aliases = {
    "material": b.Material,
    "materials": b.MaterialList,
    "treatment": b.Treatment,
    "treatments": b.TreatmentList,
    "experimenter": b.Experimenter,
    "experimenters": b.ExperimenterList,
    "embed": b.EmbeddedFile,
}

Maps alias names to block classes for use in non-template SingleBlock blocks.

optional_keys module-attribute

optional_keys = {
    b.Attachment: {
        "embedded": list,
        "path": validators.filenames.PathPosix,
    },
    b.SingleBlock: {
        "rename": validators.rename.rename_dict
    },
    b.Synthesis: {
        "cif": b.Attachment.enforce_subtype(b.CIFFile),
        "cifs": b.CifList,
        "laboratory_conditions": b.LabConditions,
        "equipment": b.EquipmentList,
    },
    b.Experimenter: {"orcid": str},
    b.Product: {
        "expected_amount": validators.numbers.positive_decimal(
            "Product/expected_amount",
            "expected_amount",
            require_unit=True,
        ),
        "expected_amount_unit": validators.units.FOSUnit.enforce_dims(
            ["[mass]", {"[length]": 3}]
        ),
        "obtained_amount": validators.numbers.positive_decimal(
            "Product/obtained_amount",
            "obtained_amount",
            require_unit=True,
        ),
        "obtained_amount_unit": validators.units.FOSUnit.enforce_dims(
            ["[mass]", {"[length]": 3}]
        ),
        "characterizations": str,
        "structure_comments": str,
    },
    b.Material: {
        "purity": validators.numbers.decimal_range(
            "b.Material/purity", "purity", 0, 1
        ),
        "treatments": b.TreatmentList,
    },
    b.Treatment: {
        "recovered_amount": validators.numbers.positive_decimal(
            "b.Treatment/recovered_amount",
            "recovered_amount",
            True,
        ),
        "recovered_amount_unit": validators.units.FOSUnit.enforce_dims(
            ["[mass]", {"[length]": 3}]
        ),
        "start_time": str,
        "end_time": str,
    },
    b.Annealing: {"gas_flow": b.FlowList},
    b.Ramp: {
        "temp": validators.numbers.positive_decimal(
            "RampNoRate/temp", "temp", True
        ),
        "time": validators.numbers.positive_decimal(
            "RampNoRate/time", "time", True
        ),
        "rate": validators.numbers.any_decimal(
            "RampNoTemp/rate", "rate", True
        ),
        "temp_unit": validators.units.FOSTempUnit,
        "time_unit": validators.units.FOSUnit.enforce_dims(
            "[time]"
        ),
        "rate_unit": validators.units.temp_rate_unit,
    },
    b.TemplateSet: TemplateLists,
}

Maps block classes to dictionaries of optional keys and their validators. Validators can be types (e.g. str, int), Block constructors, or custom validator functions.

Optional key mapping is only necessary if the expected value should be passed to a validator. Simple unexpected values can be assigned directly to SingleBlock instance attributes without validation.

required_keys module-attribute

required_keys = {
    b.SingleBlock: {"ext": SubContainer},
    b.FileBlock: {"metadata": b.MetaData},
    b.Synthesis: {
        "metadata": b.SynthesisMeta,
        "experimenters": b.ExperimenterList,
        "reaction": b.Reaction,
        "products": b.ProductList,
        "materials": b.MaterialList,
        "treatments": b.TreatmentList,
    },
    b.TemplateBlock: {"template_name": str},
    b.MetaData: {
        "fos_id": str,
        "fos_type": str,
        "description": str,
    },
    b.SynthesisMeta: {"group_id": str, "project_id": str},
    b.Experimenter: {"name": str, "affiliation": str},
    b.Reaction: {
        "nominal_formula": chemformula.ChemFormula,
        "nominal_amount": validators.numbers.positive_decimal(
            "Reaction/nominal_amount", "nominal_amount"
        ),
        "nominal_amount_unit": validators.units.FOSUnit.enforce_dims(
            ["[mass]", {"[length]": 3}]
        ),
    },
    b.Product: {
        "name": str,
        "expected": bool,
        "obtained": bool,
        "formula": chemformula.ChemFormula,
        "observations": str,
    },
    b.Material: {
        "name": str,
        "type": str,
        "formula": chemformula.ChemFormula,
        "supplier": str,
        "cas": str,
        "form": str,
        "env": str,
        "amount": validators.numbers.positive_decimal(
            "b.Material/amount", "amount"
        ),
        "amount_unit": str,
    },
    b.Treatment: {
        "type": str,
        "repeats": int,
        "observations": str,
    },
    b.AnnealSection: {"type": str},
    b.Dwell: {
        "time": validators.numbers.positive_decimal(
            "Dwell/time", "time", True
        ),
        "time_unit": validators.units.FOSUnit.enforce_dims(
            "[time]"
        ),
    },
    b.Quench: {"medium": str},
    b.Annealing: {
        "program": b.AnnealProgram,
        "start_temp": validators.numbers.positive_decimal(
            "b.Annealing/start_temp", "start_temp", True
        ),
        "start_temp_unit": validators.units.FOSTempUnit,
    },
    b.Attachment: {
        "file_name": validators.filenames.file_name,
        "extension": validators.filenames.file_extension,
    },
}

Maps block classes to dictionaries of required keys and their validators. Validators can be types (e.g. str, int), Block constructors, or custom validator functions.

Debug

Source code in FoSpy/_debug.py
class Debug:
    def __init__(self):
        self.on = False

        frame = inspect.currentframe().f_back
        self.module_name = frame.f_globals.get("__name__", "<unknown>")
        self.label = f"|(Debug message from {self.module_name})"
        self.label_width = len(self.label)

    def _get_text_width(self, module=None):
        if module:
            label = f"|(Debug message from {module} via {self.module_name})"
            label_width = len(label)
        else:
            label = self.label
            label_width = self.label_width

        text_width = DEBUG_WIDTH - label_width
        return text_width, label, label_width


    def msg(self,msg, module=None):
        if not self.on:
            return

        text_width, label, label_width = self._get_text_width(module)

        wrapped = textwrap.fill(str(msg), width=text_width)

        for line in wrapped.splitlines():
            print(f'{line:<{text_width}}{label:>{label_width}}')

    def pmsg(self,msg,module=None,**kwargs):
        if not self.on:
            return

        text_width, label, label_width = self._get_text_width(module)

        buf = io.StringIO()
        pprint(msg,stream=buf, width=text_width,**kwargs)
        txt = buf.getvalue()
        for line in txt.splitlines():
            print(f'{line:<{text_width}}{label:>{label_width}}')

label instance-attribute

label = f'|(Debug message from {self.module_name})'

label_width instance-attribute

label_width = len(self.label)

module_name instance-attribute

module_name = frame.f_globals.get('__name__', '<unknown>')

on instance-attribute

on = False

__init__

__init__()
Source code in FoSpy/_debug.py
def __init__(self):
    self.on = False

    frame = inspect.currentframe().f_back
    self.module_name = frame.f_globals.get("__name__", "<unknown>")
    self.label = f"|(Debug message from {self.module_name})"
    self.label_width = len(self.label)

_get_text_width

_get_text_width(module=None)
Source code in FoSpy/_debug.py
def _get_text_width(self, module=None):
    if module:
        label = f"|(Debug message from {module} via {self.module_name})"
        label_width = len(label)
    else:
        label = self.label
        label_width = self.label_width

    text_width = DEBUG_WIDTH - label_width
    return text_width, label, label_width

msg

msg(msg, module=None)
Source code in FoSpy/_debug.py
def msg(self,msg, module=None):
    if not self.on:
        return

    text_width, label, label_width = self._get_text_width(module)

    wrapped = textwrap.fill(str(msg), width=text_width)

    for line in wrapped.splitlines():
        print(f'{line:<{text_width}}{label:>{label_width}}')

pmsg

pmsg(msg, module=None, **kwargs)
Source code in FoSpy/_debug.py
def pmsg(self,msg,module=None,**kwargs):
    if not self.on:
        return

    text_width, label, label_width = self._get_text_width(module)

    buf = io.StringIO()
    pprint(msg,stream=buf, width=text_width,**kwargs)
    txt = buf.getvalue()
    for line in txt.splitlines():
        print(f'{line:<{text_width}}{label:>{label_width}}')

SubContainer

A simple container for storing hidden or unexpected attributes of a SingleBlock

Values are only assigned directly to SingleBlock attributes if they are an expected property. Otherwise they are assigned to a SubContainer at SingleBlock.ext. Also used for SingleBlock._meta.

Example Usage:

class SingleBlock:
    ... 
    def __setattr__(self, name, value):
        ... 
        if name not in expected:
            return setattr(self.ext, name, value)

Source code in FoSpy/blocks/_containers.py
class SubContainer:
    """
    A simple container for storing hidden or unexpected attributes of a
    `SingleBlock`

    Values are only assigned directly to `SingleBlock` attributes if they are an
    expected property. Otherwise they are assigned to a `SubContainer` at
    `SingleBlock.ext`. Also used for `SingleBlock._meta`.

    Example Usage:
    ```
    class SingleBlock:
        ... 
        def __setattr__(self, name, value):
            ... 
            if name not in expected:
                return setattr(self.ext, name, value)
    ```
    """
    def __init__(self):
        pass
    def __iter__(self):
        return iter(self.__dict__)

__init__

__init__()
Source code in FoSpy/blocks/_containers.py
def __init__(self):
    pass

__iter__

__iter__()
Source code in FoSpy/blocks/_containers.py
def __iter__(self):
    return iter(self.__dict__)