tadc 2.3.5__tar.gz

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.
tadc-2.3.5/LICENSE.txt ADDED
@@ -0,0 +1 @@
1
+ Software code created by U.S. Government employees is not subject to copyright in the United States (17 U.S.C. �105). The United States/Department of Commerce reserves all rights to seek and obtain copyright protection in countries other than the United States for Software authored in its entirety by the Department of Commerce. To this end, the Department of Commerce hereby grants to Recipient a royalty-free, nonexclusive license to use, copy, and create derivative works of the Software outside of the United States.
tadc-2.3.5/PKG-INFO ADDED
@@ -0,0 +1,116 @@
1
+ Metadata-Version: 2.4
2
+ Name: tadc
3
+ Version: 2.3.5
4
+ Summary: The Tidal Analysis Datum Calculator (TADC) computes tidal datums from a water level data time series.
5
+ Author-email: "Center for Operational Oceanographic Products and Services, National Ocean Service, National Oceanic and Atmsopheric Administration" <tide.predictions@noaa.gov>
6
+ Project-URL: Online Web App, https://access.co-ops.nos.noaa.gov/datumcalc/
7
+ Project-URL: Technical Report, https://access.co-ops.nos.noaa.gov/datumcalc/docs/TechnicalReport.pdf
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Operating System :: OS Independent
10
+ Requires-Python: >=3.0
11
+ Description-Content-Type: text/markdown
12
+ License-File: LICENSE.txt
13
+ Requires-Dist: matplotlib
14
+ Requires-Dist: numpy
15
+ Requires-Dist: pandas>=2.0.3
16
+ Requires-Dist: python-dateutil
17
+ Requires-Dist: requests
18
+ Requires-Dist: scipy
19
+ Dynamic: license-file
20
+
21
+ # CO-OPS Tidal Analysis Datum Calculator (TADC)
22
+
23
+
24
+ # Overview
25
+
26
+ This is code for the NOAA Tidal Analysis Datum Calculator tool.
27
+
28
+ This tool computes tidal datums from a water level data time series. The TADC uses a Butterworth digital filter to remove high frequency (> 4 cycles/day) water level variability in order to identify tidal high and low waters from observed water level data. For official datums, CO-OPS uses a procedure called Curve Fit Manual Verification (CFMV) approach to identify tidal high and low waters that requires human oversight. The accuracy of this tool relative to the CO-OPS approach is described in detail in the following technical document:
29
+
30
+ Licate LA, Huang L and Dusek G (2017) A Comparison of Datums Derived from CO-OPS Verified Data Products and Tidal Analysis Datum Calculator. [NOAA Technical Report NOS CO-OPS 085](https://access.co-ops.nos.noaa.gov/datumcalc/docs/TechnicalReport.pdf).
31
+
32
+ For additional information, contact: NOAA's [Center for Operational Oceanographic Products and Services](https://tidesandcurrents.noaa.gov/)
33
+ User Services: tide.predictions@noaa.gov
34
+
35
+
36
+ # Installation
37
+ ```bash
38
+ pip install git+https://github.com/NOAA-CO-OPS/CO-OPS-Tidal-Analysis-Datum-Calculator
39
+ ```
40
+ or
41
+ ```bash
42
+ git clone https://github.com/NOAA-CO-OPS/dev_CO-OPS-Tidal-Analysis-Datum-Calculator
43
+ cd dev_CO-OPS-Tidal-Analysis-Datum-Calculator
44
+ conda env create -f environment.yml
45
+ conda activate tadc
46
+ ```
47
+
48
+
49
+ # Usage
50
+ You can run the TADC from the command line. Results will print to the terminal window:
51
+ ```bash
52
+ python -m tadc.run --fname data\test_timeseries_simple.csv --Subordinate_Lat 37 --Subordinate_Lon -79
53
+ ```
54
+ > [!NOTE]
55
+ > Use `--outfile_save_dir C:\your\dir` and `--make_plots True` to save results and monthly diagnostic plots.
56
+
57
+ Or, you can use TADC within other Python programs like so:
58
+ ```Python
59
+ import tadc
60
+ out = tadc.run(fname='data/test_timeseries_simple.csv', Subordinate_Lat=37, Subordinate_Lon=-79)
61
+ summary = out.readme
62
+ high_lows = out.high_lows
63
+ monthly_plots = out.plots
64
+ sub_monthly_means = out.subordinate_monthly_means
65
+ datums = out.datums
66
+ ```
67
+ Note that you can alternatively pass your timeseries directly to tadc as a `Pandas` `DataFrame`:
68
+ ```Python
69
+ import pandas as pd
70
+ import tadc
71
+ timeseries = pd.read_csv('data/test_timeseries_simple.csv')
72
+ out = tadc.run(data=timeseries, Subordinate_Lat=37.8, Subordinate_Lon=-79.6)
73
+ ```
74
+ > [!NOTE]
75
+ > One and only one of either `fname` or `data` must be specified when running `tadc()`
76
+
77
+ The object returned by `tadc.run()` also supports some further analyses on the data, in particular `daily_max_analysis`, `daily_min_analysis`, and `inundation_analysis`:
78
+ ```Python
79
+ out = tadc.run(data=timeseries, Subordinate_Lat=37.8, Subordinate_Lon=-79.6)
80
+ daily_max_obj = out.daily_max_analysis(datum='MHHW') # Do an analysis of daily maximums on MHHW #
81
+ daily_maxs = daily_max_obj.daily_maxs # returns the daily max timeseries #
82
+ daily_max_obj.plot() # creates a timeseries plot of the daily maxs #
83
+ daily_min_obj = out.daily_min_analysis(datum='MHHW') # Do an analysis of daily minimums on MHHW #
84
+ # daily_min_obj has the same sub-methods as daily_max_obj #
85
+ inundation_analysis_obj = out.inundation_analysis(threshold=0.5, threshold_datum='MHHW') # Do an analysis of inundations above MHHW+0.5 m #
86
+ inundation_analysis_obj.inundations() # returns the intervals of threshold exceedance #
87
+ inundation_analysis_obj.plot() # creates a plot of inundation time vs. depth #
88
+ ```
89
+
90
+ # Parameters:
91
+ Whether running from the command line or in Python, the following input arguments can be passed:
92
+
93
+ | Argument &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | Type &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | Default | Description |
94
+ | :--- | :--- | :--- | :--- |
95
+ | `--fname` | `file path` | `None` | Required unless `--data` is specified.<br>The full path of the timeseries data to be analyzed.
96
+ | `--data` | `pandas DataFrame` | `None` | Required unless `--fname` is specified.<br>The timeseries data to be analyzed as a Pandas DataFrame object. Only used in Python workflows.
97
+ | `--Subordinate_Lat` | `float` | `None` | The latitude (in decimal degrees) of the station for which datums are being computed.
98
+ | `--Subordinate_Lon` | `float` | `None` | The longitude (in decimal degrees) of the station for which datums are being computed.
99
+ | `--Units` | {`'Meters'`,<br>`'Centimeters'`,<br>`'Feet'`,<br>`'Inches'`} | `'Meters'` | The units of the input data. All calculations will be done on these units.<br>**Warning** Must match the units of the input data.
100
+ | `--Time_Zone` | `str` | `'GMT'` | The time zone of the input data. All calculations will be done in this timezone.<br>**Warning** Must match the time zone of the input data.
101
+ | `--resample_minutes` | `int` | `None` | Resample the input data to this sampling rate (in minutes).<br> **Note** If your data are unevenly spaced in time, resampling will be done automatically at a detected interval which can be modified by setting this parameter.
102
+ | `--Control_Station_ID` | `int` | `None` | The seven-digit station ID of the NWLON control station being used, if using a control station.
103
+ | `--Method_Option` | {`'AUTO'`,<br>`'FRED'`,<br>`'TBYT'`,<br>`'MMSC'`} | `'AUTO'` | The datum adjustment method to use when using a control station.<br>`'AUTO'`: Auto select. If using a control station and <1 month of data 'TBYT' will be used, 'MMSC' otherwise. If not using a control station 'FRED' will be used.<br>`'FRED'`: First reduction method. No adjustment from control station, simple average of highs and lows.<br>`'TBYT'`: Tide by tide analysis. Compares simultaneous high/low waters at the input and control stations.<br>`'MMSC'`: Monthly means simultaneous comparison. Compares monthly means at the input and control stations.
104
+ | `--Pick_Method` | {`'PolyFit'`,<br>`'Direct'`} | `'PolyFit'` | The method to pick high and low tide times and values.<br>`'PolyFit'`: Fit a polynomial to the observations and extract highs and lows from the fit.<br>`'Direct'`: Extract highs and lows directly from the input timeseries.
105
+ | `--outfile_save_dir` | `directory path` | `None` | The directory into which to save output files, if run from the command line. No effect if run in a Python workflow.<br>**Note** A timestamped folder will be created containing the output files.
106
+ | `--make_plots` | `bool` | `False` | Whether or not to create plots, one per month, showing the extracted high and low tides.<br>**Warning** To save plots when running from the command line, `--outfile_save_dir` must also be specified. If running in a Python workflow, plots will be created as Python objects.
107
+
108
+
109
+ # NOAA Open Source Disclaimer
110
+
111
+ This repository is a scientific product and is not official communication of the National Oceanic and Atmospheric Administration, or the United States Department of Commerce. All NOAA GitHub project code is provided on an 'as is' basis and the user assumes responsibility for its use. Any claims against the Department of Commerce or Department of Commerce bureaus stemming from the use of this GitHub project will be governed by all applicable Federal law. Any reference to specific commercial products, processes, or services by service mark, trademark, manufacturer, or otherwise, does not constitute or imply their endorsement, recommendation or favoring by the Department of Commerce. The Department of Commerce seal and logo, or the seal and logo of a DOC bureau, shall not be used in any manner to imply endorsement of any commercial product or activity by DOC or the United States Government.
112
+
113
+
114
+ # License
115
+
116
+ Software code created by U.S. Government employees is not subject to copyright in the United States (17 U.S.C. �105). The United States/Department of Commerce reserves all rights to seek and obtain copyright protection in countries other than the United States for Software authored in its entirety by the Department of Commerce. To this end, the Department of Commerce hereby grants to Recipient a royalty-free, nonexclusive license to use, copy, and create derivative works of the Software outside of the United States.
tadc-2.3.5/README.md ADDED
@@ -0,0 +1,96 @@
1
+ # CO-OPS Tidal Analysis Datum Calculator (TADC)
2
+
3
+
4
+ # Overview
5
+
6
+ This is code for the NOAA Tidal Analysis Datum Calculator tool.
7
+
8
+ This tool computes tidal datums from a water level data time series. The TADC uses a Butterworth digital filter to remove high frequency (> 4 cycles/day) water level variability in order to identify tidal high and low waters from observed water level data. For official datums, CO-OPS uses a procedure called Curve Fit Manual Verification (CFMV) approach to identify tidal high and low waters that requires human oversight. The accuracy of this tool relative to the CO-OPS approach is described in detail in the following technical document:
9
+
10
+ Licate LA, Huang L and Dusek G (2017) A Comparison of Datums Derived from CO-OPS Verified Data Products and Tidal Analysis Datum Calculator. [NOAA Technical Report NOS CO-OPS 085](https://access.co-ops.nos.noaa.gov/datumcalc/docs/TechnicalReport.pdf).
11
+
12
+ For additional information, contact: NOAA's [Center for Operational Oceanographic Products and Services](https://tidesandcurrents.noaa.gov/)
13
+ User Services: tide.predictions@noaa.gov
14
+
15
+
16
+ # Installation
17
+ ```bash
18
+ pip install git+https://github.com/NOAA-CO-OPS/CO-OPS-Tidal-Analysis-Datum-Calculator
19
+ ```
20
+ or
21
+ ```bash
22
+ git clone https://github.com/NOAA-CO-OPS/dev_CO-OPS-Tidal-Analysis-Datum-Calculator
23
+ cd dev_CO-OPS-Tidal-Analysis-Datum-Calculator
24
+ conda env create -f environment.yml
25
+ conda activate tadc
26
+ ```
27
+
28
+
29
+ # Usage
30
+ You can run the TADC from the command line. Results will print to the terminal window:
31
+ ```bash
32
+ python -m tadc.run --fname data\test_timeseries_simple.csv --Subordinate_Lat 37 --Subordinate_Lon -79
33
+ ```
34
+ > [!NOTE]
35
+ > Use `--outfile_save_dir C:\your\dir` and `--make_plots True` to save results and monthly diagnostic plots.
36
+
37
+ Or, you can use TADC within other Python programs like so:
38
+ ```Python
39
+ import tadc
40
+ out = tadc.run(fname='data/test_timeseries_simple.csv', Subordinate_Lat=37, Subordinate_Lon=-79)
41
+ summary = out.readme
42
+ high_lows = out.high_lows
43
+ monthly_plots = out.plots
44
+ sub_monthly_means = out.subordinate_monthly_means
45
+ datums = out.datums
46
+ ```
47
+ Note that you can alternatively pass your timeseries directly to tadc as a `Pandas` `DataFrame`:
48
+ ```Python
49
+ import pandas as pd
50
+ import tadc
51
+ timeseries = pd.read_csv('data/test_timeseries_simple.csv')
52
+ out = tadc.run(data=timeseries, Subordinate_Lat=37.8, Subordinate_Lon=-79.6)
53
+ ```
54
+ > [!NOTE]
55
+ > One and only one of either `fname` or `data` must be specified when running `tadc()`
56
+
57
+ The object returned by `tadc.run()` also supports some further analyses on the data, in particular `daily_max_analysis`, `daily_min_analysis`, and `inundation_analysis`:
58
+ ```Python
59
+ out = tadc.run(data=timeseries, Subordinate_Lat=37.8, Subordinate_Lon=-79.6)
60
+ daily_max_obj = out.daily_max_analysis(datum='MHHW') # Do an analysis of daily maximums on MHHW #
61
+ daily_maxs = daily_max_obj.daily_maxs # returns the daily max timeseries #
62
+ daily_max_obj.plot() # creates a timeseries plot of the daily maxs #
63
+ daily_min_obj = out.daily_min_analysis(datum='MHHW') # Do an analysis of daily minimums on MHHW #
64
+ # daily_min_obj has the same sub-methods as daily_max_obj #
65
+ inundation_analysis_obj = out.inundation_analysis(threshold=0.5, threshold_datum='MHHW') # Do an analysis of inundations above MHHW+0.5 m #
66
+ inundation_analysis_obj.inundations() # returns the intervals of threshold exceedance #
67
+ inundation_analysis_obj.plot() # creates a plot of inundation time vs. depth #
68
+ ```
69
+
70
+ # Parameters:
71
+ Whether running from the command line or in Python, the following input arguments can be passed:
72
+
73
+ | Argument &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | Type &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | Default | Description |
74
+ | :--- | :--- | :--- | :--- |
75
+ | `--fname` | `file path` | `None` | Required unless `--data` is specified.<br>The full path of the timeseries data to be analyzed.
76
+ | `--data` | `pandas DataFrame` | `None` | Required unless `--fname` is specified.<br>The timeseries data to be analyzed as a Pandas DataFrame object. Only used in Python workflows.
77
+ | `--Subordinate_Lat` | `float` | `None` | The latitude (in decimal degrees) of the station for which datums are being computed.
78
+ | `--Subordinate_Lon` | `float` | `None` | The longitude (in decimal degrees) of the station for which datums are being computed.
79
+ | `--Units` | {`'Meters'`,<br>`'Centimeters'`,<br>`'Feet'`,<br>`'Inches'`} | `'Meters'` | The units of the input data. All calculations will be done on these units.<br>**Warning** Must match the units of the input data.
80
+ | `--Time_Zone` | `str` | `'GMT'` | The time zone of the input data. All calculations will be done in this timezone.<br>**Warning** Must match the time zone of the input data.
81
+ | `--resample_minutes` | `int` | `None` | Resample the input data to this sampling rate (in minutes).<br> **Note** If your data are unevenly spaced in time, resampling will be done automatically at a detected interval which can be modified by setting this parameter.
82
+ | `--Control_Station_ID` | `int` | `None` | The seven-digit station ID of the NWLON control station being used, if using a control station.
83
+ | `--Method_Option` | {`'AUTO'`,<br>`'FRED'`,<br>`'TBYT'`,<br>`'MMSC'`} | `'AUTO'` | The datum adjustment method to use when using a control station.<br>`'AUTO'`: Auto select. If using a control station and <1 month of data 'TBYT' will be used, 'MMSC' otherwise. If not using a control station 'FRED' will be used.<br>`'FRED'`: First reduction method. No adjustment from control station, simple average of highs and lows.<br>`'TBYT'`: Tide by tide analysis. Compares simultaneous high/low waters at the input and control stations.<br>`'MMSC'`: Monthly means simultaneous comparison. Compares monthly means at the input and control stations.
84
+ | `--Pick_Method` | {`'PolyFit'`,<br>`'Direct'`} | `'PolyFit'` | The method to pick high and low tide times and values.<br>`'PolyFit'`: Fit a polynomial to the observations and extract highs and lows from the fit.<br>`'Direct'`: Extract highs and lows directly from the input timeseries.
85
+ | `--outfile_save_dir` | `directory path` | `None` | The directory into which to save output files, if run from the command line. No effect if run in a Python workflow.<br>**Note** A timestamped folder will be created containing the output files.
86
+ | `--make_plots` | `bool` | `False` | Whether or not to create plots, one per month, showing the extracted high and low tides.<br>**Warning** To save plots when running from the command line, `--outfile_save_dir` must also be specified. If running in a Python workflow, plots will be created as Python objects.
87
+
88
+
89
+ # NOAA Open Source Disclaimer
90
+
91
+ This repository is a scientific product and is not official communication of the National Oceanic and Atmospheric Administration, or the United States Department of Commerce. All NOAA GitHub project code is provided on an 'as is' basis and the user assumes responsibility for its use. Any claims against the Department of Commerce or Department of Commerce bureaus stemming from the use of this GitHub project will be governed by all applicable Federal law. Any reference to specific commercial products, processes, or services by service mark, trademark, manufacturer, or otherwise, does not constitute or imply their endorsement, recommendation or favoring by the Department of Commerce. The Department of Commerce seal and logo, or the seal and logo of a DOC bureau, shall not be used in any manner to imply endorsement of any commercial product or activity by DOC or the United States Government.
92
+
93
+
94
+ # License
95
+
96
+ Software code created by U.S. Government employees is not subject to copyright in the United States (17 U.S.C. �105). The United States/Department of Commerce reserves all rights to seek and obtain copyright protection in countries other than the United States for Software authored in its entirety by the Department of Commerce. To this end, the Department of Commerce hereby grants to Recipient a royalty-free, nonexclusive license to use, copy, and create derivative works of the Software outside of the United States.
@@ -0,0 +1,35 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "tadc"
7
+ version = "2.3.5"
8
+ description = "The Tidal Analysis Datum Calculator (TADC) computes tidal datums from a water level data time series."
9
+ readme = "README.md"
10
+ authors = [
11
+ { name="Center for Operational Oceanographic Products and Services, National Ocean Service, National Oceanic and Atmsopheric Administration", email="tide.predictions@noaa.gov" }
12
+ ]
13
+ classifiers = [
14
+ "Programming Language :: Python :: 3",
15
+ "Operating System :: OS Independent",
16
+ ]
17
+ requires-python = ">=3.0"
18
+ dependencies = [
19
+ "matplotlib",
20
+ "numpy",
21
+ "pandas>=2.0.3",
22
+ "python-dateutil",
23
+ "requests",
24
+ "scipy"
25
+ ]
26
+ license-files = ["LICENSE.txt"]
27
+
28
+ [project.urls]
29
+ "Online Web App" = "https://access.co-ops.nos.noaa.gov/datumcalc/"
30
+ "Technical Report" = "https://access.co-ops.nos.noaa.gov/datumcalc/docs/TechnicalReport.pdf"
31
+
32
+ [tool.setuptools.packages.find]
33
+ where = ["."]
34
+ include = ["tadc*"]
35
+ namespaces = false
tadc-2.3.5/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1 @@
1
+ from .run import *
@@ -0,0 +1,97 @@
1
+ """CO-OPS API data retrieval functions for CO-OPS Datums Calculator"""
2
+
3
+ from datetime import datetime, date, time, timedelta
4
+ import numpy as np
5
+ import pandas as pd
6
+ import requests
7
+
8
+ from . import tides as tf
9
+
10
+
11
+ def Get_Monthly_Means(Control_Station_ID, Begin_Month, Begin_Year, End_Month, End_Year, Conversion):
12
+ #This function retrieves the control station's monthly means using CO-OPS data api
13
+ end_days = tf.Last_Day_In_Month(int(End_Year),int(End_Month))
14
+ if int(Begin_Month) < 10:
15
+ sb = '0'
16
+ else:
17
+ sb = ''
18
+ if int(End_Month) < 10:
19
+ se = '0'
20
+ else:
21
+ se = ''
22
+ url1 = 'https://api.tidesandcurrents.noaa.gov/api/prod/datagetter?'
23
+ url2 = 'begin_date=' + str(Begin_Year) + sb + str(Begin_Month) + '01' + '&end_date=' + str(End_Year) + se + str(End_Month) + str(end_days) + '&station=' + str(Control_Station_ID)
24
+ url3 = '&product=monthly_mean&datum=stnd&units=metric&time_zone=gmt&application=TADC&format=json'
25
+ r = requests.get(url1 + url2 + url3)
26
+ MM = pd.DataFrame(r.json()['data'])
27
+ for c in ['highest','MHHW','MHW','MSL','MLW','MLLW','lowest']:
28
+ MM[c] = MM[c].astype(float) * Conversion
29
+ MM_lists = [MM[['highest','MHHW','MHW','MSL','MLW','MLLW','lowest']].iloc[i].values.tolist() for i in range(len(MM))] # Convert to the list of lists format needed by run.py #
30
+ return MM_lists
31
+
32
+
33
+ def Get_High_Lows(Control_Station_ID, Start_DT, End_DT, gmt_offset, Conversion):
34
+ #This function retrieves control station high and low tides using CO-OPS data api
35
+
36
+ #if subordinate (short-term) station time is not in gmt, get time offset
37
+ Start_DT += timedelta(hours=gmt_offset)
38
+ End_DT += timedelta(hours=gmt_offset)
39
+
40
+ if End_DT - Start_DT > timedelta(days=365):
41
+ chunks = pd.date_range(Start_DT, End_DT, periods=int(np.ceil((End_DT - Start_DT).days/365))+1)
42
+ else:
43
+ chunks = (Start_DT, End_DT)
44
+
45
+ hl_chunks = []
46
+ for i in range(len(chunks)-1):
47
+ start_dt = chunks[i]
48
+ end_dt = chunks[i+1]
49
+
50
+ start_datestr = datetime.strftime(start_dt,'%Y%m%d')
51
+ end_datestr = datetime.strftime(end_dt,'%Y%m%d')
52
+
53
+ url1 = 'https://api.tidesandcurrents.noaa.gov/api/prod/datagetter?'
54
+ url2 = 'begin_date=' + start_datestr + '&end_date=' + end_datestr + '&station=' + str(Control_Station_ID)
55
+ url3 = '&product=High_low&datum=stnd&units=metric&time_zone=gmt&application=TADC&format=json'
56
+ r = requests.get(url1 + url2 + url3)
57
+
58
+ hl_chunks.append(pd.DataFrame(r.json()['data']))
59
+ HL = pd.concat(hl_chunks,ignore_index=True)
60
+ HL['t'] = pd.to_datetime(HL['t']) - timedelta(hours=gmt_offset)
61
+ HL['v'] = HL['v'].astype(float) * Conversion
62
+ HL['ty'] = [HL['ty'].iloc[i].replace(' ','') for i in range(len(HL))]
63
+ HL_lists = [HL[['t','v','ty']].iloc[i].values.tolist() for i in range(len(HL))] # Convert to the list of lists format needed by run.py #
64
+ return HL_lists
65
+
66
+
67
+ def Get_Accepted_Datums(Station_ID, Conversion):
68
+ #This function retrieves the accepted control station datums using CO-OPS metadata api
69
+ url = 'https://api.tidesandcurrents.noaa.gov/mdapi/prod/webapi/stations/' + str(Station_ID) + '/datums.json?units=metric'
70
+ r = requests.get(url)
71
+ datums = pd.DataFrame(r.json()['datums'])
72
+ SD = []
73
+ for datum in ['MHHW','MHW','DTL','MTL','MSL','MLW','MLLW','GT','MN','DHQ','DLQ','NAVD88','LWI','HWI']:
74
+ try:
75
+ val = datums.loc[datums['name'] == datum,'value'].values[0]
76
+ except IndexError:
77
+ SD.append(np.nan)
78
+ else:
79
+ if datum not in ['LWI','HWI']:
80
+ SD.append(val * Conversion)
81
+ else:
82
+ SD.append(val)
83
+ return SD
84
+
85
+
86
+ def Get_SubMethod(Station_ID):
87
+ #This function checks if the control station is a West coast/Pacific or East Coast/Gulf Coast/Caribbean Island station
88
+ #for choosing datum computation method
89
+ url = 'https://api.tidesandcurrents.noaa.gov/mdapi/prod/webapi/stations/' + str(Station_ID) + '.json?units=metric'
90
+ r = requests.get(url)
91
+ lon = r.json()['stations'][0]['lng']
92
+ if lon < -100:
93
+ return('Standard')
94
+ else:
95
+ return('Modified')
96
+
97
+
@@ -0,0 +1,76 @@
1
+ import matplotlib.pyplot as plt
2
+ import numpy as np
3
+ import pandas as pd
4
+
5
+
6
+ class Out:
7
+ def __init__(self, daily_extremes, extremes_type, datum, units, input_file):
8
+ self.__daily_extremes = daily_extremes
9
+ if extremes_type == 'max':
10
+ self.daily_maxs = daily_extremes
11
+ self.daily_mins = None
12
+ elif extremes_type == 'min':
13
+ self.daily_mins = daily_extremes
14
+ self.daily_maxs = None
15
+ if datum == 'Input':
16
+ self.datum = 'input datum'
17
+ else:
18
+ self.datum = datum
19
+ self.units = units
20
+ self.input_file = input_file
21
+
22
+ def percentile(self, prctile):
23
+ return self.__daily_extremes['elevation'].quantile(prctile/100)
24
+
25
+ def plot(self, prctile=None):
26
+ fig,ax = plt.subplots(1,figsize=(9,5))
27
+ ax.tick_params(axis='both',labelsize=8)
28
+ ax.grid('on',linestyle='--')
29
+ ax.plot(self.__daily_extremes['time'],self.__daily_extremes['elevation'],'-o',label='Daily max',zorder=2)
30
+ ax.set_ylabel('Elevation ('+self.units+' above '+self.datum+')',fontsize=8)
31
+ if prctile != None:
32
+ prctile_elev = self.percentile(prctile)
33
+ ax.set_xlim(ax.get_xlim())
34
+ ax.plot(ax.get_xlim(),[prctile_elev,prctile_elev],'k--',label=str(prctile)+' percentile',zorder=3)
35
+ ax.legend(fontsize=8)
36
+ if self.daily_maxs is not None:
37
+ ax.set_title('Daily Maximum Water Levels for '+self.input_file,fontsize=8)
38
+ else:
39
+ ax.set_title('Daily Minimum Water Levels for '+self.input_file,fontsize=8)
40
+ total_dt = self.__daily_extremes['time'].iloc[-1] - self.__daily_extremes['time'].iloc[0]
41
+ ticks = pd.date_range(self.__daily_extremes['time'].iloc[0],
42
+ self.__daily_extremes['time'].iloc[-1],
43
+ freq=total_dt/8)
44
+ ax.set_xlim(self.__daily_extremes['time'].iloc[0] - (total_dt/8/4),
45
+ self.__daily_extremes['time'].iloc[-1] + (total_dt/8/4))
46
+ ax.set_xticks(ticks)
47
+ fig.autofmt_xdate()
48
+ fig.show()
49
+ return fig
50
+
51
+
52
+ def run(extremes_type, datum, data, datums, units, input_file):
53
+ datums['Input'] = 0
54
+
55
+ # Get timestamps into a usable format #
56
+ data = data.rename(columns={data.columns[0]:'time',data.columns[1]:'val'})
57
+ data['time'] = pd.to_datetime(data['time'])
58
+ data = data.replace(-99999.99, np.nan)
59
+
60
+ # Put the data onto the threshold datum and onto MHHW #
61
+ data_dwant = pd.DataFrame({'time':data['time'],'val':data['val']-datums[datum]})
62
+
63
+ # Calc daily maxes #
64
+ data_dwant = data_dwant.set_index('time')
65
+ interval_hrs = (data_dwant.index[1] - data_dwant.index[0]).seconds/3600
66
+ n = data_dwant.groupby(data_dwant.index.date)['val'].size()
67
+ per_complete = n / (24 / interval_hrs) * 100
68
+ if extremes_type == 'max':
69
+ dmi = data_dwant.groupby(data_dwant.index.date)['val'].idxmax()
70
+ elif extremes_type == 'min':
71
+ dmi = data_dwant.groupby(data_dwant.index.date)['val'].idxmin()
72
+ dm = data_dwant.loc[dmi].reset_index()
73
+ dm = dm.rename(columns={'time':'time','val':'elevation'})
74
+ dm['completeness'] = per_complete.values
75
+
76
+ return Out(dm, extremes_type, datum, units, input_file)
@@ -0,0 +1,18 @@
1
+ #
2
+ # Filter definitions for Datums Calculator Tide picker
3
+ #
4
+ #
5
+ from scipy.signal import butter, filtfilt
6
+
7
+ #Butterworth digital filter design.
8
+ def butter_lowpass(cutOff, fs, order=5):
9
+ nyq = 0.5 * fs
10
+ normalCutoff = cutOff / nyq
11
+ b, a = butter(order, normalCutoff, btype='low', analog = False)
12
+ return b, a
13
+
14
+ def butter_lowpass_filter(data, cutOff, fs, order=4):
15
+ b, a = butter_lowpass(cutOff, fs, order=order)
16
+ y = filtfilt(b, a, data)
17
+ return y
18
+