def create_speed_hills(ks, us, sks, sus, **kwargs): """ :type ks: numpy.ndarray :type us: numpy.ndarray :type sks: numpy.ndarray :type sus: numpy.ndarray :rtype: list[pyticas_ncrtes.core.etypes.Hill] """ from pyticas_ncrtes.core.etypes import Hill kt = kwargs.get('kt', DEFAULT_KT) f_merge = kwargs.get('merge', True) lsw = setting.SW_30MIN lsus = data_util.smooth(us, lsw) lsks = data_util.smooth(ks, lsw) lsus_minmax_idxs = np.diff(np.sign(np.diff(lsus))).nonzero()[0].tolist() lsus_over_kt = np.where(sks > kt) lsus_under_kt = np.where(sks <= kt) high_k_minmax_idxs = np.intersect1d(lsus_minmax_idxs, lsus_over_kt[0]) sus_minmax_idxs = np.diff(np.sign(np.diff(sus))).nonzero()[0].tolist() low_k_minmax_idxs = np.intersect1d(sus_minmax_idxs, lsus_under_kt[0]) minmax_idxs = [0] + np.concatenate([low_k_minmax_idxs, high_k_minmax_idxs ]).tolist() + [len(us) - 1] minmax_idxs = np.sort(np.unique(minmax_idxs)) # remove same trend (decrease or increase) tmp = [minmax_idxs[0]] for midx in range(1, len(minmax_idxs)): if minmax_idxs[midx] - minmax_idxs[midx - 1] <= 2: continue tmp.append(minmax_idxs[midx]) minmax_idxs = tmp cycles = [] for idx in range(1, len(minmax_idxs)): cycles.append([minmax_idxs[idx - 1], minmax_idxs[idx]]) if f_merge: cycles = merge_cycles(cycles, lsks, lsus) hills = [] for idx, (sidx, eidx) in enumerate(cycles): hills.append( Hill(idx, sidx, eidx, ks[sidx:eidx], us[sidx:eidx], sks[sidx:eidx], sus[sidx:eidx])) return hills
def _smoothing_data(edata): """ :type edata: pyticas_ncrtes.core.etypes.ESTData """ sw = setting.SW_2HOURS ssu, ssk = 5, 3 sus = data_util.smooth(edata.us, sw) sks = data_util.smooth(edata.ks, sw) qus = data_util.stepping(sus, ssu) qks = data_util.stepping(sks, ssk) edata.sus = sus edata.sks = sks edata.qus = np.array(qus) edata.qks = np.array(qks)
def _sist(edata): """ Speed Reduction Start Time :param edata: :type edata: pyticas_ncrtes.core.etypes.ESTData """ # edata.ncrt = 203 # faverolles 1/14/2020: set to 45mph default from 30 CONGESTED_SPEED = 45 intv30min = setting.INTV30MIN intv1h = setting.INTV1HOUR # ncrt, qus, sus = edata.ncrt, edata.qus, edata.sus qus = edata.qus ncrt, sus = edata.ncrt, data_util.smooth(edata.us, setting.SW_1HOUR) if not ncrt: return if sus[ncrt] < CONGESTED_SPEED: return sist = edata.lst # move backward for idx in range(ncrt, 0, -1): if qus[idx] - qus[idx - 1] >= -1: sist = idx else: break # move forward for idx in range(sist, ncrt): if qus[idx + 1] - qus[idx] >= 1: break else: sist = idx # find minimum speed sidx, eidx = max(0, sist - intv30min), min(sist + intv30min, len(qus) - 1) edata.sist = np.argmin(sus[sidx:eidx]).item() + sidx # minimum speed between sist candidate and ncrt if edata.sist and edata.ncrt and edata.ncrt - edata.sist > intv30min: edata.sist = np.argmin(sus[edata.sist:edata.ncrt]).item() + edata.sist # sist cannot be early than lst if edata.lst and edata.sist: edata.sist = max(edata.lst, edata.sist) # sist cannot be later than ncrt if edata.sist >= edata.ncrt: edata.sist = None
def _adjust_with_speed(edata, target_idx): """ :type edata: pyticas_ncrtes.core.etypes.ESTData :type target_idx: int :rtype: int """ logger = getLogger(__name__) sdata = data_util.smooth(edata.us, setting.SW_30MIN) qdata = edata.qus #data_util.stepping(sdata, 2) stick = None qu = qdata[target_idx] for idx in range(target_idx, 0, -1): cu = qdata[idx] if cu != qu: stick = idx break if not stick: return target_idx _stick = stick for idx in range(stick, 0, -1): if sdata[idx] > qu: _stick = idx + 1 else: break stick = _stick # for tidx in range(stick, stick+setting.INTV15MIN): # if sdata[tidx] >= qu: # return tidx + 1 # never reaches to here return stick
def _write(num, edata, output_path, prefix=''): """ :type num: int :type edata: pyticas_ncrtes.core.etypes.ESTData :type output_path: str :type prefix: str """ logger = getLogger(__name__) if edata is None or not edata.is_loaded: logger.debug(' - Data is not loaded : %s' % edata.target_station.station_id if edata else 'N/A') return sw = setting.SW_3HOURS sks, sus = data_util.smooth(edata.ks, sw), data_util.smooth(edata.us, sw) hills = hill_helper.create_uk_hills(edata.ks, edata.us, sks, sus) ecs = ['#FF0000', '#FF7F00', '#FFFF00', '#00FF00', '#0000FF', '#9400D3'] long_title = '%s (%s[prj_id=%s, s_limit=%d, label=%s], %s)' % ( edata.snow_event.snow_period.get_date_string(), edata.target_station.station_id, edata.snow_route.id if edata.snow_route else 'N/A', edata.target_station.s_limit, edata.target_station.label, edata.target_station.corridor.name) title = '%s (%s, %s)' % (edata.snow_event.snow_period.get_date_string(), edata.target_station.station_id, edata.target_station.corridor.name) if REPORT_MODE: fig = plt.figure(figsize=(16, 9), dpi=100, facecolor='white') else: fig = plt.figure(dpi=100, facecolor='white') ax1 = plt.subplot(211) ax2 = plt.subplot(223) ax3 = plt.subplot(224) ax1.axhline(y=edata.target_station.s_limit, c='b') if edata.wn_ffs: ax1.axhline(y=edata.wn_ffs, c='r') #ax1.plot(edata.us, marker='', label='Speed', c='#3794D5') ax1.plot(edata.ks, marker='', label='Density', c='#ADE2CD') # if edata.wn_avg_us is not None: # ax1.plot(edata.wn_avg_us, c='#8C65C5', label='WN Avg. Speed') # ax1.plot(edata.qus, c='#746F69', label='Q-Us') if edata.normal_func: nt_us = edata.normal_func.nighttime_func.speeds( edata.snow_event.data_period.get_timeline(as_datetime=True)) else: nt_us = [None] * edata.n_data ax1.plot(nt_us, c='k', label='Nighttime Speed') #nt_ks = edata.normal_func.nighttime_func.densities(edata.snow_event.data_period.get_timeline(as_datetime=True)) #ax1.plot(nt_ks, c='k', label='Nighttime Density') # snow start and end time sstime = edata.snow_event.time_to_index(edata.snow_event.snow_start_time) setime = edata.snow_event.time_to_index(edata.snow_event.snow_end_time) ax1.axvline(x=sstime, c='#948D90') # grey vertical line ax1.axvline(x=setime, c='#948D90') # draw chart using UK-Hills n_data = len(edata.us) ecs = ['#FF0000', '#FF7F00', '#FFFF00', '#00FF00', '#0000FF', '#9400D3'] markers = ['o', 'x', 'd', '^', '<', '>', 'v', 's', '*', '+'] ls = '-' used = [] for gidx, hill in enumerate(hills): lw = 1 c = ecs[gidx % len(ecs)] marker = '|' for midx in range(len(markers)): marker_stick = '%s-%s' % (c, markers[midx]) if marker_stick not in used: marker = markers[midx] used.append(marker_stick) break sidx, eidx = hill.sidx, hill.eidx _sidx, _eidx = sidx, eidx ax2.plot(edata.sks[_sidx:_eidx + 1], edata.sus[_sidx:_eidx + 1] * edata.sks[_sidx:_eidx + 1], c=c, marker=marker, ms=4, zorder=2) ax3.plot(edata.sks[_sidx:_eidx + 1], edata.sus[_sidx:_eidx + 1], c=c, marker=marker, ms=4, zorder=2) _ks, _us = [None] * len(edata.ks), [None] * len(edata.us) for idx in range(sidx, eidx + 1): if idx >= n_data - 1: break # _ks[idx] = edata.merged_sks[idx] # _us[idx] = edata.merged_sus[idx] _ks[idx] = edata.ks[idx] _us[idx] = edata.us[idx] ax1.plot(_us, lw=lw, ls=ls, c=c) # Normal and Wet-Normal Avg UK _recv_ks = np.array(list(range(5, 120))) if edata.normal_func: uk_function = edata.normal_func.daytime_func.get_uk_function() if uk_function and uk_function.is_valid(): ax2.plot(_recv_ks, np.array(uk_function.speeds(_recv_ks)) * _recv_ks, ls=':', lw=2, label='Normal Avg. QK') # ax2.plot(_recv_ks, uk_function.speeds(_recv_ks), ls=':', lw=2, label='Normal Avg. UK') ax3.plot(_recv_ks, uk_function.speeds(_recv_ks), ls=':', lw=2, label='Normal Avg. UK') if uk_function._wn_uk: ax2.plot(_recv_ks, np.array(uk_function.wet_normal_speeds(_recv_ks)) * _recv_ks, ls=':', lw=2, label='Wet-Normal QK') # ax2.plot(_recv_ks, uk_function.wet_normal_speeds(_recv_ks, edata.wn_ffs, edata.k_at_wn_ffs), ls=':', lw=2, label='Wet-Normal UK') ax3.plot(_recv_ks, uk_function.wet_normal_speeds(_recv_ks), ls=':', lw=2, label='Wet-Normal UK') # ax2.scatter(edata.ks, edata.us, c='#5D63FF', marker='.') # ax3.scatter(edata.sks, edata.sus, c='#5D63FF', marker='.') ms = [14, 13, 12, 11, 10, 8, 7] us = data_util.smooth(edata.us, 15) # srst if edata.srst is not None: data = np.array([None] * len(us)) data[edata.srst] = us[edata.srst] ax1.plot(data, marker='o', ms=ms[0], c='#4ED8FF', label='SRST') # light blue circle # lst if edata.lst is not None: data = np.array([None] * len(us)) data[edata.lst] = us[edata.lst] ax1.plot(data, marker='o', ms=ms[1], c='#FFAD2A', label='LST') # orange circle # sist if edata.sist is not None: data = np.array([None] * len(us)) data[edata.sist] = us[edata.sist] ax1.plot(data, marker='o', ms=ms[2], c='#68BD20', label='SIST') # orange green # # rst # if edata.rst is not None: # data = np.array([None] * len(us)) # data[edata.rst] = us[edata.rst] # ax1.plot(data, marker='o', ms=ms[2], c='#68BD20', label='RST') # green # ncrt if edata.ncrt is not None: data = np.array([None] * len(us)) data[edata.ncrt] = us[edata.ncrt] # ax1.plot(data, marker='o', ms=ms[3], c='#FF0512', label='NCRT (%d)' % edata.ncrt_type) # navy blue ax1.plot(data, marker='o', ms=ms[3], c='#FF0512', label='NCRT') # navy blue # pst if edata.pst: data = np.array([None] * len(us)) data[edata.pst] = us[edata.pst] ax1.plot(data, marker='o', ms=ms[4], c='#9535CC', label='PST') # purple diamod # sbpst # if edata.sbpst: # data = np.array([None] * len(us)) # data[edata.sbpst] = us[edata.sbpst] # ax1.plot(data, marker='p', ms=ms[4], c='#bdb76b', label='BPST') # DarkKhaki # # # sapst # if edata.sapst: # data = np.array([None] * len(us)) # data[edata.sapst] = us[edata.sapst] # ax1.plot(data, marker='p', ms=ms[4], c='#cdad00', label='APST') # gold3 # nfrt if edata.nfrt: data = np.array([None] * len(us)) data[edata.nfrt] = us[edata.nfrt] ax1.plot(data, marker='*', ms=ms[4], c='#0072CC', label='NFRT') # light blue # # stable speed area around pst # if not edata.ncrt and (edata.sbpst or edata.sapst): # data = np.array([None] * len(us)) # if edata.sbpst: # data[edata.sbpst] = us[edata.sbpst] # ax1.plot(data, marker='p', ms=ms[4], c='#FF00F8', label='NCRT-C') # light-pink pentagon # if edata.sapst and not edata.ncrt: # data[edata.sapst] = us[edata.sapst] # ax1.plot(data, marker='p', ms=ms[4], c='#FF00F8', label='') # light-pink pentagon # snowday-ffs # if edata.snowday_ffs: # ax1.axhline(y=edata.snowday_ffs, c='#33CC0A') # if edata.nfrt: # data = np.array([None] * len(us)) # data[edata.nfrt] = us[edata.nfrt] # ax1.plot(data, marker='*', ms=ms[5], c='#CC00B8', label='SnowDay-FFS') # navy blue # reported time for rp in edata.rps: data = np.array([None] * len(us)) data[rp] = us[rp] ax1.plot(data, marker='^', ms=ms[6], c='#FF0512', label='RBRT') # red circle box = ax1.get_position() ax1.set_position([box.x0, box.y0, box.width * 0.9, box.height]) ax1.legend(loc='center left', bbox_to_anchor=(1, 0.5), numpoints=1, prop={'size': 12}) ulist = np.array([90, 100, 110, 120, 150, 200, 300]) klist = np.array([80, 100, 150, 200, 250, 300, 350, 400, 450, 500, 600]) qlist = np.array([0, 2000, 3000, 3500, 4000, 4500, 5000, 6000, 7000]) _maxq = max(edata.sks * edata.sus) _maxk = max(edata.sks) _maxu = max(edata.sus) maxq = qlist[np.where(qlist > _maxq)][0] maxu = ulist[np.where(ulist > _maxu)][0] maxk = klist[np.where(klist > _maxk)][0] ax1.set_title(long_title) ax2.set_title(title + ' - Smoothed Q-K') ax3.set_title(title + ' - Smoothed U-K') ax1.set_ylabel('speed, density') ax1.set_xlabel('time') ax1.set_ylim(ymin=0, ymax=maxu) ax1.set_xlim(xmin=0, xmax=len(edata.sus)) # ax2.set_ylabel('speed') ax2.set_ylabel('flow') ax2.set_xlabel('density') # ax2.set_ylim(ymin=0, ymax=100) ax2.set_ylim(ymin=0, ymax=maxq) ax2.set_xlim(xmin=0, xmax=maxk) ax3.set_ylim(ymin=0, ymax=maxu) ax3.set_xlim(xmin=0, xmax=maxk) ax3.set_ylabel('speed') ax3.set_xlabel('density') ax1.grid() ax2.grid() ax3.grid() ax2.legend(prop={'size': 12}) ax3.legend(prop={'size': 12}) if not REPORT_MODE: plt.show() else: import datetime timeline = edata.snow_event.data_period.get_timeline(as_datetime=True) timeline = [ t - datetime.timedelta(seconds=setting.DATA_INTERVAL) for t in timeline ] ntimes = [ t.strftime('%H:%M') for idx, t in enumerate(timeline) if idx % (2 * 3600 / setting.DATA_INTERVAL) == 0 ] loc_times = [ idx for idx, t in enumerate(timeline) if idx % (2 * 3600 / setting.DATA_INTERVAL) == 0 ] ax1.set_xticks(loc_times) ax1.set_xticklabels(ntimes, rotation=90) plt.tight_layout() postfix = ' (rp)' if edata.reported_events else '' file_path = os.path.join( output_path, '(%03d) %s%s%s.png' % (num, prefix, edata.target_station.station_id, postfix)) fig.savefig(file_path, dpi=100, bbox_inches='tight') plt.close(fig) if 0: wb = xlsxwriter.Workbook( os.path.join( ncrtes.get_infra().get_path('tmp', create=True), '%s %s (night).xlsx' % (edata.snow_event.snow_period.get_date_string(), edata.target_station.station_id))) ws = wb.add_worksheet('night-data') prd = edata.snow_event.data_period.clone() prd.interval = setting.DATA_INTERVAL ws.write_column(0, 0, ['time'] + prd.get_timeline(as_datetime=False)) ws.write_column(0, 1, ['speed'] + edata.us.tolist()) ws.write_column(0, 2, ['nighttime average speed'] + edata.night_us.tolist()) ws.write_column(0, 3, ['smoothed speed'] + edata.sus.tolist()) # ws.write_column(0, 4, ['smoothed speed (2h)'] + edata.lsus.tolist()) # ws.write_column(0, 5, ['smoothed speed (1h)'] + edata.llsus.tolist()) ws.write_column(0, 6, ['nighttime ratio'] + edata.night_ratios.tolist()) wb.close()
def _write_chart_and_data(ddata, uk_origin, Kl, seg_func): if not DEBUG_MODE: return ecs = ['#FF0000', '#FF7F00', '#FFFF00', '#00FF00', '#0000FF', '#9400D3'] cnt = 0 import matplotlib.pyplot as plt plt.figure() _us_origin, _ks_origin = data_util.dict2sorted_list(uk_origin) ks_origin = np.array(_ks_origin) us_origin = np.array(_us_origin) plt.scatter(ks_origin, us_origin, marker='x', color='#999999') for func in seg_func.funcs: # print('> ', func.x1, func.x2, func.line_func, type(func)) isinstance(func, etypes.FitFunction) uf = func.get_function() lus = [] lks = [] for _k in range(int(func.x1 * 10), int(func.x2 * 10)): k = _k / 10.0 if k > 140: break lks.append(k) lus.append(uf(k)) c = ecs[cnt % len(ecs)] cnt += 1 # plt.scatter(lks, lus, marker='^', color=c) _ks, _us = [], [] for k in range(10, 200): _ks.append(k) _us.append(seg_func.speed(k)) plt.plot(_ks, data_util.smooth(_us, 11), c='b', lw=2) plt.xlim(xmin=0, xmax=160) plt.ylim(ymin=0, ymax=120) plt.title('%s (Kt=%.2f, SL=%s, label=%s)' % (ddata.station.station_id, Kl, ddata.station.s_limit, ddata.station.label)) plt.grid() periods = sorted(ddata.periods + ddata.not_congested_periods, key=lambda prd: prd.start_date) ffpath = _output_path( 'normal_function', '(%d-%d) %s.png' % (periods[0].start_date.year, periods[-1].end_date.year, ddata.station.station_id)) plt.tight_layout() plt.savefig(ffpath, dpi=100, bbox_inches='tight') # plt.show() plt.close() import xlsxwriter import os from pyticas_ncrtes import ncrtes infra = ncrtes.get_infra() output_dir = infra.get_path('ncrtes/normal-data-set', create=True) data_file = os.path.join( output_dir, '(%d-%d) %s (func).xlsx' % (periods[0].start_date.year, periods[-1].end_date.year, ddata.station.station_id)) wb = xlsxwriter.Workbook(data_file) ws = wb.add_worksheet('uk') ws.write_column(0, 0, ['k'] + _ks) ws.write_column(0, 1, ['u'] + _us) wb.close()
def _segmented_function(ddata, uk, uk_origin): """ make U-K functions as a group of segmented functions (linear functions + log function) :type ddata: pyticas_ncrtes.core.etypes.DaytimeData :type uk: dict[float, float] :type uk_origin: dict[float, float] :rtype: etypes.SegmentedFunction """ if uk is None or not any(uk): return etypes.SegmentedFunction([], None, None, None) # estimate FFS smoothing_window_size = 5 ffs, Kf = ncr_ffs.estimate(uk, smoothing_window_size=smoothing_window_size) if ffs < 0: return etypes.SegmentedFunction([], None, None, None) filtered_uk = uk filtered_us, filtered_ks = data_util.dict2sorted_list(filtered_uk) filtered_target_uk = filtered_uk filtered_target_ks = np.array(filtered_ks) filtered_target_us = np.array(filtered_us) Kt = max(filtered_target_ks[np.where(filtered_target_us >= ffs)]) # max_k with FFS margink = 1 wh_around_maxk = np.where((filtered_target_ks <= Kt + margink) & (filtered_target_ks >= Kt - margink)) median_u_at_kt = np.median(filtered_target_us[wh_around_maxk]) # prepare avg u-k data _ks, _us = [], [] for _k in range(10, 100): avg, stddev, arounds = data_util.avg_y_of_around_x( filtered_target_ks, filtered_target_us, _k, 2) if avg: _ks.append(_k) _us.append(avg) _ks = np.array(_ks) _us = np.array(_us) # smoothing _sus = data_util.smooth(_us, 11) _sus2 = data_util.smooth(_us, 21) # find k-range for calibration of log function u_under_limit = min(ddata.station.s_limit - 5, 40) k_at_lowu = _ks[np.where(_us < u_under_limit)[0][0]] wh = np.where((_ks <= k_at_lowu) & (_ks >= Kt)) _tks, _tus = _ks[wh], _sus[wh] if any(_tks): vk, vu, d = _find_vertex(_tks, _tus) else: vk, vu, d = -1, -1, -1 # set Kth if (d < 1 or (vu > 0 and median_u_at_kt - vu > 10)): kth, uth = Kt, median_u_at_kt else: kth, uth = vk, vu # log-function calibration logfunc = _after_kt(ddata.station, filtered_target_uk, kth) # find Kt from average u-k data and calibrated function # print('kth=', kth) kth2 = max(Kt, vk) Kl = _find_func_matching_point(logfunc, kth, kth2, _ks, _sus) for _ in range(10): kth2 = kth2 + 5 Kl = _find_func_matching_point(logfunc, kth, kth2, _ks, _sus) if Kl is not None: break # result segmented functions ([0] = FFS function) lfunc = etypes.LineFunction((0, ffs), 0, Kf) funcs = [lfunc] # K_vertex if not Kl: Kl = Kt + 5 Kv = vk if vk < Kl else -1 if Kt < Kv and Kv - Kt > 2: # funcs[1] = FFS to Kt u_at_kt, _, _ = data_util.avg_y_of_around_x(filtered_target_ks, filtered_target_us, Kt, 2) popts = _line_func(lfunc.x2, lfunc.get_speed(lfunc.x2), Kt, u_at_kt) lfunc = etypes.LineFunction(popts, lfunc.x2, Kt) funcs.append(lfunc) # funcs[2] = FFS to Kv u_at_kv, _, _ = data_util.avg_y_of_around_x(filtered_target_ks, filtered_target_us, Kv, 2) popts = _line_func(Kt, u_at_kt, Kv, u_at_kv) lfunc = etypes.LineFunction(popts, lfunc.x2, Kv) funcs.append(lfunc) else: # funcs[2] = FFS to Kt u_at_kt, _, _ = data_util.avg_y_of_around_x(filtered_target_ks, filtered_target_us, Kt, 2) popts = _line_func(lfunc.x2, lfunc.get_speed(lfunc.x2), Kt, u_at_kt) lfunc = etypes.LineFunction(popts, lfunc.x2, Kt) funcs.append(lfunc) # funcs[3] = Kv to Kl u_at_kl = logfunc.get_speed(Kl) popts = _line_func(lfunc.x2, lfunc.get_speed(lfunc.x2), Kl, u_at_kl) lfunc = etypes.LineFunction(popts, lfunc.x2, Kl) funcs.append(lfunc) # func[4] = logfunc logfunc.x1 = Kl logfunc.x2 = 9999 funcs.append(logfunc) seg_func1 = etypes.SegmentedFunction(funcs, Kf, Kt, ffs) funcs2 = list(funcs[:2]) logfunc2 = _after_kt(ddata.station, filtered_target_uk, Kt) Kl2 = _find_func_matching_point(logfunc2, Kt, kth2, _ks, _sus) for _ in range(10): kth2 = kth2 + 5 Kl2 = _find_func_matching_point(logfunc2, Kt, kth2, _ks, _sus) if Kl2 is not None: break if not Kl2: Kl2 = Kt + 5 lfunc = funcs2[-1] u_at_kl2 = logfunc2.get_speed(Kl) popts = _line_func(lfunc.x2, lfunc.get_speed(lfunc.x2), Kl2, u_at_kl2) lfunc = etypes.LineFunction(popts, lfunc.x2, Kl2) funcs2.append(lfunc) # func[4] = logfunc logfunc2.x1 = Kl2 logfunc2.x2 = 9999 funcs2.append(logfunc2) seg_func2 = etypes.SegmentedFunction(funcs2, Kf, Kt, ffs) checked1, max_diff1 = _check_seg_func(seg_func1, _ks, _sus2) checked2, max_diff2 = _check_seg_func(seg_func2, _ks, _sus2) if not checked1 and not checked2: print('! fail to calibrate function') return etypes.SegmentedFunction([], Kf, Kt, ffs) seg_func = None if not checked1 or not checked2: seg_func = seg_func1 if checked1 else seg_func2 else: seg_func = seg_func1 if max_diff1 < max_diff2 else seg_func2 if seg_func and seg_func.is_valid(): _write_chart_and_data(ddata, uk_origin, Kl, seg_func) return seg_func
def _collect_data_a_day(target_station, prd, dc): """ returns k,u data during speed recovery/reduction section on a day :type target_station: pyticas.ttypes.RNodeObject :type prd: pyticas.ttypes.Period :type dc: function :rtype: (dict[float, float], dict[float, float], dict[float, float], list[float], list[float], pyticas.ttypes.RNodeData, pyticas.ttypes.RNodeData, list[pyticas_ncrtes.hill.hill.Hill], bool) """ global wb logger = getLogger(__name__) _us, _ks, _qs = _station_data(target_station, prd, dc) if not _us: return None, None, None, None, None, None, None, None, False sw = SW_1HOUR us = np.array(_us.data) ks = np.array(_ks.data) qs = np.array(_qs.data) sks = data_util.smooth(ks, sw) sus = data_util.smooth(us, sw) sqs = data_util.smooth(qs, sw) if not any(sus): return None, None, None, None, None, None, None, None, False recovery_uk, reduction_uk, all_uk = {}, {}, {} dranges = _data_collecting_interval(target_station, ks, us, qs, sks, sus, sqs) is_not_congested = False if not dranges: minu_idx = np.argmin(sus).item() # toidx = min(minu_idx + setting.INTV2HOUR, len(sus)-1) toidx = None maxu = sus[minu_idx] for idx in range(minu_idx, len(sus)-1): if sus[idx] > sus[idx+1] and maxu - sus[idx+1] > 5: toidx = idx break maxu = sus[idx] if sus[idx] > maxu else maxu if not toidx: toidx = min(minu_idx + setting.INTV1HOUR, len(sus)-1) toidx = min(toidx, minu_idx + setting.INTV2HOUR) #print(target_station.station_id, prd.get_date_string(), '-> not congested : ', (minu_idx, toidx)) if toidx < len(sus)-1 or sus[toidx] > target_station.s_limit: dranges = [(minu_idx, toidx)] is_not_congested = True if not dranges: return None, None, None, None, None, None, None, None, False ########################### ws = wb.add_worksheet(prd.get_date_string()) ws.write_row(0, 0, [' ', 'k', 'u', 'q', 'sk', 'su', 'sq']) times = list(range(len(ks))) ws.write_column(1, 0, times) ws.write_column(1, 1, ks) ws.write_column(1, 2, us) ws.write_column(1, 3, qs) ws.write_column(1, 4, sks) ws.write_column(1, 5, sus) ws.write_column(1, 6, sqs) col = 8 for (sidx, eidx) in dranges: ws.write_column(0, col, ['ks(%d-%d)' % (sidx, eidx)] + ks[sidx:eidx+1].tolist()) ws.write_column(0, col+1, ['us(%d-%d)' % (sidx, eidx)] + us[sidx:eidx+1].tolist()) col += 3 ############################## sks2, sus2 = data_util.smooth(ks, 11), data_util.smooth(us, 11) # sks2, sus2 = ks, us already = [] for (sidx, eidx) in dranges: # print(target_station.station_id, prd.get_date_string(), (sidx, eidx)) for idx in range(sidx, eidx+1): if idx in already: continue _tk = (sks2[idx] if sks2[idx] not in recovery_uk else _unique_key(sks2[idx], list(recovery_uk.keys()))) recovery_uk[_tk] = sus2[idx] reduction_uk[_tk] = sus2[idx] all_uk[_tk] = sus2[idx] # _tk = (ks[idx] if ks[idx] not in recovery_uk # else _unique_key(ks[idx], list(recovery_uk.keys()))) # recovery_uk[_tk] = us[idx] # reduction_uk[_tk] = us[idx] # all_uk[_tk] = us[idx] already.append(idx) if SHOW_GRAPH: fig = plt.figure(facecolor='white', figsize=(16, 8)) ax1 = plt.subplot(121) ax2 = ax1.twinx() ax3 = plt.subplot(122) ax1.plot(qs, label='qs') ax1.plot(sqs, label='sqs') ax2.plot(us, c='#EA8BD6', label='us') ax2.plot(sus, c='#CC3137', label='sus') ax2.plot(sks, c='#1DCC2E', label='sks') for (sidx, eidx) in dranges: ax1.axvline(x=sidx, c='g', label='start') ax1.axvline(x=eidx, c='r', label='end') ecs = ['#FF0000', '#FF7F00', '#FFFF00', '#00FF00', '#0000FF', '#9400D3'] markers = ['o', 'x', 'd', '^', '<', '>', 'v', 's', '*', '+'] UK.append(recovery_uk) used = [] for idx, _uk in enumerate(UK): c = ecs[idx % len(ecs)] marker = '|' for midx in range(len(markers)): marker_stick = '%s-%s' % (c, markers[midx]) if marker_stick not in used: marker = markers[midx] used.append(marker_stick) break _ks = list(_uk.keys()) _us = [ _uk[_k] for _k in _ks] ax3.scatter(_ks, _us, c=c, marker=marker) # ax1.axvline(x=maxq_idx, c='g', label='maxq') # ax1.axvline(x=minu_idx, c='r', label='minu') # if recovered_idx: # ax1.axvline(x=recovered_idx, c='b', label='recovered') ax3.set_xlim(xmin=0, xmax=80) ax3.set_ylim(ymin=0, ymax=90) plt.suptitle('%s (s_limit=%s, period=%s)' % ( target_station.station_id, target_station.s_limit, prd.get_period_string())) ax1.legend() plt.grid() mng = plt.get_current_fig_manager() mng.window.state('zoomed') plt.show() plt.close(fig) return all_uk, recovery_uk, reduction_uk, us, ks, _us, _ks, [], is_not_congested