From a9e20ad08b24c4ae0a9a55e087dd5a8fed535837 Mon Sep 17 00:00:00 2001 From: esea_info Date: Tue, 11 Apr 2023 20:49:24 +0800 Subject: [PATCH] first commit --- .vscode/settings.json | 91 ++ app.py | 33 + app.spec | 45 + calfile/Basis aq_B055.dat | 312 +++++ calfile/Reflectivity_B055.dat | 312 +++++ calfile/abs_pure_water.dat | 197 +++ config.yml | 27 + configuration.py | 32 + data/20210305/CALIBRAT.DAT | 2058 +++++++++++++++++++++++++++++++ data/output/B055.csv | 18 + dataplot.py | 466 +++++++ icon.ico | Bin 0 -> 1150 bytes listctrl.py | 32 + myconfig.py | 188 +++ myexception.py | 14 + mylogger.py | 285 +++++ mypanel.py | 141 +++ mypath.py | 277 +++++ mythread.py | 126 ++ mytime.py | 71 ++ oscar.py | 476 +++++++ readcal.py | 1020 +++++++++++++++ retrieve.yml | 3 + uart.py | 200 +++ uiconfig/ui_algorithm.py | 110 ++ uiconfig/ui_com_setting.py | 138 +++ uiconfig/ui_filepath_setting.py | 92 ++ uiconfig/ui_log_setting.py | 100 ++ uiconfig/ui_pathsn_setting.py | 100 ++ uiconfig/ui_plot_setting.py | 100 ++ uiconfig/uiabout.py | 60 + uiconfig/uihelp.py | 58 + uiconfig/uisensor.py | 124 ++ yiwinframe.py | 772 ++++++++++++ 34 files changed, 8078 insertions(+) create mode 100644 .vscode/settings.json create mode 100644 app.py create mode 100644 app.spec create mode 100644 calfile/Basis aq_B055.dat create mode 100644 calfile/Reflectivity_B055.dat create mode 100644 calfile/abs_pure_water.dat create mode 100644 config.yml create mode 100644 configuration.py create mode 100644 data/20210305/CALIBRAT.DAT create mode 100644 data/output/B055.csv create mode 100644 dataplot.py create mode 100644 icon.ico create mode 100644 listctrl.py create mode 100644 myconfig.py create mode 100644 myexception.py create mode 100644 mylogger.py create mode 100644 mypanel.py create mode 100644 mypath.py create mode 100644 mythread.py create mode 100644 mytime.py create mode 100644 oscar.py create mode 100644 readcal.py create mode 100644 retrieve.yml create mode 100644 uart.py create mode 100644 uiconfig/ui_algorithm.py create mode 100644 uiconfig/ui_com_setting.py create mode 100644 uiconfig/ui_filepath_setting.py create mode 100644 uiconfig/ui_log_setting.py create mode 100644 uiconfig/ui_pathsn_setting.py create mode 100644 uiconfig/ui_plot_setting.py create mode 100644 uiconfig/uiabout.py create mode 100644 uiconfig/uihelp.py create mode 100644 uiconfig/uisensor.py create mode 100644 yiwinframe.py diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..f7c5140 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,91 @@ +{ + // 控制字体大小(像素) + "editor.fontSize": 16, + // 在 #editor.wordWrap# 为 wordWrapColumn 或 bounded 时,控制编辑器的折行列。100 列后换行 + "editor.wordWrapColumn": 100, + // 控制tab键是空格还是制表符 true 空格 false制表符 + "editor.detectIndentation": false, + // tab 对应空格大小 + "editor.tabSize": 4, + // 在保存时格式化文件。 + "editor.formatOnSave": false, + // 开启 vscode 文件路径导航 + "breadcrumbs.enabled": true, + // prettier 是否在每行末尾添加分号 ,C_cpp有用 + "prettier.semi": false, + // prettier 设置强制单引号 + "prettier.singleQuote": true, + // 尽可能控制尾随逗号的输出。 有效选项: 'none' - 无尾随逗号 ' es5' - 在ES5中有效的尾随逗号(对象,数组等) 'all' - 尾随逗号 尽可能(函数参数) + "prettier.trailingComma": "none", + // 定义函数参数括号前的空格处理方式。 + "javascript.format.insertSpaceBeforeFunctionParenthesis": true, + // 鼠标滚轮缩放, ctrl+滚轮 + "editor.mouseWheelZoom": true, + "editor.defaultFormatter": "ms-python.vscode-pylance", + "files.encoding":"utf8", + + // 针对python文件将 tab改为4个空格 + "[python]": { + "editor.insertSpaces": true, + "editor.tabSize": 4 + }, + + + + // 代码格式化 astyle,需要安装astyle 程序-适用C c++ java + // "astyle.executable": "D:\\AStyle\\bin\\astyle.exe", //window + // "astyle.executable": "/usr/bin/astyle", // linux + // "astyle.additional_languages": [ + // "c", + // "cpp", + // "*.h", + // ], + // "astyle.cmd_options": [ + // // 预定义风格 ----------------------------------------------------------- + // // "--style=ansi", //ANSI 风格格式和缩进 + // // "--style=kr", //Kernighan&Ritchie 风格格式和缩进 + // "--style=linux", //Linux 风格格式和缩进 + // //"--style=gnu", //GNU 风格格式和缩进 + // // "--style=java", //Java 风格格式和缩进 + // "--indent=spaces=4", //缩进4个空格 + // "--indent-preproc-block", + // "--pad-oper", //操作符两端插入一个空格 + // "--pad-header", + // "--unpad-paren", + // "--suffix=none", + // "--align-pointer=name", + // "--lineend=linux", + // "--convert-tabs", //TAB转换为空格 + // "--verbose", + // // "--delete-empty-lines", //删除多余空行 + // //"--pad-paren-in", //括号内部加入空格 + // "--unpad-paren", //移除括号两端多余空格 + // ], + + // pylint --python风格 pylint程序 + // "python.linting.enabled": true, + // "python.linting.pylintEnabled": true, + // "python.linting.lintOnSave": true, + // "python.linting.pylintPath": "D:\\pylint\\bin\\pylint.exe", + // "python.linting.pylintArgs": [ + // "--rcfile={path}/.pylintrc", + // "--extension-pkg-whitelist=PyQt5", + // "--disable=invalid-name,missing-module-docstring", + // "--disable=W0612,W0631,W0703,W0621,W0613,W0611,W1308,C0411,C0111,C0103,C0301,C0304,C0305,E1101,R0913,R0914,R0915,R0903" , + // ], + + + // 执行的终端选择,可选 + "terminal.integrated.defaultProfile.windows" : "PowerShell", + // "terminal.integrated.defaultProfile.windows" : "Git Bash", + // "terminal.integrated.defaultProfile.windows" : "Windows PowerShell", + // "terminal.integrated.defaultProfile.windows": "Ubuntu-20.04 (WSL)", + + "python.defaultInterpreterPath": "python3", // python3 或 python + "code-runner.executorMap": { + "python":"python3 -u $fullFileName" + }, + + + +} \ No newline at end of file diff --git a/app.py b/app.py new file mode 100644 index 0000000..0e3919d --- /dev/null +++ b/app.py @@ -0,0 +1,33 @@ +#! python3 +# -*- encoding: utf-8 -*- +''' +@File : app.py +@Time : 2021/09/12 12:38:46 +@Author : Jim +@Version : 1.0 +@Desp : +''' + +# VERSION = "3.3.2" +# LASTDATE = "2021-09-20" + +import wx +from yiwinframe import YiwinFrame +from mylogger import log + +from myconfig import VERSION,LASTDATE,COMPANY + +class YiwinApp(wx.App): + + def OnInit(self): + self.myframe = YiwinFrame( u'奕枫水体吸收系数测量软件 v1.0', parent=None) + self.myframe.statusBar.SetStatusText( u" 版权所有 " + COMPANY + +" Version "+ VERSION + " "+ LASTDATE, 1 ) #给状态栏设文字 + self.myframe.Show(True) + return True + +if __name__ == "__main__": + log.info(f"******** Shanghai Yiwin Instrument@Equipment Company *********", __name__, "", "") + log.info(f"******** Viper attenuation Software .... *********", __name__, "", "") + app = YiwinApp( ) + app.MainLoop() diff --git a/app.spec b/app.spec new file mode 100644 index 0000000..eef0dc7 --- /dev/null +++ b/app.spec @@ -0,0 +1,45 @@ +# -*- mode: python ; coding: utf-8 -*- + + +block_cipher = None + + +a = Analysis( + ['app.py'], + pathex=[], + binaries=[], + datas=[], + hiddenimports=[], + hookspath=[], + hooksconfig={}, + runtime_hooks=[], + excludes=[], + win_no_prefer_redirects=False, + win_private_assemblies=False, + cipher=block_cipher, + noarchive=False, +) +pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) + +exe = EXE( + pyz, + a.scripts, + a.binaries, + a.zipfiles, + a.datas, + [], + name='app', + debug=False, + bootloader_ignore_signals=False, + strip=False, + upx=True, + upx_exclude=[], + runtime_tmpdir=None, + console=False, + disable_windowed_traceback=False, + argv_emulation=False, + target_arch=None, + codesign_identity=None, + entitlements_file=None, + icon='icon.ico', +) diff --git a/calfile/Basis aq_B055.dat b/calfile/Basis aq_B055.dat new file mode 100644 index 0000000..fac827c --- /dev/null +++ b/calfile/Basis aq_B055.dat @@ -0,0 +1,312 @@ +[Spectrum] +Version = 1 +IDData = OSCAR_B055_2020-12-04_13-57-29_Waterbase_041 +IDDevice = OSCAR_B055 +IDDataType = SPECTRUM +IDDataTypeSub1 = CALIBRATED +IDDataTypeSub2 = BASIS +IDDataTypeSub3 = +DateTime = 2020-12-04 13:57:29 +PositionLatitude = 0 +PositionLongitude = 0 +Comment = Basis aq_B055 +CommentSub1 = +CommentSub2 = +CommentSub3 = +IDMethodType = +MethodName = +Mission = 1 ; 12.7888 ; ; +MissionSub = 0 +RecordType = 1 +[Attributes] +Averaging = 10 +CalFactor = 0 +Deviation = 12.7888 +FlashCount = 1 +IDBasisSpec = +IDDataBack = +IDDataCal = +IntegrationTime = 512 +Maximum = 14.0468 +P31 = 0 +P31e = 0 +PathLength = 10 +PathLengthCustomOn = 0 +RAWDynamic = 65535 +Salinity = 0 +SpectrumType = Waterbase +Temperature = 21.6 +Unit1 = $01 $01 Wavelength nm +Unit2 = $03 $05 Intensity counts +Unit3 = $f0 $05 Error counts +Unit4 = $f1 $00 Status +lampLEDs = 255 +lampReference[0] = 0 +lampReference[1] = 0 +p999 = 0 +tempLampModule = 24.9625 +tempMainCPU = 28.125 +tempRefDiode = 0 +tempSpectrometer = 27.3531 +[END] of [Attributes] +[DATA] + 0 8 0 0 + 304.594 0.0210566 0 0 + 307.975 0.0231822 0 0 + 311.356 0.0252777 0 0 + 314.738 0.0283652 0 0 + 318.12 0.0320467 0 0 + 321.503 0.036545 0 0 + 324.887 0.0395432 0 0 + 328.27 0.0447027 0 0 + 331.655 0.0490757 0 0 + 335.04 0.0535368 0 0 + 338.425 0.0582091 0 0 + 341.811 0.0632415 0 0 + 345.197 0.0693582 0 0 + 348.584 0.0762549 0 0 + 351.971 0.0862348 0 0 + 355.359 0.105558 0 0 + 358.746 0.166794 0 0 + 362.135 0.444266 0 0 + 365.523 1.61241 0 0 + 368.912 4.71591 0 0 + 372.302 8.63911 0 0 + 375.692 9.90672 0 0 + 379.082 7.6983 0 0 + 382.472 4.68655 0 0 + 385.863 2.8009 0 0 + 389.254 2.16211 0 0 + 392.645 2.63598 0 0 + 396.037 4.19367 0 0 + 399.429 6.57256 0 0 + 402.821 8.72203 0 0 + 406.213 9.42163 0 0 + 409.606 8.55542 0 0 + 412.999 6.94181 0 0 + 416.392 5.29259 0 0 + 419.785 3.98554 0 0 + 423.179 3.17615 0 0 + 426.572 2.87384 0 0 + 429.966 3.06099 0 0 + 433.36 3.76249 0 0 + 436.754 5.08917 0 0 + 440.149 7.18661 0 0 + 443.543 9.91796 0 0 + 446.938 12.517 0 0 + 450.332 14.0135 0 0 + 453.727 14.0468 0 0 + 457.122 13.0209 0 0 + 460.517 11.4783 0 0 + 463.912 9.72502 0 0 + 467.307 8.00122 0 0 + 470.702 6.54226 0 0 + 474.097 5.40552 0 0 + 477.492 4.52299 0 0 + 480.887 3.83399 0 0 + 484.282 3.31924 0 0 + 487.678 2.98197 0 0 + 491.073 2.8091 0 0 + 494.468 2.779 0 0 + 497.863 2.86794 0 0 + 501.258 3.05796 0 0 + 504.653 3.32977 0 0 + 508.048 3.65804 0 0 + 511.442 4.03031 0 0 + 514.837 4.43456 0 0 + 518.232 4.86578 0 0 + 521.626 5.3154 0 0 + 525.021 5.76721 0 0 + 528.415 6.21011 0 0 + 531.809 6.64985 0 0 + 535.203 7.0616 0 0 + 538.596 7.4466 0 0 + 541.99 7.79216 0 0 + 545.383 8.07482 0 0 + 548.776 8.28954 0 0 + 552.169 8.43504 0 0 + 555.562 8.51663 0 0 + 558.954 8.53201 0 0 + 562.347 8.49503 0 0 + 565.739 8.39947 0 0 + 569.13 8.26454 0 0 + 572.522 8.0873 0 0 + 575.913 7.85227 0 0 + 579.304 7.56516 0 0 + 582.694 7.21857 0 0 + 586.084 6.8161 0 0 + 589.474 6.35792 0 0 + 592.864 5.8454 0 0 + 596.253 5.31237 0 0 + 599.642 4.84331 0 0 + 603.03 4.47609 0 0 + 606.418 4.18657 0 0 + 609.806 3.9524 0 0 + 613.193 3.7444 0 0 + 616.58 3.55138 0 0 + 619.966 3.37612 0 0 + 623.352 3.21094 0 0 + 626.737 3.05199 0 0 + 630.122 2.89697 0 0 + 633.507 2.73312 0 0 + 636.891 2.556 0 0 + 640.274 2.36686 0 0 + 643.658 2.17118 0 0 + 647.04 1.97787 0 0 + 650.422 1.79679 0 0 + 653.804 1.62428 0 0 + 657.184 1.46539 0 0 + 660.565 1.31924 0 0 + 663.945 1.18516 0 0 + 667.324 1.06363 0 0 + 670.702 0.959542 0 0 + 674.08 0.871582 0 0 + 677.458 0.793595 0 0 + 680.835 0.722821 0 0 + 684.211 0.6558 0 0 + 687.586 0.592462 0 0 + 690.961 0.531973 0 0 + 694.335 0.474165 0 0 + 697.709 0.419892 0 0 + 701.082 0.370012 0 0 + 704.454 0.324413 0 0 + 707.825 0.282091 0 0 + 711.196 0.243811 0 0 + 714.566 0.208403 0 0 + 717.935 0.176369 0 0 + 721.303 0.147406 0 0 + 724.671 0.12289 0 0 + 728.038 0.101408 0 0 + 731.404 0.0822255 0 0 + 734.769 0.0672734 0 0 + 738.134 0.0567692 0 0 + 741.497 0.0499812 0 0 + 744.86 0.0444286 0 0 + 748.222 0.0406367 0 0 + 751.583 0.0364964 0 0 + 754.944 0.0336154 0 0 + 758.303 0.0301431 0 0 + 761.662 0.0275487 0 0 + 765.019 0.0251491 0 0 + 768.376 0.0236934 0 0 + 771.732 0.0215465 0 0 + 775.087 0.0189808 0 0 + 778.441 0.0179091 0 0 + 781.794 0.0161808 0 0 + 785.146 0.0156396 0 0 + 788.497 0.0140658 0 0 + 791.847 0.0138507 0 0 + 795.196 0.0120979 0 0 + 798.544 0.0113958 0 0 + 801.891 0.0110699 0 0 + 805.237 0.00978003 0 0 + 808.583 0.00946944 0 0 + 811.927 0.00800721 0 0 + 815.269 0.00719762 0 0 + 818.611 0.00572726 0 0 + 821.952 0.00526265 0 0 + 825.292 0.00452969 0 0 + 828.63 0.00450948 0 0 + 831.968 0.00366555 0 0 + 835.304 0.00317755 0 0 + 838.64 0.00343594 0 0 + 841.974 0.00266997 0 0 + 845.307 0.00234687 0 0 + 848.639 0.00265867 0 0 + 851.969 0.00243576 0 0 + 855.299 0.00205385 0 0 + 858.627 0.00109726 0 0 + 861.954 0.00183287 0 0 + 865.28 0.000746415 0 0 + 868.604 0.00160104 0 0 + 871.927 0.00210132 0 0 + 875.25 0.00212947 0 0 + 878.57 0.00113513 0 0 + 881.89 0.000910693 0 0 + 885.208 0.00181068 0 0 + 888.525 0.00173474 0 0 + 891.841 0.00156189 0 0 + 895.155 0.00140958 0 0 + 898.468 0.00175973 0 0 + 901.78 0.00190556 0 0 + 905.09 0.00130031 0 0 + 908.399 0.00206208 0 0 + 911.707 0.00175176 0 0 + 915.013 0.00268119 0 0 + 918.318 0.00133652 0 0 + 921.621 0.00235074 0 0 + 924.923 0.00213741 0 0 + 928.224 0.00193116 0 0 + 931.523 0.00167193 0 0 + 934.821 0.00313712 0 0 + 938.117 0.00399409 0 0 + 941.412 0.00236253 0 0 + 944.705 0.00798147 0 0 + 947.997 0.00834754 0 0 + 951.287 0.00336406 0 0 + 954.576 0.0129665 0 0 + 957.864 0.00995627 0 0 + 961.149 0.0113662 0 0 + 964.434 0.00182761 0 0 + 967.716 0.0479155 0 0 + 970.998 -0.0120681 0 0 + 974.277 0.0521257 0 0 + 977.555 -0.00392658 0 0 + 980.831 -0.00331801 0 0 + 984.106 -0.00542654 0 0 + 987.379 -0.000761557 0 0 + 990.651 -0.000917581 0 0 + 993.921 -0.000709999 0 0 + 997.189 -0.000316759 0 0 + 1000.46 -0.000508475 0 0 + 1003.72 -0.000456869 0 0 + 1006.98 -0.000226175 0 0 + 1010.25 -0.000160049 0 0 + 1013.5 -1.5969e-05 0 0 + 1016.76 -1.957e-05 0 0 + 1020.02 3.26416e-06 0 0 + 1023.27 3.09945e-05 0 0 + 1026.53 0.000103156 0 0 + 1029.78 -3.10342e-05 0 0 + 1033.03 -1.69953e-05 0 0 + 1036.28 -0.000127137 0 0 + 1039.52 -6.73423e-05 0 0 + 1042.77 1.57546e-05 0 0 + 1046.01 0.000185623 0 0 + 1049.25 0.000144434 0 0 + 1052.49 -0.00018054 0 0 + 1055.72 3.17146e-05 0 0 + 1058.96 -5.29127e-05 0 0 + 1062.19 -0.000215598 0 0 + 1065.42 0.000147456 0 0 + 1068.65 -4.9335e-06 0 0 + 1071.88 -0.000128095 0 0 + 1075.1 -0.000125368 0 0 + 1078.33 7.34804e-05 0 0 + 1081.55 -6.86384e-05 0 0 + 1084.77 -0.000124123 0 0 + 1087.99 -8.19662e-05 0 0 + 1091.2 0.000177756 0 0 + 1094.42 -5.58525e-06 0 0 + 1097.63 -5.95557e-05 0 0 + 1100.84 -0.000182336 0 0 + 1104.04 -0.000262782 0 0 + 1107.25 0.000259209 0 0 + 1110.45 -0.000167749 0 0 + 1113.66 -0.000399004 0 0 + 1116.86 -0.000423914 0 0 + 1120.05 2.15958e-05 0 0 + 1123.25 0.000275597 0 0 + 1126.44 0.000273604 0 0 + 1129.63 0.000316467 0 0 + 1132.82 -0.000118352 0 0 + 1136.01 -8.5051e-05 0 0 + 1139.19 -0.000267692 0 0 + 1142.38 0.000135329 0 0 + 1145.56 -1.74812e-05 0 0 + 1148.74 0.000689914 0 0 + 1151.91 0.00185774 0 0 +[END] of [DATA] +[END] of Spectrum + + diff --git a/calfile/Reflectivity_B055.dat b/calfile/Reflectivity_B055.dat new file mode 100644 index 0000000..7e63a01 --- /dev/null +++ b/calfile/Reflectivity_B055.dat @@ -0,0 +1,312 @@ +[Spectrum] +Version = 1 +IDData = ALAB_2020-12-04_17-11-55_757_061 +IDDevice = OSCAR_B055 +IDDataType = SPECTRUM +IDDataTypeSub1 = Reflectivity +IDDataTypeSub2 = +IDDataTypeSub3 = +DateTime = 2020-12-04 17:11:55 +PositionLatitude = 0 +PositionLongitude = 0 +Comment = Reflectivity B055 +CommentSub1 = Referenz Lamda850_100mmK +CommentSub2 = WL-Bereich 360-750 nm +CommentSub3 = +IDMethodType = Oscar Control +MethodName = OSCAR_B055 +Mission = 1 ; 9.75544 ; ; +MissionSub = 0 +RecordType = 0 +[Attributes] +Averaging = 10 +CalFactor = 0 +Deviation = 9.75544 +FlashCount = 1 +IDBasisSpec = +IDDataBack = +IDDataCal = +IntegrationTime = 2048 +Maximum = 3.21223 +P31 = 0 +P31e = 0 +PathLength = 100 +PathLengthCustomOn = 0 +RAWDynamic = 65535 +Salinity = 0 +SpectrumType = Nigrosin +Temperature = 20.7 +Unit1 = $01 $01 Wavelength nm +Unit2 = $0d $08 Reflectivity 1 +Unit3 = $0d $08 Reflectivity 1 +Unit4 = $f1 $00 Status +lampLEDs = 255 +lampReference[0] = 0 +lampReference[1] = 0 +p999 = 0 +tempLampModule = 27.3125 +tempMainCPU = 30.4312 +tempRefDiode = 0 +tempSpectrometer = 29.7562 +[END] of [Attributes] +[DATA] + 0 10 0 0 + 304.594 -NAN 0 0 + 307.975 -NAN 0 0 + 311.356 -NAN 0 0 + 314.738 -NAN 0 0 + 318.12 -NAN 0 0 + 321.503 -NAN 0 0 + 324.887 -NAN 0 0 + 328.27 -NAN 0 0 + 331.655 -NAN 0 0 + 335.04 -NAN 0 0 + 338.425 -NAN 0 0 + 341.811 -NAN 0 0 + 345.197 -NAN 0 0 + 348.584 -NAN 0 0 + 351.971 -NAN 0 0 + 355.359 -NAN 0 0 + 358.746 -NAN 0 0 + 362.135 0.978428499401649 0 0 + 365.523 0.978965953688747 0 0 + 368.912 0.97929591821286 0 0 + 372.302 0.979465872969741 0 0 + 375.692 0.979531290603612 0 0 + 379.082 0.979319242805614 0 0 + 382.472 0.979305911503146 0 0 + 385.863 0.979221413496553 0 0 + 389.254 0.979197496540882 0 0 + 392.645 0.979323668830666 0 0 + 396.037 0.979331245986962 0 0 + 399.429 0.979287619477527 0 0 + 402.821 0.979119533409878 0 0 + 406.213 0.978973859065406 0 0 + 409.606 0.978790753060641 0 0 + 412.999 0.978551720462383 0 0 + 416.392 0.978456786967265 0 0 + 419.785 0.978354214857909 0 0 + 423.179 0.978314542339825 0 0 + 426.572 0.978245299398871 0 0 + 429.966 0.978166588669129 0 0 + 433.36 0.977966897521694 0 0 + 436.754 0.977884151118849 0 0 + 440.149 0.977693826499285 0 0 + 443.543 0.977596798279483 0 0 + 446.938 0.977382806578674 0 0 + 450.332 0.977151968740062 0 0 + 453.727 0.976927976192701 0 0 + 457.122 0.976675617101858 0 0 + 460.517 0.976526056087864 0 0 + 463.912 0.976279834695182 0 0 + 467.307 0.976158213212832 0 0 + 470.702 0.975968223809452 0 0 + 474.097 0.975864381832555 0 0 + 477.492 0.97564814733514 0 0 + 480.887 0.975422871055887 0 0 + 484.282 0.975378267554234 0 0 + 487.678 0.97518550259529 0 0 + 491.073 0.975122332762432 0 0 + 494.468 0.974938884041278 0 0 + 497.863 0.974916392305076 0 0 + 501.258 0.974752516633885 0 0 + 504.653 0.974569311326216 0 0 + 508.048 0.974550022680223 0 0 + 511.442 0.974370672460727 0 0 + 514.837 0.974302747865652 0 0 + 518.232 0.974099614706827 0 0 + 521.626 0.973922361261296 0 0 + 525.021 0.973762054489896 0 0 + 528.415 0.973484174796049 0 0 + 531.809 0.973367498606616 0 0 + 535.203 0.973039382374481 0 0 + 538.596 0.972943285074893 0 0 + 541.99 0.972711445811679 0 0 + 545.383 0.972537887684075 0 0 + 548.776 0.972412371662826 0 0 + 552.169 0.972301685378471 0 0 + 555.562 0.972123819682298 0 0 + 558.954 0.971885560850787 0 0 + 562.347 0.971717847597481 0 0 + 565.739 0.971550854437924 0 0 + 569.13 0.971328384620963 0 0 + 572.522 0.971197927540782 0 0 + 575.913 0.971011504601151 0 0 + 579.304 0.970807629136665 0 0 + 582.694 0.9708116570687 0 0 + 586.084 0.97066512772835 0 0 + 589.474 0.970838032007098 0 0 + 592.864 0.970842236916884 0 0 + 596.253 0.970940116701782 0 0 + 599.642 0.97084709835456 0 0 + 603.03 0.970753920057021 0 0 + 606.418 0.970654749248275 0 0 + 609.806 0.970326360121843 0 0 + 613.193 0.970256797566305 0 0 + 616.58 0.970026140408362 0 0 + 619.966 0.969923302576538 0 0 + 623.352 0.969772124401762 0 0 + 626.737 0.969571939958024 0 0 + 630.122 0.969399888366939 0 0 + 633.507 0.969078647824134 0 0 + 636.891 0.968921269439267 0 0 + 640.274 0.968677827062214 0 0 + 643.658 0.968679533496021 0 0 + 647.04 0.968509398556534 0 0 + 650.422 0.968563862841168 0 0 + 653.804 0.968438132514117 0 0 + 657.184 0.968184350493791 0 0 + 660.565 0.967865577127992 0 0 + 663.945 0.967486924999228 0 0 + 667.324 0.967488176527944 0 0 + 670.702 0.966979931069267 0 0 + 674.08 0.966744441155398 0 0 + 677.458 0.966607254162634 0 0 + 680.835 0.966542448319853 0 0 + 684.211 0.966509544212223 0 0 + 687.586 0.966418626742675 0 0 + 690.961 0.966579055749823 0 0 + 694.335 0.966860555377936 0 0 + 697.709 0.966943564328317 0 0 + 701.082 0.96724436824475 0 0 + 704.454 0.967896682193911 0 0 + 707.825 0.968250713384282 0 0 + 711.196 0.969339433411549 0 0 + 714.566 0.971069610849988 0 0 + 717.935 0.972660542809938 0 0 + 721.303 0.973427173090292 0 0 + 724.671 0.977484950025803 0 0 + 728.038 0.982323543105391 0 0 + 731.404 0.989647380222074 0 0 + 734.769 0.997665689658877 0 0 + 738.134 1.00352514426919 0 0 + 741.497 1.01139618545043 0 0 + 744.86 1.01267967530863 0 0 + 748.222 1.02058869844595 0 0 + 751.583 -NAN 0 0 + 754.944 -NAN 0 0 + 758.303 -NAN 0 0 + 761.662 -NAN 0 0 + 765.019 -NAN 0 0 + 768.376 -NAN 0 0 + 771.732 -NAN 0 0 + 775.087 -NAN 0 0 + 778.441 -NAN 0 0 + 781.794 -NAN 0 0 + 785.146 -NAN 0 0 + 788.497 -NAN 0 0 + 791.847 -NAN 0 0 + 795.196 -NAN 0 0 + 798.544 -NAN 0 0 + 801.891 -NAN 0 0 + 805.237 -NAN 0 0 + 808.583 -NAN 0 0 + 811.927 -NAN 0 0 + 815.269 -NAN 0 0 + 818.611 -NAN 0 0 + 821.952 -NAN 0 0 + 825.292 -NAN 0 0 + 828.63 -NAN 0 0 + 831.968 -NAN 0 0 + 835.304 -NAN 0 0 + 838.64 -NAN 0 0 + 841.974 -NAN 0 0 + 845.307 -NAN 0 0 + 848.639 -NAN 0 0 + 851.969 -NAN 0 0 + 855.299 -NAN 0 0 + 858.627 -NAN 0 0 + 861.954 -NAN 0 0 + 865.28 -NAN 0 0 + 868.604 -NAN 0 0 + 871.927 -NAN 0 0 + 875.25 -NAN 0 0 + 878.57 -NAN 0 0 + 881.89 -NAN 0 0 + 885.208 -NAN 0 0 + 888.525 -NAN 0 0 + 891.841 -NAN 0 0 + 895.155 -NAN 0 0 + 898.468 -NAN 0 0 + 901.78 -NAN 0 0 + 905.09 -NAN 0 0 + 908.399 -NAN 0 0 + 911.707 -NAN 0 0 + 915.013 -NAN 0 0 + 918.318 -NAN 0 0 + 921.621 -NAN 0 0 + 924.923 -NAN 0 0 + 928.224 -NAN 0 0 + 931.523 -NAN 0 0 + 934.821 -NAN 0 0 + 938.117 -NAN 0 0 + 941.412 -NAN 0 0 + 944.705 -NAN 0 0 + 947.997 -NAN 0 0 + 951.287 -NAN 0 0 + 954.576 -NAN 0 0 + 957.864 -NAN 0 0 + 961.149 -NAN 0 0 + 964.434 -NAN 0 0 + 967.716 -NAN 0 0 + 970.998 -NAN 0 0 + 974.277 -NAN 0 0 + 977.555 -NAN 0 0 + 980.831 -NAN 0 0 + 984.106 -NAN 0 0 + 987.379 -NAN 0 0 + 990.651 -NAN 0 0 + 993.921 -NAN 0 0 + 997.189 -NAN 0 0 + 1000.46 -NAN 0 0 + 1003.72 -NAN 0 0 + 1006.98 -NAN 0 0 + 1010.25 -NAN 0 0 + 1013.5 -NAN 0 0 + 1016.76 -NAN 0 0 + 1020.02 -NAN 0 0 + 1023.27 -NAN 0 0 + 1026.53 -NAN 0 0 + 1029.78 -NAN 0 0 + 1033.03 -NAN 0 0 + 1036.28 -NAN 0 0 + 1039.52 -NAN 0 0 + 1042.77 -NAN 0 0 + 1046.01 -NAN 0 0 + 1049.25 -NAN 0 0 + 1052.49 -NAN 0 0 + 1055.72 -NAN 0 0 + 1058.96 -NAN 0 0 + 1062.19 -NAN 0 0 + 1065.42 -NAN 0 0 + 1068.65 -NAN 0 0 + 1071.88 -NAN 0 0 + 1075.1 -NAN 0 0 + 1078.33 -NAN 0 0 + 1081.55 -NAN 0 0 + 1084.77 -NAN 0 0 + 1087.99 -NAN 0 0 + 1091.2 -NAN 0 0 + 1094.42 -NAN 0 0 + 1097.63 -NAN 0 0 + 1100.84 -NAN 0 0 + 1104.04 -NAN 0 0 + 1107.25 -NAN 0 0 + 1110.45 -NAN 0 0 + 1113.66 -NAN 0 0 + 1116.86 -NAN 0 0 + 1120.05 -NAN 0 0 + 1123.25 -NAN 0 0 + 1126.44 -NAN 0 0 + 1129.63 -NAN 0 0 + 1132.82 -NAN 0 0 + 1136.01 -NAN 0 0 + 1139.19 -NAN 0 0 + 1142.38 -NAN 0 0 + 1145.56 -NAN 0 0 + 1148.74 -NAN 0 0 + 1151.91 -NAN 0 0 +[END] of [DATA] +[END] of Spectrum + + diff --git a/calfile/abs_pure_water.dat b/calfile/abs_pure_water.dat new file mode 100644 index 0000000..f00da4a --- /dev/null +++ b/calfile/abs_pure_water.dat @@ -0,0 +1,197 @@ +[Spectrum] +Version = 1 +IDData = absorption coefficients of pure water +IDDevice = OSCAR_B047 +IDDataType = SPECTRUM +IDDataTypeSub1 = CALIBRATED +IDDataTypeSub2 = pure water +IDDataTypeSub3 = Average of 10 +DateTime = 2017-12-11 12:00:07 +PositionLatitude = 0 +PositionLongitude = 0 +Comment = pure water +CommentSub1 = +CommentSub2 = +CommentSub3 = +IDMethodType = SingleSpecCalc +MethodName = SingleSpecCalc +Mission = 1 ; 9.67752 ; ; +MissionSub = 0 +RecordType = 1 +[Attributes] +Averaging = 1 +CalFactor = 0 +Deviation = 9.67752 +FlashCount = 1 +IDBasisSpec = +IDDataBack = +IDDataCal = +IntegrationTime = 1024 +Maximum = 4.5334 +P31 = 0 +P31e = 0 +PathLength = 1000 +PathLengthCustomOn = 0 +RAWDynamic = 65535 +Salinity = 0 +SpectrumType = Calibrated +Temperature = 20 +Unit1 = $01 $01 Wavelength nm +Unit2 = $03 $00 Intensity +Unit3 = $f0 $00 Error +Unit4 = $f1 $00 Status +lampLEDs = 255 +lampReference[0] = 0 +lampReference[1] = 0 +p999 = 0 +tempLampModule = 28.25 +tempMainCPU = 31.375 +tempRefDiode = 0 +tempSpectrometer = 30.5625 +[END] of [Attributes] +[DATA] + 0 9 0 0 +360 0.0066 0.0007 0 +365 0.0063 0.0007 0 +370 0.0060 0.0007 0 +375 0.0056 0.0007 1 +380 0.0052 0.0007 0 +385 0.0050 0.0007 0 +390 0.0048 0.0007 0 +395 0.0047 0.0007 0 +400 0.0046 0.0007 0 +405 0.0046 0.0007 0 +410 0.0046 0.0007 0 +415 0.0046 0.0006 0 +420.0 0.00454 0.0006 14 +422.5 0.00474 0.0006 13 +425.0 0.00478 0.0006 14 +427.5 0.00482 0.0006 13 +430.0 0.00495 0.0006 12 +432.5 0.00504 0.0005 11 +435.0 0.00530 0.0005 11 +437.5 0.00580 0.0005 10 +440.0 0.00635 0.0005 9 +442.5 0.00696 0.0005 9 +445.0 0.00751 0.0006 8 +447.5 0.00830 0.0005 7 +450.0 0.00922 0.0005 6 +452.5 0.00969 0.0004 6 +455.0 0.00962 0.0004 5 +457.5 0.00957 0.0004 5 +460.0 0.00979 0.0005 6 +462.5 0.01005 0.0005 6 +465.0 0.01011 0.0006 7 +467.5 0.0102 0.0006 6 +470.0 0.0106 0.0005 6 +472.5 0.0109 0.0008 8 +475.0 0.0114 0.0007 7 +477.5 0.0121 0.0008 8 +480.0 0.0127 0.0008 7 +482.5 0.0131 0.0008 7 +485.0 0.0136 0.0007 6 +487.5 0.0144 0.0007 6 +490.0 0.0150 0.0007 5 +492.5 0.0162 0.0014 9 +495.0 0.0173 0.0010 6 +497.5 0.0191 0.0014 8 +500.0 0.0204 0.0011 6 +502.5 0.0228 0.0012 6 +505.0 0.0256 0.0013 6 +507.5 0.0280 0.0010 5 +510.0 0.0325 0.0011 4 +512.5 0.0372 0.0012 4 +515.0 0.0396 0.0012 4 +517.5 0.0399 0.0015 5 +520.0 0.0409 0.0009 3 +522.5 0.0416 0.0014 4 +525.0 0.0417 0.0010 4 +527.5 0.0428 0.0017 5 +530.0 0.0434 0.0011 4 +532.5 0.0447 0.0017 5 +535.0 0.0452 0.0012 4 +537.5 0.0466 0.0015 4 +540.0 0.0474 0.0010 3 +542.5 0.0489 0.0016 4 +545.0 0.0511 0.0011 3 +547.5 0.0537 0.0016 4 +550.0 0.0565 0.0011 3 +552.5 0.0593 0.0012 3 +555.0 0.0596 0.0012 3 +557.5 0.0606 0.0014 4 +560.0 0.0619 0.0010 3 +562.5 0.0640 0.0015 4 +565.0 0.0642 0.0009 3 +567.5 0.0672 0.0014 3 +570.0 0.0695 0.0011 3 +572.5 0.0733 0.0017 4 +575.0 0.0772 0.0011 3 +577.5 0.0836 0.0016 3 +580.0 0.0896 0.0012 3 +582.5 0.0989 0.0016 3 +585.0 0.1100 0.0012 3 +587.5 0.1220 0.0018 3 +590.0 0.1351 0.0012 3 +592.5 0.1516 0.0017 3 +595.0 0.1672 0.0014 3 +597.5 0.1925 0.0019 3 +600.0 0.2224 0.0017 3 +602.5 0.2470 0.0023 3 +605.0 0.2577 0.0019 3 +607.5 0.2629 0.0028 3 +610.0 0.2644 0.0019 3 +612.5 0.2665 0.0023 3 +615.0 0.2678 0.0019 3 +617.5 0.2707 0.0026 3 +620.0 0.2755 0.0025 3 +622.5 0.2810 0.0039 3 +625.0 0.2834 0.0028 3 +627.5 0.2904 0.0039 3 +630.0 0.2916 0.0027 3 +632.5 0.2995 0.0038 3 +635.0 0.3012 0.0028 3 +637.5 0.3077 0.0049 3 +640.0 0.3108 0.0028 3 +642.5 0.322 0.005 3 +645.0 0.325 0.003 3 +647.5 0.335 0.004 3 +650.0 0.340 0.003 3 +652.5 0.358 0.006 3 +655.0 0.371 0.003 3 +657.5 0.393 0.006 3 +660.0 0.410 0.004 3 +662.5 0.424 0.005 3 +665.0 0.429 0.004 3 +667.5 0.436 0.005 3 +670.0 0.439 0.004 3 +672.5 0.448 0.007 3 +675.0 0.448 0.004 3 +677.5 0.461 0.006 3 +680.0 0.465 0.004 3 +682.5 0.478 0.006 3 +685.0 0.486 0.004 3 +687.5 0.502 0.006 3 +690.0 0.516 0.004 3 +692.5 0.538 0.007 3 +695.0 0.559 0.005 3 +697.5 0.592 0.008 3 +700.0 0.624 0.006 3 +702.5 0.663 0.008 3 +705.0 0.704 0.006 3 +707.5 0.756 0.009 3 +710.0 0.827 0.007 3 +712.5 0.914 0.011 3 +715.0 1.007 0.009 3 +717.5 1.119 0.014 3 +720.0 1.231 0.011 3 +722.5 1.356 0.008 3 +725.0 1.489 0.006 3 +727.5 1.678 0.007 3 +730 1.97 0.05 1 +735 2.51 0.04 1 +740 2.78 0.04 1 +745 2.83 0.04 1 +750 2.85 0.04 1 +[END] of [DATA] +[END] of Spectrum + diff --git a/config.yml b/config.yml new file mode 100644 index 0000000..d7fa56c --- /dev/null +++ b/config.yml @@ -0,0 +1,27 @@ +algorithm: + 'A720': 0 + 'PureWater': 0 + 'PureWater2': 0 +comsetting: + baudrate: 9600 + bytesize: 8 + parity: N + port: COM1 + stopbit: 1 +device: + UIPath: 150 + UISN: B055 +logsetting: + LogInterval: 1 + RefreshInterval: 0 +plotsetting: + LineBegin: 0 + LineInterval: 1 +register: + DataBeginAddress: 2614 + SNAddress: 2840 + SNLen: 5 + WLBeginAddress: 2102 + count: 2 + functioncode: 3 + slaveaddress: 1 diff --git a/configuration.py b/configuration.py new file mode 100644 index 0000000..fe19a58 --- /dev/null +++ b/configuration.py @@ -0,0 +1,32 @@ +from pathlib import Path, PurePath + +from mylogger import log +from readcal import ReadCal + +from myconfig import CAL_DIR, DATA_DIR, FILE_MARK, DeviceType + + +class Configuration: + def __init__(self, ) -> None: + log.info(f"Viper Configure init: ", __name__, "", "") + self.device_type = None + self.configuration =None + pass + + def setSystemCfgDict(self, cfg:dict) -> None: + self.configuration = cfg + log.info(f"self.configuration : {self.configuration} ", __name__, "", "") + pass + + def get_wl_from_datafile(self, fpath) -> None: + # self.cfgtool = Config() + if fpath.exists( ): + res = ReadCal.read_columns_set_by_mark( fpath, FILE_MARK, 1 ) + self.configuration.update({ "wavelength" : res[1][0] }) + pass + + def getCalConfiguration(self) -> None: + pass + + + diff --git a/data/20210305/CALIBRAT.DAT b/data/20210305/CALIBRAT.DAT new file mode 100644 index 0000000..e4ba0a3 --- /dev/null +++ b/data/20210305/CALIBRAT.DAT @@ -0,0 +1,2058 @@ +[Spectrum] +Version = 1 +IDData = OSCAR_B055_2020-01-01_11-51-00_Calibrated_906 +IDDevice = OSCAR_B055 +DateTime = 2020-01-01 11:51:00 +Comment = +CommentSub1 = +CommentSub2 = +CommentSub3 = +IDDataType = SPECTRUM +IDDataTypeSub1 = CALIBRATED +IDDataTypeSub2 = SAMPLE +Mission = 1 ; 13.6219 ; ; +[Attributes] +SpectrumType = Calibrated +Averaging = 1 +CalFactor = 0 +FlashCount = 1 +IntegrationTime = 512 +PathLength = 10 +Temperature = 20.7 +Salinity = 0 +lampLEDs = 255 +tempLampModule = 24.6875 +tempSpectrometer = 27 +tempMainCPU = 28.0312 +Deviation = 13.6219 +Maximum = 12.2999 +RAWDynamic = 65535 +Unit1 = $01 $01 Wavelength nm +Unit2 = $03 $00 Intensity +Unit3 = $f0 $00 Error +Unit4 = $f1 $00 Status +[END] of [Attributes] +[DATA] +0 8 0 0 +304.594 0.0178777 0 0 +307.975 0.0188183 0 0 +311.356 0.0236212 0 0 +314.738 0.0235589 0 0 +318.12 0.0287985 0 0 +321.503 0.0330877 0 0 +324.887 0.0350317 0 0 +328.27 0.0390082 0 0 +331.655 0.0452254 0 0 +335.04 0.0461902 0 0 +338.425 0.0499316 0 0 +341.811 0.056378 0 0 +345.197 0.0601086 0 0 +348.584 0.0653053 0 0 +351.971 0.0747377 0 0 +355.359 0.091424 0 0 +358.746 0.144001 0 0 +362.135 0.36774 0 0 +365.523 1.30934 0 0 +368.912 3.85424 0 0 +372.302 7.15963 0 0 +375.692 8.3188 0 0 +379.082 6.54306 0 0 +382.472 4.01743 0 0 +385.863 2.40929 0 0 +389.254 1.84567 0 0 +392.645 2.21673 0 0 +396.037 3.50517 0 0 +399.429 5.50701 0 0 +402.821 7.36075 0 0 +406.213 8.02104 0 0 +409.606 7.34664 0 0 +412.999 6.00774 0 0 +416.392 4.60564 0 0 +419.785 3.47851 0 0 +423.179 2.76752 0 0 +426.572 2.48927 0 0 +429.966 2.6446 0 0 +433.36 3.24723 0 0 +436.754 4.38799 0 0 +440.149 6.19412 0 0 +443.543 8.56318 0 0 +446.938 10.8523 0 0 +450.332 12.2135 0 0 +453.727 12.2999 0 0 +457.122 11.446 0 0 +460.517 10.1273 0 0 +463.912 8.60832 0 0 +467.307 7.10371 0 0 +470.702 5.81696 0 0 +474.097 4.81515 0 0 +477.492 4.03381 0 0 +480.887 3.42725 0 0 +484.282 2.97247 0 0 +487.678 2.67635 0 0 +491.073 2.52325 0 0 +494.468 2.49864 0 0 +497.863 2.58423 0 0 +501.258 2.76629 0 0 +504.653 3.02593 0 0 +508.048 3.34711 0 0 +511.442 3.71598 0 0 +514.837 4.11528 0 0 +518.232 4.52744 0 0 +521.626 4.95489 0 0 +525.021 5.38225 0 0 +528.415 5.81122 0 0 +531.809 6.23666 0 0 +535.203 6.64152 0 0 +538.596 7.02936 0 0 +541.99 7.38578 0 0 +545.383 7.69219 0 0 +548.776 7.93419 0 0 +552.169 8.10959 0 0 +555.562 8.21769 0 0 +558.954 8.26057 0 0 +562.347 8.2507 0 0 +565.739 8.1934 0 0 +569.13 8.10327 0 0 +572.522 7.98221 0 0 +575.913 7.82366 0 0 +579.304 7.63749 0 0 +582.694 7.41279 0 0 +586.084 7.14093 0 0 +589.474 6.81544 0 0 +592.864 6.44279 0 0 +596.253 6.06602 0 0 +599.642 5.73451 0 0 +603.03 5.46072 0 0 +606.418 5.19657 0 0 +609.806 4.9437 0 0 +613.193 4.70556 0 0 +616.58 4.4732 0 0 +619.966 4.26592 0 0 +623.352 4.06832 0 0 +626.737 3.87601 0 0 +630.122 3.69389 0 0 +633.507 3.49201 0 0 +636.891 3.27841 0 0 +640.274 3.04545 0 0 +643.658 2.80747 0 0 +647.04 2.57477 0 0 +650.422 2.35393 0 0 +653.804 2.15226 0 0 +657.184 1.97169 0 0 +660.565 1.80352 0 0 +663.945 1.63459 0 0 +667.324 1.47465 0 0 +670.702 1.33472 0 0 +674.08 1.21776 0 0 +677.458 1.11072 0 0 +680.835 1.01674 0 0 +684.211 0.929454 0 0 +687.586 0.853055 0 0 +690.961 0.77883 0 0 +694.335 0.71053 0 0 +697.709 0.646151 0 0 +701.082 0.59063 0 0 +704.454 0.539211 0 0 +707.825 0.491071 0 0 +711.196 0.450793 0 0 +714.566 0.413942 0 0 +717.935 0.380045 0 0 +721.303 0.347431 0 0 +724.671 0.318272 0 0 +728.038 0.290012 0 0 +731.404 0.266029 0 0 +734.769 0.241793 0 0 +738.134 0.223163 0 0 +741.497 0.202324 0 0 +744.86 0.182022 0 0 +748.222 0.165879 0 0 +751.583 0.149955 0 0 +754.944 0.135059 0 0 +758.303 0.123077 0 0 +761.662 0.108889 0 0 +765.019 0.10276 0 0 +768.376 0.0925385 0 0 +771.732 0.0815553 0 0 +775.087 0.0712924 0 0 +778.441 0.0651952 0 0 +781.794 0.0605768 0 0 +785.146 0.0539638 0 0 +788.497 0.0469224 0 0 +791.847 0.042532 0 0 +795.196 0.0396258 0 0 +798.544 0.0342593 0 0 +801.891 0.031855 0 0 +805.237 0.0294333 0 0 +808.583 0.026015 0 0 +811.927 0.0235956 0 0 +815.269 0.0234393 0 0 +818.611 0.0202752 0 0 +821.952 0.0173191 0 0 +825.292 0.0173673 0 0 +828.63 0.0142169 0 0 +831.968 0.0112363 0 0 +835.304 0.012298 0 0 +838.64 0.0118943 0 0 +841.974 0.00737611 0 0 +845.307 0.00741134 0 0 +848.639 0.00748342 0 0 +851.969 0.00653879 0 0 +855.299 0.00525594 0 0 +858.627 0.00260808 0 0 +861.954 0.00456641 0 0 +865.28 0.00520859 0 0 +868.604 0.0032823 0 0 +871.927 0.00335363 0 0 +875.25 0.00608673 0 0 +878.57 0.00319097 0 0 +881.89 -0.000392666 0 0 +885.208 0.00273924 0 0 +888.525 0.00184714 0 0 +891.841 0.00318861 0 0 +895.155 0.000239567 0 0 +898.468 0.00448103 0 0 +901.78 0.00361692 0 0 +905.09 0.00438877 0 0 +908.399 0.00268495 0 0 +911.707 0.00514502 0 0 +915.013 0.00460112 0 0 +918.318 0.0034247 0 0 +921.621 0.00530637 0 0 +924.923 0.000948308 0 0 +928.224 0.00258339 0 0 +931.523 0.00724225 0 0 +934.821 0.00805994 0 0 +938.117 0.00670302 0 0 +941.412 0.00744643 0 0 +944.705 0.00935356 0 0 +947.997 0.0142785 0 0 +951.287 0.0159169 0 0 +954.576 -0.00575867 0 0 +957.864 0.0104964 0 0 +961.149 0.0188089 0 0 +964.434 0.00719374 0 0 +967.716 0.0242946 0 0 +970.998 -0.0284896 0 0 +974.277 0.018568 0 0 +977.555 -0.00800103 0 0 +980.831 -0.00425015 0 0 +984.106 -0.00905952 0 0 +987.379 0.000628645 0 0 +990.651 -0.0110259 0 0 +993.921 -0.00290461 0 0 +997.189 -0.00426861 0 0 +1000.46 -0.00185003 0 0 +1003.72 -0.000912602 0 0 +1006.98 -0.000762055 0 0 +1010.25 -0.000442135 0 0 +1013.5 0.000110748 0 0 +1016.76 -5.8947e-05 0 0 +1020.02 -5.5622e-05 0 0 +1023.27 -0.000354915 0 0 +1026.53 -6.46257e-05 0 0 +1029.78 0.000344486 0 0 +1033.03 0.000418682 0 0 +1036.28 0.00052157 0 0 +1039.52 0.00100712 0 0 +1042.77 0.00109709 0 0 +1046.01 0.00048564 0 0 +1049.25 0.000625649 0 0 +1052.49 0.000306661 0 0 +1055.72 0.000592619 0 0 +1058.96 -3.62701e-05 0 0 +1062.19 0.00136145 0 0 +1065.42 0.000483781 0 0 +1068.65 0.00070272 0 0 +1071.88 0.00021563 0 0 +1075.1 0.00050574 0 0 +1078.33 -0.000309238 0 0 +1081.55 9.18287e-05 0 0 +1084.77 -0.000850879 0 0 +1087.99 0.000223741 0 0 +1091.2 0.00103336 0 0 +1094.42 -0.000318554 0 0 +1097.63 0.000512485 0 0 +1100.84 -0.000687683 0 0 +1104.04 -0.000179381 0 0 +1107.25 -0.000327465 0 0 +1110.45 0.000374572 0 0 +1113.66 0.000514858 0 0 +1116.86 -0.00197578 0 0 +1120.05 0.000933835 0 0 +1123.25 -0.00018615 0 0 +1126.44 0.000386707 0 0 +1129.63 -0.00118907 0 0 +1132.82 -0.000186344 0 0 +1136.01 0.00172751 0 0 +1139.19 -0.000323622 0 0 +1142.38 0.000354884 0 0 +1145.56 0.00034418 0 0 +1148.74 -0.000167506 0 0 +1151.91 0.000369686 0 0 +[END] of [DATA] +[END] of [Spectrum] + +[Spectrum] +Version = 1 +IDData = OSCAR_B055_2020-01-01_11-52-00_Calibrated_426 +IDDevice = OSCAR_B055 +DateTime = 2020-01-01 11:52:00 +Comment = +CommentSub1 = +CommentSub2 = +CommentSub3 = +IDDataType = SPECTRUM +IDDataTypeSub1 = CALIBRATED +IDDataTypeSub2 = SAMPLE +Mission = 1 ; 14.6195 ; ; +[Attributes] +SpectrumType = Calibrated +Averaging = 1 +CalFactor = 0 +FlashCount = 1 +IntegrationTime = 512 +PathLength = 10 +Temperature = 20.7 +Salinity = 0 +lampLEDs = 255 +tempLampModule = 25 +tempSpectrometer = 27.3125 +tempMainCPU = 28.3125 +Deviation = 14.6195 +Maximum = 12.3128 +RAWDynamic = 65535 +Unit1 = $01 $01 Wavelength nm +Unit2 = $03 $00 Intensity +Unit3 = $f0 $00 Error +Unit4 = $f1 $00 Status +[END] of [Attributes] +[DATA] +0 8 0 0 +304.594 0.0181496 0 0 +307.975 0.0206222 0 0 +311.356 0.0208327 0 0 +314.738 0.0235765 0 0 +318.12 0.0267931 0 0 +321.503 0.0298235 0 0 +324.887 0.0325347 0 0 +328.27 0.0382886 0 0 +331.655 0.0407333 0 0 +335.04 0.0452284 0 0 +338.425 0.0509894 0 0 +341.811 0.0529173 0 0 +345.197 0.058413 0 0 +348.584 0.0646203 0 0 +351.971 0.0728114 0 0 +355.359 0.0902718 0 0 +358.746 0.141758 0 0 +362.135 0.368406 0 0 +365.523 1.33268 0 0 +368.912 3.92195 0 0 +372.302 7.24134 0 0 +375.692 8.35538 0 0 +379.082 6.52671 0 0 +382.472 3.99067 0 0 +385.863 2.38748 0 0 +389.254 1.83521 0 0 +392.645 2.22176 0 0 +396.037 3.53462 0 0 +399.429 5.5629 0 0 +402.821 7.42334 0 0 +406.213 8.06975 0 0 +409.606 7.36586 0 0 +412.999 5.99991 0 0 +416.392 4.58945 0 0 +419.785 3.45314 0 0 +423.179 2.74346 0 0 +426.572 2.47113 0 0 +429.966 2.62392 0 0 +433.36 3.22997 0 0 +436.754 4.38511 0 0 +440.149 6.21681 0 0 +443.543 8.60569 0 0 +446.938 10.9051 0 0 +450.332 12.2536 0 0 +453.727 12.3128 0 0 +457.122 11.4312 0 0 +460.517 10.0894 0 0 +463.912 8.56043 0 0 +467.307 7.05135 0 0 +470.702 5.76965 0 0 +474.097 4.7747 0 0 +477.492 4.00131 0 0 +480.887 3.39578 0 0 +484.282 2.94521 0 0 +487.678 2.6497 0 0 +491.073 2.50573 0 0 +494.468 2.48472 0 0 +497.863 2.57686 0 0 +501.258 2.75772 0 0 +504.653 3.02381 0 0 +508.048 3.34851 0 0 +511.442 3.71841 0 0 +514.837 4.11772 0 0 +518.232 4.53478 0 0 +521.626 4.96338 0 0 +525.021 5.39033 0 0 +528.415 5.8181 0 0 +531.809 6.24548 0 0 +535.203 6.64873 0 0 +538.596 7.03688 0 0 +541.99 7.3913 0 0 +545.383 7.69758 0 0 +548.776 7.93866 0 0 +552.169 8.11509 0 0 +555.562 8.22125 0 0 +558.954 8.26048 0 0 +562.347 8.25243 0 0 +565.739 8.19304 0 0 +569.13 8.10455 0 0 +572.522 7.98639 0 0 +575.913 7.82856 0 0 +579.304 7.6414 0 0 +582.694 7.41399 0 0 +586.084 7.14409 0 0 +589.474 6.81976 0 0 +592.864 6.44549 0 0 +596.253 6.06779 0 0 +599.642 5.74055 0 0 +603.03 5.46075 0 0 +606.418 5.19971 0 0 +609.806 4.94747 0 0 +613.193 4.70507 0 0 +616.58 4.47755 0 0 +619.966 4.26454 0 0 +623.352 4.06811 0 0 +626.737 3.87696 0 0 +630.122 3.69152 0 0 +633.507 3.48899 0 0 +636.891 3.27421 0 0 +640.274 3.04377 0 0 +643.658 2.80461 0 0 +647.04 2.56731 0 0 +650.422 2.3483 0 0 +653.804 2.1507 0 0 +657.184 1.9688 0 0 +660.565 1.79857 0 0 +663.945 1.62881 0 0 +667.324 1.46954 0 0 +670.702 1.32856 0 0 +674.08 1.21227 0 0 +677.458 1.10714 0 0 +680.835 1.01312 0 0 +684.211 0.925785 0 0 +687.586 0.847147 0 0 +690.961 0.773871 0 0 +694.335 0.70628 0 0 +697.709 0.642854 0 0 +701.082 0.587555 0 0 +704.454 0.536112 0 0 +707.825 0.488197 0 0 +711.196 0.44766 0 0 +714.566 0.40957 0 0 +717.935 0.372723 0 0 +721.303 0.341324 0 0 +724.671 0.31436 0 0 +728.038 0.287558 0 0 +731.404 0.264304 0 0 +734.769 0.241042 0 0 +738.134 0.218006 0 0 +741.497 0.197163 0 0 +744.86 0.179303 0 0 +748.222 0.164868 0 0 +751.583 0.149919 0 0 +754.944 0.132335 0 0 +758.303 0.12304 0 0 +761.662 0.107384 0 0 +765.019 0.100278 0 0 +768.376 0.0888344 0 0 +771.732 0.0807839 0 0 +775.087 0.0710094 0 0 +778.441 0.0636903 0 0 +781.794 0.056626 0 0 +785.146 0.0529476 0 0 +788.497 0.0473766 0 0 +791.847 0.0434763 0 0 +795.196 0.039102 0 0 +798.544 0.0359434 0 0 +801.891 0.0308412 0 0 +805.237 0.030142 0 0 +808.583 0.0257392 0 0 +811.927 0.0228277 0 0 +815.269 0.0206918 0 0 +818.611 0.0182652 0 0 +821.952 0.0150571 0 0 +825.292 0.0151014 0 0 +828.63 0.0114349 0 0 +831.968 0.0114659 0 0 +835.304 0.0115228 0 0 +838.64 0.00907346 0 0 +841.974 0.00864581 0 0 +845.307 0.0076538 0 0 +848.639 0.00563748 0 0 +851.969 0.00493109 0 0 +855.299 0.00363084 0 0 +858.627 0.00501336 0 0 +861.954 0.00372759 0 0 +865.28 0.00183506 0 0 +868.604 0.00496567 0 0 +871.927 0.00421205 0 0 +875.25 0.00432896 0 0 +878.57 0.00197537 0 0 +881.89 0.000163267 0 0 +885.208 0.000811219 0 0 +888.525 0.00249017 0 0 +891.841 0.00589328 0 0 +895.155 0.00157802 0 0 +898.468 0.000192445 0 0 +901.78 0.00406348 0 0 +905.09 0.00176131 0 0 +908.399 0.00272955 0 0 +911.707 0.00276546 0 0 +915.013 0.000692599 0 0 +918.318 0.00354521 0 0 +921.621 -0.00184575 0 0 +924.923 -0.00514376 0 0 +928.224 0.00510985 0 0 +931.523 0.00243276 0 0 +934.821 0.00308457 0 0 +938.117 0.00120399 0 0 +941.412 -0.00150805 0 0 +944.705 0.00713922 0 0 +947.997 0.00584227 0 0 +951.287 0.00546688 0 0 +954.576 0.00156138 0 0 +957.864 0.0114128 0 0 +961.149 0.0158472 0 0 +964.434 0.0199459 0 0 +967.716 0.069832 0 0 +970.998 -0.0146935 0 0 +974.277 -0.191971 0 0 +977.555 -0.001715 0 0 +980.831 0.00171033 0 0 +984.106 -0.00143859 0 0 +987.379 -0.00458342 0 0 +990.651 -0.00961822 0 0 +993.921 0.000152127 0 0 +997.189 -0.00267149 0 0 +1000.46 -0.000750377 0 0 +1003.72 -0.000435814 0 0 +1006.98 -0.000987869 0 0 +1010.25 -0.000817099 0 0 +1013.5 -1.27278e-05 0 0 +1016.76 -5.37601e-05 0 0 +1020.02 -2.7113e-05 0 0 +1023.27 0.000143273 0 0 +1026.53 -0.000212374 0 0 +1029.78 0.000107016 0 0 +1033.03 -0.00038343 0 0 +1036.28 0.000134282 0 0 +1039.52 -0.000404311 0 0 +1042.77 -0.000244009 0 0 +1046.01 0.000350901 0 0 +1049.25 5.60395e-05 0 0 +1052.49 -0.000489839 0 0 +1055.72 -5.7452e-05 0 0 +1058.96 -0.00113163 0 0 +1062.19 -0.000674972 0 0 +1065.42 -0.000313299 0 0 +1068.65 -0.000414292 0 0 +1071.88 0.000555234 0 0 +1075.1 -0.000195252 0 0 +1078.33 -6.16727e-05 0 0 +1081.55 -0.000438689 0 0 +1084.77 -0.0001933 0 0 +1087.99 -0.000314749 0 0 +1091.2 -0.000974033 0 0 +1094.42 -0.00128058 0 0 +1097.63 -0.00100522 0 0 +1100.84 0.000571034 0 0 +1104.04 0.000206384 0 0 +1107.25 -0.00034344 0 0 +1110.45 -0.000332837 0 0 +1113.66 0.000747736 0 0 +1116.86 0.000609303 0 0 +1120.05 0.000478375 0 0 +1123.25 0.000775657 0 0 +1126.44 7.37201e-05 0 0 +1129.63 -0.000345069 0 0 +1132.82 -0.000767314 0 0 +1136.01 -0.000723267 0 0 +1139.19 0.000485237 0 0 +1142.38 -0.000696785 0 0 +1145.56 -5.80613e-05 0 0 +1148.74 0.000318664 0 0 +1151.91 -6.19028e-05 0 0 +[END] of [DATA] +[END] of [Spectrum] + +[Spectrum] +Version = 1 +IDData = OSCAR_B055_2020-01-01_11-53-00_Calibrated_832 +IDDevice = OSCAR_B055 +DateTime = 2020-01-01 11:53:00 +Comment = +CommentSub1 = +CommentSub2 = +CommentSub3 = +IDDataType = SPECTRUM +IDDataTypeSub1 = CALIBRATED +IDDataTypeSub2 = SAMPLE +Mission = 1 ; 11.5673 ; ; +[Attributes] +SpectrumType = Calibrated +Averaging = 1 +CalFactor = 0 +FlashCount = 1 +IntegrationTime = 512 +PathLength = 10 +Temperature = 20.7 +Salinity = 0 +lampLEDs = 255 +tempLampModule = 25.0625 +tempSpectrometer = 27.4375 +tempMainCPU = 28.4375 +Deviation = 11.5673 +Maximum = 12.3164 +RAWDynamic = 65535 +Unit1 = $01 $01 Wavelength nm +Unit2 = $03 $00 Intensity +Unit3 = $f0 $00 Error +Unit4 = $f1 $00 Status +[END] of [Attributes] +[DATA] +0 8 0 0 +304.594 0.0210095 0 0 +307.975 0.018856 0 0 +311.356 0.0231606 0 0 +314.738 0.0258984 0 0 +318.12 0.0288533 0 0 +321.503 0.031376 0 0 +324.887 0.03535 0 0 +328.27 0.0400893 0 0 +331.655 0.0425305 0 0 +335.04 0.0445048 0 0 +338.425 0.0497643 0 0 +341.811 0.0537057 0 0 +345.197 0.0594537 0 0 +348.584 0.0646573 0 0 +351.971 0.0728501 0 0 +355.359 0.0900645 0 0 +358.746 0.140062 0 0 +362.135 0.367717 0 0 +365.523 1.3345 0 0 +368.912 3.92053 0 0 +372.302 7.23828 0 0 +375.692 8.35384 0 0 +379.082 6.52989 0 0 +382.472 3.99586 0 0 +385.863 2.38743 0 0 +389.254 1.83373 0 0 +392.645 2.22091 0 0 +396.037 3.53329 0 0 +399.429 5.56101 0 0 +402.821 7.42098 0 0 +406.213 8.06833 0 0 +409.606 7.37004 0 0 +412.999 6.00358 0 0 +416.392 4.59052 0 0 +419.785 3.45467 0 0 +423.179 2.74445 0 0 +426.572 2.47118 0 0 +429.966 2.62478 0 0 +433.36 3.23083 0 0 +436.754 4.38554 0 0 +440.149 6.21053 0 0 +443.543 8.60458 0 0 +446.938 10.9047 0 0 +450.332 12.2511 0 0 +453.727 12.3164 0 0 +457.122 11.4308 0 0 +460.517 10.0882 0 0 +463.912 8.55778 0 0 +467.307 7.05214 0 0 +470.702 5.77023 0 0 +474.097 4.77467 0 0 +477.492 4.00137 0 0 +480.887 3.39712 0 0 +484.282 2.94685 0 0 +487.678 2.65288 0 0 +491.073 2.50609 0 0 +494.468 2.4859 0 0 +497.863 2.57497 0 0 +501.258 2.75937 0 0 +504.653 3.02484 0 0 +508.048 3.34891 0 0 +511.442 3.7209 0 0 +514.837 4.11833 0 0 +518.232 4.533 0 0 +521.626 4.96292 0 0 +525.021 5.39464 0 0 +528.415 5.82049 0 0 +531.809 6.24421 0 0 +535.203 6.65291 0 0 +538.596 7.0391 0 0 +541.99 7.39203 0 0 +545.383 7.69804 0 0 +548.776 7.94106 0 0 +552.169 8.1167 0 0 +555.562 8.22406 0 0 +558.954 8.26423 0 0 +562.347 8.25393 0 0 +565.739 8.1955 0 0 +569.13 8.10846 0 0 +572.522 7.9876 0 0 +575.913 7.82804 0 0 +579.304 7.64137 0 0 +582.694 7.41593 0 0 +586.084 7.14356 0 0 +589.474 6.81873 0 0 +592.864 6.44739 0 0 +596.253 6.06915 0 0 +599.642 5.73893 0 0 +603.03 5.46354 0 0 +606.418 5.20001 0 0 +609.806 4.94751 0 0 +613.193 4.70436 0 0 +616.58 4.4751 0 0 +619.966 4.2633 0 0 +623.352 4.06859 0 0 +626.737 3.8789 0 0 +630.122 3.69097 0 0 +633.507 3.49259 0 0 +636.891 3.27901 0 0 +640.274 3.04532 0 0 +643.658 2.80391 0 0 +647.04 2.57003 0 0 +650.422 2.35 0 0 +653.804 2.14943 0 0 +657.184 1.96972 0 0 +660.565 1.79947 0 0 +663.945 1.6287 0 0 +667.324 1.47016 0 0 +670.702 1.32941 0 0 +674.08 1.21139 0 0 +677.458 1.1087 0 0 +680.835 1.0132 0 0 +684.211 0.929295 0 0 +687.586 0.85016 0 0 +690.961 0.77516 0 0 +694.335 0.704128 0 0 +697.709 0.643395 0 0 +701.082 0.58662 0 0 +704.454 0.536643 0 0 +707.825 0.490194 0 0 +711.196 0.448183 0 0 +714.566 0.4096 0 0 +717.935 0.375443 0 0 +721.303 0.344287 0 0 +724.671 0.317076 0 0 +728.038 0.289292 0 0 +731.404 0.263347 0 0 +734.769 0.241306 0 0 +738.134 0.219492 0 0 +741.497 0.200114 0 0 +744.86 0.181276 0 0 +748.222 0.164152 0 0 +751.583 0.149691 0 0 +754.944 0.132351 0 0 +758.303 0.1211 0 0 +761.662 0.109354 0 0 +765.019 0.0985831 0 0 +768.376 0.0900715 0 0 +771.732 0.0837321 0 0 +775.087 0.0739577 0 0 +778.441 0.065417 0 0 +781.794 0.0595776 0 0 +785.146 0.0536966 0 0 +788.497 0.0459237 0 0 +791.847 0.0437373 0 0 +795.196 0.038628 0 0 +798.544 0.0335068 0 0 +801.891 0.0338065 0 0 +805.237 0.0284372 0 0 +808.583 0.0247713 0 0 +811.927 0.0228453 0 0 +815.269 0.0244265 0 0 +818.611 0.0205197 0 0 +821.952 0.0160706 0 0 +825.292 0.0128742 0 0 +828.63 0.0144686 0 0 +831.968 0.0102256 0 0 +835.304 0.0105302 0 0 +838.64 0.0108822 0 0 +841.974 0.00918315 0 0 +845.307 0.00845324 0 0 +848.639 0.00775455 0 0 +851.969 0.00814918 0 0 +855.299 0.00391984 0 0 +858.627 0.00476528 0 0 +861.954 0.00816506 0 0 +865.28 0.00607861 0 0 +868.604 0.0049926 0 0 +871.927 0.00452979 0 0 +875.25 0.00405953 0 0 +878.57 0.00381985 0 0 +881.89 0.00203845 0 0 +885.208 0.00437481 0 0 +888.525 0.00617427 0 0 +891.841 0.00425193 0 0 +895.155 0.00370854 0 0 +898.468 0.0038727 0 0 +901.78 0.00294939 0 0 +905.09 0.00414821 0 0 +908.399 0.00657443 0 0 +911.707 0.00495359 0 0 +915.013 0.00393145 0 0 +918.318 -0.000672741 0 0 +921.621 0.00571444 0 0 +924.923 0.00469463 0 0 +928.224 0.00585105 0 0 +931.523 0.00464723 0 0 +934.821 0.00865827 0 0 +938.117 0.00209621 0 0 +941.412 0.0113076 0 0 +944.705 0.0368712 0 0 +947.997 0.002831 0 0 +951.287 0.00761529 0 0 +954.576 0.0156861 0 0 +957.864 0.0251059 0 0 +961.149 0.0148138 0 0 +964.434 -0.00179305 0 0 +967.716 0.874751 0 0 +970.998 -0.00717446 0 0 +974.277 -0.029413 0 0 +977.555 0.00148235 0 0 +980.831 -0.0070036 0 0 +984.106 -0.00495531 0 0 +987.379 -0.0163626 0 0 +990.651 -0.00700422 0 0 +993.921 -0.00269957 0 0 +997.189 0.00135122 0 0 +1000.46 -0.000330127 0 0 +1003.72 -0.000192553 0 0 +1006.98 0.000551344 0 0 +1010.25 0.000683453 0 0 +1013.5 -0.000156273 0 0 +1016.76 -0.000134874 0 0 +1020.02 2.43414e-06 0 0 +1023.27 0.000144182 0 0 +1026.53 -0.000113468 0 0 +1029.78 0.000734398 0 0 +1033.03 -0.000445404 0 0 +1036.28 -0.000732773 0 0 +1039.52 5.27915e-05 0 0 +1042.77 -0.000432604 0 0 +1046.01 -0.000139342 0 0 +1049.25 0.00048234 0 0 +1052.49 0.000281727 0 0 +1055.72 -4.99659e-05 0 0 +1058.96 -0.000167652 0 0 +1062.19 0.000808072 0 0 +1065.42 0.000830731 0 0 +1068.65 0.000544373 0 0 +1071.88 0.00104647 0 0 +1075.1 0.000870033 0 0 +1078.33 -0.000444667 0 0 +1081.55 0.000828093 0 0 +1084.77 -0.000445995 0 0 +1087.99 -0.000432184 0 0 +1091.2 7.62742e-05 0 0 +1094.42 0.000348155 0 0 +1097.63 0.000881746 0 0 +1100.84 0.000825745 0 0 +1104.04 -0.000323746 0 0 +1107.25 0.000357928 0 0 +1110.45 -0.000189183 0 0 +1113.66 0.000348156 0 0 +1116.86 -0.000188905 0 0 +1120.05 -5.55151e-05 0 0 +1123.25 -5.74786e-05 0 0 +1126.44 -0.00116538 0 0 +1129.63 -0.000613045 0 0 +1132.82 8.20823e-05 0 0 +1136.01 -0.00110603 0 0 +1139.19 0.00021726 0 0 +1142.38 -5.21462e-05 0 0 +1145.56 0.00117596 0 0 +1148.74 -0.000302247 0 0 +1151.91 0.00138235 0 0 +[END] of [DATA] +[END] of [Spectrum] + +[Spectrum] +Version = 1 +IDData = OSCAR_B055_2020-01-01_11-54-00_Calibrated_181 +IDDevice = OSCAR_B055 +DateTime = 2020-01-01 11:54:00 +Comment = +CommentSub1 = +CommentSub2 = +CommentSub3 = +IDDataType = SPECTRUM +IDDataTypeSub1 = CALIBRATED +IDDataTypeSub2 = SAMPLE +Mission = 1 ; 12.9023 ; ; +[Attributes] +SpectrumType = Calibrated +Averaging = 1 +CalFactor = 0 +FlashCount = 1 +IntegrationTime = 512 +PathLength = 10 +Temperature = 20.7 +Salinity = 0 +lampLEDs = 255 +tempLampModule = 25.1875 +tempSpectrometer = 27.5625 +tempMainCPU = 28.5625 +Deviation = 12.9023 +Maximum = 12.3127 +RAWDynamic = 65535 +Unit1 = $01 $01 Wavelength nm +Unit2 = $03 $00 Intensity +Unit3 = $f0 $00 Error +Unit4 = $f1 $00 Status +[END] of [Attributes] +[DATA] +0 8 0 0 +304.594 0.0169121 0 0 +307.975 0.0183656 0 0 +311.356 0.0213953 0 0 +314.738 0.0215874 0 0 +318.12 0.0276102 0 0 +321.503 0.0314061 0 0 +324.887 0.0323402 0 0 +328.27 0.0368343 0 0 +331.655 0.0425649 0 0 +335.04 0.0460529 0 0 +338.425 0.0477858 0 0 +341.811 0.054248 0 0 +345.197 0.0594961 0 0 +348.584 0.0647016 0 0 +351.971 0.0723963 0 0 +355.359 0.0878656 0 0 +358.746 0.141211 0 0 +362.135 0.37107 0 0 +365.523 1.33274 0 0 +368.912 3.92556 0 0 +372.302 7.24523 0 0 +375.692 8.36097 0 0 +379.082 6.52722 0 0 +382.472 3.99284 0 0 +385.863 2.39087 0 0 +389.254 1.83482 0 0 +392.645 2.22537 0 0 +396.037 3.53816 0 0 +399.429 5.56481 0 0 +402.821 7.42355 0 0 +406.213 8.06749 0 0 +409.606 7.37145 0 0 +412.999 6.00648 0 0 +416.392 4.58802 0 0 +419.785 3.45262 0 0 +423.179 2.74641 0 0 +426.572 2.47127 0 0 +429.966 2.62527 0 0 +433.36 3.23324 0 0 +436.754 4.38736 0 0 +440.149 6.21437 0 0 +443.543 8.60782 0 0 +446.938 10.9048 0 0 +450.332 12.2525 0 0 +453.727 12.3127 0 0 +457.122 11.4318 0 0 +460.517 10.0904 0 0 +463.912 8.55902 0 0 +467.307 7.05104 0 0 +470.702 5.76774 0 0 +474.097 4.77579 0 0 +477.492 4.00558 0 0 +480.887 3.39685 0 0 +484.282 2.9455 0 0 +487.678 2.65364 0 0 +491.073 2.50509 0 0 +494.468 2.48557 0 0 +497.863 2.57262 0 0 +501.258 2.75993 0 0 +504.653 3.02243 0 0 +508.048 3.3487 0 0 +511.442 3.71744 0 0 +514.837 4.11854 0 0 +518.232 4.53635 0 0 +521.626 4.96174 0 0 +525.021 5.39286 0 0 +528.415 5.81881 0 0 +531.809 6.2436 0 0 +535.203 6.65038 0 0 +538.596 7.03955 0 0 +541.99 7.3942 0 0 +545.383 7.69597 0 0 +548.776 7.9414 0 0 +552.169 8.1172 0 0 +555.562 8.22299 0 0 +558.954 8.268 0 0 +562.347 8.25616 0 0 +565.739 8.194 0 0 +569.13 8.1057 0 0 +572.522 7.98531 0 0 +575.913 7.83213 0 0 +579.304 7.64276 0 0 +582.694 7.41437 0 0 +586.084 7.14396 0 0 +589.474 6.81934 0 0 +592.864 6.44549 0 0 +596.253 6.06569 0 0 +599.642 5.73516 0 0 +603.03 5.46195 0 0 +606.418 5.19764 0 0 +609.806 4.94584 0 0 +613.193 4.70462 0 0 +616.58 4.4741 0 0 +619.966 4.26449 0 0 +623.352 4.06729 0 0 +626.737 3.87708 0 0 +630.122 3.6928 0 0 +633.507 3.49239 0 0 +636.891 3.27503 0 0 +640.274 3.04545 0 0 +643.658 2.80692 0 0 +647.04 2.57173 0 0 +650.422 2.34895 0 0 +653.804 2.14734 0 0 +657.184 1.96809 0 0 +660.565 1.79854 0 0 +663.945 1.63044 0 0 +667.324 1.46916 0 0 +670.702 1.32888 0 0 +674.08 1.21108 0 0 +677.458 1.10567 0 0 +680.835 1.01407 0 0 +684.211 0.926962 0 0 +687.586 0.848304 0 0 +690.961 0.775008 0 0 +694.335 0.706909 0 0 +697.709 0.644693 0 0 +701.082 0.586927 0 0 +704.454 0.535224 0 0 +707.825 0.489503 0 0 +711.196 0.446996 0 0 +714.566 0.408896 0 0 +717.935 0.375959 0 0 +721.303 0.342595 0 0 +724.671 0.314892 0 0 +728.038 0.288083 0 0 +731.404 0.266294 0 0 +734.769 0.240583 0 0 +738.134 0.220967 0 0 +741.497 0.199875 0 0 +744.86 0.178836 0 0 +748.222 0.166844 0 0 +751.583 0.149449 0 0 +754.944 0.135042 0 0 +758.303 0.122324 0 0 +761.662 0.109845 0 0 +765.019 0.0983401 0 0 +768.376 0.0888514 0 0 +771.732 0.079579 0 0 +775.087 0.0700489 0 0 +778.441 0.0646855 0 0 +781.794 0.059091 0 0 +785.146 0.0541877 0 0 +788.497 0.0478853 0 0 +791.847 0.045455 0 0 +795.196 0.0391221 0 0 +798.544 0.0352283 0 0 +801.891 0.0320915 0 0 +805.237 0.0269663 0 0 +808.583 0.0260082 0 0 +811.927 0.0216174 0 0 +815.269 0.0202218 0 0 +818.611 0.0180426 0 0 +821.952 0.0170741 0 0 +825.292 0.0168762 0 0 +828.63 0.0147302 0 0 +831.968 0.0102337 0 0 +835.304 0.0100332 0 0 +838.64 0.00808054 0 0 +841.974 0.00764567 0 0 +845.307 0.00742732 0 0 +848.639 0.00540539 0 0 +851.969 0.00683213 0 0 +855.299 0.00635383 0 0 +858.627 0.00477849 0 0 +861.954 0.00459226 0 0 +865.28 0.00440565 0 0 +868.604 0.00387314 0 0 +871.927 0.00163168 0 0 +875.25 0.00438205 0 0 +878.57 0.0020113 0 0 +881.89 0.00111757 0 0 +885.208 0.00538231 0 0 +888.525 0.0045529 0 0 +891.841 0.00326926 0 0 +895.155 0.00127033 0 0 +898.468 0.00243986 0 0 +901.78 0.00259788 0 0 +905.09 0.000233963 0 0 +908.399 0.00239951 0 0 +911.707 0.00504723 0 0 +915.013 0.00448669 0 0 +918.318 0.00370541 0 0 +921.621 0.00422024 0 0 +924.923 0.00166385 0 0 +928.224 0.00988014 0 0 +931.523 0.00191517 0 0 +934.821 0.00153631 0 0 +938.117 0.00222436 0 0 +941.412 0.0065067 0 0 +944.705 -0.00668092 0 0 +947.997 0.00545062 0 0 +951.287 -0.00467112 0 0 +954.576 0.0230093 0 0 +957.864 0.00940965 0 0 +961.149 0.0201672 0 0 +964.434 -0.00306129 0 0 +967.716 -0.0992203 0 0 +970.998 -0.00259686 0 0 +974.277 -0.0548844 0 0 +977.555 -0.00054799 0 0 +980.831 0.00389463 0 0 +984.106 0.00112319 0 0 +987.379 -0.00587479 0 0 +990.651 0.000940344 0 0 +993.921 -0.00106886 0 0 +997.189 0.00164214 0 0 +1000.46 -0.000316022 0 0 +1003.72 -0.000887732 0 0 +1006.98 0.000729959 0 0 +1010.25 0.000454133 0 0 +1013.5 -1.35898e-05 0 0 +1016.76 5.08625e-05 0 0 +1020.02 -9.16096e-06 0 0 +1023.27 -5.55991e-05 0 0 +1026.53 0.000119473 0 0 +1029.78 -2.80692e-05 0 0 +1033.03 0.000244909 0 0 +1036.28 5.04535e-05 0 0 +1039.52 0.000317176 0 0 +1042.77 0.000540223 0 0 +1046.01 -4.00601e-05 0 0 +1049.25 -0.000768619 0 0 +1052.49 0.000170637 0 0 +1055.72 -0.000289156 0 0 +1058.96 0.000186316 0 0 +1062.19 -0.000171141 0 0 +1065.42 -0.000924127 0 0 +1068.65 6.89528e-05 0 0 +1071.88 -0.000410803 0 0 +1075.1 -0.000837752 0 0 +1078.33 -0.00121334 0 0 +1081.55 7.31184e-05 0 0 +1084.77 0.000205368 0 0 +1087.99 0.000324186 0 0 +1091.2 -0.000309333 0 0 +1094.42 -0.000853638 0 0 +1097.63 -0.00058421 0 0 +1100.84 7.2877e-05 0 0 +1104.04 0.000476684 0 0 +1107.25 -0.000330104 0 0 +1110.45 0.000608393 0 0 +1113.66 0.000211413 0 0 +1116.86 -0.000716544 0 0 +1120.05 -0.000188347 0 0 +1123.25 0.000219556 0 0 +1126.44 8.06762e-05 0 0 +1129.63 -0.000606853 0 0 +1132.82 -0.000885595 0 0 +1136.01 -0.000183622 0 0 +1139.19 -5.57681e-05 0 0 +1142.38 -0.000301978 0 0 +1145.56 0.000556118 0 0 +1148.74 0.00143725 0 0 +1151.91 0.00174753 0 0 +[END] of [DATA] +[END] of [Spectrum] + +[Spectrum] +Version = 1 +IDData = OSCAR_B055_2020-01-01_11-55-00_Calibrated_954 +IDDevice = OSCAR_B055 +DateTime = 2020-01-01 11:55:00 +Comment = +CommentSub1 = +CommentSub2 = +CommentSub3 = +IDDataType = SPECTRUM +IDDataTypeSub1 = CALIBRATED +IDDataTypeSub2 = SAMPLE +Mission = 1 ; 13.7338 ; ; +[Attributes] +SpectrumType = Calibrated +Averaging = 1 +CalFactor = 0 +FlashCount = 1 +IntegrationTime = 512 +PathLength = 10 +Temperature = 20.7 +Salinity = 0 +lampLEDs = 255 +tempLampModule = 25.3125 +tempSpectrometer = 27.6875 +tempMainCPU = 28.6875 +Deviation = 13.7338 +Maximum = 12.3148 +RAWDynamic = 65535 +Unit1 = $01 $01 Wavelength nm +Unit2 = $03 $00 Intensity +Unit3 = $f0 $00 Error +Unit4 = $f1 $00 Status +[END] of [Attributes] +[DATA] +0 8 0 0 +304.594 0.017026 0 0 +307.975 0.0210469 0 0 +311.356 0.0197163 0 0 +314.738 0.0265545 0 0 +318.12 0.027727 0 0 +321.503 0.0307629 0 0 +324.887 0.0342348 0 0 +328.27 0.0377146 0 0 +331.655 0.0447099 0 0 +335.04 0.0456731 0 0 +338.425 0.0506858 0 0 +341.811 0.0553836 0 0 +345.197 0.059124 0 0 +348.584 0.0658402 0 0 +351.971 0.0737876 0 0 +355.359 0.0890125 0 0 +358.746 0.140415 0 0 +362.135 0.36869 0 0 +365.523 1.33699 0 0 +368.912 3.92725 0 0 +372.302 7.24842 0 0 +375.692 8.36369 0 0 +379.082 6.53169 0 0 +382.472 3.99301 0 0 +385.863 2.3901 0 0 +389.254 1.83382 0 0 +392.645 2.22299 0 0 +396.037 3.53683 0 0 +399.429 5.56439 0 0 +402.821 7.42042 0 0 +406.213 8.07075 0 0 +409.606 7.36727 0 0 +412.999 6.00285 0 0 +416.392 4.58926 0 0 +419.785 3.4526 0 0 +423.179 2.74388 0 0 +426.572 2.47024 0 0 +429.966 2.6244 0 0 +433.36 3.23014 0 0 +436.754 4.38336 0 0 +440.149 6.21356 0 0 +443.543 8.6074 0 0 +446.938 10.9092 0 0 +450.332 12.2564 0 0 +453.727 12.3148 0 0 +457.122 11.4313 0 0 +460.517 10.0942 0 0 +463.912 8.55986 0 0 +467.307 7.05245 0 0 +470.702 5.77066 0 0 +474.097 4.77216 0 0 +477.492 4.00188 0 0 +480.887 3.39715 0 0 +484.282 2.9486 0 0 +487.678 2.65351 0 0 +491.073 2.50538 0 0 +494.468 2.48629 0 0 +497.863 2.57526 0 0 +501.258 2.75862 0 0 +504.653 3.02454 0 0 +508.048 3.3466 0 0 +511.442 3.71827 0 0 +514.837 4.11809 0 0 +518.232 4.53435 0 0 +521.626 4.96262 0 0 +525.021 5.39239 0 0 +528.415 5.81895 0 0 +531.809 6.24481 0 0 +535.203 6.65214 0 0 +538.596 7.03763 0 0 +541.99 7.39104 0 0 +545.383 7.69769 0 0 +548.776 7.94083 0 0 +552.169 8.11803 0 0 +555.562 8.22423 0 0 +558.954 8.2662 0 0 +562.347 8.25676 0 0 +565.739 8.19874 0 0 +569.13 8.10696 0 0 +572.522 7.98532 0 0 +575.913 7.83041 0 0 +579.304 7.64154 0 0 +582.694 7.41289 0 0 +586.084 7.14593 0 0 +589.474 6.81931 0 0 +592.864 6.44811 0 0 +596.253 6.067 0 0 +599.642 5.74182 0 0 +603.03 5.4634 0 0 +606.418 5.1993 0 0 +609.806 4.94672 0 0 +613.193 4.7067 0 0 +616.58 4.47392 0 0 +619.966 4.26454 0 0 +623.352 4.07076 0 0 +626.737 3.88052 0 0 +630.122 3.6925 0 0 +633.507 3.49448 0 0 +636.891 3.27903 0 0 +640.274 3.04764 0 0 +643.658 2.80681 0 0 +647.04 2.57082 0 0 +650.422 2.35192 0 0 +653.804 2.15002 0 0 +657.184 1.9722 0 0 +660.565 1.79794 0 0 +663.945 1.63152 0 0 +667.324 1.47046 0 0 +670.702 1.32868 0 0 +674.08 1.21134 0 0 +677.458 1.10837 0 0 +680.835 1.01331 0 0 +684.211 0.926678 0 0 +687.586 0.848253 0 0 +690.961 0.77249 0 0 +694.335 0.706833 0 0 +697.709 0.642398 0 0 +701.082 0.587811 0 0 +704.454 0.535117 0 0 +707.825 0.490614 0 0 +711.196 0.448835 0 0 +714.566 0.410483 0 0 +717.935 0.374357 0 0 +721.303 0.342949 0 0 +724.671 0.314753 0 0 +728.038 0.290141 0 0 +731.404 0.263702 0 0 +734.769 0.239946 0 0 +738.134 0.217883 0 0 +741.497 0.199234 0 0 +744.86 0.18235 0 0 +748.222 0.163757 0 0 +751.583 0.149783 0 0 +754.944 0.133664 0 0 +758.303 0.121679 0 0 +761.662 0.111154 0 0 +765.019 0.100626 0 0 +768.376 0.0904056 0 0 +771.732 0.0806449 0 0 +775.087 0.0740478 0 0 +778.441 0.0645293 0 0 +781.794 0.0579568 0 0 +785.146 0.0532978 0 0 +788.497 0.0494439 0 0 +791.847 0.0411359 0 0 +795.196 0.0377414 0 0 +798.544 0.0340923 0 0 +801.891 0.0329205 0 0 +805.237 0.0287812 0 0 +808.583 0.026347 0 0 +811.927 0.0244259 0 0 +815.269 0.0213083 0 0 +818.611 0.0188838 0 0 +821.952 0.0164231 0 0 +825.292 0.0149749 0 0 +828.63 0.0130682 0 0 +831.968 0.0120972 0 0 +835.304 0.0111469 0 0 +838.64 0.010997 0 0 +841.974 0.00981792 0 0 +845.307 0.00883192 0 0 +848.639 0.00708591 0 0 +851.969 0.00480091 0 0 +855.299 0.00457469 0 0 +858.627 0.00379818 0 0 +861.954 0.0035941 0 0 +865.28 0.00594079 0 0 +868.604 0.00370408 0 0 +871.927 0.00409027 0 0 +875.25 0.00390861 0 0 +878.57 0.00612495 0 0 +881.89 0.00405741 0 0 +885.208 0.00161583 0 0 +888.525 0.00437427 0 0 +891.841 0.00342195 0 0 +895.155 0.00427355 0 0 +898.468 0.00335326 0 0 +901.78 0.00197707 0 0 +905.09 0.00724619 0 0 +908.399 0.00172345 0 0 +911.707 0.00219358 0 0 +915.013 0.00284326 0 0 +918.318 0.000471256 0 0 +921.621 0.00226082 0 0 +924.923 -0.000708339 0 0 +928.224 0.00193915 0 0 +931.523 0.000732318 0 0 +934.821 0.00202163 0 0 +938.117 0.0100155 0 0 +941.412 -7.52868e-05 0 0 +944.705 -0.00756523 0 0 +947.997 -0.00272371 0 0 +951.287 -0.00478652 0 0 +954.576 0.0934746 0 0 +957.864 0.025811 0 0 +961.149 -0.113059 0 0 +964.434 0.0492879 0 0 +967.716 -0.0583488 0 0 +970.998 -0.00130184 0 0 +974.277 0.00795037 0 0 +977.555 0.00256112 0 0 +980.831 -0.0022134 0 0 +984.106 -0.00212187 0 0 +987.379 -0.00181087 0 0 +990.651 -0.00486112 0 0 +993.921 -0.00224796 0 0 +997.189 -0.00243709 0 0 +1000.46 -0.000752104 0 0 +1003.72 -0.000897592 0 0 +1006.98 0.000100922 0 0 +1010.25 -0.00059128 0 0 +1013.5 -0.000156294 0 0 +1016.76 8.19983e-06 0 0 +1020.02 3.41199e-05 0 0 +1023.27 -4.08867e-05 0 0 +1026.53 -4.7972e-05 0 0 +1029.78 -7.09594e-05 0 0 +1033.03 6.31354e-05 0 0 +1036.28 -0.000427323 0 0 +1039.52 -0.000614699 0 0 +1042.77 -0.000768221 0 0 +1046.01 -0.000485232 0 0 +1049.25 -0.000415296 0 0 +1052.49 -6.23921e-06 0 0 +1055.72 -0.000125447 0 0 +1058.96 -0.000238625 0 0 +1062.19 -0.00108554 0 0 +1065.42 0.000116056 0 0 +1068.65 -0.000817632 0 0 +1071.88 -0.000483009 0 0 +1075.1 -0.000395481 0 0 +1078.33 0.000375102 0 0 +1081.55 0.000361603 0 0 +1084.77 0.000120398 0 0 +1087.99 0.000116581 0 0 +1091.2 -0.000134352 0 0 +1094.42 0.00091478 0 0 +1097.63 0.000516444 0 0 +1100.84 -0.000129685 0 0 +1104.04 -0.00132263 0 0 +1107.25 -0.000414426 0 0 +1110.45 0.000385956 0 0 +1113.66 -0.000929937 0 0 +1116.86 -0.000138743 0 0 +1120.05 0.000652409 0 0 +1123.25 0.000128864 0 0 +1126.44 0.000535169 0 0 +1129.63 0.000536712 0 0 +1132.82 -0.000418236 0 0 +1136.01 0.000764496 0 0 +1139.19 -0.000946675 0 0 +1142.38 -0.000378728 0 0 +1145.56 0.000472153 0 0 +1148.74 0.000606612 0 0 +1151.91 0.00163955 0 0 +[END] of [DATA] +[END] of [Spectrum] + +[Spectrum] +Version = 1 +IDData = OSCAR_B055_2020-01-01_11-56-00_Calibrated_672 +IDDevice = OSCAR_B055 +DateTime = 2020-01-01 11:56:00 +Comment = +CommentSub1 = +CommentSub2 = +CommentSub3 = +IDDataType = SPECTRUM +IDDataTypeSub1 = CALIBRATED +IDDataTypeSub2 = SAMPLE +Mission = 1 ; 13.7715 ; ; +[Attributes] +SpectrumType = Calibrated +Averaging = 1 +CalFactor = 0 +FlashCount = 1 +IntegrationTime = 512 +PathLength = 10 +Temperature = 20.7 +Salinity = 0 +lampLEDs = 255 +tempLampModule = 25.4062 +tempSpectrometer = 27.8125 +tempMainCPU = 28.8125 +Deviation = 13.7715 +Maximum = 12.3145 +RAWDynamic = 65535 +Unit1 = $01 $01 Wavelength nm +Unit2 = $03 $00 Intensity +Unit3 = $f0 $00 Error +Unit4 = $f1 $00 Status +[END] of [Attributes] +[DATA] +0 8 0 0 +304.594 0.0195061 0 0 +307.975 0.0188882 0 0 +311.356 0.0221771 0 0 +314.738 0.0241541 0 0 +318.12 0.0255899 0 0 +321.503 0.029647 0 0 +324.887 0.0351539 0 0 +328.27 0.0371126 0 0 +331.655 0.0405727 0 0 +335.04 0.0458335 0 0 +338.425 0.049334 0 0 +341.811 0.0547914 0 0 +345.197 0.0575264 0 0 +348.584 0.0644983 0 0 +351.971 0.0752128 0 0 +355.359 0.0886855 0 0 +358.746 0.139885 0 0 +362.135 0.368031 0 0 +365.523 1.33675 0 0 +368.912 3.93104 0 0 +372.302 7.25087 0 0 +375.692 8.36723 0 0 +379.082 6.53365 0 0 +382.472 3.99063 0 0 +385.863 2.38811 0 0 +389.254 1.83639 0 0 +392.645 2.22319 0 0 +396.037 3.53381 0 0 +399.429 5.56498 0 0 +402.821 7.42661 0 0 +406.213 8.07027 0 0 +409.606 7.37009 0 0 +412.999 6.00419 0 0 +416.392 4.5865 0 0 +419.785 3.45114 0 0 +423.179 2.74332 0 0 +426.572 2.47019 0 0 +429.966 2.62616 0 0 +433.36 3.23324 0 0 +436.754 4.38732 0 0 +440.149 6.21658 0 0 +443.543 8.61022 0 0 +446.938 10.9088 0 0 +450.332 12.2565 0 0 +453.727 12.3145 0 0 +457.122 11.4348 0 0 +460.517 10.0938 0 0 +463.912 8.56195 0 0 +467.307 7.05206 0 0 +470.702 5.77128 0 0 +474.097 4.77343 0 0 +477.492 4.00135 0 0 +480.887 3.39526 0 0 +484.282 2.94875 0 0 +487.678 2.65257 0 0 +491.073 2.50408 0 0 +494.468 2.48635 0 0 +497.863 2.57326 0 0 +501.258 2.76021 0 0 +504.653 3.02237 0 0 +508.048 3.34855 0 0 +511.442 3.71594 0 0 +514.837 4.11714 0 0 +518.232 4.53279 0 0 +521.626 4.96242 0 0 +525.021 5.3918 0 0 +528.415 5.81671 0 0 +531.809 6.2461 0 0 +535.203 6.65247 0 0 +538.596 7.03897 0 0 +541.99 7.39187 0 0 +545.383 7.69554 0 0 +548.776 7.94405 0 0 +552.169 8.12118 0 0 +555.562 8.22288 0 0 +558.954 8.26578 0 0 +562.347 8.25679 0 0 +565.739 8.19922 0 0 +569.13 8.10569 0 0 +572.522 7.98748 0 0 +575.913 7.82986 0 0 +579.304 7.64198 0 0 +582.694 7.41455 0 0 +586.084 7.14562 0 0 +589.474 6.81996 0 0 +592.864 6.44577 0 0 +596.253 6.06558 0 0 +599.642 5.74011 0 0 +603.03 5.45895 0 0 +606.418 5.19679 0 0 +609.806 4.94713 0 0 +613.193 4.70635 0 0 +616.58 4.47256 0 0 +619.966 4.2634 0 0 +623.352 4.0669 0 0 +626.737 3.8791 0 0 +630.122 3.6908 0 0 +633.507 3.49323 0 0 +636.891 3.27746 0 0 +640.274 3.04553 0 0 +643.658 2.8071 0 0 +647.04 2.57205 0 0 +650.422 2.35286 0 0 +653.804 2.14994 0 0 +657.184 1.9684 0 0 +660.565 1.79707 0 0 +663.945 1.62939 0 0 +667.324 1.47101 0 0 +670.702 1.33092 0 0 +674.08 1.21283 0 0 +677.458 1.10591 0 0 +680.835 1.01232 0 0 +684.211 0.928371 0 0 +687.586 0.848463 0 0 +690.961 0.773672 0 0 +694.335 0.70727 0 0 +697.709 0.644299 0 0 +701.082 0.586516 0 0 +704.454 0.535531 0 0 +707.825 0.487836 0 0 +711.196 0.446787 0 0 +714.566 0.409656 0 0 +717.935 0.377444 0 0 +721.303 0.343339 0 0 +724.671 0.315141 0 0 +728.038 0.288813 0 0 +731.404 0.263351 0 0 +734.769 0.241795 0 0 +738.134 0.220219 0 0 +741.497 0.198635 0 0 +744.86 0.181506 0 0 +748.222 0.165356 0 0 +751.583 0.149425 0 0 +754.944 0.135262 0 0 +758.303 0.123277 0 0 +761.662 0.109819 0 0 +765.019 0.0990465 0 0 +768.376 0.0890699 0 0 +771.732 0.0812645 0 0 +775.087 0.072712 0 0 +778.441 0.0641712 0 0 +781.794 0.0580882 0 0 +785.146 0.0526951 0 0 +788.497 0.047862 0 0 +791.847 0.0434724 0 0 +795.196 0.0386095 0 0 +798.544 0.0344707 0 0 +801.891 0.0320712 0 0 +805.237 0.0271926 0 0 +808.583 0.0257425 0 0 +811.927 0.0240677 0 0 +815.269 0.0211973 0 0 +818.611 0.0187726 0 0 +821.952 0.0178066 0 0 +825.292 0.0151134 0 0 +828.63 0.0129566 0 0 +831.968 0.0104706 0 0 +835.304 0.0110352 0 0 +838.64 0.00986043 0 0 +841.974 0.00867025 0 0 +845.307 0.00950135 0 0 +848.639 0.00591796 0 0 +851.969 0.0060229 0 0 +855.299 0.00229161 0 0 +858.627 0.00804586 0 0 +861.954 0.00764766 0 0 +865.28 0.00411676 0 0 +868.604 0.00329346 0 0 +871.927 0.00514442 0 0 +875.25 0.00681474 0 0 +878.57 0.0044651 0 0 +881.89 0.00235398 0 0 +885.208 0.00212848 0 0 +888.525 0.00458344 0 0 +891.841 0.00432357 0 0 +895.155 0.00305645 0 0 +898.468 0.00245002 0 0 +901.78 0.0022133 0 0 +905.09 0.00591304 0 0 +908.399 0.0010955 0 0 +911.707 0.00201377 0 0 +915.013 0.00363718 0 0 +918.318 0.00432374 0 0 +921.621 0.0038014 0 0 +924.923 0.00239478 0 0 +928.224 0.00235939 0 0 +931.523 0.002809 0 0 +934.821 0.00604479 0 0 +938.117 0.00718987 0 0 +941.412 0.00203343 0 0 +944.705 0.00715472 0 0 +947.997 0.0292125 0 0 +951.287 0.036856 0 0 +954.576 0.313534 0 0 +957.864 -0.500441 0 0 +961.149 0.017168 0 0 +964.434 -0.0773333 0 0 +967.716 -0.0283799 0 0 +970.998 0.000656498 0 0 +974.277 -0.00735686 0 0 +977.555 0.00196859 0 0 +980.831 -0.000781732 0 0 +984.106 0.00103127 0 0 +987.379 -0.00126504 0 0 +990.651 -0.00142583 0 0 +993.921 0.00123615 0 0 +997.189 -0.00150563 0 0 +1000.46 -0.000272286 0 0 +1003.72 -0.00060305 0 0 +1006.98 -0.000323004 0 0 +1010.25 -0.000337017 0 0 +1013.5 -0.00014298 0 0 +1016.76 -7.96694e-05 0 0 +1020.02 -3.58034e-05 0 0 +1023.27 5.59697e-05 0 0 +1026.53 0.000155095 0 0 +1029.78 0.000163503 0 0 +1033.03 0.000494765 0 0 +1036.28 0.00028987 0 0 +1039.52 0.000298905 0 0 +1042.77 -0.000427321 0 0 +1046.01 0.000329412 0 0 +1049.25 4.76738e-05 0 0 +1052.49 -0.00047587 0 0 +1055.72 -0.00111913 0 0 +1058.96 -0.000635175 0 0 +1062.19 -6.28993e-05 0 0 +1065.42 -0.00067625 0 0 +1068.65 -0.000749661 0 0 +1071.88 -0.000416368 0 0 +1075.1 0.00070181 0 0 +1078.33 -0.000446539 0 0 +1081.55 0.000179338 0 0 +1084.77 0.000313534 0 0 +1087.99 5.78118e-05 0 0 +1091.2 -6.66424e-05 0 0 +1094.42 6.15538e-05 0 0 +1097.63 0.000581272 0 0 +1100.84 -0.000914409 0 0 +1104.04 -0.000330068 0 0 +1107.25 -7.11873e-05 0 0 +1110.45 -0.00032937 0 0 +1113.66 -0.000199946 0 0 +1116.86 0.000451273 0 0 +1120.05 -0.000200387 0 0 +1123.25 0.000199923 0 0 +1126.44 -0.000610513 0 0 +1129.63 0.000604293 0 0 +1132.82 -0.000207554 0 0 +1136.01 -6.75834e-05 0 0 +1139.19 -0.000603042 0 0 +1142.38 0.00116289 0 0 +1145.56 0.00017466 0 0 +1148.74 0.000301027 0 0 +1151.91 0.00168759 0 0 +[END] of [DATA] +[END] of [Spectrum] + +[Spectrum] +Version = 1 +IDData = OSCAR_B055_2020-01-01_12-08-00_Calibrated_582 +IDDevice = OSCAR_B055 +DateTime = 2020-01-01 12:08:00 +Comment = +CommentSub1 = +CommentSub2 = +CommentSub3 = +IDDataType = SPECTRUM +IDDataTypeSub1 = CALIBRATED +IDDataTypeSub2 = SAMPLE +Mission = 1 ; 14.0141 ; ; +[Attributes] +SpectrumType = Calibrated +Averaging = 1 +CalFactor = 0 +FlashCount = 1 +IntegrationTime = 512 +PathLength = 10 +Temperature = 20.7 +Salinity = 0 +lampLEDs = 255 +tempLampModule = 24.5312 +tempSpectrometer = 26.1562 +tempMainCPU = 26.5625 +Deviation = 14.0141 +Maximum = 12.2711 +RAWDynamic = 65535 +Unit1 = $01 $01 Wavelength nm +Unit2 = $03 $00 Intensity +Unit3 = $f0 $00 Error +Unit4 = $f1 $00 Status +[END] of [Attributes] +[DATA] +0 8 0 0 +304.594 0.0178478 0 0 +307.975 0.0218493 0 0 +311.356 0.0218066 0 0 +314.738 0.0245428 0 0 +318.12 0.031293 0 0 +321.503 0.0307725 0 0 +324.887 0.0342354 0 0 +328.27 0.0374554 0 0 +331.655 0.0441741 0 0 +335.04 0.0479035 0 0 +338.425 0.0508882 0 0 +341.811 0.0553241 0 0 +345.197 0.0603056 0 0 +348.584 0.0632471 0 0 +351.971 0.0724264 0 0 +355.359 0.0901031 0 0 +358.746 0.142313 0 0 +362.135 0.364236 0 0 +365.523 1.31061 0 0 +368.912 3.86264 0 0 +372.302 7.16788 0 0 +375.692 8.32272 0 0 +379.082 6.53905 0 0 +382.472 4.01667 0 0 +385.863 2.40696 0 0 +389.254 1.84112 0 0 +392.645 2.21112 0 0 +396.037 3.49688 0 0 +399.429 5.49241 0 0 +402.821 7.34137 0 0 +406.213 8.00399 0 0 +409.606 7.33495 0 0 +412.999 5.99708 0 0 +416.392 4.59781 0 0 +419.785 3.47405 0 0 +423.179 2.76198 0 0 +426.572 2.48437 0 0 +429.966 2.64045 0 0 +433.36 3.23931 0 0 +436.754 4.37934 0 0 +440.149 6.17967 0 0 +443.543 8.54245 0 0 +446.938 10.822 0 0 +450.332 12.1804 0 0 +453.727 12.2711 0 0 +457.122 11.4247 0 0 +460.517 10.1109 0 0 +463.912 8.59055 0 0 +467.307 7.086 0 0 +470.702 5.80185 0 0 +474.097 4.79637 0 0 +477.492 4.0211 0 0 +480.887 3.41583 0 0 +484.282 2.96113 0 0 +487.678 2.66284 0 0 +491.073 2.51265 0 0 +494.468 2.49071 0 0 +497.863 2.57603 0 0 +501.258 2.75609 0 0 +504.653 3.01714 0 0 +508.048 3.3395 0 0 +511.442 3.70439 0 0 +514.837 4.09849 0 0 +518.232 4.51264 0 0 +521.626 4.93841 0 0 +525.021 5.3609 0 0 +528.415 5.78381 0 0 +531.809 6.20694 0 0 +535.203 6.61125 0 0 +538.596 6.99785 0 0 +541.99 7.34863 0 0 +545.383 7.65438 0 0 +548.776 7.90141 0 0 +552.169 8.07865 0 0 +555.562 8.1854 0 0 +558.954 8.23282 0 0 +562.347 8.22648 0 0 +565.739 8.17046 0 0 +569.13 8.07793 0 0 +572.522 7.9618 0 0 +575.913 7.80449 0 0 +579.304 7.61782 0 0 +582.694 7.38944 0 0 +586.084 7.11561 0 0 +589.474 6.78917 0 0 +592.864 6.41608 0 0 +596.253 6.03549 0 0 +599.642 5.70946 0 0 +603.03 5.43277 0 0 +606.418 5.17186 0 0 +609.806 4.91584 0 0 +613.193 4.67896 0 0 +616.58 4.44959 0 0 +619.966 4.24259 0 0 +623.352 4.04452 0 0 +626.737 3.85939 0 0 +630.122 3.67659 0 0 +633.507 3.47774 0 0 +636.891 3.26277 0 0 +640.274 3.03459 0 0 +643.658 2.79646 0 0 +647.04 2.56262 0 0 +650.422 2.34628 0 0 +653.804 2.14368 0 0 +657.184 1.96243 0 0 +660.565 1.79554 0 0 +663.945 1.62935 0 0 +667.324 1.46847 0 0 +670.702 1.32857 0 0 +674.08 1.20797 0 0 +677.458 1.10365 0 0 +680.835 1.01068 0 0 +684.211 0.925378 0 0 +687.586 0.845072 0 0 +690.961 0.771356 0 0 +694.335 0.704052 0 0 +697.709 0.639443 0 0 +701.082 0.5832 0 0 +704.454 0.532042 0 0 +707.825 0.486607 0 0 +711.196 0.444869 0 0 +714.566 0.409007 0 0 +717.935 0.375608 0 0 +721.303 0.342265 0 0 +724.671 0.31262 0 0 +728.038 0.287059 0 0 +731.404 0.262834 0 0 +734.769 0.23909 0 0 +738.134 0.219241 0 0 +741.497 0.198161 0 0 +744.86 0.179816 0 0 +748.222 0.163185 0 0 +751.583 0.149707 0 0 +754.944 0.134567 0 0 +758.303 0.121853 0 0 +761.662 0.110841 0 0 +765.019 0.0971408 0 0 +768.376 0.0903371 0 0 +771.732 0.0832635 0 0 +775.087 0.0737339 0 0 +778.441 0.0651927 0 0 +781.794 0.0588617 0 0 +785.146 0.0534723 0 0 +788.497 0.0464291 0 0 +791.847 0.0415487 0 0 +795.196 0.0381509 0 0 +798.544 0.0354801 0 0 +801.891 0.0320944 0 0 +805.237 0.0281971 0 0 +808.583 0.0260081 0 0 +811.927 0.0233413 0 0 +815.269 0.0216971 0 0 +818.611 0.0177845 0 0 +821.952 0.0150739 0 0 +825.292 0.0146167 0 0 +828.63 0.012952 0 0 +831.968 0.0109741 0 0 +835.304 0.00950953 0 0 +838.64 0.00857164 0 0 +841.974 0.00890225 0 0 +845.307 0.00894303 0 0 +848.639 0.00564607 0 0 +851.969 0.00678484 0 0 +855.299 0.00763297 0 0 +858.627 0.00474158 0 0 +861.954 0.00509296 0 0 +865.28 0.00518459 0 0 +868.604 0.00326575 0 0 +871.927 0.00134033 0 0 +875.25 0.00195816 0 0 +878.57 0.00227993 0 0 +881.89 0.00201845 0 0 +885.208 0.00115507 0 0 +888.525 0.00214808 0 0 +891.841 0.00250299 0 0 +895.155 0.00559735 0 0 +898.468 0.00406778 0 0 +901.78 0.00538742 0 0 +905.09 0.00320655 0 0 +908.399 0.00223728 0 0 +911.707 0.00226084 0 0 +915.013 0.00490595 0 0 +918.318 0.000305171 0 0 +921.621 0.00513168 0 0 +924.923 0.00144316 0 0 +928.224 0.00195278 0 0 +931.523 0.00100399 0 0 +934.821 0.00331322 0 0 +938.117 -0.000191385 0 0 +941.412 -0.00181185 0 0 +944.705 0.00930277 0 0 +947.997 0.00722765 0 0 +951.287 -0.00133574 0 0 +954.576 -0.00187935 0 0 +957.864 -0.00195813 0 0 +961.149 0.00635628 0 0 +964.434 0.0105745 0 0 +967.716 -0.0096861 0 0 +970.998 -0.146173 0 0 +974.277 0.0228179 0 0 +977.555 -0.00620699 0 0 +980.831 -0.00501621 0 0 +984.106 -0.00294747 0 0 +987.379 0.00724446 0 0 +990.651 -0.00336201 0 0 +993.921 -0.00399036 0 0 +997.189 -0.00310607 0 0 +1000.46 -0.00146471 0 0 +1003.72 -0.00124863 0 0 +1006.98 -0.000203669 0 0 +1010.25 -0.000465252 0 0 +1013.5 -0.000125955 0 0 +1016.76 -6.10143e-05 0 0 +1020.02 -9.06225e-05 0 0 +1023.27 0.000382913 0 0 +1026.53 0.000292455 0 0 +1029.78 0.000352637 0 0 +1033.03 0.000353594 0 0 +1036.28 -0.00030744 0 0 +1039.52 6.77676e-05 0 0 +1042.77 -0.000657378 0 0 +1046.01 0.000179457 0 0 +1049.25 -0.000479469 0 0 +1052.49 0.00077331 0 0 +1055.72 -0.000549439 0 0 +1058.96 -0.000788854 0 0 +1062.19 0.00112443 0 0 +1065.42 -0.000701492 0 0 +1068.65 0.000463788 0 0 +1071.88 -0.00055141 0 0 +1075.1 -0.000594337 0 0 +1078.33 0.00064356 0 0 +1081.55 -0.000170861 0 0 +1084.77 0.000782544 0 0 +1087.99 0.000626502 0 0 +1091.2 0.000368136 0 0 +1094.42 -0.000745219 0 0 +1097.63 -4.12479e-05 0 0 +1100.84 0.000488809 0 0 +1104.04 0.000520803 0 0 +1107.25 0.000102133 0 0 +1110.45 -0.00116424 0 0 +1113.66 -0.000604897 0 0 +1116.86 -0.000321545 0 0 +1120.05 -0.00046513 0 0 +1123.25 -0.000188563 0 0 +1126.44 -0.000332253 0 0 +1129.63 -0.00076919 0 0 +1132.82 0.000978652 0 0 +1136.01 0.000235286 0 0 +1139.19 -0.000184984 0 0 +1142.38 -0.00043857 0 0 +1145.56 0.00112481 0 0 +1148.74 0.000880213 0 0 +1151.91 -4.09562e-05 0 0 +[END] of [DATA] +[END] of [Spectrum] + diff --git a/data/output/B055.csv b/data/output/B055.csv new file mode 100644 index 0000000..45e4912 --- /dev/null +++ b/data/output/B055.csv @@ -0,0 +1,18 @@ +B055;362.135;365.523;368.912;372.302;375.692;379.082;382.472;385.863;389.254;392.645;396.037;399.429;402.821;406.213;409.606;412.999;416.392;419.785;423.179;426.572;429.966;433.36;436.754;440.149;443.543;446.938;450.332;453.727;457.122;460.517;463.912;467.307;470.702;474.097;477.492;480.887;484.282;487.678;491.073;494.468;497.863;501.258;504.653;508.048;511.442;514.837;518.232;521.626;525.021;528.415;531.809;535.203;538.596;541.99;545.383;548.776;552.169;555.562;558.954;562.347;565.739;569.13;572.522;575.913;579.304;582.694;586.084;589.474;592.864;596.253;599.642;603.03;606.418;609.806;613.193;616.58;619.966;623.352;626.737;630.122;633.507;636.891;640.274;643.658;647.04;650.422;653.804;657.184;660.565;663.945;667.324;670.702;674.08;677.458;680.835;684.211;687.586;690.961;694.335;697.709;701.082;704.454;707.825;711.196;714.566;717.935;721.303 +2023-04-11 20:07:27;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;-10.763668055027939;8.305640072501342;31.637826554877694;48.03477977281296;51.94904038253991;43.92046873517888;30.282275085971904;18.515274810999323;13.658622670969802;18.370134441351663;29.40783794382829;41.17537487525726;49.33643700339432;51.67851518715106;48.73493019741106;42.65339654617092;35.260104682961405;28.008926326954338;22.451500039132164;19.917594700410206;21.015444700157946;25.489475650108464;32.756025413305224;42.06435812027997;51.81698014846449;59.61323203088072;63.688920586051836;63.86911181347037;61.27553173312963;57.07070900159253;51.8052855352636;45.96670425987968;40.314358632389755;35.271352518068596;30.806216342783753;26.857135218342812;23.55330174047621;21.186169723572256;19.916316730516474;19.729283211564656;20.467222928242798;21.934437171604444;23.8973322628643;26.100847575755644;28.417908858283532;30.753125068757775;33.0712381305316;35.32927088078379;37.459065942721274;39.429152460663026;41.285050198547665;42.940430138711655;44.42081263576579;45.694708189031104;46.69307016781613;47.41973251988903;47.88970073237569;48.13385899043243;48.14158818851574;47.96181848655466;47.57067698627792;47.02983018409779;46.327729045432555;45.394914823373846;44.236406623066;42.80513495789607;41.072946813848205;39.00008846084816;36.52804689988775;33.74993494537631;31.063365858214304;28.72079005511716;26.66138106482925;24.8053096479965;22.968829922528794;21.015715961676975;18.9376609840618;16.682009982738663;14.20249000364825;11.184361647225444;6.9382609934193535;1.5423016933942209;2.483037386309892;3.0775737211799967;3.043403263161106;2.3469762513268866;0.2497067928830013;-3.6112874940500985;-10.674480324842285;-3.1305892821692707;0.7576967304456016;3.46920512317714;5.705835911986699 +2020-01-01 11:51:00;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;8.415412981193239;3.5996009682587506;31.338329488965524;48.7749513729038;53.06382072824175;45.30875693934652;31.254677437114978;17.532611772316216;10.779726040523236;15.838614015715283;28.191866228270005;40.66985662655916;49.080572139996015;51.48319799151623;48.500883933779164;42.28292181009363;34.61451378177913;26.92226639410169;20.892862896209724;18.239209735086014;19.890747869186736;25.35852991591349;33.521274713508184;43.290769850459824;53.1152687544041;60.80908367848658;64.76485312234782;64.85099453829739;62.17766314472533;57.88546252994962;52.50454031350051;46.49689704670959;40.60044195055234;35.23342648168196;30.367620364654808;25.94954293423029;22.145442973056532;19.34566939986061;17.792867190973404;17.517315105555916;18.344250258868357;20.030198711674522;22.272635497046114;24.763130908702973;27.345401827467224;29.908644493688083;32.4160050563308;34.832033933363604;37.09136990438783;39.17081374925895;41.119807229076606;42.85536849200251;44.409104644778054;45.75285556671083;46.81989555171627;47.61231414995964;48.14106135144582;48.435164813011575;48.49199342321336;48.36182514653572;48.02130221181661;47.53514341402985;46.88757443079104;46.013271428886725;44.92010426348285;43.55986252876977;41.91835732244482;39.95833581445667;37.635655630271394;35.05192901881426;32.60924548135646;30.56311367000687;28.842867983650773;27.369001440848916;25.993083685487285;24.65362166462979;23.383867807324293;22.133808226335944;20.87703253197588;19.59976702684183;18.180525704012343;16.56799949335673;14.741236089072956;12.735637877309088;10.639157063826262;8.5763589883041;6.572572712242101;4.7513722915734835;3.173216882725356;1.9092118626120613;1.0498064519790538;0.6520100533130619;0.6256365637083021 +2020-01-01 11:52:00;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;8.415412981193239;3.5996009682587506;31.338329488965524;48.7749513729038;53.06382072824175;45.30875693934652;31.254677437114978;17.532611772316216;10.779726040523236;15.838614015715283;28.191866228270005;40.66985662655916;49.080572139996015;51.48319799151623;48.500883933779164;42.28292181009363;34.61451378177913;26.92226639410169;20.892862896209724;18.239209735086014;19.890747869186736;25.35852991591349;33.521274713508184;43.290769850459824;53.1152687544041;60.80908367848658;64.76485312234782;64.85099453829739;62.17766314472533;57.88546252994962;52.50454031350051;46.49689704670959;40.60044195055234;35.23342648168196;30.367620364654808;25.94954293423029;22.145442973056532;19.34566939986061;17.792867190973404;17.517315105555916;18.344250258868357;20.030198711674522;22.272635497046114;24.763130908702973;27.345401827467224;29.908644493688083;32.4160050563308;34.832033933363604;37.09136990438783;39.17081374925895;41.119807229076606;42.85536849200251;44.409104644778054;45.75285556671083;46.81989555171627;47.61231414995964;48.14106135144582;48.435164813011575;48.49199342321336;48.36182514653572;48.02130221181661;47.53514341402985;46.88757443079104;46.013271428886725;44.92010426348285;43.55986252876977;41.91835732244482;39.95833581445667;37.635655630271394;35.05192901881426;32.60924548135646;30.56311367000687;28.842867983650773;27.369001440848916;25.993083685487285;24.65362166462979;23.383867807324293;22.133808226335944;20.87703253197588;19.59976702684183;18.180525704012343;16.56799949335673;14.741236089072956;12.735637877309088;10.639157063826262;8.5763589883041;6.572572712242101;4.7513722915734835;3.173216882725356;1.9092118626120613;1.0498064519790538;0.6520100533130619;0.6256365637083021 +2020-01-01 11:53:00;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;8.415412981193239;3.5996009682587506;31.338329488965524;48.7749513729038;53.06382072824175;45.30875693934652;31.254677437114978;17.532611772316216;10.779726040523236;15.838614015715283;28.191866228270005;40.66985662655916;49.080572139996015;51.48319799151623;48.500883933779164;42.28292181009363;34.61451378177913;26.92226639410169;20.892862896209724;18.239209735086014;19.890747869186736;25.35852991591349;33.521274713508184;43.290769850459824;53.1152687544041;60.80908367848658;64.76485312234782;64.85099453829739;62.17766314472533;57.88546252994962;52.50454031350051;46.49689704670959;40.60044195055234;35.23342648168196;30.367620364654808;25.94954293423029;22.145442973056532;19.34566939986061;17.792867190973404;17.517315105555916;18.344250258868357;20.030198711674522;22.272635497046114;24.763130908702973;27.345401827467224;29.908644493688083;32.4160050563308;34.832033933363604;37.09136990438783;39.17081374925895;41.119807229076606;42.85536849200251;44.409104644778054;45.75285556671083;46.81989555171627;47.61231414995964;48.14106135144582;48.435164813011575;48.49199342321336;48.36182514653572;48.02130221181661;47.53514341402985;46.88757443079104;46.013271428886725;44.92010426348285;43.55986252876977;41.91835732244482;39.95833581445667;37.635655630271394;35.05192901881426;32.60924548135646;30.56311367000687;28.842867983650773;27.369001440848916;25.993083685487285;24.65362166462979;23.383867807324293;22.133808226335944;20.87703253197588;19.59976702684183;18.180525704012343;16.56799949335673;14.741236089072956;12.735637877309088;10.639157063826262;8.5763589883041;6.572572712242101;4.7513722915734835;3.173216882725356;1.9092118626120613;1.0498064519790538;0.6520100533130619;0.6256365637083021 +2020-01-01 11:54:00;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;8.415412981193239;3.5996009682587506;31.338329488965524;48.7749513729038;53.06382072824175;45.30875693934652;31.254677437114978;17.532611772316216;10.779726040523236;15.838614015715283;28.191866228270005;40.66985662655916;49.080572139996015;51.48319799151623;48.500883933779164;42.28292181009363;34.61451378177913;26.92226639410169;20.892862896209724;18.239209735086014;19.890747869186736;25.35852991591349;33.521274713508184;43.290769850459824;53.1152687544041;60.80908367848658;64.76485312234782;64.85099453829739;62.17766314472533;57.88546252994962;52.50454031350051;46.49689704670959;40.60044195055234;35.23342648168196;30.367620364654808;25.94954293423029;22.145442973056532;19.34566939986061;17.792867190973404;17.517315105555916;18.344250258868357;20.030198711674522;22.272635497046114;24.763130908702973;27.345401827467224;29.908644493688083;32.4160050563308;34.832033933363604;37.09136990438783;39.17081374925895;41.119807229076606;42.85536849200251;44.409104644778054;45.75285556671083;46.81989555171627;47.61231414995964;48.14106135144582;48.435164813011575;48.49199342321336;48.36182514653572;48.02130221181661;47.53514341402985;46.88757443079104;46.013271428886725;44.92010426348285;43.55986252876977;41.91835732244482;39.95833581445667;37.635655630271394;35.05192901881426;32.60924548135646;30.56311367000687;28.842867983650773;27.369001440848916;25.993083685487285;24.65362166462979;23.383867807324293;22.133808226335944;20.87703253197588;19.59976702684183;18.180525704012343;16.56799949335673;14.741236089072956;12.735637877309088;10.639157063826262;8.5763589883041;6.572572712242101;4.7513722915734835;3.173216882725356;1.9092118626120613;1.0498064519790538;0.6520100533130619;0.6256365637083021 +2020-01-01 11:55:00;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;8.415412981193239;3.5996009682587506;31.338329488965524;48.7749513729038;53.06382072824175;45.30875693934652;31.254677437114978;17.532611772316216;10.779726040523236;15.838614015715283;28.191866228270005;40.66985662655916;49.080572139996015;51.48319799151623;48.500883933779164;42.28292181009363;34.61451378177913;26.92226639410169;20.892862896209724;18.239209735086014;19.890747869186736;25.35852991591349;33.521274713508184;43.290769850459824;53.1152687544041;60.80908367848658;64.76485312234782;64.85099453829739;62.17766314472533;57.88546252994962;52.50454031350051;46.49689704670959;40.60044195055234;35.23342648168196;30.367620364654808;25.94954293423029;22.145442973056532;19.34566939986061;17.792867190973404;17.517315105555916;18.344250258868357;20.030198711674522;22.272635497046114;24.763130908702973;27.345401827467224;29.908644493688083;32.4160050563308;34.832033933363604;37.09136990438783;39.17081374925895;41.119807229076606;42.85536849200251;44.409104644778054;45.75285556671083;46.81989555171627;47.61231414995964;48.14106135144582;48.435164813011575;48.49199342321336;48.36182514653572;48.02130221181661;47.53514341402985;46.88757443079104;46.013271428886725;44.92010426348285;43.55986252876977;41.91835732244482;39.95833581445667;37.635655630271394;35.05192901881426;32.60924548135646;30.56311367000687;28.842867983650773;27.369001440848916;25.993083685487285;24.65362166462979;23.383867807324293;22.133808226335944;20.87703253197588;19.59976702684183;18.180525704012343;16.56799949335673;14.741236089072956;12.735637877309088;10.639157063826262;8.5763589883041;6.572572712242101;4.7513722915734835;3.173216882725356;1.9092118626120613;1.0498064519790538;0.6520100533130619;0.6256365637083021 +2020-01-01 11:56:00;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;8.415412981193239;3.5996009682587506;31.338329488965524;48.7749513729038;53.06382072824175;45.30875693934652;31.254677437114978;17.532611772316216;10.779726040523236;15.838614015715283;28.191866228270005;40.66985662655916;49.080572139996015;51.48319799151623;48.500883933779164;42.28292181009363;34.61451378177913;26.92226639410169;20.892862896209724;18.239209735086014;19.890747869186736;25.35852991591349;33.521274713508184;43.290769850459824;53.1152687544041;60.80908367848658;64.76485312234782;64.85099453829739;62.17766314472533;57.88546252994962;52.50454031350051;46.49689704670959;40.60044195055234;35.23342648168196;30.367620364654808;25.94954293423029;22.145442973056532;19.34566939986061;17.792867190973404;17.517315105555916;18.344250258868357;20.030198711674522;22.272635497046114;24.763130908702973;27.345401827467224;29.908644493688083;32.4160050563308;34.832033933363604;37.09136990438783;39.17081374925895;41.119807229076606;42.85536849200251;44.409104644778054;45.75285556671083;46.81989555171627;47.61231414995964;48.14106135144582;48.435164813011575;48.49199342321336;48.36182514653572;48.02130221181661;47.53514341402985;46.88757443079104;46.013271428886725;44.92010426348285;43.55986252876977;41.91835732244482;39.95833581445667;37.635655630271394;35.05192901881426;32.60924548135646;30.56311367000687;28.842867983650773;27.369001440848916;25.993083685487285;24.65362166462979;23.383867807324293;22.133808226335944;20.87703253197588;19.59976702684183;18.180525704012343;16.56799949335673;14.741236089072956;12.735637877309088;10.639157063826262;8.5763589883041;6.572572712242101;4.7513722915734835;3.173216882725356;1.9092118626120613;1.0498064519790538;0.6520100533130619;0.6256365637083021 +2020-01-01 12:08:00;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;8.415412981193239;3.5996009682587506;31.338329488965524;48.7749513729038;53.06382072824175;45.30875693934652;31.254677437114978;17.532611772316216;10.779726040523236;15.838614015715283;28.191866228270005;40.66985662655916;49.080572139996015;51.48319799151623;48.500883933779164;42.28292181009363;34.61451378177913;26.92226639410169;20.892862896209724;18.239209735086014;19.890747869186736;25.35852991591349;33.521274713508184;43.290769850459824;53.1152687544041;60.80908367848658;64.76485312234782;64.85099453829739;62.17766314472533;57.88546252994962;52.50454031350051;46.49689704670959;40.60044195055234;35.23342648168196;30.367620364654808;25.94954293423029;22.145442973056532;19.34566939986061;17.792867190973404;17.517315105555916;18.344250258868357;20.030198711674522;22.272635497046114;24.763130908702973;27.345401827467224;29.908644493688083;32.4160050563308;34.832033933363604;37.09136990438783;39.17081374925895;41.119807229076606;42.85536849200251;44.409104644778054;45.75285556671083;46.81989555171627;47.61231414995964;48.14106135144582;48.435164813011575;48.49199342321336;48.36182514653572;48.02130221181661;47.53514341402985;46.88757443079104;46.013271428886725;44.92010426348285;43.55986252876977;41.91835732244482;39.95833581445667;37.635655630271394;35.05192901881426;32.60924548135646;30.56311367000687;28.842867983650773;27.369001440848916;25.993083685487285;24.65362166462979;23.383867807324293;22.133808226335944;20.87703253197588;19.59976702684183;18.180525704012343;16.56799949335673;14.741236089072956;12.735637877309088;10.639157063826262;8.5763589883041;6.572572712242101;4.7513722915734835;3.173216882725356;1.9092118626120613;1.0498064519790538;0.6520100533130619;0.6256365637083021 +2020-01-01 11:51:00;8.417737297758135;3.6003210616146095;31.338272439002946;48.77492727918919;53.06380857297471;45.30874684378469;31.254671851695033;17.53261532414694;10.779672643743828;15.838631955112836;28.191967140583625;40.66995055518302;49.08065786270199;51.48328009262055;48.50097581388598;42.28304833654381;34.61469193371904;26.922484942198942;20.893064894784953;18.239370031948738;19.89097470286485;25.358833593133255;33.52153932962637;43.290956605696884;53.11539213296727;60.809175752703325;64.76493825822062;64.8510953221729;62.17781191356055;57.88568438935276;52.50491331016351;46.49746676033152;40.60118285600951;35.23435495825925;30.368672337783654;25.950675240662438;22.146517887380686;19.346519036982766;17.793509426865167;17.5179082380076;18.344992365267892;20.03118327542923;22.273787745746976;24.764244860684187;27.346338145237937;29.90948002948232;32.416802867203714;34.832844886797844;37.09223417373295;39.17173190982804;41.12081715938511;42.85653714763779;44.410469153844005;45.754426847107766;46.82171758485793;47.614446627227814;48.14370668978048;48.43825993770717;48.495229261930916;48.36508733085604;48.02462201317626;47.53850396910848;46.89102990740052;46.016831613096585;44.92375304290284;43.56351080009117;41.92204195611228;39.96199596378572;37.63919076941768;35.05530536201176;32.61203701781444;30.56541436137355;28.845430933487766;27.37208881829137;25.996611916755132;24.65729084277052;23.38739437277862;22.137022087802627;20.879814854326426;19.602063469247692;18.18186550000487;16.567816898314867;14.738317891495022;12.727998959540258;10.623177605896181;8.54560060332246;6.51966071209112;4.6657839884785455;3.036312907848326;1.6820459455679468;0.6921106974450838;0.12359578075040828;-0.09367329985645387;-0.031341689825133606;0.23717164699237966;0.6997800604297433;1.2979843274680154;2.0657283515050686;2.9615094560290176;3.9886574343032963;5.048029170775037;6.1827566231801345;7.400535839426023;8.609660807489144;9.866618625112752;11.165875582893802;12.525868733319928 +2020-01-01 11:52:00;8.417737297758135;3.6003210616146095;31.338272439002946;48.77492727918919;53.06380857297471;45.30874684378469;31.254671851695033;17.53261532414694;10.779672643743828;15.838631955112836;28.191967140583625;40.66995055518302;49.08065786270199;51.48328009262055;48.50097581388598;42.28304833654381;34.61469193371904;26.922484942198942;20.893064894784953;18.239370031948738;19.89097470286485;25.358833593133255;33.52153932962637;43.290956605696884;53.11539213296727;60.809175752703325;64.76493825822062;64.8510953221729;62.17781191356055;57.88568438935276;52.50491331016351;46.49746676033152;40.60118285600951;35.23435495825925;30.368672337783654;25.950675240662438;22.146517887380686;19.346519036982766;17.793509426865167;17.5179082380076;18.344992365267892;20.03118327542923;22.273787745746976;24.764244860684187;27.346338145237937;29.90948002948232;32.416802867203714;34.832844886797844;37.09223417373295;39.17173190982804;41.12081715938511;42.85653714763779;44.410469153844005;45.754426847107766;46.82171758485793;47.614446627227814;48.14370668978048;48.43825993770717;48.495229261930916;48.36508733085604;48.02462201317626;47.53850396910848;46.89102990740052;46.016831613096585;44.92375304290284;43.56351080009117;41.92204195611228;39.96199596378572;37.63919076941768;35.05530536201176;32.61203701781444;30.56541436137355;28.845430933487766;27.37208881829137;25.996611916755132;24.65729084277052;23.38739437277862;22.137022087802627;20.879814854326426;19.602063469247692;18.18186550000487;16.567816898314867;14.738317891495022;12.727998959540258;10.623177605896181;8.54560060332246;6.51966071209112;4.6657839884785455;3.036312907848326;1.6820459455679468;0.6921106974450838;0.12359578075040828;-0.09367329985645387;-0.031341689825133606;0.23717164699237966;0.6997800604297433;1.2979843274680154;2.0657283515050686;2.9615094560290176;3.9886574343032963;5.048029170775037;6.1827566231801345;7.400535839426023;8.609660807489144;9.866618625112752;11.165875582893802;12.525868733319928 +2020-01-01 11:53:00;8.417737297758135;3.6003210616146095;31.338272439002946;48.77492727918919;53.06380857297471;45.30874684378469;31.254671851695033;17.53261532414694;10.779672643743828;15.838631955112836;28.191967140583625;40.66995055518302;49.08065786270199;51.48328009262055;48.50097581388598;42.28304833654381;34.61469193371904;26.922484942198942;20.893064894784953;18.239370031948738;19.89097470286485;25.358833593133255;33.52153932962637;43.290956605696884;53.11539213296727;60.809175752703325;64.76493825822062;64.8510953221729;62.17781191356055;57.88568438935276;52.50491331016351;46.49746676033152;40.60118285600951;35.23435495825925;30.368672337783654;25.950675240662438;22.146517887380686;19.346519036982766;17.793509426865167;17.5179082380076;18.344992365267892;20.03118327542923;22.273787745746976;24.764244860684187;27.346338145237937;29.90948002948232;32.416802867203714;34.832844886797844;37.09223417373295;39.17173190982804;41.12081715938511;42.85653714763779;44.410469153844005;45.754426847107766;46.82171758485793;47.614446627227814;48.14370668978048;48.43825993770717;48.495229261930916;48.36508733085604;48.02462201317626;47.53850396910848;46.89102990740052;46.016831613096585;44.92375304290284;43.56351080009117;41.92204195611228;39.96199596378572;37.63919076941768;35.05530536201176;32.61203701781444;30.56541436137355;28.845430933487766;27.37208881829137;25.996611916755132;24.65729084277052;23.38739437277862;22.137022087802627;20.879814854326426;19.602063469247692;18.18186550000487;16.567816898314867;14.738317891495022;12.727998959540258;10.623177605896181;8.54560060332246;6.51966071209112;4.6657839884785455;3.036312907848326;1.6820459455679468;0.6921106974450838;0.12359578075040828;-0.09367329985645387;-0.031341689825133606;0.23717164699237966;0.6997800604297433;1.2979843274680154;2.0657283515050686;2.9615094560290176;3.9886574343032963;5.048029170775037;6.1827566231801345;7.400535839426023;8.609660807489144;9.866618625112752;11.165875582893802;12.525868733319928 +2020-01-01 11:54:00;8.417737297758135;3.6003210616146095;31.338272439002946;48.77492727918919;53.06380857297471;45.30874684378469;31.254671851695033;17.53261532414694;10.779672643743828;15.838631955112836;28.191967140583625;40.66995055518302;49.08065786270199;51.48328009262055;48.50097581388598;42.28304833654381;34.61469193371904;26.922484942198942;20.893064894784953;18.239370031948738;19.89097470286485;25.358833593133255;33.52153932962637;43.290956605696884;53.11539213296727;60.809175752703325;64.76493825822062;64.8510953221729;62.17781191356055;57.88568438935276;52.50491331016351;46.49746676033152;40.60118285600951;35.23435495825925;30.368672337783654;25.950675240662438;22.146517887380686;19.346519036982766;17.793509426865167;17.5179082380076;18.344992365267892;20.03118327542923;22.273787745746976;24.764244860684187;27.346338145237937;29.90948002948232;32.416802867203714;34.832844886797844;37.09223417373295;39.17173190982804;41.12081715938511;42.85653714763779;44.410469153844005;45.754426847107766;46.82171758485793;47.614446627227814;48.14370668978048;48.43825993770717;48.495229261930916;48.36508733085604;48.02462201317626;47.53850396910848;46.89102990740052;46.016831613096585;44.92375304290284;43.56351080009117;41.92204195611228;39.96199596378572;37.63919076941768;35.05530536201176;32.61203701781444;30.56541436137355;28.845430933487766;27.37208881829137;25.996611916755132;24.65729084277052;23.38739437277862;22.137022087802627;20.879814854326426;19.602063469247692;18.18186550000487;16.567816898314867;14.738317891495022;12.727998959540258;10.623177605896181;8.54560060332246;6.51966071209112;4.6657839884785455;3.036312907848326;1.6820459455679468;0.6921106974450838;0.12359578075040828;-0.09367329985645387;-0.031341689825133606;0.23717164699237966;0.6997800604297433;1.2979843274680154;2.0657283515050686;2.9615094560290176;3.9886574343032963;5.048029170775037;6.1827566231801345;7.400535839426023;8.609660807489144;9.866618625112752;11.165875582893802;12.525868733319928 +2020-01-01 11:55:00;8.417737297758135;3.6003210616146095;31.338272439002946;48.77492727918919;53.06380857297471;45.30874684378469;31.254671851695033;17.53261532414694;10.779672643743828;15.838631955112836;28.191967140583625;40.66995055518302;49.08065786270199;51.48328009262055;48.50097581388598;42.28304833654381;34.61469193371904;26.922484942198942;20.893064894784953;18.239370031948738;19.89097470286485;25.358833593133255;33.52153932962637;43.290956605696884;53.11539213296727;60.809175752703325;64.76493825822062;64.8510953221729;62.17781191356055;57.88568438935276;52.50491331016351;46.49746676033152;40.60118285600951;35.23435495825925;30.368672337783654;25.950675240662438;22.146517887380686;19.346519036982766;17.793509426865167;17.5179082380076;18.344992365267892;20.03118327542923;22.273787745746976;24.764244860684187;27.346338145237937;29.90948002948232;32.416802867203714;34.832844886797844;37.09223417373295;39.17173190982804;41.12081715938511;42.85653714763779;44.410469153844005;45.754426847107766;46.82171758485793;47.614446627227814;48.14370668978048;48.43825993770717;48.495229261930916;48.36508733085604;48.02462201317626;47.53850396910848;46.89102990740052;46.016831613096585;44.92375304290284;43.56351080009117;41.92204195611228;39.96199596378572;37.63919076941768;35.05530536201176;32.61203701781444;30.56541436137355;28.845430933487766;27.37208881829137;25.996611916755132;24.65729084277052;23.38739437277862;22.137022087802627;20.879814854326426;19.602063469247692;18.18186550000487;16.567816898314867;14.738317891495022;12.727998959540258;10.623177605896181;8.54560060332246;6.51966071209112;4.6657839884785455;3.036312907848326;1.6820459455679468;0.6921106974450838;0.12359578075040828;-0.09367329985645387;-0.031341689825133606;0.23717164699237966;0.6997800604297433;1.2979843274680154;2.0657283515050686;2.9615094560290176;3.9886574343032963;5.048029170775037;6.1827566231801345;7.400535839426023;8.609660807489144;9.866618625112752;11.165875582893802;12.525868733319928 +2020-01-01 11:56:00;8.417737297758135;3.6003210616146095;31.338272439002946;48.77492727918919;53.06380857297471;45.30874684378469;31.254671851695033;17.53261532414694;10.779672643743828;15.838631955112836;28.191967140583625;40.66995055518302;49.08065786270199;51.48328009262055;48.50097581388598;42.28304833654381;34.61469193371904;26.922484942198942;20.893064894784953;18.239370031948738;19.89097470286485;25.358833593133255;33.52153932962637;43.290956605696884;53.11539213296727;60.809175752703325;64.76493825822062;64.8510953221729;62.17781191356055;57.88568438935276;52.50491331016351;46.49746676033152;40.60118285600951;35.23435495825925;30.368672337783654;25.950675240662438;22.146517887380686;19.346519036982766;17.793509426865167;17.5179082380076;18.344992365267892;20.03118327542923;22.273787745746976;24.764244860684187;27.346338145237937;29.90948002948232;32.416802867203714;34.832844886797844;37.09223417373295;39.17173190982804;41.12081715938511;42.85653714763779;44.410469153844005;45.754426847107766;46.82171758485793;47.614446627227814;48.14370668978048;48.43825993770717;48.495229261930916;48.36508733085604;48.02462201317626;47.53850396910848;46.89102990740052;46.016831613096585;44.92375304290284;43.56351080009117;41.92204195611228;39.96199596378572;37.63919076941768;35.05530536201176;32.61203701781444;30.56541436137355;28.845430933487766;27.37208881829137;25.996611916755132;24.65729084277052;23.38739437277862;22.137022087802627;20.879814854326426;19.602063469247692;18.18186550000487;16.567816898314867;14.738317891495022;12.727998959540258;10.623177605896181;8.54560060332246;6.51966071209112;4.6657839884785455;3.036312907848326;1.6820459455679468;0.6921106974450838;0.12359578075040828;-0.09367329985645387;-0.031341689825133606;0.23717164699237966;0.6997800604297433;1.2979843274680154;2.0657283515050686;2.9615094560290176;3.9886574343032963;5.048029170775037;6.1827566231801345;7.400535839426023;8.609660807489144;9.866618625112752;11.165875582893802;12.525868733319928 +2020-01-01 12:08:00;8.417737297758135;3.6003210616146095;31.338272439002946;48.77492727918919;53.06380857297471;45.30874684378469;31.254671851695033;17.53261532414694;10.779672643743828;15.838631955112836;28.191967140583625;40.66995055518302;49.08065786270199;51.48328009262055;48.50097581388598;42.28304833654381;34.61469193371904;26.922484942198942;20.893064894784953;18.239370031948738;19.89097470286485;25.358833593133255;33.52153932962637;43.290956605696884;53.11539213296727;60.809175752703325;64.76493825822062;64.8510953221729;62.17781191356055;57.88568438935276;52.50491331016351;46.49746676033152;40.60118285600951;35.23435495825925;30.368672337783654;25.950675240662438;22.146517887380686;19.346519036982766;17.793509426865167;17.5179082380076;18.344992365267892;20.03118327542923;22.273787745746976;24.764244860684187;27.346338145237937;29.90948002948232;32.416802867203714;34.832844886797844;37.09223417373295;39.17173190982804;41.12081715938511;42.85653714763779;44.410469153844005;45.754426847107766;46.82171758485793;47.614446627227814;48.14370668978048;48.43825993770717;48.495229261930916;48.36508733085604;48.02462201317626;47.53850396910848;46.89102990740052;46.016831613096585;44.92375304290284;43.56351080009117;41.92204195611228;39.96199596378572;37.63919076941768;35.05530536201176;32.61203701781444;30.56541436137355;28.845430933487766;27.37208881829137;25.996611916755132;24.65729084277052;23.38739437277862;22.137022087802627;20.879814854326426;19.602063469247692;18.18186550000487;16.567816898314867;14.738317891495022;12.727998959540258;10.623177605896181;8.54560060332246;6.51966071209112;4.6657839884785455;3.036312907848326;1.6820459455679468;0.6921106974450838;0.12359578075040828;-0.09367329985645387;-0.031341689825133606;0.23717164699237966;0.6997800604297433;1.2979843274680154;2.0657283515050686;2.9615094560290176;3.9886574343032963;5.048029170775037;6.1827566231801345;7.400535839426023;8.609660807489144;9.866618625112752;11.165875582893802;12.525868733319928 +2023-04-11 20:11:32;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;-10.763668055027939;8.305640072501342;31.637826554877694;48.03477977281296;51.94904038253991;43.92046873517888;30.282275085971904;18.515274810999323;13.658622670969802;18.370134441351663;29.40783794382829;41.17537487525726;49.33643700339432;51.67851518715106;48.73493019741106;42.65339654617092;35.260104682961405;28.008926326954338;22.451500039132164;19.917594700410206;21.015444700157946;25.489475650108464;32.756025413305224;42.06435812027997;51.81698014846449;59.61323203088072;63.688920586051836;63.86911181347037;61.27553173312963;57.07070900159253;51.8052855352636;45.96670425987968;40.314358632389755;35.271352518068596;30.806216342783753;26.857135218342812;23.55330174047621;21.186169723572256;19.916316730516474;19.729283211564656;20.467222928242798;21.934437171604444;23.8973322628643;26.100847575755644;28.417908858283532;30.753125068757775;33.0712381305316;35.32927088078379;37.459065942721274;39.429152460663026;41.285050198547665;42.940430138711655;44.42081263576579;45.694708189031104;46.69307016781613;47.41973251988903;47.88970073237569;48.13385899043243;48.14158818851574;47.96181848655466;47.57067698627792;47.02983018409779;46.327729045432555;45.394914823373846;44.236406623066;42.80513495789607;41.072946813848205;39.00008846084816;36.52804689988775;33.74993494537631;31.063365858214304;28.72079005511716;26.66138106482925;24.8053096479965;22.968829922528794;21.015715961676975;18.9376609840618;16.682009982738663;14.20249000364825;11.184361647225444;6.9382609934193535;1.5423016933942209;2.483037386309892;3.0775737211799967;3.043403263161106;2.3469762513268866;0.2497067928830013;-3.6112874940500985;-10.674480324842285;-3.1305892821692707;0.7576967304456016;3.46920512317714;5.705835911986699 +2023-04-11 20:12:33;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;1.0;-10.763668055027939;8.305640072501342;31.637826554877694;48.03477977281296;51.94904038253991;43.92046873517888;30.282275085971904;18.515274810999323;13.658622670969802;18.370134441351663;29.40783794382829;41.17537487525726;49.33643700339432;51.67851518715106;48.73493019741106;42.65339654617092;35.260104682961405;28.008926326954338;22.451500039132164;19.917594700410206;21.015444700157946;25.489475650108464;32.756025413305224;42.06435812027997;51.81698014846449;59.61323203088072;63.688920586051836;63.86911181347037;61.27553173312963;57.07070900159253;51.8052855352636;45.96670425987968;40.314358632389755;35.271352518068596;30.806216342783753;26.857135218342812;23.55330174047621;21.186169723572256;19.916316730516474;19.729283211564656;20.467222928242798;21.934437171604444;23.8973322628643;26.100847575755644;28.417908858283532;30.753125068757775;33.0712381305316;35.32927088078379;37.459065942721274;39.429152460663026;41.285050198547665;42.940430138711655;44.42081263576579;45.694708189031104;46.69307016781613;47.41973251988903;47.88970073237569;48.13385899043243;48.14158818851574;47.96181848655466;47.57067698627792;47.02983018409779;46.327729045432555;45.394914823373846;44.236406623066;42.80513495789607;41.072946813848205;39.00008846084816;36.52804689988775;33.74993494537631;31.063365858214304;28.72079005511716;26.66138106482925;24.8053096479965;22.968829922528794;21.015715961676975;18.9376609840618;16.682009982738663;14.20249000364825;11.184361647225444;6.9382609934193535;1.5423016933942209;2.483037386309892;3.0775737211799967;3.043403263161106;2.3469762513268866;0.2497067928830013;-3.6112874940500985;-10.674480324842285;-3.1305892821692707;0.7576967304456016;3.46920512317714;5.705835911986699 \ No newline at end of file diff --git a/dataplot.py b/dataplot.py new file mode 100644 index 0000000..8c737c2 --- /dev/null +++ b/dataplot.py @@ -0,0 +1,466 @@ +# import numpy as np + +from pathlib import Path + + +class DataPlot(): + ''' + 从文件读取数据,出来成待显示数据 + ''' + + # def __init__(self, mypanel, ): + def __init__(self, ): + # self.mypanel = mypanel + # self.__eventManager = eventManger + # self.dataSaveFile = DATA_FNAME_WITHOUT_WATER + # self.axes_title = "Water Attenuation Coefficient" + # self.axes_xlabel = "Wavelength (nm)" + # self.axes_ylabel = "Attenuation Coefficient m(-1)" + # self.axes_title = "Attenuation Coefficient Demo" + self.demo_time = '' + self.demo_wl = [] # 纯水 + self.demo_data = [] # 纯水 + + self.wavelength = None + self.data_one = None + self.data_multi = None + # self.mode = "one" # multi + # self.begin_line = None + # self.line_interval = None + self.fpath :Path = Path() + self.total_lines = 0 + self.token = ";" + # self.MPL = myPanel.MPL_Panel(self) # 调用自己建立的 panel 类 + # self.Figure = self.MPL.Figure + # self.axes = self.MPL.axes + # self.FigureCanvas = self.MPL.FigureCanvas + def set_file_path( self, fpath:Path ): + self.fpath = fpath + pass + + def set_wavelength(self): + pass + + # def set_mode(self, mode ="one"): + # self.mode = mode + # pass + + def set_token(self, token =";"): + self.token = token + pass + + def set_begin_line( self, lineno = 0 ): + self.begin_line = lineno + pass + + def set_line_interval( self, line_interval = 0 ): + self.line_interval = line_interval + pass + + def get_total_lines( self, ): + ''' 大文件 ''' + count = 0 + thefile = open( self.fpath, 'rb') + while True: + buffer = thefile.read(8192*1024) + if not buffer: + break + count += buffer.count(b'\n') + self.total_lines = count + 1 + + def get_wavelength_from_file( self, ): + tmp = self.get_first_line() + self.wavelength = tmp.split(self.token)[1:] + pass + + def get_reverse_x_lineno( self, x ): + line = self.__get_reverse_x_lineno(x) + line = line.split(self.token) + return line[0], line[1:] + pass + + def get_multi_by_x_m_n( self, x,m,n ): + # res_time = [] + # res_lines = [] + lines = self.__get_reverse_x_m_n_line(x,m,n) + # print(f'+++++ {lines}') + # for i in range(len(lines)): + # ln = + # res_time.append( lines[i] [0] ) + # res_lines.append( lines[i][1:] ) + # return res_time, res_lines + return lines + pass + + def __get_reverse_x_lineno(self, x): + """ + 获得倒数第x行 + """ + try: + # filesize = os.path.getsize(self.fpath) + filesize = self.fpath.stat().st_size + if filesize == 0: + return None + else: + with open(self.fpath, 'rb') as fp: # to use seek from end, must use mode 'rb' + offset = -8 # initialize offset + while -offset < filesize: # offset cannot exceed file size + fp.seek(offset, 2) # read # offset chars from eof(represent by number '2') + lines = fp.readlines() # read from fp to eof + if len(lines) >= x+1: # if contains at least 2 lines + return lines[-1*x] # then last line is totally included + else: + offset *= 2 # enlarge offset + fp.seek(0) + lines = fp.readlines() + if len(lines) < x: + raise Exception("行数有误,请重试") + return lines[-1*x] + except FileNotFoundError: + print(self.fpath.name + ' not found!') + return None + + def __get_reverse_x_m_n_line(self, x, m=1, n=1): + """ + 获得倒数第x行, 间隔m行, 共取n个行 + """ + print(f'__get_reverse_x_m_n_line {x} {self.fpath}') + min_lines = x + m*n + res_lines = [] + try: + # filesize = os.path.getsize(self.fpath) + filesize = self.fpath.stat().st_size + if filesize == 0: + return None + else: + with open(self.fpath, 'rb') as fp: # to use seek from end, must use mode 'rb'x + offset = -8 # initialize offset + while -offset < filesize: # offset cannot exceed file size + fp.seek( offset, 2 ) # read # offset chars from eof(represent by number '2') + lines = fp.readlines() # read from fp to eof + if len(lines) >= min_lines+1 : + for i in range(n): + res_lines.append( lines[-1*(x+m*i)].decode()) + return res_lines + else: + offset *= 2 # enlarge offset + fp.seek( 0 ) + lines = fp.readlines( ) + if len(lines) < min_lines: + raise Exception("行数有误,请重试") + for i in range(n): + res_lines.append( lines[-1*(x+m*i)].decode()) + return res_lines + print(res_lines) + except FileNotFoundError: + print(self.fpath.name + ' not found!') + return None + + def get_first_line(self, ): + firstline = '' + with open(self.fpath, 'rb') as fp: # to use seek from end, must use mode 'rb'x + firstline = fp.readline() + return firstline.decode() + + def get_last_line(self,filename:Path): + """ + 获得最后一行 + :param filename: file name + :return: last line or None for empty file + """ + try: + filesize = filename.stat().st_size + if filesize == 0: + return None + else: + with open(filename, 'rb') as fp: # to use seek from end, must use mode 'rb' + offset = -8 # initialize offset + while -offset < filesize: # offset cannot exceed file size + fp.seek(offset, 2) # read # offset chars from eof(represent by number '2') + lines = fp.readlines() # read from fp to eof + if len(lines) >= 2: # if contains at least 2 lines + return lines[-1] # then last line is totally included + else: + offset *= 2 # enlarge offset + fp.seek(0) + lines = fp.readlines() + return lines[-1] + except FileNotFoundError: + print(filename + ' not found!') + return None + + def tail(file, taillines=500, return_str=True, avg_line_length=None): + """ + 大文件的尾行,小文件会导致报错 + taillines : 读取尾部多少行 + avg_line_length:每行字符平均数, + return_str:返回类型,默认为字符串,False为列表。 + offset:每次循环相对文件末尾指针偏移数 + f.tell() 当前指针位置 + f.seek(a,b) a 偏移量, b:0 1 2 ,文件头 当前位置 文件尾部 + """ + with open(file, errors='ignore') as f: + if not avg_line_length: + f.seek(0, 2) + f.seek(f.tell() - 3000) + avg_line_length = int(3000 / len(f.readlines())) + 10 + f.seek(0, 2) + end_pointer = f.tell() + offset = taillines * avg_line_length + if offset > end_pointer: + f.seek(0, 0) + lines = f.readlines()[-taillines:] + return "".join(lines) if return_str else lines + offset_init = offset + i = 1 + while len(f.readlines()) < taillines: + location = f.tell() - offset + f.seek(location) + i += 1 + offset = i * offset_init + if f.tell() - offset < 0: + f.seek(0, 0) + break + else: + f.seek(end_pointer - offset) + lines = f.readlines() + if len(lines) >= taillines: + lines = lines[-taillines:] + + return "".join(lines) if return_str else lines + + + # def makeMsg(self,key,value): + # """ + # 事件对象:制造事件 + # 将事件写入event 并send + # """ + # # event = eventManager.Event( type_ = eventManager.EVENT_MSG) + # event.dict[key] = value + + # # 发送事件 + # self.__eventManager.SendEvent(event) + +if __name__ == "__main__": + d = DataPlot() + + + + # def plot_demo( self, time_, data ,wavelength): + # ''' + # @ 根据数据画demo曲线 + # ''' + # x = np.array( wavelength ).astype(np.float) + # datetime_ = str(time_ ) + # y = np.array(data).astype(np.float) + + # self.mypanel.axes.clear() # 清空上次画的内容 + # self.mypanel.axes.set_title( self.axes_title ) + # self.mypanel.axes.set_xlabel( self.axes_xlabel ) + # self.mypanel.axes.set_ylabel( self.axes_ylabel ) + + # self.mypanel.axes.plot(x, y, color="green", linewidth=0.5 , label=datetime_ ) + # self.mypanel.axes.legend() + # self.mypanel.axes.grid(True) + # self.mypanel.FigureCanvas.draw() + + # def plot_one( self, time_, data ,wavelength): + # ''' + # @ 根据数据画一条曲线 + # @ 参数 data + # ''' + # x = np.array( wavelength ).astype(np.float) + # datetime_ = str(time_ ) + # y = np.array(data).astype(np.float) + + # self.mypanel.axes.clear() # 清空上次画的内容 + # self.mypanel.axes.set_title( self.axes_title ) + # self.mypanel.axes.set_xlabel( self.axes_xlabel ) + # self.mypanel.axes.set_ylabel( self.axes_ylabel ) + + # self.mypanel.axes.plot(x, y, color="green", linewidth=0.5 , label=datetime_ ) + # self.mypanel.axes.legend() + # self.mypanel.axes.grid(True) + # self.mypanel.FigureCanvas.draw() + + # def plotOne( self, data ): + # ''' + # @ 根据数据画一条曲线 + # @ 参数 data + # ''' + # x = np.array( self.wavelength ).astype(np.float) + + # datetime_ = data[0] + # y = np.array(data[1:]).astype(np.float) + + # self.mypanel.axes.clear() # 清空上次画的内容 + # self.mypanel.axes.set_title( self.axes_title ) + # self.mypanel.axes.set_xlabel( self.axes_xlabel ) + # self.mypanel.axes.set_ylabel( self.axes_ylabel ) + + # self.mypanel.axes.plot(x, y, color="green", linewidth=0.5 , label=datetime_ ) + # self.mypanel.axes.legend() + # self.mypanel.axes.grid(True) + # self.mypanel.FigureCanvas.draw() + + + # def OnPlot(self, wl, fpath ): + # """ + # * 查看历史曲线 + # * 默认从最后一条记录读取 + # """ + # temp = self.__get_last_line( fpath ).decode().split(TOKEN) + # time_ = temp[0] + # data = temp[1:] + + # # 加判断波长 + # print(fpath) + + # if len(data) > len( wl ): + # for i in range( len(data)-len(wl) ): + # data.pop() + + # self.plot_one( time_ , data, wl ) + + + # def plotSeven(self,wavelength,d): + # ''' + # * 根据数据画七条曲线 + # * 兼容数量不够七条的 + # ''' + # # myDebug.MyDebug.log_info( ":::::::::::: Class : %s -> Function : get_file_list " % ( __name__, ) ) + # # myDebug.MyDebug.log_ctl( " d len : %s " % ( len(d), ) ) + # # myDebug.MyDebug.log_ctl( " d : %s " % ( d, ) ) + + # x = np.array( wavelength ).astype(np.float) + # self.mypanel.axes.clear() # 清空上次画的内容 + # self.mypanel.axes.set_title( self.axes_title ) + # self.mypanel.axes.set_xlabel( self.axes_xlabel ) + # self.mypanel.axes.set_ylabel( self.axes_ylabel ) + + # # 处理 data + # length = len(d) + # data = [] + # for s in d: + # ss = s.split(TOKEN) + # ss0 = ss[0] + # ss1 = ss[1:] + # # 去掉尾部多余 + # if len(ss1) > len( wavelength ): + # for i in range( len(ss1)-len(wavelength) ): + # ss1.pop() + # data.append( [ss0, ss1] ) + + # print( " data : %s " % ( len(data) , ) ) + + # if length >=1 : + # print( " data[0][0] %s " % (data[0][0],)) + + # d0 = data[0][0] + # y0 =np.array(data[0][1]).astype(np.float) + # self.mypanel.axes.plot(x, y0, 'r', linewidth=0.5 , label = d0 ) + + # # len(data) =2 + # if len(data) >=2 : + # d1 = data[1][0] + # y1 =np.array(data[1][1]).astype(np.float) + # self.mypanel.axes.plot(x, y1, color='orange', linewidth=0.5 , label=d1 ) + # # len(data) =3 + # if len(data) >=3 : + # d2 = data[2][0] + # y2 =np.array(data[2][1]).astype(np.float) + # self.mypanel.axes.plot(x, y2, 'y', linewidth=0.5 , label=d2 ) + # # len(data) =4 + # if len(data) >=4 : + # d3 = data[3][0] + # y3 =np.array(data[3][1]).astype(np.float) + # self.mypanel.axes.plot(x, y3, 'g', linewidth=0.5 , label=d3 ) + # # len(data) =5 + # if len(data) >=5 : + # d4 = data[4][0] + # y4 =np.array(data[4][1]).astype(np.float) + # self.mypanel.axes.plot(x, y4, 'c', linewidth=0.5 , label=d4 ) + # # len(data) =6 + # if len(data) >=6 : + # d5 = data[5][0] + # y5 =np.array(data[5][1]).astype(np.float) + # self.mypanel.axes.plot(x, y5, 'b', linewidth=0.5 , label=d5 ) + # # len(data) =7 + # if len(data) >=7 : + # d6 = data[6][0] + # y6 =np.array(data[6][1]).astype(np.float) + # self.mypanel.axes.plot(x, y6, color='purple', linewidth=0.5 , label=d6 ) + + # self.mypanel.axes.legend() + # self.mypanel.axes.grid( True ) + # self.mypanel.FigureCanvas.draw() + + + # def OnPlot_7(self, wl, fpath): + # """ + # 最后间隔七条 + # 默认间隔数为1 + # """ + # result_line = [] + # count = 0 + # thefile = open( fpath, 'rb') + # while True: + # buffer = thefile.read(8192*1024) + # if not buffer: + # break + # count += buffer.count(b'\n') + # count = count + 1 + # self.makeMsg(1, u" 文件共有 " + str(count) + " 行" ) + # # self.statusBar.SetStatusText(u" 文件共有 "+str(count)+" 行",0) + # # 判断文件是否已有数据 + # if count == 0: + # #print('文件没有内容!') + # self.makeMsg(2, u"数据文件没有记录!" ) + # # with wx.MessageDialog(self, u"数据文件没有记录!", u"错误提示", wx.OK )as dlg: + # # dlg.ShowModal() + # elif count < 8: + # for i in range(count-1): + # result_line.append(linecache.getline( fpath, count-i).strip("\n")) + # else: + # for i in range(7): + # result_line.append(linecache.getline( fpath, count-i).strip("\n")) + + # # 画7天的图像 + # thefile.close() + # self.plotSeven( wl,result_line ) + + # def OnPlot_D(self, wl,fpath, interval, begin): + # """ + # 指定位置间隔七条 + # 考虑数据是否够 + # """ + # # print( "i am plot d") + # # self.readConfig() + # result_line = [] + # count = 0 + # thefile = open( fpath, 'rb') + # while True: + # buffer = thefile.read(8192*1024) + # if not buffer: + # break + # count += buffer.count(b'\n') + # count = count + 1 + # self.makeMsg(1, u" 文件共有 "+str(count)+" 行" ) + + # # 判断文件绘图参数设置是否正确 + # if count == 0: + # #print('文件没有内容!') + # self.makeMsg(2, u"数据文件没有记录!" ) + # # with wx.MessageDialog(self, u"数据文件没有记录!", u"错误提示", wx.OK )as dlg: + # # dlg.ShowModal() + # elif ( interval*7 + begin ) < (count-1): + # for i in range(7): + # result_line.append( linecache.getline( fpath,count-begin-i*interval ).strip("\n") ) + # else: + # for i in range( ( (count-1)-begin )//interval ): + # result_line.append(linecache.getline( fpath,count-begin-i*interval ).strip("\n") ) + + # # 画7天的图像 + # thefile.close() + # self.plotSeven( wl, result_line ) + \ No newline at end of file diff --git a/icon.ico b/icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..9d501c8d2984e1c930bdce344789dc448dbca948 GIT binary patch literal 1150 zcma)+ZAep57=T|tpr{}Dt6)Ug!sfTzOs5zW4qKVdtrW2@arMI=2BB7>l$zo`*tOiq zrJE@x_*I4}W(6u(27zmCp(Jyg_F;vqMJaBYZ|BY&F$q1F_nvd!bDrnD+;h1AKI94r z0CEq6Tz`O_01!-qq)28pPdWgyw%LXV@NaCEqxW6C(hsF&J=@P_z08wj52$3)_K0M` zE3jB@Y^W(Ld3Xf_9$Ulffi>> z>@*%rvtrPm5fmo(>J{>4u2|Sb9O`urnpIMCU6YI*HRFuq*)TE5g6Ze2$m5M-Ebj$z zbm$ebMy@#ZK5^XhI6N%hB%|w!GG@^*;liM6=C><#HRcn4QGYNE|w@D5Z`# z+MuMQ7gXxDtpdJD8nWN&6pB8f-sD8@HurrQua%fEjMap~)S(*rDzALr0!t zevtuNIzJ#^(2d+Ecik>sy_Qi?PP1=3?Am}*Ho(tCov%2xDJSAUojoSH71PfQVhE{w zI)frCsq1D9Ysk8uQfgt|)#@uwsm+OwteHE=QPJ!}x^AVL9b3nECvH{OgHG4rmzS&N z=U-CgXzpltRoZ#L-b3%D I8T$Y52gX0J2LJ#7 literal 0 HcmV?d00001 diff --git a/listctrl.py b/listctrl.py new file mode 100644 index 0000000..210bc4f --- /dev/null +++ b/listctrl.py @@ -0,0 +1,32 @@ +from myconfig import TOKEN +import wx + +class Listctrl(wx.Panel): + ''' + # 需要在 Frame 实例化一个实例 + # 改变需要对实例化后的进行操作 + ''' + def __init__(self, parent ): + ''' + * panel 初始化后的样子 + ''' + # self.para_setting = para + super(Listctrl,self).__init__(parent) + self.locale = wx.Locale(wx.LANGUAGE_CHINESE_SIMPLIFIED) + + self.SetBackgroundColour('lightgrey') + + self.box = wx.BoxSizer(wx.HORIZONTAL) + + self.list_ctrl = wx.ListCtrl(self, -1, style = wx.LC_REPORT | wx.LC_SORT_DESCENDING) + self.list_ctrl.SetBackgroundColour( 'lightgrey' ) + + self.list_ctrl.InsertColumn(0, u'测量时间', width = 180) + self.list_ctrl.InsertColumn(1, u'花粉_Pollen', width = 180) + i = 1 + + self.list_ctrl.SetFont( wx.Font( 11, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False ) ) + + self.box.Add(self.list_ctrl,1,wx.EXPAND) + self.SetSizer(self.box) + self.Fit() diff --git a/myconfig.py b/myconfig.py new file mode 100644 index 0000000..b34ec91 --- /dev/null +++ b/myconfig.py @@ -0,0 +1,188 @@ +#! python3 +# -*- encoding: utf-8 -*- +''' +@File : myconfig.py +@Time : 2023/03/01 15:28:20 +@Author : Jim @ Yiwin +@Version : 1.0 +@Contact : jim@yi-win.com +@Descrip : SysConfig +''' + +import yaml +from enum import Enum +from pathlib import Path +VERSION = "3.5.0" +LASTDATE = "2023-03-7" +COMPANY = u"奕枫仪器" + +CURRENT_DIR = Path() +DATA_DIR = "data" +CAL_DIR = "calfile" +OUTPUT_DIR = "output" +YAML_FILE_NAME = "config.yml" +RETRIEVE_CFG_FILE = "retrieve.yml" +PURE_WATER_FNAME = "abs_pure_water.DAT" +FILE_MARK = ['Spectrum', 'DATA'] +SAVE_EXT_NAME = ".csv" +INTERVAL = 1.0 +SEPARATOR = ";" +TOKEN = ";" +NEWLINE = "\n" + +OSCAR_R = 0.04 +OSCAR_R0 = 0.035 + +class DeviceType(Enum) : + VIPER = 1 + OSCAR = 2 + SC6 = 3 + + +DEVICE = { + "UISN" : "B055" + } + +# 一次最多 256个字节,步长<128, 字节数<256,浮点数最多63个 +# viper 2100 2462 352/2 = 171, 一次60个 +# oscar 2100 2329 230/2 = 116 一次60个 +REGISTER = { + "slaveaddress" : 1, + "functioncode" : 3, + "SNAddress" : 10, # 测试使用2980 + "SNLen" : 5, + "WLBeginAddress" : 2102, # 2100+2 + "DataBeginAddress" : 2614, # 2612+2 + "count" : 3 #oscar 2 viper 3 + } + +COMSETTING = { + "port" : "COM1" , + "baudrate" : 9600, + 'bytesize' : 8, + 'parity' : "N", + 'stopbit' : 1 + } + +PLOTSETTING = { + "LineInterval" : 1 , + "LineBegin" : 0 + } + +LOGSETTING= { + "LogInterval" : 1, + "RefreshInterval" : 0 + } + +ALGORITHM = { + "A720" : 0, # 0: 720 11项平均值法, 1: 720 附近两个点插值 2: 720 为0 + "PureWater" : 0, # 0 :包含纯水系数 1: 不包含纯水系数 + "PureWater2" : 0 + } + +RETRIEVE = { + # "Enable" : 1, + "BeginWL" : 360, + "EndWL" : 721, + "Interval" : 1 + } + +FILEPATH = { + "path" : '' + } + +class MyConfig(object): + """ + 如上预定义数据 + 先写一个yaml 文件出来,修改后,读文件数据就可以 + """ + def __init__(self) -> None: + self.device_sn = "" + self.system_cfg = {} + self.cfg_path = Path() + self.yml_cfg_file = self.cfg_path.joinpath(YAML_FILE_NAME) + self.retrieve_cfg_file = Path(RETRIEVE_CFG_FILE) + self.getSystemCfg() # 默认的值 + + def getSystemCfg(self,)->None: + ''' + 获得默认的值 + ''' + self.system_cfg = {} + self.system_cfg.update( {"device":DEVICE} ) + self.system_cfg.update( {"register":REGISTER} ) + self.system_cfg.update( {"plotsetting":PLOTSETTING} ) + self.system_cfg.update( {"logsetting":LOGSETTING} ) + self.system_cfg.update( {"comsetting":COMSETTING} ) + self.system_cfg.update( {"algorithm":ALGORITHM} ) + self.system_cfg.update( {"filepath":FILEPATH} ) + pass + + def getDictByAttr(self, *args) -> dict: + ret = {} + if len(args) == 0: + return ret + if len(args) == 1: + if not hasattr( self, args[0] ): + return ret + tmp = getattr( self, args[0] ) + if isinstance( tmp, dict ): + ret.update(tmp) + return ret + if len(args) == 2: + if not hasattr(self, args[0]): + return ret + if not isinstance(getattr(self, args[0]), dict): + return ret + tmp: dict = getattr(self, args[0]) + if not tmp.__contains__(args[1]): + return ret + tmp2 = tmp[args[1]] + if isinstance(tmp2, dict): + ret.update(tmp2) + return ret + if len(args) > 2: + return ret + pass + + # 设置字典对应的键值 + def set_attr(self, d: dict, k, v) -> bool: + if d.__contains__(k): + d.update({k: v}) + return True + return False + + def write_yaml(self, d: dict): + with open(self.yml_cfg_file, "w", encoding = "utf-8") as f: + yaml.dump(d, f) + + def read_yaml(self ) -> dict: + # self.write_yaml(self.system_cfg) + with open(self.yml_cfg_file, "r", encoding="utf-8") as f: + content = f.read() # conent 读出来是字符串 + d = yaml.load(content, Loader=yaml.FullLoader) # 用load方法转字典 + return d + + def write_rtv_yaml(self, d: dict): + with open(self.retrieve_cfg_file, "w", encoding="utf-8") as f: + yaml.dump(d, f) + + def read_rtv_yaml(self ) -> dict: + with open(self.retrieve_cfg_file, "r", encoding="utf-8") as f: + content = f.read() # conent 读出来是字符串 + d = yaml.load(content, Loader=yaml.FullLoader) # 用load方法转字典 + return d + + def set_retrieve(self) -> dict: + retrieve = {} + # retrieve.update({"enable": RETRIEVE["Enable"]}) + retrieve.update({"beginWL": RETRIEVE["BeginWL"]}) + retrieve.update({"endWL": RETRIEVE["EndWL"]}) + retrieve.update({"interval": RETRIEVE["Interval"]}) + self.write_rtv_yaml(retrieve) + return retrieve + pass + + +if __name__ == "__main__": + pass \ No newline at end of file diff --git a/myexception.py b/myexception.py new file mode 100644 index 0000000..6e1209e --- /dev/null +++ b/myexception.py @@ -0,0 +1,14 @@ +class TCPIPException(Exception): + + def __init__(self, message="TCPIP 自定义异常"): + self.message = "TCPIP exception : " + message + +class SerialException(Exception): + + def __init__(self, message="Serial 自定义异常"): + self.message = "serial exception : " + message + +class MyException(Exception): + + def __init__(self, message=" 自定义异常"): + self.message = "自定义异常: " + message \ No newline at end of file diff --git a/mylogger.py b/mylogger.py new file mode 100644 index 0000000..9c85ec9 --- /dev/null +++ b/mylogger.py @@ -0,0 +1,285 @@ +# coding=utf-8 +''' +单例模式日志 -- 使用一次关闭 handler +这种方法优缺点: +缺点: 输出的format 需要自己定义 ,并过滤 + 过滤要看是否以什么开头,或包含什么 +优点: 不占用文件资源,占用系统资源小 +调用 log.info( ) log.error() +''' + +import logging +import logging.handlers +import os +import time +import threading +# from config import LOG_PATH,LOG_LEVEL,LOG_ENABLED,LOG_FORMAT, \ +# LOG_TO_CONSOLE,LOG_TO_FILE + +MY_LOGGER_NAME = "DefaultLogger" +LOG_ENABLED = True # 是否启用日志 +LOG_TO_CONSOLE = True # 是否启用控制台输出日志 +LOG_TO_FILE = False # 是否启用文件输出 +LOG_COLOR_ENABLE = True # 是否启用颜色日志 + +LOGGER_DIR = "logs" +LOGGER_PATH = os.path.join( os.path.dirname(__file__), LOGGER_DIR ) +LOGGER_FILENAME = os.path.join( LOGGER_PATH, 'logs.log' ) + +""" +logging.INFO , logging.DEBUG , logging.WARNING , logging.ERROR , +""" +LOG_LEVEL = logging.INFO # 日志等级DEBUG INFO WARNIG ERROR +# LOG_LEVEL = logging.DEBUG +# LOG_LEVEL = logging.WARNING + +""" +# LOG_FORMAT = " %(name)s - %(module)s - %(filename)s - %(lineno)d | %(levelname)s : %(message)s" +# LOG_FORMAT = "%(levelname)s - %(asctime)s - process: %(process)d - threadname: %(thread)s " \ +# "- %(filename)s - %(funcName)s - %(lineno)d - %(module)s " \ +# "- %(message)s " +# LOG_FORMAT = "%(asctime)s - %(thread)s " \ +# "- %(levelname)s ::: %(message)s " +# '[%(asctime)s] |%(thread)s| %(levelname)-6s: %(message)s' +# fm = '%(levelname):%(levelno)s:%(name)s:%(funcName)s:%(asctime):%(pathname):%(filename):%(module):%(thread):%(threadName)' +# 此处日志颜色,修改日志颜色是通过 Filter实现的 +""" +LOG_FORMAT = '%(levelname)s\t[%(asctime)s] %(package)s:%(classname)s:%(funcname)s \t>> %(message)s' + +""" +# 此处日志颜色,修改日志颜色是通过 Filter实现的 +""" +LOG_FORMAT_COLOR_DICT = { + 'ERROR' : "\033[31mERROR\033[0m", + 'INFO' : "\033[36mINFO\033[0m", + 'DEBUG' : "\033[1mDEBUG\033[0m", + 'WARN' : "\033[33mWARN\033[0m", + 'WARNING' : "\033[33mWARNING\033[0m", + 'CRITICAL': "\033[35mCRITICAL\033[0m", +} + +""" +# Filter 用法, 以package class function 过滤 __package__ __class__ +# log.error( f"{__package__}::{__class__.__name__}::{sys._getframe().f_code.co_name} >> ") +# log.error( f"PacakgeName::ClassName::FunctionName:: ") +# LOGGER_FILTER_PACKAGE=[] 为空, 则Filter不起作用 +# 不为空,则只显示定义的报名 +# LOGGER_FILTER_CLASS=[] 为空, 则Filter不起作用 +# 不为空,则只显示定义的类或 +# LOGGER_FILTER_FUNCNAME=[] 为空, 则Filter不起作用 +# 不为空,则只显示定义的函数 +""" +# LOGGER_FILTER_PACKAGE = [ "test_logger" ] # 包名,文件名去 .py?? +LOGGER_FILTER_PACKAGE = [ ] +LOGGER_FILTER_CLASS = [ ] # 类名,文件名去 .py?? +# LOGGER_FILTER_CLASS = [ "LogTest" ] +# LOGGER_FILTER_FUNCNAME = [ "test1","test" ] # 函数名 +LOGGER_FILTER_FUNCNAME = [ ] +LOGGER_FILTER_LEVELNAME = [ ] # INFO DEBUG WARNING + +class PackageFilter(logging.Filter): + def __init__(self, filter_word:list = []): + self.filter_word = filter_word + pass + def filter(self, record: logging.LogRecord) -> bool: + if self.filter_word is not None: + return record.package in self.filter_word + +class ClassFilter(logging.Filter): + def __init__(self, filter_word:list = []): + self.filter_word = filter_word + pass + def filter(self, record: logging.LogRecord) -> bool: + if self.filter_word is not None: + return record.classname in self.filter_word + + pass + +class FunctionFilter(logging.Filter): + def __init__(self, filter_word:list = []): + self.filter_word = filter_word + pass + def filter(self, record:logging.LogRecord) -> bool: + if self.filter_word is not None: + return record.funcname in self.filter_word + +class LevelNameFilter(logging.Filter): + def __init__(self, filter_word:list = []): + self.filter_word = filter_word + pass + def filter(self, record:logging.LogRecord) -> bool: + if self.filter_word is not None: + return record.levelname in self.filter_word + +class ColorFilter(logging.Filter): + def __init__(self,): + pass + def filter(self, record: logging.LogRecord) -> bool: + record.levelname = LOG_FORMAT_COLOR_DICT.get(record.levelname) + return True + +class Log(object): + _instance_lock = threading.Lock() + + def __new__(cls, *args, **kwargs): + if not hasattr(Log, "_instance"): + with Log._instance_lock: + if not hasattr(Log, "_instance"): + Log._instance = object.__new__(cls) + return Log._instance + + def __init__(self, loggername = "DefaultLog" ): + # 文件命名 os.path.join(): 将多个路径组合后返回 + self.logger_filepath = LOGGER_FILENAME + self.loggername = loggername + self.level = LOG_LEVEL + + # 日志输出格式 + fm = LOG_FORMAT + self.formatter = logging.Formatter( fm ) + + # 生成记录器对象 + self.logger = logging.getLogger( self.loggername ) + self.logger.setLevel(LOG_LEVEL) + + # 日志过滤 + self.__add_filter() + + def __console(self, level, message, extra={} ): + # 添加 handler + self.__add_handler() + + # 判断日志级别 + if level == logging.INFO: + self.logger.info( message, extra=extra) + elif level == logging.DEBUG: + self.logger.debug(message,extra=extra) + elif level == logging.WARNING: + self.logger.warning(message,extra=extra) + elif level == logging.ERROR: + self.logger.error(message,extra=extra) + + # removeHandler在记录日志之后移除句柄,避免日志输出重复问题 + self.__remove_handler() + # if LOG_TO_FILE and self.file_handler: + # self.logger.removeHandler(self.file_handler) + # # 关闭打开的文件 + # self.file_handler.close() + # if LOG_TO_CONSOLE and self.stream_handler: + # self.logger.removeHandler(self.stream_handler) + # # 关闭打开的文件 + # self.stream_handler.close() + pass + + # debug < info< warning< error< critical + # debug模式 + def debug(self, message, package="Unknown", classname="Unknown", funcname="Unknown" ): + self.__console(logging.DEBUG, message, extra={"package":package, "classname":classname, "funcname":funcname} ) + # self.__remove_handler() + # info模式 + def info(self, message, package="Unknown", classname="Unknown", funcname="Unknown" ): + self.__console(logging.INFO, message, extra={"package":package, "classname":classname, "funcname":funcname} ) + # self.__remove_handler() + # warning模式 + def warning(self, message, package="Unknown", classname="Unknown", funcname="Unknown"): + self.__console(logging.WARNING, message, extra={"package":package, "classname":classname, "funcname":funcname} ) + # self.__remove_handler() + + # error模式 + def error(self, message, package="Unknown", classname="Unknown", funcname="Unknown"): + self.__console(logging.ERROR, message, extra={"package":package, "classname":classname, "funcname":funcname} ) + # self.__remove_handler() + + def __add_filter(self ): + if len( LOGGER_FILTER_PACKAGE ) > 0 : + self.logger.addFilter( PackageFilter( filter_word=LOGGER_FILTER_PACKAGE ) ) + if len( LOGGER_FILTER_CLASS ) > 0 : + self.logger.addFilter( ClassFilter( filter_word=LOGGER_FILTER_CLASS ) ) + if len( LOGGER_FILTER_FUNCNAME ) > 0 : + self.logger.addFilter( FunctionFilter( filter_word=LOGGER_FILTER_FUNCNAME ) ) + if len(LOGGER_FILTER_LEVELNAME) > 0 : + self.logger.addFilter( LevelNameFilter( filter_word=LOGGER_FILTER_LEVELNAME ) ) + + def __add_handler(self ): + if LOG_ENABLED and LOG_TO_FILE: + # 考虑使用 RotatingFileHandler TimedRotatingFileHandler防止日志过大 + # RotatingFileHandler("test", "a", 4096, 2, "utf-8") + # TimedRotatingFileHandler(filename=LOG_PATH+"thread_", when="D", interval=1, backupCount=7) + self.file_handler = logging.handlers.TimedRotatingFileHandler(filename=self.logger_filepath, when='D', interval=1, backupCount=30, encoding='utf-8') + # self.file_handler = logging.FileHandler( self.logger_filepath, encoding='utf-8' ) + self.file_handler.setFormatter( self.formatter ) + # self.file_handler.setLevel( LOG_LEVEL ) + # if LOG_COLOR_ENABLE: # 文件日志无需加彩色 + # self.file_handler.addFilter( ColorFilter( ) ) + self.logger.addHandler(self.file_handler) + + if LOG_ENABLED and LOG_TO_CONSOLE: + # 创建一个StreamHandler,用于输出到控制台 + + self.stream_handler = logging.StreamHandler() + self.stream_handler.setFormatter(self.formatter) + # self.stream_handler.setLevel( LOG_LEVEL ) + if LOG_COLOR_ENABLE: + self.stream_handler.addFilter( ColorFilter( ) ) + self.logger.addHandler(self.stream_handler) + + def __remove_handler(self ): + if LOG_TO_FILE and self.file_handler: + self.logger.removeHandler(self.file_handler) + if len(self.logger.handlers)>0: + self.logger.handlers.pop() + # 关闭打开的文件 + self.file_handler.close() + if LOG_TO_CONSOLE and self.stream_handler: + self.logger.removeHandler(self.stream_handler) + if len(self.logger.handlers)>0: + self.logger.handlers.pop() + # 关闭控制台 + self.stream_handler.close() + + def __remove_handler2(self ): + if LOG_ENABLED and LOG_TO_CONSOLE: + self.logger.removeHandler(self.stream_handler) + self.logger.handlers.pop() + # 关闭控制台 + self.stream_handler.close() + if LOG_ENABLED and LOG_TO_FILE: + self.logger.removeHandler(self.file_handler) + self.logger.handlers.pop() + # 关闭打开的文件 + self.file_handler.close() + + +log = Log( loggername = "DefaultLog") + +""" +filename: 指定日志文件名 +filemode: 和file函数意义相同,指定日志文件的打开模式,’w’或’a’ +format: 指定输出的格式和内容,format可以输出很多有用信息。显示的条目可以是以下内容: +%(levelname): 日志级别的名字格式 +%(levelno)s: 日志级别的数字表示 +%(name)s: 日志名字 loggername +%(funcName)s: 函数名字 +%(asctime): 日志时间,可以使用datefmt去定义时间格式,如上图。 +%(pathname): 脚本的绝对路径 +%(filename): 脚本的名字 +%(module): 模块的名字 +%(thread): thread id +%(threadName): 线程的名字 +""" + +""" +文件名行号 函数名, 要在调用的时候想办法了 +# 绝对路径 +print( __file__ ) +print( sys.argv[0] ) + +# 文件名 +print( os.path.basename(__file__) ) +print( os.path.basename(sys.argv[0]) ) + +self.__class__.__name__ +self.__class__.__name__, get_current_function_name() + +logger名 __name__ +""" \ No newline at end of file diff --git a/mypanel.py b/mypanel.py new file mode 100644 index 0000000..6aa3e9d --- /dev/null +++ b/mypanel.py @@ -0,0 +1,141 @@ +import wx +import numpy as np +from enum import Enum +from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas #FigureCanvasWxAgg +from matplotlib.backends.backend_wx import NavigationToolbar2Wx as NavigationToolbar # FIgure 导航 +from matplotlib.figure import Figure + +class LineColor(Enum): + RED = 0 + ORANGE = 1 + YELLOW = 2 + GREEN = 3 + CYAN = 4 + BLUE = 5 + PURPLE = 6 + + +class Plot(wx.Panel): + ''' + # 需要在 Frame 实例化一个实例 + # 改变需要对实例化后的进行操作 + ''' + ''' + Matplotlib Panel 单独拿出来画图 + 可以 __do_layout + 可以 __add_widgets + 可以 button事件 + 可以鼠标事件 + ''' + def __init__(self,parent): + ''' + * panel 初始化后的样子 + ''' + super(Plot,self).__init__(parent) + # 本地化语言 + self.locale = wx.Locale(wx.LANGUAGE_CHINESE_SIMPLIFIED) + + self.Figure = Figure(figsize=(4,3)) # 4,3 为英寸 + self.axes = self.Figure.add_axes([0.1,0.1,0.8,0.8],facecolor="lightgray") # 坐标系起始位置 + self.FigureCanvas = FigureCanvas(self,-1,self.Figure) + + #继承鼠标移动显示鼠标处坐标的事件 + # self.FigureCanvas.mpl_connect('motion_notify_event',self.MPLOnMouseMove) + + # self.NavigationToolbar = NavigationToolbar(self.FigureCanvas) + + # self.StaticText = wx.StaticText(self,-1,label=u'坐标信息') + + # self.SubBoxSizer = wx.BoxSizer(wx.HORIZONTAL) + # self.SubBoxSizer.Add(self.NavigationToolbar,proportion =0, border = 2,flag = wx.ALL | wx.EXPAND) + # self.SubBoxSizer.Add(self.StaticText,proportion =-1, border = 2,flag = wx.ALL | wx.EXPAND) + + self.TopBoxSizer = wx.BoxSizer(wx.VERTICAL) + # self.TopBoxSizer.Add(self.SubBoxSizer,proportion =-1, border = 2,flag = wx.ALL | wx.EXPAND) + self.TopBoxSizer.Add(self.FigureCanvas,proportion =-10, border = 2,flag = wx.ALL | wx.EXPAND) + + self.SetSizer(self.TopBoxSizer) + + self.purewater_legend = ("Pure Water Absorption Coefficience" + ,"Wavelength (nm)" + ,"Absorption Coefficience m(-1)" ) + + self.measure_legend = (" Absorption Coefficient" + ,"Wavelength (nm)" + ,"Absorption Coefficience m(-1)" ) + + def set_axes_title(self,title): + self.axes.set_title(title) + + def set_axes_xlabel(self,x): + self.axes.set_xlabel(x) + + def set_axes_ylable(self,y): + self.axes.set_ylabel(y) + + def set_title_x_y(self,title, x, y): + self.axes.set_title(title) + self.axes.set_xlabel(x) + self.axes.set_ylabel(y) + + def plot_one( self, time_, wavelength:np.ndarray, data:np.ndarray, color="green" ): + self.axes.plot(wavelength, data, color=color, linewidth=0.5 , label=time_ ) + self.axes.legend( ) + self.axes.grid( True ) + self.FigureCanvas.draw() + + + def plot_multi( self, time_, wavelength:np.ndarray, data:np.ndarray ): + len_ = len(data) + for i in range(len_): + self.axes.plot(wavelength, data[i], color=LineColor(i).name.lower(), linewidth=0.5 , label=time_[i] ) + self.axes.legend( ) + self.axes.grid(True) + self.FigureCanvas.draw() + + def clear_past( self, ): + self.axes.clear() + + # def MPLOnMouseMove(self,event): + # ''' + # * 显示坐标值 + # ''' + # ex=event.xdata#这个数据类型是numpy.float64 + # ey=event.ydata#这个数据类型是numpy.float64 + # if ex and ey : + # #可以将numpy.float64类型转化为float类型,否则格式字符串可能会出错 + # self.StaticText.SetLabel('%10.5f,%10.5f' % (float(ex),float(ey))) + +class MyPanel(wx.Panel): + """docstring for MyPanel.""" + def __init__(self, *arg, **kwarg): + super(MyPanel, self).__init__( *arg,**kwarg) + + self.SetBackgroundColour("#F2F2F2") + self.sb = wx.StaticBox( self, label='系统信息', pos = (30,30) ) + + self.sbs = wx.StaticBoxSizer( self.sb, orient=wx.VERTICAL ) + + self.vbox1 = wx.BoxSizer(wx.VERTICAL) + self.staticText0 = wx.StaticText(self , label='',size=(60, 30), style=wx.ALIGN_CENTRE_VERTICAL ) + + self.staticText1 = wx.StaticText(self, -1,size=(600, -1), + label='''\n上海奕枫仪器设备有限公司 + \n电话: 021-54270075 + \n网站: http://www.yi-win.com + \n邮件: sales@yi-win.com + \n描述: AWRAMS离线数据处理 ''' ) + + + self.vbox1.Add(self.staticText0, flag=wx.TOP|wx.LEFT, border=5) + self.vbox1.Add(self.staticText1, flag=wx.TOP|wx.LEFT, border=5) + # self.hbox1.Add(self.staticText1, flag=wx.TOP|wx.LEFT, border=5) + # self.hbox1.Add(self.textCtrl1, flag=wx.TOP|wx.LEFT, border=5) + self.sbs.Add(self.vbox1, flag=wx.TOP|wx.LEFT, border= 5) + self.SetSizer(self.sbs) + + + def setStaticText(self, msg:str): + self.staticText1.SetLabel(msg) + + \ No newline at end of file diff --git a/mypath.py b/mypath.py new file mode 100644 index 0000000..675a694 --- /dev/null +++ b/mypath.py @@ -0,0 +1,277 @@ +from pathlib import PurePath, Path + +# from myconfig import NEWLINE,TOKEN,SEPARATOR +""" +""" +class MyDir(object): + """ + 操作方法:设置base tuple_dir header + 设置的是路径, 文件名要 ifNotNewFile 传入 + 调用方法: + self.mydir.setBaseDir(path) + self.mydir.newDirIfNot() + self.mydir.newFileIfNot(file_name) + + self.mydir.setHeader(header_list, TOKEN, header_str) + if self.mydir.checkHeader() == 0: + self.mydir.writeHeader() + if self.mydir.checkHeader() == -1: + pass + self.mydir.setContent(header_list, TOKEN, header_str) + self.mydir.writeContent() + """ + + def __init__(self) -> None: + self.base_dir = Path() + self.dir_tuple = () + self.header = [] + self.header_str = "" + self.content = [] + self.content_str = "" + self.current_dir = None + self.current_filepath = None + pass + + def getDir(self,): + return self.current_dir + pass + + def setBaseDir(self, dir: Path): + self.base_dir = dir + self.current_dir = self.base_dir + pass + + def setDir(self, t:tuple=()): + self.dir_tuple = t + if len(self.dir_tuple) == 0 : + self.current_dir = self.base_dir + else: + self.current_dir = self.base_dir.joinpath( *t ) + pass + + def getDirFromBaseAndTuple(self, base_dir:Path, dir_tuple: tuple): + '''外部调用返回路径''' + ret_path = base_dir + t = dir_tuple + if len(t) == 0 : + ret_path = ret_path + else: + ret_path = ret_path.joinpath( *t ) + return ret_path + pass + + def setHeader(self, headerlist:list, headerSeperator: str = ";", headerinfo: str = None): + header_str = "" + if len(headerlist) == 0: + return + if headerinfo != None: + header_str = headerinfo + headerSeperator + for hl in headerlist: + header_str = header_str + str(hl) + headerSeperator + self.header_str = header_str[:-1] + pass + + def setContent(self, contentlist: list, contentSeperator: str = ";", contentinfo: str = None): + content_str = "" + if len(contentlist) == 0: + return + if contentinfo != None: + content_str = contentinfo + contentSeperator + tmp_str = "" + for cl in contentlist: + tmp_str = tmp_str + str(cl) + contentSeperator + self.content_str = content_str + tmp_str[:-1] + pass + + def newDirIfNot(self,) -> None: + # self.current_path = self.base_path.joinpath(self.path_tuple) + self.current_dir.mkdir(parents=True, exist_ok=True) + pass + + def newFileIfNot(self, fname: str) -> None: + self.newDirIfNot() + self.current_filepath = self.current_dir.joinpath(fname) + if not self.current_filepath.exists(): + with open(self.current_filepath, 'a') as f: + pass + return + pass + + def getCurrentFileSize(self,): + return self.current_filepath.stat().st_size + + def getFirstline(self,): + first_line = "" + with open(self.current_filepath, 'r') as f: # 打开文件 + first_line = f.readline() # 取第一行 + return first_line.strip('\n').strip('\r') + + def checkHeader(self,) -> int: + ''' + 返回: + 0 : 文件为空,可以直接写header + 1 : header对应上 无需处理 + -1: 需要提醒用户保存数据后,删除文件后再处理 + ''' + if self.getCurrentFileSize() == 0: + return 0 + first_line = self.getFirstline() + # print(f"firstline: {first_line}" ) + # print(f"header_str: {self.header_str}" ) + if first_line == self.header_str: + return 1 + return -1 + pass + + def writeHeader(self,) -> None: + with open(self.current_filepath, "a") as f: + f.write(self.header_str) + return None + pass + + def writeContent(self,new_line="\n") -> None: + with open(self.current_filepath, "a") as f: + f.write(new_line+self.content_str) + return None + pass + + def is_dir_empty(self, ): + '''文件夹是否为空''' + has_next = next(self.current_dir.iterdir(), None) + if has_next is None: + return True + return False + + def is_file_empty(self,): + '''文件是否为空''' + if self.current_dir.stat().st_size ==0: + return True + return False + + def deleteDir(self,): + '''文件夹是否为空''' + try: + if self.current_dir.exists(): + self.current_dir.rmdir() + except OSError as e: + raise Exception(e) + return True + + ## 其他需求 + def get_child_dir(self,) -> list: + ret = [] + tmp_dir = self.current_dir.glob("**/") + for td in tmp_dir: + if td.is_dir(): + ret.append(td.relative_to(self.current_dir)) + return ret + pass + + def get_child_dir_only(self,) -> list: + ret = [] + for d in self.current_dir.iterdir(): + if d.is_dir(): + ret.append(d.relative_to(self.current_dir)) + return ret + pass + + def get_files_from_currentdir(self, fmt:str="*/*" ) -> list: + '''fmt: * */* */*/*''' + ret = [] + tmp_dir = self.current_dir.glob(fmt) + print(tmp_dir) + for td in tmp_dir: + if td.is_file(): + ret.append(td) + return ret + pass + + def sort_dir_and_check( self, dirs:list ): + '''相对目录排序,目录最后一级''' + ret = [] + if len(dirs) == 0: + return ret + tmp = {} + tmp_lst = [] + for d in dirs: + last:str = d.parts[-1] + if last.isdigit() : + tmp.update( {last:d} ) + tmp_lst.append(int(last)) + pass + + tmp_lst.sort() + for t in tmp: + ret.append(tmp.get(str(t))) + pass + return ret + + + def sort_filepath_and_check(self, path_files:list): + '''相对目录排序,目录最后一级''' + ret = [] + if len(path_files) == 0: + return ret + tmp = {} + tmp_lst = [] + for d in path_files: + last:str = d.stem + if last.isdigit() : + tmp.update( {last:d} ) + tmp_lst.append(int(last)) + pass + + tmp_lst.sort() + for t in tmp: + ret.append(tmp.get(str(t))) + pass + return ret + + def group_and_sort_filepath(self,path_files:list): + ret = {} + # dirs_lst = [] + # len_files = len(path_files) + # if len_files == 0: + # return False + # for pf in path_files: + # pf_dir:str = pf.parts[-2] + # if pf_dir.isdigit() and int(pf_dir) not in dirs_lst: + # dirs_lst.append( int(pf_dir) ) + # dirs_lst.sort() + + + + + def check_dirs(self, dirs:list, begin:int =0, step:int=1): + '''检查目录是否从begin开始递增''' + len_dirs = len(dirs) + if len_dirs == 0: + return False + for i in range(begin,len_dirs,step) : + if dirs[i].parts[-1] != str(i) : + return False + return True + + def check_path_files(self,path_files:list,begin:int =0, step:int=1): + '''检查文件名从begin开始递增''' + len_files = len(path_files) + if len_files == 0: + return False + for i in range(begin,len_files,step) : + if path_files[i].stem != str(i) : + return False + return True + +if __name__ == "__main__": + mp = MyDir() + mp.setBaseDir(Path()) + print(mp.current_dir) + # t = ("test_dir","1","11") + t = ("test_dir", ) + mp.setDir( t ) + print(mp.current_dir) + + cd = mp.get_child_dir_only() + c = mp.sort_dir_and_check(cd) + print(cd ) + print(c ) diff --git a/mythread.py b/mythread.py new file mode 100644 index 0000000..b2ba0e1 --- /dev/null +++ b/mythread.py @@ -0,0 +1,126 @@ +import threading +import time + +class Mythead(threading.Thread): + '''线程守护''' + def __init__(self ): + super(Mythead, self).__init__() + pass + + def set_task(self, func, *args): + self.func = func + self.args = args + + def run(self): + # print(f" --- {len(self.args)}") + if len(self.args) > 0: + self.func(self.args) + else: + self.func( ) + +class Multithread(threading.Thread): + ''' + 多线程 + 子线程.join() -> ( 设置在start之后, 等所有阻塞线程运行完, 再运行主线程 ) + 子线程.setDaemon(True) -> 设置子线程A为守护线程, 主线程所在的进程内所有非守护线程统统运行完毕, + 无论子线程A有没有结束, 程序都结束 + Method: + + ''' + def __init__(self): + super(Multithread, self).__init__() + self.__tasks = [] + self.act = [] + # self.__block = False + pass + + # def set_task( self, tasks ): + # self.__tasks = tasks + + def add_task(self, func, daemon=False, join=True,args=()): + tmp_dict = {} + tmp_dict.update( {"func" : func}) + if daemon == True: + tmp_dict.update( {"daemon" : True}) + else: + tmp_dict.update( {"daemon" : False}) + if join == True: + tmp_dict.update( {"join" : True}) + else: + tmp_dict.update( {"join" : False}) + if args == (): + tmp_dict.update( {"args" : ()}) + else: + tmp_dict.update( {"args" : args}) + self.__tasks.append( tmp_dict ) + + def remove_tasks(self, ): + self.__tasks = [] + self.act = [] + + def add_task_2_act(self, task): + t = threading.Thread( target = task['func'], args = task['args'] ) + self.act.append(t) + t.start() + + def execute_one_act(self,i): + if self.__tasks[i]['join']: + self.act[i].join() # 子线程阻塞完毕再运行主线程 + pass + + def prepare_tasks(self): + self.act = [] + for task in self.__tasks: + self.add_task_2_act(task) + + def execute_tasks(self): + try: + for i in range( len(self.act) ): + self.execute_one_act( i ) + pass + except Exception as e: + print(e) + + def prepare_tasks(self): + self.act = [] + for task in self.__tasks: + t = threading.Thread( target = task['func'], args = task['args'] ) + self.act.append(t) + t.start() + + def simultaneously_execute_tasks(self): + self.prepare_tasks() + self.execute_tasks() + + def sequently_execute_tasks(self): + for task in self.__tasks: + t = threading.Thread( target = task['func'], args = task['args'] ) + t.start() + t.join() + + + def t1(self): + print("thread1...") + time.sleep(10) + print("thread1... after sleep...") + + def t2(self): + print("thread2...") + time.sleep(5) + print("thread2... after sleep...") + + def t3(self): + print("thread3...") + time.sleep(3) + print("thread3... after sleep...") + +if __name__ == '__main__': + mt = Multithread() + mt.add_task(mt.t1) + mt.add_task(mt.t2) + mt.add_task(mt.t3) + # mt.prepare_tasks() # 线程同步运行 + # mt.execute_tasks() + # mt.simultaneously_execute_tasks() + mt.sequently_execute_tasks() + diff --git a/mytime.py b/mytime.py new file mode 100644 index 0000000..ec7b4b2 --- /dev/null +++ b/mytime.py @@ -0,0 +1,71 @@ +from datetime import datetime, timedelta +# import locale +# locale.setlocale(locale.LC_ALL, '') + +TIME_STR = "2022-06-10 16:16:16" +STD_TIME_STR_FMT = "%Y-%m-%d %H:%M:%S" # 小写y是两位年份 +CUR_TIME_STR_FMT = "%Y-%m-%d %H:%M:%S" + + +class MyTime(object): + """ + 操作方法:设置base tuple_path header + 调用方法 + self.mytime = Mytime() + self.mytime.setCurrentTimeStrFmt() + print(self.mytime.cur_datetime) + s + """ + + def __init__(self) -> None: + self.cur_time_str_fmt = "%Y-%m-%d %H:%M:%S" + self.std_time_str_fmt = "%Y-%m-%d %H:%M:%S" + self.cur_time_str = "" + self.std_time_str = "" + self.cur_datetime = "" + pass + + def setCurrentTimeStrFmt(self, s): + self.cur_time_str_fmt = s + pass + + def setStdTimeStrFmt(self, s): + self.std_time_str_fmt = s + pass + + def setCurrentTimeStr(self, s): + self.cur_time_str = s + self.cur_datetime = datetime.strptime(self.cur_time_str, self.cur_time_str_fmt) + pass + + def setStdTimeStr(self, s): + self.std_time_str = s + self.cur_datetime = datetime.strptime( + self.std_time_str, STD_TIME_STR_FMT) + pass + + def Current2STD(self): + # self.cur_datetime = datetime.strptime(self.cur_time_str , CUR_TIME_STR_FMT) + self.std_time_str = datetime.strftime( + self.cur_datetime, STD_TIME_STR_FMT) + pass + + def STD2Current(self, format: str): + # self.cur_datetime = datetime.strptime(self.std_time_str , STD_TIME_STR_FMT) + self.cur_time_str = datetime.strftime( + self.cur_datetime, CUR_TIME_STR_FMT) + pass + + def timeDelta(self, days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0): + self.cur_datetime = self.cur_datetime + \ + timedelta(days=0, seconds=0, microseconds=0, + milliseconds=0, minutes=0, hours=0, weeks=0) + pass + + +if __name__ == "__main__": + s = "2023-02-07 14:02:46" + mt = MyTime() + mt.setCurrentTimeStr(s) + print(mt.cur_datetime) + pass diff --git a/oscar.py b/oscar.py new file mode 100644 index 0000000..a02329f --- /dev/null +++ b/oscar.py @@ -0,0 +1,476 @@ +import numpy as np +import struct +import math +import time +from scipy.optimize import leastsq + +from myconfig import TOKEN, DATA_DIR, FILE_MARK, OUTPUT_DIR, CAL_DIR +from myconfig import PURE_WATER_FNAME,SAVE_EXT_NAME,OSCAR_R,OSCAR_R0 +from myconfig import MyConfig +from configuration import Configuration + +from myexception import MyException +from mylogger import log +from mypath import MyDir +from mythread import Multithread +from readcal import ReadCal +from uart import Uart +from pathlib import Path, PurePath +from wx.lib.pubsub import pub + +FLOAT_RESERVE_BIT = 8 + +class Oscar(object): + def __init__(self,): + self.cfg = {} + self.mydir = MyDir() + self.file_lst = [] + self.raw_wavelength = [] + self.raw_wavelength_np = np.array([]) + self.purewater_wavelength = [] + self.purewater_attenuation = [] + self.output_wavelength = [] + self.basis = [] + self.reflectivity = [] + self.begin = 0 + self.end = 0 + + self.dir :Path = Path() + self.datadir :Path = self.dir.joinpath(DATA_DIR) + self.output_dir:Path= self.datadir.joinpath(OUTPUT_DIR) + self.measure_time = '' + self.data = [] + self.res = b'' + self.msg = {"type":"", "data":{}} + self.__get_purewater_wl_and_data() + + self.purewater_after_interp = [] + self.uart = Uart() + self.uart_thread = Multithread() + + self.ui_sn = '' + self.devicesn = '' + self.filesn = '' + pass + + def set_cfg(self, cfg): + self.cfg = cfg + self.ui_sn = self.cfg['device']['UISN'] + self.__get_cal_info() + pass + + # def set_read_para(self, cfg): + # self.cfg = cfg + # self.ui_sn = self.cfg['device']['UISN'] + # pass + + # def set_uart_para(self, cfg): + # self.cfg = cfg + # self.ui_sn = self.cfg['device']['UISN'] + # pass + + def __set_msg(self, typ, d): + self.msg = {} + self.msg.update( {"type":typ} ) + self.msg.update( {"data":d} ) + pass + + # def file_deal_thread(self, func) -> list: + # self.get_data_files() + # self.__deal_file_lst(func) + # pass + + def get_data_files(self,) -> list: + # 读取配置文件 + self.mydir.setBaseDir(Path(self.datadir)) + self.file_lst = self.mydir.get_files_from_currentdir(fmt="*/*.DAT") + + def get_begin_end(self,) -> list: + # 读取配置文件 + for i in range( len(self.raw_wavelength)): + if self.raw_wavelength[i]self.cfg['retrieve']['beginWL']: + self.begin = i+1 + pass + if self.raw_wavelength[i]self.cfg['retrieve']['endWL']: + self.end = i+2 + break + self.get_output_wavelength() + msg = "起始波长 : "+ str(self.output_wavelength[0]) +" , 结束波长 : "+ str(self.output_wavelength[-1]) + log.info(msg, __name__, '','') + self.__set_msg ("notice", msg ) + pub.sendMessage(self.msg) + + + def get_output_wavelength(self,) : + self.output_wavelength = self.raw_wavelength[self.begin:self.end] + pass + + def deal_file_lst(self, ): + for fl in self.file_lst: + log.info(f"-> {fl} ",__name__,"deal_file_lst") + # 判断序列号是否一致file_lst + if not self.__check_sn_from_datafile(fl): + raise MyException( "文件的序列号和系统设置不一致" ) + + # 判断原始波长是否为空 + if self.raw_wavelength == []: + self.__get_raw_wl_from_datafile(self.file_lst[0]) + + # 获得截取的开始 结束点 + self.get_begin_end() + + # 纯水系数插值 + self.interpo_pure_water() + + # 准备储存数据文件 + self.__prepare_for_save() + ReadCal.read_columns_sets_by_mark_callback( + fl, FILE_MARK, self.deal_measure_time_data, 1) + # self.__set_msg( "notice", "文件处理完毕" ) + # pub.sendMessage( "update", msg = self.msg ) + + def deal_measure_time_data(self, sn, res_time, res_data): + log.info(f" -> time : {res_time}",__name__, "deal_one_measure_time_data") + log.info(f" -> datalen : {len(res_data)} ",__name__, "deal_one_measure_time_data") + basis = self.basis[self.begin:self.end] + refl = self.reflectivity[self.begin:self.end] + for i in range(len(res_time)): + + data = self.convert_str_2_float_list( res_data[i][0][self.begin:self.end] ) + abs_coeff_with_water = self.get_absorption_coeff( + data,basis,refl,self.purewater_after_interp) + + data = self.correction_pure_water(abs_coeff_with_water) + # data = data.tolist() + # print(data) + + self.mydir.setContent( data , TOKEN, res_time[i] ) + self.mydir.writeContent() + self.measure_time = res_time[i] + self.data = data + self.__set_msg( "data", {"time":res_time[i], "data":data } ) + pub.sendMessage("update", msg=self.msg) + # pub.sendMessage("update", msg=res_data[i][0][self.begin:self.end]) + + def __check_sn_from_datafile(self, fpath) -> bool: + # 读取配置文件 + sn = ReadCal.readFileSNbyIDDevice(fpath) + if sn == self.ui_sn: + return True + return False + + def __get_raw_wl_from_datafile(self, fpath) -> None: + # 读取配置文件 + _, raw_wl = ReadCal.read_columns_set_by_mark(fpath, FILE_MARK, 0) + self.raw_wavelength = self.convert_str_2_float_list (raw_wl[0]) + self.raw_wavelength_np = np.array(raw_wl[0]) + return None + + def __prepare_for_save(self,) -> bool: + self.mydir.setBaseDir(self.output_dir) + self.mydir.newDirIfNot() + self.mydir.newFileIfNot(self.ui_sn+SAVE_EXT_NAME) + + self.mydir.setHeader(self.output_wavelength, TOKEN, self.ui_sn) + if self.mydir.checkHeader() == 0: + self.mydir.writeHeader() + if self.mydir.checkHeader() == -1: + # self.popDialog(" 文件头不一致, 请备份到其他目录,并在该目录下删除") + raise MyException(" 文件头不一致, 请备份到其他目录,并在该目录下删除") + + def interpo_pure_water(self): + self.purewater_after_interp = np.interp( + np.array(self.output_wavelength) + , np.array(self.purewater_wavelength) + , np.array(self.purewater_attenuation) + ) + pass + + def correction_turbidity(self, data:np.ndarray ): + '''浊度校正, 吸光度 + 0 : 默认11项平均 + 1 : 720 + 2 : 不浊度校正 + ''' + log.debug( "correction_turbidity .....",__name__, 'correction_turbidity' ) + if self.cfg['algorithm']['A720'] == 0: + count = data.shape[0] + tmp = 0.0 + for i in range(count-11,count,1): + tmp = tmp + data[i] + tmp = tmp/11 + return data - tmp + pass + if self.cfg['algorithm']['A720'] == 1: + count = data.shape[0] + tmp = data[count] - (self.output_wavelength[count]-720) * (data[count] -data[count-1]) \ + / (self.output_wavelength[count]-self.output_wavelength[count-1]) + print(f"tmp .... {tmp}") + return data-tmp + pass + if self.cfg['algorithm']['A720'] == 2: + return data + return data + pass + + def correction_pure_water(self, data:np.ndarray ): + '''浊度校正 + 0 : 不变 + 1 : 减去纯水 + ''' + if self.cfg['algorithm']['PureWater'] == 0: + return data + pass + if self.cfg['algorithm']['PureWater'] == 1: + return data - self.purewater_after_interp + pass + return data + pass + + def __get_cal_info(self ): + log.info(f" == ",__name__,'__get_cal_info') + caldir = self.dir.joinpath(CAL_DIR ) + basis_fpath = caldir.joinpath( "Basis aq_" + self.cfg['device']['UISN'] + ".dat") + reflectivity_fpath = caldir.joinpath( "Reflectivity_" + self.cfg['device']['UISN'] + ".dat") + + if basis_fpath.exists(): + _, res_data = ReadCal.read_columns_sets_by_mark( + basis_fpath, FILE_MARK, 1) + self.basis = self.convert_str_2_float_list( res_data[0][0] ) + if reflectivity_fpath.exists(): + _, res_data = ReadCal.read_columns_sets_by_mark( + reflectivity_fpath, FILE_MARK, 1) + self.reflectivity = self.convert_str_2_float_list( res_data[0][0] ) + + def __get_purewater_wl_and_data(self ): + log.debug(f" ok ",__name__,'__get_purewater_wl_and_data') + caldir = self.dir.joinpath(CAL_DIR ) + cal_fpath = caldir.joinpath( PURE_WATER_FNAME) + if cal_fpath.exists(): + _, res_data = ReadCal.read_columns_sets_by_mark( + cal_fpath, FILE_MARK, 0, 1) + self.purewater_wavelength = self.convert_str_2_float_list( res_data[0][0]) + self.purewater_attenuation = self.convert_str_2_float_list(res_data[0][1]) + + def set_serial(self, )-> None: + self.uart.set_serial_para( + self.cfg['comsetting']['port'] + ,self.cfg['comsetting']['baudrate'] + ,self.cfg['comsetting']['bytesize'] + ,self.cfg['comsetting']['parity'] + ,self.cfg['comsetting']['stopbit'] + ) + + def set_modbus(self, beginaddress, step)-> None: + self.uart.set_modbus( + self.cfg['register']['slaveaddress'] + ,self.cfg['register']['functioncode'] + ,beginaddress + ,step + ) + + def sn_uart_thread(self, func)-> None: + self.set_serial() + self.uart_thread.remove_tasks() + self.set_modbus( self.cfg['register']['SNAddress'], self.cfg['register']['SNLen'] ) + self.uart_thread.add_task( self.device_sn, args=(func,) ) + self.uart_thread.sequently_execute_tasks() + pass + + def wl_uart_thread(self, func)-> None: + if self.devicesn == []: + raise Exception(" 请读取设备序列号!!") + self.res = b'' + self.set_serial() + self.uart_thread.remove_tasks() + for i in range(self.cfg['register']['count']): + log.debug(f" -> i {i}", __name__,"wl_uart_thread") + self.set_modbus( self.cfg['register']['WLBeginAddress'] + i*120, 120 ) + log.debug(f" command -> {self.uart.command.hex()} ") + self.uart_thread.add_task( self.device_wl, args=() ) + self.uart_thread.sequently_execute_tasks() + self.uart_thread.remove_tasks() + # self.uart_thread.add_task_2_act( ) + # self.uart_thread.execute_one_act() + self.raw_wavelength = self.convert_buf_2_float(self.res) + # 获得截取的开始 结束点 + self.get_begin_end() + self.get_output_wavelength() + msg = "起始波长 : "+str(self.output_wavelength[0]) +" , 结束波长 : "+ str(self.output_wavelength[-1]) + log.info(msg) + self.__set_msg ("notice", msg ) + pub.sendMessage(self.msg) + func( self.output_wavelength ) + # self.__set_msg( "wl", {} ) + # pub.sendMessage("update", msg= self.msg) + + def log_uart_thread(self, func)-> None: + if self.output_wavelength == [] : + raise Exception("没有波长文件,请读取设备波长!!") + if self.purewater_after_interp == [] : + self.interpo_pure_water() + # 准备测量,保存文件的准备 + self.__prepare_for_save() + + self.res = b'' + self.set_serial() + self.uart_thread.remove_tasks() + for i in range(self.cfg['register']['count']): + self.set_modbus( self.cfg['register']['DataBeginAddress'] + i * 120, 120 ) + self.uart_thread.add_task( self.device_log, args=( ) ) + self.uart_thread.sequently_execute_tasks() + self.uart_thread.remove_tasks() + pass + data = self.convert_buf_2_float(self.res,FLOAT_RESERVE_BIT) + data = data[self.begin:self.end] + log.info( f"log data : {data}",__name__,'log_uart_thread' ) + abs_coeff_with_water = self.get_absorption_coeff( + data, + self.basis[self.begin:self.end], + self.reflectivity[self.begin:self.end], + self.purewater_after_interp ) + data = self.correction_pure_water( abs_coeff_with_water ) + # 保存文件 + tm = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()) + self.mydir.setContent( data , TOKEN, tm ) + self.mydir.writeContent() + func(tm,data) + + def device_sn(self, func)-> None: + self.res =b'' + self.uart.disconnect() + self.uart.connect() + self.uart.write() + self.res = self.uart.OneMeasure() + self.devicesn = self.res[-6:-2].decode() + self.res = b'' + func( self.devicesn ) + # pub.sendMessage("update",msg=self.msg) + + def device_wl(self, )-> None: + # self.res =b'' + # log.warning(" -->", __name__, "device_wl") + self.uart.disconnect() + self.uart.connect() + self.uart.write() + tmp = self.uart.OneMeasure() + self.res = self.res + tmp[3:len(tmp)-2] + + def device_log(self, )-> None: + # self.res =b'' + self.uart.disconnect() + self.uart.connect() + self.uart.write() + tmp = self.uart.OneMeasure() + self.res = self.res + tmp[3:len(tmp)-2] + + def convert_buf_2_float(self, buff, bit = 3 ,byteOrder= "big" )-> None: + res = [] + log.debug(f" === {len(buff)}== {buff}", __name__, 'convert_buf_2_float') + len_ = len(buff) + if len_%4 != 0: + return res + if byteOrder == "big": + for i in range( int(len_/4) ): + tmp = struct.unpack(">f", buff[i*4: i*4+4] ) + res.append( round(tmp[0],bit) ) + else: + for i in range( int(len_/4) ): + tmp = struct.unpack(">f", buff[i*4: i*4+4] ) + res.append(round(tmp[0],bit)) + return res + pass + + def convert_str_2_float_list(self, lst )-> None: + res = [] + for l in lst: + res.append(float(l)) + return res + pass + + def set_raw_wavelength_from_device(self, lst): + self.raw_wavelength = lst + pass + + + def get_absorption_coeff( self, data, refl, basis_aq, abs_coff_pw ): + """ + @description : d 一组数据 + """ + r = OSCAR_R + r0 = OSCAR_R0 + abs_coeff_with_pw =[] + + # log.info( f" do_leastsq -> {len(data)} " ) + if len(data) == len( refl) or len(data) == len( basis_aq) or len(data) == len( abs_coff_pw) : + + for fa,fb,rou,ab in zip(data, basis_aq,refl, abs_coff_pw ): + Tab = float(fa)/float(fb) + #print( "Tab %s" %Tab) + EXP_ab_r0 = np.exp(-1*float(ab)*r0) + #print ( "Exp_ab_r0 %s" %EXP_ab_r0) + Ps_ab_r = ( 1 - ( 2*float(ab)*r + 1) * np.exp (-2*float(ab)*r) ) /( 2*float(ab)*float(ab)*r*r ) + #print ( "Ps_ab_r %s" %Ps_ab_r) + # EXP_aa_r0 = exp(-1*aa*r0) + # Ps_aa_r = ( 1 - ( 2*aa*r + 1) * exp (-2*aa*r) ) /( 2*aa*aa*r*r ) + + def f(x): + return Tab*EXP_ab_r0*Ps_ab_r - \ + np.exp(-1*x*r0)*( 1 - ( 2*x*r + 1) * np.exp (-2*x*r) ) /( 2*x*x*r*r ) - \ + float(rou)* Tab *EXP_ab_r0*Ps_ab_r*( 1 - ( 2*x*r + 1) * np.exp (-2*x*r) ) /( 2*x*x*r*r ) + \ + float(rou)* np.exp(-1*x*r0)*Ps_ab_r *( 1 - ( 2*x*r + 1) * np.exp (-2*x*r) ) /( 2*x*x*r*r ) + + result_with_pw = leastsq(f, 1)[0][0] + # print( result_with_pw ) + + # 添加到数组 + abs_coeff_with_pw.append( result_with_pw ) + return abs_coeff_with_pw + +if __name__ == '__main__': + data = np.array([3,4,5,6]) + print(data.shape[0]) + print(data[3]) + print(data-1) + + + + + + + + # if self.syscfg['retrieve']['enable'] == 0: + # self.mydir.setHeader(self.raw_wavelength,TOKEN,self.ui_sn) + # if self.mydir.checkHeader()==0: + # self.mydir.writeHeader() + # if self.mydir.checkHeader()==-1: + # self.popDialog(" 文件头不一致, 请备份到其他目录,并在该目录下删除") + # raise MyException(" 文件头不一致, 请备份到其他目录,并在该目录下删除") + # res_time,res_data = ReadCal.read_columns_sets_by_mark( fl, FILE_MARK, 1 ) + # for i in range( len(res_time) ): + # self.__deal_one_measure_time_data(res_time[i], res_data[i]) + # pass + # pass + # # 需要插值处理波长 + # if self.syscfg['retrieve']['enable'] == 1: + # self.mydir.setHeader(self.new_wavelength.tolist(),TOKEN,self.ui_sn) + # if self.mydir.checkHeader()==0: + # self.mydir.writeHeader() + # if self.mydir.checkHeader()==-1: + # self.popDialog(" 文件头不一致, 请备份到其他目录,并在该目录下删除") + # raise MyException(" 文件头不一致, 请备份到其他目录,并在该目录下删除") + + # # res_data 不用带回调的函数callback 会导致多组数据拼接?? + # res_time,res_data = ReadCal.read_columns_sets_by_mark( fl, FILE_MARK, 1 ) + + # log.warning(f" ==== {len(res_time)}" ) + # log.warning(res_time) + # log.warning(f" ==== {len(res_data[0])}" ) + # log.warning(f" ==== { res_data[0] }" ) + + # for i in range( len(res_time) ): + # self.__deal_one_measure_time_data(res_time[i], res_data[0][i]) + # pass + # pass \ No newline at end of file diff --git a/readcal.py b/readcal.py new file mode 100644 index 0000000..7a00e66 --- /dev/null +++ b/readcal.py @@ -0,0 +1,1020 @@ +from mylogger import log +from myexception import MyException +from typing import Tuple,List,Optional,Union,Callable +from pathlib import Path, PurePath +from myconfig import MyConfig,DeviceType,FILE_MARK,CURRENT_DIR,CAL_DIR,DATA_DIR,SAVE_EXT_NAME,\ + INTERVAL,SEPARATOR + +class ReadCal(): + def __init__(self) -> None: + pass + + # 数据加时间值 + @staticmethod + def read_columns_set_by_mark(fpath:Path, mark:list, *column ) -> Tuple[str,List] : + # def read_column_1set_by_mark(fpath:str, column:int, *args ) -> Tuple[ str, List ] : + ''' + return: time:str List + mark : ['Spectrum','DATA'] + default end with "[END]" + column参数直接写,如: 0,1,2 + ''' + log.info(f"read_column_1set_by_mark : \ + {fpath} , mark:{mark} , column:{column}", __name__, "", "") + + # 处理mark args[0] = Spectrum + if len(mark) != 2: + log.error( f"read_column_1set_by_mark() wrong args ",__name__, "", "" ) + raise MyException( f"read_column_1set_by_mark() wrong args " ) + + if len(column) == 0: + log.error(f"read_column_1set_by_mark(), no column para, pls input column ",__name__, "", "" ) + raise MyException( f"read_column_1set_by_mark() , pls input column " ) + + if len( mark ) == 0: + mark_1 = '[Spectrum]' + mark_2 = '[DATA]' + + mark_1 = '['+ mark[0] +']' + mark_2 = '['+ mark[1] +']' + res = [] + sn = ReadCal.readFileSNbyIDDevice(fpath) + # 预备返回数据结构 + # res_time = [] + res_data = [] + columnLen = len(column) + for i in range(columnLen): + res_data.append( [] ) + + with fpath.open('r') as f_handle: + rflag = 0 + # res = [] + # res_time = [] + # res_data = [] + + for line in f_handle: + if mark_1 in line and rflag == 0: + log.debug(f" find {mark_1}", __name__, "", "" ) + rflag += 1 + continue + + if mark_2 in line and rflag > 3 : + log.debug(f" find {mark_1} end ", __name__, "", "" ) + rflag = 0 + continue + + # 获取时间 + if rflag == 1 : + data = line.strip('\n').strip(' ').split('=') + if data[0].strip() == "DateTime" : + log.debug(f" find {mark_1} -> DateTime {data[1]} ", __name__, "", "" ) + time_ = data[1].strip() + rflag += 1 + continue + + if rflag == 2 and ( mark_2 in line ) : + log.debug(f" find {mark_2} -> ", __name__, "", "" ) + rflag += 1 + continue + + if rflag == 3 : + if mark_2 not in line: + # log.debug(f" get data {line}", __name__, "", "" ) + data = line.strip('\n').strip(' ').split(' ') + # 忽略第一行,第一行0开头,保存积分时间的 + if data[0].strip() == "0" : + continue + else: + # if data[1] != "-NAN" and data[1] != "NAN" and data[1] != "+NAN" : + # 处理多列 + for i in range(columnLen): + # res_time.append( time_ ) + # print(f" ==== {data}") + res_data[i].append( data[column[i]] ) + continue + + if rflag == 3 and ( mark_2 in line ) : + log.debug(f" find {mark_2} end , line: {line} ", __name__, "", "" ) + rflag += 1 + continue #需要继续让其找到 + + if rflag == 4: + log.debug(f" job done......", __name__, "", "" ) + res_time = time_ + # res_data.append( res ) + # 只读一组数据就 break + rflag += 1 + # res = [] + # rflag = 0 + + if rflag == 5: + log.debug(f" job done, break...", __name__, "", "" ) + break + return ( res_time, res_data) + pass + + # 数据加时间值 + @staticmethod + def read_columns_sets_by_mark(fpath:Path, mark:list, *column + ) -> Tuple[List[str],List[List]] : + # def read_column_1set_by_mark(fpath:str, column:int, *args ) -> Tuple[ str, List ] : + ''' + @desc: 获取多列数据,且为多套数据,非单套数据 + @return: + res_time + ['2011-01-28 00:00:32', '2011-01-28 00:01:04', '2011-01-28 00:04:05', '2011-01-28 00:04:17'] + res_data [ [[,,,]], [[,,,]], [[,,,]], [[,,,]]] + 取 res_data[0] + @args : ['Spectrum','DATA'] + default end with "[END]" + ''' + log.info(f"read_column_1set_by_mark : \ + {fpath} , mark:{mark} , column:{column}", __name__, "", "") + + # 处理mark args[0] = Spectrum + if len(mark) != 2: + log.error( f"read_columns_sets_by_mark() wrong args ",__name__, "", "" ) + raise MyException( f"read_columns_sets_by_mark() wrong args " ) + + if len(column) == 0: + log.error(f"read_columns_sets_by_mark(), no column para, pls input column ",__name__, "", "" ) + raise MyException( f"read_columns_sets_by_mark() , pls input column " ) + + if len( mark ) == 0: + mark_1 = '[Spectrum]' + mark_2 = '[DATA]' + + mark_1 = '['+ mark[0] +']' + mark_2 = '['+ mark[1] +']' + res = [] + sn = ReadCal.readFileSNbyIDDevice(fpath) + # 预备返回数据结构 + res_data = [] + res_time = [] + res = [] + columnLen = len(column) + for i in range(columnLen): + # res_time.append( [] ) + res.append( [] ) + + with fpath.open('r') as f_handle: + rflag = 0 + + for line in f_handle: + if mark_1 in line and rflag == 0: + log.debug(f" find {mark_1}", __name__, "", "" ) + rflag += 1 + continue + + if mark_2 in line and rflag > 3 : + log.debug(f" find {mark_1} end ", __name__, "", "" ) + rflag = 0 + continue + + # 获取时间 + if rflag == 1 : + data = line.strip('\n').strip(' ').split('=') + if data[0].strip() == "DateTime" : + log.debug(f" find {mark_1} -> DateTime {data[1]} ", __name__, "", "" ) + time_ = data[1].strip() + rflag += 1 + continue + + if rflag == 2 and ( mark_2 in line ) : + log.debug(f" find {mark_2} -> ", __name__, "", "" ) + rflag += 1 + continue + + if rflag == 3 : + if mark_2 not in line: + # log.debug(f" get data {line}", __name__, "", "" ) + data = line.strip('\n').strip(' ').split(' ') + # 忽略第一行,第一行0开头,保存积分时间的 + if data[0].strip() == "0" : + continue + else: + # if data[1] != "-NAN" and data[1] != "NAN" and data[1] != "+NAN" : + # 处理多列 + for i in range(columnLen): + # res_time.append( time_ ) + res[i].append( data[column[i]] ) + continue + + if rflag == 3 and ( mark_2 in line ) : + log.debug(f" find {mark_2} end , line: {line} ", __name__, "", "" ) + rflag += 1 + continue #需要继续让其找到 + + if rflag == 4: + log.debug(f" job done......", __name__, "", "" ) + res_time.append( time_ ) + res_data.append( res ) # 可能导致不同组数据拼接起来???? + rflag += 1 + # res = [] + # rflag = 0 + + if rflag == 5: + log.debug(f" job done, break...", __name__, "", "" ) + rflag = 0 + continue + + log.debug(f" res.time len {len(res_time)} , \ + res.data len {len(res_data)} , ", __name__, "", "" ) + + return res_time, res_data + + # 数据加时间值 + @staticmethod + def read_columns_sets_by_mark_callback(fpath:Path, mark:list, callback:Callable, *column ) : + ''' + @desc: 获取多列数据,且为多套数据,非单套数据 + @return: + res_time + ['2011-01-28 00:00:32', '2011-01-28 00:01:04', '2011-01-28 00:04:05', '2011-01-28 00:04:17'] + res_data [ [[,,,]], [[,,,]], [[,,,]], [[,,,]]] + 取 res_data[0] + @args : ['Spectrum','DATA'] + default end with "[END]" + ''' + log.debug(f"read_column_1set_by_mark : \ + {fpath} , mark:{mark} , column:{column}", __name__, "", "") + + # 处理mark args[0] = Spectrum + if len(mark) != 2: + log.error( f"read_columns_sets_by_mark() wrong args ",__name__, "", "" ) + raise MyException( f"read_columns_sets_by_mark() wrong args " ) + + if len(column) == 0: + log.error(f"read_columns_sets_by_mark(), no column para, pls input column ",__name__, "", "" ) + raise MyException( f"read_columns_sets_by_mark() , pls input column " ) + + if len( mark ) == 0: + mark_1 = '[Spectrum]' + mark_2 = '[DATA]' + + mark_1 = '['+ mark[0] +']' + mark_2 = '['+ mark[1] +']' + + # 预备返回数据结构 + res_data = [] + res_time = [] + res = [] + sn = ReadCal.readFileSNbyIDDevice(fpath) + + columnLen = len(column) + for i in range(columnLen): + # res_time.append( [] ) + res.append( [] ) + + with fpath.open('r') as f_handle: + rflag = 0 + + for line in f_handle: + if mark_1 in line and rflag == 0: + log.debug(f" find {mark_1}", __name__, "", "" ) + rflag += 1 + continue + + if mark_2 in line and rflag > 3 : + log.debug(f" find {mark_1} end ", __name__, "", "" ) + rflag = 0 + continue + + # 获取时间 + if rflag == 1 : + data = line.strip('\n').strip(' ').split('=') + if data[0].strip() == "DateTime" : + log.debug(f" find {mark_1} -> DateTime {data[1]} ", __name__, "", "" ) + time_ = data[1].strip() + rflag += 1 + continue + + if rflag == 2 and ( mark_2 in line ) : + log.debug(f" find {mark_2} -> ", __name__, "", "" ) + rflag += 1 + continue + + if rflag == 3 : + if mark_2 not in line: + # log.debug(f" get data {line}", __name__, "", "" ) + data = line.strip('\n').strip(' ').split(' ') + # 忽略第一行,第一行0开头,保存积分时间的 + if data[0].strip() == "0" : + continue + else: + # if data[1] != "-NAN" and data[1] != "NAN" and data[1] != "+NAN" : + # 处理多列 + for i in range(columnLen): + res[i].append( data[column[i]] ) + continue + + if rflag == 3 and ( mark_2 in line ) : + log.debug(f" find {mark_2} end , line: {line} ", __name__, "", "" ) + rflag += 1 + continue #需要继续让其找到 + + if rflag == 4: + log.debug(f" job done......", __name__, "", "" ) + # callable , not return。 每读出一组就回调,不建议。频繁读写硬盘 + # callback(time_, res) + res_time.append( time_ ) + res_data.append( res ) + rflag += 1 + # res = [] + # rflag = 0 + + if rflag == 5: + log.debug(f" job done, break...", __name__, "", "" ) + rflag = 0 + continue + + # callable , not return。 一个文件读完直接处理 + + callback(sn, res_time, res_data) + + # res_time ['2011-01-28 00:00:32', '2011-01-28 00:01:04', '2011-01-28 00:04:05', '2011-01-28 00:04:17'] + # res_data [ [[,,,]], [[,,,]], [[,,,]], [[,,,]]] 取 res_data[0] + log.debug(f" res.time len {len(res_time)} , \ + res.data len {len(res_data)} , ", __name__, "", "" ) + + # return ( res_time, res_data) + + @staticmethod + def readDataIPinfo(fpath:Path, mark:list, callback:Callable ): + ''' + SAMIP sensor ,Inclination Pressure, InclX InclY Pressure + ''' + log.debug(f"readDataIPinfo : {fpath} , mark:{mark} , ", __name__, "", "") + + # 处理mark args[0] = Spectrum + if len(mark) != 2: + log.error( f"readDataIPinfo() wrong args ",__name__, "", "" ) + raise MyException( f"readDataIPinfo() wrong args " ) + + if len( mark ) == 0: + mark_1 = '[Spectrum]' + mark_2 = '[DATA]' + + mark_1 = '['+ mark[0] +']' + + # 预备返回数据结构 + res_data = [] + res_time = [] + res = [] + tags = ['InclX' , 'InclY', 'Pressure'] + + with fpath.open('r') as f_handle: + rflag = 0 + for line in f_handle: + if mark_1 in line and rflag == 0: + log.debug(f" find {mark_1}", __name__, "", "" ) + rflag += 1 + continue + if mark_1 in line and rflag > 5: + log.debug(f" find {mark_1} end", __name__, "", "" ) + rflag = 0 + continue + # 获取时间 + if rflag == 1 : + data = line.strip('\n').strip(' ').split('=') + if data[0].strip() == "DateTime" : + log.debug(f" find {mark_1} -> DateTime {data[1]} ", __name__, "", "" ) + time_ = data[1].strip() + rflag += 1 + continue + if rflag == 2: + if "[" not in line : + data = line.strip('\n').strip(' ').split('=') + # RAMSES 数据通过MethodName 获得传感器序列号 + if data[0].strip() in tags : + res.append( data[1].strip(' ') ) + rflag += 1 + if rflag == 5: + res_time.append(time_) + res_data.append(res) + rflag = 0 + pass + callback(res_time,res_data) + return (res_time,res_data) + + @staticmethod + def readSamSNFromIni( fpath:Path ): + """ + @description : 依据文件路径获得samsn, 兼容 SAM SAMIP传感器 + """ + + with fpath.open('r') as f_handle: + for line in f_handle: + # IDDevice = SAM_85AF + ln = line.strip('\n').strip(' ').split('=') + if ln[0].strip() == "IDDevice": + if ln[1].strip().split('_')[0] == "SAM": + return ln[1].strip().split('_')[1] + return None + pass + + @staticmethod + def readIPCalFromIni( fpath:Path ): + """ + @description : 依据文件路径获得IPCal IP标定信息 + """ + ipcal = {} + with fpath.open('r') as f_handle: + flag = 0 + for line in f_handle: + # IDDevice = SAM_85AF + ln = line.strip('\n').strip(' ').split('=') + + if flag == 0 and ln[0].strip() == "IDDevice": + if ln[1].strip().split('_')[0] == "IP": + ipcal["IPSN"] = ln[1].strip().split('_')[1] + flag += 1 + continue + + if flag == 1 and "[" in line: + flag += 1 + continue + + if flag == 2: + if "[" in line: + flag = flag + 1 + + if not "[" in line: + line_ = line.strip('\n').strip(' ').split('=') + ipcal.update({line_[0].strip():line_[1].strip()}) + + if flag == 3: + break + + return ipcal + + @staticmethod + def readSAMCalFromIni( fpath:Path ): + """ + @description : 依据文件路径获得SAMCal SAM标定信息 + """ + samcal = {} + with fpath.open('r') as f_handle: + flag = 0 + for line in f_handle: + # IDDevice = SAM_85AF + line_ = line.strip('\n').strip(' ').split('=') + if flag == 0 and line_[0].strip() == "IDDevice": + if line_[1].strip().split('_')[0] == "SAM": + samcal["SAMSN"] = line_[1].strip().split('_')[1] + flag += 1 + continue + + if flag == 1 and "[" in line: + flag += 1 + continue + + if flag == 2: + if "[" in line: + flag = flag + 1 + + if not "[" in line: + line_ = line.strip('\n').strip(' ').split('=') + samcal.update({line_[0].strip():line_[1].strip()}) + + if flag == 3: + break + return samcal + + @staticmethod + def readFileSNbyIDDevice(fpath:Path): + sn_from_file = '' + with fpath.open('r') as f_handle: + rflag = 0 + for line in f_handle: + if '[Spectrum]' in line and '[END]' not in line and rflag == 0: + rflag += 1 + pass + if rflag == 1: + data = line.strip('\n').strip(' ').split('=') + # RAMSES 数据通过MethodName 获得传感器序列号 + if data[0].strip() == "IDDevice": + sn_from_file = data[1].strip(' ').split('_')[1] + break + return sn_from_file + + @staticmethod + def readDatafileSNbyMethodName(fpath:Path): + ''' + SAMIP SAM的数据文件中, MethodName对应的值都是 SAM_{SAMSN} + 读SAMIP的数据,建议用 {SAMSN}的处理 + ''' + sn_from_file = '' + with fpath.open('r') as f_handle: + rflag = 0 + for line in f_handle: + if '[Spectrum]' in line and '[END]' not in line and rflag == 0: + rflag += 1 + pass + if rflag == 1: + data = line.strip('\n').strip(' ').split('=') + # RAMSES 数据通过MethodName 获得传感器序列号 + if data[0].strip() == "MethodName": + sn_from_file = data[1].strip(' ').split('_')[1] + break + return sn_from_file + + +if __name__ == "__main__": + log.info(f"******** main read *********", __name__, "", "") + + # path = PurePath() + # print(path) + + pass + + # def read_data_sn(self,fpath): + # with open(fpath, 'r') as f_handle: + # rflag = 0 + # for line in f_handle: + # if '[Spectrum]' in line and '[END]' not in line and rflag == 0: + # rflag += 1 + # pass + # if rflag == 1 : + # data = line.strip('\n').strip(' ').split('=') + # if data[0].strip() == "IDDevice" : + # return data[1].strip(' ').split('_')[1] + # pass + + # def read_data1(self,fpath): + # with open(fpath, 'r') as f_handle: + # rflag = 0 + # res = [] + # res_time = [] + # res_data = [] + + # for line in f_handle: + # if '[Spectrum]' in line and '[END]' not in line and rflag == 0: + # rflag += 1 + # pass + + # if '[Spectrum]' in line and '[END]' in line : + # rflag = 0 + # pass + + # # 获取时间 + # if rflag == 1 : + # data = line.strip('\n').strip(' ').split('=') + # if data[0].strip() == "DateTime" : + # time_ = data[1].strip() + # rflag += 1 + + # if rflag == 2 and ( '[DATA]' in line or '[Data]' in line ) : + # rflag += 1 + + # if rflag == 3 : + # data = line.strip('\n').strip(' ').split(' ') + + # if int(data[0].strip()) == 0 : + # pass + # else: + # # if data[1] != "-NAN" and data[1] != "NAN" and data[1] != "+NAN" : + + # res.append( float(data[1] ) ) + # if rflag == 3 and '[' in line and ']' in line: + # rflag += 1 + # if rflag == 4: + # # 这个地方 + # # self. __save_absorbance_data( res_time, res, sn ) + # res_time.append( time_ ) + # res_data.append( res ) + # # ?? 可以调用函数直接处理 + # # DealResult.deal_one_data(time_,res) + # res = [] + # rflag = 0 + # # return [['data']] + # pass + + + # def read_data_column( self,fpath, column=1 ): + # column_ = 1 + # if int(column_) : + # column_ = int(column_) + # pass + # else: + # pass + + # with open(fpath, 'r') as f_handle: + # rflag = 0 + # res = [] + # res_time = [] + # res_data = [] + + # for line in f_handle: + # if '[Spectrum]' in line and '[END]' not in line and rflag == 0: + # rflag += 1 + # pass + + # if '[Spectrum]' in line and '[END]' in line : + # rflag = 0 + # pass + + # # 获取时间 + # if rflag == 1 : + # data = line.strip('\n').strip(' ').split('=') + # if data[0].strip() == "DateTime" : + # time_ = data[1].strip() + # rflag += 1 + + # if rflag == 2 and ( '[DATA]' in line or '[Data]' in line ) : + # rflag += 1 + + # if rflag == 3 : + # data = line.strip('\n').strip(' ').split(' ') + + # if int(data[0].strip()) == 0 : + # pass + # else: + # res.append( float(data[column_] ) ) + # if rflag == 3 and '[' in line and ']' in line: + # rflag += 1 + # if rflag == 4: + # # 这个地方 + # # self. __save_absorbance_data( res_time, res, sn ) + # # res_time.append( time_ ) + # # res_data.append( res ) + # # ?? 可以调用函数直接处理 + # return time_, res + + # # return [['data']] + # pass + + # def read_data_wl( self, fpath ): + # wl = self.read_data_column( fpath, column=0 ) + # pass + + # def get_cal_file(self,sn): + # sn_ = sn + # file_ = {} + # if open( os.path.join( CAL_PATH, "SAM_"+sn_+"ini" ),"r"): + # file_ = { + # "type": "SAM", + # "back":"Back_SAM_", + # "cal":"Cal_SAM_", + # "calaq":"CalAQ_SAM_", + # "ini":"SAM_", #ini + # "immersion":"immersion_factors_Lu.DAT" + # } + # return file_ + # if open( os.path.join( CAL_PATH, "SAMIP_"+ sn_ +"_ALL.ini" ),"r"): + # file_ = { + # "type": "SAMIP", + # # "back":"Back_SAM_" + sn_ + CAL_EXT_NAME, + # # "cal":"Cal_SAM_" + sn_ + CAL_EXT_NAME, + # # "calaq":"CalAQ_SAM_" + sn_ + CAL_EXT_NAME, + # "ini":"SAMIP_"+sn+"_ALL.ini", #ini + # "immersion":"immersion_factors_Lu.DAT" + # } + # if file_['ini'] : + # samsn = self.read_ini(file_['ini'], "SAMSN") + # file_.update("cal", "Cal_SAM_" + samsn + CAL_EXT_NAME) + # file_.update("calaq", "CalAQ_SAM_" + samsn + CAL_EXT_NAME) + # file_.update("back", "Back_SAM_" + samsn + CAL_EXT_NAME) + # return file_ + # return + + # def read_cal(self,sn): + # # SAM SAMIP 不同 + # self.cal_data= {} + # # 1. 依据序列号读 ini, 判读是否有文件 SAM_8578.ini SAMIP_50BB_ALL.ini + # self.calfile = self.get_cal_file(sn) # 其中sam的是错误的 + + # # 2 读ini 文件错误 + + # cal_data = {} + # for key in self.calfile: + # if key == "immersion" : + # path_ = os.path.join( CAL_PATH, self.calfile[key] ) + # content_ = [self.read_data_column( path_, column=0 )[1]] + # content_.append( self.read_data_column( path_, column=0 )[1] ) + # cal_data.update({key:content_}) + + # if key == "cal" : + + # path_ = os.path.join( CAL_PATH, self.calfile[key] ) + # content_ = self.read_data_column( path_, column=0 ) + # cal_data.update({key:content_}) + + # if key == "back" : + # path_ = os.path.join( CAL_PATH, self.calfile[key] ) + # content_ = self.read_data_column( path_, column=0 ) + # cal_data.update({key:content_}) + + # if key == "calaq" : + # path_ = os.path.join( CAL_PATH, self.calfile[key] ) + # content_ = self.read_data_column( path_, column=0 ) + # cal_data.update({key:content_}) + + # if key == "ini" : + # cal_data.update({ "samcal" : self.read_ini( os.path.join( CAL_PATH, self.calfile[key] ), "SAMCAL" ) }) + # cal_data.update({ "ipcal" : self.read_ini( os.path.join( CAL_PATH, self.calfile[key] ), "IPCAL" ) }) + + # pass + + # DealResult.deal_cal(cal_data) + + # pass + + # def read_data(self,fname,lst): + # """ + # @description : 线程守护读取数据文件 ,循环读取 + # 考虑一次读取多组,只读一列的情况 + # sn ,begin,end, 指定读的列 + # 返回:[ [[第一组时间],[第二组时间] .... ], [ [第一组data],[第二组data] ...] ] + # RAMSES 要考虑 : InclX = -6.42, InclY = -6.5625 , Pressure = 6.61394049205538 + # 需要读一组波长出来 + # """ + # log.info( ":::::::::::: Class : %s -> Function :__read_data " % ( __name__, ) ) + # log.info( " __read_data : lst %s" % ( lst, ) ) + # sn = lst[0] + # begin = lst[1] + # end = lst[2] + # column = lst[3] + # samip_sn= lst[4] + + # # 检查 sn--- 不检查sn ,读数据就 成csv + + # # 读取一组数据的0列作为波长??? + + # # if is_sn_ok : + + # log.info( "正在处理文件 .... " + fname ) + # with open(fname, 'r') as f_handle: + # time_ = "" + # rflag = 0 + # intlx = 0.0 + # intly = 0.0 + # pressure = 0.0 + # res = [] + # res_time = [] + # res_data = [] + + # for line in f_handle: + # if rflag == 0 and '[Spectrum]' in line and '[END]' not in line : + # rflag += 1 + # pass + + # if '[Spectrum]' in line and '[END]' in line : + # rflag = 0 + # pass + + # # 获取时间, InclX, InclY ,Pressure + # if rflag == 1 : + # data = line.strip('\n').strip(' ').split('=') + # if data[0].strip() == "DateTime" : + # time_ = data[1].strip() + # rflag += 1 + # # InclX, InclY ,Pressure + + # if rflag == 2: + # data = line.strip('\n').strip(' ').split('=') + + # if data[0].strip() == "InclX" : + # intlx = data[1].strip() + + # if data[0].strip() == "InclY" : + # intly = data[1].strip() + + # if data[0].strip() == "Pressure" : + # pressure = data[1].strip() + + + # # DATA set 结束添加数据 + # if rflag == 4 and '[DATA]' in line and '[END]' in line: + # # time.sleep(10) + # res_time.append( [time_,intlx,intly,pressure] ) + # res_data.append( res ) + # res = [] + # rflag += 1 + + # if rflag == 3 : + # data = line.strip('\n').strip(' ').split(' ') + # # print("rflag %s +++++++++++++++++++++++++++++++++ %s" %(rflag,data) ) + # if data[0] != "0" and data[1] != "-NAN" and data[1] != "NAN" and data[1] != "+NAN" : #去掉第一行 0, 对应的积分时间 2^(n+1) + # # print("append %s -- %s" %(data[0],data[1]) ) + # res.append( float( data[column-1] ) ) + # if data[0] != "0" and float(data[0]) > 950 : + # # print("> 950... %s %s" %(data[0],data[1]) ) + # rflag += 1 + + # # 处理data 部分 + # if rflag == 2 and '[DATA]' in line and '[END]' not in line: + # # print("rflag %s +++++++++++++++++++++++++++++++++ data+1 " %(rflag,) ) + # rflag += 1 + + + # if rflag == 5: + # DealResult.deal_ramses_data(time_, [[intlx,intly,pressure], res]) + # # 这个地方 + # # self. __save_absorbance_data( res_time, res, sn ) + # # print("rflag 4 ......................") + # # res_time.append( [time_,intlx,intly,pressure] ) + # # print(" append time %s " %res_time) + # # res_data.append( res ) + # res = [] + # rflag = 0 + # intlx = 0.0 + # intly =0.0 + # pressure =0.0 + # # else: + # # return [] + + # log.info( "已经转换完文件,正在保存... " + fname ) + + # # 分析处理数据,还是返回原始数据 或空 ?? + # log.info( " Function :__read_data %s - %s " % ( res_time[0] ,res_data[0] ) ) + + + # # # 光强保存文件路径 + # # fpath = os.path.join(INTENSITY_PATH, samip_sn + SAVE_EXT_NAME ) + # # fpath_IP = os.path.join(INTENSITY_PATH, samip_sn + "_IP" + SAVE_EXT_NAME ) + + # # for i in range ( len(res_time) ) : + # # # print("1111111111..............%s %s " %(res_time[i],res_time[i][0]) ) + # # # time.sleep(2) + # # ProcessFile.save_time_list( str(res_time[i][0]) , res_data[i], TOKEN, fpath ) + # # # 不是samip 不保存 IP 文件 + # # if sn != samip_sn: + # # ProcessFile.save_time_list( str(res_time[i][0]) , res_time[i][1:], TOKEN, fpath_IP ) + + + # # log.info( "保存结束 ... " + fname ) + + # # 返回 ok 表示文件处理结束 + # return + # pass + + # def read_ini(self,fname ,type_): + # """ + # @description : 三个不同任务, SAM SN, SAM ATTR, IP ATTR + # 分别记为 SAMSN SAMCAL IPCAL + # """ + # log.info( " RAMSES __read_ini -> lst -> %s " % type_) + # typ = type_ + # data = [] + + # if typ == "SAMSN" : + + # with open(fname, 'r') as f_handle: + # for line in f_handle: + # # IDDevice = SAM_85AF + # ln = line.strip('\n').strip(' ').split('=') + # if ln[0].strip() == "IDDevice" : + # if ln[1].strip().split('_')[0] =="SAM" : + # return ln[1].strip().split('_')[1] + # pass + + # if typ == "SAMCAL" : + # samcal= {} + # with open(fname, 'r') as f_handle: + # flag = 0 + # for line in f_handle: + # # IDDevice = SAM_85AF + # line_ = line.strip('\n').strip(' ').split('=') + # if flag == 0 and line_[0].strip() == "IDDevice" : + # if line_[1].strip().split('_')[0] =="SAM" : + # samcal["SAMSN"] = line_[1].strip().split('_')[1] + # flag += 1 + + # if flag == 2 and "[END]" in line: + # flag += 1 + + # if flag == 2: + # # print(" 1 %s %s %s" % (fname,line_[0],line_[1])) + # samcal[line_[0]] = line_[1] + + # if flag == 1 and line_[0].strip() == "[ATTRIBUTES]" : + # flag += 1 + + # if flag == 2 and "[END]" in line: + # flag += 1 + + # return samcal + + # pass + + # if typ == "IPCAL" : + # ipcal= {} + # with open(fname, 'r') as f_handle: + # flag = 0 + # for line in f_handle: + # # IDDevice = SAM_85AF + # ln = line.strip('\n').strip(' ').split('=') + + # if flag == 0 and ln[0].strip() == "IDDevice" : + # if ln[1].strip().split('_')[0] =="IP" : + # ipcal["IPSN"] = ln[1].strip().split('_')[1] + # flag += 1 + + # if flag == 2 and "[END]" in line: + # flag += 1 + + # if flag == 2: + # ipcal[ln[0]] = ln[1] + + # if flag == 1 and ln[0].strip() == "[ATTRIBUTES]" : + # flag += 1 + + # return ipcal + + # return + # pass + + # def read_raw( self, fname , lst, uiraw): + # """ + # @description : 三个不同任务, SAM SN, SAM ATTR, IP ATTR + # 对波长进行标定处理 + # 并存入文件 + # λ(N) = C0s + C1s·N + C2s· N2 + C3s·N3 + # """ + + # sep = uiraw["1"] + # air_water = int(uiraw["2"]) + + # with open(fname, 'r') as f_handle: + # sn = "" + # wl = "" + # is_samip = 0 + # # data = data[2:] + # # cal_data = lst[sn] + # wl_cal = [] + # cal_data = [] + # intg_time = 128 + # ip_cal = [] + # cal = [] + # calaq = [] + # b0 = [] + # b1 = [] + + # for line in f_handle: + # data = line.split(",") + # sn_d = data[0] + + # if sn_d != sn : + # sn = sn_d + # intg_time = int( data[1] ) + # cal_data = lst[sn] + # # 判断sam SAMIP + # if cal_data[0][0] != cal_data[0][1] : + # is_samip = 1 + + # wl_cal = cal_data[1] + # ip_cal = cal_data[2] + + # if air_water == 1 : + # cal = cal_data[3] + # else: + # cal = cal_data[2] + + # b0 = cal_data[4] + # b1 = cal_data[5] + + # for i in range(1,256): + # temp = float(wl_cal["C0s"]) + \ + # float(wl_cal["C1s"]) * i + \ + # float(wl_cal["C2s"]) * i * i + \ + # float(wl_cal["C3s"]) * i *i *i + # wl.append(temp) + + + + # # 处理数据 + # data = data[2:] + # intensity = [] + # Cn = [] + + # for i in range( 255 ): + # # NAN 为 0 + # # if cal[i] = "+NAN": + # # intensity.append(0) + # # else: + # Mn = data[i] / 65535 + # Bn = float( b0[i] ) + float( b1[i] ) * intg_time / 8192 #积分时间比 + # Cn.append(Bn - Mn) + + # offset = 0 # DarkPixelStart = 237 DarkPixelStop = 254的平均值. 数组中236-254 + # for i in range( int( wl_cal['DarkPixelStart']) -1 , int( wl_cal['DarkPixelStop']) ): + # offset = offset + float( Cn[i] ) + # offset = offset/ ( int( wl_cal['DarkPixelStop']) - int( wl_cal['DarkPixelStart']) +1 ) + + # for i in range( 255 ): + # Dn = Cn[i] - offset + # En = 8192 * Dn / intg_time + + # # ???? Sn 来自 cal calaq 文件的部分 + # Sn = cal[i] + # intensity.append( En / Sn ) + + # # 还需要处理传感器的 IP + # if is_samip : + # # ip 数据过来后的格式 + # pass + + # return intensity + + # # 数据分别写到文件 diff --git a/retrieve.yml b/retrieve.yml new file mode 100644 index 0000000..7119f5d --- /dev/null +++ b/retrieve.yml @@ -0,0 +1,3 @@ +beginWL: 360 +endWL: 721 +interval: 1 diff --git a/uart.py b/uart.py new file mode 100644 index 0000000..19fc96d --- /dev/null +++ b/uart.py @@ -0,0 +1,200 @@ +import serial +import struct +import time + +class Uart(object): + def __init__(self,): + self.ser = serial.Serial() + self.__buf = b'' + self.command = b'' + self._is_connected = False + self.begin_time = None + pass + + def set_serial_para(self, port="COM1",baudrate=9600,bytesize=8,parity="N", stopbit=1, timeout = 4): + self.port = port + self.ser.port = port + self.ser.baudrate = baudrate + self.ser.bytesize = bytesize + self.ser.parity = parity + self.ser.stopbits = stopbit + self.ser.timeout = timeout + + def set_modbus(self, slaveaddress=1, functioncode=3, beginaddress=0, step=5 ): + self.slaveaddress = slaveaddress + self.functioncode = functioncode + self.beginaddress = beginaddress + self.step = step + self.command = self.__get_modbus_command() + self.rcv_len = 2*self.step + 5 # 16bit + + def connect(self,): + try: + self.ser.open() + if self.ser.isOpen(): + self._is_connected = True + self.ser.close() + except Exception as e: + self._is_connected = False + # SerialException(f"KH3000 can not open port : {self.ser.port}") + + if self.ser is not None and self.ser.isOpen(): + self.ser.close() + return self._is_connected + + def disconnect(self,): + if self._is_connected or self.ser.isOpen(): + self.ser.close() + self._is_received = False + self._is_connected = False + pass + + def write(self,) -> None: + try: + self.ser.open() + if self.ser.isOpen(): + self.ser._is_connected = True + except Exception as e: + self.ser. _is_connected = False + + if self.ser._is_connected: + self.begin_time = time.time() + self.ser.reset_input_buffer() + self.ser.reset_output_buffer() + # print(f"========= command {self.command.hex() }") + self.ser.write(self.command) + # if isHex: + # data = bytes.fromhex(data) + # self.ser.write(bytes(data)) + # else: + # self.ser.write(bytes(data, encoding='utf8')+b'\x0A\x0D') + + def receive(self,): + self.flush() + while 1: + if not self._is_receiving: + break + if self.ser.in_waiting: # 这个接收是随机的 + for _ in range(self.ser.in_waiting): + # print( type(_serial.read(1))) + temp = self.ser.read(1) # 可以直接读取指定长度 + self.__buf = self.__buf + temp + if len(self.__buf) >= self.rcv_len: + break + if time.time() - self.begin_time > self.ser.timeout: + self.__buf = b'' + break + + self._is_receiving = False + + def OneMeasure(self) -> bytes: + if not self.ser.isOpen(): + self.ser.open() + self._is_receiving = True + self.__buf = b'' + self.receive() + + if len(self.__buf)>=self.rcv_len and not self._is_receiving : + return self.__buf + + return b'' + pass + + def reset_input_buffer(self)->None: + self.ser.reset_input_buffer() + pass + + def reset_output_buffer(self)->None: + self.ser.reset_output_buffer() + pass + + def flush(self)->None: + self.ser.flush() + pass + + def IsOpen(self)->bool: + return self._is_connected + pass + + def IsReceived(self)->bool: + return self._is_received + pass + + def getResult(self)->bytes: + return self.__buf + pass + + def add_crc16( self, buf:bytes ): + ''' + 一般发送命令都是'01030000000A'这样的字符串 + 输入:test2 = '01030000000A' + 输出:0xc5cd + hexstr[2:].upper() 去掉 + ''' + crc = 0xFFFF + for pos in buf: + crc ^= pos + for i in range(8): + if ((crc & 1) != 0): + crc >>= 1 + crc ^= 0xA001 + else: + crc >>= 1 + return ((crc & 0xff) << 8) + (crc >> 8) + # return hex(((crc & 0xff) << 8) + (crc >> 8))[2:].upper() + + def crc16Check(self,buf:bytes): + if len(buf) > 4 : + crc = self.add_crc16(buf[:-2]) + if (crc & 0xff) == buf[-1] and (crc >> 8)== buf[-2]: + return True + else: + return False + else: + return False + + def __get_modbus_command(self, ): + res = b'' + res = res + self.slaveaddress.to_bytes(1, byteorder="big") + res = res + self.functioncode.to_bytes(1, byteorder="big") + res = res + self.beginaddress.to_bytes(2, byteorder="big") + res = res + self.step.to_bytes(2, byteorder="big") + crc = self.add_crc16(res) + hi = (crc >> 8).to_bytes(1, byteorder="big") + lo = (crc & 0xff).to_bytes(1, byteorder="big") + return res + hi + lo + + pass + +if __name__ == '__main__': + # 字符串转字节 + u = Uart() + s = "01030000000A" + sss = b'\x01\x03\x00\x00\x00\x0A\xC5\xCD' + print(bytes.fromhex(s)) + print(bytearray.fromhex(s)) + + + print( u.add_crc16(bytes.fromhex(s)) ) + print("00000000000000000000000000000000000") + print(sss[:-2]) + if u.crc16Check(sss): + print("TRUE,...") + else: + print("fffffffffffff") + + # 数字转字节 + a = 1024 + b=a.to_bytes(2, byteorder='big') # 2个字节 + + + a.from_bytes(b'\x04\x00', byteorder='big') + + # ASCIIunpack + data = "a" + bytes(data, encoding='utf8') + + # struct 打包转字节 + ss = struct.pack('>H', 8) # unpack + print(ss) + pass \ No newline at end of file diff --git a/uiconfig/ui_algorithm.py b/uiconfig/ui_algorithm.py new file mode 100644 index 0000000..50ba6d7 --- /dev/null +++ b/uiconfig/ui_algorithm.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python +# -*- encoding: utf-8 -*- +import wx +# from configobj import ConfigObj +from myconfig import MyConfig +from myconfig import YAML_FILE_NAME + +class UI_Algorithm(wx.Dialog): + """ + @description : 算法配置 + """ + def __init__(self, parent, id): + # 串口页面配置 + super(UI_Algorithm, self).__init__( parent ,id = id ) + self.config = MyConfig() + self.InitUI() + self.SetSize((400, 400)) + self.SetTitle(" 算法配置 ") + + def InitUI(self): + self.config_yml = self.config.read_yaml() + + self.panel = wx.Panel(self) + self.vbox = wx.BoxSizer(wx.VERTICAL) + + self.sb = wx.StaticBox(self.panel, label='算法配置') + self.sbs = wx.StaticBoxSizer(self.sb, orient=wx.VERTICAL) + + self.hbox1 = wx.BoxSizer(wx.HORIZONTAL) + self.staticText1 = wx.StaticText(self.panel, label='浊度校正 ',size=(60, -1), style=wx.ALIGN_CENTRE_VERTICAL ) + self.textCtrl1 = wx.TextCtrl(self.panel, value="",size=(250,25) ) + tmp = self.get_str_from_config( "algorithm", "A720" ) + if tmp is not None: + self.textCtrl1.SetValue(tmp) + self.hbox1.Add(self.staticText1, flag=wx.TOP|wx.LEFT, border=5) + self.hbox1.Add(self.textCtrl1, flag=wx.TOP|wx.LEFT, border=5) + self.sbs.Add(self.hbox1, flag=wx.TOP|wx.LEFT, border= 5) + + self.hbox2 = wx.BoxSizer(wx.HORIZONTAL) + self.staticText2 = wx.StaticText(self.panel, label='包含纯水: ' ,size=(60, -1)) + # self.staticText2_1 = wx.StaticText(self.panel, label='分钟 ' ,size=(60, -1)) + self.textCtrl2 = wx.TextCtrl(self.panel, value="",size=(250,25)) + tmp = self.get_str_from_config( "algorithm", "2" ) + if tmp is not None: + self.textCtrl2.SetValue(tmp) + self.hbox2.Add(self.staticText2, flag=wx.TOP|wx.LEFT, border=5) + self.hbox2.Add(self.textCtrl2,flag=wx.TOP|wx.LEFT, border=5) + # self.hbox2.Add(self.staticText2_1, flag=wx.TOP|wx.LEFT, border=5) + self.sbs.Add(self.hbox2, flag=wx.TOP|wx.LEFT, border=5) + + self.hbox3 = wx.BoxSizer(wx.HORIZONTAL) + self.staticText3 = wx.StaticText(self.panel, label='纯水: ' ,size=(60, -1)) + # self.staticText2_1 = wx.StaticText(self.panel, label='分钟 ' ,size=(60, -1)) + self.textCtrl3 = wx.TextCtrl(self.panel, value="",size=(250,25)) + tmp = self.get_str_from_config( "algorithm", "3" ) + if tmp is not None: + self.textCtrl3.SetValue(tmp) + self.hbox3.Add(self.staticText3, flag=wx.TOP|wx.LEFT, border=5) + self.hbox3.Add(self.textCtrl3,flag=wx.TOP|wx.LEFT, border=5) + # self.hbox2.Add(self.staticText2_1, flag=wx.TOP|wx.LEFT, border=5) + self.sbs.Add(self.hbox3, flag=wx.TOP|wx.LEFT, border=5) + + self.panel.SetSizer(self.sbs) + + self.hbox_0 = wx.BoxSizer(wx.HORIZONTAL) + self.okButton = wx.Button(self, label=u'保存配置') + self.closeButton = wx.Button(self, label='Close') + self.hbox_0.Add(self.okButton) + self.hbox_0.Add(self.closeButton, flag = wx.LEFT, border=5) + + # 添加 vbox 到panel + self.vbox.Add(self.panel, proportion=1, + flag=wx.ALL | wx.EXPAND, border=5) + + self.vbox.Add(self.hbox_0, flag=wx.ALIGN_CENTER | wx.TOP | wx.BOTTOM, border=10) + self.SetSizer(self.vbox) + + self.okButton.Bind(wx.EVT_BUTTON, self.OnSave) + self.closeButton.Bind(wx.EVT_BUTTON, self.OnClose) + + def get_str_from_config( self, section, key ): + return str(self.config_yml[section][key]) + pass + + def set_config_by_section_key_val( self, section, key, val ): + # print(f" {key} current type {type( self.config_yml[section][key] )}") + if type( self.config_yml[section][key] ) == int: + self.config_yml[section][key] = int(val) + elif type( self.config_yml[section][key] ) == float: + self.config_yml[section][key] = float(val) + else: + self.config_yml[section][key] = val + pass + + def saveData(self, e): + pass + + def OnClose(self, e): + self.Destroy() + + def OnSave(self, e): + success = True + # 赋值字典,写入文件 + self.set_config_by_section_key_val( 'algorithm',"1",self.textCtrl1.GetValue( ) ) + self.set_config_by_section_key_val( 'algorithm',"2",self.textCtrl2.GetValue( ) ) + self.set_config_by_section_key_val( 'algorithm',"3",self.textCtrl2.GetValue( ) ) + self.config.write_yaml(self.config_yml) + del self.config + if success: + self.EndModal(wx.ID_OK) \ No newline at end of file diff --git a/uiconfig/ui_com_setting.py b/uiconfig/ui_com_setting.py new file mode 100644 index 0000000..9c9bef8 --- /dev/null +++ b/uiconfig/ui_com_setting.py @@ -0,0 +1,138 @@ +#!/usr/bin/env python +# -*- encoding: utf-8 -*- +import wx +from myconfig import MyConfig +from myconfig import YAML_FILE_NAME + +class UI_Com_Setting(wx.Dialog): + """ + @description : Com 配置 + """ + def __init__(self, parent,id): + # 串口页面配置 + super(UI_Com_Setting, self).__init__( parent ,id=id ) + self.config = MyConfig() + self.InitUI() + self.SetSize((400, 400)) + self.SetTitle(" 设置串口参数 ") + + def InitUI(self): + + self.config_yml = self.config.read_yaml() + # print(self.config_yml['comsetting']) + + self.panel = wx.Panel(self) + self.vbox = wx.BoxSizer(wx.VERTICAL) + + self.sb = wx.StaticBox(self.panel, label='设置串口') + self.sbs = wx.StaticBoxSizer(self.sb, orient=wx.VERTICAL) + + self.hbox1 = wx.BoxSizer(wx.HORIZONTAL) + self.staticText1 = wx.StaticText(self.panel, label='串口号: ',size=(60, -1), style=wx.ALIGN_CENTRE_VERTICAL ) + self.textCtrl1 = wx.TextCtrl(self.panel, value="",size=(250,25) ) + tmp = self.get_str_from_config("comsetting",'port') + if tmp is not None: + self.textCtrl1.SetValue(tmp) + self.hbox1.Add(self.staticText1, flag=wx.TOP|wx.LEFT, border=5) + self.hbox1.Add(self.textCtrl1, flag=wx.TOP|wx.LEFT, border=5) + self.sbs.Add(self.hbox1, flag=wx.TOP|wx.LEFT, border= 5) + + self.hbox2 = wx.BoxSizer(wx.HORIZONTAL) + self.staticText2 = wx.StaticText(self.panel, label='波特率: ' ,size=(60, -1)) + # self.staticText2_1 = wx.StaticText(self.panel, label='分钟 ' ,size=(60, -1)) + self.textCtrl2 = wx.TextCtrl(self.panel, value="",size=(250,25)) + tmp = self.get_str_from_config("comsetting",'baudrate') + if tmp is not None: + self.textCtrl2.SetValue(tmp) + self.hbox2.Add(self.staticText2, flag=wx.TOP|wx.LEFT, border=5) + self.hbox2.Add(self.textCtrl2,flag=wx.TOP|wx.LEFT, border=5) + # self.hbox2.Add(self.staticText2_1, flag=wx.TOP|wx.LEFT, border=5) + self.sbs.Add(self.hbox2, flag=wx.TOP|wx.LEFT, border=5) + + self.hbox3 = wx.BoxSizer(wx.HORIZONTAL) + self.staticText3 = wx.StaticText(self.panel, label='数据位: ' ,size=(60, -1)) + # self.staticText3_1 = wx.StaticText(self.panel, label='分钟 ' ,size=(60, -1)) + self.textCtrl3 = wx.TextCtrl(self.panel, value="",size=(250,25)) + tmp = self.get_str_from_config("comsetting",'bytesize') + if tmp is not None: + self.textCtrl3.SetValue(tmp) + self.hbox3.Add(self.staticText3, flag=wx.TOP|wx.LEFT, border=5) + self.hbox3.Add(self.textCtrl3,flag=wx.TOP|wx.LEFT, border=5) + # self.hbox3.Add(self.staticText3_1, flag=wx.TOP|wx.LEFT, border=5) + self.sbs.Add(self.hbox3, flag=wx.TOP|wx.LEFT, border=5) + + self.hbox4 = wx.BoxSizer(wx.HORIZONTAL) + self.staticText4 = wx.StaticText(self.panel, label='奇偶性: ' ,size=(60, -1)) + # self.staticText3_1 = wx.StaticText(self.panel, label='分钟 ' ,size=(60, -1)) + self.textCtrl4 = wx.TextCtrl(self.panel, value="",size=(250,25)) + tmp = self.get_str_from_config("comsetting",'parity') + if tmp is not None: + self.textCtrl4.SetValue(tmp) + self.hbox4.Add(self.staticText4, flag=wx.TOP|wx.LEFT, border=5) + self.hbox4.Add(self.textCtrl4,flag=wx.TOP|wx.LEFT, border=5) + self.sbs.Add( self.hbox4, flag=wx.TOP|wx.LEFT, border=5 ) + + self.hbox5 = wx.BoxSizer(wx.HORIZONTAL) + self.staticText5 = wx.StaticText(self.panel, label='停止位: ' ,size=(60, -1)) + # self.staticText3_1 = wx.StaticText(self.panel, label='分钟 ' ,size=(60, -1)) + self.textCtrl5 = wx.TextCtrl(self.panel, value="",size=(250,25)) + tmp = self.get_str_from_config("comsetting",'stopbit') + if tmp is not None: + self.textCtrl5.SetValue(tmp) + self.hbox5.Add(self.staticText5, flag=wx.TOP|wx.LEFT, border=5) + self.hbox5.Add(self.textCtrl5, flag=wx.TOP|wx.LEFT, border=5) + self.sbs.Add( self.hbox5, flag=wx.TOP|wx.LEFT, border=5 ) + + self.panel.SetSizer(self.sbs) + + self.hbox_0 = wx.BoxSizer(wx.HORIZONTAL) + self.okButton = wx.Button(self, label=u'保存配置') + self.closeButton = wx.Button(self, label='Close') + self.hbox_0.Add(self.okButton) + self.hbox_0.Add(self.closeButton, flag = wx.LEFT, border=5) + + # 添加 vbox 到panel + self.vbox.Add(self.panel, proportion=1, + flag=wx.ALL | wx.EXPAND, border=5) + + self.vbox.Add(self.hbox_0, flag=wx.ALIGN_CENTER | wx.TOP | wx.BOTTOM, border=10) + + self.SetSizer(self.vbox) + + self.okButton.Bind(wx.EVT_BUTTON, self.OnSave) + self.closeButton.Bind(wx.EVT_BUTTON, self.OnClose) + + def get_str_from_config( self, section, key ): + return str(self.config_yml[section][key]) + pass + + def set_config_by_section_key_val( self, section, key, val ): + # print(f" {key} current type {type( self.config_yml[section][key] )}") + if type( self.config_yml[section][key] ) == int: + self.config_yml[section][key] = int(val) + elif type( self.config_yml[section][key] ) == float: + self.config_yml[section][key] = float(val) + else: + self.config_yml[section][key] = val + pass + + def saveData( self, e ): + pass + + def OnClose( self, e ): + self.Destroy() + + def OnSave(self, e): + success = True + # 赋值字典,写入文件 + self.set_config_by_section_key_val("comsetting", 'port', self.textCtrl1.GetValue( )) + self.set_config_by_section_key_val("comsetting", 'baudrate', self.textCtrl2.GetValue( )) + self.set_config_by_section_key_val("comsetting", 'bytesize', self.textCtrl3.GetValue( )) + self.set_config_by_section_key_val("comsetting", 'parity', self.textCtrl4.GetValue( )) + self.set_config_by_section_key_val("comsetting", 'stopbit', self.textCtrl5.GetValue( )) + + self.config.write_yaml(self.config_yml) + del self.config + + if success: + self.EndModal(wx.ID_OK) \ No newline at end of file diff --git a/uiconfig/ui_filepath_setting.py b/uiconfig/ui_filepath_setting.py new file mode 100644 index 0000000..6bd51d1 --- /dev/null +++ b/uiconfig/ui_filepath_setting.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python +# -*- encoding: utf-8 -*- +import wx +# from configobj import ConfigObj +from myconfig import MyConfig +from myconfig import YAML_FILE_NAME + +class UI_Filepath_Setting(wx.Dialog): + """ + @description : 文件路径 配置 + """ + def __init__(self, parent,id): + # 串口页面配置 + super(UI_Filepath_Setting, self).__init__( parent ,id=id ) + self.config = MyConfig() + self.InitUI() + self.SetSize((400, 400)) + self.SetTitle(" 设置文件路径 ") + + def InitUI(self): + self.config_yml = self.config.read_yaml() + # self.sensor = self.config_sensor.get(self.did) + # print(self.config_sensor) + # print(self.sensor) + + self.panel = wx.Panel( self ) + self.vbox = wx.BoxSizer( wx.VERTICAL ) + + self.sb = wx.StaticBox(self.panel, label='文件路径 配置') + self.sbs = wx.StaticBoxSizer(self.sb, orient=wx.VERTICAL) + + self.hbox1 = wx.BoxSizer(wx.HORIZONTAL) + self.staticText1 = wx.StaticText(self.panel, label='文件路径: ',size=(60, -1), style=wx.ALIGN_CENTRE_VERTICAL ) + self.textCtrl1 = wx.TextCtrl(self.panel, value="",size=(250,25) ) + tmp = self.get_str_from_config("filepath","path") + if tmp is not None: + self.textCtrl1.SetValue(tmp) + self.hbox1.Add(self.staticText1, flag=wx.TOP|wx.LEFT, border=5) + self.hbox1.Add(self.textCtrl1, flag=wx.TOP|wx.LEFT, border=5) + self.sbs.Add(self.hbox1, flag=wx.TOP|wx.LEFT, border= 5) + + + self.panel.SetSizer(self.sbs) + + self.hbox_0 = wx.BoxSizer(wx.HORIZONTAL) + self.okButton = wx.Button(self, label=u'保存配置') + self.closeButton = wx.Button(self, label='Close') + self.hbox_0.Add(self.okButton) + self.hbox_0.Add(self.closeButton, flag = wx.LEFT, border=5) + + # 添加 vbox 到panel + self.vbox.Add(self.panel, proportion=1, + flag=wx.ALL | wx.EXPAND, border=5) + + self.vbox.Add(self.hbox_0, flag=wx.ALIGN_CENTER | wx.TOP | wx.BOTTOM, border=10) + + self.SetSizer(self.vbox) + + self.okButton.Bind(wx.EVT_BUTTON, self.OnSave) + self.closeButton.Bind(wx.EVT_BUTTON, self.OnClose) + + def get_str_from_config( self, section, key ): + return str(self.config_yml[section][key]) + pass + + def set_config_by_section_key_val( self, section, key, val ): + # print(f" {key} current type {type( self.config_yml[section][key] )}") + if type( self.config_yml[section][key] ) == int: + self.config_yml[section][key] = int(val) + elif type( self.config_yml[section][key] ) == float: + self.config_yml[section][key] = float(val) + else: + self.config_yml[section][key] = val + pass + + + def saveData(self, e): + pass + + def OnClose(self, e): + + self.Destroy() + + def OnSave(self, e): + success = True + # 赋值字典,写入文件 + self.set_config_by_section_key_val('filepath',"path",self.textCtrl1.GetValue( )) + self.config_yml.write_yaml(self.config_sensor) + del self.config + + if success: + self.EndModal(wx.ID_OK) \ No newline at end of file diff --git a/uiconfig/ui_log_setting.py b/uiconfig/ui_log_setting.py new file mode 100644 index 0000000..ae32c8e --- /dev/null +++ b/uiconfig/ui_log_setting.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python +# -*- encoding: utf-8 -*- +import wx +# from configobj import ConfigObj +from myconfig import MyConfig +from myconfig import YAML_FILE_NAME + +class UI_Log_Setting(wx.Dialog): + """ + @description : Sensor 配置 + """ + def __init__(self, parent, id): + # 串口页面配置 + super(UI_Log_Setting, self).__init__( parent ,id = id ) + self.config = MyConfig() + self.InitUI() + self.SetSize((400, 400)) + self.SetTitle(" 设置光程 序列号 ") + + def InitUI(self): + self.config_yml = self.config.read_yaml() + + self.panel = wx.Panel(self) + self.vbox = wx.BoxSizer(wx.VERTICAL) + + self.sb = wx.StaticBox(self.panel, label='设置光程 序列号') + self.sbs = wx.StaticBoxSizer(self.sb, orient=wx.VERTICAL) + + self.hbox1 = wx.BoxSizer(wx.HORIZONTAL) + self.staticText1 = wx.StaticText(self.panel, label='采集间隔: ',size=(60, -1), style=wx.ALIGN_CENTRE_VERTICAL ) + self.textCtrl1 = wx.TextCtrl(self.panel, value="",size=(250,25) ) + tmp = self.get_str_from_config( "logsetting", "LogInterval" ) + if tmp is not None: + self.textCtrl1.SetValue(tmp) + self.hbox1.Add(self.staticText1, flag=wx.TOP|wx.LEFT, border=5) + self.hbox1.Add(self.textCtrl1, flag=wx.TOP|wx.LEFT, border=5) + self.sbs.Add(self.hbox1, flag=wx.TOP|wx.LEFT, border= 5) + + self.hbox2 = wx.BoxSizer(wx.HORIZONTAL) + self.staticText2 = wx.StaticText(self.panel, label='保存间隔: ' ,size=(60, -1)) + # self.staticText2_1 = wx.StaticText(self.panel, label='分钟 ' ,size=(60, -1)) + self.textCtrl2 = wx.TextCtrl(self.panel, value="",size=(250,25)) + tmp = self.get_str_from_config( "logsetting", "RefreshInterval" ) + if tmp is not None: + self.textCtrl2.SetValue(tmp) + self.hbox2.Add(self.staticText2, flag=wx.TOP|wx.LEFT, border=5) + self.hbox2.Add(self.textCtrl2,flag=wx.TOP|wx.LEFT, border=5) + # self.hbox2.Add(self.staticText2_1, flag=wx.TOP|wx.LEFT, border=5) + self.sbs.Add(self.hbox2, flag=wx.TOP|wx.LEFT, border=5) + + self.panel.SetSizer(self.sbs) + + self.hbox_0 = wx.BoxSizer(wx.HORIZONTAL) + self.okButton = wx.Button(self, label=u'保存配置') + self.closeButton = wx.Button(self, label='Close') + self.hbox_0.Add(self.okButton) + self.hbox_0.Add(self.closeButton, flag = wx.LEFT, border=5) + + # 添加 vbox 到panel + self.vbox.Add(self.panel, proportion=1, + flag=wx.ALL | wx.EXPAND, border=5) + + self.vbox.Add(self.hbox_0, flag=wx.ALIGN_CENTER | wx.TOP | wx.BOTTOM, border=10) + + self.SetSizer(self.vbox) + + self.okButton.Bind(wx.EVT_BUTTON, self.OnSave) + self.closeButton.Bind(wx.EVT_BUTTON, self.OnClose) + + def get_str_from_config( self, section, key ): + return str(self.config_yml[section][key]) + pass + + def set_config_by_section_key_val( self, section, key, val ): + # print(f" {key} current type {type( self.config_yml[section][key] )}") + if type( self.config_yml[section][key] ) == int: + self.config_yml[section][key] = int(val) + elif type( self.config_yml[section][key] ) == float: + self.config_yml[section][key] = float(val) + else: + self.config_yml[section][key] = val + pass + + + def saveData(self, e): + pass + + def OnClose(self, e): + + self.Destroy() + + def OnSave(self, e): + success = True + # 赋值字典,写入文件 + self.set_config_by_section_key_val('logsetting',"LogInterval",self.textCtrl1.GetValue( )) + self.set_config_by_section_key_val('logsetting',"RefreshInterval",self.textCtrl2.GetValue( )) + self.config.write_yaml(self.config_yml) + del self.config + if success: + self.EndModal(wx.ID_OK) \ No newline at end of file diff --git a/uiconfig/ui_pathsn_setting.py b/uiconfig/ui_pathsn_setting.py new file mode 100644 index 0000000..067c9ce --- /dev/null +++ b/uiconfig/ui_pathsn_setting.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python +# -*- encoding: utf-8 -*- +import wx +# from configobj import ConfigObj +from myconfig import MyConfig +from myconfig import YAML_FILE_NAME + +class UI_PathSN_Setting(wx.Dialog): + """ + @description : 设置光程 序列号 + """ + def __init__(self, parent,id): + # 串口页面配置 + super(UI_PathSN_Setting, self).__init__( parent ,id=id ) + self.config = MyConfig() + self.InitUI() + self.SetSize((400, 400)) + self.SetTitle(" 设置光程 序列号 ") + + def InitUI(self): + self.config_yml = self.config.read_yaml() + + self.panel = wx.Panel(self) + self.vbox = wx.BoxSizer(wx.VERTICAL) + + self.sb = wx.StaticBox(self.panel, label='设置光程 序列号') + self.sbs = wx.StaticBoxSizer(self.sb, orient=wx.VERTICAL) + + # self.hbox1 = wx.BoxSizer(wx.HORIZONTAL) + # self.staticText1 = wx.StaticText(self.panel, label='光 程: ',size=(60, -1), style=wx.ALIGN_CENTRE_VERTICAL ) + # self.textCtrl1 = wx.TextCtrl(self.panel, value="",size=(250,25) ) + # tmp = self.get_str_from_config( "device", "UIPath" ) + # if tmp is not None: + # self.textCtrl1.SetValue(tmp) + # self.hbox1.Add(self.staticText1, flag=wx.TOP|wx.LEFT, border=5) + # self.hbox1.Add(self.textCtrl1, flag=wx.TOP|wx.LEFT, border=5) + # self.sbs.Add(self.hbox1, flag=wx.TOP|wx.LEFT, border= 5) + + self.hbox2 = wx.BoxSizer(wx.HORIZONTAL) + self.staticText2 = wx.StaticText(self.panel, label='序列号: ' ,size=(60, -1)) + # self.staticText2_1 = wx.StaticText(self.panel, label='分钟 ' ,size=(60, -1)) + self.textCtrl2 = wx.TextCtrl(self.panel, value="",size=(250,25)) + tmp = self.get_str_from_config( "device", "UISN" ) + if tmp is not None: + self.textCtrl2.SetValue(tmp) + self.hbox2.Add(self.staticText2, flag=wx.TOP|wx.LEFT, border=5) + self.hbox2.Add(self.textCtrl2,flag=wx.TOP|wx.LEFT, border=5) + # self.hbox2.Add(self.staticText2_1, flag=wx.TOP|wx.LEFT, border=5) + self.sbs.Add(self.hbox2, flag=wx.TOP|wx.LEFT, border=5) + + self.panel.SetSizer(self.sbs) + + self.hbox_0 = wx.BoxSizer(wx.HORIZONTAL) + self.okButton = wx.Button(self, label=u'保存配置') + self.closeButton = wx.Button(self, label='Close') + self.hbox_0.Add(self.okButton) + self.hbox_0.Add(self.closeButton, flag = wx.LEFT, border=5) + + # 添加 vbox 到panel + self.vbox.Add(self.panel, proportion=1, + flag=wx.ALL | wx.EXPAND, border=5) + + self.vbox.Add(self.hbox_0, flag=wx.ALIGN_CENTER | wx.TOP | wx.BOTTOM, border=10) + + self.SetSizer(self.vbox) + + self.okButton.Bind(wx.EVT_BUTTON, self.OnSave) + self.closeButton.Bind(wx.EVT_BUTTON, self.OnClose) + + def get_str_from_config( self, section, key ): + return str(self.config_yml[section][key]) + pass + + def set_config_by_section_key_val( self, section, key, val ): + # print(f" {key} current type {type( self.config_yml[section][key] )}") + if type( self.config_yml[section][key] ) == int: + self.config_yml[section][key] = int(val) + elif type( self.config_yml[section][key] ) == float: + self.config_yml[section][key] = float(val) + else: + self.config_yml[section][key] = val + pass + + + def saveData(self, e): + pass + + def OnClose(self, e): + + self.Destroy() + + def OnSave(self, e): + success = True + # 赋值字典,写入文件 + # self.set_config_by_section_key_val('device',"UIPath",self.textCtrl1.GetValue( )) + self.set_config_by_section_key_val('device',"UISN",self.textCtrl2.GetValue( )) + self.config.write_yaml(self.config_yml) + del self.config + if success: + self.EndModal(wx.ID_OK) \ No newline at end of file diff --git a/uiconfig/ui_plot_setting.py b/uiconfig/ui_plot_setting.py new file mode 100644 index 0000000..cafdbc9 --- /dev/null +++ b/uiconfig/ui_plot_setting.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python +# -*- encoding: utf-8 -*- +import wx +# from configobj import ConfigObj +from myconfig import MyConfig +from myconfig import YAML_FILE_NAME + +class UI_Plot_Setting(wx.Dialog): + """ + @description : 绘图 配置 + """ + def __init__(self, parent, id): + # 串口页面配置 + super(UI_Plot_Setting, self).__init__( parent ,id = id ) + self.config = MyConfig() + self.InitUI() + self.SetSize((400, 400)) + self.SetTitle(" 绘图 序列号 ") + + def InitUI(self): + self.config_yml = self.config.read_yaml() + + self.panel = wx.Panel(self) + self.vbox = wx.BoxSizer(wx.VERTICAL) + + self.sb = wx.StaticBox(self.panel, label='绘图 序列号') + self.sbs = wx.StaticBoxSizer(self.sb, orient=wx.VERTICAL) + + self.hbox1 = wx.BoxSizer(wx.HORIZONTAL) + self.staticText1 = wx.StaticText(self.panel, label='起始行号 ',size=(60, -1), style=wx.ALIGN_CENTRE_VERTICAL ) + self.textCtrl1 = wx.TextCtrl(self.panel, value="",size=(250,25) ) + tmp = self.get_str_from_config( "plotsetting", "LineBegin" ) + if tmp is not None: + self.textCtrl1.SetValue(tmp) + self.hbox1.Add(self.staticText1, flag=wx.TOP|wx.LEFT, border=5) + self.hbox1.Add(self.textCtrl1, flag=wx.TOP|wx.LEFT, border=5) + self.sbs.Add(self.hbox1, flag=wx.TOP|wx.LEFT, border= 5) + + self.hbox2 = wx.BoxSizer(wx.HORIZONTAL) + self.staticText2 = wx.StaticText(self.panel, label='间隔行号: ' ,size=(60, -1)) + # self.staticText2_1 = wx.StaticText(self.panel, label='分钟 ' ,size=(60, -1)) + self.textCtrl2 = wx.TextCtrl(self.panel, value="",size=(250,25)) + tmp = self.get_str_from_config( "plotsetting", "LineInterval" ) + if tmp is not None: + self.textCtrl2.SetValue(tmp) + self.hbox2.Add(self.staticText2, flag=wx.TOP|wx.LEFT, border=5) + self.hbox2.Add(self.textCtrl2,flag=wx.TOP|wx.LEFT, border=5) + # self.hbox2.Add(self.staticText2_1, flag=wx.TOP|wx.LEFT, border=5) + self.sbs.Add(self.hbox2, flag=wx.TOP|wx.LEFT, border=5) + + self.panel.SetSizer(self.sbs) + + self.hbox_0 = wx.BoxSizer(wx.HORIZONTAL) + self.okButton = wx.Button(self, label=u'保存配置') + self.closeButton = wx.Button(self, label='Close') + self.hbox_0.Add(self.okButton) + self.hbox_0.Add(self.closeButton, flag = wx.LEFT, border=5) + + # 添加 vbox 到panel + self.vbox.Add(self.panel, proportion=1, + flag=wx.ALL | wx.EXPAND, border=5) + + self.vbox.Add(self.hbox_0, flag=wx.ALIGN_CENTER | wx.TOP | wx.BOTTOM, border=10) + + self.SetSizer(self.vbox) + + self.okButton.Bind(wx.EVT_BUTTON, self.OnSave) + self.closeButton.Bind(wx.EVT_BUTTON, self.OnClose) + + def get_str_from_config( self, section, key ): + return str(self.config_yml[section][key]) + pass + + def set_config_by_section_key_val( self, section, key, val ): + # print(f" {key} current type {type( self.config_yml[section][key] )}") + if type( self.config_yml[section][key] ) == int: + self.config_yml[section][key] = int(val) + elif type( self.config_yml[section][key] ) == float: + self.config_yml[section][key] = float(val) + else: + self.config_yml[section][key] = val + pass + + + def saveData(self, e): + pass + + def OnClose(self, e): + + self.Destroy() + + def OnSave(self, e): + success = True + # 赋值字典,写入文件 + self.set_config_by_section_key_val('plotsetting',"LineBegin",self.textCtrl1.GetValue( )) + self.set_config_by_section_key_val('plotsetting',"LineInterval",self.textCtrl2.GetValue( )) + self.config.write_yaml(self.config_yml) + del self.config + if success: + self.EndModal(wx.ID_OK) \ No newline at end of file diff --git a/uiconfig/uiabout.py b/uiconfig/uiabout.py new file mode 100644 index 0000000..56a33c7 --- /dev/null +++ b/uiconfig/uiabout.py @@ -0,0 +1,60 @@ +import wx + +# 设置串口参数的对话框类 + +class About(wx.Dialog): + + def __init__(self, *args, **kwds): + + # 参数调入后初始化 + super(About, self).__init__(*args, **kwds) + + self.InitUI() + self.SetSize((400, 400)) + self.SetTitle("使用帮助") + + def InitUI(self): + + self.panel = wx.Panel(self) + self.vbox = wx.BoxSizer(wx.VERTICAL) + + self.sb = wx.StaticBox(self.panel, label='使用帮助') + self.sbs = wx.StaticBoxSizer(self.sb, orient=wx.VERTICAL) + + self.hbox1 = wx.BoxSizer(wx.HORIZONTAL) + self.staticText1 = wx.StaticText(self.panel, + label='''\n上海奕枫仪器设备有限公司 +电话: 021-54270075 +网站: http://www.yi-win.com +邮件: sales@yi-win.com ''' ) + self.hbox1.Add(self.staticText1) + self.sbs.Add(self.hbox1) + + + + self.panel.SetSizer(self.sbs) + + self.hbox_0 = wx.BoxSizer(wx.HORIZONTAL) + self.okButton = wx.Button(self, label=u'确认') + self.closeButton = wx.Button(self, label='关闭') + self.hbox_0.Add(self.okButton) + self.hbox_0.Add(self.closeButton, flag=wx.LEFT, border=5) + + self.vbox.Add(self.panel, proportion=1, + flag=wx.ALL | wx.EXPAND, border=5) + self.vbox.Add(self.hbox_0, flag=wx.ALIGN_CENTER | wx.TOP | wx.BOTTOM, border=10) + + self.SetSizer(self.vbox) + + self.okButton.Bind(wx.EVT_BUTTON, self.OnSave) + self.closeButton.Bind(wx.EVT_BUTTON, self.OnClose) + + + def saveData(self, e): + pass + + def OnClose(self, e): + self.Destroy() + + def OnSave(self, e): + self.EndModal(wx.ID_OK) \ No newline at end of file diff --git a/uiconfig/uihelp.py b/uiconfig/uihelp.py new file mode 100644 index 0000000..8c7a1c7 --- /dev/null +++ b/uiconfig/uihelp.py @@ -0,0 +1,58 @@ +import wx + +# 设置串口参数的对话框类 + +class Help(wx.Dialog): + + def __init__(self, *args, **kwds): + + # 参数调入后初始化 + super(Help, self).__init__(*args, **kwds) + + self.InitUI() + self.SetSize((400, 400)) + self.SetTitle("使用帮助") + + def InitUI(self): + + self.panel = wx.Panel(self) + self.vbox = wx.BoxSizer(wx.VERTICAL) + + self.sb = wx.StaticBox(self.panel, label='使用帮助') + self.sbs = wx.StaticBoxSizer(self.sb, orient=wx.VERTICAL) + + self.hbox1 = wx.BoxSizer(wx.HORIZONTAL) + self.staticText1 = wx.StaticText(self.panel, + label='''\n上海奕枫仪器设备有限公司 +电话: 021-54270075 +网站: http://www.yi-win.com +邮件: sales@yi-win.com ''' ) + self.hbox1.Add(self.staticText1) + self.sbs.Add(self.hbox1) + + self.panel.SetSizer(self.sbs) + + self.hbox_0 = wx.BoxSizer(wx.HORIZONTAL) + self.okButton = wx.Button(self, label=u'确认') + self.closeButton = wx.Button(self, label='关闭') + self.hbox_0.Add(self.okButton) + self.hbox_0.Add(self.closeButton, flag=wx.LEFT, border=5) + + self.vbox.Add(self.panel, proportion=1, + flag=wx.ALL | wx.EXPAND, border=5) + self.vbox.Add(self.hbox_0, flag=wx.ALIGN_CENTER | wx.TOP | wx.BOTTOM, border=10) + + self.SetSizer(self.vbox) + + self.okButton.Bind(wx.EVT_BUTTON, self.OnSave) + self.closeButton.Bind(wx.EVT_BUTTON, self.OnClose) + + + def saveData(self, e): + pass + + def OnClose(self, e): + self.Destroy() + + def OnSave(self, e): + self.EndModal(wx.ID_OK) \ No newline at end of file diff --git a/uiconfig/uisensor.py b/uiconfig/uisensor.py new file mode 100644 index 0000000..36a2e1b --- /dev/null +++ b/uiconfig/uisensor.py @@ -0,0 +1,124 @@ +#!/usr/bin/env python +# -*- encoding: utf-8 -*- +import wx +# from configobj import ConfigObj +from myconfig import MyConfig +from myconfig import YAML_FILE_NAME + +class UISensor(wx.Dialog): + """ + @description : Sensor 配置 + """ + def __init__(self, parent, id, did): + # 参数调入后初始化 + self.did = did + super(UISensor, self).__init__( parent, id=id ) + self.config = MyConfig() + self.InitUI() + self.SetSize((400, 400)) + self.SetTitle(" 设置页面 串口 采集间隔 ") + + def InitUI(self): + + self.config_sensor = self.config.read_yaml() + # self.sensor = self.config_sensor.get(self.did) + # print(self.config_sensor) + # print(self.sensor) + + self.panel = wx.Panel(self) + self.vbox = wx.BoxSizer(wx.VERTICAL) + + self.sb = wx.StaticBox(self.panel, label='设置页面') + self.sbs = wx.StaticBoxSizer(self.sb, orient=wx.VERTICAL) + + self.hbox1 = wx.BoxSizer(wx.HORIZONTAL) + self.staticText1 = wx.StaticText(self.panel, label='Lsky: ',size=(60, -1), style=wx.ALIGN_CENTRE_VERTICAL ) + self.textCtrl1 = wx.TextCtrl(self.panel, value="",size=(250,25) ) + tmp = self.getSnByDidAndFunc("Lsky",self.did) + if tmp is not None: + self.textCtrl1.SetValue(tmp) + self.hbox1.Add(self.staticText1, flag=wx.TOP|wx.LEFT, border=5) + self.hbox1.Add(self.textCtrl1, flag=wx.TOP|wx.LEFT, border=5) + self.sbs.Add(self.hbox1, flag=wx.TOP|wx.LEFT, border= 5) + + self.hbox2 = wx.BoxSizer(wx.HORIZONTAL) + self.staticText2 = wx.StaticText(self.panel, label='Esky: ' ,size=(60, -1)) + # self.staticText2_1 = wx.StaticText(self.panel, label='分钟 ' ,size=(60, -1)) + self.textCtrl2 = wx.TextCtrl(self.panel, value="",size=(250,25)) + tmp = self.getSnByDidAndFunc("Esky",self.did) + if tmp is not None: + self.textCtrl2.SetValue(tmp) + self.hbox2.Add(self.staticText2, flag=wx.TOP|wx.LEFT, border=5) + self.hbox2.Add(self.textCtrl2,flag=wx.TOP|wx.LEFT, border=5) + # self.hbox2.Add(self.staticText2_1, flag=wx.TOP|wx.LEFT, border=5) + self.sbs.Add(self.hbox2, flag=wx.TOP|wx.LEFT, border=5) + + self.hbox3 = wx.BoxSizer(wx.HORIZONTAL) + self.staticText3 = wx.StaticText(self.panel, label='Lwater: ' ,size=(60, -1)) + # self.staticText3_1 = wx.StaticText(self.panel, label='分钟 ' ,size=(60, -1)) + self.textCtrl3 = wx.TextCtrl(self.panel, value="",size=(250,25)) + tmp = self.getSnByDidAndFunc("Lwater",self.did) + if tmp is not None: + self.textCtrl3.SetValue(tmp) + self.hbox3.Add(self.staticText3, flag=wx.TOP|wx.LEFT, border=5) + self.hbox3.Add(self.textCtrl3,flag=wx.TOP|wx.LEFT, border=5) + # self.hbox3.Add(self.staticText3_1, flag=wx.TOP|wx.LEFT, border=5) + self.sbs.Add(self.hbox3, flag=wx.TOP|wx.LEFT, border=5) + + self.panel.SetSizer(self.sbs) + + self.hbox_0 = wx.BoxSizer(wx.HORIZONTAL) + self.okButton = wx.Button(self, label=u'保存配置') + self.closeButton = wx.Button(self, label='Close') + self.hbox_0.Add(self.okButton) + self.hbox_0.Add(self.closeButton, flag = wx.LEFT, border=5) + + # 添加 vbox 到panel + self.vbox.Add(self.panel, proportion=1, + flag=wx.ALL | wx.EXPAND, border=5) + + self.vbox.Add(self.hbox_0, flag=wx.ALIGN_CENTER | wx.TOP | wx.BOTTOM, border=10) + + self.SetSizer(self.vbox) + + self.okButton.Bind(wx.EVT_BUTTON, self.OnSave) + self.closeButton.Bind(wx.EVT_BUTTON, self.OnClose) + + def getSnByDidAndFunc(self,func,did): + temp:dict = self.config_sensor.get(did) + for v in temp.values(): + if v["FUNC"] == func: + return v["SN"] + return None + pass + + def setSnByDidAndFunc(self,func,did,val): + temp:dict = self.config_sensor.get(did) + for k,v in temp.items(): + if v["FUNC"] == func: + temp[k]['SN'] =val + self.config_sensor.update({did:temp}) + + pass + + def saveData(self, e): + pass + + def OnClose(self, e): + + self.Destroy() + + def OnSave(self, e): + success = True + # 赋值字典,写入文件 + self.setSnByDidAndFunc('Lsky',self.did,self.textCtrl1.GetValue( )) + self.setSnByDidAndFunc('Esky',self.did,self.textCtrl2.GetValue( )) + self.setSnByDidAndFunc('Lwater',self.did,self.textCtrl3.GetValue( )) + print(self.textCtrl3.GetValue( )) + + print(self.config_sensor) + self.config.write_yaml(self.config_sensor) + del self.config + + if success: + self.EndModal(wx.ID_OK) \ No newline at end of file diff --git a/yiwinframe.py b/yiwinframe.py new file mode 100644 index 0000000..a7aeb03 --- /dev/null +++ b/yiwinframe.py @@ -0,0 +1,772 @@ +import wx +import os +import time +import threading +import numpy as np +from pathlib import Path,PurePath +from wx.lib.pubsub import pub +# from configobj import ConfigObj + +from listctrl import Listctrl +# from mypanel import MyPanel +from mypanel import Plot + +from uiconfig.ui_com_setting import UI_Com_Setting +from uiconfig.ui_filepath_setting import UI_Filepath_Setting +from uiconfig.ui_pathsn_setting import UI_PathSN_Setting +from uiconfig.ui_plot_setting import UI_Plot_Setting +from uiconfig.ui_log_setting import UI_Log_Setting +from uiconfig.uiabout import About +from uiconfig.uihelp import Help + +from myconfig import DeviceType,YAML_FILE_NAME,RETRIEVE_CFG_FILE +from myconfig import TOKEN,DATA_DIR,FILE_MARK,OUTPUT_DIR,SAVE_EXT_NAME +from myconfig import MyConfig +from configuration import Configuration +# from awrams import AWRAMS,HandHeldBuf + +from myexception import MyException +from mylogger import log +from mypath import MyDir +from mythread import Mythead +from readcal import ReadCal +from uart import Uart +from oscar import Oscar +from dataplot import DataPlot + +# -定义菜单ID,关联Event------------------------- +""" +# 菜单 文件 -- 处理文件 + 设备 -- 序列 波长 测量 + 设置 -- 串口 光程 文件路径 绘图参数 采集设置 + 作图 -- 最后一条曲线 最后七条 指定位置七条 + 帮助 +""" + +ID_MEASURE = 1 +ID_DEAL_FILE = 2 +ID_DEVICE_SN = 3 +ID_DEVICE_WL = 4 +ID_DEVICE_LOG = 5 +ID_COM_SETTING = 6 +ID_PATH_SN = 7 +ID_FILE_PATH = 8 +ID_PLOT_SETTING = 9 +ID_LOG_SETTING = 10 + +ID_DEVICE_STOP = 11 + +ID_PLOT_ONE = 15 +ID_PLOT_SEVEN = 16 +ID_PLOT_RULE = 17 + +ID_HELP = 21 +ID_ABOUT = 22 + +class YiwinFrame( wx.Frame ): + '''将buf类传进来''' + def __init__(self, title, parent, size=(900, 750)): + self.device_id = 2 + self.device_type = DeviceType.OSCAR.name + self.raw_wavelength = [] + self.new_wavelength = [] + self.device_wavelength = [] + self.device_data = [] + self.output_wavelength = [] + self.output_wl_ndarray = np.array([]) + self.syscfg = {} + self.sensor_cfg = {} + self.retrieve = {} + self.calinfo_is_ok = False + self.title = title + self.dir :Path = Path() + self.datadir :Path = self.dir.joinpath(DATA_DIR) + self.output_dir:Path = self.datadir.joinpath(OUTPUT_DIR) + self.save_fname :Path = Path() + self.result = '' + self.displayData:list = [] + self.interval = 0 + self.measure_time = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()) + + super(YiwinFrame, self).__init__( parent, title=self.title, size = size ) + + self.BoxSizer = wx.BoxSizer(wx.HORIZONTAL) # 建立一个Boxsizer + self.SetSizer(self.BoxSizer) + self.Centre(wx.BOTH) + + # 建立 listctrl panel 放到BoxSizer + self.listctrl_panel = Listctrl( self ) # 调用自己建立的 Listctrl panel 类 + self.BoxSizer.Add( self.listctrl_panel, proportion =-10, border = 2, flag = wx.ALL | wx.EXPAND) + self.list_ctrl = self.listctrl_panel.list_ctrl + # 隐藏 等待show + self.listctrl_panel.Hide() + + self.plotpanel = Plot( self ) # 调用自己建立的 Listctrl panel 类 + self.BoxSizer.Add( self.plotpanel, proportion =-10, border = 0, flag = wx.ALL | wx.EXPAND) + # self.static_text = self.plotpanel.staticText1 + # 隐藏 等待show + self.plotpanel.Show() + + self.statusBar = self.CreateStatusBar() # 创建状态栏 + self.statusBar.SetFieldsCount(2) # 状态栏分成3个区域 + self.statusBar.SetStatusWidths([-1, -1]) # 区域宽度比列,用负数 + self.statusBar.SetStatusText(u" 等待接收消息......", 0) + + self.__set_menu() # 添加菜单 + self.__attach_events() # 菜单事件 + self.__set_properties() + # self.__read_config() + self.__setTimer() + log.info(f"system init....",__name__, "__init__") + self.mycfg = MyConfig() + self.mydir = MyDir() + self.mycfg.set_retrieve() + self.__read_config() + self.ui_sn = self.syscfg['device']['UISN'] + self.device_sn = '' + self.file_sn = '' + self.interval = self.syscfg['logsetting']['LogInterval'] + self.port = self.syscfg['comsetting']['port'] + + self.uart = Uart() + self.oscar = Oscar() + self.dataplot = DataPlot() + self.plot_pure_water() + + pub.subscribe( self.updateDisplay, "update") + pass + + def __set_menu(self): + ''' + # 设置菜单 + ''' + self.menubar = wx.MenuBar() + + fileMenu = wx.Menu() + fileMenu.Append(ID_DEAL_FILE, u'&处理文件', '...') + self.menubar.Append(fileMenu, u'&文件 ') + + deviceMenu = wx.Menu() + deviceMenu.Append(ID_DEVICE_SN, u'&序列号', '...') + deviceMenu.AppendSeparator() + deviceMenu.Append(ID_DEVICE_WL, u'&波长', '...') + deviceMenu.AppendSeparator() + deviceMenu.Append(ID_DEVICE_LOG, u'&采集数据', '...') + deviceMenu.AppendSeparator() + deviceMenu.Append(ID_DEVICE_STOP, u'&停止采集', '...') + self.menubar.Append(deviceMenu, u'&设备 ') + + settingMenu = wx.Menu() + settingMenu.Append(ID_COM_SETTING, u'&串口设置', '...') + settingMenu.AppendSeparator() + settingMenu.Append(ID_PATH_SN, u'&序列号', ' ') + settingMenu.AppendSeparator() + settingMenu.Append(ID_FILE_PATH, u'&文件路径', ' ') + settingMenu.AppendSeparator() + settingMenu.Append(ID_PLOT_SETTING, u'&绘图设置', ' ') + settingMenu.AppendSeparator() + settingMenu.Append(ID_LOG_SETTING, u'&采集设置', ' ') + self.menubar.Append(settingMenu, u'&系统设置') + + plotMenu = wx.Menu() + plotMenu.Append( ID_PLOT_ONE, u'&最后一条', '...' ) + plotMenu.AppendSeparator() + plotMenu.Append( ID_PLOT_SEVEN, u'&最后七条', '...' ) + plotMenu.AppendSeparator() + plotMenu.Append( ID_PLOT_RULE, u'&指定七条', '...' ) + self.menubar.Append(plotMenu, u'&绘图 ') + + aboutMenu = wx.Menu() + aboutMenu.Append( ID_HELP, u'&帮助', 'help...' ) + aboutMenu.AppendSeparator() + aboutMenu.Append( ID_ABOUT, u'&关于我们', '关于我们...' ) + self.menubar.Append( aboutMenu, u'&帮助') + + self.SetMenuBar(self.menubar) + pass + + def __set_properties(self): + self.SetSize((800, 600)) + # self.SetTitle(u'传感器数据采集--上海奕枫仪器设备有限公司') + self.Centre() + + def __attach_events(self): + ''' + # 绑定菜单事件 + ''' + self.Bind(wx.EVT_MENU, self.OnDealFile, id = ID_DEAL_FILE) + + self.Bind(wx.EVT_MENU, self.OnDeviceSN, id = ID_DEVICE_SN) + self.Bind(wx.EVT_MENU, self.OnDeviceWL, id = ID_DEVICE_WL) + self.Bind(wx.EVT_MENU, self.OnDeviceLog, id = ID_DEVICE_LOG) + self.Bind(wx.EVT_MENU, self.OnDeviceStop, id = ID_DEVICE_STOP) + self.Bind(wx.EVT_MENU, self.OnComSetting, id = ID_COM_SETTING) + self.Bind(wx.EVT_MENU, self.OnPathSNSetting, id = ID_PATH_SN) + self.Bind(wx.EVT_MENU, self.OnFilePathSetting, id = ID_FILE_PATH) + self.Bind(wx.EVT_MENU, self.OnPlotSetting, id = ID_PLOT_SETTING) + self.Bind(wx.EVT_MENU, self.OnLogSetting, id = ID_LOG_SETTING) + + self.Bind(wx.EVT_MENU, self.OnPlotOne, id = ID_PLOT_ONE) + self.Bind(wx.EVT_MENU, self.OnPlotSeven, id = ID_PLOT_SEVEN) + self.Bind(wx.EVT_MENU, self.OnPlotRule, id = ID_PLOT_RULE) + + self.Bind(wx.EVT_MENU, self.OnHelpConfig, id = ID_HELP) + self.Bind(wx.EVT_MENU, self.OnAboutConfig, id = ID_ABOUT) + pass + + def __setTimer(self): + self.timer = wx.Timer(self) #创建定时器,菜单以后 + self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer) #绑定一个定时器事件 + pass + + def updateDisplay(self,msg): + log.debug(f" updateDisplay 。。 {msg['data']}") + if msg['type'] == "notice": + self.__update_notice(msg['data']) + pass + if msg['type'] == "sn": + self.__update_sn(msg['data']) + pass + if msg['type'] == "wl": + self.__update_wl(msg['data']) + pass + if msg['type'] == "log": + self.__update_log(msg['data'] ) + print(f" ...log update ...{msg['data']} " ) + pass + if msg['type'] == "data": + # log.info(f" ... update .{msg['data']}........... " ) + self.__update_data(msg['data']) + pass + pass + + def __update_sn(self,sn): + if sn != self.ui_sn: + self.alterStatus_0(f" sn: {sn} 与系统sn {self.ui_sn} 一致") + self.popDialog(f" sn: {sn} 与系统sn {self.ui_sn} 一致") + raise MyException(f" sn: {sn} 与系统sn {self.ui_sn} 一致") + else: + self.alterStatus_0(f" sn: {sn} 与系统sn {self.ui_sn} 不一致") + pass + + def __update_notice(self,msg): + log.debug(f" msg : {msg}") + self.alterStatus_0(msg) + pass + + def __update_wl(self,wl): + log.debug(f" 获得的波长成功 : {wl}") + self.output_wavelength = wl + self.alterStatus_0( f" 获得的波长成功 " ) + pass + + def __update_log(self,d): + log.info(f" 获得的数据 {d}") + self.alterStatus_0( d) + + def __update_data( self, d ): + '''对于文件过来的数据''' + log.debug(f" ", __name__," __update_data") + self.plotpanel.clear_past() + self.plotpanel.set_title_x_y( *self.plotpanel.measure_legend ) + self.plotpanel.plot_one( + d['time'] + ,np.array(self.oscar.output_wavelength) + ,np.array(d['data']) + ) + pass + + def OnStart( self, event ): + log.info( f" OnStart....interval: { self.interval } minutes, port: { self.port} " ) + interval_ms = int(self.interval) * 60 * 1000 + self.timer.Start( interval_ms ) # 开始监测 + + def OnStop( self ,event ): + self.timer.Stop() + pass + + def OnTimer(self, event): + ''' 定时器实现 ''' + # log.info( f"OnTimer .... " ) + self.__OnDeviceLog( ) + pass + + def __read_config(self,): + # 读取配置文件 + self.syscfg = self.mycfg.read_yaml() + retrieve = self.mycfg.read_rtv_yaml() + self.syscfg.update( { "retrieve" : retrieve } ) + + def OnDealFile(self, e)-> None: + self.__OnDeviceStop() + log.info( f"OnDealFile: 处理测量文件", __name__, "", "" ) + # 线程守护 + self.mt = Mythead() + self.oscar.set_cfg(self.syscfg) + try: + self.oscar.get_data_files() + self.mt.set_task( self.oscar.deal_file_lst ) + self.mt.start() + self.alterStatus_0(" 处理完所有文件" ) + except Exception as e: + self.alterStatus_0(e ) + self.popDialog( e ) + pass + + def OnDeviceSN(self, e)-> None: + self.__OnDeviceStop() + log.info(f"OnDeviceSN: 获取device sn ", __name__, "", "") + # self.mt = Mythead() + self.oscar.set_cfg(self.syscfg) + self.oscar.set_serial() + # self.oscar.set_modbus(self.syscfg['register']['SNAddress'], self.syscfg['register']['SNLen']) + try: + self.oscar.sn_uart_thread( self.get_device_sn ) + except Exception as e: + self.alterStatus_0(e ) + self.popDialog( e ) + self.alterStatus_0(" SN 匹配一致" ) + pass + + def get_device_sn(self,sn): + self.device_sn = sn + if self.device_sn != self.ui_sn: + log.error( f" 设备SN {self.device_sn} 与系统设置 {self.ui_sn}不一致 错误 " ) + pass + else: + log.info(" sn 匹配成功 ! ") + pass + + def OnDeviceWL(self, e)-> None: + self.__OnDeviceStop() + log.info(f"OnDeviceWL: 获得device wavelength ... ", __name__, "", "") + if self.device_sn != '': + self.oscar.set_cfg( self.syscfg ) + self.oscar.set_serial() + try: + self.oscar.wl_uart_thread( self.get_device_wl ) + except Exception as e: + self.alterStatus_0(e ) + self.popDialog( e ) + self.alterStatus_0(" 获取波长成功!" ) + else: + self.popDialog('请获取设备序列号SN信息再试') + pass + + def get_device_wl(self, wl_buf): + if len(wl_buf) != 0: + self.output_wavelength = wl_buf + self.output_wl_ndarray = np.array(self.output_wavelength) + else: + log.error( " 获取设备波长出错 " ) + raise MyException( " 获取设备波长出错 " ) + pass + + def OnDeviceLog(self, e)-> None: + self.__OnDeviceStop() + log.info( f"OnDeviceLog: 采集数据 定时器采集", __name__, "", "" ) + # !!!! 判断是否有波长和sn + if self.output_wavelength == []: + self.alterStatus_0( " 没有设备波长信息,请获取设备波长") + self.popDialog( " 没有设备波长信息,请获取设备波长") + raise MyException(" 没有设备波长信息,请获取设备波长") + self.__OnDeviceLog() + + # 如何整点获取,如何快速获取 + self.timer.Start( int(self.interval) * 60 * 1000 ) + pass + + def __OnDeviceLog(self,)-> None: + self.device_data = b'' + self.mt = Mythead() + self.oscar.set_cfg( self.syscfg ) + self.oscar.set_serial() + try: + self.oscar.log_uart_thread( self.get_device_data ) + except Exception as e: + print(e) + self.alterStatus_0(e ) + self.popDialog( e ) + pass + + def get_device_data( self,tm, data_buf ): + if len(data_buf) != 0: + self.device_data = self.oscar.convert_buf_2_float( data_buf ,8 ) + self.plotpanel.clear_past() + self.plotpanel.set_title_x_y( *self.plotpanel.measure_legend ) + self.plotpanel.plot_one( + tm + , self.output_wl_ndarray + ,np.array(data_buf) + ) + else: + log.error( " 采集设备数据出错 " ) + raise MyException(" 采集设备数据出错 ") + pass + + def OnDeviceStop(self, e)-> None: + self.__OnDeviceStop() + pass + + def __OnDeviceStop(self, )-> None: + if self.timer.IsRunning(): + self.timer.Stop() + pass + + def plot_pure_water(self,): + # self.dataplot.set_file_path() + self.__OnDeviceStop() + self.plotpanel.set_title_x_y( *self.plotpanel.purewater_legend ) + time_ = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()) + + wl = np.array(self.oscar.purewater_wavelength) + att = np.array(self.oscar.purewater_attenuation) + self.plotpanel.plot_one(time_, wl, att) + pass + + def OnPlotOne(self,e): + self.__OnDeviceStop() + self.plotpanel.set_title_x_y( *self.plotpanel.measure_legend ) + self.dataplot.set_file_path( self.output_dir.joinpath(self.ui_sn+SAVE_EXT_NAME) ) + self.dataplot.set_token(TOKEN) + # !! 判断波长,获得波长 + wavelength:str = self.dataplot.get_first_line().strip('\n').strip('\r') + self.output_wavelength = wavelength.split(TOKEN)[1:] + self.output_wl_ndarray = np.array(self.output_wavelength).astype(np.float64) + + line = self.dataplot.get_multi_by_x_m_n(1,1,1) + line = line[0].strip('\n').strip('\r').split(TOKEN) + tm = line[0] + line = np.array(line[1:]).astype(np.float64) + self.plotpanel.axes.clear() + self.plotpanel.plot_one( tm, self.output_wl_ndarray, line ) + self.alterStatus_0( f" plot {tm}") + pass + + def OnPlotSeven(self,e): + self.__OnDeviceStop() + self.plotpanel.set_title_x_y( *self.plotpanel.measure_legend ) + times = [] + lines = [] + log.debug( f'+++ ',__name__, 'OnPlotSeven' ) + self.dataplot.set_file_path( self.output_dir.joinpath( self.ui_sn+SAVE_EXT_NAME ) ) + self.dataplot.set_token(TOKEN) + # !! 判断波长,获得波长 + wavelength:str = self.dataplot.get_first_line().strip('\n').strip('\r') + self.output_wavelength = wavelength.split(TOKEN)[1:] + self.output_wl_ndarray = np.array(self.output_wavelength).astype(np.float64) + + line_7 = self.dataplot.get_multi_by_x_m_n(1,1,7) + # log.warning( f'+++ {line_7} ',__name__, 'OnPlotSeven' ) + for line in line_7: + line = line.strip('\n').strip('\r').split(TOKEN) + tm = line[0] + line = np.array(line[1:]).astype(np.float64) + times.append(tm) + lines.append( line ) + self.plotpanel.axes.clear() + self.plotpanel.plot_multi( times, self.output_wl_ndarray, lines ) + self.alterStatus_0( f" plot 7 ") + pass + + def OnPlotRule(self,e): + self.__OnDeviceStop() + self.plotpanel.set_title_x_y( *self.plotpanel.measure_legend ) + times = [] + lines = [] + log.debug( f'+++ ',__name__, 'OnPlotSeven' ) + self.dataplot.set_file_path( self.output_dir.joinpath( self.ui_sn+SAVE_EXT_NAME ) ) + self.dataplot.set_token(TOKEN) + # !! 判断波长,获得波长 + wavelength:str = self.dataplot.get_first_line().strip('\n').strip('\r') + self.output_wavelength = wavelength.split(TOKEN)[1:] + self.output_wl_ndarray = np.array(self.output_wavelength).astype(np.float64) + + line_7 = self.dataplot.get_multi_by_x_m_n(1,1,7) + # log.warning( f'+++ {line_7} ',__name__, 'OnPlotSeven' ) + for line in line_7: + line = line.strip('\n').strip('\r').split(TOKEN) + tm = line[0] + line = np.array(line[1:]).astype(np.float64) + times.append( tm ) + lines.append( line ) + self.plotpanel.axes.clear() + self.plotpanel.plot_multi( times, self.output_wl_ndarray, lines ) + self.alterStatus_0( f" plot designated ") + pass + + def OnComSetting(self,e): + with UI_Com_Setting( + self, + -1 ) as Dialog_Sensor_Setting: + Dialog_Sensor_Setting.CenterOnParent() + resultLog = Dialog_Sensor_Setting.ShowModal() + + if resultLog == wx.ID_OK: + log.info( " COM config dialog confirm, call back " ) + self.__read_config() + pass + + def OnPathSNSetting(self,e): + with UI_PathSN_Setting( + self, + -1 ) as Dialog_Sensor_Setting: + Dialog_Sensor_Setting.CenterOnParent() + resultLog = Dialog_Sensor_Setting.ShowModal() + + if resultLog == wx.ID_OK: + log.info( " PathSN config dialog confirm, call back " ) + self.__read_config() + pass + + def OnFilePathSetting(self,e): + with UI_Filepath_Setting( + self, + -1 ) as Dialog_Sensor_Setting: + Dialog_Sensor_Setting.CenterOnParent() + resultLog = Dialog_Sensor_Setting.ShowModal() + + if resultLog == wx.ID_OK: + log.info( " FilePath config dialog confirm, call back " ) + self.__read_config() + pass + + def OnPlotSetting(self,e): + with UI_Plot_Setting( + self, + -1 ) as Dialog_Sensor_Setting: + Dialog_Sensor_Setting.CenterOnParent() + resultLog = Dialog_Sensor_Setting.ShowModal() + + if resultLog == wx.ID_OK: + log.info( " Plot config dialog confirm, call back " ) + self.__read_config() + pass + + def OnLogSetting(self,e): + with UI_Log_Setting( + self, + -1 ) as Dialog_Sensor_Setting: + Dialog_Sensor_Setting.CenterOnParent() + resultLog = Dialog_Sensor_Setting.ShowModal() + + if resultLog == wx.ID_OK: + log.info( " Log config dialog confirm, call back " ) + self.__read_config() + pass + + def OnHelpConfig(self, e): + with Help( + self, + -1, + "") as Dialog_Help: + resultLog = Dialog_Help.ShowModal() + if resultLog == wx.ID_OK: + log.info("Help info") + pass + + def OnAboutConfig(self, e): + with About( + self, + -1, + "") as Dialog_About: + resultLog = Dialog_About.ShowModal() + + if resultLog == wx.ID_OK: + log.info("Aboutus") + pass + + def OnOther(self, e): + pass + + def OnQuit(self, e): + self.Close() + + def alterStatus_0(self,msg): + self.statusBar.SetStatusText( msg, 0 ) + + def popDialog(self, msg, msg_type=u"错误提示"): + with wx.MessageDialog( self, msg, msg_type, wx.OK )as dlg: + dlg.ShowModal() + + +# class SerialThread(threading.Thread): +# """进度条类 """ +# def __init__(self, parent): +# """ +# :param parent: 主线程UI +# """ +# super(SerialThread, self).__init__() # 继承 +# self.parent = parent +# # log.info(f"SerialThread ... {self.parent.kh}") +# self.start() +# self.join() +# # self.setDaemon(True) # 设置为守护线程, 即子线程是守护进程,主线程结束子线程也随之结束。 + + +# def stop(self): +# self.parent.kh.disconnect() +# log.info(" Serial stop.... ") +# pass + + # def run(self): + # log.info(" Serial run.... ") + # wx.CallAfter(self.parent.OnRcv) + + # wx.CallAfter(self.parent.update_process_bar, count) # 调用parent的函数 + # wx.CallAfter(self.parent.close_process_bar) # destroy进度条 + + # def OnSerialThreadStart(self): + # self.m = SerialThread(self) + # pass + + # def OnSerialThreadStop(self): + # self.m.stop() + # pass + + # def OnDisplaySave(self): + # ''' + # 保存数据 self.result + # ''' + # log.info(f"OnDisplaySave ....") + # # self.m = SerialThread(self) + # # self.kh.flush() + # self.OnSerialThreadStart() + + + # def OnRcv( self ): + # log.info(f"OnRcv....") + # self.kh.setPort(self.port) + # if not self.OnDetectPort: + # MyException(f"Can not find port : {self.port}") + # log.info(f"{self.port} ok!") + # # if not self.kh: + # # self.kh = KH3000(self.port) + # # self.result = self.kh.OneMeasure() + # log.info( f"OnRcv success {self.result}", __class__.__name__ ) + # self.OnSave() + # self.OnDisplay() + # pass + + + # def __get_data_files(self,) -> list: + # # 读取配置文件 + # file_lst = [] + # self.mydir.setBaseDir( Path(self.datadir) ) + # file_lst = self.mydir.get_files_from_currentdir(fmt= "*/*.DAT") + # return file_lst + + # def __check_sn_from_datafile(self,fpath) -> bool: + # # 读取配置文件 + # sn = ReadCal.readFileSNbyIDDevice(fpath) + # if sn == self.ui_sn: + # return True + # return False + + # def __get_raw_wl_from_datafile(self,fpath) -> list: + # # 读取配置文件 + # _,raw_wl = ReadCal.read_columns_set_by_mark(fpath, FILE_MARK,0) + # return raw_wl + + # def __deal_file_lst(self,file_lst): + + # for fl in file_lst: + # # 判断序列号是否一致file_lst + # if not self.__check_sn_from_datafile(fl): + # self.onNotify("文件的序列号和系统设置不一致" ) + # self.popDialog(" 文件的序列号和系统设置不一致") + # raise MyException("文件的序列号和系统设置不一致") + + # # 判断原始波长是否为空 + # if self.raw_wavelength == []: + # res = self.__get_raw_wl_from_datafile(file_lst[0]) + # self.raw_wavelength = res[0] + + # # 处理输出文件 + # self.mydir.setBaseDir(self.output_dir) + # self.mydir.newDirIfNot() + # self.mydir.newFileIfNot(self.ui_sn+SAVE_EXT_NAME) + # if self.syscfg['retrieve']['enable'] == 0: + # self.mydir.setHeader(self.raw_wavelength,TOKEN,self.ui_sn) + # if self.mydir.checkHeader()==0: + # self.mydir.writeHeader() + # if self.mydir.checkHeader()==-1: + # self.popDialog(" 文件头不一致, 请备份到其他目录,并在该目录下删除") + # raise MyException(" 文件头不一致, 请备份到其他目录,并在该目录下删除") + # res_time,res_data = ReadCal.read_columns_sets_by_mark( fl, FILE_MARK, 1 ) + # for i in range( len(res_time) ): + # self.__deal_one_measure_time_data(res_time[i], res_data[i]) + # pass + # pass + # # 需要插值处理波长 + # if self.syscfg['retrieve']['enable'] == 1: + # self.mydir.setHeader(self.new_wavelength.tolist(),TOKEN,self.ui_sn) + # if self.mydir.checkHeader()==0: + # self.mydir.writeHeader() + # if self.mydir.checkHeader()==-1: + # self.popDialog(" 文件头不一致, 请备份到其他目录,并在该目录下删除") + # raise MyException(" 文件头不一致, 请备份到其他目录,并在该目录下删除") + + # # res_data 不用带回调的函数callback 会导致多组数据拼接?? + # res_time,res_data = ReadCal.read_columns_sets_by_mark( fl, FILE_MARK, 1 ) + + # log.warning(f" ==== {len(res_time)}" ) + # log.warning(res_time) + # log.warning(f" ==== {len(res_data[0])}" ) + # log.warning(f" ==== { res_data[0] }" ) + + # for i in range( len(res_time) ): + # self.__deal_one_measure_time_data(res_time[i], res_data[0][i]) + # pass + # pass + + # def __deal_one_measure_time_data(self,res_time,res_data): + # if self.syscfg['retrieve']['enable'] == 0: + # self.mydir.setContent(res_data ,TOKEN,res_time ) + # self.mydir.writeContent() + # # 插值处理 + # if self.syscfg['retrieve']['enable'] == 1: + # # tmp_data = np.interp( self.new_wavelength, np.array(self.raw_wavelength) , np.array(res_data) ) + + # x = self.new_wavelength + # xp = np.array(self.raw_wavelength).astype(np.float32) + # fp = np.array(res_data).astype(np.float32) + # log.warning(f" {x}") + # log.warning(f" {xp.shape }") + # log.warning(f" { fp.shape }") + # tmp_data = np.interp( x, xp , fp ) + # # tmp_data = np.interp( self.new_wavelength.tolist(), self.raw_wavelength , res_data[0] ) + # self.mydir.setContent( tmp_data ,TOKEN, res_time ) + # self.mydir.writeContent() + # pass + + + # def __deal_one_file(self,fpath): + # res_time,res_data = ReadCal.read_columns_sets_by_mark( fpath, FILE_MARK, 1 ) + # for i in range( len(res_time) ): + # if self.syscfg['retrieve']['enable'] == 0: + # self.mydir.setContent(res_data[i],TOKEN,res_time[i]) + # self.mydir.writeContent() + # # 插值处理 + # if self.syscfg['retrieve']['enable'] == 1: + # self.mydir.setContent(res_data[i],TOKEN,res_time[i]) + # self.mydir.writeContent() + # pass + # pass + + # def __set_serial(self, )-> None: + # self.uart.set_serial_para( + # self.syscfg['comsetting']['port'] + # ,self.syscfg['comsetting']['baudrate'] + # ,self.syscfg['comsetting']['bytesize'] + # ,self.syscfg['comsetting']['parity'] + # ,self.syscfg['comsetting']['stopbit'] + # ) + + # def __set_modbus(self, beginaddress, step)-> None: + # self.uart.set_modbus( + # self.syscfg['register']['slaveadress'] + # ,self.syscfg['register']['functioncode'] + # ,beginaddress + # ,step + # ) \ No newline at end of file