import numpy as np
from .conesRegion import conesRegion
[docs]
class conesMFRegion(conesRegion):
"""
Extends conesRegion with the two extra data sources needed by Multi-Fidelity EnKF:
the control ensemble and the ancillary ensemble, both already projected onto the principal (fine) mesh
"""
def __init__(self):
"""
Initialize the conesMFRegion class
"""
super().__init__()
self.stateControlProj = np.empty((0, 0), dtype='float')
self.paramControlProj = np.empty((0, 0), dtype='float')
self.samplingControlProj = np.empty((0, 0), dtype='float')
self.stateNvarControlProj = int()
self.stateAncillaryProj = np.empty((0, 0), dtype='float')
self.paramAncillaryProj = np.empty((0, 0), dtype='float')
self.samplingAncillaryProj = np.empty((0, 0), dtype='float')
self.stateNvarAncillaryProj = int()
[docs]
def setStateControlProj(self, state):
"""
Set the control-projected state directly
:param state: Control-projected state array
:type state: numpy ndarray
:returns: None
"""
self.stateControlProj = state
return
[docs]
def setParamsControlProj(self, params):
"""
Set the control-projected parameters directly
:param params: Control-projected parameters array
:type params: numpy ndarray
:returns: None
"""
self.paramControlProj = params
return
[docs]
def filterStateControlProj(self, state_control_proj, stateCells):
"""
From the global control-projected state matrix, extract the rows
belonging to this region's cells
:param state_control_proj: list of 1-D arrays (one per state variable), each spanning all coarse cells
:type state_control_proj: list of numpy ndarray
:param stateCells: nested list [proc][cell_id] of global cell ids for the coarse mesh
:type stateCells: list of list of int
:returns: None
"""
regionCells = [x for xs in self.globalCells for x in xs]
stateCells = [x for xs in stateCells for x in xs]
idx = [i for i, cell in enumerate(stateCells) if cell in regionCells]
self.stateControlProj = np.zeros((state_control_proj.shape[0], len(idx), state_control_proj[0].shape[1]))
stateNvar = 0
for ii, var in enumerate(state_control_proj):
self.stateControlProj[ii] = var[idx]
stateNvar = ii
self.stateNvarControlProj = stateNvar + 1
self.stateControlProj = np.vstack(self.stateControlProj)
return
[docs]
def filterSamplingControlProj(self, sampling_control_proj, sampling_order):
"""
From the global control-projected sampling matrix, exctract and
reorder the values belonging to this region's observations
:param sampling_control_proj: The raw control-projected sampling matrix gathered
:type sampling_control_proj: numpy ndarray
:param sampling_order: A list of observation id ordered by gather
:type sampling_order: list
:returns: None
"""
n_obs = len(self.obsList)
n_var = sum(1 for s in self.obsList[0].var_list if not s.endswith("_std"))
filtered_sampling = np.zeros((n_obs * n_var, sampling_control_proj.shape[1]))
global_order_map = {obs_id: i for i, obs_id in enumerate(sampling_order)}
for i_local, obs in enumerate(self.obsList):
i_global = global_order_map[obs.id]
filtered_sampling[i_local*n_var:(i_local+1)*n_var, :] = \
sampling_control_proj[i_global*n_var:(i_global+1)*n_var, :]
self.samplingControlProj = filtered_sampling
return
# -- Ancillary: identical logic, separate storage --
[docs]
def setStateAncillaryProj(self, state):
"""
Set the ancillary-projected state directly
:param state: Ancillary-projected state array
:type state: numpy ndarray
:returns: None
"""
self.stateAncillaryProj = state
return
[docs]
def setParamsAncillaryProj(self, params):
"""
Set the ancillary-projected parameters directly
:param params: Ancillary-projected parameters array
:type params: numpy ndarray
:returns: None
"""
self.paramAncillaryProj = params
return
[docs]
def filterStateAncillaryProj(self, state_ancillary_proj, stateCells):
"""
From the global ancillary-projected state matrix, extract the rows
belonging to this region's cells
:param state_ancillary_proj: list of 1-D arrays (one per state variable), each spanning all coarse cells
:type state_ancillary_proj: list of numpy ndarray
:param stateCells: nested list [proc][cell_id] of global cell ids for the coarse mesh
:type stateCells: list of list of int
:returns: None
"""
regionCells = [x for xs in self.globalCells for x in xs]
stateCells = [x for xs in stateCells for x in xs]
idx = [i for i, cell in enumerate(stateCells) if cell in regionCells]
self.stateAncillaryProj = np.zeros((state_ancillary_proj.shape[0], len(idx), state_ancillary_proj[0].shape[1]))
stateNvar = 0
for ii, var in enumerate(state_ancillary_proj):
self.stateAncillaryProj[ii] = var[idx]
stateNvar = ii
self.stateNvarAncillaryProj = stateNvar + 1
self.stateAncillaryProj = np.vstack(self.stateAncillaryProj)
return
[docs]
def filterSamplingAncillaryProj(self, sampling_ancillary_proj, sampling_order):
"""
From the global ancillary-projected sampling matrix, extract and
reorder the values belonging to this region's observations
:param sampling_ancillary_proj: The raw ancillary-projected sampling matrix gathered
:type sampling_ancillary_proj: numpy ndarray
:param sampling_order: A list of observation id ordered by gather
:type sampling_order: list
:returns: None
"""
n_obs = len(self.obsList)
n_var = sum(1 for s in self.obsList[0].var_list if not s.endswith("_std"))
filtered_sampling = np.zeros((n_obs * n_var, sampling_ancillary_proj.shape[1]))
global_order_map = {obs_id: i for i, obs_id in enumerate(sampling_order)}
for i_local, obs in enumerate(self.obsList):
i_global = global_order_map[obs.id]
filtered_sampling[i_local*n_var:(i_local+1)*n_var, :] = \
sampling_ancillary_proj[i_global*n_var:(i_global+1)*n_var, :]
self.samplingAncillaryProj = filtered_sampling
return
[docs]
def splitStateControlProj(self):
"""
Split the region's stacked control-projected state matrix back into
one array per state variable
:returns: List of the state arrays, one per state variable
:rtype: list
"""
return np.split(self.stateControlProj, self.stateNvarControlProj)
[docs]
def splitStateAncillaryProj(self):
"""
Split the region's stacked control-projected state matrix back into
one array per state variable
:returns: List of state arrays, one per state variable
:rtype: list
"""
return np.split(self.stateAncillaryProj, self.stateNvarAncillaryProj)