Exemple #1
0
 def __new__(cls, argname, arg, *allowed_types, **kwargs):
     allowed = listify_args(allowed_types)
     my_caller = get_kwarg(kwargs, 'caller') or (caller() + '()')
     if len(allowed) == 1:
         return TypeError('Argument {0} to {1} must be {2} (got {3})'.format(
             argname,
             my_caller,
             classname(allowed[0]),
             type(arg).__name__
         ))
     else:
         return TypeError("Argument {0} to {1} must be one of ({2}) (got {3})".format(
             argname,
             my_caller,
             ', '.join(classname(a) for a in allowed),
             type(arg).__name__
         ))
Exemple #2
0
    def __new__(cls, *args, **kwargs):
        """
        TODO Move this to class level documentation, since it doesn't show up in Sphinx
        Takes several different forms.  Given a number of arguments (possibly nested lists), a Tensor is created as
        expected.  *This is the only form in which arguments may be specified without keywords.*
        `Tensor` can also be initialized by giving a list of dimensions for the `shape` (aliased as `dimension`)
        keyword argument, with a possible default value keyword argument `default_val`.
        Unless otherwise specified via the `dtype` keyword argument, it is assumed that the input data should be cast
        as a `numpy.float64`.

        """
        # Pop off any special args or kwargs and store their values for later
        has_indices = False
        ret_val = None
        indices = None
        units = pop_kwarg(kwargs, 'units')
        name = kwargs.pop('name', None)
        #--------------------------------------------------------------------------------#
        # pop off any kwargs that the subclass's __init__ takes...
        subclass_kwargs = {}
        for supercls in cls.__mro__:
            if supercls is Tensor:
                break
            if hasattr(supercls, '__tensor_init__') and callable(supercls.__tensor_init__):
                if hasattr(supercls.__tensor_init__, 'getargspec'):
                    argspec = supercls.__tensor_init__.getargspec()
                else:
                    argspec = inspect.getargspec(supercls.__tensor_init__)
                for arg in argspec.args[1:]:
                    subclass_kwargs[arg] = kwargs.pop(arg, None)
        #--------------------------------------------------------------------------------#
        # Check for indices...
        indices_kwarg = kwargs.pop('indices', None)
        if indices_kwarg is None and len(args) == 1 and isinstance(args[0], basestring):
            args = list(args)
            indices_kwarg = args.pop(0)
            args = tuple(args)
        index_range_set = pop_multikwarg(kwargs, 'index_range_set', 'in_set', 'set')
        if indices_kwarg is not None:
            has_indices = True
            indices = EinsumTensor.split_indices(indices_kwarg)
            if index_range_set is None:
                index_range_set = IndexRange.global_index_range_set
            shape = []
            for idx in indices:
                if idx not in index_range_set.known_ranges:
                    raise IndexError("unknown index '" + idx + "'")
                shape.append(index_range_set.known_ranges[idx].size)
            shape = tuple(shape)
            if "shape" in kwargs:
                kwshape = kwargs.pop('shape')
                if shape != kwshape:
                    raise TypeError("inconsistent shape:  indices '{}' indicate a shape of {}, but"
                                    " the keyword 'shape' was given with the shape {}".format(
                        ",".join(indices), shape, kwshape
                    ))
            kwargs['shape'] = shape
        #--------------------------------------------------------------------------------#
        # Now create a numpy.ndarray object...
        def_val = pop_kwarg(kwargs, 'default_val', 'default_value', 'default') or 0.0
        # Set the default data type to float, unless the user specifies
        dtype = get_kwarg(kwargs, 'dtype') or float
        if not callable(dtype) and grendel.show_warnings:
            warn("dtype given to {0} constructor is not Callable and thus cannot be used for casting." \
                 "  It is better to use callable types for dtype if possible; e.g. numpy.float64 instead" \
                 "of numpy.dtype('float64')".format(classname(cls)))
        kwargs['dtype'] = dtype
        # Typecast the default value
        if callable(dtype):
            def_val = dtype(def_val)
        # See if we have a shape...
        shape = pop_kwarg(kwargs, 'shape', 'dimension')
        # See if we have data...
        # This allows us to support the form Tensor(1, 2, 3, 4)
        if len(args) == 1 and isinstance(args[0], np.ndarray):
            data = args[0]
        else:
            data = listify_args(*args)
        if 'data' in kwargs:
            if data:
                raise TypeError("`data` may be specified as a keyword argument or as " \
                                "the regular arguments to {0} constructor, but not both.".format(classname(cls)))
            else:
                data = pop_kwarg('data')
        if shape and not isinstance(data, np.ndarray):
            has_content = False
            if len(args) != 0:
                has_content = True
            if not has_content:
                if def_val == 0.0:
                    try:
                        ret_val = np.zeros(shape=shape, **kwargs)
                    except:
                        raise
                else:
                    ret_val = (np.ones(shape=shape, **kwargs) * def_val)
            else:
                if grendel.sanity_checking_enabled:
                    # Check data length
                    tmp = np.array(data)
                    needed_data_size = 1
                    for dim in shape: needed_data_size *= dim
                    try:
                        tmp.reshape((needed_data_size,))
                    except ValueError:
                        raise ValueError("Data provided to {0} constructor is incompatible with the shape {1}".format(classname(cls), shape))
                    # Check data type
                ret_val = np.array(data, **kwargs).reshape(shape)
        else:
            # Just pass on the data and any surviving kwargs
            try:
                if isinstance(data, np.ndarray) and (
                        len(kwargs) == 0
                     or (len(kwargs) == 1 and 'dtype' in kwargs and kwargs['dtype'] == data.dtype)
                ):
                    # Just do a view
                    ret_val = data.view(cls)
                else:
                    # Otherwise, we need to call the numpy "constructor" (actually a factory function) of ndarray
                    ret_val = np.array(data, **kwargs)
            except:
                # debugging breakpoint hook
                raise
            if shape and ret_val.shape != shape:
                raise ValueError("Shape mismatch: data shape {0} does not match specified shape {1}".format(
                    data.shape, shape
                ))
        #--------------------------------------------------------------------------------#
        # View-cast the ret_val to the class in question, but only if we haven't already
        if not isinstance(ret_val, cls):
            ret_val = ret_val.view(cls)
        # Now assign stuff from any special args...
        if has_indices:
            ret_val.indices = indices
            ret_val.index_range_set = index_range_set
        else:
            ret_val.indices = None
        ret_val.units = units
        ret_val.name = name
        if name is None:
            ret_val.name = "(unnamed tensor)"
        # pass the remaining kwargs to the initializer...
        ret_val.__tensor_init__(**subclass_kwargs)
        return ret_val
