"""Defines a class for internally representing arrays used in equilibrium calculations"""importnumpyasnpfromxarrayimportDataset
[docs]classLightDataset:""" Lightweight wrapper around an xarray Dataset. Attributes ---------- data_vars : dict coords : dict attrs : dict Notes ----- The idea of LightDataset is to provide the same constructor API as Dataset objects, but doesn't provide any `sel` or other functionality. Calls to getitem or getattr to get a DataArray from xarray Datasets can take ~1ms or more, which is problematic when the equilibrium solver operates on the order of a few tens of ms and xarray Datasets are in the core loop. This class provides a similar getattr API to accessing data variables and "wraps" xarray Datasets in the sense that any LightDataset can be converted to an xarray Dataset by the getdataset method. """def__init__(self,data_vars=None,coords=None,attrs=None):""" Parameters ---------- data_vars : Dictionary of {Variable: (Dimensions, Values)} coords : Mapping of {Dimension: Values} attrs : Returns ------- LightDataset Notes ----- Takes on same format as xarray.Dataset initializer """self.data_vars=data_varsordict()self.coords=coordsordict()self.attrs=attrsordict()forvar,(coord,values)indata_vars.items():setattr(self,var,values)forcoord,valuesincoords.items():setattr(self,coord,values)
[docs]defget_dataset(self):"""Build an xarray Dataset"""returnDataset(self.data_vars,self.coords,self.attrs)
def__getitem__(self,item):try:returngetattr(self,item)except:raiseKeyError("`{}` is not a variable or coordinate".format(item))
[docs]defmerge(self,other,inplace=False,compat='no_conflicts'):ifcompat!='equals':raiseValueError("Only `compat='equals'` is supported. Passed `compat={}`".format(compat))ifinplace:forvar,coords_valsinother.data_vars.items():ifvarnotinself.data_vars.keys():self.data_vars[var]=coords_valssetattr(self,var,coords_vals[1])else:ifnp.all(self.data_vars[var]!=coords_vals):raiseValueError("Cannot merge EquilibriumResults because data variable `{}` is not equal to preexisting variable".format(var))forcoord,valuesinother.coords.items():ifcoordnotinself.coords.keys():self.coords[var]=valuessetattr(self,coord,values)else:ifnp.all(self.coords[coord]!=values):raiseValueError("Cannot merge EquilibriumResults because coordinate `{}` is not equal to preexisting coordinate".format(coord))else:raiseNotImplementedError("Copy merges not implemented")returnself