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

1""" 

2 

3This module implements **Filters**. These are functions that modify the content of a `Model`_, a `Measure`_, or spherical harmonics data. 

4 

5Filter functions can be divided into three categories : 

6 

7 - 1. Filters on `Model`_ 

8 

9 These filters take a `Model`_ object as input and return a `Model`_ object as output. 

10 

11 .. code-block:: python 

12 

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 

18 

19 - 2. Filters on `Measure`_ 

20 

21 These filters take a `Measure`_ object as input and return a `Measure`_ object as output. 

22 

23 .. code-block:: python 

24 

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 

30 

31 - 3. Filters on spherical harmonics coefficient 

32 

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. 

35 

36 .. code-block:: python 

37 

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 

49 

50 

51 If the filter cannot handle 3D arrays with realisations, the :code:`@coeffilter_norealisations` decorator should be used. 

52 

53 .. code-block:: python 

54 

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 

61 

62 This decorator will allow looping on the different realisations of the Model and calling the filter for each one. 

63 

64 

65Calling filters 

66############### 

67 

68Thanks to the decorators, all filters are called on a `Model`_ object. 

69 

70.. code-block:: python 

71 

72 from webgeodyn.filters.filename import my_filter 

73 from webgeodyn.models import Models 

74 

75 models = Models() 

76 models.loadModel("/path/to/model/data/"),"Test Model","dataFormat") 

77 my_filter(models["Test Model"]) 

78 

79 

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). 

82 

83Copying data before filtering 

84----------------------------- 

85 

86The `Model`_ can be copied before applying the filter in order to avoid rewriting the data inside the `Model`_. 

87 

88.. code-block:: python 

89 

90 newModel = my_filter(models["Test Model"],copy=True) 

91 

92 

93Applying filter to specific measures 

94------------------------------------ 

95 

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`: 

97 

98.. code-block:: python 

99 

100 my_filter(models["Test Model"],measureName=["MF","SV"]) 

101 

102This will apply the filter to measures named "MF" and "SV" 

103 

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 

106 

107Decorators 

108########## 

109 

110""" 

111 

112from webgeodyn.models import Model 

113import numpy as np 

114 

115 

116def coeffilter(coeffilter_function): 

117 """ Decorator for filters only applied to the coefficients of spherical harmonics. 

118 

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 

126 

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"],] 

134 

135 if "copy" in kwargs: 

136 del kwargs["copy"] 

137 if "measureName" in kwargs: 

138 del kwargs["measureName"] 

139 

140 for measureName in measurelist: 

141 if measureName not in model.measures: 

142 raise ValueError(measureName + " is not inside given model measures.") 

143 

144 new_coefs = coeffilter_function(returnedModel.measures[measureName].data, *args, **kwargs) 

145 returnedModel.measures[measureName].setData(new_coefs) 

146 

147 returnedModel.clearCache() 

148 return returnedModel 

149 return applyfilter 

150 

151 

152def coeffilter_norealisations(coeffilter_function): 

153 """ Decorator for coeffilters that do not handle realisations. 

154 

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 

162 

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"],] 

170 

171 if "copy" in kwargs: 

172 del kwargs["copy"] 

173 if "measureName" in kwargs: 

174 del kwargs["measureName"] 

175 

176 for measureName in measurelist: 

177 if measureName not in model.measures: 

178 raise ValueError(measureName + " is not inside given model measures.") 

179 

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) 

191 

192 returnedModel.clearCache() 

193 return returnedModel 

194 return applyfilter 

195 

196 

197def measurefilter(measurefilter_function): 

198 """ Decorator for filters only applied to measures. 

199 

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 

207 

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"],] 

215 

216 if "copy" in kwargs: 

217 del kwargs["copy"] 

218 if "measureName" in kwargs: 

219 del kwargs["measureName"] 

220 

221 for measureName in measurelist: 

222 if measureName not in model.measures: 

223 raise ValueError(measureName + " is not inside given model measures.") 

224 

225 new_measure = measurefilter_function(returnedModel.measures[measureName],*args, **kwargs) 

226 returnedModel.measures[measureName] = new_measure 

227 

228 returnedModel.clearCache() 

229 return returnedModel 

230 return applyfilter 

231 

232 

233def modelfilter(modelfilter_function): 

234 """ Decorator for filters directly applied to the model. 

235 

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 

243 

244 if "copy" in kwargs: 

245 del kwargs["copy"] 

246 

247 returnedModel = modelfilter_function(returnedModel, *args, **kwargs) 

248 

249 returnedModel.clearCache() 

250 return returnedModel 

251 return applyfilter