Skip to content

Configuration

Config ¤

Source code in feniax/preprocessor/configuration.py
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
class Config:

    def __init__(self, sett: dict):
        self.__sett = copy.copy(sett)
        self.__serial_data = None
        self.__extract_attr()
        self.__load_container()
        self.__defaults()
        self.__set_defaults()        
        self.__build()

    def __extract_attr(self):
        """Extracts attributes that do not belong to a container.
        This attributes are located at the first level of the input settings."""
        if "ex" in self.__sett.keys():
            self.__set_experimental(self.__sett.pop("ex"))
        if "engine" in self.__sett.keys():
            self.__set_attr(engine=self.__sett.pop("engine"))

    def __load_container(self):
        """Load the container with the configuration dataclasses"""

        # TODO: Extend to functionality for various containers
        self.__container = importlib.import_module(
            f"feniax.preprocessor.containers.{self.engine}"
        )
        self.__container = importlib.reload(self.__container)  # remove after testing

    def __defaults(self):
        self.__MOD_DEFAULT = dict(optionsjax=["jax_np", "jax_scipy"])
        self.__CONTAINER_DEFAULT = dict(intrinsicmodal=["const", "log"])

    def __set_defaults(self):
        # default modules
        for k, v in self.__MOD_DEFAULT.items():
            _container = importlib.import_module(f"feniax.preprocessor.containers.{k}")
            for i in v:
                container_k = getattr(_container, "".join(["D", i]))                
                if i in self.__sett.keys():
                    setattr(self, i, container_k(**self.__sett[i]))
                    del self.__sett[i]
                else:
                    setattr(self, i, container_k())
        # default containers within self.engine module
        for k, vlist in self.__CONTAINER_DEFAULT.items():
            if self.engine == k:
                for v in vlist:
                    container_v = getattr(self.__container, "".join(["D", v]))
                    if v in self.__sett.keys():
                        setattr(self, v, container_v(**self.__sett[v]))
                        del self.__sett[v]
                    else:
                        setattr(self, v, container_v())

    def __build(self):
        if self.engine == "intrinsicmodal":  # needs some specialisation here
            k = "fem"  # initialised fem first as it will be pass to system
            v = self.__sett[k]
            container_k = getattr(self.__container, "".join(["D", k]))
            container_k_initialised = container_k(**v)
            setattr(self, k, container_k_initialised)
            for k, v in self.__sett.items():
                if k != "fem" and v is not None: # avoid empty containers
                    container_k = getattr(self.__container, "".join(["D", k]))
                    if k == "systems" or k == "system":  # pass Dfem
                        container_k_initialised = container_k(
                            **(v | dict(_fem=self.fem))
                        )
                    else:
                        container_k_initialised = container_k(**v)
                    setattr(self, k, container_k_initialised)
        else:  # not currently in used
            for k, v in self.__sett.items():
                container_k = getattr(self.__container, "".join(["D", k]))
                setattr(self, k, container_k(**v))

    def __set_experimental(self, experimental: dict):
        ex_object = inputs.dict2object(experimental)
        setattr(self, "ex", ex_object)

    def __set_attr(self, **kwargs):
        for k, v in kwargs.items():
            setattr(self, k, v)

    @classmethod
    def from_file(cls, file_dir: str | pathlib.Path, **kwargs):
        yaml = YAML()
        yaml_dict = yaml.load(pathlib.Path(file_dir))
        return cls(yaml_dict)

    def clone(self, add_attr:dict=None, del_attr:str|list=None):
        self_dict = serialize_nocomments(self)
        if add_attr is not None:
            self_dict = feniax.utils.dict_merge(self_dict, add_attr)
        if del_attr is not None:
            if isinstance(del_attr, str):
                feniax.utils.dict_deletebypath(self_dict, del_attr)
            elif isinstance(del_attr, list):
                for li in del_attr:
                    feniax.utils.dict_deletebypath(self_dict, li)
        return Config(self_dict)

__extract_attr() ¤

Extracts attributes that do not belong to a container. This attributes are located at the first level of the input settings.

Source code in feniax/preprocessor/configuration.py
26
27
28
29
30
31
32
def __extract_attr(self):
    """Extracts attributes that do not belong to a container.
    This attributes are located at the first level of the input settings."""
    if "ex" in self.__sett.keys():
        self.__set_experimental(self.__sett.pop("ex"))
    if "engine" in self.__sett.keys():
        self.__set_attr(engine=self.__sett.pop("engine"))

__load_container() ¤

Load the container with the configuration dataclasses

Source code in feniax/preprocessor/configuration.py
34
35
36
37
38
39
40
41
def __load_container(self):
    """Load the container with the configuration dataclasses"""

    # TODO: Extend to functionality for various containers
    self.__container = importlib.import_module(
        f"feniax.preprocessor.containers.{self.engine}"
    )
    self.__container = importlib.reload(self.__container)  # remove after testing