Exemple #3
0
    def __new__(cls, *args, **kwargs):
        """
        TODO Move this to class level documentation, since it doesn't show up in Sphinx
        Takes several different forms.  Given a number of arguments (possibly nested lists), a Tensor is created as
        expected.  *This is the only form in which arguments may be specified without keywords.*
        `Tensor` can also be initialized by giving a list of dimensions for the `shape` (aliased as `dimension`)
        keyword argument, with a possible default value keyword argument `default_val`.
        Unless otherwise specified via the `dtype` keyword argument, it is assumed that the input data should be cast
        as a `numpy.float64`.

        """
        # Pop off any special args or kwargs and store their values for later
        has_indices = False
        ret_val = None
        indices = None
        units = pop_kwarg(kwargs, 'units')
        name = kwargs.pop('name', None)
        #--------------------------------------------------------------------------------#
        # pop off any kwargs that the subclass's __init__ takes...
        subclass_kwargs = {}
        for supercls in cls.__mro__:
            if supercls is Tensor:
                break
            if hasattr(supercls, '__tensor_init__') and callable(
                    supercls.__tensor_init__):
                if hasattr(supercls.__tensor_init__, 'getargspec'):
                    argspec = supercls.__tensor_init__.getargspec()
                else:
                    argspec = inspect.getargspec(supercls.__tensor_init__)
                for arg in argspec.args[1:]:
                    subclass_kwargs[arg] = kwargs.pop(arg, None)
        #--------------------------------------------------------------------------------#
        # Check for indices...
        indices_kwarg = kwargs.pop('indices', None)
        if indices_kwarg is None and len(args) == 1 and isinstance(
                args[0], basestring):
            args = list(args)
            indices_kwarg = args.pop(0)
            args = tuple(args)
        index_range_set = pop_multikwarg(kwargs, 'index_range_set', 'in_set',
                                         'set')
        if indices_kwarg is not None:
            has_indices = True
            indices = EinsumTensor.split_indices(indices_kwarg)
            if index_range_set is None:
                index_range_set = IndexRange.global_index_range_set
            shape = []
            for idx in indices:
                if idx not in index_range_set.known_ranges:
                    raise IndexError("unknown index '" + idx + "'")
                shape.append(index_range_set.known_ranges[idx].size)
            shape = tuple(shape)
            if "shape" in kwargs:
                kwshape = kwargs.pop('shape')
                if shape != kwshape:
                    raise TypeError(
                        "inconsistent shape:  indices '{}' indicate a shape of {}, but"
                        " the keyword 'shape' was given with the shape {}".
                        format(",".join(indices), shape, kwshape))
            kwargs['shape'] = shape
        #--------------------------------------------------------------------------------#
        # Now create a numpy.ndarray object...
        def_val = pop_kwarg(kwargs, 'default_val', 'default_value',
                            'default') or 0.0
        # Set the default data type to float, unless the user specifies
        dtype = get_kwarg(kwargs, 'dtype') or float
        if not callable(dtype) and grendel.show_warnings:
            warn("dtype given to {0} constructor is not Callable and thus cannot be used for casting." \
                 "  It is better to use callable types for dtype if possible; e.g. numpy.float64 instead" \
                 "of numpy.dtype('float64')".format(classname(cls)))
        kwargs['dtype'] = dtype
        # Typecast the default value
        if callable(dtype):
            def_val = dtype(def_val)
        # See if we have a shape...
        shape = pop_kwarg(kwargs, 'shape', 'dimension')
        # See if we have data...
        # This allows us to support the form Tensor(1, 2, 3, 4)
        if len(args) == 1 and isinstance(args[0], np.ndarray):
            data = args[0]
        else:
            data = listify_args(*args)
        if 'data' in kwargs:
            if data:
                raise TypeError("`data` may be specified as a keyword argument or as " \
                                "the regular arguments to {0} constructor, but not both.".format(classname(cls)))
            else:
                data = pop_kwarg('data')
        if shape and not isinstance(data, np.ndarray):
            has_content = False
            if len(args) != 0:
                has_content = True
            if not has_content:
                if def_val == 0.0:
                    try:
                        ret_val = np.zeros(shape=shape, **kwargs)
                    except:
                        raise
                else:
                    ret_val = (np.ones(shape=shape, **kwargs) * def_val)
            else:
                if grendel.sanity_checking_enabled:
                    # Check data length
                    tmp = np.array(data)
                    needed_data_size = 1
                    for dim in shape:
                        needed_data_size *= dim
                    try:
                        tmp.reshape((needed_data_size, ))
                    except ValueError:
                        raise ValueError(
                            "Data provided to {0} constructor is incompatible with the shape {1}"
                            .format(classname(cls), shape))
                    # Check data type
                ret_val = np.array(data, **kwargs).reshape(shape)
        else:
            # Just pass on the data and any surviving kwargs
            try:
                if isinstance(data, np.ndarray) and (
                        len(kwargs) == 0 or
                    (len(kwargs) == 1 and 'dtype' in kwargs
                     and kwargs['dtype'] == data.dtype)):
                    # Just do a view
                    ret_val = data.view(cls)
                else:
                    # Otherwise, we need to call the numpy "constructor" (actually a factory function) of ndarray
                    ret_val = np.array(data, **kwargs)
            except:
                # debugging breakpoint hook
                raise
            if shape and ret_val.shape != shape:
                raise ValueError(
                    "Shape mismatch: data shape {0} does not match specified shape {1}"
                    .format(data.shape, shape))
        #--------------------------------------------------------------------------------#
        # View-cast the ret_val to the class in question, but only if we haven't already
        if not isinstance(ret_val, cls):
            ret_val = ret_val.view(cls)
        # Now assign stuff from any special args...
        if has_indices:
            ret_val.indices = indices
            ret_val.index_range_set = index_range_set
        else:
            ret_val.indices = None
        ret_val.units = units
        ret_val.name = name
        if name is None:
            ret_val.name = "(unnamed tensor)"
        # pass the remaining kwargs to the initializer...
        ret_val.__tensor_init__(**subclass_kwargs)
        return ret_val
