Fully support the conversion of RINEX 2.xx & RINEX 3.xx

This commit is contained in:
KenanZhu111 committed 2024-11-17 15:16:42 +08:00
1 parent 3bf4f85363
commit 357010c137
6 files changed
+471 -250

No files matched your search

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 175 KiB

+49 -63
View File
@@ -1,17 +1,17 @@
# @ File : KNZ_Convert.py # @ File : KNZ_Convert.py
# #
# @ Brief : GUI main functions.
#
# Copyright (c) 2024 - 2024 KenanZhu. All Right Reserved. # Copyright (c) 2024 - 2024 KenanZhu. All Right Reserved.
# #
# @ Author : KenanZhu # @ Author : KenanZhu
# @ Time : 2024/11/13 # @ Time : 2024/11/13
# @ Brief :
# :
# @ IDE : PyCharm # @ IDE : PyCharm
# #
# ---------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------
# ---SELF--- # # ---SELPORT--- #
import rnx_convert as conv import rnx_convert as conv
# ---THRI--- # # ---STDPORT--- #
import queue import queue
import threading import threading
import tkinter as tk import tkinter as tk
@@ -20,17 +20,18 @@ from tkinter import ttk
from PIL import ImageTk from PIL import ImageTk
from base64 import b64decode from base64 import b64decode
from tkinter import filedialog from tkinter import filedialog
# --------------------------------------------------------------------------------------- # ------------- #
# global const
InPaths = [] InPaths = []
# # io oath combox index
I_Box_Counter=0 I_Box_Counter=0
O_Box_Counter=0 O_Box_Counter=0
# # io format list & index
I_Format_Rnx_List=0 I_Format_Rnx_List=0
I_RINEX_BoxList=['2','3'] I_RINEX_BoxList=['2','3']
O_Format_Rnx_List=0 O_Format_Rnx_List=0
O_RINEX_BoxList=['2.10','2.11','2.12','3.00','3.01','3.02','3.03','3.04','3.05'] O_RINEX_BoxList=['2.10','2.11','2.12','3.00','3.01','3.02','3.03','3.04','3.05']
# --------------------------------------------------------------------------------------- # ------------------------------------------------------------------------------------- #
def instanceOPT(parenthwnd, func): def instanceOPT(parenthwnd, func):
OPTIONS(parenthwnd, func) OPTIONS(parenthwnd, func)
@@ -143,14 +144,8 @@ class CALLBACK:
return filedir return filedir
path_len -= 1 path_len -= 1
def Convert( def Convert(self,
self, Pro_style, File_O_ynVar, File_I_BoxVar, File_O_BoxVar, Convertcards, Exec_Progress):
Pro_style,
File_O_ynVar,
File_I_BoxVar,
File_O_BoxVar,
Convertcards,
Exec_Progress):
# ------------------------------------------------------------------------------- # -------------------------------------------------------------------------------
# > # >
# Method: # Method:
@@ -183,7 +178,7 @@ class CALLBACK:
Exec_Progress.config(value=0) Exec_Progress.config(value=0)
Pro_style.configure('text.Horizontal.TProgressbar', text=ErrorMsg) Pro_style.configure('text.Horizontal.TProgressbar', text=ErrorMsg)
return return
### #
resqueue=queue.Queue() resqueue=queue.Queue()
Pro_style.configure( Pro_style.configure(
'text.Horizontal.TProgressbar', 'text.Horizontal.TProgressbar',
@@ -211,24 +206,11 @@ class CALLBACK:
'text.Horizontal.TProgressbar', 'text.Horizontal.TProgressbar',
text='Complete ! %d successful. %d fails.'%(State_O, len(InPath)-State_O)) text='Complete ! %d successful. %d fails.'%(State_O, len(InPath)-State_O))
def _Convert( def _Convert(self,
self, Pro_style, File_O_ynVar, File_I_BoxVar, File_O_BoxVar, Convertcards, Exec_Progress):
Pro_style,
File_O_ynVar,
File_I_BoxVar,
File_O_BoxVar,
Convertcards,
Exec_Progress):
T=threading.Thread(target=lambda : T=threading.Thread(target=lambda :
self.Convert( self.Convert(Pro_style, File_O_ynVar, File_I_BoxVar, File_O_BoxVar, Convertcards, Exec_Progress))
Pro_style,
File_O_ynVar,
File_I_BoxVar,
File_O_BoxVar,
Convertcards,
Exec_Progress
))
T.start() T.start()
@staticmethod @staticmethod
@@ -294,9 +276,10 @@ class MAINGUI:
# Author: @KenanZhu All Right Reserved. # Author: @KenanZhu All Right Reserved.
# ------------------------------------------------------------------------------- # -------------------------------------------------------------------------------
self.hwnd.title("KNZ_Convert") self.hwnd.title("KNZ_Convert")
self.hwnd.resizable(0, 0)
self.func.Move_center(self.hwnd, 400, 243) self.func.Move_center(self.hwnd, 400, 243)
### self.hwnd.maxsize( 1000, 243)
self.hwnd.minsize( 400, 243)
#
icon_ico = (b'AAABAAEAICAAAAEAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAABAAADjsAAA47AAAAAAAAAAAAAAAAAAAAAAAAAAAA' icon_ico = (b'AAABAAEAICAAAAEAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAABAAADjsAAA47AAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
@@ -359,11 +342,11 @@ class MAINGUI:
icon_ico = b64decode(icon_ico) icon_ico = b64decode(icon_ico)
icon_ico = ImageTk.PhotoImage(data=icon_ico) icon_ico = ImageTk.PhotoImage(data=icon_ico)
self.hwnd.tk.call('wm', 'iconphoto', self.hwnd._w, icon_ico) self.hwnd.tk.call('wm', 'iconphoto', self.hwnd._w, icon_ico)
### #
self.initCONVERT() self.initCONVERT()
### #
self.initExecCtrl() self.initExecCtrl()
### #
self.hwnd.protocol('WM_DELETE_WINDOW',self.hwnd.quit) self.hwnd.protocol('WM_DELETE_WINDOW',self.hwnd.quit)
self.hwnd.mainloop() self.hwnd.mainloop()
@@ -394,22 +377,22 @@ class MAINGUI:
# ------------------------------------------------------------------------------- # -------------------------------------------------------------------------------
self.SingleFrame=ttk.Frame(self.hwnd) self.SingleFrame=ttk.Frame(self.hwnd)
### Initialize of input frame # Initialize of input frame
File_I_Frame=tk.LabelFrame( File_I_Frame=tk.LabelFrame(
self.SingleFrame, self.SingleFrame,
text='Object Observation of RINEX') text='Object Observation of RINEX')
File_I_Frame.pack(side=tk.TOP, fill=tk.X, padx='1px', pady='0px') File_I_Frame.pack(side=tk.TOP, fill=tk.X, padx='1px', pady='0px')
### Initialize of input box # Initialize of input box
File_I_Box=ttk.Combobox( File_I_Box=ttk.Combobox(
File_I_Frame, File_I_Frame,
width=47, width=47,
height=4, height=4,
values=('',), values=('',),
textvariable=self.File_I_BoxVar) textvariable=self.File_I_BoxVar)
File_I_Box.pack(side=tk.LEFT, anchor='w', padx='1px', pady='1px') File_I_Box.pack(side=tk.LEFT, fill=tk.X, expand=tk.YES, anchor='w', padx='1px', pady='1px')
### Initialize of input Button # Initialize of input Button
File_I_Bbutton=ttk.Button( File_I_Bbutton=ttk.Button(
File_I_Frame, File_I_Frame,
text='...', text='...',
@@ -426,17 +409,17 @@ class MAINGUI:
# ------------------------------------------------------------------------------- # -------------------------------------------------------------------------------
self.BatchFrame=ttk.Frame(self.hwnd) self.BatchFrame=ttk.Frame(self.hwnd)
### #
Files_I_Frame=tk.LabelFrame( Files_I_Frame=tk.LabelFrame(
self.BatchFrame, self.BatchFrame,
text='Objects Observation of RINEX') text='Objects Observation of RINEX')
Files_I_Frame.pack(side=tk.TOP, fill=tk.X, padx='1px', pady='0px') Files_I_Frame.pack(side=tk.TOP, fill=tk.X, padx='1px', pady='0px')
### #
Files_I_CtrlFrame=ttk.Frame(Files_I_Frame) Files_I_CtrlFrame=ttk.Frame(Files_I_Frame)
Files_I_CtrlFrame.pack(side=tk.RIGHT, fill=tk.Y, anchor='e', padx='1px', pady='1px') Files_I_CtrlFrame.pack(side=tk.RIGHT, fill=tk.Y, anchor='e', padx='1px', pady='1px')
### #
Files_I_CtrlInput=ttk.Button( Files_I_CtrlInput=ttk.Button(
Files_I_CtrlFrame, Files_I_CtrlFrame,
text='...', text='...',
@@ -451,23 +434,23 @@ class MAINGUI:
command=lambda :self.func.Clear_I_Files(Files_I_ShowText)) command=lambda :self.func.Clear_I_Files(Files_I_ShowText))
Files_I_CtrlClear.pack(side=tk.BOTTOM, anchor='e', padx='1px', pady='1px') Files_I_CtrlClear.pack(side=tk.BOTTOM, anchor='e', padx='1px', pady='1px')
### #
Files_I_ShowFrame=ttk.Frame(Files_I_Frame) Files_I_ShowFrame=ttk.Frame(Files_I_Frame)
Files_I_ShowFrame.pack(side=tk.LEFT, fill=tk.X, anchor='e', padx='1px', pady='1px') Files_I_ShowFrame.pack(side=tk.LEFT, fill=tk.X, expand=tk.YES, anchor='e', padx='1px', pady='1px')
### #
ScrollbarX=ttk.Scrollbar(Files_I_ShowFrame,orient=tk.HORIZONTAL) ScrollbarX=ttk.Scrollbar(Files_I_ShowFrame,orient=tk.HORIZONTAL)
ScrollbarX.pack(side=tk.BOTTOM, fill=tk.X) ScrollbarX.pack(side=tk.BOTTOM, fill=tk.X)
ScrollbarY=ttk.Scrollbar(Files_I_ShowFrame) ScrollbarY=ttk.Scrollbar(Files_I_ShowFrame)
ScrollbarY.pack(side=tk.RIGHT, fill=tk.Y) ScrollbarY.pack(side=tk.RIGHT, fill=tk.Y)
### #
Files_I_ShowText=tk.Text( Files_I_ShowText=tk.Text(
Files_I_ShowFrame, Files_I_ShowFrame,
xscrollcommand=ScrollbarX.set, xscrollcommand=ScrollbarX.set,
yscrollcommand=ScrollbarY.set, yscrollcommand=ScrollbarY.set,
height=4, wrap='none', font=('Segoe UI',9)) height=4, wrap='none', font=('Segoe UI',9))
Files_I_ShowText.pack(side=tk.LEFT, fill=tk.BOTH, anchor='w', padx='1px', pady='1px') Files_I_ShowText.pack(side=tk.LEFT, fill=tk.X, expand=tk.YES, anchor='w', padx='1px', pady='1px')
ScrollbarX.config(command=Files_I_ShowText.xview) ScrollbarX.config(command=Files_I_ShowText.xview)
ScrollbarY.config(command=Files_I_ShowText.yview) ScrollbarY.config(command=Files_I_ShowText.yview)
@@ -500,7 +483,7 @@ class MAINGUI:
text='Output directory') text='Output directory')
File_O_Frame.pack(side=tk.TOP, fill=tk.X, padx='1px', pady='1px') File_O_Frame.pack(side=tk.TOP, fill=tk.X, padx='1px', pady='1px')
### #
File_O_yn=ttk.Checkbutton( File_O_yn=ttk.Checkbutton(
File_O_Frame, File_O_Frame,
text='Directory', text='Directory',
@@ -513,7 +496,7 @@ class MAINGUI:
File_O_Button)) File_O_Button))
File_O_yn.pack(side=tk.LEFT, anchor='w', padx='1px', pady='0px') File_O_yn.pack(side=tk.LEFT, anchor='w', padx='1px', pady='0px')
### #
File_O_Box=ttk.Combobox( File_O_Box=ttk.Combobox(
File_O_Frame, File_O_Frame,
width=36, width=36,
@@ -521,9 +504,9 @@ class MAINGUI:
values=('',), values=('',),
state=tk.DISABLED, state=tk.DISABLED,
textvariable=self.File_O_BoxVar) textvariable=self.File_O_BoxVar)
File_O_Box.pack(side=tk.LEFT, anchor='w', padx='1px', pady='0px') File_O_Box.pack(side=tk.LEFT, fill=tk.X, expand=tk.YES, anchor='w', padx='1px', pady='0px')
### #
File_O_Button=ttk.Button( File_O_Button=ttk.Button(
File_O_Frame, File_O_Frame,
text='...', text='...',
@@ -548,7 +531,7 @@ class MAINGUI:
command=lambda :instanceOPT(self.hwnd,self.func) command=lambda :instanceOPT(self.hwnd,self.func)
) )
Conv_Option.pack(side=tk.RIGHT, padx='1px', pady='0px') Conv_Option.pack(side=tk.RIGHT, padx='1px', pady='0px')
### #
Conv_Button=ttk.Button( Conv_Button=ttk.Button(
CtrlButtonFrame, CtrlButtonFrame,
text='Convert', text='Convert',
@@ -561,7 +544,7 @@ class MAINGUI:
self.Convertcards, self.Convertcards,
self.Exec_Progress)) self.Exec_Progress))
Conv_Button.pack(side=tk.RIGHT, padx='1px', pady='0px') Conv_Button.pack(side=tk.RIGHT, padx='1px', pady='0px')
### #
Exit_button=ttk.Button( Exit_button=ttk.Button(
CtrlButtonFrame, CtrlButtonFrame,
text='Exit', text='Exit',
@@ -569,7 +552,7 @@ class MAINGUI:
command=self.hwnd.quit) command=self.hwnd.quit)
Exit_button.pack(side=tk.LEFT, padx='1px', pady='0px') Exit_button.pack(side=tk.LEFT, padx='1px', pady='0px')
### #
StateFrame=ttk.Frame(self.ExecFrame) StateFrame=ttk.Frame(self.ExecFrame)
StateFrame.pack(side=tk.TOP, fill=tk.X, padx='1px', pady='4px') StateFrame.pack(side=tk.TOP, fill=tk.X, padx='1px', pady='4px')
self.Pro_style=ttk.Style(StateFrame) self.Pro_style=ttk.Style(StateFrame)
@@ -595,7 +578,8 @@ class MAINGUI:
maximum=100, maximum=100,
mode='determinate', mode='determinate',
style='text.Horizontal.TProgressbar') style='text.Horizontal.TProgressbar')
self.Exec_Progress.pack(side=tk.LEFT) self.Exec_Progress.pack(side=tk.LEFT, fill=tk.X, expand=tk.YES)
class OPTIONS: class OPTIONS:
def __init__(self, parenthwnd, func): def __init__(self, parenthwnd, func):
@@ -625,7 +609,7 @@ class OPTIONS:
self.opthwnd.resizable(0, 0) self.opthwnd.resizable(0, 0)
self.func.Move_center(self.opthwnd, 310, 110) self.func.Move_center(self.opthwnd, 310, 110)
### Set icon # Set icon
icon_ico=(b'AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' icon_ico=(b'AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOrq6v/q6ur/6urq/+rq6v/q6ur/6urq/+rq6v/q6ur/6' b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOrq6v/q6ur/6urq/+rq6v/q6ur/6urq/+rq6v/q6ur/6'
@@ -646,11 +630,11 @@ class OPTIONS:
icon_ico=ImageTk.PhotoImage(data=icon_ico) icon_ico=ImageTk.PhotoImage(data=icon_ico)
self.opthwnd.tk.call('wm', 'iconphoto', self.opthwnd._w, icon_ico) self.opthwnd.tk.call('wm', 'iconphoto', self.opthwnd._w, icon_ico)
### Mian frame # Mian frame
self.MainFrame=ttk.Frame(self.opthwnd) self.MainFrame=ttk.Frame(self.opthwnd)
self.MainFrame.pack() self.MainFrame.pack()
### init # init
self.initOPTIONS() self.initOPTIONS()
self.initEXECTRL() self.initEXECTRL()
@@ -702,7 +686,7 @@ class OPTIONS:
state=tk.DISABLED, state=tk.DISABLED,
values=I_RTCM_BoxList) values=I_RTCM_BoxList)
I_RTCM_Box.set(I_RTCM_BoxList[0]) I_RTCM_Box.set(I_RTCM_BoxList[0])
#I_RTCM_Box['state']='readonly' # I_RTCM_Box['state']='readonly'
I_RTCM_Box.pack(side=tk.RIGHT) I_RTCM_Box.pack(side=tk.RIGHT)
# ------------------------------------------------------------------------------- # -------------------------------------------------------------------------------
# Target format frame # Target format frame
@@ -743,7 +727,7 @@ class OPTIONS:
state=tk.DISABLED, state=tk.DISABLED,
values=O_RTCM_BoxList) values=O_RTCM_BoxList)
O_RTCM_Box.set(I_RTCM_BoxList[0]) O_RTCM_Box.set(I_RTCM_BoxList[0])
#O_RTCM_Box['state']='readonly' # O_RTCM_Box['state']='readonly'
O_RTCM_Box.pack(side=tk.RIGHT) O_RTCM_Box.pack(side=tk.RIGHT)
def initEXECTRL(self): def initEXECTRL(self):
@@ -782,6 +766,8 @@ class OPTIONS:
I_Format_Rnx_List=I_RINEX_BoxList.index(self.I_RINEX_Box.get()) I_Format_Rnx_List=I_RINEX_BoxList.index(self.I_RINEX_Box.get())
O_Format_Rnx_List=O_RINEX_BoxList.index(self.O_RINEX_Box.get()) O_Format_Rnx_List=O_RINEX_BoxList.index(self.O_RINEX_Box.get())
# Main program entry ---------------------------- #
if __name__ == "__main__": if __name__ == "__main__":
root=tk.Tk() root=tk.Tk()
call=CALLBACK() call=CALLBACK()
+4 -3
View File
@@ -18,9 +18,7 @@ the file is lossless conversion, only convert the foemat,
do not modify the information. do not modify the information.
2. The double character observation types of RINEX2.xx version will be automatically matched according to the following table: 2. The double character observation types of RINEX2.xx version will be automatically matched according to the following table:
[Convert_chart.jpg](Convert_chart.jpg) ### Update brief ###
### About Project ###
2024/11/14: At present, the RINEX2.xx format conversion has been fully supported, 2024/11/14: At present, the RINEX2.xx format conversion has been fully supported,
the format output error of the previous version has been modified, the format output error of the previous version has been modified,
and the conversion from 2.xx to 3.xx is currently supported. and the conversion from 2.xx to 3.xx is currently supported.
@@ -28,6 +26,9 @@ and the conversion from 2.xx to 3.xx is currently supported.
2024/11/15: Correct the output format, omit the empty observation and change the 2024/11/15: Correct the output format, omit the empty observation and change the
rule of match. rule of match.
2024/11/17: Fully support the conversion of RINEX 2.xx & RINEX 3.xx, also support
the conversion of same major version.
### Update plan ### ### Update plan ###
1. 2.xx and 3.xx versions are fully supported, and support mutual conversion. 1. 2.xx and 3.xx versions are fully supported, and support mutual conversion.
2. Gradually introduce the conversion support for RTCM files. 2. Gradually introduce the conversion support for RTCM files.
+2 -3
View File
@@ -14,11 +14,10 @@
1. 主要对2.11 & 2.10 格式的RINEX观测值文件进行无损转换,不需要额外参数输入,软件会自动转换格式,不会对原文件信息进行更改。 1. 主要对2.11 & 2.10 格式的RINEX观测值文件进行无损转换,不需要额外参数输入,软件会自动转换格式,不会对原文件信息进行更改。
2. 对于RINEX2.xx版本的两字符观测值类型将按照如下表格进行自动匹配: 2. 对于RINEX2.xx版本的两字符观测值类型将按照如下表格进行自动匹配:
[Convert_chart.jpg](Convert_chart.jpg) ### 更新简记 ###
### 关于项目 ###
2024/11/14: 目前已经对RINEX2.xx格式转换进行了全面支持,修改了上一版本的格式输出错误,目前支持2.xx转换为3.xx。 2024/11/14: 目前已经对RINEX2.xx格式转换进行了全面支持,修改了上一版本的格式输出错误,目前支持2.xx转换为3.xx。
2024/11/15: 更正了输出格式,忽略空余信号并更改匹配规则 2024/11/15: 更正了输出格式,忽略空余信号并更改匹配规则
2024/11/17: 支持RINEX2.xx格式和RINEX3.xx格式的相互转换,同时支持同一主要版本之间的转换。
### 更新计划 ### ### 更新计划 ###
1. 2.xx版本与3.xx版本全面支持,支持相互转换。 1. 2.xx版本与3.xx版本全面支持,支持相互转换。
+398 -181
View File
@@ -1,19 +1,28 @@
# @ File : rnx_convert.py # @ File : rnx_convert.py
# #
# @ Brief : RINEX Convert functions.
#
# Copyright (c) 2024 - 2024 KenanZhu. All Right Reserved. # Copyright (c) 2024 - 2024 KenanZhu. All Right Reserved.
# #
# @ Author : KenanZhu # @ Author : KenanZhu
# @ Time : 2024/11/13 # @ Time stamp : [2024/11/13] First release.
# @ Brief : # : [2024/11/14] Correct: convert of observation type of
# 'P1/P2' of GPS is correct into 'C1W/C2W'.
# : [2024/11/15] Fix bug: remove the empty observation of
# RINEX 2.xx format.
# : [2024/11/17] Add new: complish the funtions of convert
# form RINEX 3.xx to RINEX 2.xx and also support
# convert in major version of RINEX.
# : # :
# @ IDE : PyCharm # @ IDE/Editor : PyCharm / VisualStudio Code
# #
# ---------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------
# ---STDPORT--- #
import re import re
import time import time
import math import math
import threading import threading
# ------------- #
emp='' emp=''
bnk=' ' bnk=' '
@@ -21,9 +30,9 @@ bnk=' '
def conv_time(): def conv_time():
# generate convert timestamp # generate convert timestamp
covpro='KNZ_Convert ver1.2.5' covpro='KNZ_Convert ver1.2.5'
covtmp='COV-PGM / DATE' covcom='COMMENT'
# Get the locate time and transform to RINEX format # Get the locate time and transform to Uni-format
y=time.localtime().tm_year y=time.localtime().tm_year
m=time.localtime().tm_mon m=time.localtime().tm_mon
d=time.localtime().tm_mday d=time.localtime().tm_mday
@@ -41,14 +50,12 @@ def conv_time():
outline=(covpro + outline=(covpro +
20*bnk + 20*bnk +
localtime+ localtime+
covtmp + covcom +
'\n') '\n')
return outline return outline
# Convert data format --------------------------- #
# Convert Format ------------------------------ #
def datefmt2_conv(inline): def datefmt2_conv(inline):
hou=inline[49:51] hou=inline[49:51]
min=inline[52:54] min=inline[52:54]
@@ -60,9 +67,7 @@ def datefmt2_conv(inline):
bnk + "UTC" + bnk + "UTC" +
bnk + "PGM / RUN BY / DATE\n") bnk + "PGM / RUN BY / DATE\n")
# Convert data format --------------------------- #
# Convert Format ------------------------------ #
def datefmt3_conv(inline): def datefmt3_conv(inline):
hou=inline[49:51] hou=inline[49:51]
min=inline[51:53] min=inline[51:53]
@@ -70,17 +75,15 @@ def datefmt3_conv(inline):
return (inline[0:49] + return (inline[0:49] +
hou + ':' + hou + ':' +
min + ':' + min + ':' +
sec + ':' + sec +
'UTCPGM / RUN BY / DATE\n') 'UTCPGM / RUN BY / DATE\n')
# Convert observ type of RINEX 2.xx to Uni-format ------------- #
# Convert observ type of RINEX 2.xx to Uni-Format --------------- #
def obsfmt2_conv(obstypes, sys): def obsfmt2_conv(obstypes, sys):
counter =0 counter =0
obstypex=[] obstypex=[]
obsbomit='' obsbomit=emp
match sys: match sys:
case 'G': case 'G':
@@ -144,9 +147,7 @@ def obsfmt2_conv(obstypes, sys):
return obstypex return obstypex
# Convert observ msg of RINEX 2.xx to Uni-format ---------------- #
# Convert observ msg of RINEX 2.xx to Uni-Format ---------------- #
def obstype2_conv(inline, in_f, omilist): def obstype2_conv(inline, in_f, omilist):
# uni-format message label # uni-format message label
obsobs='SYS / # / OBS TYPES' obsobs='SYS / # / OBS TYPES'
@@ -182,14 +183,12 @@ def obstype2_conv(inline, in_f, omilist):
outline=7*bnk outline=7*bnk
return outlines return outlines
# Generate the convert stamp ------------------------ #
def conv_stamp(inline, outlines, desver):
# Convert obstpe msg of RINEX 2.xx to Uni-Format --------------- #
def obstpe2_conv(inline, outlines, desver):
oriver=inline[ 5: 9] oriver=inline[ 5: 9]
# generate convert stamp # generate convert stamp
obscov='COV-OBSERVATION DATA' obscov='COV-OBSERVATION DATA'
covpro='COV-RINEX VER / TYPE' obscom='COMMENT'
outlines.append( 5*bnk+ outlines.append( 5*bnk+
oriver+ oriver+
@@ -198,16 +197,14 @@ def obstpe2_conv(inline, outlines, desver):
1*bnk+ 1*bnk+
obscov+ obscov+
24*bnk+ 24*bnk+
covpro+ obscom+
'\n') '\n')
outlines.append(conv_time()) outlines.append(conv_time())
outlines.append( outlines.append(
inline.replace('%s'%re.search(r'[1-9]\d*.\d*|0\.\d*[1-9]\d*', inline).group(), desver)) inline.replace('%s'%re.search(r'[1-9]\d*.\d*|0\.\d*[1-9]\d*', inline).group(), desver))
return return
# Convert RINEX 2.xx(header) to Uni-format -------------- #
# Convert head_data of RINEX 2.xx to Uni-format -------------- #
def rnx2_head2uni(in_f, desver, outlines, omilist): def rnx2_head2uni(in_f, desver, outlines, omilist):
# rinex message label # rinex message label
obscom='COMMENT' obscom='COMMENT'
@@ -221,11 +218,11 @@ def rnx2_head2uni(in_f, desver, outlines, omilist):
while True: while True:
inline=in_f.readline() inline=in_f.readline()
# file is aleady checked so no need to judge again # file is aleady checked so no need to judge again
if not inline: pass if not inline: break
if inline.find(obscom)>=0: outlines.append(inline) if inline.find(obscom)>=0: outlines.append(inline)
elif inline.find(obspro)>=0: outlines.append(datefmt2_conv(inline)) elif inline.find(obspro)>=0: outlines.append(datefmt2_conv(inline))
elif inline.find(obsobs)>=0: outlines.extend(obstype2_conv(inline, in_f, omilist)) elif inline.find(obsobs)>=0: outlines.extend(obstype2_conv(inline, in_f, omilist))
elif inline.find(obstpe)>=0: obstpe2_conv(inline, outlines, desver) elif inline.find(obstpe)>=0: conv_stamp(inline, outlines, desver)
elif inline.find(obsl12)>=0: continue elif inline.find(obsl12)>=0: continue
elif inline.find(obsend)>=0: break elif inline.find(obsend)>=0: break
else : outlines.append(inline) else : outlines.append(inline)
@@ -235,9 +232,7 @@ def rnx2_head2uni(in_f, desver, outlines, omilist):
return 1 return 1
# Convert RINEX 2.xx(data) to Uni-Format ------------------- #
# Convert obs of RINEX 2.xx to Uni-Format ------------------- #
def rnx2_data2uni(in_f, outlines, omilist, obsnum): def rnx2_data2uni(in_f, outlines, omilist, obsnum):
sPRN=[] sPRN=[]
scounter=0 scounter=0
@@ -245,7 +240,7 @@ def rnx2_data2uni(in_f, outlines, omilist, obsnum):
# return false when file end # return false when file end
inline=in_f.readline() inline=in_f.readline()
if not inline : return False if not inline: return False
# get epoch message & flag state # get epoch message & flag state
year = int(inline[0 :3]) year = int(inline[0 :3])
@@ -310,17 +305,13 @@ def rnx2_data2uni(in_f, outlines, omilist, obsnum):
outlines.append(sPRN[i]+outline+"\n") outlines.append(sPRN[i]+outline+"\n")
return True return True
# Convert Uni-format to RINEX 3.xx --------------------- # # Convert Uni-format to RINEX 3.xx --------------------- #
def uni2rnx3_data(outlines, out_path): def uni2rnx3_data(outlines, out_path):
out_f = open(out_path, 'a') out_f=open(out_path, 'a')
out_f.writelines(outlines) out_f.writelines(outlines)
out_f.close() out_f.close()
return return
# Get observ type need be omitted --------------------- # # Get observ type need be omitted --------------------- #
def getomit(omilist): def getomit(omilist):
for i in range(len(omilist)): for i in range(len(omilist)):
@@ -333,36 +324,391 @@ def getomit(omilist):
omilist.pop(0) omilist.pop(0)
return return
# Convert RINEX 2.xx to Des-format --------------------- #
# Convert data of RINEX 2.xx to Des-format ----------------- #
def rnx2des(in_path, out_path, oriver, desver): def rnx2des(in_path, out_path, oriver, desver):
headread=False headread=False
outlines=[] outlines=[]
omilist=[] omilist=[]
# convert rinex 2.xx(header) to Uni-format # convert RINEX 2.xx(header) to Uni-format
in_f=open(in_path, 'r') in_f=open(in_path, 'r')
match rnx2_head2uni(in_f, desver, outlines, omilist): match rnx2_head2uni(in_f, desver, outlines, omilist):
case 1: headread=True case 1: headread=True
case 0: headread=False case 0: headread=False
uni2rnx3_data(outlines, out_path)
outlines=[]
if headread: if headread:
# convert Uni-foramt(header) to Des-format
match desver[0:1]:
case '2': addemp=uni2rnx2_data(4, outlines, out_path, True, None)
case '3': uni2rnx3_data(outlines, out_path)
outlines=[]
# get each observ type and omit the empty # get each observ type and omit the empty
obsnum=omilist[0] obsnum=omilist[0]
omilist.pop(0) omilist.pop(0)
getomit(omilist) getomit(omilist)
# convert RINEX 2.xx(data) to Uni-format
while rnx2_data2uni(in_f, outlines, omilist, obsnum): while rnx2_data2uni(in_f, outlines, omilist, obsnum):
# convert Uni-foramt(data) to Des-format
match desver[0:1]: match desver[0:1]:
case '2': return 0 case '2': uni2rnx2_data(4, outlines, out_path, False, addemp)
case '3': uni2rnx3_data(outlines, out_path) case '3': uni2rnx3_data(outlines, out_path)
outlines=[] outlines=[]
elif not headread: return 0
in_f.close()
return 1 return 1
# Get the position of new add observ type ----------------- #
def getaddemp(alltypes, sysstype):
addemp=[[],[],[],[]]
for i in range(len(sysstype)):
for j in range(len(sysstype[i])):
for k in range(len(alltypes)):
if sysstype[i][j]==alltypes[k]:
addemp[i].append(k)
return addemp
# Filter the same obs fmt in RINEX 2.xx ----------------- #
def obsfmt_filter(alltypes):
empemp=[]
spos=npos=0
empemp.append(len(alltypes))
while True:
npos+=1
if spos==empemp[0]: break
if npos==empemp[0]:
spos+=1
npos=spos
continue
if not alltypes[spos]: continue
if not alltypes[npos]: continue
if alltypes[spos]==alltypes[npos]:
alltypes[npos]=emp
empemp.append(npos)
# restruct the data
totnum=empemp[0]
empemp=sorted(empemp[1:])
empemp.insert(0,totnum)
empemp.clear()
# addemp.append(empemp)
# clear the empty
alltypes=[obs for obs in alltypes if obs!=emp]
return alltypes
# Sort by observ type --------------------------- #
def sort_observ(alltypes):
alltypex=[]
temtypes=[]
freindex=['1','2','3','4',
'5','6','7','8']
obsetype=['C','L','D','S']
for type in alltypes:
freidx=freindex.index(type[1:2])/ 1
if type=='P1C' or type=='P2C':
tyeidx=obsetype.index(type[2:3])/10
else:
tyeidx=obsetype.index(type[0:1])/10
alltypex.append(freidx+tyeidx)
sdx=ndx=0
while True:
if len(alltypex)==0:
break
if (ndx+1)==len(alltypex):
temtypes.append(alltypes[sdx])
alltypes.pop(sdx)
alltypex.pop(sdx)
sdx=ndx=0
continue
ndx+=1
if alltypex[ndx]<=alltypex[sdx]:
sdx=ndx
continue
return temtypes
# Convert observ type of RINEX 3.xx to Uni-Format --------------- #
def obsfmt3_conv(alltypes):
alltypex=[]
for type in alltypes:
if type[1:2]=='1':
if type=='C1W': type='P1'
elif type[1:2]=='2':
if type=='C2W': type='P2'
else: pass
alltypex.append(type[0:2])
return alltypex
# Convert observ msg of RINEX 3.xx to Uni-Format ---------------- #
def obstype3_conv(i, sysnum, outlines, outlinex):
sysstype=[]
alltypes=[]
obstypes=[]
# rinex message label
obsobs='# / TYPES OF OBSERV'
for j in range(sysnum):
obstypes=[]
# reject system not support in Uni-Format
match outlines[i][0:1]:
case 'G': obstypes.append(0)
case 'E': obstypes.append(1)
case 'R': obstypes.append(2)
case 'S': obstypes.append(3)
case _:
i+=1
continue
obsnum=int(outlines[i][1:6])
for k in range(math.ceil(obsnum/13)):
obstypes.extend(outlines[i][6:60].split())
if k+1==math.ceil(obsnum/13): break
i+=1
# check the differ observ type in glonass
if obstypes[0]==2:
try:
pos=obstypes.index('C1P')
obstypes[pos]='P1C'
except ValueError: pass
try:
pos=obstypes.index('C2P')
obstypes[pos]='P2C'
except ValueError: pass
sysstype.append(obsfmt3_conv(obstypes[1:]))
alltypes=list(set(obstypes[1:]+alltypes))
i+=1
# sort observ types
alltypes=sort_observ(alltypes)
# convert observ type into des-format
alltypes=obsfmt3_conv(alltypes)
# fliter the same observ type
alltypes=obsfmt_filter(alltypes)
# get new added pos
addemp=getaddemp(alltypes, sysstype)
num =len(alltypes)
outline=4*bnk+'%2d'%num
for j in range(num):
outline+=4*bnk+alltypes[j]
if (j+1)==num:
bnx=((9-num%9)*6)*bnk
outlinex.append(outline+bnx+obsobs+'\n')
outline=0*bnk
elif (j+1)%9==0:
bnx=0*bnk
outlinex.append(outline+bnx+obsobs+'\n')
outline=6*bnk
# get amout of observ tyeps
addemp.append(num)
return addemp
# Get the total amount of sat system -------------------- #
def getsys_rnx3(in_f):
# rinex message label
obsobs='SYS / # / OBS TYPES'
readst=False
syslis=[]
sysnum=0
while True:
inline=in_f.readline()
if not inline: break
if inline.find(obsobs)>=0:
readst=True
sys=inline[0:1]
if sys and sys not in syslis:
syslis.append(sys)
sysnum+=1
elif readst and inline.find(obsobs)<0: break
in_f.seek(0)
return sysnum
# Convert head_data of RINEX 3.xx to Uni-format -------------- #
def rnx3_head2uni(in_f, desver, outlines):
# rinex message label
# obscom='COMMENT'
obstpe='RINEX VERSION / TYPE'
# obspro='PGM / RUN BY / DATE'
# obsobs='SYS / # / OBS TYPES'
obsshi='SYS / PHASE SHIFT'
obsrsb='GLONASS COD/PHS/BIS'
obsrsl='GLONASS SLOT / FRQ #'
obsend='END OF HEADER'
# get input head file & convert
while True:
inline=in_f.readline()
# file is aleady checked so no need to judge again
if not inline: break
#if inline.find(obscom)>=0: outlines.append(inline)
#elif inline.find(obspro)>=0: outlines.append(inline)
#elif inline.find(obsobs)>=0: outlines.append(inline)
elif inline.find(obstpe)>=0: conv_stamp(inline, outlines, desver)
elif inline.find(obsshi)>=0: continue
elif inline.find(obsrsb)>=0: continue
elif inline.find(obsrsl)>=0: continue
elif inline.find(obsend)>=0: break
else : outlines.append(inline)
# get the end message after break
outlines.append(60*bnk+obsend+'\n')
return 1
# Convert obs of RINEX 3.xx to Uni-format ------------------- #
def rnx2uni3_data(outlines, in_f):
inline=in_f.readline()
if not inline: return False
if not int(inline[30:32])==0: return True
outlines.append(inline)
satnum=int(inline[33:35])
for i in range(satnum):
outlines.append(in_f.readline())
return True
# Convert RINEX 3.xx(epoch msg) to RINEX 2.xx --------------- #
def rnx3rnx2_epo(outline, sPRN):
outlines=[]
datedat=outline.split()
outline=(
'%3d%3d%3d%3d%3d%11.7f%3d%3d'
%(int(datedat[1])-2000,int(datedat[2]), int(datedat[3]),# |year |month |day
int(datedat[4]) ,int(datedat[5]),float(datedat[6]),# |hour |minute |second
int(datedat[7]) ,len(sPRN))) # |flag |satnum |
# convert to RINEX 2.xx
satnum=len(sPRN)
for i in range(satnum):
outline+=sPRN[i]
if (i+1)==len(sPRN):
outlines.append(outline+'\n')
elif (i+1)%12==0:
outlines.append(outline+'\n')
outline=32*bnk
return outlines
# Convert RINEX 3.xx(data of each sat) to RINEX 2.xx ------------ #
def rnx3rnx2_dat(addemp, obsnum, outline):
outlines=[]
num=range(len(addemp))
empdat=16*bnk
outlinx=[empdat for i in range(obsnum)]
for i,j in zip(num,addemp):
if not outlinx[j]==empdat: continue
if outline[i*16+3:i*16+16+3]:
outlinx[j]=outline[i*16+3:i*16+16+3]\
.replace('\n',2*bnk).replace('\r',2*bnk)
else: continue
outline=emp
for i in range(len(outlinx)):
outline+=outlinx[i]
for i in range(math.ceil(len(outline)/80)):
outlines.append(outline[i*80:i*80+80]+'\n')
return outlines
# Convert RINEX 3.xx to RINEX 2.xx --------------------- #
def rnx3rnx2_data(outlines, addemp):
sPRN=[]
datline=[]
outlinex=[]
# filter the sat system ecxcept:#
# ---GPS-Galileo-GLONASS-SBAS---#
for i in range(len(outlines)):
if outlines[i][0:1]=='G': pass
elif outlines[i][0:1]=='E': pass
elif outlines[i][0:1]=='R': pass
elif outlines[i][0:1]=='S': pass
else: continue
datline.append(i)
sPRN.append(outlines[i][0:3])
outlinex.extend(rnx3rnx2_epo(outlines[0], sPRN))
for i in datline:
if outlines[i][0:1]=='G': idx=0
elif outlines[i][0:1]=='E': idx=1
elif outlines[i][0:1]=='R': idx=2
elif outlines[i][0:1]=='S': idx=3
else: continue
outlinex.extend(rnx3rnx2_dat(addemp[idx], addemp[4], outlines[i]))
return outlinex
# Convert Uni-format to RINEX 2.xx --------------------- #
def uni2rnx2_data(sysnum, outlines, out_path, headordata, add_emp):
# rinex message label
obspro='PGM / RUN BY / DATE'
obsobs='SYS / # / OBS TYPES'
obsend='END OF HEADER'
outlinex=[]
obsread=False
# convert Uni-format to RINEX 2.xx(header)
if headordata:
for i in range(len(outlines)):
if outlines[i].find(obspro)>=0: outlinex.append(datefmt3_conv(outlines[i]))
elif outlines[i].find(obsobs)>=0:
if not obsread:
obsread=True
addemp=obstype3_conv(i, sysnum, outlines, outlinex)
else: continue
elif outlines[i].find(obsend)>=0: outlinex.append(outlines[i])
else: outlinex.append(outlines[i])
# convert Uni-format to RINEX 2.xx(data)
elif not headordata:
outlinex=rnx3rnx2_data(outlines, add_emp)
# output to destination file
out_f=open(out_path, 'a')
out_f.writelines(outlinex)
out_f.close()
if headordata: return addemp
elif not headordata: return 0
# Convert data of RINEX 3.xx to Des-format ----------------- #
def rnx3des(in_path, out_path, oriver, desver):
headread=False
outlines=[]
in_f=open(in_path, 'r')
# get the amount of sat system
sysnum=getsys_rnx3(in_f)
# convert RINEX 3.xx(header) to Uni-format
match rnx3_head2uni(in_f, desver, outlines):
case 1: headread=True
case 0: headread=False
# convert Uni-foramt(header) to Des-format
if headread:
match desver[0:1]:
case '2': addemp=uni2rnx2_data(sysnum, outlines, out_path, True, None)
case '3': uni2rnx3_data(outlines, out_path)
outlines=[]
# convert RINEX 3.xx(data) to Uni-format
while rnx2uni3_data(outlines, in_f):
# convert Uni-foramt(data) to Des-format
match desver[0:1]:
case '2': uni2rnx2_data(sysnum, outlines, out_path, False, addemp)
case '3': uni2rnx3_data(outlines, out_path)
outlines=[]
elif not headread: return 0
return 1
# Reject data of invaild input ----------------------- # # Reject data of invaild input ----------------------- #
def rnx_reject(in_path, out_path, oriver): def rnx_reject(in_path, out_path, oriver):
@@ -393,8 +739,6 @@ def rnx_reject(in_path, out_path, oriver):
return 1 return 1
# --------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------
# CONVERT FUNCTION # CONVERT FUNCTION
# #
@@ -413,11 +757,10 @@ def Convert_Un(in_path, out_path, oriver, desver, resqueue):
if file_state: if file_state:
match oriver: match oriver:
case '2': rnx2des(in_path, out_path, oriver, desver) case '2': rnx2des(in_path, out_path, oriver, desver)
case '3': resqueue.put(0) case '3': rnx3des(in_path, out_path, oriver, desver)
else : resqueue.put(0) else : return resqueue.put(0)
resqueue.put(1) return resqueue.put(1)
return
# Multi-threading task --------------------------- # # Multi-threading task --------------------------- #
def _Convert_Un(in_path, out_path, oriver, desver, resqueue): def _Convert_Un(in_path, out_path, oriver, desver, resqueue):
@@ -427,129 +770,3 @@ def _Convert_Un(in_path, out_path, oriver, desver, resqueue):
T.start() T.start()
T.join() T.join()
return resqueue.get() return resqueue.get()
# --------------------------------------------------------------- #
# The functions below are not be useable. on progress............ #
#
#
# --------------------------------------------------------------- #
# Convert observ type of RINEX 3.xx to Uni-Format --------------- #
def obsfmt_conv_cxx(obstypes):
outlines=[]
outline='%6d'%len(obstypes)
for i in range(len(obstypes)):
outline+='%6s'%obstypes[i]
if (i+1)==len(obstypes):
outlines.append(outline + (9 - (i+1)%9)*6*bnk + '# / TYPES OF OBSERV\n')
outline=''
elif (i+1)%9==0:
outlines.append(outline + '# / TYPES OF OBSERV\n')
outline=6*bnk
return outlines
# Convert observ msg of RINEX 3.xx to Uni-Format ---------------- #
def obstype_conv_cxx(obstypes, inline, in_f):
while True:
if inline[0:1]=='G': flag=True
elif inline[0:1]=='E': flag=True
elif inline[0:1]=='R': flag=True
elif inline[0:1]=='S': flag=True
else: flag=False
if flag:
obsnum=int(inline[2:6])
for i in range(math.ceil(obsnum/13)):
for obs in inline[6:60].split():
if obs[1:2]=='3': continue
if obs[1:2]=='4': continue
if obs[2:3]=='P': obs='P'+obs[1:2]
else: obs=obs[0:2]
if obs and obs not in obstypes:
obstypes.append(obs)
if i+1==math.ceil(obsnum/13):
break
inline=in_f.readline()
return
# Convert head_data of RINEX 3.xx to Uni-format -------------- #
def rnx3_head2uni(in_path, out_path, desver):
try:
with open(in_path, 'r'): pass
except FileNotFoundError:
return -12
obstypes=[]
outlines=[]
in_put=False
output=False
in_f=open(in_path, 'r')
while True:
inline=in_f.readline()
if not inline:
return 0
if in_put and not output:
if not inline.find('SYS / # / OBS TYPES')>=0:
output=True
if in_put and output:
outlines.extend(obsfmt_conv_cxx(obstypes))
in_put=False
output=False
if inline.find('COMMENT')>=0:
outlines.append(inline)
elif inline.find('RINEX VERSION / TYPE')>=0:
if not inline.find('OBSERVATION DATA')>=0:
return -10
if not float(inline[5: 9])>=3:
return -10
# Output convert message
outlines.append(
5*bnk+'%s->%s'%(str(inline[5: 9]),str(desver))+
1*bnk+'COV-OBSERVATION DATA'+
24*bnk+'COV-RINEX VER / TYPE\n')
outlines.append(conv_time())
outlines.append(inline.replace(
'%s'%re.search(r'[1-9]\d*.\d*|0\.\d*[1-9]\d*', inline).group(),
desver))
elif inline.find('PGM / RUN BY / DATE')>=0:
outlines.append(datefmt3_conv(inline))
elif inline.find('SYS / # / OBS TYPES')>=0:
in_put=True
obstype_conv_cxx(obstypes, inline, in_f)
elif inline.find('SYS / PHASE SHIFT')>=0:
continue
elif inline.find('GLONASS COD/PHS/BIS')>=0:
continue
elif inline.find('GLONASS SLOT / FRQ #')>=0:
continue
elif inline.find("END OF HEADER")>=0:
outlines.append(inline)
break
else: outlines.append(inline)
try:
with open(out_path, 'w'): pass
except PermissionError:
return -11
out_f=open(out_path, 'a')
out_f.writelines(outlines)
out_f.close()
return 1
+18
View File
@@ -0,0 +1,18 @@
# @ File : rtcm_convert.py.py
#
# Copyright (c) 2024 - 2024 KenanZhu. All Right Reserved.
#
# @ Author : KenanZhu
# @ Time : 2024/11/16
# @ Brief :
# :
# @ IDE : PyCharm
#
# ----------------------------------------------------------------------------------------
# ---SELPORT--- #
# ---STDPORT--- #
# ------------- #
def Convert_Un():
return 0