import numpy as np
from ..conesFunctions import cones_open_netcdf_dataset
[docs]
class conesStaticObservation():
"""
A class representing a single static (fixed position) observation, backed
by an observation netCDF file
"""
def __init__(self):
self.type = str()
self.file = str()
self.id = int()
self.coordinates = np.zeros(3)
self.var_list = str()
self.localCell = list()
self.globalCell = list()
self.ranks = list()
self.time = float()
self.current_time_idx = int()
[docs]
def set_id(self, id_obs):
"""
Set the observation id, used to index it in the netCDF file
:param id_obs: The observation id
:type id_obs: int
:returns: None
"""
self.id = id_obs
return
[docs]
def set_file(self, file_path):
"""
Set the path to the observation netCDF file
:param file_path: The observation netCDF file path"
:type file_path: str
:returns: None
"""
self.file = file_path
return
[docs]
def get_coordinates_from_netcdf(self):
"""
Read and set the observation's (x, y, z) coordinates from the netCDF file
:returns: None
"""
ds = cones_open_netcdf_dataset(self.file)
x = ds.x.values[self.id]
y = ds.y.values[self.id]
z = ds.z.values[self.id]
self.coordinates = np.array([x, y, z])
return
[docs]
def get_vars_from_netcdf(self, obsVar):
"""
Read the requested observed variables (and their standard deviation)
at this observation's id and time series, and set them as attributes
:param obsVar: The list of variable names to read
:type obsvar: list
:returns: None
"""
ds = cones_open_netcdf_dataset(self.file)
self.var_list = []
for var_name in ds.data_vars:
if var_name in obsVar:
setattr(self, var_name, ds[var_name].isel(obs=self.id).values)
setattr(self, var_name+"_std", ds[var_name+"_std"].isel(obs=self.id).values)
self.var_list.append(var_name)
self.var_list.append(var_name+"_std")
return
[docs]
def get_time_from_netcdf(self):
"""
Read and set the observation's time series from the netCDF file
:returns: None
"""
ds = cones_open_netcdf_dataset(self.file)
self.time = ds['time'].values.astype('float64')
return
[docs]
def set_ranks(self, obs_ids):
"""
Set the list of ranks holding a cell for this observation
(In case of not identical decomposition)
:param obs_ids: list, per rank, of observation ids held by that rank
:type obs_ids: list
:returns: None
"""
self.ranks = [j for j, sub in enumerate(obs_ids) if self.id in sub]
return
[docs]
def set_local_cell(self, cell_obs, obs_ids):
"""
Set the observations's local cell id on each of its owning ranks
:param cell_obs: list, per rank, of local cell ids for the observations held by that rank
:type cell_obs: list
:param obs_ids: list, per rank, of observation ids held by that rank
:type obs_ids: list
:returns: None
"""
for j in self.ranks:
self.localCell.append(cell_obs[j][obs_ids[j].index(self.id)])
return
[docs]
def set_global_cell(self, cell_obs, obs_ids):
"""
Set the observation's global cell id on each of its owning ranks
:param cell_obs: list, per rank, of global cell ids for the observations held by that rank
:type cell_obs: list
:param obs_ids: list, per rank, of observation ids held by that rank
:type obs_ids: list
:returns: None
"""
for j in self.ranks:
self.globalCell.append(cell_obs[j][obs_ids[j].index(self.id)])
return
[docs]
def set_current_time_index(self, time):
"""
Set the index of this observation's time series closest to 'time'
:param time: The current simulation time
:type time: float
:returns: None
"""
idx = np.abs(self.time - time).argmin()
self.current_time_idx = idx
return
[docs]
def report(self):
print("=========================")
print("Observation id:", self.id)
print("Coordinates", self.coordinates)
print("Rank", self.ranks)
# print("Time", self.time)
# for var in self.var_list:
# print(var, "=", getattr(self, var))
print("Local cell ID", self.localCell)
print("Global cell ID", self.globalCell)
print("=========================")