示例#1
0
class DefaultAuxdataClassHandler(DefaultLoggingClass):
    """ Class for retrieving handler classes for auxiliary data
    (mss, sic, sitype, snow). The classes are initialized with directory
    information from the local machine definition and the auxdata information
    from `auxdata.yaml` configuration file.
    """
    def __init__(self):
        super(DefaultAuxdataClassHandler,
              self).__init__(self.__class__.__name__)
        self.pysiral_config = ConfigInfo()
        self.error = ErrorStatus(caller_id=self.__class__.__name__)

    def get_pyclass(self, auxdata_class, auxdata_id, l2_procdef_opt):
        """
        Returns a class for handling auxiliary data files, that is initialized
        with auxdata settings in `config/auxdata_def.yaml` and with the
        directory specified in `local_machine_def.yaml`

        Args:
            auxdata_class (str): Auxdata class (e.g. mss, sic, sitype, snow)
            auxdata_id (str): Auxdata class identifier (e.g. osisaf)

        Returns:
            class: The initialized auxdata handler class
        """

        # Clear errors
        self.error.reset()

        # Initialize the class with information from auxdata_def.yaml
        auxdata_def = self.get_auxdata_def(auxdata_class, auxdata_id)
        if auxdata_def is None:
            error_id = "auxdata_missing_definition"
            error_message = PYSIRAL_ERROR_CODES[error_id] % (auxdata_class,
                                                             auxdata_id)
            self.error.add_error(error_id, error_message)
            self.error.raise_on_error()

        # Set the auxdata config
        cfg = AuxClassConfig()

        # connect to repository on local machine
        if "local_repository" in auxdata_def:
            local_repository_id = auxdata_def.local_repository
            local_repo = self.get_local_repository(auxdata_class,
                                                   local_repository_id)
            if local_repo is None and local_repository_id is not None:
                error_id = "auxdata_missing_localrepo_def"
                error_message = PYSIRAL_ERROR_CODES[error_id] % (auxdata_class,
                                                                 auxdata_id)
                self.error.add_error(error_id, error_message)
                self.error.raise_on_error()
            cfg.set_local_repository(local_repo)

        # set doc str (should be mandatory for all auxdata handlers)
        if "long_name" in auxdata_def:
            cfg.set_long_name(auxdata_def.long_name)

        # set filename (e.g. for mss)
        if "filename" in auxdata_def:
            local_repository_id = auxdata_def.local_repository
            local_repo = self.get_local_repository(auxdata_class,
                                                   local_repository_id)
            filename = os.path.join(local_repo, auxdata_def.filename)
            cfg.set_filename(filename)

        # set filenaming (e.g. for sic, sitype, snow)
        if "filenaming" in auxdata_def:
            cfg.set_filenaming(auxdata_def.filenaming)

        # set subfolders (e.g. for sic, sitype, snow)
        if "subfolders" in auxdata_def:
            cfg.set_subfolder(auxdata_def.subfolders)

        # Set the default options from the auxiliary definition file
        if "options" in auxdata_def:
            options = auxdata_def.get("options", None)
            if options is not None:
                cfg.set_options(**options)

        # Override option with definition from the l2 processor settings
        if l2_procdef_opt is not None:
            cfg.set_options(**l2_procdef_opt)

        # Get the auxiliary data class
        module_name, class_name = "pysiral.auxdata.%s" % (
            auxdata_class), auxdata_def["pyclass"]
        auxclass = get_cls(module_name, class_name)
        if auxclass is None:
            error_id = "auxdata_invalid_class_name"
            msg = "Invalid Auxdata class: %s.%s" % (module_name, class_name)
            self.error.add_error(PYSIRAL_ERROR_CODES[error_id], msg)
            self.error.raise_on_error()

        # Init the auxiliary class
        # Note: This will trigger any action defined in the subclasses, such as reading static background files
        auxdata_handler = auxclass(cfg)

        # All done, return
        return auxdata_handler

    def get_local_repository(self, auxdata_class, auxdata_id):
        """ Get the local repository for the the auxdata type and id """
        if auxdata_id is None:
            return None
        aux_repo_defs = self.pysiral_config.local_machine.auxdata_repository
        try:
            local_repo_auxclass = aux_repo_defs[auxdata_class]
        except KeyError:
            msg = "Missing auxdata definition in local_machine_def.yaml: auxdata_repository.%s" % auxdata_class
            self.error.add_error("missing-localmachinedef-tag", msg)
            self.error.raise_on_error()
        return local_repo_auxclass.get(auxdata_id, None)

    def get_auxdata_def(self, auxdata_class, auxdata_id):
        """ Returns the definition in `config/auxdata_def.yaml` for
        specified auxdata class and id """
        try:
            auxdata_class_def = self.pysiral_config.auxdata[auxdata_class]
        except KeyError:
            msg = "Invalid auxdata class [%s] in auxdata_def.yaml" % auxdata_class
            self.error.add_error("invalid-auxdata-class", msg)
            self.error.raise_on_error()
        return auxdata_class_def.get(auxdata_id, None)
