pyadps 0.2.0b0__py3-none-any.whl → 0.3.0b0__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/pages/01_Read_File.py +96 -17
- pyadps/pages/02_View_Raw_Data.py +69 -33
- pyadps/pages/03_Download_Raw_File.py +4 -4
- pyadps/pages/04_Sensor_Health.py +892 -0
- pyadps/pages/05_QC_Test.py +478 -0
- pyadps/pages/06_Profile_Test.py +959 -0
- pyadps/pages/07_Velocity_Test.py +599 -0
- pyadps/pages/{07_Write_File.py → 08_Write_File.py} +127 -52
- pyadps/pages/09_Auto_process.py +62 -0
- pyadps/utils/__init__.py +2 -3
- pyadps/utils/autoprocess.py +129 -46
- pyadps/utils/metadata/config.ini +22 -4
- pyadps/utils/metadata/demo.000 +0 -0
- pyadps/utils/plotgen.py +499 -0
- pyadps/utils/profile_test.py +491 -126
- pyadps/utils/pyreadrdi.py +13 -6
- pyadps/utils/readrdi.py +78 -6
- pyadps/utils/script.py +21 -23
- pyadps/utils/sensor_health.py +120 -0
- pyadps/utils/signal_quality.py +343 -23
- pyadps/utils/velocity_test.py +75 -27
- pyadps/utils/writenc.py +8 -1
- {pyadps-0.2.0b0.dist-info → pyadps-0.3.0b0.dist-info}/METADATA +53 -22
- pyadps-0.3.0b0.dist-info/RECORD +33 -0
- {pyadps-0.2.0b0.dist-info → pyadps-0.3.0b0.dist-info}/WHEEL +1 -1
- 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/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.0b0.dist-info}/LICENSE +0 -0
- {pyadps-0.2.0b0.dist-info → pyadps-0.3.0b0.dist-info}/entry_points.txt +0 -0
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.3
|
2
2
|
Name: pyadps
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.3.0b0
|
4
4
|
Summary: A Python package for ADCP data processing
|
5
5
|
Home-page: https://example.com
|
6
6
|
License: MIT
|
@@ -22,18 +22,30 @@ Requires-Dist: numpy (>=1.26.4)
|
|
22
22
|
Requires-Dist: pandas (>=2.2.2)
|
23
23
|
Requires-Dist: plotly (>=5.22.0)
|
24
24
|
Requires-Dist: plotly-resampler (>=0.10.0)
|
25
|
+
Requires-Dist: pygeomag (>=1.1.0,<2.0.0)
|
25
26
|
Requires-Dist: scipy (>=1.14.0)
|
26
27
|
Requires-Dist: streamlit (>=1.36.0)
|
27
|
-
Requires-Dist: wmm2020 (>=1.1.1)
|
28
28
|
Project-URL: Documentation, https://example.com/docs
|
29
29
|
Project-URL: Repository, https://github.com/p-amol/pyadps
|
30
30
|
Description-Content-Type: text/markdown
|
31
31
|
|
32
32
|
# pyadps
|
33
33
|
|
34
|
-
`pyadps` is a Python package for processing moored Acoustic Doppler
|
34
|
+
`pyadps` is a Python package for processing moored Acoustic Doppler
|
35
|
+
Current Profiler (ADCP) data. It provides various functionalities
|
36
|
+
such as data reading, quality control tests, NetCDF file creation,
|
37
|
+
and visualization.
|
35
38
|
|
36
|
-
This software offers both a graphical interface (`Streamlit`) for
|
39
|
+
This software offers both a graphical interface (`Streamlit`) for
|
40
|
+
those new to Python and direct Python package access for experienced
|
41
|
+
users. Please note that `pyadps` is primarily designed for Teledyne
|
42
|
+
RDI workhorse ADCPs. Other company's ADCP files are not compatible,
|
43
|
+
and while some other RDI models may work, they might require additional
|
44
|
+
considerations.
|
45
|
+
|
46
|
+
- Documentation: <https://pyadps.readthedocs.io>
|
47
|
+
- Source code: <https://github.com/p-amol/pyadps>
|
48
|
+
- Bug reports: <https://github.com/p-amol/pyadps/issues>
|
37
49
|
|
38
50
|
## Table of Contents
|
39
51
|
|
@@ -43,37 +55,49 @@ This software offers both a graphical interface (`Streamlit`) for those new to P
|
|
43
55
|
|
44
56
|
## Installation
|
45
57
|
|
46
|
-
We recommend installing the package within a virtual environment.
|
47
|
-
|
58
|
+
We recommend installing the package within a virtual environment.
|
59
|
+
At present, the package is compatible exclusively with Python version 3.12.
|
60
|
+
You can create a Python environment using tools like `venv` or `conda`.
|
61
|
+
Below are instructions for both methods.
|
48
62
|
|
49
63
|
### 1. Using `venv` (Built-in Python Tool)
|
50
64
|
|
51
65
|
#### Step 1: Install Python version 3.12 (if not already installed)
|
66
|
+
|
52
67
|
Ensure you have Python installed. You can download the latest version from [python.org](https://www.python.org/downloads/).
|
53
68
|
|
54
|
-
#### Step 2: Create a Virtual Environment
|
69
|
+
#### Step 2: Create a Virtual Environment
|
70
|
+
|
55
71
|
- Open your terminal or command prompt.
|
56
72
|
- Navigate to your project folder:
|
73
|
+
|
57
74
|
```bash
|
58
75
|
cd /path/to/your/project
|
59
76
|
```
|
60
|
-
|
77
|
+
|
78
|
+
- Run the following command to create a virtual environment
|
79
|
+
(replace adpsenv with your preferred environment name):
|
61
80
|
|
62
81
|
```bash
|
63
82
|
python -m venv adpsenv
|
64
83
|
```
|
65
84
|
|
66
85
|
#### Step 3: Activate the Environment
|
86
|
+
|
67
87
|
- On Windows:
|
88
|
+
|
68
89
|
```bash
|
69
90
|
adpsenv\Scripts\activate
|
70
91
|
```
|
71
92
|
|
72
93
|
- On macOS/Linux:
|
94
|
+
|
73
95
|
```bash
|
74
96
|
source adpsenv/bin/activate
|
75
97
|
```
|
76
|
-
|
98
|
+
|
99
|
+
You’ll see the environment name in your terminal prompt
|
100
|
+
indicating the environment is active.
|
77
101
|
|
78
102
|
#### Step 4: Install Dependencies
|
79
103
|
|
@@ -84,44 +108,51 @@ pip install pyadps
|
|
84
108
|
```
|
85
109
|
|
86
110
|
#### Step 5: Deactivate the Environment
|
111
|
+
|
87
112
|
When you’re done working in the environment, deactivate it by running:
|
88
113
|
|
89
114
|
```bash
|
90
115
|
deactivate
|
91
116
|
```
|
92
117
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
### 2. Using `conda` (Anaconda/Miniconda):
|
118
|
+
### 2. Using `conda` (Anaconda/Miniconda)
|
97
119
|
|
98
120
|
#### Step 1: Install Conda
|
121
|
+
|
99
122
|
First, you need to have Conda installed on your system. You can either install:
|
100
123
|
|
101
124
|
- [Anaconda (Full Distribution)](https://www.anaconda.com/products/individual)
|
102
125
|
- [Miniconda (Lightweight Version)](https://docs.conda.io/en/latest/miniconda.html)
|
103
126
|
|
104
127
|
#### Step 2: Create a Conda Environment with Python 3.12
|
105
|
-
|
128
|
+
|
129
|
+
Once Conda is installed, open a terminal or command prompt and run
|
130
|
+
the following to create a new environment (replace `adpsenv` with
|
131
|
+
your preferred environment name):
|
106
132
|
|
107
133
|
```bash
|
108
134
|
conda create --name adpsenv python=3.12
|
109
135
|
```
|
110
136
|
|
111
|
-
#### Step 3: Activate the Environment
|
137
|
+
#### Step 3: Activate the Conda Environment
|
138
|
+
|
112
139
|
```bash
|
113
140
|
conda activate adpsenv
|
114
141
|
```
|
115
142
|
|
116
|
-
#### Step 4: Install Dependencies
|
117
|
-
|
143
|
+
#### Step 4: Install pyadps Dependencies
|
144
|
+
|
145
|
+
You can install packages with pip inside Conda environments.
|
146
|
+
|
118
147
|
```bash
|
119
148
|
pip install pyadps
|
120
149
|
```
|
121
150
|
|
122
|
-
#### Step 5: Deactivate the Environment
|
123
|
-
|
124
|
-
|
151
|
+
#### Step 5: Deactivate the Conda Environment
|
152
|
+
|
153
|
+
When done working in the environment, deactivate the environment by running:
|
154
|
+
|
155
|
+
```bash
|
125
156
|
conda deactivate
|
126
157
|
```
|
127
158
|
|
@@ -130,11 +161,11 @@ conda deactivate
|
|
130
161
|
### Streamlit web interface
|
131
162
|
|
132
163
|
Open a terminal or command prompt, activate the environment, and run the command.
|
164
|
+
|
133
165
|
```bash
|
134
166
|
run-pyadps
|
135
167
|
```
|
136
168
|
|
137
|
-
|
138
169
|
## License
|
139
170
|
|
140
171
|
This project is licensed under the MIT License. See the LICENSE file for details.
|
@@ -0,0 +1,33 @@
|
|
1
|
+
pyadps/Home_Page.py,sha256=gC0eFMtn85U_A4KcVlCEzXkB6a_J0WD3vpK691Kmyw8,1180
|
2
|
+
pyadps/__init__.py,sha256=bNCm6_WIhiwvaUeOZhRkyLZyzzUKfSH80Fslg0JPJyk,232
|
3
|
+
pyadps/__main__.py,sha256=cIFUayxPnKl00oIR99L6IUEvc8trW7dijtfBQCAen5c,356
|
4
|
+
pyadps/pages/01_Read_File.py,sha256=VfzxaOETEAdIJwth6QPiqDLgWtPc-nZf30huJR1velM,11611
|
5
|
+
pyadps/pages/02_View_Raw_Data.py,sha256=AhT7gvDbcMRPf-WIBzTQ0o-nn9_q7NH6plTlpMtgzaY,6170
|
6
|
+
pyadps/pages/03_Download_Raw_File.py,sha256=6tv1b5zyImSOVkTVhhGpm2TUVkvanhlTUksUlKJMWC8,8791
|
7
|
+
pyadps/pages/04_Sensor_Health.py,sha256=2abiawkByeOIx8h2B2-cm_UVL--dKWR7OWkZHu6TnY0,33499
|
8
|
+
pyadps/pages/05_QC_Test.py,sha256=kHTB4X3trKjLjT2pgIKzHMRCR2MvRf23V6BaThieAPU,16043
|
9
|
+
pyadps/pages/06_Profile_Test.py,sha256=bjfEqTwYUTdpFPf8ovEIqiz7O5pP_Y4Kxnj6AidF0FE,34163
|
10
|
+
pyadps/pages/07_Velocity_Test.py,sha256=mFYjXaswTZNkpWd9k2peq96uPBj-oTd6QYE7J8eQSHY,22792
|
11
|
+
pyadps/pages/08_Write_File.py,sha256=GrAo2KVOck2DYSp0x3Lb1pdYL-lZF8SBEdyDT7ev_j0,19542
|
12
|
+
pyadps/pages/09_Auto_process.py,sha256=gOvLEfwAPxe9v-W8DASKSuNQzB5BjHLnPkwUgOufwdI,1776
|
13
|
+
pyadps/pages/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
14
|
+
pyadps/utils/__init__.py,sha256=v1FzqeMdtqNlZfYN_Hzl7oNtMLkJacT-vATgz45hhno,373
|
15
|
+
pyadps/utils/autoprocess.py,sha256=aLsbLD5CoZ7bz1p737g01w1ym8BjEZjZpgGzLrngdUM,13825
|
16
|
+
pyadps/utils/metadata/config.ini,sha256=TC7htzGwUukIXt_u3JR5ycyvOoDj_JxWgGY6khjNeck,2154
|
17
|
+
pyadps/utils/metadata/demo.000,sha256=qxB3sgjABrpv4DNXkwjpbSxk5sc4UwAI8kgQX0--PM8,234468
|
18
|
+
pyadps/utils/metadata/flmeta.json,sha256=diIB9nht_0uw9YJNSFGdZYGzeVbR-07zIZS9Nf4VPSE,14245
|
19
|
+
pyadps/utils/metadata/vlmeta.json,sha256=_dkQlGkkUvpAIM7S6kEUenSaiCpOrwXg8n1aU3dDF3s,22535
|
20
|
+
pyadps/utils/plotgen.py,sha256=YsOetfczZ6NQMcLDZGMs_GsOT4AISsyaBA62rq7-CdM,26228
|
21
|
+
pyadps/utils/profile_test.py,sha256=RRTDJNKeUG8mJWFDhVJpBQQNidLG5C06pOT8XbWeeXE,20401
|
22
|
+
pyadps/utils/pyreadrdi.py,sha256=P1UTDrglgbYn3XQGUTsqNPynDGE-zp4cI_TW8yfOlic,35090
|
23
|
+
pyadps/utils/readrdi.py,sha256=36GfMn3bLQis8PsrL3zlAC22rBU9ItosWug3_44yesg,47403
|
24
|
+
pyadps/utils/script.py,sha256=RCRPm1s_HJpqWRO-E316WmFkONv9lkp2tzzvPGF2-I4,4919
|
25
|
+
pyadps/utils/sensor_health.py,sha256=aHRaU4kMJZ9dGmYypKpCCgq-owWoNjvcl1I_9I7dG68,3973
|
26
|
+
pyadps/utils/signal_quality.py,sha256=ab0Sr0oPFxkFWBjuGbl_IZNQEnfi_mXPyHmVzaGSOBU,16239
|
27
|
+
pyadps/utils/velocity_test.py,sha256=-95NKLQJ8Ni8etdxhDHxsfMF4MdRWcXL9fgLgWy7Kn0,6112
|
28
|
+
pyadps/utils/writenc.py,sha256=WrL5uh--qPLTPo-f2b49j0Ozm7Fq6H-97AJe4KMWkyE,10071
|
29
|
+
pyadps-0.3.0b0.dist-info/LICENSE,sha256=sfY_7DzQF5FxnO2T6ek74dfm5uBmwEp1oEg_WlzNsb8,1092
|
30
|
+
pyadps-0.3.0b0.dist-info/METADATA,sha256=RiQu9cwuLigYrVrbkjr9I9nfJh2Jrdaj2chl8aiSZG4,4463
|
31
|
+
pyadps-0.3.0b0.dist-info/WHEEL,sha256=RaoafKOydTQ7I_I3JTrPCg6kUmTgtm4BornzOqyEfJ8,88
|
32
|
+
pyadps-0.3.0b0.dist-info/entry_points.txt,sha256=qS5lbmTJLC4Ys0nu4-2tJoBpAHxTREta30KFrDyTfsY,90
|
33
|
+
pyadps-0.3.0b0.dist-info/RECORD,,
|
pyadps/pages/04_QC_Test.py
DELETED
@@ -1,334 +0,0 @@
|
|
1
|
-
import numpy as np
|
2
|
-
import pandas as pd
|
3
|
-
import plotly.express as px
|
4
|
-
import plotly.graph_objects as go
|
5
|
-
import streamlit as st
|
6
|
-
from plotly.subplots import make_subplots
|
7
|
-
from plotly_resampler import FigureResampler
|
8
|
-
from streamlit.runtime.state import session_state
|
9
|
-
from utils.signal_quality import ev_check, false_target, pg_check, qc_check
|
10
|
-
|
11
|
-
if "flead" not in st.session_state:
|
12
|
-
st.write(":red[Please Select Data!]")
|
13
|
-
st.stop()
|
14
|
-
|
15
|
-
# `mask` holds the temporary changes in the page
|
16
|
-
# `qcmask` holds the final changes in the page
|
17
|
-
if "mask" not in st.session_state:
|
18
|
-
st.session_state.mask = np.copy(st.session_state.orig_mask)
|
19
|
-
|
20
|
-
if not st.session_state.isQCMask:
|
21
|
-
st.write(":grey[Creating a new mask file ...]")
|
22
|
-
st.session_state.qc_mask = np.copy(st.session_state.orig_mask)
|
23
|
-
st.session_state.isSubmit = False
|
24
|
-
else:
|
25
|
-
st.write(":grey[Working on a saved mask file ...]")
|
26
|
-
st.write(":orange[WARNING! QC test already completed. Reset to change settings.]")
|
27
|
-
reset_button1 = st.button("Reset Mask Data")
|
28
|
-
if reset_button1:
|
29
|
-
st.session_state.mask = np.copy(st.session_state.orig_mask)
|
30
|
-
st.session_state.qc_mask = np.copy(st.session_state.orig_mask)
|
31
|
-
st.write(":green[Mask data is reset to default]")
|
32
|
-
|
33
|
-
if "isThresh" not in st.session_state:
|
34
|
-
st.session_state.isThresh = False
|
35
|
-
|
36
|
-
# Load data
|
37
|
-
flobj = st.session_state.flead
|
38
|
-
vlobj = st.session_state.vlead
|
39
|
-
velocity = st.session_state.velocity
|
40
|
-
echo = st.session_state.echo
|
41
|
-
correlation = st.session_state.correlation
|
42
|
-
pgood = st.session_state.pgood
|
43
|
-
ensembles = st.session_state.head.ensembles
|
44
|
-
cells = flobj.field()["Cells"]
|
45
|
-
fdata = flobj.fleader
|
46
|
-
vdata = vlobj.vleader
|
47
|
-
x = np.arange(0, ensembles, 1)
|
48
|
-
y = np.arange(0, cells, 1)
|
49
|
-
|
50
|
-
|
51
|
-
@st.cache_data
|
52
|
-
def fillplot_plotly(data, colorscale="balance"):
|
53
|
-
fig = FigureResampler(go.Figure())
|
54
|
-
data1 = np.where(data == -32768, np.nan, data)
|
55
|
-
fig.add_trace(
|
56
|
-
go.Heatmap(z=data1[:, 0:-1], x=x, y=y, colorscale=colorscale, hoverongaps=False)
|
57
|
-
)
|
58
|
-
st.plotly_chart(fig)
|
59
|
-
|
60
|
-
|
61
|
-
@st.cache_data
|
62
|
-
def plot_noise(dep=0, rec=-1):
|
63
|
-
n = dep
|
64
|
-
m = rec
|
65
|
-
colorleft = [
|
66
|
-
"rgb(240, 255, 255)",
|
67
|
-
"rgb(115, 147, 179)",
|
68
|
-
"rgb(100, 149, 237)",
|
69
|
-
"rgb(15, 82, 186)",
|
70
|
-
]
|
71
|
-
colorright = [
|
72
|
-
"rgb(250, 200, 152)",
|
73
|
-
"rgb(255, 165, 0)",
|
74
|
-
"rgb(255, 95, 31)",
|
75
|
-
"rgb(139, 64, 0)",
|
76
|
-
]
|
77
|
-
fig = make_subplots(
|
78
|
-
rows=1,
|
79
|
-
cols=2,
|
80
|
-
subplot_titles=[
|
81
|
-
f"Deployment Ensemble ({x[n]+1})",
|
82
|
-
f"Recovery Ensemble ({x[m]+1})",
|
83
|
-
],
|
84
|
-
)
|
85
|
-
for i in range(4):
|
86
|
-
fig.add_trace(
|
87
|
-
go.Scatter(
|
88
|
-
x=echo[i, :, n],
|
89
|
-
y=y,
|
90
|
-
name=f"Beam (D) {i+1}",
|
91
|
-
line=dict(color=colorleft[i]),
|
92
|
-
),
|
93
|
-
row=1,
|
94
|
-
col=1,
|
95
|
-
)
|
96
|
-
for i in range(4):
|
97
|
-
fig.add_trace(
|
98
|
-
go.Scatter(
|
99
|
-
x=echo[i, :, m],
|
100
|
-
y=y,
|
101
|
-
name=f"Beam (R) {i+1}",
|
102
|
-
line=dict(color=colorright[i]),
|
103
|
-
),
|
104
|
-
row=1,
|
105
|
-
col=2,
|
106
|
-
)
|
107
|
-
|
108
|
-
fig.update_layout(height=600, width=800, title_text="Echo Intensity")
|
109
|
-
fig.update_xaxes(title="Echo (count)")
|
110
|
-
fig.update_yaxes(title="Cells")
|
111
|
-
st.plotly_chart(fig)
|
112
|
-
|
113
|
-
######### NOISE FLOOR IDENTIFICATION ##############
|
114
|
-
dn = rn = 1
|
115
|
-
st.header("Noise Floor Identification", divider="blue")
|
116
|
-
st.write(
|
117
|
-
"""
|
118
|
-
If the ADCP has collected data from the air either
|
119
|
-
before deployment or after recovery, this data can
|
120
|
-
be used to estimate the echo intensity threshold.
|
121
|
-
The plots below show the echo intensity from the first
|
122
|
-
and last ensembles. The noise level is typically around
|
123
|
-
30-40 counts throughout the entire profile.
|
124
|
-
"""
|
125
|
-
)
|
126
|
-
dn = st.number_input("Deployment Ensemble", x[0] + 1, x[-1] + 1, x[0] + 1)
|
127
|
-
# r = st.number_input("Recovery Ensemble", -1 * (x[-1] + 1), -1 * (x[0] + 1), -1)
|
128
|
-
rn = st.number_input("Recovery Ensemble", x[0] + 1, x[-1] + 1, x[-1] + 1)
|
129
|
-
dn = dn - 1
|
130
|
-
rn = rn - 1
|
131
|
-
|
132
|
-
plot_noise(dep=dn, rec=rn)
|
133
|
-
|
134
|
-
|
135
|
-
################## QC Test ###################
|
136
|
-
|
137
|
-
st.header("Quality Control Tests", divider="blue")
|
138
|
-
st.write("")
|
139
|
-
|
140
|
-
left, right = st.columns([1, 1])
|
141
|
-
with left:
|
142
|
-
st.write(""" Teledyne RDI recommends these quality control tests,
|
143
|
-
some of which can be configured before deployment.
|
144
|
-
The pre-deployment values configured for the ADCP are listed
|
145
|
-
in the table below. The noise-floor identification graph above
|
146
|
-
can assist in determining the echo intensity threshold.
|
147
|
-
For more information about these tests,
|
148
|
-
refer to *Acoustic Doppler Current Profiler Principles of
|
149
|
-
Operation: A Practical Primer* by Teledyne RDI.""")
|
150
|
-
fdata = st.session_state.flead.field()
|
151
|
-
st.divider()
|
152
|
-
st.write(":blue-background[Additional Information:]")
|
153
|
-
st.write(f"Number of Pings per Ensemble: `{fdata["Pings"]}`")
|
154
|
-
st.write(f"Number of Beams: `{fdata["Beams"]}`")
|
155
|
-
st.divider()
|
156
|
-
st.write(":red-background[Thresholds used during deployment:]")
|
157
|
-
thresh = pd.DataFrame(
|
158
|
-
[
|
159
|
-
["Correlation", fdata["Correlation Thresh"]],
|
160
|
-
["Error Velocity", fdata["Error Velocity Thresh"]],
|
161
|
-
["Echo Intensity", 0],
|
162
|
-
["False Target", fdata["False Target Thresh"]],
|
163
|
-
["Percentage Good", fdata["Percent Good Min"]],
|
164
|
-
],
|
165
|
-
columns=["Threshold", "Values"],
|
166
|
-
)
|
167
|
-
|
168
|
-
st.write(thresh)
|
169
|
-
|
170
|
-
with right:
|
171
|
-
with st.form(key="my_form"):
|
172
|
-
st.write("Would you like to apply new threshold?")
|
173
|
-
|
174
|
-
ct = st.number_input(
|
175
|
-
"Select Correlation Threshold",
|
176
|
-
0,
|
177
|
-
255,
|
178
|
-
fdata["Correlation Thresh"],
|
179
|
-
)
|
180
|
-
|
181
|
-
evt = st.number_input(
|
182
|
-
"Select Error Velocity Threshold",
|
183
|
-
0,
|
184
|
-
9999,
|
185
|
-
fdata["Error Velocity Thresh"],
|
186
|
-
)
|
187
|
-
|
188
|
-
et = st.number_input(
|
189
|
-
"Select Echo Intensity Threshold",
|
190
|
-
0,
|
191
|
-
255,
|
192
|
-
0,
|
193
|
-
)
|
194
|
-
|
195
|
-
ft = st.number_input(
|
196
|
-
"Select False Target Threshold",
|
197
|
-
0,
|
198
|
-
255,
|
199
|
-
fdata["False Target Thresh"],
|
200
|
-
)
|
201
|
-
|
202
|
-
option = st.selectbox(
|
203
|
-
"Would you like to use a three-beam solution?", (True, False)
|
204
|
-
)
|
205
|
-
|
206
|
-
pgt = st.number_input(
|
207
|
-
"Select Percent Good Threshold",
|
208
|
-
0,
|
209
|
-
100,
|
210
|
-
fdata["Percent Good Min"],
|
211
|
-
)
|
212
|
-
submit_button = st.form_submit_button(label="Submit")
|
213
|
-
|
214
|
-
|
215
|
-
mask = st.session_state.mask
|
216
|
-
with left:
|
217
|
-
if submit_button:
|
218
|
-
st.session_state.newthresh = pd.DataFrame(
|
219
|
-
[
|
220
|
-
["Correlation", str(ct)],
|
221
|
-
["Error Velocity", str(evt)],
|
222
|
-
["Echo Intensity", str(et)],
|
223
|
-
["False Target", str(ft)],
|
224
|
-
["Three Beam", str(option)],
|
225
|
-
["Percentage Good", str(pgt)],
|
226
|
-
],
|
227
|
-
columns=["Threshold", "Values"],
|
228
|
-
)
|
229
|
-
st.session_state.isThresh = True
|
230
|
-
# st.write(st.session_state.newthresh)
|
231
|
-
|
232
|
-
mask = pg_check(pgood, mask, pgt, threebeam=option)
|
233
|
-
mask = qc_check(correlation, mask, ct)
|
234
|
-
mask = qc_check(echo, mask, et)
|
235
|
-
mask = ev_check(velocity[3, :, :], mask, evt)
|
236
|
-
mask = false_target(echo, mask, ft, threebeam=True)
|
237
|
-
st.session_state.mask = mask
|
238
|
-
|
239
|
-
if st.session_state.isThresh:
|
240
|
-
st.write(":green-background[Current Thresholds]")
|
241
|
-
st.write(st.session_state.newthresh)
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
st.header("Mask File", divider="blue")
|
246
|
-
st.write(
|
247
|
-
"""
|
248
|
-
Displayed the mask file.
|
249
|
-
Ensure to save any necessary changes or apply additional thresholds if needed.
|
250
|
-
"""
|
251
|
-
)
|
252
|
-
|
253
|
-
|
254
|
-
if st.button("Display mask file"):
|
255
|
-
st.subheader("Default Mask File")
|
256
|
-
st.write(
|
257
|
-
"""
|
258
|
-
ADCP assigns missing values based on thresholds set before deployment.
|
259
|
-
These values cannot be recovered and the default
|
260
|
-
"""
|
261
|
-
)
|
262
|
-
fillplot_plotly(st.session_state.orig_mask, colorscale="greys")
|
263
|
-
|
264
|
-
|
265
|
-
st.subheader("Update Mask File")
|
266
|
-
st.write(
|
267
|
-
"""
|
268
|
-
Update, display and save the updated mask file after applying threshold.
|
269
|
-
If thresholds are not saved, default mask file is used.
|
270
|
-
"""
|
271
|
-
)
|
272
|
-
# values, counts = np.unique(mask, return_counts=True)
|
273
|
-
fillplot_plotly(st.session_state.mask, colorscale="greys")
|
274
|
-
|
275
|
-
############## SENSOR HEALTH ######################
|
276
|
-
st.header("Sensor Health", divider="blue")
|
277
|
-
st.write("The following details can be used to determine whether the additional sensors are functioning properly.")
|
278
|
-
# ################## Pressure Sensor Check ###################
|
279
|
-
# st.subheader("Pressure Sensor Check", divider="orange")
|
280
|
-
#
|
281
|
-
# st.subheader("Temperature Sensor Check", divider="orange")
|
282
|
-
#
|
283
|
-
# st.subheader("Tilt Sensor Check", divider="orange")
|
284
|
-
################## Fix Orientation ###################
|
285
|
-
st.subheader("Fix Orientation", divider="orange")
|
286
|
-
|
287
|
-
|
288
|
-
if st.session_state.beam_direction == 'Up':
|
289
|
-
beamalt = 'Down'
|
290
|
-
else:
|
291
|
-
beamalt = 'Up'
|
292
|
-
st.write(f"The current orientation of ADCP is `{st.session_state.beam_direction}`. Use the below option to correct the orientation.")
|
293
|
-
|
294
|
-
beamdir_select = st.radio(f'Change orientation to {beamalt}', ['No', 'Yes'])
|
295
|
-
if beamdir_select == 'Yes':
|
296
|
-
st.session_state.beam_direction = beamalt
|
297
|
-
st.write(f"The orientation changed to `{st.session_state.beam_direction}`")
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
################## Save Button #############
|
303
|
-
st.header("Save Data", divider="blue")
|
304
|
-
col1, col2 = st.columns([1, 1])
|
305
|
-
with col1:
|
306
|
-
save_mask_button = st.button(label="Save Mask Data")
|
307
|
-
|
308
|
-
if save_mask_button:
|
309
|
-
# st.session_state.mask = mask
|
310
|
-
st.session_state.qc_mask = np.copy(st.session_state.mask)
|
311
|
-
st.session_state.isQCMask = True
|
312
|
-
st.session_state.isProfileMask = False
|
313
|
-
st.session_state.isGridSave = False
|
314
|
-
st.session_state.isVelocityMask = False
|
315
|
-
st.write(":green[Mask file saved]")
|
316
|
-
else:
|
317
|
-
st.write(":red[Mask data not saved]")
|
318
|
-
with col2:
|
319
|
-
reset_mask_button = st.button("Reset mask Data")
|
320
|
-
if reset_mask_button:
|
321
|
-
st.session_state.mask = np.copy(st.session_state.orig_mask)
|
322
|
-
st.session_state.isQCMask = False
|
323
|
-
st.session_state.isGrid = False
|
324
|
-
st.session_state.isProfileMask = False
|
325
|
-
st.session_state.isVelocityMask = False
|
326
|
-
st.write(":green[Mask data is reset to default]")
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|