Source code for libvhc.recipes

# Virus Health Check: a validation tool for HETDEX/VIRUS data
# Copyright (C) 2015, 2016, 2017, 2018  "The HETDEX collaboration"
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <https://www.gnu.org/licenses/>.
"""Module implementing the recipes entry points
"""
from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

import os
import re

import pyhetdex.doc.docstring as doc
from pyhetdex.tools import six_ext
import pyhetdex.tools.files.file_tools as ft

import libvhc.loaders as vhcload
import libvhc.utils as vhcutils
import libvhc.exceptions as vhcexcept

# utilities
RECIPE_FILE = "v_recipe.txt"
"Name of the recipe file"


[docs]def get_recipe(path, log): """Load and try to read the recipe name or infer it from the files in path Parameters ---------- path : string path where to look for files if the recipe file does not exists log : :class:`logging.Logger` logger to use """ recipe_names = vhcload.load_recipes(log) try: # read the recipe with open(recipe_file(path)) as f: recipe = f.read().strip("\n") except six_ext.FileOpenError: log.warning("No recipe file found") recipe = make_recipe(path, log) # check that the recipe is among the loaded ones if recipe not in recipe_names: msg = ("The recipe '{}' is not known. Make sure that the package" " providing it is correctly installed.") raise vhcexcept.VHCRecipeError(msg.format(msg)) return recipe
[docs]def recipe_file(path): """Return the name of the recipe file Parameters ---------- path : string path where the recipe file leaves Returns ------- string name of the recipe file """ return os.path.join(path, RECIPE_FILE)
[docs]@doc.format_docstring(RECIPE_FILE) def make_recipe(path, log): """Infer the recipe name of the first virus fits file found. If the recipe is known, write it to the '{}' file. Parameters ---------- path : string path provided to the vhc executable. log : :class:`logging.Logger` logger to use Returns ------- recipe : string recipe name """ try: fname = next(ft.scan_files(path, matches=vhcutils.generic_virus_match, exclude_dirs=['gp', 'wfs'])) recipe = "unknown" for k, v in vhcutils.recipe_match.items(): if re.search(ft.wildcards_to_regex(v), fname) is not None: recipe = k break except StopIteration: log.critical("No fits file found.") recipe = "unknown" if recipe == "unknown": msg = "Impossible to retrieve the recipe from the file names" raise vhcexcept.VHCRecipeError(msg) with open(recipe_file(path), 'w') as f: f.write(recipe + '\n') log.info("The recipe '%s' has be written to file", recipe) return recipe
# recipe definitions common_drivers = ["common:n_files", "common:n_pixels", "common:bitstat", "common:headerkeys", "common:nullpix", # "common:check_header", "common:check_overscan", # "common:check_line_overscan", "common:exptime", "common:dettemp", "common:saturation", "common:repeat", ]
[docs]def recipe_protopype(name): # pragma: no cover """Signature for a function used to register a recipe. Parameters ---------- name : string name under which the recipe is advertised Returns ------- string file name template to use to collect all the relevant file or to guess the recipe name from the files; e.g. for the ``flat`` recipe ``[0-9]*flt.fits`` is returned list of strings list of default drivers to run for the recipe, if no ``v_driver.txt`` file is found; e.g. ``['common:n_files', 'common:saturation']`` """ pass
[docs]def flat_recipe(name): """File names and drivers available for the flat recipe""" recipe_match = "*[0-9]*flt.fits" default_drivers = common_drivers + [ "flat:min_flux", "flat:n_fibers", "flat:check_throughput", "flat:check_distortion"] return recipe_match, default_drivers
[docs]def bias_recipe(name): """File names and drivers available for the bias recipe""" recipe_match = "*[0-9]*zro.fits" default_drivers = common_drivers + ["bias:compare", "bias:flat", "bias:linestddev", "bias:fft"] return recipe_match, default_drivers
[docs]def arc_recipe(name): """File names and drivers available for the arc recipe""" recipe_match = "*[0-9]*cmp.fits" default_drivers = common_drivers + ["arc:find_peaks"] return recipe_match, default_drivers
[docs]def hetdex_dither_recipe(name): """File names and drivers available for the hetdex_dither recipe""" recipe_match = "*[0-9]*sci.fits" default_drivers = common_drivers + ["hetdex_dithers:n_dithers", "hetdex_dithers:col_cte", "hetdex_dithers:sky_level"] return recipe_match, default_drivers
[docs]def twilight_recipe(name): """File names and drivers available for the twilight recipe""" recipe_match = "*[0-9]*twi.fits" default_drivers = common_drivers + [ "flat:min_flux", "flat:n_fibers", "flat:check_throughput", "flat:check_distortion", "flat:col_cte"] return recipe_match, default_drivers
[docs]def dark_recipe(name): """File names and drivers available for the dark recipe""" recipe_match = "*[0-9]*drk.fits" default_drivers = common_drivers + ["bias:compare", "bias:flat"] return recipe_match, default_drivers
[docs]def engineering_recipe(name): """File names and drivers available for the engineering recipe""" recipe_match = "*[0-9]*eng.fits" default_drivers = common_drivers return recipe_match, default_drivers