def setupDfs0(): global shePath global dfs global dfsDataX global dfsDataY global nX global nY global nZ import clr global simStart global simStart now = MShePy.wm.currentTime() clr.AddReference("DHI.Mike.Install, Version=1.0.0.0, Culture=neutral, PublicKeyToken=c513450b5d0bf0bf") # "fully qualified" name required! from DHI.Mike.Install import MikeImport, MikeProducts MikeImport.SetupLatest() clr.AddReference("DHI.Generic.MikeZero.DFS") clr.AddReference("DHI.Generic.MikeZero.EUM") clr.AddReference("System") import System from System import Array from DHI.Generic.MikeZero import eumUnit, eumItem, eumQuantity from DHI.Generic.MikeZero.DFS import DfsFactory, DfsBuilder, DfsSimpleType, DataValueType shePath = MShePy.wm.getSheFilePath() sheDir = os.path.dirname(shePath) filename = os.path.join(sheDir, 'BndFluxes.dfs2') builder = DfsBuilder.Create(filename, "MSHE SZ boundary fluxes output per layer", 0) builder.SetDataType(1) factory = DfsFactory() builder.SetGeographicalProjection(factory.CreateProjectionGeoOrigin("NON-UTM", 0, 0, 0)) simStart = now nowSys = System.DateTime(now.year, now.month, now.day, now.hour, now.minute, now.second) # note: time unit given here has to be used in WriteItemTimeStepNext axis = factory.CreateTemporalNonEqCalendarAxis(eumUnit.eumUsec, nowSys) builder.SetTemporalAxis(axis) builder.DeleteValueFloat = -1e-30 (startTime, endTime, values) = MShePy.wm.getValues(MShePy.paramTypes.SZ_X_FLO) # just for the geometry (nX, nY, nZ) = values.shape() (x0, y0) = MShePy.wm.gridCellToCoord(0, 0) (x1, y1) = MShePy.wm.gridCellToCoord(1, 1) dfsDataX = Array.CreateInstance(System.Single, nX * nY) dfsDataY = Array.CreateInstance(System.Single, nX * nY) for x in range(nX): for y in range(nY): if(not MShePy.wm.gridIsInModel(x, y)): dfsDataX[x + y * nX] = builder.DeleteValueFloat dfsDataY[x + y * nX] = builder.DeleteValueFloat dx = x1 - x0 # cell size, dx == dy axis = factory.CreateAxisEqD2(eumUnit.eumUmeter, nX, x0 - dx / 2, dx, nY, y0 - dx / 2, dx) itemBuilder = builder.CreateDynamicItemBuilder() itemBuilder.SetValueType(DataValueType.MeanStepBackward) itemBuilder.SetAxis(axis) for iz in range(nZ): for xy in ['x', 'y']: itemBuilder.Set('Boundary inflow layer {0}, {1}-direction'.format(iz + 1, xy), eumQuantity.Create(eumItem.eumIDischarge, eumUnit.eumUm3PerSec), DfsSimpleType.Float) builder.AddDynamicItem(itemBuilder.GetDynamicItemInfo()) builder.CreateFile(filename) dfs = builder.GetFile()
def create( self, filename, data, start_time=None, dt=1, datetimes=None, items=None, length_x=1, length_y=1, x0=0, y0=0, coordinate=None, timeseries_unit=TimeStep.SECOND, title=None, ): """ Create a dfs2 file Parameters ---------- filename: str Location to write the dfs2 file data: list[np.array] list of matrices, one for each item. Matrix dimension: time, y, x start_time: datetime, optional start date of type datetime. timeseries_unit: Timestep, optional TimeStep default TimeStep.SECOND dt: float, optional The time step. Therefore dt of 5.5 with timeseries_unit of TimeStep.MINUTE means 5 mins and 30 seconds. Default 1 datetimes: list[datetime], optional datetimes, creates a non-equidistant calendar axis items: list[ItemInfo], optional List of ItemInfo corresponding to a variable types (ie. Water Level). coordinate: ['UTM-33', 12.4387, 55.2257, 327] for UTM, Long, Lat, North to Y orientation. Note: long, lat in decimal degrees x0: float, optional Lower right position x0: float, optional Lower right position length_x: float, optional length of each grid in the x direction (projection units) length_y: float, optional length of each grid in the y direction (projection units) title: str, optional title of the dfs2 file. Default is blank. """ if title is None: title = "" n_time_steps = np.shape(data[0])[0] number_y = np.shape(data[0])[1] number_x = np.shape(data[0])[2] n_items = len(data) if start_time is None: start_time = datetime.now() if coordinate is None: coordinate = ["LONG/LAT", 0, 0, 0] if items is None: items = [ItemInfo(f"temItem {i+1}") for i in range(n_items)] if not all(np.shape(d)[0] == n_time_steps for d in data): raise Warning( "ERROR data matrices in the time dimension do not all match in the data list. " "Data is list of matices [t,y,x]") if not all(np.shape(d)[1] == number_y for d in data): raise Warning( "ERROR data matrices in the Y dimension do not all match in the data list. " "Data is list of matices [t,y,x]") if not all(np.shape(d)[2] == number_x for d in data): raise Warning( "ERROR data matrices in the X dimension do not all match in the data list. " "Data is list of matices [t,y,x,]") if len(items) != n_items: raise Warning( "number of items must correspond to the number of arrays in data list" ) if datetimes is None: equidistant = True if not type(start_time) is datetime: raise Warning("start_time must be of type datetime ") else: equidistant = False start_time = datetimes[0] # if not isinstance(timeseries_unit, int): # raise Warning("timeseries_unit must be an integer. timeseries_unit: second=1400, minute=1401, hour=1402, " # "day=1403, month=1405, year= 1404See dfsutil options for help ") system_start_time = System.DateTime( start_time.year, start_time.month, start_time.day, start_time.hour, start_time.minute, start_time.second, ) # Create an empty dfs2 file object factory = DfsFactory() builder = Dfs2Builder.Create(title, "mikeio", 0) # Set up the header builder.SetDataType(0) if coordinate[0] == "LONG/LAT": builder.SetGeographicalProjection( factory.CreateProjectionGeoOrigin(coordinate[0], coordinate[1], coordinate[2], coordinate[3])) else: builder.SetGeographicalProjection( factory.CreateProjectionProjOrigin(coordinate[0], coordinate[1], coordinate[2], coordinate[3])) if equidistant: builder.SetTemporalAxis( factory.CreateTemporalEqCalendarAxis(timeseries_unit, system_start_time, 0, dt)) else: builder.SetTemporalAxis( factory.CreateTemporalNonEqCalendarAxis( eumUnit.eumUsec, system_start_time)) builder.SetSpatialAxis( factory.CreateAxisEqD2(eumUnit.eumUmeter, number_x, x0, length_x, number_y, y0, length_y)) for i in range(n_items): builder.AddDynamicItem( items[i].name, eumQuantity.Create(items[i].type, items[i].unit), DfsSimpleType.Float, DataValueType.Instantaneous, ) try: builder.CreateFile(filename) except IOError: print("cannot create dfs2 file: ", filename) dfs = builder.GetFile() deletevalue = dfs.FileInfo.DeleteValueFloat # -1.0000000031710769e-30 for i in range(n_time_steps): for item in range(n_items): d = data[item][i, :, :] d[np.isnan(d)] = deletevalue d = d.reshape(number_y, number_x) d = np.flipud(d) darray = Array[System.Single](np.array( d.reshape(d.size, 1)[:, 0])) if equidistant: dfs.WriteItemTimeStepNext(0, darray) else: t = datetimes[i] relt = (t - start_time).seconds dfs.WriteItemTimeStepNext(relt, darray) dfs.Close()
def create(self, filename, data, start_time=None, dt=1, datetimes=None, length_x=1, length_y=1, x0=0, y0=0, coordinate=None, timeseries_unit=TimeStep.SECOND, variable_type=None, unit=None, names=None, title=None): """ Creates a dfs2 file filename: Location to write the dfs2 file data: list of matrices, one for each item. Matrix dimension: y, x, time start_time: start date of type datetime. timeseries_unit: TimeStep default TimeStep.SECOND dt: The time step. Therefore dt of 5.5 with timeseries_unit of TimeStep.MINUTE means 5 mins and 30 seconds. Default 1 datetimes: list of datetimes, creates a non-equidistant calendar axis variable_type: Array integers corresponding to a variable types (ie. Water Level). Use dfsutil type_list to figure out the integer corresponding to the variable. unit: Array integers corresponding to the unit corresponding to the variable types The unit (meters, seconds), use dfsutil unit_list to figure out the corresponding unit for the variable. coordinate: ['UTM-33', 12.4387, 55.2257, 327] for UTM, Long, Lat, North to Y orientation. Note: long, lat in decimal degrees x0: Lower right position x0: Lower right position length_x: length of each grid in the x direction (projection units) length_y: length of each grid in the y direction (projection units) names: array of names (ie. array of strings). (can be blank) title: title of the dfs2 file. Default is blank. """ if title is None: title = "" n_time_steps = np.shape(data[0])[0] number_y = np.shape(data[0])[1] number_x = np.shape(data[0])[2] n_items = len(data) if start_time is None: start_time = datetime.now() if coordinate is None: coordinate = ['LONG/LAT', 0, 0, 0] if names is None: names = [f"Item {i+1}" for i in range(n_items)] if variable_type is None: variable_type = [999] * n_items if unit is None: unit = [0] * n_items if not all(np.shape(d)[0] == n_time_steps for d in data): raise Warning( "ERROR data matrices in the time dimension do not all match in the data list. " "Data is list of matices [t,y,x]") if not all(np.shape(d)[1] == number_y for d in data): raise Warning( "ERROR data matrices in the Y dimension do not all match in the data list. " "Data is list of matices [t,y,x]") if not all(np.shape(d)[2] == number_x for d in data): raise Warning( "ERROR data matrices in the X dimension do not all match in the data list. " "Data is list of matices [t,y,x,]") if len(names) != n_items: raise Warning( "names must be an array of strings with the same number as matrices in data list" ) if len(variable_type) != n_items or not all( isinstance(item, int) and 0 <= item < 1e15 for item in variable_type): raise Warning( "type if specified must be an array of integers (enuType) with the same number of " "elements as data columns") if len(unit) != n_items or not all( isinstance(item, int) and 0 <= item < 1e15 for item in unit): raise Warning( "unit if specified must be an array of integers (enuType) with the same number of " "elements as data columns") if datetimes is None: equidistant = True if not type(start_time) is datetime: raise Warning("start_time must be of type datetime ") else: equidistant = False start_time = datetimes[0] #if not isinstance(timeseries_unit, int): # raise Warning("timeseries_unit must be an integer. timeseries_unit: second=1400, minute=1401, hour=1402, " # "day=1403, month=1405, year= 1404See dfsutil options for help ") system_start_time = System.DateTime(start_time.year, start_time.month, start_time.day, start_time.hour, start_time.minute, start_time.second) # Create an empty dfs2 file object factory = DfsFactory() builder = Dfs2Builder.Create(title, 'pydhi', 0) # Set up the header builder.SetDataType(0) if coordinate[0] == 'LONG/LAT': builder.SetGeographicalProjection( factory.CreateProjectionGeoOrigin(coordinate[0], coordinate[1], coordinate[2], coordinate[3])) else: builder.SetGeographicalProjection( factory.CreateProjectionProjOrigin(coordinate[0], coordinate[1], coordinate[2], coordinate[3])) if equidistant: builder.SetTemporalAxis( factory.CreateTemporalEqCalendarAxis(timeseries_unit, system_start_time, 0, dt)) else: builder.SetTemporalAxis( factory.CreateTemporalNonEqCalendarAxis( eumUnit.eumUsec, system_start_time)) builder.SetSpatialAxis( factory.CreateAxisEqD2(eumUnit.eumUmeter, number_x, x0, length_x, number_y, y0, length_y)) for i in range(n_items): builder.AddDynamicItem( names[i], eumQuantity.Create(variable_type[i], unit[i]), DfsSimpleType.Float, DataValueType.Instantaneous) try: builder.CreateFile(filename) except IOError: print('cannot create dfs2 file: ', filename) dfs = builder.GetFile() deletevalue = dfs.FileInfo.DeleteValueFloat # -1.0000000031710769e-30 for i in range(n_time_steps): for item in range(n_items): d = data[item][i, :, :] d[np.isnan(d)] = deletevalue d = d.reshape(number_y, number_x) d = np.flipud(d) darray = Array[System.Single](np.array( d.reshape(d.size, 1)[:, 0])) if equidistant: dfs.WriteItemTimeStepNext(0, darray) else: t = datetimes[i] relt = (t - start_time).seconds dfs.WriteItemTimeStepNext(relt, darray) dfs.Close()
def write( self, filename, data, start_time=None, dt=1, datetimes=None, items=None, dx=None, dy=None, x0=0, y0=0, coordinate=None, title=None, ): """ Create a dfs2 file Parameters ---------- filename: str Location to write the dfs2 file data: list[np.array] or Dataset list of matrices, one for each item. Matrix dimension: time, y, x start_time: datetime, optional start date of type datetime. dt: float, optional The time step in seconds. datetimes: list[datetime], optional datetimes, creates a non-equidistant calendar axis items: list[ItemInfo], optional List of ItemInfo corresponding to a variable types (ie. Water Level). x0: float, optional Lower right position x0: float, optional Lower right position dx: float, optional length of each grid in the x direction (projection units) dy: float, optional length of each grid in the y direction (projection units) coordinate: ['UTM-33', 12.4387, 55.2257, 327] for UTM, Long, Lat, North to Y orientation. Note: long, lat in decimal degrees title: str, optional title of the dfs2 file. Default is blank. """ self._write_handle_common_arguments( title, data, items, coordinate, start_time, dt ) number_y = np.shape(data[0])[1] number_x = np.shape(data[0])[2] if dx is None: if self._dx is not None: dx = self._dx else: dx = 1 if dy is None: if self._dy is not None: dy = self._dy else: dy = 1 if not all(np.shape(d)[0] == self._n_time_steps for d in data): raise ValueError( "ERROR data matrices in the time dimension do not all match in the data list. " "Data is list of matrices [t,y,x]" ) if not all(np.shape(d)[1] == number_y for d in data): raise ValueError( "ERROR data matrices in the Y dimension do not all match in the data list. " "Data is list of matrices [t,y,x]" ) if not all(np.shape(d)[2] == number_x for d in data): raise ValueError( "ERROR data matrices in the X dimension do not all match in the data list. " "Data is list of matrices [t,y,x]" ) if datetimes is None: self._is_equidistant = True else: self._is_equidistant = False start_time = datetimes[0] self._start_time = start_time factory = DfsFactory() builder = Dfs2Builder.Create(title, "mikeio", 0) self._builder = builder self._factory = factory builder.SetSpatialAxis( factory.CreateAxisEqD2( eumUnit.eumUmeter, number_x, x0, dx, number_y, y0, dy ) ) dfs = self._setup_header(filename) # coordinate, start_time, dt, timeseries_unit, items, filename # ) deletevalue = dfs.FileInfo.DeleteValueFloat # -1.0000000031710769e-30 for i in range(self._n_time_steps): for item in range(self._n_items): d = self._data[item][i, :, :] d[np.isnan(d)] = deletevalue d = d.reshape(number_y, number_x) d = np.flipud(d) darray = to_dotnet_float_array(d.reshape(d.size, 1)[:, 0]) if self._is_equidistant: dfs.WriteItemTimeStepNext(0, darray) else: t = datetimes[i] relt = (t - self._start_time).total_seconds() dfs.WriteItemTimeStepNext(relt, darray) dfs.Close()