pyadps 0.2.0b0__py3-none-any.whl → 0.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyadps/Home_Page.py +11 -5
- pyadps/pages/01_Read_File.py +623 -211
- pyadps/pages/02_View_Raw_Data.py +97 -41
- pyadps/pages/03_Download_Raw_File.py +200 -67
- pyadps/pages/04_Sensor_Health.py +905 -0
- pyadps/pages/05_QC_Test.py +493 -0
- pyadps/pages/06_Profile_Test.py +971 -0
- pyadps/pages/07_Velocity_Test.py +600 -0
- pyadps/pages/08_Write_File.py +623 -0
- pyadps/pages/09_Add-Ons.py +168 -0
- pyadps/utils/__init__.py +5 -3
- pyadps/utils/autoprocess.py +371 -80
- pyadps/utils/logging_utils.py +269 -0
- pyadps/utils/metadata/config.ini +22 -4
- pyadps/utils/metadata/demo.000 +0 -0
- pyadps/utils/metadata/flmeta.json +420 -420
- pyadps/utils/metadata/vlmeta.json +611 -565
- pyadps/utils/multifile.py +292 -0
- pyadps/utils/plotgen.py +505 -3
- pyadps/utils/profile_test.py +720 -125
- pyadps/utils/pyreadrdi.py +164 -92
- pyadps/utils/readrdi.py +436 -186
- pyadps/utils/script.py +197 -147
- pyadps/utils/sensor_health.py +120 -0
- pyadps/utils/signal_quality.py +472 -68
- pyadps/utils/velocity_test.py +79 -31
- pyadps/utils/writenc.py +222 -39
- {pyadps-0.2.0b0.dist-info → pyadps-0.3.0.dist-info}/METADATA +63 -33
- pyadps-0.3.0.dist-info/RECORD +35 -0
- {pyadps-0.2.0b0.dist-info → pyadps-0.3.0.dist-info}/WHEEL +1 -1
- {pyadps-0.2.0b0.dist-info → pyadps-0.3.0.dist-info}/entry_points.txt +1 -0
- pyadps/pages/04_QC_Test.py +0 -334
- pyadps/pages/05_Profile_Test.py +0 -575
- pyadps/pages/06_Velocity_Test.py +0 -341
- pyadps/pages/07_Write_File.py +0 -452
- pyadps/utils/cutbin.py +0 -413
- pyadps/utils/regrid.py +0 -279
- pyadps-0.2.0b0.dist-info/RECORD +0 -31
- {pyadps-0.2.0b0.dist-info → pyadps-0.3.0.dist-info}/LICENSE +0 -0
@@ -0,0 +1,168 @@
|
|
1
|
+
import os
|
2
|
+
import tempfile
|
3
|
+
from pathlib import Path
|
4
|
+
|
5
|
+
import re
|
6
|
+
import io
|
7
|
+
import contextlib
|
8
|
+
|
9
|
+
import configparser
|
10
|
+
import streamlit as st
|
11
|
+
from utils.autoprocess import autoprocess
|
12
|
+
from utils.multifile import ADCPBinFileCombiner
|
13
|
+
|
14
|
+
# To make the page wider if the user presses the reload button.
|
15
|
+
st.set_page_config(layout="wide")
|
16
|
+
|
17
|
+
|
18
|
+
def ansi_to_html(text):
|
19
|
+
"""
|
20
|
+
Function to convert ANSI (console color) to HTML.
|
21
|
+
To display the text, map the output to st.markdown
|
22
|
+
"""
|
23
|
+
text = re.sub(r"\x1b\[31m", "<span style='color:red'><br>", text) # red
|
24
|
+
text = re.sub(r"\x1b\[32m", "<span style='color:green'><br>", text) # red
|
25
|
+
text = re.sub(r"\x1b\[33m", "<span style='color:orange'><br>", text) # green
|
26
|
+
text = re.sub(r"\x1b\[0m", "</span>", text) # reset
|
27
|
+
return text
|
28
|
+
|
29
|
+
|
30
|
+
@st.cache_data
|
31
|
+
def file_access(uploaded_file):
|
32
|
+
"""
|
33
|
+
Function creates temporary directory to store the uploaded file.
|
34
|
+
The path of the file is returned
|
35
|
+
|
36
|
+
Args:
|
37
|
+
uploaded_file (string): Name of the uploaded file
|
38
|
+
|
39
|
+
Returns:
|
40
|
+
path (string): Path of the uploaded file
|
41
|
+
"""
|
42
|
+
temp_dir = tempfile.mkdtemp()
|
43
|
+
path = os.path.join(temp_dir, uploaded_file.name)
|
44
|
+
with open(path, "wb") as f:
|
45
|
+
f.write(uploaded_file.getvalue())
|
46
|
+
return path
|
47
|
+
|
48
|
+
|
49
|
+
def display_config_as_json(config_file):
|
50
|
+
config = configparser.ConfigParser()
|
51
|
+
config.read_string(config_file.getvalue().decode("utf-8"))
|
52
|
+
st.json({section: dict(config[section]) for section in config.sections()})
|
53
|
+
|
54
|
+
|
55
|
+
def main():
|
56
|
+
st.title("🧰 Add-Ons")
|
57
|
+
st.header("🔧 Auto Processing Tool", divider=True)
|
58
|
+
st.write(
|
59
|
+
"You can use a configuration file from `pyadps` to re-process ADCP data by simply adjusting threshold values within the file. "
|
60
|
+
"This allows you to fine-tune the output without repeating the full processing workflow in the software."
|
61
|
+
)
|
62
|
+
st.write(
|
63
|
+
"To begin, upload both a binary ADCP file and a `config.ini` file for processing."
|
64
|
+
)
|
65
|
+
|
66
|
+
# File Upload Section
|
67
|
+
uploaded_binary_file = st.file_uploader(
|
68
|
+
"Upload ADCP Binary File", type=["000", "bin"]
|
69
|
+
)
|
70
|
+
uploaded_config_file = st.file_uploader(
|
71
|
+
"Upload Config File (config.ini)", type=["ini"]
|
72
|
+
)
|
73
|
+
|
74
|
+
if uploaded_binary_file and uploaded_config_file:
|
75
|
+
st.success("Files uploaded successfully!")
|
76
|
+
|
77
|
+
# Display config.ini file content as JSON
|
78
|
+
display_config_as_json(uploaded_config_file)
|
79
|
+
|
80
|
+
fpath = file_access(uploaded_binary_file)
|
81
|
+
# Process files
|
82
|
+
with st.spinner("Processing files. Please wait..."):
|
83
|
+
autoprocess(uploaded_config_file, binary_file_path=fpath)
|
84
|
+
st.success("Processing completed successfully!")
|
85
|
+
st.write("Processed file written.")
|
86
|
+
|
87
|
+
st.header("🔗 Binary File Combiner", divider=True)
|
88
|
+
st.write(
|
89
|
+
"ADCPs may produce multiple binary segments instead of a single continuous file. "
|
90
|
+
"This tool scans each uploaded binary file for the `7f7f` header, removes any broken ensembles at the beginning or the end, and combines all valid segments into a single file. "
|
91
|
+
"To ensure correct order during concatenation, please rename the files using sequential numbering. "
|
92
|
+
"For example: `KKS_000.000`, `KKS_001.000`, `KKS_002.000`."
|
93
|
+
)
|
94
|
+
output_cat_filename = "merged_000.000"
|
95
|
+
st.info(f"Current file name: **{output_cat_filename}**")
|
96
|
+
output_cat_filename_radio = st.radio(
|
97
|
+
"Would you like to edit the output filename?",
|
98
|
+
["No", "Yes"],
|
99
|
+
horizontal=True,
|
100
|
+
)
|
101
|
+
if output_cat_filename_radio == "Yes":
|
102
|
+
output_cat_filename = st.text_input(
|
103
|
+
"Enter file name (e.g., GD10A000)",
|
104
|
+
value=output_cat_filename,
|
105
|
+
)
|
106
|
+
|
107
|
+
display_log = st.radio(
|
108
|
+
"Display log from console:",
|
109
|
+
["No", "Yes"],
|
110
|
+
horizontal=True,
|
111
|
+
)
|
112
|
+
|
113
|
+
uploaded_files = st.file_uploader(
|
114
|
+
"Upload multiple binary files", type=["bin", "000"], accept_multiple_files=True
|
115
|
+
)
|
116
|
+
|
117
|
+
if uploaded_files:
|
118
|
+
st.info("Saving uploaded files to temporary disk files...")
|
119
|
+
|
120
|
+
# Save files to temporary path
|
121
|
+
temp_file_paths = []
|
122
|
+
for uploaded_file in uploaded_files:
|
123
|
+
suffix = Path(uploaded_file.name).suffix
|
124
|
+
with tempfile.NamedTemporaryFile(delete=False, suffix=suffix) as tmp:
|
125
|
+
tmp.write(uploaded_file.read())
|
126
|
+
temp_path = Path(tmp.name)
|
127
|
+
temp_file_paths.append(temp_path)
|
128
|
+
|
129
|
+
st.divider()
|
130
|
+
st.subheader("🛠 Processing and Combining...")
|
131
|
+
|
132
|
+
if display_log == "Yes":
|
133
|
+
# The `buffer` is used to display console output to streamlit
|
134
|
+
buffer = io.StringIO()
|
135
|
+
with contextlib.redirect_stdout(buffer):
|
136
|
+
adcpcat = ADCPBinFileCombiner()
|
137
|
+
combined_data = adcpcat.combine_files(temp_file_paths)
|
138
|
+
st.markdown(ansi_to_html(buffer.getvalue()), unsafe_allow_html=True)
|
139
|
+
else:
|
140
|
+
adcpcat = ADCPBinFileCombiner()
|
141
|
+
combined_data = adcpcat.combine_files(temp_file_paths)
|
142
|
+
|
143
|
+
if combined_data:
|
144
|
+
st.success("✅ Valid binary data has been combined successfully.")
|
145
|
+
st.warning(
|
146
|
+
"⚠️ Note: The time axis in the final file may be irregular due to missing ensembles during concatenation."
|
147
|
+
)
|
148
|
+
st.download_button(
|
149
|
+
label="📥 Download Combined Binary File",
|
150
|
+
data=bytes(combined_data),
|
151
|
+
file_name=output_cat_filename,
|
152
|
+
mime="application/octet-stream",
|
153
|
+
)
|
154
|
+
else:
|
155
|
+
st.warning("⚠️ No valid data found to combine.")
|
156
|
+
|
157
|
+
# Optional: Clean up temporary files
|
158
|
+
for path in temp_file_paths:
|
159
|
+
try:
|
160
|
+
os.remove(path)
|
161
|
+
except Exception as e:
|
162
|
+
st.warning(f"Failed to delete temp file {path}: {e}")
|
163
|
+
else:
|
164
|
+
st.info("Please upload binary files to begin.")
|
165
|
+
|
166
|
+
|
167
|
+
if __name__ == "__main__":
|
168
|
+
main()
|
pyadps/utils/__init__.py
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
# pyadps/utils/__init__.py
|
2
2
|
|
3
|
-
from pyadps.utils.cutbin import *
|
4
3
|
from pyadps.utils.plotgen import *
|
5
4
|
from pyadps.utils.profile_test import *
|
6
5
|
from pyadps.utils.pyreadrdi import *
|
7
6
|
from pyadps.utils.readrdi import *
|
8
|
-
from pyadps.utils.
|
7
|
+
from pyadps.utils.sensor_health import *
|
9
8
|
from pyadps.utils.signal_quality import *
|
10
9
|
from pyadps.utils.velocity_test import *
|
11
10
|
from pyadps.utils.writenc import *
|
12
|
-
|
11
|
+
from pyadps.utils.autoprocess import *
|
12
|
+
from pyadps.utils.logging_utils import *
|
13
|
+
from pyadps.utils.multifile import *
|
14
|
+
from pyadps.utils.script import *
|