Skip to content

Commit 24d9b67

Browse files
authored
Merge pull request #56 from ooipy/bug-fixes
Adding all bug fixes for 1.1.1 release
2 parents 48256d1 + a4d94e8 commit 24d9b67

File tree

12 files changed

+257
-90
lines changed

12 files changed

+257
-90
lines changed

.github/workflows/linting.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
2+
name: Lint code
3+
4+
on: [pull_request, push]
5+
6+
jobs:
7+
lint-code:
8+
runs-on: ubuntu-20.04
9+
steps:
10+
- uses: actions/checkout@v2
11+
- uses: actions/setup-python@v2
12+
- uses: pre-commit/[email protected]
13+
# allow to error for now
14+
continue-on-error: true

.github/workflows/unit_test.yml

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,40 +4,55 @@ on: [push, pull_request]
44

55
jobs:
66
unit_test:
7-
runs-on: ubuntu-latest
7+
name: ${{ matrix.python-version }}-unit-test
8+
runs-on: ubuntu-20.04
9+
continue-on-error: ${{ matrix.experimental }}
10+
strategy:
11+
matrix:
12+
python-version: [3.7, 3.8]
13+
experimental: [false]
814
steps:
915
- name: Checkout Repo
1016
uses: actions/checkout@v2
17+
- name: Setup Python
18+
uses: actions/setup-python@v1
19+
with:
20+
python-version: ${{ matrix.python-version }}
21+
architecture: x64
22+
- name: Cache conda
23+
uses: actions/cache@v2
24+
env:
25+
# Increase this value to reset cache if conda_envs/py${{ matrix.python-version }}.yml has not changed
26+
CACHE_NUMBER: 0
27+
with:
28+
path: ~/conda_pkgs_dir
29+
key: ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}-${{ hashFiles('conda_envs/py${{ matrix.python-version }}.yml') }}
1130
- name: Install conda
1231
uses: conda-incubator/setup-miniconda@v2
1332
with:
1433
activate-environment: ooi
15-
environment-file: conda_envs/ooi_linux.yml
16-
auto-update-conda: true
17-
python-version: 3.8
18-
miniconda-version: "latest"
34+
environment-file: conda_envs/py${{ matrix.python-version }}.yml
35+
python-version: ${{ matrix.python-version }}
1936
auto-activate-base: false
20-
- shell: bash -l {0}
37+
use-only-tar-bz2: true
38+
- name: Print conda env
39+
shell: bash -l {0}
2140
run: |
2241
conda info
2342
conda list
24-
- name: install pytest
43+
- name: Install pytest
2544
shell: bash -l {0}
26-
run: conda install --yes pytest
27-
- name: install ooipy
45+
run: mamba install --yes pytest
46+
- name: Install ooipy
2847
shell: bash -l {0}
2948
run: pip install .
30-
- name: run unit tests
49+
- name: Run unit tests
3150
shell: bash -l {0}
3251
env:
3352
FORCE_COLOR: 3
34-
run: pytest -vv tests
35-
- name: save unit tests in file
36-
if: ${{ always() }}
37-
shell: bash -l {0}
38-
run: py.test tests &> unit_test_log.log
53+
run: pytest -vv tests |& tee unit_test_log.log
3954
- name: Upload unit test log
40-
if: ${{ always() }}
55+
if: ${{ success() || failure() }}
4156
uses: actions/upload-artifact@v2
4257
with:
4358
name: unit_test_log

.pre-commit-config.yaml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
repos:
2+
- repo: https://github.com/pre-commit/pre-commit-hooks
3+
rev: v3.1.0
4+
hooks:
5+
- id: trailing-whitespace
6+
- id: end-of-file-fixer
7+
- id: check-docstring-first
8+
- id: check-json
9+
- id: check-yaml
10+
- id: pretty-format-json
11+
args: ["--autofix", "--indent=2", "--no-sort-keys"]
12+
13+
- repo: https://github.com/ambv/black
14+
rev: 19.10b0
15+
hooks:
16+
- id: black
17+
args: ["--line-length", "100"]
18+
19+
- repo: https://gitlab.com/pycqa/flake8
20+
rev: 3.8.3
21+
hooks:
22+
- id: flake8
23+
args:
24+
[
25+
"--ignore",
26+
"E999,N802,N806,W503,W504",
27+
"--exclude=setup.py,tests,__init__.py,ooipy/__init__.py,ooipy/request/__init__.py,ooipy/hydrophone/__init__.py,,ooipy/ctd/__init__.py,ooipy/surface_buoy/__init__.py,ooipy/visualize/__init__.py,docs",
28+
"--tee",
29+
"--output-file=flake8_log.txt",
30+
]
31+
32+
- repo: https://github.com/asottile/seed-isort-config
33+
rev: v2.2.0
34+
hooks:
35+
- id: seed-isort-config
36+
37+
- repo: https://github.com/pre-commit/mirrors-isort
38+
rev: v5.2.0
39+
hooks:
40+
- id: isort
41+
42+
- repo: https://github.com/myint/rstcheck
43+
rev: master
44+
hooks:
45+
- id: rstcheck

