IOutputVariable.py 4.08 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
#MDANSE : Molecular Dynamics Analysis for Neutron Scattering Experiments
#------------------------------------------------------------------------------------------
#Copyright (C)
#2015- Eric C. Pellegrini Institut Laue-Langevin
#BP 156
#6, rue Jules Horowitz
#38042 Grenoble Cedex 9
#France
#pellegrini[at]ill.fr
#goret[at]ill.fr
#aoun[at]ill.fr
#
#This library is free software; you can redistribute it and/or
#modify it under the terms of the GNU Lesser General Public
#License as published by the Free Software Foundation; either
#version 2.1 of the License, or (at your option) any later version.
#
#This library 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
#Lesser General Public License for more details.
#
#You should have received a copy of the GNU Lesser General Public
#License along with this library; if not, write to the Free Software
#Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

''' 
Created on Mar 27, 2015

30
:author: Eric C. Pellegrini
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
'''

import collections

import numpy

from MDANSE import REGISTRY
from MDANSE.Core.Error import Error

class OutputVariableError(Error):
    pass

class OutputData(collections.OrderedDict):
    
    def add(self, dataName, dataType, data, **kwargs):
46 47
                
        collections.OrderedDict.__setitem__(self,dataName,REGISTRY["output_variable"][dataType](data, dataName, **kwargs))
48 49 50 51 52 53 54 55
    
    def write(self, basename, formats, header=None):
        
        for fmt in formats:  
            REGISTRY["format"][fmt].write(basename, self, header)

class IOutputVariable(numpy.ndarray):
    '''
56
    Defines a MDANSE output variable.
57
    
58 59
    A MDANSE output variable is defined as s subclass of Numpy array that stores additional attributes.
    Those extra attributes will be contain information necessary for the the MDANSE plotter. 
60 61
    '''
    
62
    _registry = "output_variable"
63
        
64
    def __new__(cls, value, name, axis='index', units="unitless"):
65
        '''
66
        Instanciate a new MDANSE output variable.
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
                
        @param cls: the class to instantiate.
        @type cls: an OutputVariable object
        
        @param name: the name of the output variable.
        @type name: string
        
        @param value: the input numpy array.
        @type value: numpy array
        
        @note: This is the standard implementation for subclassing a numpy array.
        Please look at http://docs.scipy.org/doc/numpy/user/basics.subclassing.html for more information.
        '''
        
        if isinstance(value, tuple):
82 83 84
            value = numpy.zeros(value, dtype=numpy.float64)
        else:        
            value = numpy.array(value, dtype=numpy.float64)
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
            
        if value.ndim != cls._nDimensions:
            raise OutputVariableError("Invalid number of dimensions for an output variable of type %r" % cls.name)

        # Input array is an already formed ndarray instance
        # We first cast to be our class type
        obj = numpy.asarray(value).view(cls)
                                                        
        # The name of the output variable.               
        obj.name = name
                        
        obj.units = units

        obj.axis = axis
                                                        
        return obj
                
    def __array_finalize__(self, obj):
        
        if obj is None:
            return
                
        self.name = getattr(obj, 'name', None)
    
        self.axis = getattr(obj, 'axis',())

        self.units = getattr(obj, 'units','unitless')

    def __array_wrap__(self, out_arr, context=None):

        return numpy.ndarray.__array_wrap__(self, out_arr, context)
        
    def info(self):
        
        info = []

        info.append("# variable name: %s"  % self.name)
122
        info.append("# \ttype: %s"  % self._type)
123 124 125 126 127 128
        info.append("# \taxis: %s" % str(self.axis))
        info.append("# \tunits: %s" % self.units)
        
        info = "\n".join(info)
        
        return info