def write( self, filename, data, start_time=None, dt=1, items=None, dx=1.0, dy=1.0, dz=1.0, x0=0, y0=0, coordinate=None, timeseries_unit=TimeStepUnit.SECOND, title=None, ): """ Write a dfs3 file Parameters ---------- filename: str Location to write the dfs3 file data: list[np.array] list of matrices, one for each item. Matrix dimension: time, z, 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 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 y0: 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) dz: float, optional length of each grid in the z direction (projection units) title: str, optional title of the dfs2 file. Default is blank. """ if title is None: title = "dfs3 file" n_time_steps = np.shape(data[0])[0] number_z = np.shape(data[0])[1] number_y = np.shape(data[0])[2] number_x = np.shape(data[0])[3] n_items = len(data) system_start_time = to_dotnet_datetime(start_time) # Create an empty dfs3 file object factory = DfsFactory() builder = Dfs3Builder.Create(title, "mikeio", 0) # Set up the header builder.SetDataType(1) builder.SetGeographicalProjection( factory.CreateProjectionGeoOrigin(*coordinate)) builder.SetTemporalAxis( factory.CreateTemporalEqCalendarAxis(timeseries_unit, system_start_time, 0, dt)) builder.SetSpatialAxis( factory.CreateAxisEqD3( eumUnit.eumUmeter, number_x, x0, dx, number_y, y0, dy, number_z, 0, dz, )) 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 dfs3 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 = np.flipud(d) darray = to_dotnet_float_array(d.reshape(d.size, 1)[:, 0]) dfs.WriteItemTimeStepNext(0, darray) dfs.Close()
def create_equidistant_calendar(self, dfs3file, data, start_time, timeseries_unit, dt, variable_type, unit, coordinate, x0, y0, length_x, length_y, names, title=None): """ Creates a dfs3 file dfs3file: Location to write the dfs3 file data: list of matrices, one for each item. Matrix dimension: y, x, z, time start_time: start date of type datetime. timeseries_unit: second=1400, minute=1401, hour=1402, day=1403, month=1405, year= 1404 dt: The time step (double based on the timeseries_unit). Therefore dt of 5.5 with timeseries_unit of minutes means 5 mins and 30 seconds. 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 OR [TODO: Support not Local Coordinates ...] x0: Lower right position y0: Lower right position length_x: length of each grid in the x direction (meters) length_y: length of each grid in the y direction (meters) names: array of names (ie. array of strings). title: title of the dfs3 file (can be blank) """ if title is None: title = "dfs0 file" number_y = np.shape(data[0])[0] number_x = np.shape(data[0])[1] number_z = np.shape(data[0])[2] n_time_steps = np.shape(data[0])[3] n_items = len(data) if not all(np.shape(d)[0] == 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 [y,x,time]") if not all(np.shape(d)[1] == 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 [y,x,time]") if not all(np.shape(d)[2] == number_z 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 [y,x,time]") if not all(np.shape(d)[3] == 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 [y,x,time]") 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 not type(start_time) is datetime.datetime: raise Warning("start_time must be of type datetime ") 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 dfs3 file object factory = DfsFactory() builder = Dfs3Builder.Create(title, 'pydhi', 0) # Set up the header builder.SetDataType(1) builder.SetGeographicalProjection( factory.CreateProjectionGeoOrigin(coordinate[0], coordinate[1], coordinate[2], coordinate[3])) builder.SetTemporalAxis( factory.CreateTemporalEqCalendarAxis(timeseries_unit, system_start_time, 0, dt)) builder.SetSpatialAxis( factory.CreateAxisEqD3(eumUnit.eumUmeter, number_x, x0, length_x, number_y, y0, length_y, number_z, 0, 1)) deletevalue = builder.DeleteValueFloat for i in range(n_items): builder.AddDynamicItem( names[i], eumQuantity.Create(variable_type[i], unit[i]), DfsSimpleType.Float, DataValueType.Instantaneous) try: builder.CreateFile(dfs3file) except IOError: print('cannot create dfs3 file: ', dfs3file) dfs = builder.GetFile() for i in range(n_time_steps): for item in range(n_items): #d = data[item][:, :, :, i] #d.reshape(number_z, number_y, number_x).swapaxes(0, 2).swapaxes(0, 1) #d = np.flipud(d) #d[np.isnan(d)] = deletevalue #darray = Array[System.Single](np.array(d.reshape(d.size, 1)[:, 0])) #dfs.WriteItemTimeStepNext(0, darray) # TESTED AND WORKDS if data already in the y,x,z,t format d = data[item][:, :, :, i] d = d.swapaxes(0, 1) d = d.swapaxes(0, 2) d = np.fliplr(d) d[np.isnan(d)] = deletevalue darray = Array[System.Single](np.array( d.reshape(d.size, 1)[:, 0])) dfs.WriteItemTimeStepNext(0, darray) dfs.Close()