Exemple #4
0
import os
import subprocess

from grendel.util.descriptors import RaiseOnAccessDescriptor
from grendel.util.overloading import get_kwarg
from grendel.util import SystemInfo

# OS check... currently only 'posix' is supported
if not os.name == 'posix':
    raise OSError("Q-Chem interface is currently only available on posix-like systems. "
                  " This system returns '" + os.name + "' for the Python expression 'os.name'")

SystemInfo.qchem_executable = get_kwarg(os.environ, 'QCHEM_EXECUTABLE', 'QCHEM_EXE', 'QCHEM')
if not SystemInfo.qchem_executable:
    try:
        # try to find Q-Chem using `which`, which should be always available on posix systems
        # the last part strips the newline from the output
        SystemInfo.qchem_executable = subprocess.check_output(["which", 'qchem'])[:-1]
        if not os.access(SystemInfo.qchem_executable, os.X_OK):
            SystemInfo.qchem_executable = RaiseOnAccessDescriptor(SystemError,
                'Q-Chem executable at {0} is not an executable file.  Check the contents of the '
                'QCHEM_EXECUTABLE environment variable (or, if it is not defined, check the '
                'QCHEM_EXE or QCHEM environment variables.)'.format(SystemInfo.qchem_executable))
    except subprocess.CalledProcessError:
        SystemInfo.qchem_executable = RaiseOnAccessDescriptor(SystemError,
            'Q-Chem executable not found.  Try a different interface or set the QCHEM_EXECUTABLE '
            'environment variable to the location of the executable.  (Equivalently, you can set'
            ' either of the QCHEM or QCHEM_EXE environment variables.')

