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",
+ " inter_no | \n",
+ " node_id | \n",
+ " start_unix | \n",
+ " phas_A | \n",
+ " phas_B | \n",
+ " move_A | \n",
+ " move_B | \n",
+ " duration | \n",
+ " state_A | \n",
+ " state_B | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 | \n",
+ " 175 | \n",
+ " i0 | \n",
+ " 1704415810 | \n",
+ " 1 | \n",
+ " 1 | \n",
+ " 8 | \n",
+ " 4 | \n",
+ " 43 | \n",
+ " grrrgrrrgGGGGrgrr | \n",
+ " gGGrgrrrgrrrrrgrr | \n",
+ "
\n",
+ " \n",
+ " 1 | \n",
+ " 175 | \n",
+ " i0 | \n",
+ " 1704415810 | \n",
+ " 2 | \n",
+ " 2 | \n",
+ " 7 | \n",
+ " 3 | \n",
+ " 45 | \n",
+ " grrGgrrrgrrrrrgrr | \n",
+ " grrrgrrrgrrrrGgrr | \n",
+ "
\n",
+ " \n",
+ " 2 | \n",
+ " 175 | \n",
+ " i0 | \n",
+ " 1704415810 | \n",
+ " 3 | \n",
+ " 3 | \n",
+ " 6 | \n",
+ " 1 | \n",
+ " 33 | \n",
+ " grrrgGGrgrrrrrgrr | \n",
+ " grrrgrrGgrrrrrgrr | \n",
+ "
\n",
+ " \n",
+ " 3 | \n",
+ " 175 | \n",
+ " i0 | \n",
+ " 1704415810 | \n",
+ " 3 | \n",
+ " 4 | \n",
+ " 6 | \n",
+ " 2 | \n",
+ " 22 | \n",
+ " grrrgGGrgrrrrrgrr | \n",
+ " grrrgrrrgrrrrrgGr | \n",
+ "
\n",
+ " \n",
+ " 4 | \n",
+ " 175 | \n",
+ " i0 | \n",
+ " 1704415810 | \n",
+ " 4 | \n",
+ " 4 | \n",
+ " 5 | \n",
+ " 2 | \n",
+ " 37 | \n",
+ " grrrgrrrgrrrrrgrG | \n",
+ " grrrgrrrgrrrrrgGr | \n",
+ "
\n",
+ " \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ "
\n",
+ " \n",
+ " 387 | \n",
+ " 210 | \n",
+ " u60 | \n",
+ " 1704416820 | \n",
+ " 1 | \n",
+ " 1 | \n",
+ " 6 | \n",
+ " 18 | \n",
+ " 25 | \n",
+ " GGGGGGGGr | \n",
+ " GGGGGGGGr | \n",
+ "
\n",
+ " \n",
+ " 388 | \n",
+ " 210 | \n",
+ " u60 | \n",
+ " 1704416820 | \n",
+ " 1 | \n",
+ " 2 | \n",
+ " 6 | \n",
+ " 2 | \n",
+ " 13 | \n",
+ " GGGGGGGGr | \n",
+ " GGGGGGGGr | \n",
+ "
\n",
+ " \n",
+ " 389 | \n",
+ " 210 | \n",
+ " u60 | \n",
+ " 1704416820 | \n",
+ " 2 | \n",
+ " 2 | \n",
+ " 5 | \n",
+ " 2 | \n",
+ " 38 | \n",
+ " GGGGGGGGG | \n",
+ " GGGGGGGGr | \n",
+ "
\n",
+ " \n",
+ " 390 | \n",
+ " 210 | \n",
+ " u60 | \n",
+ " 1704416820 | \n",
+ " 3 | \n",
+ " 3 | \n",
+ " 7 | \n",
+ " 4 | \n",
+ " 62 | \n",
+ " GGGGGGGGr | \n",
+ " GGGGGGGGr | \n",
+ "
\n",
+ " \n",
+ " 391 | \n",
+ " 210 | \n",
+ " u60 | \n",
+ " 1704416820 | \n",
+ " 4 | \n",
+ " 4 | \n",
+ " 8 | \n",
+ " 3 | \n",
+ " 21 | \n",
+ " GGGGGGGGr | \n",
+ " GGGGGGGGr | \n",
+ "
\n",
+ " \n",
+ "
\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']