Source code for pysptools.util.input_vld

#
#------------------------------------------------------------------------------
# Copyright (c) 2013-2014, Christian Therien
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#------------------------------------------------------------------------------
#
# input_vld.py - This file is part of the PySptools package.
#

import numpy as np


def simple_decorator(decorator):
    """ A well behaved decorator.
        Ref. wiki.python.org
    """
    def new_decorator(f):
        g = decorator(f)
        g.__name__ = f.__name__
        g.__doc__ = f.__doc__
        g.__dict__.update(f.__dict__)
        return g
    # Now a few lines needed to make simple_decorator itself
    # be a well-behaved decorator.
    new_decorator.__name__ = decorator.__name__
    new_decorator.__doc__ = decorator.__doc__
    new_decorator.__dict__.update(decorator.__dict__)
    return new_decorator


[docs]class InputValidation(object): """ Validate method inputs. """ # input_type axes_type = 1 bool_type = 2 cmap_exist = 3 columns_type = 4 cube_type = 5 cube_type2 = 6 # more restricted, for HySime far_type = 7 # for HfcVd float_type = 8 float_type2 = 9 index_range = 10 int_type = 11 int_type2 = 12 # int or None labels_type = 13 lib_type = 14 list_type = 15 mask_type = 16 spectrum_length = 17 spectrum_type = 18 string_type = 19 string_type2 = 20 suffix_type = 21 threshold_type = 22 threshold_type2 = 23 threshold_type3 = 24 # for AbundanceClassification transform_type = 25 def __init__(self, class_id): self.class_id = class_id def dispatch(self, check_type, *args): if check_type == self.cube_type: self._cube_type(args) if check_type == self.lib_type: self._lib_type(args) if check_type == self.threshold_type: self._threshold_type(args) if check_type == self.cmap_exist: self._cmap_exist(args) if check_type == self.suffix_type: self._suffix_type(args) if check_type == self.index_range: self._index_range(args) if check_type == self.bool_type: self._bool_type(args) if check_type == self.spectrum_length: self._spectrum_length(args) if check_type == self.labels_type: self._labels_type(args) if check_type == self.mask_type: self._mask_type(args) if check_type == self.spectrum_type: self._spectrum_type(args) if check_type == self.threshold_type2: self._threshold_type2(args) if check_type == self.int_type: self._int_type(args) if check_type == self.axes_type: self._axes_type(args) if check_type == self.transform_type: self._transform_type(args) if check_type == self.int_type2: self._int_type2(args) if check_type == self.cube_type2: self._cube_type2(args) if check_type == self.far_type: self._far_type(args) if check_type == self.threshold_type3: self._threshold_type3(args) if check_type == self.string_type: self._string_type(args) if check_type == self.string_type2: self._string_type2(args) if check_type == self.list_type: self._list_type(args) if check_type == self.float_type: self._float_type(args) if check_type == self.float_type2: self._float_type2(args) if check_type == self.columns_type: self._int_type2(args) def _cube_type(self, args): method = args[0] M = args[1] obj_id = args[2] if type(M) is not np.ndarray: err1 = 'in {0}.{1}(), {2} is not a numpy.array' raise TypeError(err1.format(self.class_id, method, obj_id)) if M.ndim != 3: err2 = 'in {0}.{1}(), {2} have {3} dimension(s), expected 3 dimensions' raise RuntimeError(err2.format(self.class_id, method, obj_id, M.ndim)) def _lib_type(self, args): method = args[0] E = args[1] obj_id = args[2] if type(E) is not np.ndarray: err1 = 'in {0}.{1}(), {2} is not a numpy.array' raise TypeError(err1.format(self.class_id, method, obj_id)) if E.ndim != 1 and E.ndim != 2: err2 = 'in {0}.{1}(), {2} have {3} dimension(s), expected 2 dimensions' raise RuntimeError(err2.format(self.class_id, method, obj_id, E.ndim)) def _threshold_type(self, args): method = args[0] E = args[1] threshold = args[2] if type(threshold) is not float and type(threshold) is not list: err1 = 'in {0}.{1}(), threshold have {2}, expected float or list type' raise TypeError(err1.format(self.class_id, method, type(threshold))) if type(threshold) is list and len(threshold) != E.shape[0]: err2 = 'in {0}.{1}(), threshold have length {2}, expected length {3}' raise ValueError(err2.format(self.class_id, method, len(threshold), E.shape[0])) if type(threshold) is float: err3 = 'in {0}.{1}(), threshold value is {2}, expected value between 0.0 and 1.0' if threshold < 0.0 or threshold > 1.0: raise ValueError(err3.format(self.class_id, method, threshold)) if type(threshold) is list: err4 = 'in {0}.{1}(), threshold value is {2} at index {3}, expected value between 0.0 and 1.0' for i in range(len(threshold)): if threshold[i] < 0.0 or threshold[i] > 1.0: raise ValueError(err4.format(self.class_id, method, threshold[i], i)) def _spectrum_length(self, args): method = args[0] M = args[1] M_id = args[2] E = args[3] E_id = args[4] if E.ndim == 1: if M.shape[2] != E.shape[0]: err1 = 'in {0}.{1}(), the {2} spectrum length is different to the {3} spectrum length' raise RuntimeError(err1.format(self.class_id, method, M_id, E_id)) if E.ndim == 2: if M.shape[2] != E.shape[1]: err2 = 'in {0}.{1}(), the {2} spectrum length is different to the {3} spectrum length' raise RuntimeError(err2.format(self.class_id, method, M_id, E_id)) def _cmap_exist(self, args): method = args[0] cmap = args[1] to_call = args[2] # = args[2] if not isinstance(cmap, np.ndarray): err1 = 'in {0}.{1}(), call {2} before calling {3}' raise RuntimeError(err1.format(self.class_id, method, to_call, method)) def _suffix_type(self, args): method = args[0] suffix = args[1] if type(suffix) is not str and suffix != None: err1 = 'in {0}.{1}(), suffix is not of str type or None' raise TypeError(err1.format(self.class_id, method)) def _bool_type(self, args): method = args[0] obj = args[1] obj_id = args[2] if type(obj) is not bool: err = 'in {0}.{1}(), {2} is not of bool type' raise TypeError(err.format(self.class_id, method, obj_id)) def _index_range(self, args): method = args[0] idx = args[1] n_em = args[2] if idx == 'all': return if idx < 1 or idx > n_em: err1 = 'in {0}.{1}(), indexing at {2} is out of range, expected a value between 1 and {3} or the string \'all\'' raise IndexError(err1.format(self.class_id, method, idx, n_em)) def _labels_type(self, args): method = args[0] labels = args[1] if type(labels) is not list and labels != None: err1 = 'in {0}.{1}(), labels is not a list or None' raise TypeError(err1.format(self.class_id, method)) def _mask_type(self, args): method = args[0] mask = args[1] if type(mask) is not np.ndarray and mask != None: err1 = 'in {0}.{1}(), mask is not a numpy.array' raise TypeError(err1.format(self.class_id, method)) if isinstance(mask, np.ndarray) and mask.ndim != 2: err2 = 'in {0}.{1}(), mask have {2} dimension(s), expected 2 dimensions' raise RuntimeError(err2.format(self.class_id, method, mask.ndim)) def _spectrum_type(self, args): method = args[0] t = args[1] obj_id = args[2] if type(t) is not np.ndarray: err1 = 'in {0}.{1}(), {2} is not a numpy.array' raise TypeError(err1.format(self.class_id, method, obj_id)) if t.ndim != 1: err2 = 'in {0}.{1}(), {2} have {3} dimension(s), a vector is expected' raise RuntimeError(err2.format(self.class_id, method, obj_id, t.ndim)) def _threshold_type2(self, args): method = args[0] threshold = args[1] if type(threshold) is not float and threshold != None: err1 = 'in {0}.{1}(), threshold is not of float type or None' raise TypeError(err1.format(self.class_id, method)) def _int_type(self, args): method = args[0] number = args[1] obj_id = args[2] if type(number) is not int: err1 = 'in {0}.{1}(), {2} is not of int type' raise TypeError(err1.format(self.class_id, method, obj_id)) def _axes_type(self, args): method = args[0] axes = args[1] if type(axes) is not dict and axes != None: err1 = 'in {0}.{1}(), axes is not of dict type or None' raise TypeError(err1.format(self.class_id, method)) def _transform_type(self, args): method = args[0] q = args[1] transform = args[2] if transform == None: return if type(transform) is not np.ndarray: err1 = 'in {0}.{1}(), transform is not a numpy.array' raise RuntimeError(err1.format(self.class_id, method)) if transform.ndim != 3: err2 = 'in {0}.{1}(), transform have {2} dimension(s), expected 3 dimensions' raise RuntimeError(err2.format(self.class_id, method, transform.ndim)) if q-1 != transform.shape[2]: err3 = 'in {0}.{1}(), q equal {2} and transform have {3} components, expected q == components - 1' raise RuntimeError(err3.format(self.class_id, method, q, transform.shape[2])) def _int_type2(self, args): method = args[0] number = args[1] obj_id = args[2] if type(number) is not int and number != None: err1 = 'in {0}.{1}(), {2} is not of int type or None' raise TypeError(err1.format(self.class_id, method, obj_id)) def _cube_type2(self, args): method = args[0] M = args[1] obj_id = args[2] if type(M) is not np.ndarray: err1 = 'in {0}.{1}(), {2} is not a numpy.array' raise TypeError(err1.format(self.class_id, method, obj_id)) if M.ndim != 3: err2 = 'in {0}.{1}(), {2} have {3} dimension(s), expected 3 dimensions' raise RuntimeError(err2.format(self.class_id, method, obj_id, M.ndim)) h, w, numBands = M.shape if numBands < 2: err3 = 'in {0}.{1}(), too few bands to estimate the noise' raise RuntimeError(err3.format(self.class_id, method)) def _far_type(self, args): method = args[0] far = args[1] obj_id = args[2] if not (type(far) is list or far == 'default'): err1 = 'in {0}.{1}(), far have {2}, expected list type' raise TypeError(err1.format(self.class_id, method, type(far))) if type(far) is list: for i in range(len(far)): if far[i] > 1.0: err2 = 'in {0}.{1}(), far value is {2} at index {3}, expected value < 1' raise ValueError(err2.format(self.class_id, method, far[i], i)) def _threshold_type3(self, args): method = args[0] M = args[1] threshold = args[2] if type(threshold) is not float and type(threshold) is not list: err1 = 'in {0}.{1}(), threshold have {2}, expected float or list type' raise TypeError(err1.format(self.class_id, method, type(threshold))) if type(threshold) is list and len(threshold) != M.shape[2]: err2 = 'in {0}.{1}(), threshold have length {2}, expected length {3}' raise ValueError(err2.format(self.class_id, method, len(threshold), M.shape[2])) if type(threshold) is float: err3 = 'in {0}.{1}(), threshold value is {2}, expected value between 0.0 and 1.0' if threshold < 0.0 or threshold > 1.0: raise ValueError(err3.format(self.class_id, method, threshold)) if type(threshold) is list: err4 = 'in {0}.{1}(), threshold value is {2} at index {3}, expected value between 0.0 and 1.0' for i in range(len(threshold)): if threshold[i] < 0.0 or threshold[i] > 1.0: raise ValueError(err4.format(self.class_id, method, threshold[i], i)) def _string_type(self, args): method = args[0] string = args[1] obj_id = args[2] if type(string) is not str: err1 = 'in {0}.{1}(), {2} is not of string type' raise TypeError(err1.format(self.class_id, method, obj_id)) def _string_type2(self, args): method = args[0] string = args[1] obj_id = args[2] if type(string) is not str and string != None: err1 = 'in {0}.{1}(), {2} is not of string type or None' raise TypeError(err1.format(self.class_id, method, obj_id)) def _list_type(self, args): method = args[0] lst = args[1] obj_id = args[2] if type(lst) is not list: err1 = 'in {0}.{1}(), {2} is not of list type' raise TypeError(err1.format(self.class_id, method, obj_id)) def _float_type(self, args): method = args[0] flt = args[1] obj_id = args[2] if type(flt) is not float: err1 = 'in {0}.{1}(), {2} is not of float type' raise TypeError(err1.format(self.class_id, method, obj_id)) def _float_type2(self, args): method = args[0] flt = args[1] obj_id = args[2] if type(flt) is not float and flt != None: err1 = 'in {0}.{1}(), {2} is not of float type or None' raise TypeError(err1.format(self.class_id, method, obj_id))