Source code for icenet.utils

import logging
import subprocess as sp

from enum import Flag, auto
from functools import wraps


[docs] class Hemisphere(Flag): """Representation of hemispheres & both with bitwise operations. An enum.Flag derived class representing the different hemispheres (north, south, or both), providing methods to check which hemisphere is selected via bitwise operations: & (AND), | (OR), ^ (XOR), and ~ (INVERT) """ NONE = 0 NORTH = auto() SOUTH = auto() BOTH = NORTH | SOUTH
[docs] class HemisphereMixin: """A mixin relating to Hemisphere checking. Attributes: _hemisphere: Represents the bitmask value of the hemisphere. Defaults to Hemisphere.NONE (i.e., 0). """ _hemisphere: int = Hemisphere.NONE @property def hemisphere(self) -> int: """The bitmask value representing the hemisphere.""" return self._hemisphere @property def hemisphere_str(self) -> list: """A list of strings representing the selected hemispheres.""" return ["north"] if self.north else \ ["south"] if self.south else \ ["north", "south"] @property def hemisphere_loc(self) -> list: """Get a list of latitude and longitude extent representing the hemisphere's location.""" # A list of latitude and longitude extent representing the hemisphere's location. # [north lat, west lon, south lat, east lon] return [90, -180, 0, 180] if self.north else \ [0, -180, -90, 180] if self.south else \ [90, -180, -90, 180] @property def north(self) -> bool: """A flag indicating if `_hemisphere` is north. True if the hemisphere is north, False otherwise.""" return (self._hemisphere & Hemisphere.NORTH) == Hemisphere.NORTH @property def south(self) -> bool: """A flag indicating if `_hemisphere` is south. True if the hemisphere is south, False otherwise.""" return (self._hemisphere & Hemisphere.SOUTH) == Hemisphere.SOUTH @property def both(self) -> int: """The bitmask value representing both hemispheres.""" return self._hemisphere & Hemisphere.BOTH
[docs] def run_command(command: str, dry: bool = False) -> object: """Run a shell command A wrapper in case we want some additional handling to go in here Args: command: Command to run in shell. dry (optional): Whether to do a dry run or to run actual command. Default is False. Returns: subprocess.CompletedProcess return of the executed command. """ if dry: logging.info("Skipping dry command: {}".format(command)) return 0 ret = sp.run(command, shell=True) if ret.returncode < 0: logging.warning( "Child was terminated by signal: {}".format(-ret.returncode)) else: logging.info("Child returned: {}".format(-ret.returncode)) return ret
[docs] def setup_logging(func, log_format="[%(asctime)-17s :%(levelname)-8s] - %(message)s"): @wraps(func) def wrapper(*args, **kwargs): parsed_args = func(*args, **kwargs) level = logging.INFO if hasattr(parsed_args, "verbose") and parsed_args.verbose: level = logging.DEBUG logging.basicConfig( level=level, format=log_format, datefmt="%d-%m-%y %T", ) # TODO: better way of handling these on a case by case basis logging.getLogger("cdsapi").setLevel(logging.WARNING) logging.getLogger("matplotlib").setLevel(logging.WARNING) logging.getLogger("matplotlib.pyplot").setLevel(logging.WARNING) logging.getLogger("requests").setLevel(logging.WARNING) logging.getLogger("tensorflow").setLevel(logging.WARNING) logging.getLogger("urllib3").setLevel(logging.WARNING) return parsed_args return wrapper