MANIFEST.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
include README.md
22
include LICENSE
33
include *.txt
4+
include ooipy/hydrophone/calibration_by_assetID.csv

conda_envs/py3.7.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
name: ooi
2+
channels:
3+
- conda-forge
4+
- defaults
5+
dependencies:
6+
- python=3.7
7+
- obspy
8+
- fsspec
9+
- aiohttp
10+
- pandas
11+
- mamba

conda_envs/py3.8.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
name: ooi
2+
channels:
3+
- conda-forge
4+
- defaults
5+
dependencies:
6+
- python=3.8
7+
- obspy
8+
- fsspec
9+
- aiohttp
10+
- pandas
11+
- mamba

features_since_release.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,7 @@ Updates in resealse v1.1.0
1414
- added request/ctd_request.py module
1515
- added ctd/basic.py module for extracting CTD data and computing parameter profiles over the water column
1616

17+
Updates in release v1.1.1
18+
-------------------------
19+
20+
- bug fixes in multiprocessing functions and hydrophone sensitivity correction

ooipy/hydrophone/basic.py

Lines changed: 81 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -82,35 +82,26 @@ def frequency_calibration(self, N):
8282
output_array : np.array
8383
array with correction coefficient for every frequency
8484
"""
85-
# Calibration for Low Frequency Hydrophones
85+
# Load calibation file and get appropriate calibration info
86+
filename = os.path.dirname(ooipy.__file__) + \
87+
'/hydrophone/calibration_by_assetID.csv'
88+
# Use deployment CSV to determine asset_ID
89+
assetID = self.get_asset_ID()
90+
91+
# load calibration data as pandas dataframe
92+
cal_by_assetID = pd.read_csv(filename, header=[0, 1])
93+
94+
f_calib = cal_by_assetID[assetID]['Freq (kHz)'].to_numpy() * 1000
95+
sens_calib_0 = cal_by_assetID[assetID]['0 phase'].to_numpy()
96+
sens_calib_90 = cal_by_assetID[assetID]['90 phase'].to_numpy()
97+
sens_calib = 0.5 * (sens_calib_0 + sens_calib_90)
98+
f = np.linspace(0, round(self.stats.sampling_rate / 2), N)
99+
100+
# Convert calibration to correct units
86101
if round(self.stats.sampling_rate) == 200:
87-
lf_cal = {
88-
'HYSB1': 2311.11, 'HYS14': 2499.09, 'AXBA1': 2257.3,
89-
'AXEC2': 2421.0, 'AXCC1': 2480.98}
90-
f = np.linspace(0, 100, N)
91-
f_calib = np.array([0, 100])
92-
sens_calib_db = 20 * np.log10(lf_cal[self.stats.station] * 1e-6)
93-
sens_calib = np.array([sens_calib_db, sens_calib_db])
94-
95-
# Calibratino for Broadband Hydrophones
102+
sens_calib = 20 * np.log10(sens_calib * 1e-6)
96103
elif round(self.stats.sampling_rate) == 64000:
97-
filename = os.path.dirname(ooipy.__file__) + \
98-
'/hydrophone/calibration_by_assetID.pkl'
99-
# Use deployment CSV to determine asset_ID
100-
assetID = self.get_asset_ID()
101-
102-
# load calibration data as pandas dataframe
103-
with open(filename, 'rb') as f:
104-
cal_by_assetID = pickle.load(f)
105-
106-
f_calib = cal_by_assetID[assetID]['Freq (kHz)'].to_numpy() * 1000
107-
sens_calib_0 = cal_by_assetID[assetID]['0 phase'].to_numpy()
108-
sens_calib_90 = cal_by_assetID[assetID]['90 phase'].to_numpy()
109-
# Average 0 and 90 degree phase response
110-
sens_calib = 0.5 * (sens_calib_0 + sens_calib_90)
111104
sens_calib = sens_calib + 128.9
112-
f = np.linspace(0, 32000, N)
113-
114105
else:
115106
raise Exception('Invalid sampling rate')
116107

@@ -306,14 +297,16 @@ def compute_spectrogram_mp(self, n_process=None, win='hann', L=4096,
306297
temp_slice = self.slice(starttime=UTCDateTime(starttime),
307298
endtime=UTCDateTime(endtime))
308299
tmp_obj = HydrophoneData(data=temp_slice.data,
309-
header=temp_slice.stats)
300+
header=temp_slice.stats,
301+
node=self.stats.location)
310302
ooi_hyd_data_list.append((tmp_obj, win, L, avg_time, overlap))
311303

312304
starttime = self.stats.starttime + datetime.timedelta(
313305
seconds=(N - 1) * seconds_per_process)
314306
temp_slice = self.slice(starttime=UTCDateTime(starttime),
315307
endtime=UTCDateTime(self.stats.endtime))
316-
tmp_obj = HydrophoneData(data=temp_slice.data, header=temp_slice.stats)
308+
tmp_obj = HydrophoneData(data=temp_slice.data, header=temp_slice.stats,
309+
node=self.stats.location)
317310
ooi_hyd_data_list.append((tmp_obj, win, L, avg_time, overlap))
318311

319312
with mp.get_context("spawn").Pool(n_process) as p:
@@ -488,7 +481,8 @@ def compute_psd_welch_mp(self, split, n_process=None, win='hann', L=4096,
488481
temp_slice = self.slice(starttime=UTCDateTime(starttime),
489482
endtime=UTCDateTime(endtime))
490483
tmp_obj = HydrophoneData(data=temp_slice.data,
491-
header=temp_slice.stats)
484+
header=temp_slice.stats,
485+
node=self.stats.location)
492486
ooi_hyd_data_list.append(
493487
(tmp_obj, win, L, overlap, avg_method, interpolate, scale))
494488

@@ -499,7 +493,8 @@ def compute_psd_welch_mp(self, split, n_process=None, win='hann', L=4096,
499493
temp_slice = self.slice(starttime=UTCDateTime(starttime),
500494
endtime=UTCDateTime(self.stats.endtime))
501495
tmp_obj = HydrophoneData(data=temp_slice.data,
502-
header=temp_slice.stats)
496+
header=temp_slice.stats,
497+
node=self.stats.location)
503498
ooi_hyd_data_list.append(
504499
(tmp_obj, win, L, overlap, avg_method, interpolate, scale))
505500
# use segmentation specified by split
@@ -509,7 +504,8 @@ def compute_psd_welch_mp(self, split, n_process=None, win='hann', L=4096,
509504
temp_slice = self.slice(starttime=UTCDateTime(row[0]),
510505
endtime=UTCDateTime(row[1]))
511506
tmp_obj = HydrophoneData(data=temp_slice.data,
512-
header=temp_slice.stats)
507+
header=temp_slice.stats,
508+
node=self.stats.location)
513509
ooi_hyd_data_list.append(
514510
(tmp_obj, win, L, overlap, avg_method, interpolate, scale))
515511

@@ -570,38 +566,61 @@ def wav_write(self, filename, norm=False, new_sample_rate=None):
570566
wavfile.write(filename, int(sampling_rate), data)
571567

572568
def get_asset_ID(self):
573-
url = 'https://raw.githubusercontent.com/OOI-CabledArray/' \
574-
'deployments/main/HYDBBA_deployments.csv'
575-
hyd_df = pd.read_csv(url)
576-
577-
if self.stats.location == 'LJ01D': # LJ01D'Oregon Shelf Base Seafloor
578-
ref = 'CE02SHBP-LJ01D-11-HYDBBA106'
579-
if self.stats.location == 'LJ01A': # LJ01AOregon Slope Base Seafloor
580-
ref = 'RS01SLBS-LJ01A-09-HYDBBA102'
581-
if self.stats.location == 'PC01A': # Oregan Slope Base Shallow
582-
ref = 'RS01SBPS-PC01A-08-HYDBBA103'
583-
if self.stats.location == 'PC03A': # Axial Base Shallow Profiler
584-
ref = 'RS03AXPS-PC03A-08-HYDBBA303'
585-
if self.stats.location == 'LJ01C': # Oregon Offshore Base Seafloor
586-
ref = 'CE04OSBP-LJ01C-11-HYDBBA105'
587-
if self.stats.location == 'LJ03A': # Axial Base Seafloor
588-
ref = 'RS03AXBS-LJ03A-09-HYDBBA302'
589-
590-
hyd_df['referenceDesignator']
591-
592-
df_ref = hyd_df.loc[hyd_df['referenceDesignator'] == ref]
593-
594-
df_start = df_ref.loc[(df_ref['startTime'] < self.stats.starttime) &
595-
(df_ref['endTime'] > self.stats.starttime)]
596-
df_end = df_ref.loc[(df_ref['startTime'] < self.stats.endtime) &
597-
(df_ref['endTime'] > self.stats.endtime)]
598-
599-
if df_start.index.to_numpy() == df_end.index.to_numpy():
600-
idx = df_start.index.to_numpy()
601-
asset_ID = df_start['assetID'][int(idx)]
569+
'''
570+
get_asset_ID returns the hydrophone asset ID for a given data sample.
571+
This data can be foun `here <https://raw.githubusercontent.com/
572+
OOI-CabledArray/deployments/main/HYDBBA_deployments.csv'>`_ for
573+
broadband hydrophones. Since Low frequency hydrophones remain
574+
constant with location and time, if the hydrophone is low frequency,
575+
the node ID is returned
576+
'''
577+
# Low frequency hydrophone
578+
if round(self.stats.sampling_rate) == 200:
579+
asset_ID = self.stats.location
580+
581+
elif round(self.stats.sampling_rate) == 64000:
582+
url = 'https://raw.githubusercontent.com/OOI-CabledArray/' \
583+
'deployments/main/HYDBBA_deployments.csv'
584+
hyd_df = pd.read_csv(url)
585+
586+
# LJ01D'Oregon Shelf Base Seafloor
587+
if self.stats.location == 'LJ01D':
588+
ref = 'CE02SHBP-LJ01D-11-HYDBBA106'
589+
# LJ01AOregon Slope Base Seafloor
590+
if self.stats.location == 'LJ01A':
591+
ref = 'RS01SLBS-LJ01A-09-HYDBBA102'
592+
# Oregan Slope Base Shallow
593+
if self.stats.location == 'PC01A':
594+
ref = 'RS01SBPS-PC01A-08-HYDBBA103'
595+
# Axial Base Shallow Profiler
596+
if self.stats.location == 'PC03A':
597+
ref = 'RS03AXPS-PC03A-08-HYDBBA303'
598+
# Oregon Offshore Base Seafloor
599+
if self.stats.location == 'LJ01C':
600+
ref = 'CE04OSBP-LJ01C-11-HYDBBA105'
601+
# Axial Base Seafloor
602+
if self.stats.location == 'LJ03A':
603+
ref = 'RS03AXBS-LJ03A-09-HYDBBA302'
604+
605+
hyd_df['referenceDesignator']
606+
607+
df_ref = hyd_df.loc[hyd_df['referenceDesignator'] == ref]
608+
609+
df_start = df_ref.loc[(df_ref['startTime'] < self.stats.starttime)
610+
& (df_ref['endTime']
611+
> self.stats.starttime)]
612+
df_end = df_ref.loc[(df_ref['startTime'] < self.stats.endtime) &
613+
(df_ref['endTime'] > self.stats.endtime)]
614+
615+
if df_start.index.to_numpy() == df_end.index.to_numpy():
616+
idx = df_start.index.to_numpy()
617+
asset_ID = df_start['assetID'][int(idx)]
618+
else:
619+
raise Exception('Hydrophone Data involves multiple'
620+
'deployments. Feature to be added later')
602621
else:
603-
raise Exception('Hydrophone Data involves multiple deployments.'
604-
'Feature to be added later')
622+
raise Exception('Invalid hydrophone sampling rate')
623+
605624
return asset_ID
606625

607626

0 commit comments

Comments
 (0)