From d1a0dfd6d9fb6227cc5feed1a437a406d6d33bbe Mon Sep 17 00:00:00 2001 From: teutoburg Date: Wed, 20 Dec 2023 18:08:08 +0100 Subject: [PATCH 01/14] Get logger from utils function instead of root logging --- scopesim/commands/user_commands.py | 13 +-- scopesim/detector/detector.py | 14 ++-- scopesim/detector/detector_array.py | 10 +-- scopesim/effects/apertures.py | 11 +-- scopesim/effects/detector_list.py | 24 +++--- scopesim/effects/effects_utils.py | 7 +- scopesim/effects/electronic.py | 38 +++++---- scopesim/effects/psf_utils.py | 8 +- scopesim/effects/shutter.py | 8 +- scopesim/effects/spectral_efficiency.py | 8 +- scopesim/effects/spectral_trace_list.py | 18 ++-- scopesim/effects/spectral_trace_list_utils.py | 37 +++++---- scopesim/effects/ter_curves.py | 10 ++- scopesim/effects/ter_curves_utils.py | 11 ++- scopesim/optics/fov.py | 48 +++++------ scopesim/optics/fov_manager_utils.py | 10 ++- scopesim/optics/fov_utils.py | 34 ++++---- scopesim/optics/image_plane.py | 15 ++-- scopesim/optics/image_plane_utils.py | 82 +++++++++---------- scopesim/optics/optical_element.py | 10 ++- scopesim/optics/optics_manager.py | 9 +- scopesim/optics/radiometry_utils.py | 13 +-- scopesim/optics/surface.py | 15 ++-- scopesim/optics/surface_utils.py | 17 ++-- scopesim/server/database.py | 19 +++-- scopesim/server/download_utils.py | 22 +++-- scopesim/server/github_utils.py | 9 +- scopesim/source/source.py | 53 ++++++------ scopesim/source/source_utils.py | 18 ++-- scopesim/utils.py | 4 + 30 files changed, 328 insertions(+), 267 deletions(-) diff --git a/scopesim/commands/user_commands.py b/scopesim/commands/user_commands.py index 2d40336f..713f4ad8 100644 --- a/scopesim/commands/user_commands.py +++ b/scopesim/commands/user_commands.py @@ -1,14 +1,15 @@ import os -import logging import copy from pathlib import Path -import numpy as np import yaml import httpx from .. import rc -from ..utils import find_file, top_level_catch +from ..utils import find_file, top_level_catch, get_logger + + +logger = get_logger(__name__) __all__ = ["UserCommands"] @@ -181,7 +182,7 @@ def update(self, **kwargs): if yaml_input == "default.yaml": self.default_yamls = yaml_dict else: - logging.warning("%s could not be found", yaml_input) + logger.warning("%s could not be found", yaml_input) elif isinstance(yaml_input, dict): self.cmds.update(yaml_input) @@ -232,7 +233,7 @@ def set_modes(self, modes=None): if mode in self.modes_dict: defyam["properties"]["modes"].append(mode) if "deprecate" in self.modes_dict[mode]: - logging.warning(self.modes_dict[mode]["deprecate"]) + logger.warning(self.modes_dict[mode]["deprecate"]) else: raise ValueError(f"mode '{mode}' was not recognised") @@ -362,7 +363,7 @@ def add_packages_to_rc_search(local_path, package_list): if not pkg_dir.exists(): # todo: keep here, but add test for this by downloading test_package # raise ValueError("Package could not be found: {}".format(pkg_dir)) - logging.warning("Package could not be found: %s", pkg_dir) + logger.warning("Package could not be found: %s", pkg_dir) rc.__search_path__.append_first(pkg_dir) diff --git a/scopesim/detector/detector.py b/scopesim/detector/detector.py index 9c796395..62a3efe1 100644 --- a/scopesim/detector/detector.py +++ b/scopesim/detector/detector.py @@ -1,14 +1,16 @@ -import logging import numpy as np from ..base_classes import ImagePlaneBase, DetectorBase from ..optics import image_plane_utils as imp_utils -from .. import utils +from ..utils import get_logger, from_currsys, stringify_dict from astropy.io import fits from astropy.wcs import WCS +logger = get_logger(__name__) + + class Detector(DetectorBase): def __init__(self, header, **kwargs): image = np.zeros((header["NAXIS2"], header["NAXIS1"])) @@ -33,13 +35,13 @@ def reset(self): @property def hdu(self): - new_meta = utils.stringify_dict(self.meta) + new_meta = stringify_dict(self.meta) self._hdu.header.update(new_meta) - pixel_scale = utils.from_currsys("!INST.pixel_scale") - plate_scale = utils.from_currsys("!INST.plate_scale") + pixel_scale = from_currsys("!INST.pixel_scale") + plate_scale = from_currsys("!INST.plate_scale") if pixel_scale == 0 or plate_scale == 0: - logging.warning("Could not create sky WCS.") + logger.warning("Could not create sky WCS.") else: sky_wcs, _ = imp_utils.sky_wcs_from_det_wcs( WCS(self._hdu.header, key="D"), pixel_scale, plate_scale) diff --git a/scopesim/detector/detector_array.py b/scopesim/detector/detector_array.py index 1a889514..68ab412a 100644 --- a/scopesim/detector/detector_array.py +++ b/scopesim/detector/detector_array.py @@ -1,13 +1,13 @@ # -*- coding: utf-8 -*- """Contains DetectorArray and aux functions.""" -import logging - from astropy.io import fits from .detector import Detector +from ..utils import stringify_dict, get_logger + -from .. import utils +logger = get_logger(__name__) class DetectorArray: @@ -86,7 +86,7 @@ def readout(self, image_planes, array_effects=None, dtcr_effects=None, for hdr in self._detector_list.detector_headers()] # 4. iterate through all Detectors, extract image from image_plane - logging.info("Extracting from %d detectors...", len(self.detectors)) + logger.info("Extracting from %d detectors...", len(self.detectors)) for detector in self.detectors: detector.extract_from(image_plane) @@ -133,7 +133,7 @@ def _repr_pretty_(self, p, cycle): def make_primary_hdu(meta): """Create the primary header from meta data.""" prihdu = fits.PrimaryHDU() - prihdu.header.update(utils.stringify_dict(meta)) + prihdu.header.update(stringify_dict(meta)) return prihdu diff --git a/scopesim/effects/apertures.py b/scopesim/effects/apertures.py index 7f041fe3..91484ed2 100644 --- a/scopesim/effects/apertures.py +++ b/scopesim/effects/apertures.py @@ -1,7 +1,5 @@ """Effects related to field masks, including spectroscopic slits.""" -from pathlib import Path -import logging import yaml import numpy as np @@ -14,8 +12,11 @@ from ..optics import image_plane_utils as imp_utils from ..base_classes import FOVSetupBase -from ..utils import quantify, quantity_from_table, from_currsys, check_keys, \ - figure_factory +from ..utils import (quantify, quantity_from_table, from_currsys, check_keys, + figure_factory, get_logger) + + +logger = get_logger(__name__) class ApertureMask(Effect): @@ -126,7 +127,7 @@ def apply_to(self, obj, **kwargs): # Outdated. Remove when removing all old FOVManager code from effects def fov_grid(self, which="edges", **kwargs): """Return a header with the sky coordinates.""" - logging.warning("DetectorList.fov_grid will be depreciated in v1.0") + logger.warning("DetectorList.fov_grid will be depreciated in v1.0") if which == "edges": self.meta.update(kwargs) return self.header diff --git a/scopesim/effects/detector_list.py b/scopesim/effects/detector_list.py index 2ae7b96d..1d13866b 100644 --- a/scopesim/effects/detector_list.py +++ b/scopesim/effects/detector_list.py @@ -1,7 +1,5 @@ """TBA.""" -import logging - import numpy as np from astropy import units as u from astropy.table import Table @@ -9,9 +7,11 @@ from ..base_classes import FOVSetupBase from .effects import Effect from .apertures import ApertureMask -from .. import utils -from ..utils import close_loop, figure_factory from ..optics.image_plane_utils import header_from_list_of_xy, calc_footprint +from ..utils import (from_currsys, close_loop, figure_factory, + quantity_from_table, unit_from_table, get_logger) + +logger = get_logger(__name__) __all__ = ["DetectorList", "DetectorWindow"] @@ -141,7 +141,7 @@ def apply_to(self, obj, **kwargs): xy_mm = calc_footprint(hdr, "D") pixel_size = hdr["CDELT1D"] # mm pixel_scale = kwargs.get("pixel_scale", self.meta["pixel_scale"]) # ["] - pixel_scale = utils.from_currsys(pixel_scale) + pixel_scale = from_currsys(pixel_scale) # x["] = x[mm] * ["] / [mm] xy_sky = xy_mm * pixel_scale / pixel_size @@ -158,11 +158,11 @@ def apply_to(self, obj, **kwargs): def fov_grid(self, which="edges", **kwargs): """Return an ApertureMask object. kwargs are "pixel_scale" [arcsec].""" - logging.warning("DetectorList.fov_grid will be depreciated in v1.0") + logger.warning("DetectorList.fov_grid will be depreciated in v1.0") aperture_mask = None if which == "edges": self.meta.update(kwargs) - self.meta = utils.from_currsys(self.meta) + self.meta = from_currsys(self.meta) hdr = self.image_plane_header xy_mm = calc_footprint(hdr, "D") @@ -181,9 +181,9 @@ def fov_grid(self, which="edges", **kwargs): @property def image_plane_header(self): tbl = self.active_table - pixel_size = np.min(utils.quantity_from_table("pixel_size", tbl, u.mm)) - x_unit = utils.unit_from_table("x_size", tbl, u.mm) - y_unit = utils.unit_from_table("y_size", tbl, u.mm) + pixel_size = np.min(quantity_from_table("pixel_size", tbl, u.mm)) + x_unit = unit_from_table("x_size", tbl, u.mm) + y_unit = unit_from_table("y_size", tbl, u.mm) xcen = tbl["x_cen"].data.astype(float) ycen = tbl["y_cen"].data.astype(float) @@ -221,7 +221,7 @@ def active_table(self): else: raise ValueError("Could not determine which detectors are active: " f"{self.meta['active_detectors']}, {self.table},") - tbl = utils.from_currsys(tbl) + tbl = from_currsys(tbl) return tbl @@ -229,7 +229,7 @@ def detector_headers(self, ids=None): if ids is not None and all(isinstance(ii, int) for ii in ids): self.meta["active_detectors"] = list(ids) - tbl = utils.from_currsys(self.active_table) + tbl = from_currsys(self.active_table) hdrs = [] for row in tbl: pixel_size = row["pixel_size"] diff --git a/scopesim/effects/effects_utils.py b/scopesim/effects/effects_utils.py index 780c1bbc..c3c680c2 100644 --- a/scopesim/effects/effects_utils.py +++ b/scopesim/effects/effects_utils.py @@ -1,6 +1,5 @@ """TBA.""" -import logging import inspect from copy import deepcopy, copy from collections.abc import Iterable @@ -8,6 +7,10 @@ from astropy.table import Table from .. import effects as efs +from ..utils import get_logger + + +logger = get_logger(__name__) def combine_surface_effects_OLD(surface_effects): @@ -132,7 +135,7 @@ def z_order_in_range(z_eff, z_range: range) -> bool: """ if not isinstance(z_eff, Iterable): - logging.warning("z_order %d should be a single-item iterable", z_eff) + logger.warning("z_order %d should be a single-item iterable", z_eff) z_eff = [z_eff] return any(zi in z_range for zi in z_eff) diff --git a/scopesim/effects/electronic.py b/scopesim/effects/electronic.py index f1e0f3c7..f40d9e07 100644 --- a/scopesim/effects/electronic.py +++ b/scopesim/effects/electronic.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- """ Electronic detector effects - related to detector readout. @@ -20,8 +21,6 @@ - pseudo_random_field """ -import logging - import numpy as np from astropy.io import fits @@ -29,8 +28,11 @@ from .. import rc from . import Effect from ..base_classes import DetectorBase, ImagePlaneBase -from ..utils import from_currsys, figure_factory -from .. import utils +from ..utils import (from_currsys, figure_factory, check_keys, real_colname, + pretty_print_dict, get_logger) + + +logger = get_logger(__name__) class DetectorModePropertiesSetter(Effect): @@ -89,7 +91,7 @@ def __init__(self, **kwargs): self.meta.update(kwargs) required_keys = ["mode_properties"] - utils.check_keys(self.meta, required_keys, action="error") + check_keys(self.meta, required_keys, action="error") self.mode_properties = kwargs["mode_properties"] @@ -110,7 +112,7 @@ def apply_to(self, obj, **kwargs): def list_modes(self): """Return list of available detector modes.""" - return utils.pretty_print_dict(self.mode_properties) + return pretty_print_dict(self.mode_properties) def select_mode(self, obj, **kwargs): """Automatically select detector mode based on image plane peak value. @@ -183,7 +185,7 @@ def __init__(self, **kwargs): self.meta.update(kwargs) required_keys = ["fill_frac", "full_well", "mindit"] - utils.check_keys(self.meta, required_keys, action="error") + check_keys(self.meta, required_keys, action="error") def apply_to(self, obj, **kwargs): if isinstance(obj, (ImagePlaneBase, DetectorBase)): @@ -236,7 +238,7 @@ def __init__(self, **kwargs): self.meta.update(kwargs) required_keys = ["dit", "ndit"] - utils.check_keys(self.meta, required_keys, action="error") + check_keys(self.meta, required_keys, action="error") def apply_to(self, obj, **kwargs): if isinstance(obj, DetectorBase): @@ -258,7 +260,7 @@ def __init__(self, **kwargs): self.meta.update(kwargs) required_keys = ["bias"] - utils.check_keys(self.meta, required_keys, action="error") + check_keys(self.meta, required_keys, action="error") def apply_to(self, obj, **kwargs): if isinstance(obj, DetectorBase): @@ -282,7 +284,7 @@ def __init__(self, **kwargs): self.meta.update(kwargs) self.required_keys = ["noise_std", "n_channels", "ndit"] - utils.check_keys(self.meta, self.required_keys, action="error") + check_keys(self.meta, self.required_keys, action="error") def apply_to(self, det, **kwargs): if isinstance(det, DetectorBase): @@ -329,7 +331,7 @@ def __init__(self, **kwargs): self.meta.update(kwargs) self.required_keys = ["noise_std", "ndit"] - utils.check_keys(self.meta, self.required_keys, action="error") + check_keys(self.meta, self.required_keys, action="error") def apply_to(self, det, **kwargs): if isinstance(det, DetectorBase): @@ -379,7 +381,7 @@ def apply_to(self, det, **kwargs): # Check if there are negative values in the data negvals = np.sum(data < 0) if negvals: - logging.warning(f"Effect ShotNoise: {negvals} negative pixels") + logger.warning(f"Effect ShotNoise: {negvals} negative pixels") data[data < 0] = 0 below = data < 2**20 @@ -411,12 +413,12 @@ def __init__(self, **kwargs): self.meta["z_order"] = [830] required_keys = ["value", "dit", "ndit"] - utils.check_keys(self.meta, required_keys, action="error") + check_keys(self.meta, required_keys, action="error") def apply_to(self, obj, **kwargs): if isinstance(obj, DetectorBase): if isinstance(from_currsys(self.meta["value"]), dict): - dtcr_id = obj.meta[utils.real_colname("id", obj.meta)] + dtcr_id = obj.meta[real_colname("id", obj.meta)] dark = from_currsys(self.meta["value"][dtcr_id]) elif isinstance(from_currsys(self.meta["value"]), float): dark = from_currsys(self.meta["value"]) @@ -485,7 +487,7 @@ def __init__(self, **kwargs): self.meta.update(kwargs) self.required_keys = ["ndit"] - utils.check_keys(self.meta, self.required_keys, action="error") + check_keys(self.meta, self.required_keys, action="error") def apply_to(self, obj, **kwargs): if isinstance(obj, DetectorBase): @@ -552,7 +554,7 @@ def __init__(self, **kwargs): self.meta["z_order"] = [870] self.required_keys = ["bin_size"] - utils.check_keys(self.meta, self.required_keys, action="error") + check_keys(self.meta, self.required_keys, action="error") def apply_to(self, det, **kwargs): if isinstance(det, DetectorBase): @@ -570,7 +572,7 @@ def __init__(self, **kwargs): self.meta["z_order"] = [870] self.required_keys = ["binx","biny"] - utils.check_keys(self.meta, self.required_keys, action="error") + check_keys(self.meta, self.required_keys, action="error") def apply_to(self, det, **kwargs): if isinstance(det, DetectorBase): @@ -602,7 +604,7 @@ def apply_to(self, obj, **kwargs): new_dtype = self.meta["dtype"] if not np.issubdtype(new_dtype, np.integer): - logging.warning("Setting quantized data to dtype %s, which is not " + logger.warning("Setting quantized data to dtype %s, which is not " "an integer subtype.", new_dtype) # This used to create a new ImageHDU with the same header but the data diff --git a/scopesim/effects/psf_utils.py b/scopesim/effects/psf_utils.py index e411be5a..450f966b 100644 --- a/scopesim/effects/psf_utils.py +++ b/scopesim/effects/psf_utils.py @@ -1,5 +1,4 @@ import numpy as np -import logging from scipy import ndimage as spi from scipy.interpolate import RectBivariateSpline, griddata @@ -10,7 +9,10 @@ from .. import utils from ..optics import image_plane_utils as imp_utils -from ..utils import figure_factory +from ..utils import figure_factory, get_logger + + +logger = get_logger(__name__) def round_kernel_edges(kernel): @@ -141,7 +143,7 @@ def cutout_kernel(image, fov_header, kernel_header=None): xcen, ycen = 0.5 * w, 0.5 * h xcen_w, ycen_w = wk.wcs_world2pix(np.array([[0., 0.]]), 0).squeeze().round(7) if xcen != xcen_w or ycen != ycen_w: - logging.warning("PSF center off") + logger.warning("PSF center off") dx = 0.5 * fov_header["NAXIS1"] dy = 0.5 * fov_header["NAXIS2"] diff --git a/scopesim/effects/shutter.py b/scopesim/effects/shutter.py index 5f0c9c1d..1ffd09d1 100644 --- a/scopesim/effects/shutter.py +++ b/scopesim/effects/shutter.py @@ -1,10 +1,12 @@ # -*- coding: utf-8 -*- """Contains the Shutter effect.""" -import logging - from . import Effect from ..base_classes import ImagePlaneBase +from ..utils import get_logger + + +logger = get_logger(__name__) class Shutter(Effect): @@ -19,6 +21,6 @@ def apply_to(self, obj, **kwargs): if not isinstance(obj, ImagePlaneBase): return obj - logging.warning("Shutter is closed, setting all pixels to zero.") + logger.warning("Shutter is closed, setting all pixels to zero.") obj.data[:] = 0.0 return obj diff --git a/scopesim/effects/spectral_efficiency.py b/scopesim/effects/spectral_efficiency.py index 69d0ffa7..628281c0 100644 --- a/scopesim/effects/spectral_efficiency.py +++ b/scopesim/effects/spectral_efficiency.py @@ -1,6 +1,5 @@ """Spectral grating efficiencies.""" -import logging import numpy as np from astropy.io import fits @@ -11,7 +10,10 @@ from .effects import Effect from .ter_curves import TERCurve from .ter_curves_utils import apply_throughput_to_cube -from ..utils import figure_factory +from ..utils import figure_factory, get_logger + + +logger = get_logger(__name__) class SpectralEfficiency(Effect): @@ -101,7 +103,7 @@ def apply_to(self, obj, **kwargs): try: effic = self.efficiencies[trace_id] except KeyError: - logging.warning("No grating efficiency for trace %s", trace_id) + logger.warning("No grating efficiency for trace %s", trace_id) return obj wcs = WCS(obj.hdu.header).spectral diff --git a/scopesim/effects/spectral_trace_list.py b/scopesim/effects/spectral_trace_list.py index 72174942..60b3e24f 100644 --- a/scopesim/effects/spectral_trace_list.py +++ b/scopesim/effects/spectral_trace_list.py @@ -5,7 +5,6 @@ `spectral_trace_list_utils.SpectralTrace` objects to a `FieldOfView`. """ -import logging from itertools import cycle from tqdm import tqdm @@ -16,9 +15,12 @@ from .effects import Effect from .ter_curves import FilterCurve from .spectral_trace_list_utils import SpectralTrace, make_image_interpolations -from ..utils import from_currsys, check_keys, figure_factory from ..optics.image_plane_utils import header_from_list_of_xy from ..base_classes import FieldOfViewBase, FOVSetupBase +from ..utils import from_currsys, check_keys, figure_factory, get_logger + + +logger = get_logger(__name__) class SpectralTraceList(Effect): @@ -193,7 +195,7 @@ def apply_to(self, obj, **kwargs): # for MAAT pass elif obj.hdu is None and obj.cube is None: - logging.info("Making cube") + logger.info("Making cube") obj.cube = obj.make_cube_hdu() spt = self.spectral_traces[obj.trace_id] @@ -267,18 +269,18 @@ def rectify_traces(self, hdulist, xi_min=None, xi_max=None, interps=None, filtwaves = filtcurve.table["wavelength"] filtwave = filtwaves[filtcurve.table["transmission"] > 0.01] wave_min, wave_max = min(filtwave), max(filtwave) - logging.info("Full wavelength range: %.02f .. %.02f um", - wave_min, wave_max) + logger.info("Full wavelength range: %.02f .. %.02f um", + wave_min, wave_max) if xi_min is None or xi_max is None: try: xi_min = inhdul[0].header["HIERARCH INS SLIT XIMIN"] xi_max = inhdul[0].header["HIERARCH INS SLIT XIMAX"] - logging.info( + logger.info( "Slit limits taken from header: %.02f .. %.02f arcsec", xi_min, xi_max) except KeyError: - logging.error(""" + logger.error(""" Spatial slit limits (in arcsec) must be provided: - either as method parameters xi_min and xi_max - or as header keywords HIERARCH INS SLIT XIMIN/XIMAX @@ -288,7 +290,7 @@ def rectify_traces(self, hdulist, xi_min=None, xi_max=None, interps=None, bin_width = kwargs.get("bin_width", None) if interps is None: - logging.info("Computing interpolation functions") + logger.info("Computing interpolation functions") interps = make_image_interpolations(hdulist) pdu = fits.PrimaryHDU() diff --git a/scopesim/effects/spectral_trace_list_utils.py b/scopesim/effects/spectral_trace_list_utils.py index 275e6f36..e29390b9 100644 --- a/scopesim/effects/spectral_trace_list_utils.py +++ b/scopesim/effects/spectral_trace_list_utils.py @@ -9,8 +9,6 @@ - utility functions for use with spectral traces """ -import logging - import numpy as np from scipy.interpolate import RectBivariateSpline @@ -23,8 +21,11 @@ from astropy.wcs import WCS from astropy.modeling.models import Polynomial2D -from ..utils import power_vector, quantify, from_currsys, close_loop, \ - figure_factory +from ..utils import (power_vector, quantify, from_currsys, close_loop, + figure_factory, get_logger) + + +logger = get_logger(__name__) class SpectralTrace: @@ -136,7 +137,7 @@ def compute_interpolation_functions(self): self.dispersion_axis = "x" else: self.dispersion_axis = "y" - logging.warning("Dispersion axis determined to be %s", + logger.warning("Dispersion axis determined to be %s", self.dispersion_axis) def map_spectra_to_focal_plane(self, fov): @@ -149,7 +150,7 @@ def map_spectra_to_focal_plane(self, fov): The method returns a section of the fov image along with info on where this image lies in the focal plane. """ - logging.info("Mapping %s", fov.trace_id) + logger.info("Mapping %s", fov.trace_id) # Initialise the image based on the footprint of the spectral # trace and the focal plane WCS wave_min = fov.meta["wave_min"].value # [um] @@ -160,7 +161,7 @@ def map_spectra_to_focal_plane(self, fov): xi_min=xi_min, xi_max=xi_max) if xlim_mm is None: - logging.warning("xlim_mm is None") + logger.warning("xlim_mm is None") return None fov_header = fov.header @@ -182,7 +183,7 @@ def map_spectra_to_focal_plane(self, fov): # Check if spectral trace footprint is outside FoV if xmax < 0 or xmin > naxis1d or ymax < 0 or ymin > naxis2d: - logging.info("Spectral trace %s: footprint is outside FoV", + logger.info("Spectral trace %s: footprint is outside FoV", fov.trace_id) return None @@ -274,7 +275,7 @@ def map_spectra_to_focal_plane(self, fov): img_header["YMAX"] = ymax if np.any(image < 0): - logging.warning("map_spectra_to_focal_plane: %d negative pixels", + logger.warning("map_spectra_to_focal_plane: %d negative pixels", np.sum(image < 0)) image_hdu = fits.ImageHDU(header=img_header, data=image) @@ -308,25 +309,25 @@ def rectify(self, hdulist, interps=None, wcs=None, **kwargs): Spatial limits of the slit on the sky. This should be taken from the header of the hdulist, but this is not yet provided by scopesim """ - logging.info("Rectifying %s", self.trace_id) + logger.info("Rectifying %s", self.trace_id) wave_min = kwargs.get("wave_min", self.wave_min) wave_max = kwargs.get("wave_max", self.wave_max) if wave_max < self.wave_min or wave_min > self.wave_max: - logging.info(" Outside filter range") + logger.info(" Outside filter range") return None wave_min = max(wave_min, self.wave_min) wave_max = min(wave_max, self.wave_max) - logging.info(" %.02f .. %.02f um", wave_min, wave_max) + logger.info(" %.02f .. %.02f um", wave_min, wave_max) # bin_width is taken as the minimum dispersion of the trace bin_width = kwargs.get("bin_width", None) if bin_width is None: self._set_dispersion(wave_min, wave_max) bin_width = np.abs(self.dlam_per_pix.y).min() - logging.info(" Bin width %.02g um", bin_width) + logger.info(" Bin width %.02g um", bin_width) pixscale = from_currsys(self.meta["pixel_scale"]) @@ -336,14 +337,14 @@ def rectify(self, hdulist, interps=None, wcs=None, **kwargs): try: xi_min = hdulist[0].header["HIERARCH INS SLIT XIMIN"] except KeyError: - logging.error("xi_min not found") + logger.error("xi_min not found") return None xi_max = kwargs.get("xi_max", None) if xi_max is None: try: xi_max = hdulist[0].header["HIERARCH INS SLIT XIMAX"] except KeyError: - logging.error("xi_max not found") + logger.error("xi_max not found") return None if wcs is None: @@ -361,7 +362,7 @@ def rectify(self, hdulist, interps=None, wcs=None, **kwargs): # Create interpolation functions if not provided if interps is None: - logging.info("Computing image interpolations") + logger.info("Computing image interpolations") interps = make_image_interpolations(hdulist, kx=1, ky=1) # Create Xi, Lam images (do I need Iarr and Jarr or can I build Xi, Lam directly?) @@ -676,8 +677,8 @@ def __init__(self, fov, dlam_per_pix): dlam_per_pix_val = dlam_per_pix(np.asarray(self.lam)) except TypeError: dlam_per_pix_val = dlam_per_pix - logging.warning("Using scalar dlam_per_pix = %.2g", - dlam_per_pix_val) + logger.warning("Using scalar dlam_per_pix = %.2g", + dlam_per_pix_val) for i, eta in enumerate(cube_eta): lam0 = self.lam + dlam_per_pix_val * eta / d_eta diff --git a/scopesim/effects/ter_curves.py b/scopesim/effects/ter_curves.py index 9b9a5dc3..dbe56414 100644 --- a/scopesim/effects/ter_curves.py +++ b/scopesim/effects/ter_curves.py @@ -1,6 +1,5 @@ """Transmission, emissivity, reflection curves.""" -import logging from collections.abc import Collection import numpy as np @@ -16,8 +15,11 @@ from ..base_classes import SourceBase, FOVSetupBase from ..optics.surface import SpectralSurface from ..source.source import Source -from ..utils import from_currsys, quantify, check_keys, find_file, \ - figure_factory +from ..utils import (from_currsys, quantify, check_keys, find_file, + figure_factory, get_logger) + + +logger = get_logger(__name__) class TERCurve(Effect): @@ -338,7 +340,7 @@ def query_server(self, **kwargs): tbl = self.skycalc_conn.get_sky_spectrum(return_type="table") except ConnectionError: msg = "Could not connect to skycalc server" - logging.exception(msg) + logger.exception(msg) raise ValueError(msg) return tbl diff --git a/scopesim/effects/ter_curves_utils.py b/scopesim/effects/ter_curves_utils.py index eb9b2702..370ec5a2 100644 --- a/scopesim/effects/ter_curves_utils.py +++ b/scopesim/effects/ter_curves_utils.py @@ -1,7 +1,6 @@ """TBA.""" from pathlib import Path -import logging import numpy as np from astropy import units as u @@ -14,7 +13,11 @@ from scopesim.source.source_templates import vega_spectrum, st_spectrum, \ ab_spectrum -from ..utils import find_file, quantity_from_table, from_currsys +from ..utils import find_file, quantity_from_table, from_currsys, get_logger + + +logger = get_logger(__name__) + FILTER_DEFAULTS = {"U": "Generic/Bessell.U", "B": "Generic/Bessell.B", @@ -95,13 +98,13 @@ def download_svo_filter(filter_name, return_style="synphot"): silent=True, ) if not path: - logging.debug("File not found in %s, downloading...", PATH_SVO_DATA) + logger.debug("File not found in %s, downloading...", PATH_SVO_DATA) path = download_file(url, cache=True) try: tbl = Table.read(path, format='votable') except ValueError: - logging.error("Unable to load %s from %s.", filter_name, path) + logger.error("Unable to load %s from %s.", filter_name, path) raise wave = u.Quantity(tbl['Wavelength'].data.data, u.Angstrom, copy=False) diff --git a/scopesim/optics/fov.py b/scopesim/optics/fov.py index c11500ea..7ce24a6f 100644 --- a/scopesim/optics/fov.py +++ b/scopesim/optics/fov.py @@ -1,6 +1,5 @@ """Defines FieldOfView class.""" -import logging from copy import deepcopy from itertools import chain from collections.abc import Iterable @@ -18,7 +17,10 @@ from . import image_plane_utils as imp_utils from ..base_classes import SourceBase, FieldOfViewBase -from .. import utils +from ..utils import from_currsys, quantify, has_needed_keywords, get_logger + + +logger = get_logger(__name__) class FieldOfView(FieldOfViewBase): @@ -44,8 +46,8 @@ class FieldOfView(FieldOfViewBase): def __init__(self, header, waverange, detector_header=None, **kwargs): self.meta = { "id": None, - "wave_min": utils.quantify(waverange[0], u.um), - "wave_max": utils.quantify(waverange[1], u.um), + "wave_min": quantify(waverange[0], u.um), + "wave_max": quantify(waverange[1], u.um), "wave_bin_n": 1, "wave_bin_type": "linear", @@ -63,10 +65,10 @@ def __init__(self, header, waverange, detector_header=None, **kwargs): } self.meta.update(kwargs) - if not any((utils.has_needed_keywords(header, s) for s in ["", "S"])): + if not any((has_needed_keywords(header, s) for s in ["", "S"])): raise ValueError( f"Header must contain a valid sky-plane WCS: {dict(header)}") - if not utils.has_needed_keywords(header, "D"): + if not has_needed_keywords(header, "D"): raise ValueError( f"Header must contain a valid image-plane WCS: {dict(header)}") @@ -120,7 +122,7 @@ def extract_from(self, src): fields_in_fov = [field for field in src.fields if fu.is_field_in_fov(self.header, field)] if not fields_in_fov: - logging.warning("No fields in FOV.") + logger.warning("No fields in FOV.") spec_refs = set() volume = self.volume() @@ -319,7 +321,7 @@ def _make_image_tablefields(self, fluxes): xpix, ypix = imp_utils.val2pix(self.header, field["x"] / 3600, field["y"] / 3600) - if utils.from_currsys(self.meta["sub_pixel"]): + if from_currsys(self.meta["sub_pixel"]): for idx, row in enumerate(field): xs, ys, fracs = imp_utils.sub_pixel_fractions(xpix[idx], ypix[idx]) @@ -363,13 +365,13 @@ def make_image_hdu(self, use_photlam=False): [ph s-1 pixel-1] or PHOTLAM (if use_photlam=True) """ - spline_order = utils.from_currsys("!SIM.computing.spline_order") + spline_order = from_currsys("!SIM.computing.spline_order") # Make waveset and canvas image fov_waveset = self.waveset bin_widths = np.diff(fov_waveset) # u.um bin_widths = 0.5 * (np.r_[0, bin_widths] + np.r_[bin_widths, 0]) - area = utils.from_currsys(self.meta["area"]) # u.m2 + area = from_currsys(self.meta["area"]) # u.m2 # PHOTLAM * u.um * u.m2 --> ph / s specs = {ref: spec(fov_waveset) if use_photlam @@ -389,7 +391,7 @@ def make_image_hdu(self, use_photlam=False): spline_order=spline_order) for flux, weight, x, y in self._make_image_tablefields(fluxes): - if utils.from_currsys(self.meta["sub_pixel"]): + if from_currsys(self.meta["sub_pixel"]): # These x and y should not be arrays when sub_pixel is # enabled, it is therefore not necessary to deploy the fix # below in the else-branch. @@ -489,7 +491,7 @@ def _make_cube_tablefields(self, specs): xpix, ypix = imp_utils.val2pix(self.header, xsky, ysky) flux_vector = specs[row["ref"]].value * row["weight"] / self.pixel_area - if utils.from_currsys(self.meta["sub_pixel"]): + if from_currsys(self.meta["sub_pixel"]): xs, ys, fracs = imp_utils.sub_pixel_fractions(xpix, ypix) for i, j, k in zip(xs, ys, fracs): yield flux_vector * k, i, j @@ -501,7 +503,7 @@ def _make_cube_backfields(self, specs): # TODO: The following would have been identical to the other two # make methods, but was commented out. Why? # bg_solid_angle = u.Unit(field.header["SOLIDANG"]).to(u.arcsec**-2) # float [arcsec-2] - # pixel_area = utils.from_currsys(self.meta["pixel_scale"]) ** 2 # float [arcsec2] + # pixel_area = from_currsys(self.meta["pixel_scale"]) ** 2 # float [arcsec2] # area_factor = pixel_area * bg_solid_angle # float [arcsec2 * arcsec-2] # Cube should be in PHOTLAM arcsec-2 for SpectralTrace mapping @@ -555,14 +557,14 @@ def make_cube_hdu(self): [ph s-1 AA-1 arcsec-2] # as needed by SpectralTrace """ - spline_order = utils.from_currsys("!SIM.computing.spline_order") + spline_order = from_currsys("!SIM.computing.spline_order") # 1. Make waveset and canvas cube (area, bin_width are applied at end) # TODO: Why is this not self.waveset? What's different? - wave_unit = u.Unit(utils.from_currsys("!SIM.spectral.wave_unit")) + wave_unit = u.Unit(from_currsys("!SIM.spectral.wave_unit")) fov_waveset = np.arange( self.meta["wave_min"].value, self.meta["wave_max"].value, - utils.from_currsys("!SIM.spectral.spectral_bin_width")) * wave_unit + from_currsys("!SIM.spectral.spectral_bin_width")) * wave_unit fov_waveset = fov_waveset.to(u.um) # TODO: what's with this code?? @@ -609,7 +611,7 @@ def make_cube_hdu(self): # PHOTLAM = ph/s/cm-2/AA # area = m2, fov_waveset = um # SpectralTrace wants ph/s/um/arcsec2 --> get rid of m2, leave um - area = utils.from_currsys(self.meta["area"]) # u.m2 + area = from_currsys(self.meta["area"]) # u.m2 canvas_cube_hdu.data *= area.to(u.cm ** 2).value canvas_cube_hdu.data *= 1e4 # ph/s/AA/arcsec2 --> ph/s/um/arcsec2 @@ -657,9 +659,9 @@ def data(self): def corners(self): """Return sky footprint, image plane footprint.""" # Couldn't find where this is ever used, put warning here just in case - logging.warning("calc_footprint has been updated, any code that " - "relies on this .corners property must likely be " - "adapted as well.") + logger.warning("calc_footprint has been updated, any code that " + "relies on this .corners property must likely be " + "adapted as well.") sky_corners = imp_utils.calc_footprint(self.header) imp_corners = imp_utils.calc_footprint(self.header, "D") return sky_corners, imp_corners @@ -668,8 +670,8 @@ def corners(self): def waverange(self): """Return wavelength range in um [wave_min, wave_max].""" if self._waverange is None: - wave_min = utils.quantify(self.meta["wave_min"], u.um).value - wave_max = utils.quantify(self.meta["wave_max"], u.um).value + wave_min = quantify(self.meta["wave_min"], u.um).value + wave_max = quantify(self.meta["wave_max"], u.um).value self._waverange = [wave_min, wave_max] return self._waverange @@ -678,7 +680,7 @@ def wavelength(self): """Return central wavelength in um.""" if self._wavelength is None: self._wavelength = np.average(self.waverange) - return utils.quantify(self._wavelength, u.um) + return quantify(self._wavelength, u.um) @property def waveset(self): diff --git a/scopesim/optics/fov_manager_utils.py b/scopesim/optics/fov_manager_utils.py index bf6afa98..95a40f8b 100644 --- a/scopesim/optics/fov_manager_utils.py +++ b/scopesim/optics/fov_manager_utils.py @@ -1,4 +1,3 @@ -import logging from copy import deepcopy from itertools import product from more_itertools import pairwise @@ -10,11 +9,14 @@ from .fov import FieldOfView from .. import effects as efs from ..effects.effects_utils import get_all_effects -from ..utils import check_keys +from ..utils import check_keys, get_logger # TODO: Where are all these functions used?? +logger = get_logger(__name__) + + def get_3d_shifts(effects, **kwargs): """ Returns the total 3D shifts (x,y,lam) from a series of Shift3D objects @@ -260,7 +262,7 @@ def get_imaging_fovs(headers, waveset, shifts, **kwargs): # Actually evaluating the generators here is only necessary for the log msg waveset = list(waveset) headers = list(headers) - logging.info("Preparing %d FieldOfViews", (len(waveset) - 1) * len(headers)) + logger.info("Preparing %d FieldOfViews", (len(waveset) - 1) * len(headers)) combos = product(pairwise(waveset), headers) for fov_id, ((wave_min, wave_max), hdr) in enumerate(combos): @@ -347,7 +349,7 @@ def get_spectroscopy_fovs(headers, shifts, effects=None, **kwargs): shift_dx = shifts["x_shifts"] # in [deg] shift_dy = shifts["y_shifts"] - logging.info("Preparing %d FieldOfViews", len(headers)) + logger.info("Preparing %d FieldOfViews", len(headers)) apertures = get_all_effects(effects, (efs.ApertureList, efs.ApertureMask)) masks = [ap.fov_grid(which="masks") for ap in apertures] diff --git a/scopesim/optics/fov_utils.py b/scopesim/optics/fov_utils.py index 478abf7f..57e0565b 100644 --- a/scopesim/optics/fov_utils.py +++ b/scopesim/optics/fov_utils.py @@ -1,4 +1,3 @@ -import logging import numpy as np from astropy import units as u @@ -7,8 +6,11 @@ from astropy.wcs import WCS from synphot import SourceSpectrum, Empirical1D -from .. import utils from . import image_plane_utils as imp_utils +from ..utils import from_currsys, quantify, quantity_from_table, get_logger + + +logger = get_logger(__name__) def is_field_in_fov(fov_header, field, wcs_suffix=""): @@ -34,18 +36,18 @@ def is_field_in_fov(fov_header, field, wcs_suffix=""): is_inside_fov = True else: if isinstance(field, Table): - x = list(utils.quantity_from_table("x", field, + x = list(quantity_from_table("x", field, u.arcsec).to(u.deg).value) - y = list(utils.quantity_from_table("y", field, + y = list(quantity_from_table("y", field, u.arcsec).to(u.deg).value) s = wcs_suffix - # cdelt = utils.quantify(fov_header["CDELT1" + s], u.deg).value + # cdelt = quantify(fov_header["CDELT1" + s], u.deg).value cdelt = fov_header[f"CDELT1{s}"] * u.Unit(fov_header[f"CUNIT1{s}"]).to(u.deg) field_header = imp_utils.header_from_list_of_xy(x, y, cdelt, s) elif isinstance(field, (fits.ImageHDU, fits.PrimaryHDU)): field_header = field.header else: - logging.warning("Input was neither Table nor ImageHDU: %s", field) + logger.warning("Input was neither Table nor ImageHDU: %s", field) return False xy = imp_utils.calc_footprint(field_header, wcs_suffix) @@ -105,8 +107,8 @@ def combine_table_fields(fov_header, src, field_indexes): for ii in field_indexes: field = src.fields[ii] if isinstance(field, Table): - xcol = utils.quantity_from_table("x", field, u.arcsec) - ycol = utils.quantity_from_table("y", field, u.arcsec) + xcol = quantity_from_table("x", field, u.arcsec) + ycol = quantity_from_table("y", field, u.arcsec) x += list(xcol.to(u.deg).value) y += list(ycol.to(u.deg).value) ref += list(field["ref"]) @@ -159,7 +161,7 @@ def combine_imagehdu_fields(fov_header, src, fields_indexes, wave_min, wave_max, """ image = np.zeros((fov_header["NAXIS2"], fov_header["NAXIS1"])) canvas_hdu = fits.ImageHDU(header=fov_header, data=image) - spline_order = utils.from_currsys("!SIM.computing.spline_order") + spline_order = from_currsys("!SIM.computing.spline_order") pixel_area = (fov_header["CDELT1"] * fov_header["CDELT2"] * u.Unit(fov_header["CUNIT1"].lower()).to(u.arcsec) ** 2) @@ -334,14 +336,14 @@ def extract_area_from_imagehdu(imagehdu, fov_volume): hdu_waves = get_cube_waveset(hdr) wdel = hdr["CDELT3"] wunit = u.Unit(hdr.get("CUNIT3", "AA")) - fov_waves = utils.quantify(fov_volume["waves"], u.um).to(wunit).value + fov_waves = quantify(fov_volume["waves"], u.um).to(wunit).value mask = ((hdu_waves > fov_waves[0] - 0.5 * wdel) * (hdu_waves <= fov_waves[1] + 0.5 * wdel)) # need to go [+/-] half a bin # OC [2021-12-14] if fov range is not covered by the source return nothing if not np.any(mask): - logging.warning("FOV %s um - %s um: not covered by Source", - fov_waves[0], fov_waves[1]) + logger.warning("FOV %s um - %s um: not covered by Source", + fov_waves[0], fov_waves[1]) # FIXME: returning None here breaks the principle that a function # should always return the same type. Maybe this should # instead raise an exception that's caught higher up... @@ -379,7 +381,7 @@ def extract_area_from_imagehdu(imagehdu, fov_volume): new_hdr["SPEC_REF"] = hdr.get("SPEC_REF") if not data.size: - logging.warning("Empty image HDU.") + logger.warning("Empty image HDU.") new_imagehdu = fits.ImageHDU(data=data) new_imagehdu.header.update(new_hdr) @@ -412,7 +414,7 @@ def extract_range_from_spectrum(spectrum, waverange): raise ValueError(f"spectrum must be of type synphot.SourceSpectrum: " f"{type(spectrum)}") - wave_min, wave_max = utils.quantify(waverange, u.um).to(u.AA).value + wave_min, wave_max = quantify(waverange, u.um).to(u.AA).value spec_waveset = spectrum.waveset.to(u.AA).value mask = (spec_waveset > wave_min) * (spec_waveset < wave_max) @@ -421,8 +423,8 @@ def extract_range_from_spectrum(spectrum, waverange): # "%s <> %s for spectrum %s"), # [wave_min, wave_max], spec_waveset, spectrum) if wave_min < min(spec_waveset) or wave_max > max(spec_waveset): - logging.info(("Waverange only partially overlaps with Spectrum waveset: " - "%s <> %s for spectrum %s"), + logger.info(("Waverange only partially overlaps with Spectrum waveset: " + "%s <> %s for spectrum %s"), [wave_min, wave_max], spec_waveset, spectrum) wave = np.r_[wave_min, spec_waveset[mask], wave_max] diff --git a/scopesim/optics/image_plane.py b/scopesim/optics/image_plane.py index 003a6272..96a92464 100644 --- a/scopesim/optics/image_plane.py +++ b/scopesim/optics/image_plane.py @@ -1,5 +1,4 @@ import numpy as np -import logging from astropy.io import fits from astropy.table import Table @@ -8,8 +7,10 @@ from .image_plane_utils import add_table_to_imagehdu, add_imagehdu_to_imagehdu from ..base_classes import ImagePlaneBase +from ..utils import from_currsys, has_needed_keywords, get_logger from .. import rc -from .. import utils + +logger = get_logger(__name__) class ImagePlane(ImagePlaneBase): @@ -51,7 +52,7 @@ def __init__(self, header, **kwargs): self.meta.update(kwargs) self.id = header["IMGPLANE"] if "IMGPLANE" in header else 0 - if not any(utils.has_needed_keywords(header, s) + if not any(has_needed_keywords(header, s) for s in ["", "D", "S"]): raise ValueError(f"header must have a valid image-plane WCS: " f"{dict(header)}") @@ -61,9 +62,9 @@ def __init__(self, header, **kwargs): self.hdu = fits.ImageHDU(data=image, header=header) self._det_wcs = self._get_wcs(header, "D") - logging.debug("det %s", self._det_wcs) + logger.debug("det %s", self._det_wcs) self._sky_wcs = self._get_wcs(header, " ") - logging.debug("sky %s", self._sky_wcs) + logger.debug("sky %s", self._sky_wcs) def add(self, hdus_or_tables, sub_pixel=None, spline_order=None, wcs_suffix=""): @@ -108,9 +109,9 @@ def add(self, hdus_or_tables, sub_pixel=None, spline_order=None, """ if sub_pixel is None: - sub_pixel = utils.from_currsys("!SIM.sub_pixel.flag") + sub_pixel = from_currsys("!SIM.sub_pixel.flag") if spline_order is None: - spline_order = utils.from_currsys("!SIM.computing.spline_order") + spline_order = from_currsys("!SIM.computing.spline_order") if isinstance(hdus_or_tables, (list, tuple)): for hdu_or_table in hdus_or_tables: diff --git a/scopesim/optics/image_plane_utils.py b/scopesim/optics/image_plane_utils.py index bf96a4f6..d75156e9 100644 --- a/scopesim/optics/image_plane_utils.py +++ b/scopesim/optics/image_plane_utils.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -import logging + from typing import Tuple from itertools import product from collections.abc import Iterable @@ -12,7 +12,11 @@ from astropy.utils.exceptions import AstropyWarning from scipy import ndimage as ndi -from .. import utils +from ..utils import (unit_from_table, quantity_from_table, has_needed_keywords, + get_logger) + + +logger = get_logger(__name__) def get_canvas_header(hdu_or_table_list, pixel_scale=1 * u.arcsec): @@ -57,7 +61,7 @@ def _get_headers(hdus_or_tables): headers = list(_get_headers(hdu_or_table_list)) if not headers: - logging.warning("No tables or ImageHDUs were passed") + logger.warning("No tables or ImageHDUs were passed") return None hdr = _make_bounding_header_from_headers(*headers, pixel_scale=pixel_scale) @@ -67,8 +71,8 @@ def _get_headers(hdus_or_tables): raise MemoryError(size_warning.format(adverb="too", num_pix=num_pix, size="8 GB")) if num_pix > 2 ** 25: # 2 * 4096**2 - logging.warning(size_warning.format(adverb="", num_pix=num_pix, - size="256 MB")) + logger.warning(size_warning.format(adverb="", num_pix=num_pix, + size="256 MB")) return hdr @@ -288,22 +292,18 @@ def add_table_to_imagehdu(table: Table, canvas_hdu: fits.ImageHDU, """ s = wcs_suffix - if not utils.has_needed_keywords(canvas_hdu.header, s): + if not has_needed_keywords(canvas_hdu.header, s): raise ValueError(f"canvas_hdu must include an appropriate WCS: {s}") - f = utils.quantity_from_table("flux", table, default_unit=u.Unit("ph s-1")) + f = quantity_from_table("flux", table, default_unit=u.Unit("ph s-1")) if s == "D": - x = utils.quantity_from_table("x_mm", table, - default_unit=u.mm).to(u.mm) - y = utils.quantity_from_table("y_mm", table, - default_unit=u.mm).to(u.mm) + x = quantity_from_table("x_mm", table, default_unit=u.mm).to(u.mm) + y = quantity_from_table("y_mm", table, default_unit=u.mm).to(u.mm) else: arcsec = u.arcsec canvas_unit = u.Unit(canvas_hdu.header[f"CUNIT1{s}"]) - x = utils.quantity_from_table("x", table, - default_unit=arcsec.to(canvas_unit)) - y = utils.quantity_from_table("y", table, - default_unit=arcsec.to(canvas_unit)) + x = quantity_from_table("x", table, default_unit=arcsec.to(canvas_unit)) + y = quantity_from_table("y", table, default_unit=arcsec.to(canvas_unit)) x *= arcsec.to(canvas_unit) y *= arcsec.to(canvas_unit) @@ -491,12 +491,12 @@ def rescale_imagehdu(imagehdu: fits.ImageHDU, pixel_scale: float, # zoom = np.append(zoom, [1]) zoom[2] = 1. if primary_wcs.naxis != imagehdu.data.ndim: - logging.warning("imagehdu.data.ndim is %d, but primary_wcs.naxis with " + logger.warning("imagehdu.data.ndim is %d, but primary_wcs.naxis with " "key %s is %d, both should be equal.", imagehdu.data.ndim, wcs_suffix, primary_wcs.naxis) zoom = zoom[:2] - logging.debug("zoom %s", zoom) + logger.debug("zoom %s", zoom) if all(zoom == 1.): # Nothing to do @@ -519,18 +519,18 @@ def rescale_imagehdu(imagehdu: fits.ImageHDU, pixel_scale: float, ww = WCS(imagehdu.header, key=key) if ww.naxis != imagehdu.data.ndim: - logging.warning("imagehdu.data.ndim is %d, but wcs.naxis with key " - "%s is %d, both should be equal.", - imagehdu.data.ndim, key, ww.naxis) + logger.warning("imagehdu.data.ndim is %d, but wcs.naxis with key " + "%s is %d, both should be equal.", + imagehdu.data.ndim, key, ww.naxis) # TODO: could this be ww = ww.sub(2) instead? or .celestial? ww = WCS(imagehdu.header, key=key, naxis=imagehdu.data.ndim) if any(ctype != "LINEAR" for ctype in ww.wcs.ctype): - logging.warning("Non-linear WCS rescaled using linear procedure.") + logger.warning("Non-linear WCS rescaled using linear procedure.") new_crpix = (zoom + 1) / 2 + (ww.wcs.crpix - 1) * zoom new_crpix = np.round(new_crpix * 2) / 2 # round to nearest half-pixel - logging.debug("new crpix %s", new_crpix) + logger.debug("new crpix %s", new_crpix) ww.wcs.crpix = new_crpix # Keep CDELT3 if cube... @@ -604,9 +604,9 @@ def reorient_imagehdu(imagehdu: fits.ImageHDU, wcs_suffix: str = "", imagehdu.header = hdr elif any("PC1_1" in key for key in imagehdu.header): - logging.warning(("PC Keywords were found, but not used due to " - "different wcs_suffix given: %s \n %s"), - wcs_suffix, dict(imagehdu.header)) + logger.warning(("PC Keywords were found, but not used due to " + "different wcs_suffix given: %s \n %s"), + wcs_suffix, dict(imagehdu.header)) return imagehdu @@ -758,10 +758,10 @@ def add_imagehdu_to_imagehdu(image_hdu: fits.ImageHDU, sky_center = _fix_360(sky_center) # logging.debug("canvas %s", canvas_wcs) # logging.debug("new %s", new_wcs) - logging.debug("sky %s", sky_center) + logger.debug("sky %s", sky_center) sky_center *= conv_fac pix_center = canvas_wcs.wcs_world2pix(sky_center, 0) - logging.debug("pix %s", pix_center) + logger.debug("pix %s", pix_center) canvas_hdu.data = overlay_image(new_hdu.data, canvas_hdu.data, coords=pix_center.squeeze()) @@ -794,7 +794,7 @@ def pix2val(header, x, y, wcs_suffix=""): pc11, pc12, pc21, pc22 = 1, 0, 0, 1 if (pc11 * pc22 - pc12 * pc21) != 1.0: - logging.error("PC matrix det != 1.0") + logger.error("PC matrix det != 1.0") da = header["CDELT1"+s] db = header["CDELT2"+s] @@ -837,7 +837,7 @@ def val2pix(header, a, b, wcs_suffix=""): pc11, pc12, pc21, pc22 = 1, 0, 0, 1 if (pc11 * pc22 - pc12 * pc21) != 1.0: - logging.error("PC matrix det != 1.0") + logger.error("PC matrix det != 1.0") da = float(header["CDELT1"+s]) db = float(header["CDELT2"+s]) @@ -883,8 +883,8 @@ def calc_footprint(header, wcs_suffix="", new_unit: str = None): wcs_suffix = wcs_suffix or " " if isinstance(header, fits.ImageHDU): - logging.warning("Passing a HDU to calc_footprint will be deprecated " - "in v1.0. Please pass the header only.") + logger.warning("Passing a HDU to calc_footprint will be deprecated " + "in v1.0. Please pass the header only.") header = header.header # TODO: maybe celestial instead?? @@ -953,8 +953,8 @@ def calc_table_footprint(table: Table, x_name: str, y_name: str, else: padding = 0. - x_convf = utils.unit_from_table(x_name, table, tbl_unit).to(new_unit) - y_convf = utils.unit_from_table(y_name, table, tbl_unit).to(new_unit) + x_convf = unit_from_table(x_name, table, tbl_unit).to(new_unit) + y_convf = unit_from_table(y_name, table, tbl_unit).to(new_unit) x_col = table[x_name] * x_convf y_col = table[y_name] * y_convf @@ -1062,17 +1062,17 @@ def det_wcs_from_sky_wcs(sky_wcs: WCS, # Once Scopesim is consistent there, remove astropy units. pixel_scale <<= u.arcsec / u.pixel plate_scale <<= u.arcsec / u.mm - logging.debug("Pixel scale: %s", pixel_scale) - logging.debug("Plate scale: %s", plate_scale) + logger.debug("Pixel scale: %s", pixel_scale) + logger.debug("Plate scale: %s", plate_scale) pixel_size = pixel_scale / plate_scale # TODO: add check if cunit is consistent along all axes cunit = sky_wcs.wcs.cunit[0] corners = sky_wcs.calc_footprint(center=False, axes=naxis) * cunit - logging.debug("WCS sky corners: %s", corners) + logger.debug("WCS sky corners: %s", corners) corners /= plate_scale corners = corners.to(u.mm) - logging.debug("WCS det corners: %s", corners) + logger.debug("WCS det corners: %s", corners) return create_wcs_from_points(corners, pixel_size, "D") @@ -1109,15 +1109,15 @@ def sky_wcs_from_det_wcs(det_wcs: WCS, # Once Scopesim is consistent there, remove astropy units. pixel_scale <<= u.arcsec / u.pixel plate_scale <<= u.arcsec / u.mm - logging.debug("Pixel scale: %s", pixel_scale) - logging.debug("Plate scale: %s", plate_scale) + logger.debug("Pixel scale: %s", pixel_scale) + logger.debug("Plate scale: %s", plate_scale) # TODO: add check if cunit is consistent along all axes cunit = det_wcs.wcs.cunit[0] corners = det_wcs.calc_footprint(center=False, axes=naxis) * cunit - logging.debug("WCS det corners: %s", corners) + logger.debug("WCS det corners: %s", corners) corners *= plate_scale corners = corners.to(u.arcsec) - logging.debug("WCS sky corners: %s", corners) + logger.debug("WCS sky corners: %s", corners) return create_wcs_from_points(corners, pixel_scale) diff --git a/scopesim/optics/optical_element.py b/scopesim/optics/optical_element.py index f234a901..63fb2df1 100644 --- a/scopesim/optics/optical_element.py +++ b/scopesim/optics/optical_element.py @@ -1,4 +1,3 @@ -import logging from inspect import isclass from typing import TextIO from io import StringIO @@ -8,11 +7,14 @@ from .. import effects as efs from ..effects.effects_utils import (make_effect, get_all_effects, z_order_in_range) -from ..utils import write_report +from ..utils import write_report, get_logger from ..reports.rst_utils import table_to_rst from .. import rc +logger = get_logger(__name__) + + class OpticalElement: """ Contains all information to describe a section of an optical system. @@ -83,8 +85,8 @@ def add_effect(self, effect): if isinstance(effect, efs.Effect): self.effects.append(effect) else: - logging.warning("%s is not an Effect object and was not added", - effect) + logger.warning("%s is not an Effect object and was not added", + effect) def get_all(self, effect_class): return get_all_effects(self.effects, effect_class) diff --git a/scopesim/optics/optics_manager.py b/scopesim/optics/optics_manager.py index cc5242a6..3b995cc9 100644 --- a/scopesim/optics/optics_manager.py +++ b/scopesim/optics/optics_manager.py @@ -1,4 +1,4 @@ -import logging + from inspect import isclass from typing import TextIO from io import StringIO @@ -13,11 +13,14 @@ from .. import effects as efs from ..effects.effects_utils import is_spectroscope from ..effects.effects_utils import combine_surface_effects -from ..utils import write_report, from_currsys +from ..utils import write_report, from_currsys, get_logger from ..reports.rst_utils import table_to_rst from .. import rc +logger = get_logger(__name__) + + class OpticsManager: """ The workhorse class for dealing with all externally defined Effect objects. @@ -356,7 +359,7 @@ def __getitem__(self, item): def __setitem__(self, key, value): obj = self.__getitem__(key) if isinstance(obj, list) and len(obj) > 1: - logging.warning("%s does not return a singular object:\n %s", key, obj) + logger.warning("%s does not return a singular object:\n %s", key, obj) elif isinstance(obj, efs.Effect) and isinstance(value, dict): obj.meta.update(value) diff --git a/scopesim/optics/radiometry_utils.py b/scopesim/optics/radiometry_utils.py index 6a6b4b8b..fee51987 100644 --- a/scopesim/optics/radiometry_utils.py +++ b/scopesim/optics/radiometry_utils.py @@ -1,14 +1,17 @@ from collections import OrderedDict from copy import deepcopy -import logging from astropy import units as u from astropy.io import ascii as ioascii from astropy.table import Table, vstack from .surface import SpectralSurface -from ..utils import real_colname, insert_into_ordereddict, \ - change_table_entry, convert_table_comments_to_dict, from_currsys +from ..utils import (real_colname, insert_into_ordereddict, + change_table_entry, convert_table_comments_to_dict, + from_currsys, get_logger) + + +logger = get_logger(__name__) def combine_emissions(tbl, surfaces, row_indexes, etendue, use_area=False): @@ -135,8 +138,8 @@ def add_surface_to_table(tbl, surf, name, position, silent=True): position=position) else: if not silent: - logging.warning(("%s was not found in the meta dictionary of %s. " - "This could cause problems"), colname, name) + logger.warning(("%s was not found in the meta dictionary of %s. " + "This could cause problems"), colname, name) colname = real_colname("name", new_tbl.colnames) new_tbl = change_table_entry(new_tbl, colname, name, position=position) diff --git a/scopesim/optics/surface.py b/scopesim/optics/surface.py index 2997e071..a14fb46c 100644 --- a/scopesim/optics/surface.py +++ b/scopesim/optics/surface.py @@ -1,4 +1,3 @@ -import logging from pathlib import Path from dataclasses import dataclass from typing import Any @@ -13,10 +12,14 @@ from synphot.models import Empirical1D from ..effects import ter_curves_utils as ter_utils -from ..utils import get_meta_quantity, quantify, extract_type_from_unit -from ..utils import from_currsys, convert_table_comments_to_dict, find_file from .surface_utils import make_emission_from_emissivity,\ make_emission_from_array +from ..utils import (get_meta_quantity, quantify, extract_type_from_unit, + from_currsys, convert_table_comments_to_dict, find_file, + get_logger) + + +logger = get_logger(__name__) @dataclass @@ -196,7 +199,7 @@ def _get_ter_property(self, ter_property, fmt="synphot"): response_curve = value_arr else: response_curve = None - logging.warning("Both wavelength and %s must be set", ter_property) + logger.warning("Both wavelength and %s must be set", ter_property) return response_curve @@ -254,8 +257,8 @@ def _get_array(self, colname): elif colname in self.table.colnames: val = self.table[colname].data else: - logging.debug("%s not found in either '.meta' or '.table': [%s]", - colname, self.meta.get("name", self.meta["filename"])) + logger.debug("%s not found in either '.meta' or '.table': [%s]", + colname, self.meta.get("name", self.meta["filename"])) return None col_units = colname+"_unit" diff --git a/scopesim/optics/surface_utils.py b/scopesim/optics/surface_utils.py index d70cbb7b..a84352c1 100644 --- a/scopesim/optics/surface_utils.py +++ b/scopesim/optics/surface_utils.py @@ -1,10 +1,13 @@ -import logging import numpy as np from astropy import units as u from synphot import SourceSpectrum, BlackBody1D, Empirical1D -from ..utils import quantify, extract_type_from_unit, extract_base_from_unit +from ..utils import (quantify, extract_type_from_unit, extract_base_from_unit, + get_logger) + + +logger = get_logger(__name__) def make_emission_from_emissivity(temp, emiss_src_spec): @@ -27,7 +30,7 @@ def make_emission_from_emissivity(temp, emiss_src_spec): temp = temp.to(u.Kelvin, equivalencies=u.temperature()).value if emiss_src_spec is None: - logging.warning("Either emission or emissivity must be set") + logger.warning("Either emission or emissivity must be set") flux = None else: flux = SourceSpectrum(BlackBody1D, temperature=temp) @@ -63,8 +66,8 @@ def make_emission_from_array(flux, wave, meta): if "emission_unit" in meta: flux = quantify(flux, meta["emission_unit"]) else: - logging.warning("emission_unit must be set in self.meta, " - "or emission must be an astropy.Quantity") + logger.warning("emission_unit must be set in self.meta, " + "or emission must be an astropy.Quantity") flux = None if isinstance(wave, u.Quantity) and isinstance(flux, u.Quantity): @@ -81,8 +84,8 @@ def make_emission_from_array(flux, wave, meta): flux.meta["history"] = [("Created from emission array with units " f"{orig_unit}")] else: - logging.warning("wavelength and emission must be " - "astropy.Quantity py_objects") + logger.warning("wavelength and emission must be " + "astropy.Quantity py_objects") flux = None return flux diff --git a/scopesim/server/database.py b/scopesim/server/database.py index 6c8e346f..5ce0cd18 100644 --- a/scopesim/server/database.py +++ b/scopesim/server/database.py @@ -1,7 +1,6 @@ # -*- coding: utf-8 -*- """Functions to download instrument packages and example data.""" -import logging from datetime import date from warnings import warn from pathlib import Path @@ -18,6 +17,10 @@ get_server_elements) from .download_utils import (get_server_folder_contents, handle_download, handle_unzipping, create_client, ServerError) +from ..utils import get_logger + + +logger = get_logger(__name__) _GrpVerType = Mapping[str, Iterable[str]] _GrpItrType = Iterator[Tuple[str, List[str]]] @@ -154,13 +157,13 @@ def crawl_server_dirs(client=None) -> Iterator[Tuple[str, Set[str]]]: return for dir_name in get_server_folder_contents(client, "", "/"): - logging.info("Searching folder '%s'", dir_name) + logger.info("Searching folder '%s'", dir_name) try: p_dir = get_server_folder_package_names(client, dir_name) except ValueError as err: - logging.info(err) + logger.info(err) continue - logging.info("Found packages %s.", p_dir) + logger.info("Found packages %s.", p_dir) yield dir_name, p_dir @@ -394,7 +397,7 @@ def download_packages(pkg_names: Union[Iterable[str], str], """ base_url = get_base_url() print("Gathering information from server ...") - logging.info("Accessing %s", base_url) + logger.info("Accessing %s", base_url) with create_client(base_url) as client: all_versions = get_all_package_versions(client) @@ -413,9 +416,9 @@ def download_packages(pkg_names: Union[Iterable[str], str], client, pkg_name, release, all_versions, folders_dict, save_dir, padlen) except PkgNotFoundError as error: - logging.error("\n") # needed until tqdm redirect implemented - logging.error(error) - logging.error("Skipping download of package '%s'", pkg_name) + logger.error("\n") # needed until tqdm redirect implemented + logger.error(error) + logger.error("Skipping download of package '%s'", pkg_name) continue save_paths.append(pkg_path) diff --git a/scopesim/server/download_utils.py b/scopesim/server/download_utils.py index 15b47aab..7c0ad806 100644 --- a/scopesim/server/download_utils.py +++ b/scopesim/server/download_utils.py @@ -2,7 +2,6 @@ """Used only by the `database` and `github_utils` submodules.""" import re -import logging # Python 3.8 doesn't yet know these things....... # from collections.abc import Iterator, Iterable, Mapping @@ -19,6 +18,11 @@ # from tqdm.contrib.logging import logging_redirect_tqdm # put with logging_redirect_tqdm(loggers=all_loggers): around tqdm +from ..utils import get_logger + + +logger = get_logger(__name__) + class ServerError(Exception): """Some error with the server or connection to the server.""" @@ -67,11 +71,11 @@ def handle_download(client, pkg_url: str, file_inner.write(chunk) except httpx.HTTPStatusError as err: - logging.error("Error response %s while requesting %s.", - err.response.status_code, err.request.url) + logger.error("Error response %s while requesting %s.", + err.response.status_code, err.request.url) raise ServerError("Cannot connect to server.") from err except Exception as err: - logging.exception("Unhandled exception while accessing server.") + logger.exception("Unhandled exception while accessing server.") raise ServerError("Cannot connect to server.") from err @@ -97,15 +101,15 @@ def send_get(client, sub_url, stream: bool = False): response = client.get(sub_url) response.raise_for_status() except httpx.RequestError as err: - logging.exception("An error occurred while requesting %s.", - err.request.url) + logger.exception("An error occurred while requesting %s.", + err.request.url) raise ServerError("Cannot connect to server.") from err except httpx.HTTPStatusError as err: - logging.error("Error response %s while requesting %s.", - err.response.status_code, err.request.url) + logger.error("Error response %s while requesting %s.", + err.response.status_code, err.request.url) raise ServerError("Cannot connect to server.") from err except Exception as err: - logging.exception("Unhandled exception while accessing server.") + logger.exception("Unhandled exception while accessing server.") raise ServerError("Cannot connect to server.") from err return response diff --git a/scopesim/server/github_utils.py b/scopesim/server/github_utils.py index 2ded8ad8..5be570de 100644 --- a/scopesim/server/github_utils.py +++ b/scopesim/server/github_utils.py @@ -10,12 +10,15 @@ """ -import logging import re from pathlib import Path from typing import Union from .download_utils import handle_download, send_get, create_client +from ..utils import get_logger + + +logger = get_logger(__name__) def create_github_url(url: str) -> None: @@ -32,7 +35,7 @@ def create_github_url(url: str) -> None: if re.match(repo_only_url, url): message = ("✘ The given url is a complete repository. Use 'git clone'" " to download the repository") - logging.error(message) + logger.error(message) raise ValueError(message) # extract the branch name from the given url (e.g master) @@ -75,4 +78,4 @@ def download_github_folder(repo_url: str, save_path = output_dir / entry["path"] handle_download(client, entry["download_url"], save_path, entry["path"], padlen=0, disable_bar=True) - logging.info("Downloaded: %s", entry["path"]) + logger.info("Downloaded: %s", entry["path"]) diff --git a/scopesim/source/source.py b/scopesim/source/source.py index 1becbef1..e359ec5c 100644 --- a/scopesim/source/source.py +++ b/scopesim/source/source.py @@ -33,7 +33,6 @@ """ import pickle -import logging from copy import deepcopy from pathlib import Path import numpy as np @@ -44,8 +43,7 @@ from astropy import units as u from astropy.wcs import WCS -from synphot import SpectralElement, SourceSpectrum, Empirical1D -from synphot.units import PHOTLAM +from synphot import SpectralElement from ..optics.image_plane import ImagePlane from ..optics import image_plane_utils as imp_utils @@ -54,9 +52,12 @@ from . import source_templates as src_tmp from ..base_classes import SourceBase -from .. import utils -from ..utils import close_loop, figure_factory -# TODO: explicit util imports above... +from ..utils import (find_file, is_fits, get_fits_type, quantify, + quantity_from_table, convert_table_comments_to_dict, + close_loop, figure_factory, get_logger) + + +logger = get_logger(__name__) class Source(SourceBase): @@ -185,7 +186,7 @@ def __init__(self, filename=None, cube=None, ext=0, else: msg = ("image_hdu must be accompanied by either spectra or flux:\n" f"spectra: {spectra}, flux: {flux}") - logging.exception(msg) + logger.exception(msg) raise ValueError(msg) elif x is not None and y is not None and \ @@ -193,10 +194,10 @@ def __init__(self, filename=None, cube=None, ext=0, self._from_arrays(x, y, ref, weight, spectra) def _from_file(self, filename, spectra, flux): - filename = utils.find_file(filename) + filename = find_file(filename) - if utils.is_fits(filename): - fits_type = utils.get_fits_type(filename) + if is_fits(filename): + fits_type = get_fits_type(filename) data = fits.getdata(filename) hdr = fits.getheader(filename) hdr["FILENAME"] = Path(filename).name @@ -212,11 +213,11 @@ def _from_file(self, filename, spectra, flux): hdr1 = fits.getheader(filename, 1) hdr.update(hdr1) tbl = Table(data, meta=dict(hdr)) - tbl.meta.update(utils.convert_table_comments_to_dict(tbl)) + tbl.meta.update(convert_table_comments_to_dict(tbl)) self._from_table(tbl, spectra) else: tbl = ioascii.read(filename) - tbl.meta.update(utils.convert_table_comments_to_dict(tbl)) + tbl.meta.update(convert_table_comments_to_dict(tbl)) self._from_table(tbl, spectra) def _from_table(self, tbl, spectra): @@ -257,8 +258,8 @@ def _from_imagehdu_and_spectra(self, image_hdu, spectra): self.spectra += spectra else: image_hdu.header["SPEC_REF"] = "" - logging.warning("No spectrum was provided. SPEC_REF set to ''. " - "This could cause problems later") + logger.warning("No spectrum was provided. SPEC_REF set to ''. " + "This could cause problems later") raise NotImplementedError for i in [1, 2]: @@ -300,8 +301,8 @@ def _from_arrays(self, x, y, ref, weight, spectra): if weight is None: weight = np.ones(len(x)) - x = utils.quantify(x, u.arcsec) - y = utils.quantify(y, u.arcsec) + x = quantify(x, u.arcsec) + y = quantify(y, u.arcsec) tbl = Table(names=["x", "y", "ref", "weight"], data=[x, y, np.array(ref) + len(self.spectra), weight]) tbl.meta["x_unit"] = "arcsec" @@ -340,8 +341,8 @@ def _from_cube(self, cube, ext=0): u.Unit(bunit) except KeyError: bunit = "erg / (s cm2 arcsec2)" - logging.warning("Keyword \"BUNIT\" not found, setting to %s by default", - bunit) + logger.warning("Keyword \"BUNIT\" not found, setting to %s by default", + bunit) except ValueError as errcode: print("\"BUNIT\" keyword is malformed:", errcode) raise @@ -400,8 +401,8 @@ def image_in_range(self, wave_min, wave_max, pixel_scale=1*u.arcsec, if isinstance(field, Table): fluxes = self.photons_in_range(wave_min, wave_max, area, field["ref"]) * field["weight"] - x = utils.quantity_from_table("x", field, u.arcsec) - y = utils.quantity_from_table("y", field, u.arcsec) + x = quantity_from_table("x", field, u.arcsec) + y = quantity_from_table("y", field, u.arcsec) tbl = Table(names=["x", "y", "flux"], data=[x, y, fluxes]) tbl.meta.update(field.meta) hdu_or_table = tbl @@ -507,16 +508,16 @@ def shift(self, dx=0, dy=0, layers=None): for ii in layers: if isinstance(self.fields[ii], Table): - x = utils.quantity_from_table("x", self.fields[ii], u.arcsec) - x += utils.quantify(dx, u.arcsec) + x = quantity_from_table("x", self.fields[ii], u.arcsec) + x += quantify(dx, u.arcsec) self.fields[ii]["x"] = x - y = utils.quantity_from_table("y", self.fields[ii], u.arcsec) - y += utils.quantify(dy, u.arcsec) + y = quantity_from_table("y", self.fields[ii], u.arcsec) + y += quantify(dy, u.arcsec) self.fields[ii]["y"] = y elif isinstance(self.fields[ii], (fits.ImageHDU, fits.PrimaryHDU)): - dx = utils.quantify(dx, u.arcsec).to(u.deg) - dy = utils.quantify(dy, u.arcsec).to(u.deg) + dx = quantify(dx, u.arcsec).to(u.deg) + dy = quantify(dy, u.arcsec).to(u.deg) self.fields[ii].header["CRVAL1"] += dx.value self.fields[ii].header["CRVAL2"] += dy.value diff --git a/scopesim/source/source_utils.py b/scopesim/source/source_utils.py index c9c09bdd..c28159ff 100644 --- a/scopesim/source/source_utils.py +++ b/scopesim/source/source_utils.py @@ -1,4 +1,3 @@ -import logging from collections.abc import Iterable import numpy as np @@ -7,14 +6,17 @@ from astropy.table import Table from synphot import SourceSpectrum, Empirical1D, SpectralElement -from .. import utils +from ..utils import find_file, quantify, get_logger + + +logger = get_logger(__name__) def validate_source_input(**kwargs): if "filename" in kwargs and kwargs["filename"] is not None: filename = kwargs["filename"] - if utils.find_file(filename) is None: - logging.warning("filename was not found: %s", filename) + if find_file(filename) is None: + logger.warning("filename was not found: %s", filename) if "image" in kwargs and kwargs["image"] is not None: image_hdu = kwargs["image"] @@ -23,7 +25,7 @@ def validate_source_input(**kwargs): f"{type(image_hdu) = }") if len(wcs.find_all_wcs(image_hdu.header)) == 0: - logging.warning("image does not contain valid WCS. %s", + logger.warning("image does not contain valid WCS. %s", wcs.WCS(image_hdu)) if "table" in kwargs and kwargs["table"] is not None: @@ -119,7 +121,7 @@ def photons_in_range(spectra, wave_min, wave_max, area=None, bandpass=None): counts = 1E4 * np.array(counts) # to get from cm-2 to m-2 counts *= u.ph * u.s**-1 * u.m**-2 if area is not None: - counts *= utils.quantify(area, u.m ** 2) + counts *= quantify(area, u.m ** 2) return counts @@ -128,8 +130,8 @@ def make_imagehdu_from_table(x, y, flux, pix_scale=1*u.arcsec): pix_scale = pix_scale.to(u.deg) unit = pix_scale.unit - x = utils.quantify(x, unit) - y = utils.quantify(y, unit) + x = quantify(x, unit) + y = quantify(y, unit) xpixmin = int(np.floor(np.min(x) / pix_scale)) ypixmin = int(np.floor(np.min(y) / pix_scale)) diff --git a/scopesim/utils.py b/scopesim/utils.py index 5b414d4f..3b3798bb 100644 --- a/scopesim/utils.py +++ b/scopesim/utils.py @@ -400,6 +400,10 @@ def setup_loggers(**kwargs): logger.addHandler(s_handler) +def get_logger(name: str): + return logging.getLogger("astar." + name) + + def set_logger_level(which="console", level="ERROR"): """ Set the level of logging for either the console or file logger. From dee388851e565c8d18bd799f88b36bbb8812021d Mon Sep 17 00:00:00 2001 From: teutoburg Date: Thu, 11 Jan 2024 15:34:27 +0100 Subject: [PATCH 02/14] Remove unused logger functions and their tests --- scopesim/tests/test_utils_functions.py | 33 ------------------- scopesim/utils.py | 45 -------------------------- 2 files changed, 78 deletions(-) diff --git a/scopesim/tests/test_utils_functions.py b/scopesim/tests/test_utils_functions.py index 6f21b63c..0713486b 100644 --- a/scopesim/tests/test_utils_functions.py +++ b/scopesim/tests/test_utils_functions.py @@ -193,39 +193,6 @@ def test_converts_astropy_table(self): assert utils.from_currsys(tbl["seeds2"][1]) is None -class TestSetupLoggers: - def test_no_loggers_present_in_initial_scopesim_load(self): - hdlrs = logging.getLogger().handlers - - assert not any([hdlr.name == "scopesim_file_logger" for hdlr in hdlrs]) - - def test_setup_loggers_has_no_loggers(self): - utils.setup_loggers(log_to_file=False, log_to_console=False) - hdlrs = logging.getLogger().handlers - - assert not any([hdlr.name == "scopesim_file_logger" for hdlr in hdlrs]) - - def test_log_file_exist_when_file_logging_turned_on(self): - utils.setup_loggers(log_to_file=True) - filepath = Path(rc.__config__["!SIM.logging.file_path"]) - level = rc.__config__["!SIM.logging.file_level"] - f_handler = logging.getLogger().handlers[-1] - - assert filepath.exists() - assert f_handler.level == logging._checkLevel(level) - - logging.shutdown() - filepath.unlink() - - def test_console_logger_has_output(self, capsys): - utils.setup_loggers(log_to_console=True) - utils.set_logger_level("console", "INFO") - logging.info("Hello World!") - captured = capsys.readouterr() - assert "Hello World!" in captured.out - - logging.shutdown() - # load_example_optical_train modifies __currsys__! @pytest.mark.usefixtures("protect_currsys") diff --git a/scopesim/utils.py b/scopesim/utils.py index 3b3798bb..d1f421bb 100644 --- a/scopesim/utils.py +++ b/scopesim/utils.py @@ -373,55 +373,10 @@ def angle_in_arcseconds(distance, width): return np.arctan2(width, distance) * u.rad.to(u.arcsec) -def setup_loggers(**kwargs): - """ - Set up both console and file loggers. - - Acceptable parameters are the same as the ``!SIM.logging`` sub dictionary - - """ - logd = rc.__currsys__["!SIM.logging"] - logd.update(kwargs) - - logger = logging.getLogger() - hdlr_names = [hdlr.name for hdlr in logger.handlers] - - if logd["log_to_file"] and "scopesim_file_logger" not in hdlr_names: - f_handler = logging.FileHandler(logd["file_path"], - logd["file_open_mode"]) - f_handler.name = "scopesim_file_logger" - f_handler.setLevel(logd["file_level"]) - logger.addHandler(f_handler) - - if logd["log_to_console"] and "scopesim_console_logger" not in hdlr_names: - s_handler = logging.StreamHandler(sys.stdout) - s_handler.name = "scopesim_console_logger" - s_handler.setLevel(logd["console_level"]) - logger.addHandler(s_handler) - - def get_logger(name: str): return logging.getLogger("astar." + name) -def set_logger_level(which="console", level="ERROR"): - """ - Set the level of logging for either the console or file logger. - - Parameters - ---------- - which : {"console", "file"} - level : {"ON", "OFF", "DEBUG", "INFO", "WARN", "ERROR", "CRITICAL"} - """ - hdlr_name = f"scopesim_{which}_logger" - level = {"ON": "INFO", "OFF": "CRITICAL"}.get(level.upper(), level) - logger = logging.getLogger() - logger.setLevel(level) - for hdlr in logger.handlers: - if hdlr.name == hdlr_name: - hdlr.setLevel(level) - - def _get_required_packages(): reqs = metadata.requires(__package__) for req in reqs: From ee433e045e7a0194661720d1abe2e18408776fa6 Mon Sep 17 00:00:00 2001 From: teutoburg Date: Thu, 11 Jan 2024 15:41:12 +0100 Subject: [PATCH 03/14] Use logger factory from astar-utils --- scopesim/utils.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/scopesim/utils.py b/scopesim/utils.py index d1f421bb..999a25aa 100644 --- a/scopesim/utils.py +++ b/scopesim/utils.py @@ -20,6 +20,8 @@ from astropy.io import fits from astropy.table import Column, Table +from astar_utils import get_logger + from . import rc @@ -373,10 +375,6 @@ def angle_in_arcseconds(distance, width): return np.arctan2(width, distance) * u.rad.to(u.arcsec) -def get_logger(name: str): - return logging.getLogger("astar." + name) - - def _get_required_packages(): reqs = metadata.requires(__package__) for req in reqs: From 4d5dc45b1c469910b4ba89ea24a39794f9f3e378 Mon Sep 17 00:00:00 2001 From: teutoburg Date: Thu, 11 Jan 2024 15:48:32 +0100 Subject: [PATCH 04/14] Use module logger --- scopesim/utils.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/scopesim/utils.py b/scopesim/utils.py index 999a25aa..eedc2e12 100644 --- a/scopesim/utils.py +++ b/scopesim/utils.py @@ -25,6 +25,9 @@ from . import rc +logger = get_logger(__name__) + + def unify(x, unit, length=1): """ Convert all types of input to an astropy array/unit pair. @@ -504,7 +507,7 @@ def find_file(filename, path=None, silent=False): # no file found msg = f"File cannot be found: {filename}" if not silent: - logging.error(msg) + logger.error(msg) if from_currsys("!SIM.file.error_on_missing_file"): raise ValueError(msg) @@ -549,16 +552,16 @@ def convert_table_comments_to_dict(tbl): comments_str = "\n".join(tbl.meta["comments"]) comments_dict = yaml.full_load(comments_str) except yaml.error.YAMLError: - logging.warning("Couldn't convert .meta['comments'] to dict") + logger.warning("Couldn't convert
.meta['comments'] to dict") comments_dict = tbl.meta["comments"] elif "COMMENT" in tbl.meta: try: comments_dict = yaml.full_load("\n".join(tbl.meta["COMMENT"])) except yaml.error.YAMLError: - logging.warning("Couldn't convert
.meta['COMMENT'] to dict") + logger.warning("Couldn't convert
.meta['COMMENT'] to dict") comments_dict = tbl.meta["COMMENT"] else: - logging.debug("No comments in table") + logger.debug("No comments in table") return comments_dict @@ -590,7 +593,7 @@ def real_colname(name, colnames, silent=True): if not real_name: real_name = None if not silent: - logging.warning("None of %s were found in %s", names, colnames) + logger.warning("None of %s were found in %s", names, colnames) else: real_name = real_name[0] @@ -780,8 +783,8 @@ def unit_from_table(colname: str, table: Table, return u.Unit(com_tbl[colname_u]) tbl_name = table.meta.get("name", table.meta.get("filename")) - logging.info(("%s_unit was not found in table.meta: %s. Default to: %s"), - colname, tbl_name, default_unit) + logger.info("%s_unit was not found in table.meta: %s. Default to: %s", + colname, tbl_name, default_unit) return u.Unit(default_unit) @@ -886,9 +889,9 @@ def check_keys(input_dict, required_keys, action="error", all_any="all"): f"input_dict: \n{required_keys} " f"\n{input_dict.keys()}") if "warn" in action: - logging.warning(("One or more of the following keys missing " - "from input_dict: \n%s \n%s"), required_keys, - input_dict.keys()) + logger.warning( + "One or more of the following keys missing from input_dict: " + "\n%s \n%s", required_keys, input_dict.keys()) return keys_present From 1b9f80f25acfb67091e7486cd429783c000a4a62 Mon Sep 17 00:00:00 2001 From: teutoburg Date: Thu, 11 Jan 2024 15:49:49 +0100 Subject: [PATCH 05/14] Use bug_logger for bug report etc. --- scopesim/utils.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/scopesim/utils.py b/scopesim/utils.py index eedc2e12..75afb0f2 100644 --- a/scopesim/utils.py +++ b/scopesim/utils.py @@ -26,6 +26,7 @@ logger = get_logger(__name__) +bug_logger = get_logger("bug_report") def unify(x, unit, length=1): @@ -454,7 +455,7 @@ def log_bug_report(level=logging.DEBUG) -> None: """Emit bug report as logging message.""" with StringIO() as str_stream: _write_bug_report(str_stream) - logging.log(level, str_stream.getvalue()) + bug_logger.log(level, str_stream.getvalue()) def find_file(filename, path=None, silent=False): @@ -1013,15 +1014,15 @@ def wrapper(*args, **kwargs): output = func(*args, **kwargs) except Exception as err: # FIXME: This try-except should not be necessary, but - # logging.exception has an issue in some versions. + # logger.exception has an issue in some versions. try: - logging.exception( + bug_logger.exception( "Unhandled exception occured, see log file for details.") except TypeError: - logging.error( + bug_logger.error( "Unhandled exception occured, see log file for details.") - logging.error("Couldn't log full exception stack.") - logging.error("Error message was: '%s'", err) + bug_logger.error("Couldn't log full exception stack.") + bug_logger.error("Error message was: '%s'", err) log_bug_report(logging.ERROR) raise return output From c96c8be3032ecd6e1e03031d4b975231864fe8f5 Mon Sep 17 00:00:00 2001 From: teutoburg Date: Thu, 11 Jan 2024 22:55:56 +0100 Subject: [PATCH 06/14] Also change commented-out logging calls --- scopesim/optics/fov_utils.py | 6 +++--- scopesim/optics/image_plane_utils.py | 7 ++++--- scopesim/optics/optical_element.py | 4 ++-- scopesim/source/source_utils.py | 4 ++-- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/scopesim/optics/fov_utils.py b/scopesim/optics/fov_utils.py index 57e0565b..4cb42067 100644 --- a/scopesim/optics/fov_utils.py +++ b/scopesim/optics/fov_utils.py @@ -419,9 +419,9 @@ def extract_range_from_spectrum(spectrum, waverange): mask = (spec_waveset > wave_min) * (spec_waveset < wave_max) # if sum(mask) == 0: - # logging.info(("Waverange does not overlap with Spectrum waveset: " - # "%s <> %s for spectrum %s"), - # [wave_min, wave_max], spec_waveset, spectrum) + # logger.info( + # "Waverange does not overlap with Spectrum waveset: %s <> %s for " + # "spectrum %s", [wave_min, wave_max], spec_waveset, spectrum) if wave_min < min(spec_waveset) or wave_max > max(spec_waveset): logger.info(("Waverange only partially overlaps with Spectrum waveset: " "%s <> %s for spectrum %s"), diff --git a/scopesim/optics/image_plane_utils.py b/scopesim/optics/image_plane_utils.py index d75156e9..11287b5e 100644 --- a/scopesim/optics/image_plane_utils.py +++ b/scopesim/optics/image_plane_utils.py @@ -742,7 +742,8 @@ def add_imagehdu_to_imagehdu(image_hdu: fits.ImageHDU, wcs_suffix=canvas_wcs.wcs.alt, spline_order=spline_order, conserve_flux=conserve_flux) - # logging.debug("fromrescale %s", WCS(new_hdu.header, key=canvas_wcs.wcs.alt)) + # TODO: Perhaps add separately formatted WCS logger? + # logger.debug("fromrescale %s", WCS(new_hdu.header, key=canvas_wcs.wcs.alt)) new_hdu = reorient_imagehdu(new_hdu, wcs_suffix=canvas_wcs.wcs.alt, spline_order=spline_order, @@ -756,8 +757,8 @@ def add_imagehdu_to_imagehdu(image_hdu: fits.ImageHDU, sky_center = new_wcs.wcs_pix2world(img_center, 0) if new_wcs.wcs.cunit[0] == "deg": sky_center = _fix_360(sky_center) - # logging.debug("canvas %s", canvas_wcs) - # logging.debug("new %s", new_wcs) + # logger.debug("canvas %s", canvas_wcs) + # logger.debug("new %s", new_wcs) logger.debug("sky %s", sky_center) sky_center *= conv_fac pix_center = canvas_wcs.wcs_world2pix(sky_center, 0) diff --git a/scopesim/optics/optical_element.py b/scopesim/optics/optical_element.py index 63fb2df1..b9ffd399 100644 --- a/scopesim/optics/optical_element.py +++ b/scopesim/optics/optical_element.py @@ -218,8 +218,8 @@ def __getitem__(self, item): if isinstance(obj, list) and len(obj) == 1: obj = obj[0] # if obj is None or len(obj) == 0: - # logging.warning(f'No result for key: "{item}". ' - # f'Did you mean "#{item}"?') + # logger.warning( + # "No result for key: '%s'. Did you mean '#%s'?", item, item) return obj diff --git a/scopesim/source/source_utils.py b/scopesim/source/source_utils.py index c28159ff..c6069cfb 100644 --- a/scopesim/source/source_utils.py +++ b/scopesim/source/source_utils.py @@ -260,7 +260,7 @@ def make_img_wcs_header(pixel_scale, image_size): # imagehdu.data = imagehdu.data.value # else: # unit = "" -# logging.warning("No flux unit found on ImageHDU. Please add BUNIT or " -# "FLUXUNIT to the header.") +# logger.warning("No flux unit found on ImageHDU. Please add BUNIT or " +# "FLUXUNIT to the header.") # # return unit From 0939731ae5ccf718bfc81a4784e21e0776f350a9 Mon Sep 17 00:00:00 2001 From: teutoburg Date: Thu, 11 Jan 2024 23:38:33 +0100 Subject: [PATCH 07/14] Remove redundant import --- scopesim/tests/test_utils_functions.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/scopesim/tests/test_utils_functions.py b/scopesim/tests/test_utils_functions.py index 0713486b..bcc639fd 100644 --- a/scopesim/tests/test_utils_functions.py +++ b/scopesim/tests/test_utils_functions.py @@ -1,7 +1,5 @@ """Unit tests for module scopesim.utils""" -from pathlib import Path -import logging import pytest from unittest.mock import patch From a3efcb52609db53fd2efae89d90cdec9aa9f0fce Mon Sep 17 00:00:00 2001 From: teutoburg Date: Thu, 11 Jan 2024 23:38:49 +0100 Subject: [PATCH 08/14] Change default console logging level to info --- scopesim/defaults.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scopesim/defaults.yaml b/scopesim/defaults.yaml index 3a215013..37a35758 100644 --- a/scopesim/defaults.yaml +++ b/scopesim/defaults.yaml @@ -57,7 +57,7 @@ properties : file_path: ".scopesim.log" file_open_mode: "w" # w - overwrite, a - append file_level: "DEBUG" # DEBUG INFO WARNING ERROR CRITICAL - console_level: "WARNING" # DEBUG INFO WARNING ERROR CRITICAL + console_level: "INFO" # DEBUG INFO WARNING ERROR CRITICAL tests : # overridden in tests/__init__.py From 88f40bf5871e8cb517403d2e492b8e6498f05fcf Mon Sep 17 00:00:00 2001 From: teutoburg Date: Thu, 11 Jan 2024 23:39:43 +0100 Subject: [PATCH 09/14] We're not in simcado anymore --- scopesim/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scopesim/__init__.py b/scopesim/__init__.py index 17c7b997..b3b94634 100644 --- a/scopesim/__init__.py +++ b/scopesim/__init__.py @@ -1,4 +1,4 @@ -"""The Instrument data simulator for MICADO on the E-ELT""" +"Generalised telescope observation simulator." ################################################################################ # TURN OFF WARNINGS # From 14e54f6ef9ece6162e1013f32417853f37c50508 Mon Sep 17 00:00:00 2001 From: teutoburg Date: Thu, 11 Jan 2024 23:40:21 +0100 Subject: [PATCH 10/14] Formatting --- scopesim/__init__.py | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/scopesim/__init__.py b/scopesim/__init__.py index b3b94634..6cbd38c5 100644 --- a/scopesim/__init__.py +++ b/scopesim/__init__.py @@ -1,8 +1,8 @@ "Generalised telescope observation simulator." -################################################################################ -# TURN OFF WARNINGS # -################################################################################ +############################################################################### +# TURN OFF WARNINGS # +############################################################################### import sys import logging import warnings @@ -12,19 +12,19 @@ warnings.simplefilter('ignore', UserWarning) warnings.simplefilter('ignore', FutureWarning) -warnings.simplefilter('ignore', RuntimeWarning) # warnings for the developer +warnings.simplefilter('ignore', RuntimeWarning) # warnings for the developer warnings.simplefilter('ignore', category=AstropyWarning) yaml.warnings({'YAMLLoadWarning': False}) -################################################################################ -# PACKAGE GLOBAL VARIABLES # -################################################################################ +############################################################################### +# PACKAGE GLOBAL VARIABLES # +############################################################################### from . import rc -################################################################################ -# SET BASIC LOGGING LEVEL # -################################################################################ +############################################################################### +# SET BASIC LOGGING LEVEL # +############################################################################### root = logging.getLogger() root.setLevel("DEBUG") # DEBUG @@ -46,9 +46,9 @@ root.addHandler(stdout_handler) -################################################################################ -# IMPORT PACKAGE MODULES # -################################################################################ +############################################################################### +# IMPORT PACKAGE MODULES # +############################################################################### # Import all the modules to go under ScopeSim @@ -72,8 +72,8 @@ from .tests.mocks.load_basic_instrument import load_example_optical_train -################################################################################ -# VERSION INFORMATION # -################################################################################ +############################################################################### +# VERSION INFORMATION # +############################################################################### __version__ = metadata.version(__package__) From 61fcb2442888691508d00925c5368424ad997aab Mon Sep 17 00:00:00 2001 From: teutoburg Date: Thu, 11 Jan 2024 23:40:48 +0100 Subject: [PATCH 11/14] Update basic logging config --- scopesim/__init__.py | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/scopesim/__init__.py b/scopesim/__init__.py index 6cbd38c5..2a7b71df 100644 --- a/scopesim/__init__.py +++ b/scopesim/__init__.py @@ -26,24 +26,29 @@ # SET BASIC LOGGING LEVEL # ############################################################################### -root = logging.getLogger() -root.setLevel("DEBUG") # DEBUG - -if rc.__config__["!SIM.logging.log_to_file"] is True: - file_path = rc.__config__["!SIM.logging.file_path"] - write_mode = rc.__config__["!SIM.logging.file_open_mode"] - file_handler = logging.FileHandler(file_path, write_mode) - file_handler.setLevel(rc.__config__["!SIM.logging.file_level"]) # DEBUG - formatter = logging.Formatter('%(levelname)s - %(message)s') +# TODO: this should be replaced with YAML-based config!! see prepipy + +# This should be part of ScopeSim (the app) and not scopesim_core eventually + +top_logger = logging.getLogger("astar") +top_logger.setLevel(logging.WARNING) +sim_logger = top_logger.getChild(__package__) +sim_logger.setLevel(logging.DEBUG) +formatter = logging.Formatter("%(name)s - %(levelname)s: %(message)s") + +log_dict = rc.__config__["!SIM.logging"] +if log_dict["log_to_file"]: + file_handler = logging.FileHandler(log_dict["file_path"], + log_dict["file_open_mode"]) + file_handler.setLevel(log_dict["file_level"]) # DEBUG file_handler.setFormatter(formatter) - root.addHandler(file_handler) + top_logger.addHandler(file_handler) -if rc.__config__["!SIM.logging.log_to_console"] is True: +if log_dict["log_to_console"]: stdout_handler = logging.StreamHandler(sys.stdout) - stdout_handler.setLevel(rc.__config__["!SIM.logging.console_level"]) # WARNING - formatter = logging.Formatter('%(levelname)s - %(message)s') + stdout_handler.setLevel(log_dict["console_level"]) # INFO stdout_handler.setFormatter(formatter) - root.addHandler(stdout_handler) + top_logger.addHandler(stdout_handler) ############################################################################### From 9db09fddedb3e862e424d5909ecdb31c68493068 Mon Sep 17 00:00:00 2001 From: teutoburg Date: Fri, 12 Jan 2024 01:02:49 +0100 Subject: [PATCH 12/14] Bump more-itertools req --- poetry.lock | 10 +++++----- pyproject.toml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/poetry.lock b/poetry.lock index 10756b77..a8d9d0f8 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1909,13 +1909,13 @@ files = [ [[package]] name = "more-itertools" -version = "9.0.0" +version = "10.1.0" description = "More routines for operating on iterables, beyond itertools" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "more-itertools-9.0.0.tar.gz", hash = "sha256:5a6257e40878ef0520b1803990e3e22303a41b5714006c32a3fd8304b26ea1ab"}, - {file = "more_itertools-9.0.0-py3-none-any.whl", hash = "sha256:250e83d7e81d0c87ca6bd942e6aeab8cc9daa6096d12c5308f3f92fa5e5c1f41"}, + {file = "more-itertools-10.1.0.tar.gz", hash = "sha256:626c369fa0eb37bac0291bce8259b332fd59ac792fa5497b59837309cd5b114a"}, + {file = "more_itertools-10.1.0-py3-none-any.whl", hash = "sha256:64e0735fcfdc6f3464ea133afe8ea4483b1c5fe3a3d69852e6503b43a0b222e6"}, ] [[package]] @@ -3696,4 +3696,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = "^3.9" -content-hash = "8ca449a3d76211029c22ccda783abae5d17c4acc30e87b8aa7ad3a8010a96ca8" +content-hash = "6fabbcb30c56e58c4c643e2478ed9cc38bd2b815d3f318452b070e39c2fc493d" diff --git a/pyproject.toml b/pyproject.toml index 75147ae5..9acc1d5d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,7 +31,7 @@ httpx = "^0.23.0" beautifulsoup4 = "^4.12.1" lxml = "^4.9.3" pyyaml = "^6.0.1" -more-itertools = "^9.0" +more-itertools = "^10.1.0" tqdm = "^4.66.1" synphot = "^1.2.1" From 41468d83d91a552d78c1d2a3d2ae4df54af66a8d Mon Sep 17 00:00:00 2001 From: teutoburg Date: Fri, 12 Jan 2024 02:43:26 +0100 Subject: [PATCH 13/14] Add astar-utils as a dependency --- poetry.lock | 17 ++++++++++++++++- pyproject.toml | 1 + 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/poetry.lock b/poetry.lock index a8d9d0f8..9654b4e7 100644 --- a/poetry.lock +++ b/poetry.lock @@ -140,6 +140,21 @@ types-python-dateutil = ">=2.8.10" doc = ["doc8", "sphinx (>=7.0.0)", "sphinx-autobuild", "sphinx-autodoc-typehints", "sphinx_rtd_theme (>=1.3.0)"] test = ["dateparser (==1.*)", "pre-commit", "pytest", "pytest-cov", "pytest-mock", "pytz (==2021.1)", "simplejson (==3.*)"] +[[package]] +name = "astar-utils" +version = "0.2.0b0" +description = "Contains commonly-used utilities for AstarVienna's projects." +optional = false +python-versions = ">=3.9,<4.0" +files = [ + {file = "astar_utils-0.2.0b0-py3-none-any.whl", hash = "sha256:4a47a188edb3156ee45e0bfdc211350c9553c3c69aad1ce9872bb0b2c9ec7044"}, + {file = "astar_utils-0.2.0b0.tar.gz", hash = "sha256:b45322ca89dff98e89828bfe0f1cd6a04fe3fafb5f49dc5a42ce1431328a8e5e"}, +] + +[package.dependencies] +more-itertools = ">=10.1.0,<11.0.0" +pyyaml = ">=6.0.1,<7.0.0" + [[package]] name = "astropy" version = "5.3.3" @@ -3696,4 +3711,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = "^3.9" -content-hash = "6fabbcb30c56e58c4c643e2478ed9cc38bd2b815d3f318452b070e39c2fc493d" +content-hash = "db0d8ac00666a493c6c939f6b621d50c7a8b7c44cecd257adbc2671163b95f21" diff --git a/pyproject.toml b/pyproject.toml index 9acc1d5d..1e403a06 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,6 +37,7 @@ tqdm = "^4.66.1" synphot = "^1.2.1" skycalc_ipy = "^0.3.0" anisocado = "^0.3.0" +astar-utils = {version = "^0.2.0b0", allow-prereleases = true} [tool.poetry.group.dev] optional = true From 1b6ba70e82283f0092077af041fd877c83d4fdd4 Mon Sep 17 00:00:00 2001 From: teutoburg Date: Fri, 12 Jan 2024 02:46:58 +0100 Subject: [PATCH 14/14] Use debug level here to avoid spam --- scopesim/utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scopesim/utils.py b/scopesim/utils.py index 75afb0f2..c655d418 100644 --- a/scopesim/utils.py +++ b/scopesim/utils.py @@ -784,8 +784,8 @@ def unit_from_table(colname: str, table: Table, return u.Unit(com_tbl[colname_u]) tbl_name = table.meta.get("name", table.meta.get("filename")) - logger.info("%s_unit was not found in table.meta: %s. Default to: %s", - colname, tbl_name, default_unit) + logger.debug("%s_unit was not found in table.meta: %s. Default to: %s", + colname, tbl_name, default_unit) return u.Unit(default_unit)