18
18
19
19
# Internal imports
20
20
import pipt .misc_tools .analysis_tools as at
21
+ import pipt .misc_tools .extract_tools as extract
21
22
from geostat .decomp import Cholesky # Making realizations
22
23
from pipt .misc_tools import cov_regularization
23
24
from pipt .misc_tools import wavelet_tools as wt
24
25
from misc import read_input_csv as rcsv
25
26
from misc .system_tools .environ_var import OpenBlasSingleThread # Single threaded OpenBLAS runs
26
27
27
28
29
+
28
30
class Ensemble :
29
31
"""
30
32
Class for organizing misc. variables and simulator for an ensemble-based inversion run. Here, the forecast step
@@ -56,11 +58,13 @@ def __init__(self, keys_en, sim, redund_sim=None):
56
58
self .aux_input = None
57
59
58
60
# Setup logger
59
- logging .basicConfig (level = logging .INFO ,
60
- filename = 'pet_logger.log' ,
61
- filemode = 'w' ,
62
- format = '%(asctime)s : %(levelname)s : %(name)s : %(message)s' ,
63
- datefmt = '%Y-%m-%d %H:%M:%S' )
61
+ logging .basicConfig (
62
+ level = logging .INFO ,
63
+ filename = 'pet_logger.log' ,
64
+ filemode = 'w' ,
65
+ format = '%(asctime)s : %(levelname)s : %(name)s : %(message)s' ,
66
+ datefmt = '%Y-%m-%d %H:%M:%S'
67
+ )
64
68
self .logger = logging .getLogger ('PET' )
65
69
66
70
# Check if folder contains any En_ files, and remove them!
@@ -117,7 +121,7 @@ def __init__(self, keys_en, sim, redund_sim=None):
117
121
self .disable_tqdm = False
118
122
119
123
# extract information that is given for the prior model
120
- self .prior_info = self . _extract_prior_info ( )
124
+ self .prior_info = extract . extract_prior_info ( self . keys_en )
121
125
122
126
# Calculate initial ensemble if IMPORTSTATICVAR has not been given in init. file.
123
127
# Prior info. on state variables must be given by PRIOR_<STATICVAR-name> keyword.
@@ -143,7 +147,11 @@ def __init__(self, keys_en, sim, redund_sim=None):
143
147
print ('\033 [1;33mInput states have different ensemble size\033 [1;m' )
144
148
sys .exit (1 )
145
149
self .ne = min (tmp_ne )
146
- self ._ext_ml_info ()
150
+
151
+ if 'multilevel' in self .keys_en :
152
+ ml_info = extract .extract_multilevel_info (self .keys_en )
153
+ self .multilevel , self .tot_level , self .ml_ne , self .ML_error_corr , self .error_comp_scheme , self .ML_corr_done = ml_info
154
+ #self._ext_ml_info()
147
155
148
156
def _ext_ml_info (self ):
149
157
'''
@@ -172,117 +180,7 @@ def _ext_ml_info(self):
172
180
self .error_comp_scheme = self .keys_en ['multilevel' ][i ][2 ]
173
181
self .ML_corr_done = False
174
182
175
- def _extract_prior_info (self ) -> dict :
176
- '''
177
- Extract prior information on STATE from keyword(s) PRIOR_<STATE entries>.
178
- '''
179
-
180
- # Get state names as list
181
- state_names = self .keys_en ['state' ]
182
- if not isinstance (state_names , list ): state_names = [state_names ]
183
-
184
- # Check if PRIOR_<state names> exists for each entry in state
185
- for name in state_names :
186
- assert f'prior_{ name } ' in self .keys_en , \
187
- 'PRIOR_{0} is missing! This keyword is needed to make initial ensemble for {0} entered in ' \
188
- 'STATE' .format (name .upper ())
189
-
190
- # define dict to store prior information in
191
- prior_info = {name : None for name in state_names }
192
-
193
- # loop over state priors
194
- for name in state_names :
195
- prior = self .keys_en [f'prior_{ name } ' ]
196
-
197
- # Check if is a list (old way)
198
- if isinstance (prior , list ):
199
- # list of lists - old way of inputting prior information
200
- prior_dict = {}
201
- for i , opt in enumerate (list (zip (* prior ))[0 ]):
202
- if opt == 'limits' :
203
- prior_dict [opt ] = prior [i ][1 :]
204
- else :
205
- prior_dict [opt ] = prior [i ][1 ]
206
- prior = prior_dict
207
- else :
208
- assert isinstance (prior , dict ), 'PRIOR_{0} must be a dictionary or list of lists!' .format (name .upper ())
209
-
210
-
211
- # load mean if in file
212
- if isinstance (prior ['mean' ], str ):
213
- assert prior ['mean' ].endswith ('.npz' ), 'File name does not end with \' .npz\' !'
214
- load_file = np .load (prior ['mean' ])
215
- assert len (load_file .files ) == 1 , \
216
- 'More than one variable located in {0}. Only the mean vector can be stored in the .npz file!' \
217
- .format (prior ['mean' ])
218
- prior ['mean' ] = load_file [load_file .files [0 ]]
219
- else : # Single number inputted, make it a list if not already
220
- if not isinstance (prior ['mean' ], list ):
221
- prior ['mean' ] = [prior ['mean' ]]
222
-
223
- # loop over keys in prior
224
- for key in prior .keys ():
225
- # ensure that entry is a list
226
- if (not isinstance (prior [key ], list )) and (key != 'mean' ):
227
- prior [key ] = [prior [key ]]
228
-
229
- # change the name of some keys
230
- prior ['variance' ] = prior .pop ('var' , None )
231
- prior ['corr_length' ] = prior .pop ('range' , None )
232
-
233
- # process grid
234
- if 'grid' in prior :
235
- grid_dim = prior ['grid' ]
236
-
237
- # check if 3D-grid
238
- if (len (grid_dim ) == 3 ) and (grid_dim [2 ] > 1 ):
239
- nz = int (grid_dim [2 ])
240
- prior ['nz' ] = nz
241
- prior ['nx' ] = int (grid_dim [0 ])
242
- prior ['ny' ] = int (grid_dim [1 ])
243
-
244
-
245
- # Check mean when values have been inputted directly (not when mean has been loaded)
246
- mean = prior ['mean' ]
247
- if isinstance (mean , list ) and len (mean ) < nz :
248
- # Check if it is more than one entry and give error
249
- assert len (mean ) == 1 , \
250
- 'Information from MEAN has been given for {0} layers, whereas {1} is needed!' \
251
- .format (len (mean ), nz )
252
-
253
- # Only 1 entry; copy this to all layers
254
- print (
255
- '\033 [1;33mSingle entry for MEAN will be copied to all {0} layers\033 [1;m' .format (nz ))
256
- prior ['mean' ] = mean * nz
257
-
258
- #check if info. has been given on all layers. In the case it has not been given, we just copy the info. given.
259
- for key in ['vario' , 'variance' , 'aniso' , 'angle' , 'corr_length' ]:
260
- if key in prior .keys ():
261
- val = prior [key ]
262
- if len (val ) < nz :
263
- # Check if it is more than one entry and give error
264
- assert len (val ) == 1 , \
265
- 'Information from {0} has been given for {1} layers, whereas {2} is needed!' \
266
- .format (key .upper (), len (val ), nz )
267
-
268
- # Only 1 entry; copy this to all layers
269
- print (
270
- '\033 [1;33mSingle entry for {0} will be copied to all {1} layers\033 [1;m' .format (key .upper (), nz ))
271
- prior [key ] = val * nz
272
-
273
- else :
274
- prior ['nx' ] = int (grid_dim [0 ])
275
- prior ['ny' ] = int (grid_dim [1 ])
276
- prior ['nz' ] = 1
277
-
278
- prior .pop ('grid' , None )
279
-
280
- # add prior to prior_info
281
- prior_info [name ] = prior
282
-
283
- return prior_info
284
-
285
-
183
+
286
184
def gen_init_ensemble (self ):
287
185
"""
288
186
Generate the initial ensemble of (joint) state vectors using the GeoStat class in the "geostat" package.
@@ -353,6 +251,7 @@ def gen_init_ensemble(self):
353
251
# Save the ensemble for later inspection
354
252
np .savez ('prior.npz' , ** self .state )
355
253
254
+
356
255
def get_list_assim_steps (self ):
357
256
"""
358
257
Returns list of assimilation steps. Useful in a 'loop'-script.
0 commit comments