diff --git a/Analysis/0411_unp-left_p-right-uturn/0417_generate_signals.ipynb b/Analysis/0411_unp-left_p-right-uturn/0417_generate_signals.ipynb new file mode 100644 index 000000000..8f0346ba2 --- /dev/null +++ b/Analysis/0411_unp-left_p-right-uturn/0417_generate_signals.ipynb @@ -0,0 +1,301 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "import pandas as pd\n", + "import numpy as np\n", + "import sys\n", + "import copy\n", + "sys.path.append('../../Scripts')\n", + "from preprocess_daily import DailyPreprocessor\n", + "from generate_signals import SignalGenerator" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1. 데이터를 준비합니다.\n", + "1-1. 네트워크가 로드되었습니다.\n", + "1-2. 테이블들이 로드되었습니다.\n", + "2. 신호이력 테이블을 변환합니다.\n", + "3. 이동류정보 테이블을 변환합니다.\n", + "4. 통합 테이블을 생성합니다.\n" + ] + } + ], + "source": [ + "self = SignalGenerator()\n", + "self.prepare_data() # 1 \n", + "self.process_history() # 2\n", + "self.process_movement() # 3\n", + "self.make_histids() # 4\n", + "self.set_timepoints()" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
inter_nonode_idstart_unixphas_Aphas_Bmove_Amove_Bdurationstate_Astate_B
0175i01704415810118443grrrgrrrgGGGGrgrrgGGrgrrrgrrrrrgrr
1175i01704415810227345grrGgrrrgrrrrrgrrgrrrgrrrgrrrrGgrr
2175i01704415810336133grrrgGGrgrrrrrgrrgrrrgrrGgrrrrrgrr
3175i01704415810346222grrrgGGrgrrrrrgrrgrrrgrrrgrrrrrgGr
4175i01704415810445237grrrgrrrgrrrrrgrGgrrrgrrrgrrrrrgGr
.................................
387210u6017044168201161825GGGGGGGGrGGGGGGGGr
388210u601704416820126213GGGGGGGGrGGGGGGGGr
389210u601704416820225238GGGGGGGGGGGGGGGGGr
390210u601704416820337462GGGGGGGGrGGGGGGGGr
391210u601704416820448321GGGGGGGGrGGGGGGGGr
\n", + "

392 rows × 10 columns

