def avgWinds(self): if not self.aSknt: self.sped = None self.drct = None return self.avg_sknt = int(float(sum(self.aSknt)) / float(len(self.aSknt))) utot = 0 vtot = 0 for s, d in zip(self.aSknt, self.aDrct): u, v = uv(s, d) if s > self.xsped: self.xsped = s * 1.150 self.xdrct = d self.xdrctTxt = util.drct2text(d) utot += u vtot += v uavg = utot / len(self.aSknt) vavg = vtot / len(self.aSknt) self.avg_drct = mydir(uavg, vavg) self.avg_drctTxt = util.drct2text(self.avg_drct) self.aSknt = [] self.aDrct = []
def test_drct2text(): """ Test conversion of drct2text """ assert util.drct2text(360) == "N" assert util.drct2text(90) == "E" # A hack to get move coverage for i in range(360): util.drct2text(i)
def computeOthers(d): r = {} # Need something to compute other values needed for output for sid in d.keys(): ob = d[sid] ob["ticks"] = calendar.timegm(ob['utc_valid'].timetuple()) if ob['sknt'] is not None: ob["sped"] = ob["sknt"] * 1.17 if ob.get('tmpf') is not None and ob.get('dwpf') is not None: tmpf = temperature(ob['tmpf'], 'F') dwpf = temperature(ob['dwpf'], 'F') ob["relh"] = meteorology.relh(tmpf, dwpf).value('%') else: ob['relh'] = None if ob['relh'] == 'M': ob['relh'] = None if (ob.get('tmpf') is not None and ob.get('dwpf') is not None and ob.get('sped') is not None): ob['feel'] = meteorology.mcalc_feelslike( masked_array([ob['tmpf'], ], units('degF'), mask=[False, ]), masked_array([ob['dwpf'], ], units('degF'), mask=[False, ]), masked_array([ob['sped'], ], units('mile per hour'), mask=[False, ]) ).to(units('degF')).magnitude[0] else: ob['feel'] = None if ob['feel'] == 'M': ob['feel'] = None ob["altiTend"] = 'S' ob["drctTxt"] = util.drct2text(ob["drct"]) if ob["max_drct"] is None: ob["max_drct"] = 0 ob["max_drctTxt"] = util.drct2text(ob["max_drct"]) ob["20gu"] = 0 if ob['gust'] is not None: ob["gmph"] = ob["gust"] * 1.17 if ob['max_gust'] is not None: ob["max_sped"] = ob["max_gust"] * 1.17 else: ob['max_sped'] = 0 ob['pday'] = 0 if ob['pday'] is None else ob['pday'] ob['pmonth'] = 0 if ob['pmonth'] is None else ob['pmonth'] ob["gtim"] = "0000" ob["gtim2"] = "12:00 AM" if ob["max_gust_ts"] is not None and ob["max_gust_ts"] != "null": ob["gtim"] = ob["max_gust_ts"].strftime("%H%M") ob["gtim2"] = ob["max_gust_ts"].strftime("%-I:%M %p") r[sid] = ob return r
def computeOthers(d): r = {} # Need something to compute other values needed for output for sid in d.keys(): ob = d[sid] ob["ticks"] = calendar.timegm(ob['utc_valid'].timetuple()) if ob['sknt'] is not None: ob["sped"] = ob["sknt"] * 1.17 if ob.get('tmpf') is not None and ob.get('dwpf') is not None: tmpf = temperature(ob['tmpf'], 'F') dwpf = temperature(ob['dwpf'], 'F') ob["relh"] = meteorology.relh(tmpf, dwpf).value('%') else: ob['relh'] = None if ob['relh'] == 'M': ob['relh'] = None if (ob.get('tmpf') is not None and ob.get('dwpf') is not None and ob.get('sped') is not None): tmpf = temperature(ob['tmpf'], 'F') dwpf = temperature(ob['dwpf'], 'F') sknt = speed(ob['sped'], 'MPH') ob["feel"] = meteorology.feelslike(tmpf, dwpf, sknt).value("F") else: ob['feel'] = None if ob['feel'] == 'M': ob['feel'] = None ob["altiTend"] = 'S' ob["drctTxt"] = util.drct2text(ob["drct"]) if ob["max_drct"] is None: ob["max_drct"] = 0 ob["max_drctTxt"] = util.drct2text(ob["max_drct"]) ob["20gu"] = 0 if ob['gust'] is not None: ob["gmph"] = ob["gust"] * 1.17 if ob['max_gust'] is not None: ob["max_sped"] = ob["max_gust"] * 1.17 else: ob['max_sped'] = 0 ob['pday'] = 0 if ob['pday'] is None else ob['pday'] ob['pmonth'] = 0 if ob['pmonth'] is None else ob['pmonth'] ob["gtim"] = "0000" ob["gtim2"] = "12:00 AM" if ob["max_gust_ts"] is not None and ob["max_gust_ts"] != "null": ob["gtim"] = ob["max_gust_ts"].strftime("%H%M") ob["gtim2"] = ob["max_gust_ts"].strftime("%-I:%M %p") r[sid] = ob return r
def wind_message(self): """Convert this into a Jabber style message""" drct = 0 sknt = 0 time = self.time.replace(tzinfo=timezone.utc) if self.wind_gust: sknt = self.wind_gust.value("KT") if self.wind_dir: drct = self.wind_dir.value() if self.wind_speed_peak: v1 = self.wind_speed_peak.value("KT") d1 = self.wind_dir_peak.value() t1 = self.peak_wind_time.replace(tzinfo=timezone.utc) if v1 > sknt: sknt = v1 drct = d1 time = t1 key = "%s;%s;%s" % (self.station_id, sknt, time) if key not in WIND_ALERTS: WIND_ALERTS[key] = 1 speed = datatypes.speed(sknt, "KT") return ("gust of %.0f knots (%.1f mph) from %s @ %s") % ( speed.value("KT"), speed.value("MPH"), drct2text(drct), time.strftime("%H%MZ"), )
def plotter(fdict): """ Go """ import matplotlib matplotlib.use('agg') import matplotlib.pyplot as plt import matplotlib.patheffects as PathEffects pgconn = psycopg2.connect(database='iem', host='iemdb', user='******') cursor = pgconn.cursor(cursor_factory=psycopg2.extras.DictCursor) station = fdict.get('zstation', 'AMW') network = fdict.get('network', 'IA_ASOS') units = fdict.get('units', 'MPH').upper() if units not in PDICT: units = 'MPH' year = int(fdict.get('year', datetime.datetime.now().year)) month = int(fdict.get('month', datetime.datetime.now().month)) sts = datetime.date(year, month, 1) ets = (sts + datetime.timedelta(days=35)).replace(day=1) nt = NetworkTable(network) cursor.execute(""" SELECT day, avg_sknt, vector_avg_drct from summary s JOIN stations t ON (t.iemid = s.iemid) WHERE t.id = %s and t.network = %s and s.day >= %s and s.day < %s ORDER by day ASC """, (station, network, sts, ets)) days = [] drct = [] sknt = [] for row in cursor: if row[1] is None: continue days.append(row[0].day) drct.append(row[2]) sknt.append(row[1]) if len(sknt) == 0: return "ERROR: No Data Found" df = pd.DataFrame(dict(day=pd.Series(days), drct=pd.Series(drct), sknt=pd.Series(sknt))) sknt = speed(np.array(sknt), 'KT').value(units) (fig, ax) = plt.subplots(1, 1) ax.bar(np.array(days)-0.4, sknt, ec='green', fc='green') pos = max([min(sknt) / 2.0, 0.5]) for d, _, r in zip(days, sknt, drct): draw_line(plt, d, max(sknt)+0.5, (270. - r) / 180. * np.pi) txt = ax.text(d, pos, drct2text(r), ha='center', rotation=90, color='white', va='center') txt.set_path_effects([PathEffects.withStroke(linewidth=2, foreground="k")]) ax.grid(True, zorder=11) ax.set_title(("%s [%s]\n%s Daily Average Wind Speed and Direction" ) % (nt.sts[station]['name'], station, sts.strftime("%b %Y"))) ax.set_xlim(0.5, max(days)+0.5) ax.set_ylim(top=max(sknt)+2) ax.set_ylabel("Average Wind Speed [%s]" % (PDICT.get(units),)) return fig, df
def plotter(fdict): """ Go """ pgconn = get_dbconn('iem') cursor = pgconn.cursor(cursor_factory=psycopg2.extras.DictCursor) ctx = get_autoplot_context(fdict, get_description()) station = ctx['zstation'] network = ctx['network'] units = ctx['units'] year = ctx['year'] month = ctx['month'] sts = datetime.date(year, month, 1) ets = (sts + datetime.timedelta(days=35)).replace(day=1) nt = NetworkTable(network) cursor.execute( """ SELECT day, avg_sknt, vector_avg_drct from summary s JOIN stations t ON (t.iemid = s.iemid) WHERE t.id = %s and t.network = %s and s.day >= %s and s.day < %s ORDER by day ASC """, (station, network, sts, ets)) days = [] drct = [] sknt = [] for row in cursor: if row[1] is None: continue days.append(row[0].day) drct.append(row[2]) sknt.append(row[1]) if not sknt: raise ValueError("ERROR: No Data Found") df = pd.DataFrame( dict(day=pd.Series(days), drct=pd.Series(drct), sknt=pd.Series(sknt))) sknt = speed(np.array(sknt), 'KT').value(units) (fig, ax) = plt.subplots(1, 1) ax.bar(np.array(days), sknt, ec='green', fc='green', align='center') pos = max([min(sknt) / 2.0, 0.5]) for d, _, r in zip(days, sknt, drct): draw_line(d, max(sknt) + 0.5, (270. - r) / 180. * np.pi) txt = ax.text(d, pos, drct2text(r), ha='center', rotation=90, color='white', va='center') txt.set_path_effects( [PathEffects.withStroke(linewidth=2, foreground="k")]) ax.grid(True, zorder=11) ax.set_title(("%s [%s]\n%s Daily Average Wind Speed and Direction") % (nt.sts[station]['name'], station, sts.strftime("%b %Y"))) ax.set_xlim(0.5, 31.5) ax.set_xticks(range(1, 31, 5)) ax.set_ylim(top=max(sknt) + 2) ax.set_ylabel("Average Wind Speed [%s]" % (PDICT.get(units), )) return fig, df
def plotter(fdict): """ Go """ pgconn = get_dbconn("iem") ctx = get_autoplot_context(fdict, get_description()) station = ctx["zstation"] plot_units = ctx["units"] year = ctx["year"] month = ctx["month"] sts = datetime.date(year, month, 1) ets = (sts + datetime.timedelta(days=35)).replace(day=1) df = read_sql( """ SELECT day, avg_sknt as sknt, vector_avg_drct as drct from summary s JOIN stations t ON (t.iemid = s.iemid) WHERE t.id = %s and t.network = %s and s.day >= %s and s.day < %s and avg_sknt is not null ORDER by day ASC """, pgconn, params=(station, ctx["network"], sts, ets), ) if df.empty: raise NoDataFound("ERROR: No Data Found") df["day"] = pd.to_datetime(df["day"]) sknt = (df["sknt"].values * units("knot")).to(XREF_UNITS[plot_units]).m (fig, ax) = plt.subplots(1, 1) ax.bar(df["day"].dt.day.values, sknt, ec="green", fc="green", align="center") pos = max([min(sknt) / 2.0, 0.5]) for d, _, r in zip(df["day"].dt.day.values, sknt, df["drct"].values): draw_line(d, max(sknt) + 0.5, (270.0 - r) / 180.0 * np.pi) txt = ax.text( d, pos, drct2text(r), ha="center", rotation=90, color="white", va="center", ) txt.set_path_effects( [PathEffects.withStroke(linewidth=2, foreground="k")]) ax.grid(True, zorder=11) ax.set_title( ("%s [%s]\n%s Daily Average Wind Speed and Direction") % (ctx["_nt"].sts[station]["name"], station, sts.strftime("%b %Y"))) ax.set_xlim(0.5, 31.5) ax.set_xticks(range(1, 31, 5)) ax.set_ylim(top=max(sknt) + 2) ax.set_ylabel("Average Wind Speed [%s]" % (PDICT[plot_units], )) return fig, df
def plotter(fdict): """ Go """ import matplotlib matplotlib.use('agg') import matplotlib.pyplot as plt pgconn = psycopg2.connect(database='asos', host='iemdb', user='******') ctx = get_autoplot_context(fdict, get_description()) station = ctx['zstation'] network = ctx['network'] units = ctx['units'] nt = NetworkTable(network) df = read_sql(""" select date_trunc('hour', valid) as ts, avg(sknt) as sknt, max(drct) as drct from alldata WHERE station = %s and sknt is not null and drct is not null GROUP by ts """, pgconn, params=(station, ), parse_dates=('ts',), index_col=None) sknt = speed(df['sknt'].values, 'KT') drct = direction(df['drct'].values, 'DEG') df['u'], df['v'] = [x.value('MPS') for x in meteorology.uv(sknt, drct)] df['month'] = df['ts'].dt.month grp = df[['month', 'u', 'v', 'sknt']].groupby('month').mean() grp['u_%s' % (units,)] = speed(grp['u'].values, 'KT').value(units.upper()) grp['v_%s' % (units,)] = speed(grp['u'].values, 'KT').value(units.upper()) grp['sped_%s' % (units,)] = speed(grp['sknt'].values, 'KT').value(units.upper()) drct = meteorology.drct(speed(grp['u'].values, 'KT'), speed(grp['v'].values, 'KT')) grp['drct'] = drct.value('DEG') maxval = grp['sped_%s' % (units,)].max() (fig, ax) = plt.subplots(1, 1) ax.barh(grp.index.values, grp['sped_%s' % (units,)].values, align='center') ax.set_xlabel("Average Wind Speed [%s]" % (UNITS[units],)) ax.set_yticks(grp.index.values) ax.set_yticklabels(calendar.month_abbr[1:]) ax.grid(True) ax.set_xlim(0, maxval * 1.2) for mon, row in grp.iterrows(): ax.text(maxval * 1.1, mon, drct2text(row['drct']), ha='center', va='center', bbox=dict(color='white')) ax.text(row['sped_%s' % (units,)] * 0.98, mon, "%.1f" % (row['sped_%s' % (units,)],), ha='right', va='center', bbox=dict(color='white', boxstyle='square,pad=0.03',)) ax.set_ylim(12.5, 0.5) ax.set_title(("[%s] %s [%s-%s]\nMonthly Average Wind Speed and" " Vector Average Direction" ) % (station, nt.sts[station]['name'], df['ts'].min().year, df['ts'].max().year)) return fig, grp
def plotter(fdict): """ Go """ import matplotlib matplotlib.use('agg') import matplotlib.pyplot as plt pgconn = get_dbconn('asos') ctx = get_autoplot_context(fdict, get_description()) station = ctx['zstation'] network = ctx['network'] units = ctx['units'] nt = NetworkTable(network) df = read_sql(""" select date_trunc('hour', valid at time zone 'UTC') as ts, avg(sknt) as sknt, max(drct) as drct from alldata WHERE station = %s and sknt is not null and drct is not null GROUP by ts """, pgconn, params=(station, ), index_col=None) sknt = speed(df['sknt'].values, 'KT') drct = direction(df['drct'].values, 'DEG') df['u'], df['v'] = [x.value('MPS') for x in meteorology.uv(sknt, drct)] df['month'] = df['ts'].dt.month grp = df[['month', 'u', 'v', 'sknt']].groupby('month').mean() grp['u_%s' % (units,)] = speed(grp['u'].values, 'KT').value(units.upper()) grp['v_%s' % (units,)] = speed(grp['u'].values, 'KT').value(units.upper()) grp['sped_%s' % (units,)] = speed(grp['sknt'].values, 'KT').value(units.upper()) drct = meteorology.drct(speed(grp['u'].values, 'KT'), speed(grp['v'].values, 'KT')) grp['drct'] = drct.value('DEG') maxval = grp['sped_%s' % (units,)].max() (fig, ax) = plt.subplots(1, 1) ax.barh(grp.index.values, grp['sped_%s' % (units,)].values, align='center') ax.set_xlabel("Average Wind Speed [%s]" % (UNITS[units],)) ax.set_yticks(grp.index.values) ax.set_yticklabels(calendar.month_abbr[1:]) ax.grid(True) ax.set_xlim(0, maxval * 1.2) for mon, row in grp.iterrows(): ax.text(maxval * 1.1, mon, drct2text(row['drct']), ha='center', va='center', bbox=dict(color='white')) ax.text(row['sped_%s' % (units,)] * 0.98, mon, "%.1f" % (row['sped_%s' % (units,)],), ha='right', va='center', bbox=dict(color='white', boxstyle='square,pad=0.03',)) ax.set_ylim(12.5, 0.5) ax.set_title(("[%s] %s [%s-%s]\nMonthly Average Wind Speed and" " Vector Average Direction" ) % (station, nt.sts[station]['name'], df['ts'].min().year, df['ts'].max().year)) return fig, grp
def avgWinds(self): """My wind averager""" if not self.aSPED: self.sped = None self.drct = None return self.sped = sum(self.aSPED) / len(self.aSPED) utot = 0 vtot = 0 for i in range(len(self.aSPED)): u, v = uv(self.aSPED[i], self.aDrct[i]) utot += u vtot += v uavg = utot / len(self.aSPED) vavg = vtot / len(self.aSPED) self.drct = dir(uavg, vavg) self.drctTxt = util.drct2text(self.drct)
def do_imagework(cameras, cid, tokens, now): """Process the images""" # Hard coded... drct = cameras[cid]["pan0"] drct_text = util.drct2text(drct) # Create 320x240 variant fn = "165.206.203.34/rwis_images/Vid-000512%s.jpg" % ("-".join(tokens), ) try: i0 = Image.open(fn) i320 = i0.resize((320, 240), Image.ANTIALIAS) except Exception: if os.path.isfile(fn): os.unlink(fn) return draw = ImageDraw.Draw(i0) text = "(%s) %s %s" % ( drct_text, cameras[cid]["name"], now.strftime("%-2I:%M:%S %p - %d %b %Y"), ) (width, height) = FONT.getsize(text) draw.rectangle([5, 475 - height, 5 + width, 475], fill="#000000") draw.text((5, 475 - height), text, font=FONT) # Save 640x480 i0.save("%s-640x480.jpg" % (cid, )) draw = ImageDraw.Draw(i320) text = "(%s) %s %s" % ( drct_text, cameras[cid]["name"], now.strftime("%-2I:%M:%S %p - %d %b %Y"), ) (width, height) = FONT.getsize(text) draw.rectangle([5, 235 - height, 5 + width, 235], fill="#000000") draw.text((5, 235 - height), text, font=FONT) # Save 640x480 i320.save("%s-320x240.jpg" % (cid, )) del i0 del i320 return drct
def highcharts(fdict): """ Generate the highcharts variant""" import matplotlib matplotlib.use('agg') from windrose.windrose import histogram ctx = get_context(fdict) dir_edges, var_bins, table = histogram(ctx['df']['drct'].values, ctx['df']['smph'].values, np.array([0, 2, 5, 7, 10, 15, 20]), 18, True) arr = [drct2text(mydir) for mydir in dir_edges] return """ var arr = """ + str(arr) + """; $("#ap_container").highcharts({ series: [{name: '2 - 5', data: """ + str(zip(arr, table[1])) + """, _colorIndex: 0}, {name: '5 - 7', data: """ + str(zip(arr, table[2])) + """, _colorIndex: 1}, {name: '7 - 10', data: """ + str(zip(arr, table[3])) + """, _colorIndex: 2}, {name: '10 - 15', data: """ + str(zip(arr, table[4])) + """, _colorIndex: 3}, {name: '15 - 20', data: """ + str(zip(arr, table[5])) + """, _colorIndex: 4}, {name: '20 +', data: """ + str(zip(arr, table[6])) + """, _colorIndex: 5}], chart: { polar: true, type: 'column' }, title: { 'text': '""" + ctx['title'] + """' }, subtitle: { 'text': '""" + ctx['subtitle'] + """'
def highcharts(fdict): """ Generate the highcharts variant""" import matplotlib matplotlib.use('agg') from windrose.windrose import histogram ctx = get_context(fdict) dir_edges, var_bins, table = histogram(ctx['df']['drct'].values, ctx['df']['smph'].values, np.array([0, 2, 5, 7, 10, 15, 20]), 18, True) arr = [drct2text(mydir) for mydir in dir_edges] return """ var arr = """+str(arr)+"""; $("#ap_container").highcharts({ series: [{name: '2 - 5', data: """+str(zip(arr, table[1]))+""", _colorIndex: 0}, {name: '5 - 7', data: """+str(zip(arr, table[2]))+""", _colorIndex: 1}, {name: '7 - 10', data: """+str(zip(arr, table[3]))+""", _colorIndex: 2}, {name: '10 - 15', data: """+str(zip(arr, table[4]))+""", _colorIndex: 3}, {name: '15 - 20', data: """+str(zip(arr, table[5]))+""", _colorIndex: 4}, {name: '20 +', data: """+str(zip(arr, table[6]))+""", _colorIndex: 5}], chart: { polar: true, type: 'column' }, title: { 'text': '"""+ctx['title']+"""' }, subtitle: { 'text': '"""+ctx['subtitle']+"""'
def wind_message(self): """Convert this into a Jabber style message""" drct = 0 sknt = 0 time = self.time.replace(tzinfo=pytz.UTC) if self.wind_gust: sknt = self.wind_gust.value("KT") if self.wind_dir: drct = self.wind_dir.value() if self.wind_speed_peak: v1 = self.wind_speed_peak.value("KT") d1 = self.wind_dir_peak.value() t1 = self.peak_wind_time.replace(tzinfo=pytz.UTC) if v1 > sknt: sknt = v1 drct = d1 time = t1 key = "%s;%s;%s" % (self.station_id, sknt, time) if key not in WIND_ALERTS: WIND_ALERTS[key] = 1 speed = datatypes.speed(sknt, 'KT') return ("gust of %.0f knots (%.1f mph) from %s @ %s" ) % (speed.value('KT'), speed.value('MPH'), drct2text(drct), time.strftime("%H%MZ"))
def get_data(ts): """ Get the data for this timestamp """ iemcursor = IEM.cursor() cursor = ISUAG.cursor(cursor_factory=psycopg2.extras.DictCursor) qcdict = loadqc() nt = NetworkTable("ISUSM") data = { "type": "FeatureCollection", "crs": { "type": "EPSG", "properties": { "code": 4326, "coordinate_order": [1, 0] } }, "features": [] } # Fetch the daily values iemcursor.execute( """ SELECT id, pday, max_tmpf, min_tmpf from summary s JOIN stations t on (t.iemid = s.iemid) WHERE t.network = 'ISUSM' and day = %s """, (ts.date(), )) daily = {} for row in iemcursor: daily[row[0]] = { 'pday': row[1], 'max_tmpf': row[2], 'min_tmpf': row[3] } cursor.execute(""" SELECT * from sm_hourly where valid = %s """, (ts, )) for row in cursor: sid = row['station'] lon = nt.sts[sid]['lon'] lat = nt.sts[sid]['lat'] q = qcdict.get(sid, {}) data['features'].append({ "type": "Feature", "id": sid, "properties": { "encrh_avg": ("%s%%" % safe(row['encrh_avg'], 1) if row['encrh_avg'] > 0 else "M"), "rh": "%s%%" % (safe(row["rh"], 0), ), "hrprecip": (safe_p(row['rain_mm_tot']) if not q.get('precip', False) else 'M'), "et": safe_p(row['etalfalfa']), "bat": safe(row['battv_min'], 2), "radmj": safe(row['slrmj_tot'], 2), "tmpf": safe_t(row['tair_c_avg']), "high": safe_t(daily.get(sid, {}).get('max_tmpf', None), 'F'), "low": safe_t(daily.get(sid, {}).get('min_tmpf', None), 'F'), "pday": (safe(daily.get(sid, {}).get('pday', None), 2) if not q.get('precip', False) else 'M'), "soil04t": (safe_t(row['tsoil_c_avg']) if not q.get('soil4', False) else 'M'), "soil12t": (safe_t(row['t12_c_avg']) if not q.get('soil12', False) else 'M'), "soil24t": (safe_t(row['t24_c_avg']) if not q.get('soil24', False) else 'M'), "soil50t": (safe_t(row['t50_c_avg']) if not q.get('soil50', False) else 'M'), "soil12m": (safe_m(row['vwc_12_avg']) if not q.get('soil12', False) else 'M'), "soil24m": (safe_m(row['vwc_24_avg']) if not q.get('soil24', False) else 'M'), "soil50m": (safe_m(row['vwc_50_avg']) if not q.get('soil50', False) else 'M'), "gust": safe(row['ws_mph_max'], 1), "wind": ("%s@%.0f") % (drct2text(row['winddir_d1_wvt']), row['ws_mps_s_wvt'] * 2.23), 'name': nt.sts[sid]['name'] }, "geometry": { "type": "Point", "coordinates": [lon, lat] } }) sys.stdout.write(json.dumps(data))
def plotter(fdict): """ Go """ pgconn = get_dbconn("asos") ctx = get_autoplot_context(fdict, get_description()) station = ctx["zstation"] units = ctx["units"] df = read_sql( """ select date_trunc('hour', valid at time zone 'UTC') as ts, avg(sknt) as sknt, max(drct) as drct from alldata WHERE station = %s and sknt is not null and drct is not null GROUP by ts """, pgconn, params=(station, ), index_col=None, ) if df.empty: raise NoDataFound("No Data Found.") sknt = speed(df["sknt"].values, "KT") drct = direction(df["drct"].values, "DEG") df["u"], df["v"] = [x.value("MPS") for x in meteorology.uv(sknt, drct)] df["month"] = df["ts"].dt.month grp = df[["month", "u", "v", "sknt"]].groupby("month").mean() grp["u_%s" % (units, )] = speed(grp["u"].values, "KT").value(units.upper()) grp["v_%s" % (units, )] = speed(grp["u"].values, "KT").value(units.upper()) grp["sped_%s" % (units, )] = speed(grp["sknt"].values, "KT").value(units.upper()) drct = meteorology.drct(speed(grp["u"].values, "KT"), speed(grp["v"].values, "KT")) grp["drct"] = drct.value("DEG") maxval = grp["sped_%s" % (units, )].max() (fig, ax) = plt.subplots(1, 1) ax.barh(grp.index.values, grp["sped_%s" % (units, )].values, align="center") ax.set_xlabel("Average Wind Speed [%s]" % (UNITS[units], )) ax.set_yticks(grp.index.values) ax.set_yticklabels(calendar.month_abbr[1:]) ax.grid(True) ax.set_xlim(0, maxval * 1.2) for mon, row in grp.iterrows(): ax.text( maxval * 1.1, mon, drct2text(row["drct"]), ha="center", va="center", bbox=dict(color="white"), ) ax.text( row["sped_%s" % (units, )] * 0.98, mon, "%.1f" % (row["sped_%s" % (units, )], ), ha="right", va="center", bbox=dict(color="white", boxstyle="square,pad=0.03"), ) ax.set_ylim(12.5, 0.5) ax.set_title(("[%s] %s [%s-%s]\nMonthly Average Wind Speed and" " Vector Average Direction") % ( station, ctx["_nt"].sts[station]["name"], df["ts"].min().year, df["ts"].max().year, )) return fig, grp
continue t = tokens[0] cid = "IDOT-%s-%s" % (t[0], t[2]) gmt = datetime.datetime(int(t[3]), int(t[4]), int(t[5]), int(t[6]), int(t[7])) gmt = gmt.replace(tzinfo=pytz.timezone("UTC")) now = gmt.astimezone(pytz.timezone("America/Chicago")) if cid not in cameras: print "ingest_dot_webcams.py unknown CameraID: %s" % (cid, ) cameras[cid] = {'pan0': 0, 'name': 'unknown'} # Hard coded... d = cameras[cid] drct = d['pan0'] drctTxt = util.drct2text(drct) # Create 320x240 variant fn = "165.206.203.34/rwis_images/Vid-000512%s.jpg" % ("-".join(t), ) try: i0 = Image.open(fn) i320 = i0.resize((320, 240), Image.ANTIALIAS) except: if os.path.isfile(fn): os.unlink(fn) continue draw = ImageDraw.Draw(i0) s = "(%s) %s %s" % (drctTxt, d['name'], now.strftime("%-2I:%M:%S %p - %d %b %Y")) (w, h) = font.getsize(s)
def main(): ''' Go!''' ncursor.execute(""" DELETE from lsrs WHERE valid > %s and valid < %s """, (RT_T0 - datetime.timedelta(minutes=300), RT_T1 + datetime.timedelta(minutes=300))) print('Removed %s rows from nwa lsr table' % (ncursor.rowcount,)) # Get DMX coords in 26915 pcursor.execute("""SELECT ST_x( ST_transform( ST_GeomFromEWKT('SRID=4326;POINT(-93.723892 41.731220)'), 26915)) as x, ST_y( ST_transform( ST_GeomFromEWKT('SRID=4326;POINT(-93.723892 41.731220)'), 26915)) as y """) row = pcursor.fetchone() radx = row['x'] rady = row['y'] # Get all LSRs within 230m of the nexrad pcursor.execute("""SELECT *, ST_astext(geom) as tgeom, ST_x( ST_transform( geom, 26915) ) - ST_x( ST_transform( ST_GeomFromEWKT('SRID=4326;POINT(%s %s)'), 26915)) as offset_x, ST_y( ST_transform( geom, 26915) ) - ST_y( ST_transform( ST_GeomFromEWKT('SRID=4326;POINT(%s %s)'), 26915)) as offset_y from lsrs WHERE valid BETWEEN '%s' and '%s' and ST_distance( ST_transform(geom, 26915), ST_transform( ST_GeomFromEWKT('SRID=4326;POINT(%s %s)'), 26915)) < (230.0 / 0.6214 * 1000.0) """ % (NEXRAD_LON, NEXRAD_LAT, NEXRAD_LON, NEXRAD_LAT, (ARCHIVE_T0 - datetime.timedelta(minutes=120) ).strftime("%Y-%m-%d %H:%M+00"), (ARCHIVE_T1 + datetime.timedelta(minutes=120) ).strftime("%Y-%m-%d %H:%M+00"), NEXRAD_LON, NEXRAD_LAT)) for row in pcursor: locx = radx + row['offset_x'] locy = rady + row['offset_y'] # Locate nearest city and distance, hmm sql = """ SELECT name, ST_distance(ST_transform(the_geom, 26915), ST_GeomFromEWKT('SRID=26915;POINT(%s %s)')) as d, %s - ST_x(ST_transform(the_geom,26915)) as offsetx, %s - ST_y(ST_transform(the_geom,26915)) as offsety from cities_iowa ORDER by d ASC LIMIT 1 """ % (locx, locy, locx, locy) ncursor.execute(sql) row2 = ncursor.fetchone() deg = getdir(0 - row2['offsetx'], 0 - row2['offsety']) drct = util.drct2text(deg) miles = row2['d'] * 0.0006214 # meters -> miles newcity = "%.1f %s %s" % (miles, drct, row2['name']) city = row['city'] if REAL88D == FAKE88D else newcity # Compute the new valid time ts = row['valid'] offset = ((ts - ARCHIVE_T0).days * 86400. + (ts - ARCHIVE_T0).seconds) / SPEEDUP # Speed up! valid = RT_T0 + datetime.timedelta(seconds=offset) # Query for WFO sql = """ SELECT * from nws_ugc WHERE ST_transform(ST_GeomFromEWKT('SRID=26915;POINT(%s %s)'),4326) && geom and ST_Contains(geom, ST_transform(ST_GeomFromEWKT('SRID=26915;POINT(%s %s)'),4326)) """ % (locx, locy, locx, locy) ncursor.execute(sql) row2 = ncursor.fetchone() wfo = row['wfo'] if FAKE88D == REAL88D else row2['wfo'] cnty = row['county'] if FAKE88D == REAL88D else row2['name'] st = row['state'] if FAKE88D == REAL88D else row2['state'] # newremark = "%s\n[WAS: %s %s]" % (row['source'], row['city'], # row['county']) # remark = row['remark'] if FAKE88D == REAL88D else newremark sql = """ INSERT into lsrs(valid, type, magnitude, city, county, state, source, remark, wfo, typetext, geom) values ('%s', '%s', %s, '%s', '%s', '%s', '%s', '%s', '%s', '%s', ST_transform( ST_GeomFromEWKT('SRID=26915;POINT(%s %s)'), 4326)) RETURNING ST_x(geom) as x, ST_y(geom) as y """ % (valid.strftime("%Y-%m-%d %H:%M+00"), row['type'], row['magnitude'] or 0, city.replace("'", ""), cnty.replace("'", ""), st, row['source'], row['remark'], wfo, row['typetext'], locx, locy) ncursor.execute(sql) row2 = ncursor.fetchone() print(("%s,%s,%.3f,%.3f,%s,%s,%s,%s,%s,%s" ) % (ts.strftime("%Y-%m-%d %H:%M"), valid.strftime("%Y-%m-%d %H:%M"), row2['x'], row2['y'], row['magnitude'], row['typetext'], row['source'], city, row['city'], row['remark'])) ncursor.close() NWA.commit() NWA.close()
def plotter(fdict): """ Go """ import matplotlib matplotlib.use('agg') import matplotlib.pyplot as plt import matplotlib.patheffects as PathEffects pgconn = psycopg2.connect(database='iem', host='iemdb', user='******') cursor = pgconn.cursor(cursor_factory=psycopg2.extras.DictCursor) station = fdict.get('zstation', 'AMW') network = fdict.get('network', 'IA_ASOS') units = fdict.get('units', 'MPH').upper() if units not in PDICT: units = 'MPH' year = int(fdict.get('year', datetime.datetime.now().year)) month = int(fdict.get('month', datetime.datetime.now().month)) sts = datetime.date(year, month, 1) ets = (sts + datetime.timedelta(days=35)).replace(day=1) nt = NetworkTable(network) cursor.execute( """ SELECT day, avg_sknt, vector_avg_drct from summary s JOIN stations t ON (t.iemid = s.iemid) WHERE t.id = %s and t.network = %s and s.day >= %s and s.day < %s ORDER by day ASC """, (station, network, sts, ets)) days = [] drct = [] sknt = [] for row in cursor: if row[1] is None: continue days.append(row[0].day) drct.append(row[2]) sknt.append(row[1]) if len(sknt) == 0: return "ERROR: No Data Found" df = pd.DataFrame( dict(day=pd.Series(days), drct=pd.Series(drct), sknt=pd.Series(sknt))) sknt = speed(np.array(sknt), 'KT').value(units) (fig, ax) = plt.subplots(1, 1) ax.bar(np.array(days) - 0.4, sknt, ec='green', fc='green') pos = max([min(sknt) / 2.0, 0.5]) for d, _, r in zip(days, sknt, drct): draw_line(plt, d, max(sknt) + 0.5, (270. - r) / 180. * np.pi) txt = ax.text(d, pos, drct2text(r), ha='center', rotation=90, color='white', va='center') txt.set_path_effects( [PathEffects.withStroke(linewidth=2, foreground="k")]) ax.grid(True, zorder=11) ax.set_title(("%s [%s]\n%s Daily Average Wind Speed and Direction") % (nt.sts[station]['name'], station, sts.strftime("%b %Y"))) ax.set_xlim(0.5, max(days) + 0.5) ax.set_ylim(top=max(sknt) + 2) ax.set_ylabel("Average Wind Speed [%s]" % (PDICT.get(units), )) return fig, df
def highcharts(fdict): """ Generate the highcharts variant""" ctx = get_context(fdict) dir_edges, _, table = histogram( ctx["df"]["drct"].values, ctx["df"]["smph"].values, np.array([0, 2, 5, 7, 10, 15, 20]), 18, True, ) arr = [drct2text(mydir) for mydir in dir_edges] return (""" var arr = """ + str(arr) + """; $("#ap_container").highcharts({ series: [{name: '2 - 5', data: """ + str(list(zip(arr, table[1]))) + """, _colorIndex: 0}, {name: '5 - 7', data: """ + str(list(zip(arr, table[2]))) + """, _colorIndex: 1}, {name: '7 - 10', data: """ + str(list(zip(arr, table[3]))) + """, _colorIndex: 2}, {name: '10 - 15', data: """ + str(list(zip(arr, table[4]))) + """, _colorIndex: 3}, {name: '15 - 20', data: """ + str(list(zip(arr, table[5]))) + """, _colorIndex: 4}, {name: '20 +', data: """ + str(list(zip(arr, table[6]))) + """, _colorIndex: 5}], chart: { polar: true, type: 'column' }, title: { 'text': '""" + ctx["title"] + """' }, subtitle: { 'text': '""" + ctx["subtitle"] + """' }, pane: { 'size': '85%' }, legend: { title: {text: 'Wind Speed [MPH]'}, verticalAlign: 'bottom', layout: 'horizontal' }, xAxis: { 'tickInterval': 18./8., 'labels': { formatter: function(){ var v = this.value.toFixed(1); if (v == '0.0') {return 'N';} if (v == '2.3') {return 'NE';} if (v == '4.5') {return 'E';} if (v == '6.8') {return 'SE';} if (v == '9.0') {return 'S';} if (v == '11.3') {return 'SW';} if (v == '13.5') {return 'W';} if (v == '15.8') {return 'NW';} return v; } } }, yAxis: { 'min': 0, 'endOnTick': false, 'showLastLabel': true, 'title': { 'text': 'Frequency (%)' }, 'reversedStacks': false }, tooltip: { positioner: function () { return { x: 10, y: 10 }; }, 'valueSuffix': '%', shared: true, valueDecimals: 1, formatter: function () { var s = '<b>' + arr[this.x] + ' ('+ this.points[0].total.toFixed(1)+'%)</b>'; $.each(this.points, function () { s += '<br/>' + this.series.name + ': ' + this.y.toFixed(1) + '%'; }); return s; }, }, plotOptions: { 'series': { 'stacking': 'normal', 'shadow': false, 'groupPadding': 0, 'pointPlacement': 'on' } } }); """)
continue t = tokens[0] cid = "IDOT-%s-%s" % (t[0], t[2]) gmt = datetime.datetime(int(t[3]), int(t[4]), int(t[5]), int(t[6]), int(t[7])) gmt = gmt.replace(tzinfo=pytz.timezone("UTC")) now = gmt.astimezone(pytz.timezone("America/Chicago")) if cid not in cameras: print "ingest_dot_webcams.py unknown CameraID: %s" % (cid,) cameras[cid] = {'pan0': 0, 'name': 'unknown'} # Hard coded... d = cameras[cid] drct = d['pan0'] drctTxt = util.drct2text(drct) # Create 320x240 variant fn = "165.206.203.34/rwis_images/Vid-000512%s.jpg" % ("-".join(t),) try: i0 = Image.open(fn) i320 = i0.resize((320, 240), Image.ANTIALIAS) except: if os.path.isfile(fn): os.unlink(fn) continue draw = ImageDraw.Draw(i0) s = "(%s) %s %s" % (drctTxt, d['name'], now.strftime("%-2I:%M:%S %p - %d %b %Y")) (w, h) = font.getsize(s)
def get_data(ts): """ Get the data for this timestamp """ iemcursor = IEM.cursor() cursor = ISUAG.cursor(cursor_factory=psycopg2.extras.DictCursor) qcdict = loadqc() nt = NetworkTable("ISUSM", only_online=False) data = {"type": "FeatureCollection", "features": []} # Fetch the daily values iemcursor.execute( """ SELECT id, pday, max_tmpf, min_tmpf from summary s JOIN stations t on (t.iemid = s.iemid) WHERE t.network = 'ISUSM' and day = %s """, (ts.date(),), ) daily = {} for row in iemcursor: daily[row[0]] = { "pday": row[1], "max_tmpf": row[2], "min_tmpf": row[3], } cursor.execute( """ SELECT h.station, h.encrh_avg, coalesce(m.rh_avg_qc, h.rh_qc) as rh, h.rain_mm_tot, etalfalfa, battv_min, coalesce(m.slrkj_tot_qc * 3600 / 1000000, h.slrmj_tot_qc) as slrmj_tot, coalesce(m.tair_c_avg, h.tair_c_avg) as tair_c_avg, coalesce(m.tsoil_c_avg_qc, h.tsoil_c_avg_qc) as tsoil_c_avg_qc, coalesce(m.t12_c_avg_qc, h.t12_c_avg_qc) as t12_c_avg_qc, coalesce(m.t24_c_avg_qc, h.t24_c_avg_qc) as t24_c_avg_qc, coalesce(m.t50_c_avg_qc, h.t50_c_avg_qc) as t50_c_avg_qc, coalesce(m.calcvwc12_avg_qc, h.calc_vwc_12_avg_qc) as calc_vwc_12_avg_qc, coalesce(m.calcvwc24_avg_qc, h.calc_vwc_24_avg_qc) as calc_vwc_24_avg_qc, coalesce(m.calcvwc50_avg_qc, h.calc_vwc_50_avg_qc) as calc_vwc_50_avg_qc, coalesce(m.ws_mph_max, h.ws_mph_max) as ws_mph_max, coalesce(m.winddir_d1_wvt, h.winddir_d1_wvt) as winddir_d1_wvt, coalesce(m.ws_mph_s_wvt * 0.447, h.ws_mps_s_wvt)as ws_mps_s_wvt from sm_hourly h LEFT JOIN sm_minute m on (h.station = m.station and h.valid = m.valid) where h.valid = %s """, (ts,), ) for row in cursor: sid = row["station"] if sid not in nt.sts: continue lon = nt.sts[sid]["lon"] lat = nt.sts[sid]["lat"] q = qcdict.get(sid, {}) data["features"].append( { "type": "Feature", "id": sid, "properties": { "encrh_avg": ( "%s%%" % safe(row["encrh_avg"], 1) if row["encrh_avg"] is not None and row["encrh_avg"] > 0 else "M" ), "rh": "%s%%" % (safe(row["rh"], 0),), "hrprecip": ( safe_p(row["rain_mm_tot"]) if not q.get("precip", False) else "M" ), "et": safe_p(row["etalfalfa"]), "bat": safe(row["battv_min"], 2), "radmj": safe(row["slrmj_tot"], 2), "tmpf": safe_t(row["tair_c_avg"]), "high": safe_t( daily.get(sid, {}).get("max_tmpf", None), "F" ), "low": safe_t( daily.get(sid, {}).get("min_tmpf", None), "F" ), "pday": ( safe(daily.get(sid, {}).get("pday", None), 2) if not q.get("precip", False) else "M" ), "soil04t": ( safe_t(row["tsoil_c_avg_qc"]) if not q.get("soil4", False) else "M" ), "soil12t": ( safe_t(row["t12_c_avg_qc"]) if not q.get("soil12", False) else "M" ), "soil24t": ( safe_t(row["t24_c_avg_qc"]) if not q.get("soil24", False) else "M" ), "soil50t": ( safe_t(row["t50_c_avg_qc"]) if not q.get("soil50", False) else "M" ), "soil12m": ( safe_m(row["calc_vwc_12_avg_qc"]) if not q.get("soil12", False) else "M" ), "soil24m": ( safe_m(row["calc_vwc_24_avg_qc"]) if not q.get("soil24", False) else "M" ), "soil50m": ( safe_m(row["calc_vwc_50_avg_qc"]) if not q.get("soil50", False) else "M" ), "gust": safe(row["ws_mph_max"], 1), "wind": ("%s@%.0f") % ( drct2text(row["winddir_d1_wvt"]), row["ws_mps_s_wvt"] * 2.23, ), "name": nt.sts[sid]["name"], }, "geometry": {"type": "Point", "coordinates": [lon, lat]}, } ) return json.dumps(data)