def fromWKB(wkb): """ Builds a stdlib.Geometry object from a WKB string :param wkb: wkb string :return: stdlib.Geometry """ geom = None # parse the wkt string into ogr ogrgeom = ogr.CreateGeometryFromWkb(wkb) # get geometry type geomtype = ogrgeom.GetGeometryName() if geomtype == stdlib.GeomType.POINT: geom = fromGdalPoint(ogrgeom) elif geomtype == stdlib.GeomType.LINESTRING: geom = fromGdalLinestring(ogrgeom) elif geomtype == stdlib.GeomType.POLYGON: geom = fromGdalPolygon(ogrgeom) else: elog.critical("Unsupported geometry type %s, in utilities.geometry.fromWKB" % geomtype) return geom[0]
def on_run(self, e): # get data to send to the engine name = self.simulation_name_textbox.GetValue() db = self.database_combo.GetValue() # user_name = self.account_combo.GetValue() datasets = self.get_selected_items() user_info = self.get_user_info() # todo: check all constraints before executing a simulation # raise exceptions before executing the simulation if user_info is None: elog.critical( 'Cannot execute simulation if no user account is provided') return # set a default simulation name if none is provided if name.strip() == '': name = "Simulation_run_" + time.strftime('%m-%d-%Y') # build kwargs to pass to engineAccessors kwargs = dict(simulationName=name, dbName=db, user_info=user_info, datasets=datasets) # initiate simulation engineAccessors.runSimulation(**kwargs) self.Close()
def fromWKB(wkb): """ Builds a stdlib.Geometry object from a WKB string :param wkb: wkb string :return: stdlib.Geometry """ geom = None # parse the wkt string into ogr ogrgeom = ogr.CreateGeometryFromWkb(wkb) # get geometry type geomtype = ogrgeom.GetGeometryName() if geomtype == stdlib.GeomType.POINT: geom = fromGdalPoint(ogrgeom) elif geomtype == stdlib.GeomType.LINESTRING: geom = fromGdalLinestring(ogrgeom) elif geomtype == stdlib.GeomType.POLYGON: geom = fromGdalPolygon(ogrgeom) else: elog.critical( "Unsupported geometry type %s, in utilities.geometry.fromWKB" % geomtype) return geom[0]
def getDates2(self, timevalue=None, start=None, end=None, ndarray=False): """ gets datavalue indices for a datetime :param timevalue: datetime object :return: returns the datavalue index, and the time value corresponding to the nearest requested datetime """ if isinstance(timevalue, list): times = [] for t in timevalue: idx = self._nearest(self.__times2, timevalue, 'left') if len(self.__times2) and idx <= len(self.__times2): times.append((idx, self.__times2[idx])) else: times.append(0, None) if ndarray: return numpy.array(times) else: return times elif start is not None and end is not None: if not isinstance(start, datetime.datetime) or not isinstance( end, datetime.datetime): elog.critical( 'ERROR ExchangeItem.getDates2: Could not fetch date time from range because the "start" and/or "endtimes" are not valued datetime objects.' ) sPrint( 'Could not fetch date time from range because the "start" and/or "endtimes" are not valued datetime objects.', MessageType.CRITICAL) return 0, None st = self._nearest(self.__times2, start, 'left') et = self._nearest(self.__times2, end, 'right') + 1 times = [(idx, self.__times2[idx]) for idx in range(st, et)] if ndarray: return numpy.array(times) else: return times elif isinstance(timevalue, datetime.datetime): idx = self._nearest(self.__times2, timevalue, 'left') if len(self.__times2) and idx <= len(self.__times2): return idx, self.__times2[idx] else: return 0, None else: # return all known values times = [(idx, self.__times2[idx]) for idx in range(0, len(self.__times2))] if ndarray: return numpy.array(times) else: return times
def load_links(self, links): # get all known transformations space = SpatialInterpolation() time = TemporalInterpolation() spatial_transformations = {i.name(): i for i in space.methods()} temporal_transformations = {i.name(): i for i in time.methods()} links_to_add = [] for link in links: # get 'from' and 'to' model attributes from_model_id = link['from_id'] from_model_item = link['from_item'] from_model_name = link['from_name'] to_model_id = link['to_id'] to_model_item = link['to_item'] to_model_name = link['to_name'] from_model = self.get_model_object_from_ID(from_model_id) to_model = self.get_model_object_from_ID(to_model_id) if from_model is None or to_model is None: elog.critical("Failed to create link between %s and %s." % (from_model_name, to_model_name)) sPrint( "Failed to create link between %s and %s." % (from_model_name, to_model_name), MessageType.CRITICAL) return sPrint('Adding link between: %s and %s... ' % (from_model_name, to_model_name)) # get the spatial and temporal transformations temporal_transformation_name = link['temporal_transformation'] spatial_transformation_name = link['spatial_transformation'] # set the transformation values temporal = temporal_transformations[ temporal_transformation_name] if temporal_transformation_name.lower( ) != 'none' else None spatial = spatial_transformations[ spatial_transformation_name] if spatial_transformation_name.lower( ) != 'none' else None # create the link engine.addLink(source_id=from_model_id, source_item=from_model_item, target_id=to_model_id, target_item=to_model_item, spatial_interpolation=spatial, temporal_interpolation=temporal) links_to_add.append([from_model, to_model]) wx.CallAfter(self.createLoadedLinks, links_to_add)
def setValuesBySlice(self, values, time_index_slice=(None, None, None), geometry_index_slice=(None, None, None)): """ sets datavalues for the component. :param values: Values to set # :param value_index_slice: tuple representing the start, stop, and step range of the values :param time_index_slice: tuple representing the start, stop, and step range of the date times :param geometry_index_slice: tuple representing the start, stop, and step range of the geometries :return: True if successful, otherwise False """ if len(self.__values2) == 0 or len(self.__times2) == 0: elog.critical( 'Error ExchangeItem.setValuesBySlice: Exchange item values and/or times arrays were not set properly' ) sPrint( 'Exchange item values and/or times arrays were not set properly Make sure "initializeDatesValues" is being called during/after component initialization.', MessageType.CRITICAL) return False try: # get index ranges tb, te, tstep = time_index_slice gb, ge, gstep = geometry_index_slice # set initial values for missing slice indices tb = 0 if tb is None else tb gb = 0 if gb is None else gb te = len(self.__times2) if te is None else te ge = len(self.__geoms2) if ge is None else ge tstep = 1 if tstep is None else tstep gstep = 1 if gstep is None else gstep # convert the values into a numpy array if they aren't already if not isinstance(values, numpy.ndarray): values = numpy.array(values) # set the values[times][geoms] # reshape the input array to fit the desired slicing target_shape = ((te - tb) / tstep, (ge - gb) / gstep) values = values.reshape(target_shape) self.__values2[tb:te:tstep, gb:ge:gstep] = values except Exception as e: elog.error('Error ExchangeItem.setValuesBySlice: %s' % e) sPrint( 'Error setting values for times %s, geometries %s: %s' % (str(time_index_slice), str(geometry_index_slice), e), MessageType.ERROR) return False return True
def SetPlotData(self, geom_list, colors): # build geometry object # todo: this should only be done once, not every time data is selected # POINT if geom_list[0].GetGeometryName() == stdlib.GeomType.POINT: # get x,y points x, y = zip(*[(g.GetX(), g.GetY()) for g in geom_list]) self.ax.scatter(x, y, color=colors) # POLYGON elif geom_list[0].GetGeometryName() == stdlib.GeomType.POLYGON: poly_list = [] # get geometry reference ref = geom_list[0].GetGeometryRef(0) # build a list of points pts = numpy.array(ref.GetPoints()) a = tuple(map(tuple, pts[:, 0:2])) poly_list.append(a) # build a polygon collection pcoll = PolyCollection(poly_list, closed=True, facecolor=colors, alpha=0.5, edgecolor=None, linewidths=(2,)) # add the polygon collection to the plot self.ax.add_collection(pcoll, autolim=True) # LINESTRING elif geom_list[0].GetGeometryName() == stdlib.GeomType.LINESTRING: line_list = [] # build a list of points pts = numpy.array(geom_list[0].GetPoints()) # p = pts[:,0:2] a = tuple(map(tuple, pts[:, 0:2])) line_list.append(a) # build a line collection lcoll = LineCollection(line_list, colors=colors) # add the line collection to the plot self.ax.add_collection(lcoll, autolim=True) else: elog.critical("Unsupported line geometry found in SpatialPlotCtrl.SetPlotData") self.ax.grid() self.ax.axis("auto") self.ax.margins(0.1)
def getDates2(self, timevalue=None, start=None, end=None, ndarray=False): """ gets datavalue indices for a datetime :param timevalue: datetime object :return: returns the datavalue index, and the time value corresponding to the nearest requested datetime """ if isinstance(timevalue, list): times = [] for t in timevalue: idx = self._nearest(self.__times2, timevalue, 'left') if len(self.__times2) and idx <= len(self.__times2): times.append((idx, self.__times2[idx])) else: times.append(0, None) if ndarray: return numpy.array(times) else: return times elif start is not None and end is not None: if not isinstance(start, datetime.datetime) or not isinstance(end, datetime.datetime): elog.critical('ERROR ExchangeItem.getDates2: Could not fetch date time from range because the "start" and/or "endtimes" are not valued datetime objects.') sPrint('Could not fetch date time from range because the "start" and/or "endtimes" are not valued datetime objects.', MessageType.CRITICAL) return 0, None st = self._nearest(self.__times2, start, 'left') et = self._nearest(self.__times2, end, 'right') + 1 times = [(idx, self.__times2[idx]) for idx in range(st, et)] if ndarray: return numpy.array(times) else: return times elif isinstance(timevalue, datetime.datetime): idx = self._nearest(self.__times2, timevalue, 'left') if len(self.__times2) and idx <= len(self.__times2): return idx, self.__times2[idx] else: return 0, None else: # return all known values times = [(idx, self.__times2[idx]) for idx in range(0, len(self.__times2))] if ndarray: return numpy.array(times) else: return times
def prepare(self): ''' Called before simulation run to prepare the model :return: READY status ''' try: # initialize the date and value containers sd = self.simulation_start() ed = self.simulation_end() ts = self.time_step() for output in self.outputs().itervalues(): output.initializeDatesValues(sd, ed, ts) except Exception, e: elog.critical(e) elog.critical('Failed to prepare model: %s' % self.name()) self.status(stdlib.Status.ERROR)
def prepare(self): ''' Called before simulation run to prepare the model :return: READY status ''' try: # initialize the date and value containers sd = self.simulation_start() ed = self.simulation_end() ts = self.time_step() for output in self.outputs().itervalues(): output.initializeDatesValues(sd, ed, ts) except Exception, e: elog.critical(e) elog.critical('Failed to prepare model: %s' % self.name()) self.status(stdlib.Status.ERROR)
def build_polygon_geometries(coords): """ Builds stdlib Geometry objects from coordinates :param coords: list or numpy array of polygons coordinates [[[1,2],[2,3], ], ] :return: numpy array of stdlib geometries """ # try to convert x,y coordinates into numpy arrays try: if not isinstance(coords, numpy.ndarray): if isinstance(coords, list): coords = numpy.asarray(coords) else: coords = numpy.array([coords]) except: elog.critical('Could not convert the x,y coordinates into numpy array objects!') return None shape = coords.shape poly_count = shape[0] if len(shape) == 3 else 1 has_multiple = 1 if len(shape) > 2 else 0 geoms = numpy.empty((poly_count), dtype=object) if has_multiple: for i in xrange(0, len(coords)): ring = ogr.Geometry(ogr.wkbLinearRing) for pt in coords[i]: ring.AddPoint(float(pt[0]), float(pt[1])) poly = stdlib.Geometry2(ogr.wkbPolygon) poly.AddGeometry(ring) geoms[i] = poly else: ring = ogr.Geometry(ogr.wkbLinearRing) for pt in coords: ring.AddPoint(float(pt[0]), float(pt[1])) poly = stdlib.Geometry2(ogr.wkbPolygon) poly.AddGeometry(ring) geoms[0] = poly return geoms
def setValuesBySlice (self, values, time_index_slice=(None, None, None), geometry_index_slice=(None, None, None)): """ sets datavalues for the component. :param values: Values to set # :param value_index_slice: tuple representing the start, stop, and step range of the values :param time_index_slice: tuple representing the start, stop, and step range of the date times :param geometry_index_slice: tuple representing the start, stop, and step range of the geometries :return: True if successful, otherwise False """ if len(self.__values2) == 0 or len(self.__times2) == 0: elog.critical('Error ExchangeItem.setValuesBySlice: Exchange item values and/or times arrays were not set properly') sPrint('Exchange item values and/or times arrays were not set properly Make sure "initializeDatesValues" is being called during/after component initialization.', MessageType.CRITICAL) return False try: # get index ranges tb, te, tstep = time_index_slice gb, ge, gstep = geometry_index_slice # set initial values for missing slice indices tb = 0 if tb is None else tb gb = 0 if gb is None else gb te = len(self.__times2) if te is None else te ge = len(self.__geoms2) if ge is None else ge tstep = 1 if tstep is None else tstep gstep = 1 if gstep is None else gstep # convert the values into a numpy array if they aren't already if not isinstance(values, numpy.ndarray): values = numpy.array(values) # set the values[times][geoms] # reshape the input array to fit the desired slicing target_shape = ((te-tb) / tstep, (ge-gb) / gstep) values = values.reshape(target_shape) self.__values2[tb:te:tstep, gb:ge:gstep] = values except Exception as e: elog.error('Error ExchangeItem.setValuesBySlice: %s' % e) sPrint('Error setting values for times %s, geometries %s: %s' % (str(time_index_slice), str(geometry_index_slice), e), MessageType.ERROR) return False return True
def build_polygon_geometries(coords): """ Builds stdlib Geometry objects from coordinates :param coords: list or numpy array of polygons coordinates [[[1,2],[2,3], ], ] :return: numpy array of stdlib geometries """ # try to convert x,y coordinates into numpy arrays try: if not isinstance(coords, numpy.ndarray): if isinstance(coords, list): coords = numpy.asarray(coords) else: coords = numpy.array([coords]) except: elog.critical( 'Could not convert the x,y coordinates into numpy array objects!') return None shape = coords.shape poly_count = shape[0] if len(shape) == 3 else 1 has_multiple = 1 if len(shape) > 2 else 0 geoms = numpy.empty((poly_count), dtype=object) if has_multiple: for i in xrange(0, len(coords)): ring = ogr.Geometry(ogr.wkbLinearRing) for pt in coords[i]: ring.AddPoint(float(pt[0]), float(pt[1])) poly = stdlib.Geometry2(ogr.wkbPolygon) poly.AddGeometry(ring) geoms[i] = poly else: ring = ogr.Geometry(ogr.wkbLinearRing) for pt in coords: ring.AddPoint(float(pt[0]), float(pt[1])) poly = stdlib.Geometry2(ogr.wkbPolygon) poly.AddGeometry(ring) geoms[0] = poly return geoms
def build_point_geometries(x, y): """ Builds stdlib Geometry objects from a list of x and y coordinates :param x: single value, list, or numpy array of x coordinates :param y: single value, list, or numpy array of y coordinates :return: numpy array of stdlib geometries """ # try to convert x,y coordinates into numpy arrays if type(x) != type(y): elog.critical( 'Could not convert the x,y coordinates into numpy array objects: X and Y types do not match' ) return None try: if not isinstance(x, numpy.ndarray) and not isinstance( y, numpy.ndarray): if (isinstance(x, list) or isinstance(x, tuple)) and (isinstance( y, list) or isinstance(y, tuple)): x = numpy.asarray(x) y = numpy.asarray(y) else: x = numpy.array([x]) y = numpy.array([y]) except: elog.critical( 'Could not convert the x,y coordinates into numpy array objects!') return None geoms = numpy.empty((x.shape[0]), dtype=object) for i in range(len(x)): point = stdlib.Geometry2(ogr.wkbPoint) # point = ogr.Geometry(ogr.wkbPoint) point.AddPoint(float(x[i]), float(y[i])) geoms[i] = point return geoms
def load_links(self, links): # get all known transformations space = SpatialInterpolation() time = TemporalInterpolation() spatial_transformations = {i.name(): i for i in space.methods()} temporal_transformations = {i.name(): i for i in time.methods()} links_to_add = [] for link in links: # get 'from' and 'to' model attributes from_model_id = link['from_id'] from_model_item = link['from_item'] from_model_name = link['from_name'] to_model_id = link['to_id'] to_model_item = link['to_item'] to_model_name = link['to_name'] from_model = self.get_model_object_from_ID(from_model_id) to_model = self.get_model_object_from_ID(to_model_id) if from_model is None or to_model is None: elog.critical("Failed to create link between %s and %s." % (from_model_name, to_model_name)) sPrint("Failed to create link between %s and %s." % (from_model_name, to_model_name), MessageType.CRITICAL) return sPrint('Adding link between: %s and %s... ' % (from_model_name, to_model_name)) # get the spatial and temporal transformations temporal_transformation_name = link['temporal_transformation'] spatial_transformation_name = link['spatial_transformation'] # set the transformation values temporal = temporal_transformations[temporal_transformation_name] if temporal_transformation_name.lower() != 'none' else None spatial = spatial_transformations[spatial_transformation_name] if spatial_transformation_name.lower() != 'none' else None # create the link engine.addLink(source_id=from_model_id, source_item=from_model_item, target_id=to_model_id, target_item=to_model_item, spatial_interpolation=spatial, temporal_interpolation=temporal) links_to_add.append([from_model, to_model]) wx.CallAfter(self.createLoadedLinks, links_to_add)
def build_point_geometries(x, y): """ Builds stdlib Geometry objects from a list of x and y coordinates :param x: single value, list, or numpy array of x coordinates :param y: single value, list, or numpy array of y coordinates :return: numpy array of stdlib geometries """ # try to convert x,y coordinates into numpy arrays if type(x) != type(y): elog.critical('Could not convert the x,y coordinates into numpy array objects: X and Y types do not match') return None try: if not isinstance(x, numpy.ndarray) and not isinstance(y, numpy.ndarray): if (isinstance(x, list) or isinstance(x, tuple) ) and ( isinstance(y, list) or isinstance(y, tuple) ): x = numpy.asarray(x) y = numpy.asarray(y) else: x = numpy.array([x]) y = numpy.array([y]) except: elog.critical('Could not convert the x,y coordinates into numpy array objects!') return None geoms = numpy.empty((x.shape[0]), dtype=object) for i in range(len(x)): point = stdlib.Geometry2(ogr.wkbPoint) # point = ogr.Geometry(ogr.wkbPoint) point.AddPoint(float(x[i]), float(y[i])) geoms[i] = point return geoms
import stdlib from emitLogging import elog from sprint import * from utilities import mdl, geometry from wrappers import feed_forward import datetime import shutil # make sure that the win32com library is installed. This is required for weap to run. try: import win32com.client as com except: msg = 'Error loading WEAP model, missing required library: Win32com.' msg_ext = 'This can be installed by issuing the following command:\n\t"pip install pypiwin32"\n' sPrint(msg + msg_ext, MessageType.CRITICAL) elog.critical(msg) raise Exception(msg) class weap(feed_forward.Wrapper): def __init__(self, config_params): """ initialization that will occur when loaded into a configuration """ super(weap, self).__init__(config_params) sPrint('WEAP Model - Begin Component Initialization') # open WEAP via COM try:
def run(self, inputs): # todo: Do ts variable all have the same shape (i.e. same timestep?) # NOTES: # C_tsvarArray (or RegArray in RunUEB C code) stores the time series values for all inputs # C_tsvarArray[0] --> Ta (air temp) # C_tsvarArray[1] --> Precipitation (mm/day) # C_tsvarArray[2] --> V (wind speed) # C_tsvarArray[3] --> RH (relative humidity) # C_tsvarArray[4] --> atmospheric pressure ? # C_tsvarArray[5] --> Qsiobs # C_tsvarArray[6] --> Qli # C_tsvarArray[7] --> Qnetob # C_tsvarArray[8] --> Qg # C_tsvarArray[9] --> Snowalb # C_tsvarArray[10] --> Tmin # C_tsvarArray[11] --> Tmax # C_tsvarArray[12] --> Vapor Pressure of air # # get output exchange items # self.swe = self.outputs()['Snow Water Equivalent'] # swit = self.outputs()['Surface Water Input Total'] try: # Initialize SiteState SiteState = numpy.zeros((32,)) # loop over all activeCells for i in xrange(len(self.activeCells)): # todo: remove, this is for debugging # if i > 10: # break # track grid cell self.C_uebCellY = self.activeCells[i][0] self.C_uebCellX = self.activeCells[i][1] for s in xrange(32): if self.C_strsvArray.contents[s].svType == 1: SiteState[s] = self.C_strsvArray.contents[s].svArrayValues[self.C_uebCellY][self.C_uebCellX] else: SiteState[s] = self.C_strsvArray.contents[s].svdefValue # convert SiteState into a ctype C_SiteState = (c_float * len(SiteState))(*SiteState) # todo: get all data at beginning of run, then slice as necessary here # get the input data for the current geometry prcp = self.inputs()['Precipitation'].getValues2(geom_idx_start=i, geom_idx_end=i) temp = self.inputs()['Temperature'].getValues2(geom_idx_start=i, geom_idx_end=i) # skip calculation if no temperatures are provided for the current point (i.e completely missing data) if max(temp[:-1]) > 0: # set the input data for this geometry for idx in range(len(prcp)): # set air temperature and precipitation values in tsvarArray (index 0 and 1) self.C_tsvarArray.contents[0][idx] = temp[idx][0] self.C_tsvarArray.contents[1][idx] = prcp[idx][0] # RUN THE UEB CALCS self.__uebLib.RUNUEB(self.C_tsvarArray, C_SiteState, self.C_parvalArray, byref(pointer(self.C_outvarArray)), self.C_ModelStartDate, self.C_ModelStartHour, self.C_ModelEndDate, self.C_ModelEndHour, self.C_ModelDt, self.C_ModelUTCOffset) # outvararray 70var * numtimesteps # set output data numtimesteps = len(self.__swe.getDates2()) values = numpy.array(self.C_outvarArray[17][0:numtimesteps]) # convert C_type into numpy array values[numpy.isnan(values)] = self.__swe.noData() # set nan values to noData self.__swe.setValuesBySlice(values, geometry_index_slice=(i, i+1, 1)) # set data in wrapper values = numpy.array(self.C_outvarArray[25][0:numtimesteps]) # convert C_type into numpy array values[numpy.isnan(values)] = self.__swit.noData() # set nan values to noData self.__swit.setValuesBySlice(values, geometry_index_slice=(i, i+1, 1)) # set data in wrapper # if i % round((len(self.activeCells)) / 10) == 0: # print "%d of %d elements complete " % ((i+1), len(self.activeCells)) # sys.stdout.flush() # elog.info("... %d of %d elements complete " % ((i+1), len(self.activeCells)), overwrite=True) except Exception, e: elog.critical('UEB run failed: %s' % e) sPrint('An error was encountered while running the UEB model: %s' % e) return False
def run(self, inputs): # todo: Do ts variable all have the same shape (i.e. same timestep?) # NOTES: # C_tsvarArray (or RegArray in RunUEB C code) stores the time series values for all inputs # C_tsvarArray[0] --> Ta (air temp) # C_tsvarArray[1] --> Precipitation (mm/day) # C_tsvarArray[2] --> V (wind speed) # C_tsvarArray[3] --> RH (relative humidity) # C_tsvarArray[4] --> atmospheric pressure ? # C_tsvarArray[5] --> Qsiobs # C_tsvarArray[6] --> Qli # C_tsvarArray[7] --> Qnetob # C_tsvarArray[8] --> Qg # C_tsvarArray[9] --> Snowalb # C_tsvarArray[10] --> Tmin # C_tsvarArray[11] --> Tmax # C_tsvarArray[12] --> Vapor Pressure of air # # get output exchange items # self.swe = self.outputs()['Snow Water Equivalent'] # swit = self.outputs()['Surface Water Input Total'] try: # Initialize SiteState SiteState = numpy.zeros((32, )) # loop over all activeCells for i in xrange(len(self.activeCells)): # todo: remove, this is for debugging # if i > 10: # break # track grid cell self.C_uebCellY = self.activeCells[i][0] self.C_uebCellX = self.activeCells[i][1] for s in xrange(32): if self.C_strsvArray.contents[s].svType == 1: SiteState[s] = self.C_strsvArray.contents[ s].svArrayValues[self.C_uebCellY][self.C_uebCellX] else: SiteState[s] = self.C_strsvArray.contents[s].svdefValue # convert SiteState into a ctype C_SiteState = (c_float * len(SiteState))(*SiteState) # todo: get all data at beginning of run, then slice as necessary here # get the input data for the current geometry prcp = self.inputs()['Precipitation'].getValues2( geom_idx_start=i, geom_idx_end=i) temp = self.inputs()['Temperature'].getValues2( geom_idx_start=i, geom_idx_end=i) # skip calculation if no temperatures are provided for the current point (i.e completely missing data) if max(temp[:-1]) > 0: # set the input data for this geometry for idx in range(len(prcp)): # set air temperature and precipitation values in tsvarArray (index 0 and 1) self.C_tsvarArray.contents[0][idx] = temp[idx][0] self.C_tsvarArray.contents[1][idx] = prcp[idx][0] # RUN THE UEB CALCS self.__uebLib.RUNUEB( self.C_tsvarArray, C_SiteState, self.C_parvalArray, byref(pointer(self.C_outvarArray)), self.C_ModelStartDate, self.C_ModelStartHour, self.C_ModelEndDate, self.C_ModelEndHour, self.C_ModelDt, self.C_ModelUTCOffset) # outvararray 70var * numtimesteps # set output data numtimesteps = len(self.__swe.getDates2()) values = numpy.array( self.C_outvarArray[17] [0:numtimesteps]) # convert C_type into numpy array values[numpy.isnan( values)] = self.__swe.noData() # set nan values to noData self.__swe.setValuesBySlice( values, geometry_index_slice=(i, i + 1, 1)) # set data in wrapper values = numpy.array( self.C_outvarArray[25] [0:numtimesteps]) # convert C_type into numpy array values[numpy.isnan( values)] = self.__swit.noData() # set nan values to noData self.__swit.setValuesBySlice( values, geometry_index_slice=(i, i + 1, 1)) # set data in wrapper # if i % round((len(self.activeCells)) / 10) == 0: # print "%d of %d elements complete " % ((i+1), len(self.activeCells)) # sys.stdout.flush() # elog.info("... %d of %d elements complete " % ((i+1), len(self.activeCells)), overwrite=True) except Exception, e: elog.critical('UEB run failed: %s' % e) sPrint('An error was encountered while running the UEB model: %s' % e) return False
def build_exchange_items_from_config(params): # get all inputs and outputs iitems = params['input'] if 'input' in params else [] oitems = params['output'] if 'output' in params else [] eitems = iitems + oitems items = {stdlib.ExchangeItemType.INPUT:[],stdlib.ExchangeItemType.OUTPUT:[]} # loop through each input/output and create an exchange item for io in eitems: variable = None unit = None srs = None geoms = [] # get all input and output exchange items as a list iotype = stdlib.ExchangeItemType.OUTPUT if io['type'].upper() == stdlib.ExchangeItemType.OUTPUT else stdlib.ExchangeItemType.INPUT for key, value in io.iteritems(): sPrint(key, MessageType.DEBUG) if key == 'variable_name_cv': sPrint('Creating Variable', MessageType.DEBUG) variable = create_variable(value) sPrint('Done Creating Variable', MessageType.DEBUG) if 'variable_definition' in io.keys(): variable.VariableDefinition(io['variable_definition']) elif key == 'unit_type_cv': unit = create_unit(value) elif key == 'elementset' : # check if the value is a path if os.path.dirname(value ) != '': gen_path = os.path.abspath(os.path.join(params['basedir'],value)) if not os.path.isfile(gen_path): # get filepath relative to *.mdl elog.critical('Could not find file at path %s, generated from relative path %s'%(gen_path, value)) raise Exception('Could not find file at path %s, generated from relative path %s'%(gen_path, value)) # parse the geometry from the shapefile geoms, srs = utilities.spatial.read_shapefile(gen_path) srs = srs.AutoIdentifyEPSG() # otherwise it must be a wkt else: try: # get the wkt text string value = value.strip('\'').strip('"') # parse the wkt string into a stdlib.Geometry object geom = utilities.geometry.fromWKT(value) for g in geom: geoms.append(g) except: elog.warning('Could not load component geometry from *.mdl file') # this is OK. Just set the geoms to [] and assume that they will be populated during initialize. geom = [] if 'espg_code' in io: srs = utilities.spatial.get_srs_from_epsg(io['epsg_code']) # generate a unique uuid for this exchange item id = uuid.uuid4().hex # create exchange item ei = stdlib.ExchangeItem(id, name=variable.VariableNameCV(), desc=variable.VariableDefinition(), unit= unit, variable=variable, # srs_epsg=srs, #todo: this is causing problems type=iotype) # add geometry to exchange item (NEW) ei.addGeometries2(geoms) # save exchange items based on type items[ei.type()].append(ei) return items
import stdlib from emitLogging import elog from sprint import * from utilities import mdl, geometry from wrappers import feed_forward import datetime import shutil # make sure that the win32com library is installed. This is required for weap to run. try: import win32com.client as com except: msg = 'Error loading WEAP model, missing required library: Win32com.' msg_ext = 'This can be installed by issuing the following command:\n\t"pip install pypiwin32"\n' sPrint(msg+msg_ext, MessageType.CRITICAL) elog.critical(msg) raise Exception(msg) class weap(feed_forward.Wrapper): def __init__(self,config_params): """ initialization that will occur when loaded into a configuration """ super(weap,self).__init__(config_params) sPrint('WEAP Model - Begin Component Initialization') # open WEAP via COM
def run_feed_forward(obj, ds=None): """ executes a feed forward coupled model simulation Args: obj: engine coordinator object ds: dataSaveInfo object Returns: None """ # set engine status obj.status.set(stdlib.Status.NOTREADY) # todo: determine unresolved exchange items (utilities) sim_st = time.time() # determine execution order elog.info("Determining execution order... ") sPrint("Determining execution order... ", MessageType.INFO) exec_order = obj.determine_execution_order() for i in range(0, len(exec_order)): elog.info("%d.) %s" % (i + 1, obj.get_model(model_id=exec_order[i]).name())) links = {} spatial_maps = {} # todo: move this into function elog.info("Generating spatial maps... ") sPrint("Generating spatial maps... ") for modelid in exec_order: # get links l = obj.get_from_links_by_model(modelid) links[modelid] = l # build spatial maps for linkid, link in l.iteritems(): source = link.source_exchange_item() target = link.target_exchange_item() key = generate_link_key(link) # set default spatial interpolation to ExactMatch if link.spatial_interpolation() is None: sPrint( "Spatial interpolation not provided, using the default mapping approach: 'Spatial Index'", MessageType.WARNING, ) link.spatial_interpolation(spatial_index()) spatial_interp = link.spatial_interpolation() source_geoms = source.getGeometries2() target_geoms = target.getGeometries2() if len(source_geoms) == 0: sPrint( "Cannot continue simulation, %s -- %s contains 0 geometries" % link.source_component().name(), source.name(), ) if len(target_geoms) == 0: sPrint( "Cannot continue simulation, %s -- %s contains 0 geometries" % link.target_component().name(), target.name(), ) # save the spatial mapping based on link key spatial_maps[key] = spatial_interp.transform(source_geoms, target_geoms) # prepare all models for modelid in exec_order: model_inst = obj.get_model_object(modelid).instance() model_inst.prepare() if model_inst.status() != stdlib.Status.READY: msg = ( 'Cannot continue with simulation because model "%s" has a status of "%s" after the preparation' ' phase. Status must be "%s" in order to proceed with simulation ' % (model_inst.name(), model_inst.status(), stdlib.Status.READY) ) elog.critical(msg) sPrint(msg, MessageType.ERROR) return False # update engine status obj.status.set(stdlib.Status.READY) # loop through models and execute run for modelid in exec_order: # update engine status obj.status.set(stdlib.Status.RUNNING) st = time.time() # get the current model instance model_inst = obj.get_model_object(modelid).instance() sPrint("Executing module: %s \n" % model_inst.name(), MessageType.INFO) try: # retrieve inputs from database sPrint("[1 of 3] Retrieving input data... ") input_data = model_inst.inputs() # pass these inputs ts to the models' run function sPrint("[2 of 3] Performing calculation... ") model_inst.run(input_data) # update links sPrint("[3 of 3] Updating links... ") oei = model_inst.outputs() update.update_links_feed_forward(links[modelid], oei, spatial_maps) model_inst.finish() elog.info("..module simulation completed in %3.2f seconds" % (time.time() - st)) except Exception: # set the model status to failed model_inst.status(stdlib.Status.FAILED) return # raise Exception('Error during model execution') # set the model status to successful model_inst.status(stdlib.Status.SUCCESS) sPrint( "------------------------------------------\n" + " Simulation Summary \n" + "------------------------------------------\n" + "Completed without error :)\n" + "Simulation duration: %3.2f seconds\n" % (time.time() - sim_st) + "------------------------------------------" ) # update engine status obj.status.set(stdlib.Status.SUCCESS) # save simulation results model_ids = exec_order if ds is None: msg = "Simulation results will not be stored in database because database connection was not provided prior to simulation." elog.info(msg) sPrint(msg, messageType=MessageType.INFO) else: database.save(obj, ds, model_ids)
def run_feed_forward(obj, ds=None): """ executes a feed forward coupled model simulation Args: obj: engine coordinator object ds: dataSaveInfo object Returns: None """ # set engine status obj.status.set(stdlib.Status.NOTREADY) # todo: determine unresolved exchange items (utilities) sim_st = time.time() # determine execution order elog.info('Determining execution order... ') sPrint('Determining execution order... ', MessageType.INFO) exec_order = obj.determine_execution_order() for i in range(0, len(exec_order)): elog.info('%d.) %s' % (i + 1, obj.get_model(model_id=exec_order[i]).name())) links = {} spatial_maps = {} # todo: move this into function elog.info('Generating spatial maps... ') sPrint('Generating spatial maps... ') for modelid in exec_order: # get links l = obj.get_from_links_by_model(modelid) links[modelid] = l # build spatial maps for linkid, link in l.iteritems(): source = link.source_exchange_item() target = link.target_exchange_item() key = generate_link_key(link) # set default spatial interpolation to ExactMatch if link.spatial_interpolation() is None: sPrint('Spatial interpolation not provided, using the default mapping approach: \'Spatial Index\'', MessageType.WARNING) link.spatial_interpolation(spatial_index()) spatial_interp = link.spatial_interpolation() source_geoms = source.getGeometries2() target_geoms = target.getGeometries2() if len(source_geoms) == 0: sPrint('Cannot continue simulation, %s -- %s contains 0 geometries' % link.source_component().name(), source.name() ) if len(target_geoms) == 0: sPrint('Cannot continue simulation, %s -- %s contains 0 geometries' % link.target_component().name(), target.name()) # save the spatial mapping based on link key spatial_maps[key] = spatial_interp.transform(source_geoms, target_geoms) # prepare all models for modelid in exec_order: model_inst = obj.get_model_object(modelid).instance() model_inst.prepare() if model_inst.status() != stdlib.Status.READY: msg = 'Cannot continue with simulation because model "%s" has a status of "%s" after the preparation' \ ' phase. Status must be "%s" in order to proceed with simulation ' \ % (model_inst.name(), model_inst.status(), stdlib.Status.READY) elog.critical(msg) sPrint(msg, MessageType.ERROR) return False # update engine status obj.status.set(stdlib.Status.READY) # loop through models and execute run for modelid in exec_order: # update engine status obj.status.set(stdlib.Status.RUNNING) st = time.time() # get the current model instance model_inst = obj.get_model_object(modelid).instance() sPrint('Executing module: %s \n' % model_inst.name(), MessageType.INFO) try: # retrieve inputs from database sPrint("[1 of 3] Retrieving input data... ") input_data = model_inst.inputs() # pass these inputs ts to the models' run function sPrint("[2 of 3] Performing calculation... ") model_inst.run(input_data) # update links sPrint("[3 of 3] Updating links... ") oei = model_inst.outputs() update.update_links_feed_forward(links[modelid], oei, spatial_maps) model_inst.finish() elog.info('..module simulation completed in %3.2f seconds' % (time.time() - st)) except Exception: # set the model status to failed model_inst.status(stdlib.Status.FAILED) return # raise Exception('Error during model execution') # set the model status to successful model_inst.status(stdlib.Status.SUCCESS) sPrint('------------------------------------------\n' + ' Simulation Summary \n' + '------------------------------------------\n' + 'Completed without error :)\n' + 'Simulation duration: %3.2f seconds\n' % (time.time() - sim_st) + '------------------------------------------') # update engine status obj.status.set(stdlib.Status.SUCCESS) # save simulation results model_ids = exec_order if ds is None: msg = 'Simulation results will not be stored in database because database connection was not provided prior to simulation.' elog.info(msg) sPrint(msg, messageType=MessageType.INFO) else: database.save(obj, ds, model_ids)