示例#2
0
class DefaultAuxdataClassHandler(DefaultLoggingClass):
    """ Class for retrieving handler classes for auxiliary data
    (mss, sic, sitype, snow). The classes are initialized with directory
    information from the local machine definition and the auxdata information
    from `auxdata.yaml` configuration file.
    """

    def __init__(self):
        super(DefaultAuxdataClassHandler, self).__init__(self.__class__.__name__)
        self.error = ErrorStatus(caller_id=self.__class__.__name__)

    def get_pyclass(self, auxdata_class, auxdata_id, l2_procdef_opt):
        """
        Returns a class for handling auxiliary data files, that is initialized
        with auxdata settings in `config/auxdata_def.yaml` and with the
        directory specified in `local_machine_def.yaml`

        Args:
            auxdata_class (str): Auxdata class (e.g. mss, sic, sitype, snow)
            auxdata_id (str): Auxdata class identifier (e.g. osisaf)

        Returns:
            class: The initialized auxdata handler class
        """

        # Clear errors
        self.error.reset()

        # Initialize the class with information from auxdata_def.yaml
        auxdata_def = self.get_auxdata_def(auxdata_class, auxdata_id)
        if auxdata_def is None:
            error_id = "auxdata_missing_definition"
            error_message = PYSIRAL_ERROR_CODES[error_id] % (auxdata_class, auxdata_id)
            self.error.add_error(error_id, error_message)
            self.error.raise_on_error()

        # Set the auxdata config
        cfg = AuxClassConfig()

        # connect to repository on local machine
        if "local_repository" in auxdata_def:
            local_repository_id = auxdata_def.local_repository
            local_repo = self.get_local_repository(auxdata_class, local_repository_id)
            if local_repo is None and local_repository_id is not None:
                error_id = "auxdata_missing_localrepo_def"
                error_message = f"Missing entry `auxdata_repository.{auxdata_class}.{auxdata_id}` in " + \
                    f"local_machine_def ({psrlcfg.local_machine_def_filepath})"
                self.error.add_error(error_id, error_message)
                self.error.raise_on_error()
            empty_str = len(local_repo) == 0 if local_repo is not None else False
            if empty_str:
                msg = "Path definition for {}.{} exists in local_machine_def.yaml, but is empty string"
                msg = msg.format(auxdata_class, auxdata_id)
                logger.warning(msg)
            cfg.set_local_repository(local_repo)

        # set doc str (should be mandatory for all auxdata handlers)
        if "long_name" in auxdata_def:
            cfg.set_long_name(auxdata_def.long_name)

        # set filename (e.g. for mss)
        if "filename" in auxdata_def:
            local_repository_id = auxdata_def.local_repository
            local_repo = self.get_local_repository(auxdata_class, local_repository_id)
            filename = Path(local_repo) / auxdata_def.filename
            cfg.set_filename(filename)

        # set filenaming (e.g. for sic, sitype, snow)
        if "filenaming" in auxdata_def:
            cfg.set_filenaming(auxdata_def.filenaming)

        # set subfolders (e.g. for sic, sitype, snow)
        if "subfolders" in auxdata_def:
            cfg.set_subfolder(auxdata_def.subfolders)

        # Set the default options from the auxiliary definition file
        if "options" in auxdata_def:
            options = auxdata_def.get("options", None)
            if options is not None:
                cfg.set_options(**options)

        # Override option with definition from the l2 processor settings
        if l2_procdef_opt is not None:
            cfg.set_options(**l2_procdef_opt)

        # Get the auxiliary data class
        module_name, class_name = f"pysiral.auxdata.{auxdata_class}", auxdata_def["pyclass"]
        auxclass = get_cls(module_name, class_name)
        if auxclass is None:
            error_id = "auxdata_invalid_class_name"
            msg = "Invalid Auxdata class: %s.%s" % (module_name, class_name)
            self.error.add_error(PYSIRAL_ERROR_CODES[error_id], msg)
            self.error.raise_on_error()

        # Init the auxiliary class
        # Note: This will trigger any action defined in the subclasses, such as reading static background files
        auxdata_handler = auxclass(cfg)

        # All done, return
        return auxdata_handler

    def get_local_repository(self, auxdata_class, auxdata_id):
        """ Get the local repository for the the auxdata type and id """
        if auxdata_id is None:
            return None
        aux_repo_defs = psrlcfg.local_machine.auxdata_repository
        try:
            local_repo_auxclass = aux_repo_defs[auxdata_class]
        except KeyError:
            local_repo_auxclass = {}
            msg = "Missing auxdata definition in local_machine_def.yaml: auxdata_repository.%s" % auxdata_class
            self.error.add_error("missing-localmachinedef-tag", msg)
            self.error.raise_on_error()
        return local_repo_auxclass.get(auxdata_id, None)

    def get_auxdata_def(self, auxdata_class: str, auxdata_id: str) -> "AttrDict":
        """
        Returns the definition in `config/auxdata_def.yaml` for specified auxdata class and id.
        Raises an error if the entry is not found.
        :param auxdata_class: The code for auxiliary data type (sic, mss, sitype, snow, ...)
        :param auxdata_id: The id of a specific data set for the auxiliary data class (e.g. sic:osisaf-operational)
        :return: The configuration dictionary
        """

        auxdata_def = psrlcfg.auxdef.get_definition(auxdata_class, auxdata_id)
        if auxdata_def is None:
            msg = f"Cannot find entry for auxiliary data set {auxdata_class}:{auxdata_id} in auxdata_def.yaml"
            self.error.add_error("invalid-auxdata-class", msg)
            self.error.raise_on_error()
        return auxdata_def.attrdict