commit a9e20ad08b24c4ae0a9a55e087dd5a8fed535837 Author: esea_info Date: Tue Apr 11 20:49:24 2023 +0800 first commit 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 0000000..9d501c8 Binary files /dev/null and b/icon.ico differ 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