|
1 | 1 | """Module for the Base Operation class.""" |
2 | 2 |
|
| 3 | +from copy import deepcopy |
3 | 4 | from .operation_interface import OperationInterface |
4 | 5 | from .base_domain import BaseDomain |
5 | 6 | from ..utils import check_consistency, check_positive_integer |
@@ -31,26 +32,7 @@ def __init__(self, geometries): |
31 | 32 | :raises NotImplementedError: If the dimensions of the geometries are not |
32 | 33 | consistent. |
33 | 34 | """ |
34 | | - # Check geometries are list or tuple |
35 | | - if not isinstance(geometries, (list, tuple)): |
36 | | - raise TypeError( |
37 | | - "geometries must be either a list or a tuple of BaseDomain." |
38 | | - ) |
39 | | - |
40 | | - # Check consistency |
41 | | - check_consistency(geometries, (BaseDomain, BaseOperation)) |
42 | | - |
43 | | - # Check geometries |
44 | | - for geometry in geometries: |
45 | | - if geometry.variables != geometries[0].variables: |
46 | | - raise NotImplementedError( |
47 | | - f"The {self.__class__.__name__} of geometries living in " |
48 | | - "different ambient spaces is not well-defined. " |
49 | | - "All geometries must share the same dimensions and labels." |
50 | | - ) |
51 | | - |
52 | | - # Initialization |
53 | | - self._geometries = geometries |
| 35 | + self.geometries = geometries |
54 | 36 |
|
55 | 37 | def _validate_sampling(self, n, mode, variables): |
56 | 38 | """ |
@@ -95,18 +77,40 @@ def _validate_sampling(self, n, mode, variables): |
95 | 77 |
|
96 | 78 | return sorted(variables) |
97 | 79 |
|
98 | | - def update(self, _): |
| 80 | + def update(self, domain): |
99 | 81 | """ |
100 | 82 | Update the domain resulting from the operation. |
101 | 83 |
|
102 | | - :raises NotImplementedError: The :meth:`update` method is not |
103 | | - implemented for operation domains. Please update the individual |
104 | | - domains instead. |
105 | | - """ |
106 | | - raise NotImplementedError( |
107 | | - "The update method is not implemented for operation domains. " |
108 | | - "Please update the individual domains instead." |
109 | | - ) |
| 84 | + :param DomainInterface domain: The domain whose labels are to be merged |
| 85 | + into the current one. |
| 86 | + :raises NotImplementedError: If the geometries involved in the operation |
| 87 | + are of different types. |
| 88 | + :raises TypeError: If the passed domain is not of the same type of all |
| 89 | + the geometries involved in the operation. |
| 90 | + :return: A new domain instance with the merged labels. |
| 91 | + :rtype: BaseOperation |
| 92 | + """ |
| 93 | + # Check all geometries are of the same type |
| 94 | + domain_type = type(self.geometries[0]) |
| 95 | + if not all(isinstance(g, domain_type) for g in self.geometries): |
| 96 | + raise NotImplementedError( |
| 97 | + f"The {self.__class__.__name__} of geometries of different" |
| 98 | + " types does not support the update operation. All geometries" |
| 99 | + " must be of the same type." |
| 100 | + ) |
| 101 | + |
| 102 | + # Check domain type consistency |
| 103 | + if not isinstance(domain, domain_type): |
| 104 | + raise TypeError( |
| 105 | + f"Cannot update the {self.__class__.__name__} of domains of" |
| 106 | + f" type {domain_type} with domain of type {type(domain)}." |
| 107 | + ) |
| 108 | + |
| 109 | + # Update each geometry |
| 110 | + updated = deepcopy(self) |
| 111 | + updated.geometries = [geom.update(domain) for geom in self.geometries] |
| 112 | + |
| 113 | + return updated |
110 | 114 |
|
111 | 115 | def partial(self): |
112 | 116 | """ |
@@ -167,3 +171,36 @@ def geometries(self): |
167 | 171 | :rtype: list[BaseDomain] |
168 | 172 | """ |
169 | 173 | return self._geometries |
| 174 | + |
| 175 | + @geometries.setter |
| 176 | + def geometries(self, values): |
| 177 | + """ |
| 178 | + Setter for the ``geometries`` property. |
| 179 | +
|
| 180 | + :param values: The geometries to be set. |
| 181 | + :type values: list[BaseDomain] | tuple[BaseDomain] |
| 182 | + :raises TypeError: If values is neither a list nor a tuple. |
| 183 | + :raises ValueError: If values elements are not instances of |
| 184 | + :class:`~pina.domain.base_domain.BaseDomain`. |
| 185 | + :raises NotImplementedError: If the dimensions of the geometries are not |
| 186 | + consistent. |
| 187 | + """ |
| 188 | + # Check geometries are list or tuple |
| 189 | + if not isinstance(values, (list, tuple)): |
| 190 | + raise TypeError( |
| 191 | + "geometries must be either a list or a tuple of BaseDomain." |
| 192 | + ) |
| 193 | + |
| 194 | + # Check consistency |
| 195 | + check_consistency(values, (BaseDomain, BaseOperation)) |
| 196 | + |
| 197 | + # Check geometries |
| 198 | + for v in values: |
| 199 | + if v.variables != values[0].variables: |
| 200 | + raise NotImplementedError( |
| 201 | + f"The {self.__class__.__name__} of geometries living in " |
| 202 | + "different ambient spaces is not well-defined. " |
| 203 | + "All geometries must share the same dimensions and labels." |
| 204 | + ) |
| 205 | + |
| 206 | + self._geometries = values |
0 commit comments