[docs]classRiverNetwork:""" A class representing a river network for hydrological processing. Attributes ---------- n_nodes : int The number of nodes in the river network. n_edges : int The number of nodes in the river network. sinks : array-like Nodes with no downstream connections. sources : array-like Nodes with no upstream connections. bifurcates : bool Whether the river network has bifurcations. shape : tuple The size of the river network grid. None if the network is vector-based. mask : array-like Flattened 1D indices on the raster grid corresponding to river network nodes. array_backend : str The array backend of the river network. device : str The device of the river network. return_type : str The default return type of the river network. Either "gridded" or "masked". """def__init__(self,river_network_storage:RiverNetworkStorage):self._storage=river_network_storageself.n_nodes=self._storage.n_nodesself.n_edges=self._storage.n_edgesself.sources=self._storage.sourcesself.sinks=self._storage.sinksself.bifurcates=self._storage.bifurcatesself.edge_weights=self._storage.edge_weightsself.mask=self._storage.maskself.shape=self._storage.shapeself.array_backend="numpy"self.device="cpu"self.return_type="gridded"self.coords=self._storage.coordsself.data=[self._storage.sorted_data]self.groups=np.split(self._storage.sorted_data,self._storage.splits,axis=1)def__str__(self):returnf"RiverNetwork with {self.n_nodes} nodes and {self.n_edges} edges."def__repr__(self):returnself.__str__()
[docs]defto_device(self,device=None,array_backend=None):""" Change the RiverNetwork's array backend and/or move it to a different device. Parameters ---------- device : str, optional The device to which to transfer. Default is None, which is `'cpu'` for all backends except cupy, which is `'gpu'`. array_backend : str, optional The array backend. One of "numpy", "np", "cupy", "cp", "pytorch", "torch", "jax", "jnp", "tensorflow" or "tf". Default is None, which uses `self.array_backend`. Returns ------- RiverNetwork The modified RiverNetwork. """# TODO: use xp.asarrayifarray_backend=="np":array_backend="numpy"elifarray_backend=="cp":array_backend="cupy"elifarray_backend=="jnp":array_backend="jax"elifarray_backend=="tf":array_backend="tensorflow"elifarray_backend=="pytorch":array_backend="torch"ifdeviceisNone:device="cpu"ifarray_backend!="cupy"else"gpu"ifarray_backendisNone:ifself.array_backend=="numpy"anddevicein["gpu","cuda"]:array_backend="cupy"else:array_backend=self.array_backendifarray_backendin["torch","cupy","numpy"]:self.groups=[to_device(group,device,array_backend=array_backend)forgroupinself.groups]self.mask=to_device(self.mask,device,array_backend=array_backend)self.data=[to_device(self.data[0],device,array_backend=array_backend)]elifarray_backend=="jax":assertdevice=="cpu"importjax.numpyasjnpself.groups=[jnp.array(x)forxinself.groups]self.mask=jnp.array(self.mask)self.data=[jnp.array(self.data[0])]elifarray_backend=="tensorflow":assertdevice=="cpu"importtensorflowastfself.groups=[tf.convert_to_tensor(x,dtype=tf.int32)forxinself.groups]self.mask=tf.convert_to_tensor(self.mask,dtype=tf.int32)self.data=[tf.convert_to_tensor(self.data[0],dtype=tf.int32)]else:raiseNotImplementedErrorself.array_backend=array_backendself.device=devicereturnself
[docs]defset_default_return_type(self,return_type):""" Set the default return type for the river network. Parameters ---------- return_type : str The default return_type to use. Returns ------- None """ifreturn_typenotin["gridded","masked"]:raiseValueError(f'Invalid return_type {return_type}. Valid types are "gridded", "masked"')self.return_type=return_type
[docs]defexport(self,fpath="river_network.joblib",compression=1):""" Save the river network to a local file. Parameters ---------- fpath : str, optional The filepath specifying where to save the RiverNetwork. Default is `'river_network.joblib'`. compression : str, optional The compression factor used for saving. Default is 1. Returns ------- None """importjoblibjoblib.dump(self._storage,fpath,compress=compression)