Source code for specio.core.functions

"""
These functions represent specio's main interface for the user. They provide a
common API to read spectra data for a large variety of formats. All read
functions accept keyword arguments, which are passed on to the format that does
the actual work.  To see what keyword arguments are supported by a specific
format, use the :func:`.help` function.

Functions for reading:

  * :func:`.specread` - read a file with spectra from the specified uri

More control:

For a larger degree of control, specio provides a function
:func:`.get_reader`. It returns an :class:`.Reader` object, which can be used
to read data and meta data in a more controlled manner.  This also allows
specific scientific formats to be exposed in a way that best suits that
file-format.

----

Supported resource URI's:

All functions described here accept a URI to describe the resource to
read from or write to. These can be a wide range of things.

For reading:

* a normal filename, e.g. ``'c:\\foo\\bar.png'``
* a file object with a ``read()`` / ``write()`` method.

"""

# Copyright (c) 2017
# Authors: Guillaume Lemaitre <guillaume.lemaitre@inria.fr>
# License: BSD 3 clause

from __future__ import print_function

import os
import glob
from itertools import chain

import numpy as np

from . import Request
from .util import Spectrum
from .. import formats


[docs]def help(name=None): """Print the help regarding a given format. Print the documentation of the format specified by name, or a list of supported formats if name is omitted. Parameters ---------- name : str Can be the name of a format, a filename extension, or a full filename. """ if not name: print(formats) else: print(formats[name])
# Base functions that return a reader
[docs]def get_reader(uri, format=None, **kwargs): """Return a Reader instance. Returns a :class:`.Reader` object which can be used to read data and meta data from the specified file. Parameters ---------- uri : {str, file} The resource to load the image from, e.g. a filename. format : str The format to use to read the file. By default specio selects the appropriate for you based on the filename and its contents. kwargs : dict Further keyword arguments are passed to the reader. See :func:`.help` to see what arguments are available for a particular format. Returns ------- reader : Format.Reader :class:`specio.Reader` instance allowing to read the data. """ # Create request object request = Request(uri, **kwargs) # Get format if format is not None: format = formats[format] else: format = formats.search_read_format(request) if format is None: raise ValueError('Could not find a format to read the specified file') # Return its reader object return format.get_reader(request)
# Spectra def _get_reader_get_data(uri, format, **kwargs): """Get the reader and the associated data.""" reader = get_reader(uri, format, **kwargs) with reader: return reader.get_data(index=None) def _validate_filenames(uri): """Check the filenames and expand in the case of wildcard. Parameters ---------- uri : {str, list of str, file} The resource to load the spectrum from. The input accepted are: * a filename or a list of filename of spectrum; * a filename or a list of filename containing a wildcard (e.g. ``'./data/*.spc'``). Returns ------- filenames : list of str Returns a list of all file names. """ if isinstance(uri, list): return list(chain.from_iterable( [sorted(glob.glob(os.path.expanduser(f))) for f in uri])) else: return sorted(glob.glob(os.path.expanduser(uri))) def _zip_spectrum(spectrum, tol_wavelength): """Compress if possible several Spectrum into a single one. Parameters ---------- spectrum : list of Spectrum The list of Spectrum to zip. tol_wavelength : float Tolerance to merge spectrum when their wavelength are slightly different. Returns ------- zipped_spectrum : Spectrum or list of Spectrum The zipped spectra(um) if it was possible to zip them. """ all_spectrum = all([isinstance(sp, Spectrum) for sp in spectrum]) if all_spectrum: # check that the wavelength of the different spectrum are the # same and concatenate all spectrum in a single data structure wavelength = spectrum[0].wavelength try: consistent_wavelength = [np.allclose(sp.wavelength, wavelength, atol=tol_wavelength) for sp in spectrum] if not all(consistent_wavelength): return spectrum except ValueError: # the above comparison will fail when two arrays have # different sizes return spectrum else: spectrum_2d, meta_2d = zip(*[(sp.amplitudes, sp.meta) for sp in spectrum]) return Spectrum(np.vstack(spectrum_2d), wavelength, meta_2d) else: # chain the spectrum into a single list output_spectrum = [] for sp in spectrum: if isinstance(sp, list): output_spectrum += sp else: output_spectrum.append(sp) return output_spectrum
[docs]def specread(uri, format=None, tol_wavelength=1e-5, **kwargs): """Read spectra in a given format. Reads spectrum from the specified file. Returns a list or a :class:`specio.Spectrum` instance containing the data, wavelength, and the meta data Parameters ---------- uri : {str, list of str, file} The resource to load the spectrum from. The input accepted are: * a filename or a list of filename of spectrum; * a filename or a list of filename containing a wildcard (e.g. ``'./data/*.spc'``); * a file object. format : str The format to use to read the file. By default specio selects the appropriate for you based on the filename and its contents. tol_wavelength : float, optional Tolerance to merge spectrum when their wavelength are slightly different. kwargs : dict Further keyword arguments are passed to the reader. See :func:`.help` to see what arguments are available for a particular format. Returns ------- spectrum : specio.core.Spectrum or a list of specio.core.Spectrum A :class:`specio.core.Spectrum` or a list of :class:`specio.core.Spectrum`. A :class:`specio.core.Spectrum` contains: * a 1D ndarray of shape (n_wavelength,) or 2D ndarray of shape (n_spectra, n_wavelength) ``amplitudes``; * a 1D ndarray of shape (n_wavelength,) ``wavelength``; * a dict ``meta``. """ filenames = _validate_filenames(uri) spectrum = [_get_reader_get_data(f, format, **kwargs) for f in filenames] return (_zip_spectrum(spectrum, tol_wavelength) if len(spectrum) > 1 else spectrum[0])