# Check that the Q-Chem executable is in fact executable:
Exemple #5
0
import os
import subprocess

from grendel.util.descriptors import RaiseOnAccessDescriptor
from grendel.util.overloading import get_kwarg
from grendel.util import SystemInfo

# OS check... currently only 'posix' is supported
if not os.name == 'posix':
    raise OSError(
        "Q-Chem interface is currently only available on posix-like systems. "
        " This system returns '" + os.name +
        "' for the Python expression 'os.name'")

SystemInfo.qchem_executable = get_kwarg(os.environ, 'QCHEM_EXECUTABLE',
                                        'QCHEM_EXE', 'QCHEM')
if not SystemInfo.qchem_executable:
    try:
        # try to find Q-Chem using `which`, which should be always available on posix systems
        # the last part strips the newline from the output
        SystemInfo.qchem_executable = subprocess.check_output(
            ["which", 'qchem'])[:-1]
        if not os.access(SystemInfo.qchem_executable, os.X_OK):
            SystemInfo.qchem_executable = RaiseOnAccessDescriptor(
                SystemError,
                'Q-Chem executable at {0} is not an executable file.  Check the contents of the '
                'QCHEM_EXECUTABLE environment variable (or, if it is not defined, check the '
                'QCHEM_EXE or QCHEM environment variables.)'.format(
                    SystemInfo.qchem_executable))
    except subprocess.CalledProcessError:
        SystemInfo.qchem_executable = RaiseOnAccessDescriptor(