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 _clone(infilename, outfilename): """Clone a dfs file Parameters ---------- infilename : str input filename outfilename : str output filename Returns ------- DfsFile MIKE generic dfs file object """ source = DfsFileFactory.DfsGenericOpen(infilename) fi = source.FileInfo builder = DfsBuilder.Create(fi.FileTitle, fi.ApplicationTitle, fi.ApplicationVersion) # Set up the header builder.SetDataType(fi.DataType) builder.SetGeographicalProjection(fi.Projection) builder.SetTemporalAxis(fi.TimeAxis) builder.SetItemStatisticsType(fi.StatsType) builder.DeleteValueByte = fi.DeleteValueByte builder.DeleteValueDouble = fi.DeleteValueDouble builder.DeleteValueFloat = fi.DeleteValueFloat builder.DeleteValueInt = fi.DeleteValueInt builder.DeleteValueUnsignedInt = fi.DeleteValueUnsignedInt # Copy custom blocks - if any for customBlock in fi.CustomBlocks: builder.AddCustomBlock(customBlock) # Copy dynamic items for itemInfo in source.ItemInfo: builder.AddDynamicItem(itemInfo) # Create file builder.CreateFile(outfilename) # Copy static items while True: static_item = source.ReadStaticItemNext() if static_item is None: break builder.AddStaticItem(static_item) # Get the file file = builder.GetFile() source.Close() return file
def CreateDfsBuilder(self): resultData = self.resultData factory = self.factory builder = DfsBuilder.Create("ResultDataExtractor-script", "MIKE SDK", 100) # Set up file header builder.SetDataType(1) builder.SetGeographicalProjection(factory.CreateProjectionUndefined()) builder.SetTemporalAxis( factory.CreateTemporalNonEqCalendarAxis(eumUnit.eumUsec, resultData.StartTime)) builder.SetItemStatisticsType(StatType.NoStat) return builder
def _setup_header(self): factory = DfsFactory() builder = DfsBuilder.Create(self._title, "DFS", 0) builder.SetDataType(1) builder.SetGeographicalProjection(factory.CreateProjectionUndefined()) system_start_time = to_dotnet_datetime(self._start_time) if self._is_equidistant: temporal_axis = factory.CreateTemporalEqCalendarAxis( self._timeseries_unit, system_start_time, 0, self._dt ) else: temporal_axis = factory.CreateTemporalNonEqCalendarAxis( self._timeseries_unit, system_start_time ) builder.SetTemporalAxis(temporal_axis) builder.SetItemStatisticsType(StatType.RegularStat) dtype_dfs = self._to_dfs_datatype(self._dtype) for i in range(self._n_items): item = self._items[i] newitem = builder.CreateDynamicItemBuilder() quantity = eumQuantity.Create(item.type, item.unit) newitem.Set( item.name, quantity, dtype_dfs, ) if self._data_value_type is not None: newitem.SetValueType(self._data_value_type[i]) else: newitem.SetValueType(DataValueType.Instantaneous) newitem.SetAxis(factory.CreateAxisEqD0()) builder.AddDynamicItem(newitem.GetDynamicItemInfo()) try: builder.CreateFile(self._filename) except IOError: raise IOError(f"Cannot create dfs0 file: {self._filename}") return builder.GetFile()
def create( self, filename, data, start_time=None, timeseries_unit=TimeStep.SECOND, dt=1.0, datetimes=None, items=None, title=None, data_value_type=None, ): """Create a dfs0 file. Parameters ---------- filename: str Full path and filename to dfs0 to be created. data: list[np.array] values start_time: datetime.datetime, , optional start date of type datetime. timeseries_unit: Timestep, optional Timestep unitdefault Timestep.SECOND dt: float, optional the time step. Therefore dt of 5.5 with timeseries_unit of minutes means 5 mins and 30 seconds. default to 1.0 items: list[ItemInfo], optional List of ItemInfo corresponding to a variable types (ie. Water Level). title: str, optional title data_value_type: list[DataValueType], optional DataValueType default DataValueType.INSTANTANEOUS """ if title is None: title = "dfs0 file" n_items = len(data) n_time_steps = np.shape(data[0])[0] if start_time is None: start_time = datetime.now() if items is None: items = [ItemInfo(f"temItem {i+1}") for i in range(n_items)] if len(items) != n_items: raise Warning( "names must be an array of strings 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 ") dt = np.float(dt) datetimes = np.array( [ start_time + timedelta(seconds=(step * dt)) for step in np.arange(n_time_steps) ] ) else: start_time = datetimes[0] equidistant = False # if not isinstance(timeseries_unit, int): # raise Warning("timeseries_unit must be an integer. See dfsutil options for help ") system_start_time = to_dotnet_datetime(start_time) factory = DfsFactory() builder = DfsBuilder.Create(title, "DFS", 0) builder.SetDataType(1) builder.SetGeographicalProjection(factory.CreateProjectionUndefined()) if equidistant: builder.SetTemporalAxis( factory.CreateTemporalEqCalendarAxis( timeseries_unit, system_start_time, 0, dt ) ) else: builder.SetTemporalAxis( factory.CreateTemporalNonEqCalendarAxis( timeseries_unit, system_start_time ) ) builder.SetItemStatisticsType(StatType.RegularStat) for i in range(n_items): item = builder.CreateDynamicItemBuilder() item.Set( items[i].name, eumQuantity.Create(items[i].type, items[i].unit), DfsSimpleType.Float, ) if data_value_type is not None: item.SetValueType(data_value_type[i]) else: item.SetValueType(DataValueType.Instantaneous) item.SetAxis(factory.CreateAxisEqD0()) builder.AddDynamicItem(item.GetDynamicItemInfo()) try: builder.CreateFile(filename) except IOError: print("cannot create dfso file: ", filename) dfs = builder.GetFile() delete_value = dfs.FileInfo.DeleteValueFloat for i in range(n_items): d = data[i] d[np.isnan(d)] = delete_value data1 = np.stack(data, axis=1) t_seconds = [(t - datetimes[0]).total_seconds() for t in datetimes] Dfs0Util.WriteDfs0DataDouble(dfs, t_seconds, to_dotnet_array(data1)) dfs.Close()
def dfstodfs0(dfsfile, dfs0file, func=np.nanmean): """ Function: take average (or other statistics) over dfs and output dfs0 Usage: dfstodfs0(dfsfile, dfs0file) dfstodfs0(dfsfile, dfs0file, func=np.nanmean) """ # Read dfs dfs_in = DfsFileFactory.DfsGenericOpen(dfsfile) fileInfo = dfs_in.FileInfo # Basic info from input file n_time_steps = fileInfo.TimeAxis.NumberOfTimeSteps if n_time_steps == 0: raise Warning( "Static dfs files (with no time steps) are not supported.") # Create an empty dfs1 file object factory = DfsFactory() builder = DfsBuilder.Create(fileInfo.FileTitle, fileInfo.ApplicationTitle, fileInfo.ApplicationVersion) # Set up the header builder.SetDataType(fileInfo.DataType) builder.SetGeographicalProjection(factory.CreateProjectionUndefined()) builder.SetTemporalAxis(fileInfo.TimeAxis) builder.DeleteValueByte = fileInfo.DeleteValueByte builder.DeleteValueDouble = fileInfo.DeleteValueDouble builder.DeleteValueFloat = fileInfo.DeleteValueFloat builder.DeleteValueInt = fileInfo.DeleteValueInt builder.DeleteValueUnsignedInt = fileInfo.DeleteValueUnsignedInt # dynamic items n_items = safe_length(dfs_in.ItemInfo) for item in range(n_items): ii = dfs_in.ItemInfo[item] itemj = builder.CreateDynamicItemBuilder() itemj.Set(ii.Name, ii.Quantity, DfsSimpleType.Float) itemj.SetValueType(DataValueType.Instantaneous) itemj.SetAxis(factory.CreateAxisEqD0()) # itemj.SetReferenceCoordinates(0, 0, 0) builder.AddDynamicItem(itemj.GetDynamicItemInfo()) try: builder.CreateFile(dfs0file) except IOError: print("cannot create dfs0 file: ", dfs0file) dfs_out = builder.GetFile() # read-write data deleteValue = fileInfo.DeleteValueFloat for it in range(n_time_steps): for item in range(n_items): itemdata = dfs_in.ReadItemTimeStep(item + 1, it) d = to_numpy(itemdata.Data) d[d == deleteValue] = np.nan d0 = func(d) d = np.zeros(1) d[0] = d0 d[np.isnan(d)] = deleteValue darray = to_dotnet_float_array(d) dfs_out.WriteItemTimeStepNext(itemdata.Time, darray) dfs_in.Close() dfs_out.Close()
def _clone(infilename: str, outfilename: str, start_time=None, items=None) -> DfsFile: """Clone a dfs file Parameters ---------- infilename : str input filename outfilename : str output filename start_time : datetime, optional new start time for the new file, default items : list(int), optional clone only these items, default: all items Returns ------- DfsFile MIKE generic dfs file object """ source = DfsFileFactory.DfsGenericOpen(infilename) fi = source.FileInfo builder = DfsBuilder.Create(fi.FileTitle, fi.ApplicationTitle, fi.ApplicationVersion) # Set up the header builder.SetDataType(fi.DataType) builder.SetGeographicalProjection(fi.Projection) # Copy time axis time_axis = fi.TimeAxis if start_time is not None: dt = to_dotnet_datetime(start_time) time_axis.set_StartDateTime(dt) builder.SetTemporalAxis(time_axis) builder.SetItemStatisticsType(fi.StatsType) builder.DeleteValueByte = fi.DeleteValueByte builder.DeleteValueDouble = fi.DeleteValueDouble builder.DeleteValueFloat = fi.DeleteValueFloat builder.DeleteValueInt = fi.DeleteValueInt builder.DeleteValueUnsignedInt = fi.DeleteValueUnsignedInt # Copy custom blocks - if any for customBlock in fi.CustomBlocks: builder.AddCustomBlock(customBlock) # Copy dynamic items item_numbers = _valid_item_numbers(source.ItemInfo, items) for item in item_numbers: builder.AddDynamicItem(source.ItemInfo[item]) # Create file builder.CreateFile(outfilename) # Copy static items while True: static_item = source.ReadStaticItemNext() if static_item is None: break builder.AddStaticItem(static_item) # Get the file file = builder.GetFile() source.Close() return file
def create(self, filename, data, start_time=None, timeseries_unit=TimeStep.SECOND, dt=1, datetimes=None, variable_type=None, unit=None, names=None, title=None, data_value_type=None): """create creates a dfs0 file. filename: Full path and filename to dfs0 to be created. data: a numpy matrix 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 minutes means 5 mins and 30 seconds. default to 1 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. names: array of names (ie. array of strings) title: title (string) data_value_type: DataValueType default DataValueType.INSTANTANEOUS """ if title is None: title = "dfs0 file" n_items = len(data) n_time_steps = np.shape(data[0])[0] if start_time is None: start_time = datetime.now() 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 names is not None and len(names) != n_items: raise Warning( "names must be an array of strings with the same number of elements as data columns" ) if len(variable_type) != n_items: raise Warning( "type if specified must be an array of integers (eumType) with the same number of " "elements as data columns") if len(unit) != n_items: raise Warning( "unit if specified must be an array of integers (eumType) 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: start_time = datetimes[0] equidistant = False #if not isinstance(timeseries_unit, int): # raise Warning("timeseries_unit must be an integer. See 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) factory = DfsFactory() builder = DfsBuilder.Create(title, 'DFS', 0) builder.SetDataType(1) builder.SetGeographicalProjection(factory.CreateProjectionUndefined()) if equidistant: builder.SetTemporalAxis( factory.CreateTemporalEqCalendarAxis(timeseries_unit, system_start_time, 0, dt)) else: builder.SetTemporalAxis( factory.CreateTemporalNonEqCalendarAxis( timeseries_unit, system_start_time)) builder.SetItemStatisticsType(StatType.RegularStat) for i in range(n_items): item = builder.CreateDynamicItemBuilder() if type is not None: item.Set(names[i], eumQuantity.Create(variable_type[i], unit[i]), DfsSimpleType.Float) else: item.Set(str(i), eumQuantity.Create(eumItem.eumIItemUndefined, 0), DfsSimpleType.Float) if data_value_type is not None: item.SetValueType(data_value_type[i]) else: item.SetValueType(DataValueType.Instantaneous) item.SetAxis(factory.CreateAxisEqD0()) builder.AddDynamicItem(item.GetDynamicItemInfo()) try: builder.CreateFile(filename) except IOError: print('cannot create dfso file: ', filename) dfs = builder.GetFile() delete_value = dfs.FileInfo.DeleteValueFloat for i in range(n_items): d = data[i] d[np.isnan(d)] = delete_value # COPY OVER THE DATA for it in range(n_time_steps): for ii in range(n_items): d = Array[System.Single](np.array(data[ii][it:it + 1])) if equidistant: dfs.WriteItemTimeStepNext(it, d) else: dt = (datetimes[it] - datetimes[0]).total_seconds() dfs.WriteItemTimeStepNext(dt, d) dfs.Close()