def collect_subbasin(payload, shapes): # Gather weather stations and their data # collectively to avoid re-reading stations # that are shared across huc-12s huc12_ws = nearest_weather_stations(shapes) # Find the weather stations unique across all huc12s unique_ws = {w.station: w for w in huc12_ws}.values() # Find largest time range for which ALL weather stations have values, # then limit all stations to that range. begyear = int(max([w.begyear for w in huc12_ws])) endyear = int(min([w.endyear for w in huc12_ws])) huc12_ws = [w._replace(begyear=begyear)._replace(endyear=endyear) for w in huc12_ws] # Gather the temp and prcp values for each unique weather stations unique_wd = weather_data(unique_ws, begyear, endyear) # Get the stations and averaged tmp/prcp data for a specific huc-12 def get_weather(watershed_id): ws = [w for w in huc12_ws if w.watershed_id == watershed_id] stations = [w.station for w in ws] temps_by_station = [unique_wd[0][station] for station in stations] prcps_by_station = [unique_wd[1][station] for station in stations] return (ws, (average_weather_data(temps_by_station), average_weather_data(prcps_by_station))) # Build the GMS data for each huc-12 return [ collect_data(convert_data(payload, wkaoi), aoi, watershed_id, get_weather(watershed_id)) for (wkaoi, watershed_id, aoi) in shapes ]
def get_weather_simulation_for_project(project, category): wss = nearest_weather_stations([(None, None, project.area_of_interest)]) data = [] errs = [] for ws in wss: url = settings.WEATHER_DATA_BUCKET_URL.format(category=category, station=ws.station) # Ensure the station exists, if not exit quickly res = requests.head(url) if not res.ok: errs.append(f'Error {res.status_code} while getting data for' f' {category}/{ws.station}') return {}, errs # Fetch and parse station weather data, noting any errors with closing(requests.get(url, stream=True)) as r: ws_data, ws_errs = get_weather_modifications(r.raw) data.append(ws_data) errs += ws_errs # Respond with errors, if any if errs: return {}, errs # Check that the datasets have the same characteristics for c in ['WxYrBeg', 'WxYrEnd', 'WxYrs']: s = set([d[c] for d in data]) if len(s) > 1: errs.append(f'{c} does not match in dataset: {s}') # Respond with errors, if any if errs: return {}, errs # Final result has characteristics of the first station (which would be # identical to all other stations), and the precipitation and temperature # data which is the mean of all stations. return { 'WxYrBeg': data[0]['WxYrBeg'], 'WxYrEnd': data[0]['WxYrEnd'], 'WxYrs': data[0]['WxYrs'], 'Prec': average_weather_data([d['Prec'] for d in data]), 'Temp': average_weather_data([d['Temp'] for d in data]), }, errs
def collect_data(geop_results, geojson, watershed_id=None, weather=None): geop_result = {k: v for r in geop_results for k, v in r.items()} geom = GEOSGeometry(geojson, srid=4326) area = geom.transform(5070, clone=True).area # Square Meters # Data Model is called z by convention z = settings.GWLFE_DEFAULTS.copy() z['watershed_id'] = watershed_id # Statically calculated lookup values z['DayHrs'] = day_lengths(geom) # Data from the Weather Stations dataset if weather is not None: ws, wd = weather else: ws = nearest_weather_stations([(None, watershed_id, geojson)]) z['Grow'] = growing_season(ws) z['Acoef'] = erosion_coeff(ws, z['Grow']) z['PcntET'] = et_adjustment(ws) z['WxYrBeg'] = int(max([w.begyear for w in ws])) z['WxYrEnd'] = int(min([w.endyear for w in ws])) z['WxYrs'] = z['WxYrEnd'] - z['WxYrBeg'] + 1 # Data from the County Animals dataset ag_lscp = ag_ls_c_p(geom) z['C'][0] = ag_lscp.hp_c z['C'][1] = ag_lscp.crop_c livestock_aeu, poultry_aeu, population = animal_energy_units(geom) z['AEU'] = livestock_aeu / (area * ACRES_PER_SQM) z['n41j'] = livestock_aeu z['n41k'] = poultry_aeu z['n41l'] = livestock_aeu + poultry_aeu z['NumAnimals'] = [int(population.get(animal, 0)) for animal in ANIMAL_KEYS] z['ManNitr'], z['ManPhos'] = manure_spread(z['AEU']) # Data from Streams dataset z['StreamLength'] = stream_length(geom) or 10 # Meters z['n42b'] = round(z['StreamLength'] / 1000, 1) # Kilometers # Data from Point Source Discharge dataset n_load, p_load, discharge = point_source_discharge(geom, area, drb=geom.within(DRB)) z['PointNitr'] = n_load z['PointPhos'] = p_load z['PointFlow'] = discharge # Data from National Weather dataset if weather is None: wd = weather_data(ws, z['WxYrBeg'], z['WxYrEnd']) temps_dict, prcps_dict = wd temps = average_weather_data(temps_dict.values()) prcps = average_weather_data(prcps_dict.values()) else: temps, prcps = wd z['Temp'] = temps z['Prec'] = prcps # Begin processing geop_result # Set stream related variables to zero if AoI does not contain # any streams. if 'ag_stream_pct' in geop_result: z['AgLength'] = geop_result['ag_stream_pct'] * z['StreamLength'] z['UrbLength'] = z['StreamLength'] - z['AgLength'] z['n42'] = round(z['AgLength'] / 1000, 1) z['n46e'] = (geop_result['med_high_urban_stream_pct'] * z['StreamLength'] / 1000) z['n46f'] = (geop_result['low_urban_stream_pct'] * z['StreamLength'] / 1000) else: z['AgLength'] = 0 z['UrbLength'] = 0 z['n42'] = 0 z['n46e'] = 0 z['n46f'] = 0 z['CN'] = geop_result['cn'] z['SedPhos'] = geop_result['soilp'] z['Area'] = [percent * area * HECTARES_PER_SQM for percent in geop_result['landuse_pcts']] # Immediately return an error if z['Area'] is a list of 0s if sum(z['Area']) == 0: raise Exception(NO_LAND_COVER) z['UrbAreaTotal'] = sum(z['Area'][NRur:]) z['PhosConc'] = phosphorus_conc(z['SedPhos']) z['NumNormalSys'] = num_normal_sys(z['Area']) z['AgSlope3'] = geop_result['ag_slope_3_pct'] * area * HECTARES_PER_SQM z['AgSlope3To8'] = (geop_result['ag_slope_3_8_pct'] * area * HECTARES_PER_SQM) z['n41'] = geop_result['n41'] z['AvSlope'] = geop_result['avg_slope'] z['AvKF'] = geop_result['avg_kf'] z['KF'] = geop_result['kf'] z['KV'] = kv_coefficient(geop_result['landuse_pcts'], z['Grow']) # Original at [email protected]:9803-9807 z['n23'] = z['Area'][1] # Row Crops Area z['n23b'] = z['Area'][13] # High Density Mixed Urban Area z['n24'] = z['Area'][0] # Hay/Pasture Area z['n24b'] = z['Area'][11] # Low Density Mixed Urban Area z['SedDelivRatio'] = sediment_delivery_ratio(area * SQKM_PER_SQM) z['TotArea'] = area * HECTARES_PER_SQM z['GrNitrConc'] = geop_result['gr_nitr_conc'] z['GrPhosConc'] = geop_result['gr_phos_conc'] z['MaxWaterCap'] = geop_result['avg_awc'] z['SedAFactor'] = sed_a_factor(geop_result['landuse_pcts'], z['CN'], z['AEU'], z['AvKF'], z['AvSlope']) # Use zeroed out stream variables if there are no streams in the AoI if 'lu_stream_pct' in geop_result: z['LS'] = ls_factors(geop_result['lu_stream_pct'], z['StreamLength'], z['Area'], z['AvSlope'], ag_lscp) else: zeroed_lu_stream_pct = [0.0] * 16 z['LS'] = ls_factors(zeroed_lu_stream_pct, 0, z['Area'], z['AvSlope'], ag_lscp) z['P'] = p_factors(z['AvSlope'], ag_lscp) z['SedNitr'] = geop_result['soiln'] z['RecessionCoef'] = geop_result['recess_coef'] return z