domain.py 2.97 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12
# 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 <http://www.gnu.org/licenses/>.
Theo Steininger's avatar
Theo Steininger committed
13
#
Martin Reinecke's avatar
Martin Reinecke committed
14
# Copyright(C) 2013-2018 Max-Planck-Society
Theo Steininger's avatar
Theo Steininger committed
15 16 17
#
# NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik
# and financially supported by the Studienstiftung des deutschen Volkes.
18 19

import abc
Martin Reinecke's avatar
Martin Reinecke committed
20
from ..utilities import NiftyMetaBase
21 22


Martin Reinecke's avatar
Martin Reinecke committed
23
class Domain(NiftyMetaBase()):
Martin Reinecke's avatar
Martin Reinecke committed
24
    """The abstract class repesenting a (structured or unstructured) domain.
25
    """
Martin Reinecke's avatar
step 1  
Martin Reinecke committed
26 27
    def __init__(self):
        self._hash = None
28

29 30 31 32
    @abc.abstractmethod
    def __repr__(self):
        raise NotImplementedError

33
    def __hash__(self):
Martin Reinecke's avatar
Martin Reinecke committed
34 35 36 37
        """Returns a hash value for the object.

        Notes
        -----
Martin Reinecke's avatar
Martin Reinecke committed
38 39
        Only members that are explicitly added to
        :attr:`._needed_for_hash` will be used for hashing.
Martin Reinecke's avatar
Martin Reinecke committed
40
        """
Martin Reinecke's avatar
step 1  
Martin Reinecke committed
41 42 43 44 45 46
        if self._hash is None:
            h = 0
            for key in self._needed_for_hash:
                h ^= hash(vars(self)[key])
            self._hash = h
        return self._hash
47 48

    def __eq__(self, x):
Martin Reinecke's avatar
Martin Reinecke committed
49
        """Checks whether two domains are equal.
Theo Steininger's avatar
Theo Steininger committed
50

51 52
        Parameters
        ----------
Martin Reinecke's avatar
Martin Reinecke committed
53
        x : Domain
Martin Reinecke's avatar
Martin Reinecke committed
54
            The domain `self` is compared to.
Theo Steininger's avatar
Theo Steininger committed
55

56 57
        Returns
        -------
Martin Reinecke's avatar
Martin Reinecke committed
58
        bool : True iff `self` and x describe the same domain.
Martin Reinecke's avatar
Martin Reinecke committed
59 60 61 62

        Notes
        -----
        Only members that are explicitly added to
Martin Reinecke's avatar
Martin Reinecke committed
63
        :attr:`._needed_for_hash` will be used for comparison.
Martin Reinecke's avatar
Martin Reinecke committed
64 65 66 67

        Subclasses of Domain should not re-define :meth:`__eq__`,
        :meth:`__ne__`, or :meth:`__hash__`; they should instead add their
        relevant attributes' names to :attr:`._needed_for_hash`.
68
        """
Martin Reinecke's avatar
Martin Reinecke committed
69 70
        if self is x:  # shortcut for simple case
            return True
Martin Reinecke's avatar
Martin Reinecke committed
71
        if not isinstance(x, type(self)):
72
            return False
73 74 75
        for key in self._needed_for_hash:
            if vars(self)[key] != vars(x)[key]:
                return False
Martin Reinecke's avatar
Martin Reinecke committed
76
        return True
77 78

    def __ne__(self, x):
Martin Reinecke's avatar
Martin Reinecke committed
79
        """Returns the opposite of :meth:`.__eq__()`"""
80 81 82 83
        return not self.__eq__(x)

    @abc.abstractproperty
    def shape(self):
Martin Reinecke's avatar
Martin Reinecke committed
84
        """tuple of int: number of pixels along each axis
Theo Steininger's avatar
Theo Steininger committed
85

Martin Reinecke's avatar
Martin Reinecke committed
86 87
        The shape of the array-like object required to store information
        living on the domain.
88
        """
Martin Reinecke's avatar
Martin Reinecke committed
89
        raise NotImplementedError
90 91

    @abc.abstractproperty
Martin Reinecke's avatar
Martin Reinecke committed
92
    def size(self):
Martin Reinecke's avatar
Martin Reinecke committed
93
        """int: total number of pixels.
94

Martin Reinecke's avatar
Martin Reinecke committed
95
        Equivalent to the products over all entries in the domain's shape.
96
        """
Martin Reinecke's avatar
Martin Reinecke committed
97
        raise NotImplementedError