Coverage for webgeodyn/filters/__init__.py: 0%
87 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-12-18 09:33 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2023-12-18 09:33 +0000
1"""
3This module implements **Filters**. These are functions that modify the content of a `Model`_, a `Measure`_, or spherical harmonics data.
5Filter functions can be divided into three categories :
7 - 1. Filters on `Model`_
9 These filters take a `Model`_ object as input and return a `Model`_ object as output.
11 .. code-block:: python
13 from webgeodyn.filters import modelfilter
14 @modelfilter
15 def my_filter(model, other, optional, arguments):
16 # model is a Model object, the filter should return a Model object.
17 return modified_model
19 - 2. Filters on `Measure`_
21 These filters take a `Measure`_ object as input and return a `Measure`_ object as output.
23 .. code-block:: python
25 from webgeodyn.filters import measurefilter
26 @measurefilter
27 def my_filter(measure, other, optional, arguments):
28 # measure is a Measure object, the filter should return a Measure object.
29 return modified_measure
31 - 3. Filters on spherical harmonics coefficient
33 These filters take a 2D (resp. 3D) array as an input, and return 2D (resp. 3D) array.
34 These filters are declared using the :code:`@coeffilter` decorator.
36 .. code-block:: python
38 from webgeodyn.filters import coeffilter
39 @coeffilter
40 def my_filter(coefs, other, optional, arguments):
41 # coefs :
42 # 2D array [times, schmidtSemiNormalized spher. harm. coefs]
43 # or 3D array [times, schmidtSemiNormalized spher. harm. coefs]
44 # other, optional, arguments :
45 # arguments that can be defined to configure the filter.
46 #
47 # if coefs is 2D (resp. 3D) modified_coefs must be 2D (resp 3D.)
48 return modified_coefs
51 If the filter cannot handle 3D arrays with realisations, the :code:`@coeffilter_norealisations` decorator should be used.
53 .. code-block:: python
55 from webgeodyn.filters import coeffilter_norealisations
56 @coeffilter_norealisations
57 def my_filter(coefs, other, optional, arguments):
58 # coefs :
59 # 2D array only [times, schmidtSemiNormalized spher. harm. coefs]
60 return modified_coefs
62 This decorator will allow looping on the different realisations of the Model and calling the filter for each one.
65Calling filters
66###############
68Thanks to the decorators, all filters are called on a `Model`_ object.
70.. code-block:: python
72 from webgeodyn.filters.filename import my_filter
73 from webgeodyn.models import Models
75 models = Models()
76 models.loadModel("/path/to/model/data/"),"Test Model","dataFormat")
77 my_filter(models["Test Model"])
80.. warning::
81 The `Model`_ object is directly modified by the filter (i.e. the data is replaced) unless you specify :code:`copy=True` argument when calling the filter (see below).
83Copying data before filtering
84-----------------------------
86The `Model`_ can be copied before applying the filter in order to avoid rewriting the data inside the `Model`_.
88.. code-block:: python
90 newModel = my_filter(models["Test Model"],copy=True)
93Applying filter to specific measures
94------------------------------------
96:code:`@measurefilter` and :code:`@coeffilter` are by default applied to all measures in the Model. But it can be applied to a subset of measures by specifing :code:`measureName`:
98.. code-block:: python
100 my_filter(models["Test Model"],measureName=["MF","SV"])
102This will apply the filter to measures named "MF" and "SV"
104.. _Measure: https://geodynamo.gricad-pages.univ-grenoble-alpes.fr/webgeodyn/webgeodyn.data.html
105.. _Model: https://geodynamo.gricad-pages.univ-grenoble-alpes.fr/webgeodyn/webgeodyn.models.model.html#webgeodyn.models.model.Model
107Decorators
108##########
110"""
112from webgeodyn.models import Model
113import numpy as np
116def coeffilter(coeffilter_function):
117 """ Decorator for filters only applied to the coefficients of spherical harmonics.
119 The functions decorated by this decorator take coefs as the first parameter and return filtered coefs.
120 """
121 def applyfilter(model, *args, **kwargs):
122 if "copy" in kwargs and kwargs["copy"]:
123 returnedModel = model.copy()
124 else:
125 returnedModel = model
127 if "measureName" not in kwargs or kwargs["measureName"] is None:
128 # Filter is called on the whole model, applying the filter to all measures
129 measurelist = model.measures.keys()
130 elif type(kwargs["measureName"]) == list:
131 measurelist = kwargs["measureName"]
132 else:
133 measurelist = [kwargs["measureName"],]
135 if "copy" in kwargs:
136 del kwargs["copy"]
137 if "measureName" in kwargs:
138 del kwargs["measureName"]
140 for measureName in measurelist:
141 if measureName not in model.measures:
142 raise ValueError(measureName + " is not inside given model measures.")
144 new_coefs = coeffilter_function(returnedModel.measures[measureName].data, *args, **kwargs)
145 returnedModel.measures[measureName].setData(new_coefs)
147 returnedModel.clearCache()
148 return returnedModel
149 return applyfilter
152def coeffilter_norealisations(coeffilter_function):
153 """ Decorator for coeffilters that do not handle realisations.
155 The functions decorated by this decorator take coefs as the first parameter and return filtered coefs.
156 """
157 def applyfilter(model, *args, **kwargs):
158 if "copy" in kwargs and kwargs["copy"]:
159 returnedModel = model.copy()
160 else:
161 returnedModel = model
163 if "measureName" not in kwargs or kwargs["measureName"] is None:
164 # Filter is called on the whole model, applying the filter to all measures
165 measurelist = model.measures.keys()
166 elif type(kwargs["measureName"]) == list:
167 measurelist = kwargs["measureName"]
168 else:
169 measurelist = [kwargs["measureName"],]
171 if "copy" in kwargs:
172 del kwargs["copy"]
173 if "measureName" in kwargs:
174 del kwargs["measureName"]
176 for measureName in measurelist:
177 if measureName not in model.measures:
178 raise ValueError(measureName + " is not inside given model measures.")
180 if returnedModel.measures[measureName].has_realisations:
181 new_coefs = None
182 nreal = returnedModel.measures[measureName].data.shape[2]
183 for ireal in range(nreal):
184 new_realisation = coeffilter_function(returnedModel.measures[measureName].data[:,:,ireal],*args)
185 if new_coefs is None:
186 new_coefs = np.zeros((new_realisation.shape[0],new_realisation.shape[1],nreal))
187 new_coefs[:,:,ireal] = new_realisation
188 else:
189 new_coefs = coeffilter_function(returnedModel.measures[measureName].data,*args, **kwargs)
190 returnedModel.measures[measureName].setData(new_coefs)
192 returnedModel.clearCache()
193 return returnedModel
194 return applyfilter
197def measurefilter(measurefilter_function):
198 """ Decorator for filters only applied to measures.
200 The functions decorated by this decorator take measures as the first parameter and return the filtered measures.
201 """
202 def applyfilter(model, *args, **kwargs):
203 if "copy" in kwargs and kwargs["copy"]:
204 returnedModel = model.copy()
205 else:
206 returnedModel = model
208 if "measureName" not in kwargs or kwargs["measureName"] is None:
209 # Filter is called on the whole model, applying the filter to all measures
210 measurelist = model.measures.keys()
211 elif type(kwargs["measureName"]) == list:
212 measurelist = kwargs["measureName"]
213 else:
214 measurelist = [kwargs["measureName"],]
216 if "copy" in kwargs:
217 del kwargs["copy"]
218 if "measureName" in kwargs:
219 del kwargs["measureName"]
221 for measureName in measurelist:
222 if measureName not in model.measures:
223 raise ValueError(measureName + " is not inside given model measures.")
225 new_measure = measurefilter_function(returnedModel.measures[measureName],*args, **kwargs)
226 returnedModel.measures[measureName] = new_measure
228 returnedModel.clearCache()
229 return returnedModel
230 return applyfilter
233def modelfilter(modelfilter_function):
234 """ Decorator for filters directly applied to the model.
236 The functions decorated by this decorator take the model as first parameter and return the filtered model.
237 """
238 def applyfilter(model, *args, **kwargs):
239 if "copy" in kwargs and kwargs["copy"]:
240 returnedModel = model.copy()
241 else:
242 returnedModel = model
244 if "copy" in kwargs:
245 del kwargs["copy"]
247 returnedModel = modelfilter_function(returnedModel, *args, **kwargs)
249 returnedModel.clearCache()
250 return returnedModel
251 return applyfilter