Source code for vdat.config.versions

# Virus Data Analysis Tool: a data reduction GUI for HETDEX/VIRUS data
# Copyright (C) 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/>.
'''Configuration and support files versioning and checking'''

import configparser as cp
import os
import sys

from pyhetdex.cure import distortion
from pyhetdex.het import fplane, ifu_centers
from pyhetdex.tools.configuration import ConfigParser
import six
import yaml

COPY_FILES = ['vdat_setting.cfg',
              'vdat_commands.yml',
              'tasks.yml',
              'fplane.txt',
              os.path.join('extra_files', 'defaultL.dist'),
              os.path.join('extra_files', 'defaultR.dist'),
              os.path.join('extra_files', 'dither_positions.txt'),
              os.path.join('extra_files', 'IFUcen_HETDEX.txt'),
              os.path.join('extra_files', 'lines_L.par'),
              os.path.join('extra_files', 'lines_R.par'),
              ]
'files to copy'

IMPORTANT_FILES = ['vdat_setting.cfg',
                   'vdat_commands.yml',
                   'tasks.yml',
                   'fplane.txt'
                   ]
'''Files essential to run VDAT but that can have different names and be however
passed to the code via configuration or command line options'''

VERSION_VDAT_SETTING = '2.0.0'
'version of the vdat_setting file'
VERSION_VDAT_COMMANDS = '1.3.0'
'version of the vdat_commands file'
VERSION_TASKS = '1.3.0'
'version of the tasks file'


[docs]def version_name(filename): '''Return the name of the variable storing the version of ``filename`` Parameters ---------- filename : string name of the file for which to find the version Returns ------- string name of the variable storing the configuration file ''' file_name = os.path.splitext(filename)[0].replace(os.path.sep, '_') return "VERSION_" + file_name.upper()
[docs]def version_of_file(filename): '''If available, returns the version string for the ``filename`` as defined in :mod:`vdat.config.versions` Parameters ---------- filename : string name of the file for which to find the version Returns ------- version : string version or None, if no version is available ''' name = version_name(filename) thismodule = sys.modules[__name__] try: version = getattr(thismodule, name) except AttributeError: version = None return version
[docs]def version_from_file(path, filename): '''Try to extract the version number from ``path + filename`` Parameters ---------- path : string path where the file resides filename : string name of the file Returns ------- version : string version as extracted from the file or None, if no version is found ''' vname = version_name(filename) version = None with open(os.path.join(path, filename)) as f: for l in f: if vname in l: version = l.split('=')[1].strip() break return version
[docs]def files_with_version(): '''Return the list of file names, that can be copied, that have an associated version. Returns ------- list of strings file names ''' return [fn for fn in COPY_FILES if version_of_file(fn)]
# loaders
[docs]class LoaderError(Exception): 'Raised when a loader fails for any reason' pass
[docs]def configparser_loader(fname): '''Try to load the file using configparser Parameters ---------- fname : string file to load Raises ------ LoaderError if it fails to load ''' c = ConfigParser() try: c.read(fname) except cp.Error as e: six.raise_from(LoaderError(e), e)
[docs]def yaml_loader(fname): '''Try to load the file using yaml Parameters ---------- fname : string file to load Raises ------ LoaderError if it fails to load ''' try: with open(fname) as f: yaml.safe_load(f) except yaml.error.YAMLError as e: six.raise_from(LoaderError(e), e)
[docs]def fplane_loader(fname): '''Try to load the file as a fplane file. Parameters ---------- fname : string file to load Raises ------ LoaderError if it fails to load ''' try: fplane.FPlane(fname) except (ValueError, IndexError) as e: six.raise_from(LoaderError(e), e)
[docs]def dist_loader(fname): '''Try to load the file as a distortion file. Parameters ---------- fname : string file to load Raises ------ LoaderError if it fails to load ''' try: distortion.Distortion(fname) except Exception as e: six.raise_from(LoaderError(e), e)
[docs]def ifucent_loader(fname): '''Try to load the file as an ifu center file. Parameters ---------- fname : string file to load Raises ------ LoaderError if it fails to load ''' try: ifu_centers.IFUCenter(fname) except (ValueError, ) as e: six.raise_from(LoaderError(e), e)
[docs]def lines_loader(fname): '''Try to load the file as an line file. Parameters ---------- fname : string file to load Raises ------ LoaderError if it fails to load ''' try: with open(fname) as f: for l in f: if l.startswith('#'): continue else: l, x, ac = l.split() except ValueError as e: six.raise_from(LoaderError(e), e)
[docs]def dither_position_loader(fname): '''Try to load the file as dither position file. Parameters ---------- fname : string file to load Raises ------ LoaderError if it fails to load ''' try: with open(fname) as f: for line in f: if line.startswith('#'): continue else: line = line.split() line[0] if len(line[1:]) % 2 != 0: raise ValueError('The number of x/y dither shifts must' ' be even not {} as in line "{}"' .format(len(line[1:]), line)) except (IndexError, ValueError) as e: six.raise_from(LoaderError(e), e)
LOADERS_FILES = { 'vdat_setting.cfg': configparser_loader, 'vdat_commands.yml': yaml_loader, 'tasks.yml': yaml_loader, 'fplane.txt': fplane_loader, os.path.join('extra_files', 'defaultL.dist'): dist_loader, os.path.join('extra_files', 'defaultR.dist'): dist_loader, os.path.join('extra_files', 'dither_positions.txt'): dither_position_loader, os.path.join('extra_files', 'IFUcen_HETDEX.txt'): ifucent_loader, os.path.join('extra_files', 'lines_L.par'): lines_loader, os.path.join('extra_files', 'lines_R.par'): lines_loader }