\n", + "
" + ], + "text/plain": [ + " inter_no node_id start_unix phas_A phas_B move_A move_B duration \\\n", + "0 175 i0 1704415810 1 1 8 4 43 \n", + "1 175 i0 1704415810 2 2 7 3 45 \n", + "2 175 i0 1704415810 3 3 6 1 33 \n", + "3 175 i0 1704415810 3 4 6 2 22 \n", + "4 175 i0 1704415810 4 4 5 2 37 \n", + ".. ... ... ... ... ... ... ... ... \n", + "387 210 u60 1704416820 1 1 6 18 25 \n", + "388 210 u60 1704416820 1 2 6 2 13 \n", + "389 210 u60 1704416820 2 2 5 2 38 \n", + "390 210 u60 1704416820 3 3 7 4 62 \n", + "391 210 u60 1704416820 4 4 8 3 21 \n", + "\n", + " state_A state_B \n", + "0 grrrgrrrgGGGGrgrr gGGrgrrrgrrrrrgrr \n", + "1 grrGgrrrgrrrrrgrr grrrgrrrgrrrrGgrr \n", + "2 grrrgGGrgrrrrrgrr grrrgrrGgrrrrrgrr \n", + "3 grrrgGGrgrrrrrgrr grrrgrrrgrrrrrgGr \n", + "4 grrrgrrrgrrrrrgrG grrrgrrrgrrrrrgGr \n", + ".. ... ... \n", + "387 GGGGGGGGr GGGGGGGGr \n", + "388 GGGGGGGGr GGGGGGGGr \n", + "389 GGGGGGGGG GGGGGGGGr \n", + "390 GGGGGGGGr GGGGGGGGr \n", + "391 GGGGGGGGr GGGGGGGGr \n", + "\n", + "[392 rows x 10 columns]" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "self.histids" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "sts", + "language": "python", + "name": "sts" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.10" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/Results/sn_1704419700.add.xml b/Results/sn_1704419700.add.xml index ba9568802..954cb7a89 100644 --- a/Results/sn_1704419700.add.xml +++ b/Results/sn_1704419700.add.xml @@ -1,50 +1,50 @@ - - - + + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + - + @@ -84,176 +84,164 @@ - - - + + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - + + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + - + @@ -326,7 +314,7 @@ - + @@ -383,28 +371,22 @@ - - - - - - + + + - - + + - - - - - + + - - + + - + - + @@ -444,230 +426,218 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - + + + - - + + - - + + - - - - - + + - + - - + + - - + + - - + + - + - - + + - - + + - - + + - + + + + - + - - - + + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + - - - + + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + \ No newline at end of file diff --git a/Scripts/__pycache__/preprocess_daily.cpython-38.pyc b/Scripts/__pycache__/preprocess_daily.cpython-38.pyc index 12e8d554b..bdfb2a49d 100644 Binary files a/Scripts/__pycache__/preprocess_daily.cpython-38.pyc and b/Scripts/__pycache__/preprocess_daily.cpython-38.pyc differ diff --git a/Scripts/generate_signals.py b/Scripts/generate_signals.py index d42c33874..98bca07e2 100644 --- a/Scripts/generate_signals.py +++ b/Scripts/generate_signals.py @@ -592,6 +592,96 @@ class SignalGenerator(): self.histids = self.histids.sort_values(by=['start_unix', 'node_id', 'phas_A', 'phas_B']).reset_index(drop=True) self.histids = self.histids[['inter_no', 'node_id', 'start_unix', 'phas_A', 'phas_B', 'move_A', 'move_B', 'duration', 'state_A', 'state_B']] + # 5. 신호 생성 + def get_signals(self): + print("5. 신호를 생성합니다.") + self.set_timepoints() + self.time51 = datetime.now() + self.assign_red_yellow() + self.time52 = datetime.now() + self.make_tl_file() + self.time53 = datetime.now() + + # 5-1. 신호 파일의 시작 및 종료시각 설정 + def set_timepoints(self): + self.offsets = {} + self.sigtable = [] + sim_start = self.present_time - 300 + for node_id, group in self.histids.groupby('node_id'): + lsbs = group[group['start_unix'] < sim_start]['start_unix'].max() # the last start_unix before sim_start + self.offsets[node_id] = lsbs - sim_start + group = group[group.start_unix >= lsbs] + start_unixes = np.array(group.start_unix) + start_unixes = np.sort(np.unique(start_unixes))[:self.node2num_cycles[node_id]] + + group = group[group.start_unix.isin(start_unixes)] + self.sigtable.append(group) + self.sigtable = pd.concat(self.sigtable).reset_index(drop=True) + self.sigtable['phase_sumo'] = self.sigtable.groupby(['node_id', 'start_unix']).cumcount() + + # 5-2. 적색 및 황색신호 부여 + def assign_red_yellow(self): + ''' + 적색, 황색신호를 반영한 신호문자열 배정 + + input : sigtable + - 모든 교차로에 대한 (시작유닉스, 세부현시번호)별 현시시간, 신호문자열, 진입·진출엣지 + * 세부현시란 오버랩을 반영한 현시번호를 뜻함. + + output : SIGTABLE + - 모든 교차로에 대한 (시작유닉스, 녹황적세부현시번호)별 현시시간, (황·적색신호가 포함된) 신호문자열 + * 녹황적세부현시번호란 세부현시번호에 r, g, y 옵션까지 포함된 현시번호를 뜻함. + ''' + self.SIGTABLE = [] + for node_id in self.node_ids: + sig = self.sigtable.query('node_id==@node_id') + for i, row in sig.iterrows(): + inter_no = row.inter_no + phas_A = row.phas_A + phas_B = row.phas_B + start_unix = row.start_unix + prow = self.load_prow(inter_no, start_unix)[1].iloc[0] + red_A = prow[f'red_A{phas_A}'] + yellow_A = prow[f'yellow_A{phas_A}'] + red_B = prow[f'red_B{phas_B}'] + yellow_B = prow[f'yellow_B{phas_B}'] + sig.loc[i, ['red_A', 'red_B', 'yellow_A', 'yellow_B']] = red_A, red_B, yellow_A, yellow_B + sig = sig.astype({'red_A': int, 'red_B': int, 'yellow_A': int, 'yellow_B': int, + 'phas_A':str, 'phas_B':str}) + sig = sig.drop(['move_A','move_B'], axis=1) + + sig_A = sig[['start_unix', 'phas_A', 'duration', 'state_A', 'red_A', 'yellow_A']].reset_index(drop=True) + sig_B = sig[['start_unix', 'phas_B', 'duration', 'state_B', 'red_B', 'yellow_B']].reset_index(drop=True) + + csig_A = self.cumulate(sig_A, 'A') + csig_B = self.cumulate(sig_B, 'B') + + SIG = pd.merge(csig_A, csig_B, on=['start_time', 'start_unix'], how='outer') + SIG = SIG.sort_values(by='start_time').reset_index(drop=True) + SIG[['phas_A', 'state_A']] = SIG[['phas_A', 'state_A']].fillna(method='ffill') + SIG[['phas_B', 'state_B']] = SIG[['phas_B', 'state_B']].fillna(method='ffill') + SIG['phase'] = SIG['phas_A'] + "_" + SIG['phas_B'] + SIG['node_id'] = node_id + SIG = SIG[['node_id', 'start_unix', 'start_time', 'phase', 'state_A', 'state_B']] + SIG['duration'] = SIG['start_time'].shift(-1) - SIG['start_time'] + SIG = SIG[:-1] + SIG['duration'] = SIG['duration'].astype(int) + for row in SIG.itertuples(): + state = '' + for a, b, in zip(row.state_A, row.state_B): + if a == 'r': + state += b + elif b == 'r': + state += a + elif a == b: + state += a + else: + raise ValueError(f"예상되지 않은 조합 발생: a={a}, b={b}") + SIG.at[row.Index, 'state'] = state + SIG = SIG.drop(columns=['start_time', 'state_A', 'state_B']) + self.SIGTABLE.append(SIG) + self.SIGTABLE = pd.concat(self.SIGTABLE) + self.SIGTABLE # 5-2-1 helper function of 5-2 def get_red(self, pre_state:str, cur_state:str): @@ -688,108 +778,6 @@ class SignalGenerator(): csig = pd.concat(csig).reset_index(drop=True) return csig - # 5. 신호 생성 - def get_signals(self): - print("5. 신호를 생성합니다.") - self.set_timepoints() - self.time51 = datetime.now() - self.assign_red_yellow() - self.time52 = datetime.now() - self.make_tl_file() - self.time53 = datetime.now() - - # 5-1. 신호 파일의 시작 및 종료시각 설정 - def set_timepoints(self): - self.offsets = {} - self.sigtable = [] - sim_start = self.present_time - 300 - for node_id, group in self.histids.groupby('node_id'): - lsbs = group[group['start_unix'] < sim_start]['start_unix'].max() # the last start_unix before sim_start - self.offsets[node_id] = lsbs - sim_start - group = group[group.start_unix >= lsbs] - start_unixes = np.array(group.start_unix) - start_unixes = np.sort(np.unique(start_unixes))[:self.node2num_cycles[node_id]] - - group = group[group.start_unix.isin(start_unixes)] - self.sigtable.append(group) - self.sigtable = pd.concat(self.sigtable).reset_index(drop=True) - self.sigtable['phase_sumo'] = self.sigtable.groupby(['node_id', 'start_unix']).cumcount() - - # 유턴 신호가 한번도 배정되지 않은 경우에 대해서는 유턴이동류의 신호를 항상 g로 배정 - for uturn_id in self.uturn_ids: - the_uturn = self.sigtable.node_id==uturn_id - states = np.unique(self.sigtable[the_uturn][['state_A', 'state_B']].values) - if not any('G' in state for state in states): - uindex = self.uid2uindex[uturn_id] - for i, row in self.sigtable[the_uturn].iterrows(): - self.sigtable.at[i, 'state_A'] = row.state_A[:uindex] + 'g' + row.state_A[uindex+1:] - self.sigtable.at[i, 'state_B'] = row.state_B[:uindex] + 'g' + row.state_B[uindex+1:] - - # 5-2. 적색 및 황색신호 부여 - def assign_red_yellow(self): - ''' - 적색, 황색신호를 반영한 신호문자열 배정 - - input : sigtable - - 모든 교차로에 대한 (시작유닉스, 세부현시번호)별 현시시간, 신호문자열, 진입·진출엣지 - * 세부현시란 오버랩을 반영한 현시번호를 뜻함. - - output : SIGTABLE - - 모든 교차로에 대한 (시작유닉스, 녹황적세부현시번호)별 현시시간, (황·적색신호가 포함된) 신호문자열 - * 녹황적세부현시번호란 세부현시번호에 r, g, y 옵션까지 포함된 현시번호를 뜻함. - ''' - self.SIGTABLE = [] - for node_id in self.node_ids: - sig = self.sigtable.query('node_id==@node_id') - for i, row in sig.iterrows(): - inter_no = row.inter_no - phas_A = row.phas_A - phas_B = row.phas_B - start_unix = row.start_unix - prow = self.load_prow(inter_no, start_unix)[1].iloc[0] - red_A = prow[f'red_A{phas_A}'] - yellow_A = prow[f'yellow_A{phas_A}'] - red_B = prow[f'red_B{phas_B}'] - yellow_B = prow[f'yellow_B{phas_B}'] - sig.loc[i, ['red_A', 'red_B', 'yellow_A', 'yellow_B']] = red_A, red_B, yellow_A, yellow_B - sig = sig.astype({'red_A': int, 'red_B': int, 'yellow_A': int, 'yellow_B': int, - 'phas_A':str, 'phas_B':str}) - sig = sig.drop(['move_A','move_B'], axis=1) - - sig_A = sig[['start_unix', 'phas_A', 'duration', 'state_A', 'red_A', 'yellow_A']].reset_index(drop=True) - sig_B = sig[['start_unix', 'phas_B', 'duration', 'state_B', 'red_B', 'yellow_B']].reset_index(drop=True) - - csig_A = self.cumulate(sig_A, 'A') - csig_B = self.cumulate(sig_B, 'B') - - SIG = pd.merge(csig_A, csig_B, on=['start_time', 'start_unix'], how='outer') - SIG = SIG.sort_values(by='start_time').reset_index(drop=True) - SIG[['phas_A', 'state_A']] = SIG[['phas_A', 'state_A']].fillna(method='ffill') - SIG[['phas_B', 'state_B']] = SIG[['phas_B', 'state_B']].fillna(method='ffill') - SIG['phase'] = SIG['phas_A'] + "_" + SIG['phas_B'] - SIG['node_id'] = node_id - SIG = SIG[['node_id', 'start_unix', 'start_time', 'phase', 'state_A', 'state_B']] - SIG['duration'] = SIG['start_time'].shift(-1) - SIG['start_time'] - SIG = SIG[:-1] - SIG['duration'] = SIG['duration'].astype(int) - for row in SIG.itertuples(): - state = '' - for a, b, in zip(row.state_A, row.state_B): - if a == 'r': - state += b - elif b == 'r': - state += a - elif a == b: - state += a - else: - raise ValueError(f"예상되지 않은 조합 발생: a={a}, b={b}") - SIG.at[row.Index, 'state'] = state - SIG = SIG.drop(columns=['start_time', 'state_A', 'state_B']) - self.SIGTABLE.append(SIG) - self.SIGTABLE = pd.concat(self.SIGTABLE) - self.SIGTABLE - - # 5-3. 신호파일 생성 def make_tl_file(self): strings = ['\n']