From 7ca8fcc061032f3cd1de4dde5550527a594fb9d2 Mon Sep 17 00:00:00 2001 From: Joe Ranalli Date: Sat, 14 Sep 2024 13:21:12 -0400 Subject: [PATCH] Cleaning Up Dependency Pins and Test Targets - Updating dependencies and test targets - Fix deprecation warnings raised by numpy --- .github/workflows/tests.yml | 11 ++++++-- Changelog.md | 5 +++- setup.cfg | 28 ++++++++++---------- src/solarspatialtools/signalproc.py | 6 ++--- src/solarspatialtools/spatial.py | 3 +++ src/solarspatialtools/stats.py | 5 +++- tests/test_cmv.py | 2 +- tests/test_field.py | 4 +-- tests/test_irradiance.py | 4 +-- tests/test_signalproc.py | 40 ++++++++++++++--------------- 10 files changed, 62 insertions(+), 46 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 3d19430..8d2346f 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -5,7 +5,14 @@ on: [pull_request, push] jobs: tests: - runs-on: ubuntu-latest + strategy: + fail-fast: false # don't cancel other matrix jobs when one fails + matrix: + python-version: ["3.10", "3.11", "3.12"] + os: [ubuntu-latest, macos-latest, windows-latest] + + + runs-on: ${{ matrix.os }} steps: - name: Checkout @@ -14,7 +21,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: "3.x" + python-version: ${{ matrix.python-version }} - name: Install dependencies run: | diff --git a/Changelog.md b/Changelog.md index 5539986..74cc0f8 100644 --- a/Changelog.md +++ b/Changelog.md @@ -69,4 +69,7 @@ site itself. - Added matplotlib dependency - Move demos back to the parent directory using nblink # Version 0.4.6 - Sept 13, 2024 -- Fix license name in cfg \ No newline at end of file +- Fix license name in cfg +# Version 0.4.7 - Sept 14, 2024 +- Updating dependencies and test targets +- Fix deprecation warnings raised by numpy \ No newline at end of file diff --git a/setup.cfg b/setup.cfg index efe13ef..9cd33dd 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = solarspatialtools -version = 0.4.6 +version = 0.4.7 author = 'Joe Ranalli' author_email = jar339@psu.edu description = A package for spatial analysis of solar energy and solar irradiance @@ -19,14 +19,14 @@ classifiers = [options] install_requires = - numpy<2 - pandas<=2.2.2 - tables<=3.9.2 - pyproj<=3.6.1 - pvlib<=0.11.0 - netcdf4<1.7.2 - scipy<=1.14.0 - matplotlib<=3.9.2 + numpy + pandas + tables + pyproj + pvlib + netcdf4 + scipy + matplotlib [options.extras_require] tests = @@ -36,8 +36,8 @@ demos = jupyter docs = - sphinx - sphinx_rtd_theme - nbsphinx - ipython - nbsphinx-link \ No newline at end of file + sphinx==7.4.7 + sphinx_rtd_theme==2.0.0 + nbsphinx==0.9.5 + ipython==8.27.0 + nbsphinx-link==1.3.0 \ No newline at end of file diff --git a/src/solarspatialtools/signalproc.py b/src/solarspatialtools/signalproc.py index 235ccce..8e4bfb1 100644 --- a/src/solarspatialtools/signalproc.py +++ b/src/solarspatialtools/signalproc.py @@ -462,7 +462,7 @@ def _residual(dels, freqs, phases, mask): if method == 'diff': if not np.any(np.array(np.shape(tf)) == 1): - raise ValueError('tf must be a 1D array for method: fit') + raise ValueError('tf must be a 1D array for method: diff') # # Method 1: unwrap phase and take derivative tfv = tf.values.flatten() @@ -479,7 +479,7 @@ def _residual(dels, freqs, phases, mask): try: return (curve_fit(_delay_fitter, np.expand_dims(tf.index, axis=1)[ix], - np.unwrap(np.angle(tf.loc[ix]).flatten()))[0], + np.unwrap(np.angle(tf.loc[ix]).flatten()))[0].item(), ix) except ValueError: from warnings import warn @@ -653,7 +653,7 @@ def compute_delays(ts_in, ts_out, mode='loop', scaling='coeff'): extras['peak_corr'][i] = xcorr[peak_lag_index] extras['mean_corr'][i] = np.mean(xcorr) - extras['zero_corr'][i] = xcorr[zero_lag_ind] + extras['zero_corr'][i] = xcorr[zero_lag_ind].item() # Scale extras['peak_corr'] *= corr_scale diff --git a/src/solarspatialtools/spatial.py b/src/solarspatialtools/spatial.py index e76cb09..083bb3b 100644 --- a/src/solarspatialtools/spatial.py +++ b/src/solarspatialtools/spatial.py @@ -254,6 +254,9 @@ def magnitude(vec): magnitude : numeric the magnitude of the vector """ + # respond differently for Pandas Types + if isinstance(vec, pd.Series): + return np.sqrt(vec.iloc[0]**2 + vec.iloc[1]**2) return np.sqrt(vec[0]**2+vec[1]**2) diff --git a/src/solarspatialtools/stats.py b/src/solarspatialtools/stats.py index b34cce0..da5adea 100644 --- a/src/solarspatialtools/stats.py +++ b/src/solarspatialtools/stats.py @@ -383,7 +383,10 @@ def calc_quantile(timeseries, n_days="30d", quantile=0.9): p90.index.astype(str)) # Concat this day onto the output object - out_df = pd.concat((out_df, p90), axis=0) + if len(out_df) == 0: + out_df = p90 + else: + out_df = pd.concat((out_df, p90), axis=0) # localize the timeseries and the column names back to the input out_df = out_df.tz_localize(ts.index.tz).reindex(ts.index) diff --git a/tests/test_cmv.py b/tests/test_cmv.py index a98121a..5010fa6 100644 --- a/tests/test_cmv.py +++ b/tests/test_cmv.py @@ -76,7 +76,7 @@ def test_cmv_artificial(theta_deg, velocity, mode): signals[4, :] = x for i, delay in enumerate(delays): signals[i, :] = np.roll(x, int(delay*fs)) - df = pd.DataFrame(signals.T, index=pd.TimedeltaIndex(t, 's')) + df = pd.DataFrame(signals.T, index=pd.to_timedelta(t, 's')) # Compute the CMV cld_spd, cld_dir, dat = cmv.compute_cmv(df, pos_utm, diff --git a/tests/test_field.py b/tests/test_field.py index 1a79652..4adc4e8 100644 --- a/tests/test_field.py +++ b/tests/test_field.py @@ -130,7 +130,7 @@ def test_compute_delays(delay, delay_method): y3 = np.roll(x, int(3*delay * fs)) y4 = np.roll(x, int(4*delay * fs)) - df = pd.DataFrame(np.array([x,y1,y2,y3,y4]).T, index=pd.TimedeltaIndex(t, 's'), columns=['x1','x2','x3','x4','x5']) + df = pd.DataFrame(np.array([x,y1,y2,y3,y4]).T, index=pd.to_timedelta(t, 's'), columns=['x1','x2','x3','x4','x5']) ref = 'x1' delays, coh = field.compute_delays(df, ref, navgs=5, coh_limit=0.6, freq_limit=1, method=delay_method) @@ -154,7 +154,7 @@ def test_compute_delays_nan(delay_method): y3 = np.roll(x, int(3*delay * fs)) y4 = np.nan * np.zeros_like(y3) - df = pd.DataFrame(np.array([x,y1,y2,y3,y4]).T, index=pd.TimedeltaIndex(t, 's'), columns=['x1','x2','x3','x4','x5']) + df = pd.DataFrame(np.array([x,y1,y2,y3,y4]).T, index=pd.to_timedelta(t, 's'), columns=['x1','x2','x3','x4','x5']) ref = 'x1' delays, coh = field.compute_delays(df, ref, navgs=5, coh_limit=0.6, freq_limit=1, method=delay_method) diff --git a/tests/test_irradiance.py b/tests/test_irradiance.py index abf2a1b..827ca0d 100644 --- a/tests/test_irradiance.py +++ b/tests/test_irradiance.py @@ -34,7 +34,7 @@ def test_clearsky_index(): assert_allclose(out, expected, atol=0.001) # GHI series & CS series - times = pd.date_range(start='20180601', periods=2, freq='12H') + times = pd.date_range(start='20180601', periods=2, freq='12h') ghi_measured = pd.Series([100, 500], index=times) ghi_modeled = pd.Series([500, 1000], index=times) out = clearsky_index(ghi_measured, ghi_modeled) @@ -44,7 +44,7 @@ def test_clearsky_index(): assert out.values == approx(expected.values) # GHI 2D frame & CS 1D series - times = pd.date_range(start='20180601', periods=3, freq='12H') + times = pd.date_range(start='20180601', periods=3, freq='12h') ghi_measured = pd.DataFrame([[100, 100], [200, 200], [500, 500]], index=times) ghi_modeled = pd.Series([500, 800, 1000], index=times) out = clearsky_index(ghi_measured, ghi_modeled) diff --git a/tests/test_signalproc.py b/tests/test_signalproc.py index a5c14a3..75f6546 100644 --- a/tests/test_signalproc.py +++ b/tests/test_signalproc.py @@ -77,7 +77,7 @@ def test_averaged_psd(): T = 5.0 # seconds t = np.linspace(0, T, int(T*fs), endpoint=False) # time variable x = 0.5*np.sin(2*np.pi*2*t) # +0.1*np.sin(2*np.pi*10*t) - input_tsig = pd.Series(x, index=pd.TimedeltaIndex(t, 's')) + input_tsig = pd.Series(x, index=pd.to_timedelta(t, 's')) # Calculate the averaged PSD using the function navgs = 5 @@ -103,8 +103,8 @@ def test_averaged_tf(): t = np.linspace(0, T, int(T*fs), endpoint=False) # time variable x = 0.5*np.sin(2*np.pi*2*t) # input signal y = 0.5*np.sin(2*np.pi*2*t + np.pi/4) # output signal with phase shift - x_tsig = pd.Series(x, index=pd.TimedeltaIndex(t, 's')) - y_tsig = pd.Series(y, index=pd.TimedeltaIndex(t, 's')) + x_tsig = pd.Series(x, index=pd.to_timedelta(t, 's')) + y_tsig = pd.Series(y, index=pd.to_timedelta(t, 's')) # Calculate the averaged transfer function using the function navgs = 5 @@ -168,8 +168,8 @@ def test_tf_delay(delay): noise = np.random.random(len(t))/5 # add broadband noise x = 0.5*np.sin(2*np.pi*2*t) + noise # noisy signal y = np.roll(x, int(delay*fs)) # Explicitly delay the signal - x_tsig = pd.Series(x, index=pd.TimedeltaIndex(t, 's')) - y_tsig = pd.Series(y, index=pd.TimedeltaIndex(t, 's')) + x_tsig = pd.Series(x, index=pd.to_timedelta(t, 's')) + y_tsig = pd.Series(y, index=pd.to_timedelta(t, 's')) # Calculate the averaged transfer function using the function navgs = 5 @@ -199,8 +199,8 @@ def test_tf_delay_multi(delay): y2 = np.roll(x, int(2 * delay * fs)) y3 = np.roll(x, int(3 * delay * fs)) y4 = np.roll(x, int(4 * delay * fs)) - x_tsig = pd.Series(x, index=pd.TimedeltaIndex(t, 's')) - ysigs = [pd.Series(y, index=pd.TimedeltaIndex(t, 's')) for y in + x_tsig = pd.Series(x, index=pd.to_timedelta(t, 's')) + ysigs = [pd.Series(y, index=pd.to_timedelta(t, 's')) for y in [y1, y2, y3, y4]] ysigs_df = pd.DataFrame(np.array(ysigs).T, columns=[0, 1, 2, 3], index=ysigs[0].index) @@ -235,8 +235,8 @@ def test_tf_delay_nan(): y3 = np.roll(x, int(3 * delay * fs)) y4 = np.nan * np.zeros_like(y3) - x_tsig = pd.Series(x, index=pd.TimedeltaIndex(t, 's')) - ysigs = [pd.Series(y, index=pd.TimedeltaIndex(t, 's')) for y in + x_tsig = pd.Series(x, index=pd.to_timedelta(t, 's')) + ysigs = [pd.Series(y, index=pd.to_timedelta(t, 's')) for y in [y1, y2, y3, y4]] ysigs_df = pd.DataFrame(np.array(ysigs).T, columns=[0, 1, 2, 3], index=ysigs[0].index) @@ -267,8 +267,8 @@ def test_xcorr_delay(delay): noise = np.random.random(len(t))/5 # add broadband noise x = 0.5*np.sin(2*np.pi*0.01*t) + noise # noisy signal y = np.roll(x, int(delay*fs)) # Explicitly delay the signal - x_tsig = pd.Series(x, index=pd.TimedeltaIndex(t, 's')) - y_tsig = pd.Series(y, index=pd.TimedeltaIndex(t, 's')) + x_tsig = pd.Series(x, index=pd.to_timedelta(t, 's')) + y_tsig = pd.Series(y, index=pd.to_timedelta(t, 's')) # Calculate the averaged transfer function using the function delay_result, _ = xcorr_delay(x_tsig, y_tsig, "coeff") @@ -310,7 +310,7 @@ def test_averaged_psd_multi(): x4 = 0.5 * np.sin(2 * np.pi * 2 * t) + np.random.random(len(t)) xs = [x1, x2, x3, x4] - tsigs = [pd.Series(x, index=pd.TimedeltaIndex(t, 's')) for x in xs] + tsigs = [pd.Series(x, index=pd.to_timedelta(t, 's')) for x in xs] tsigs_df = pd.DataFrame(np.array(tsigs).T, columns=[0, 1, 2, 3], index=tsigs[0].index) navgs = 5 overlap = 0.5 @@ -342,8 +342,8 @@ def test_averaged_tf_multiout(): y2 = np.roll(x, int(2*delay * fs)) y3 = np.roll(x, int(3*delay * fs)) y4 = np.roll(x, int(4*delay * fs)) - x_tsig = pd.Series(x, index=pd.TimedeltaIndex(t, 's')) - ysigs = [pd.Series(y, index=pd.TimedeltaIndex(t, 's')) for y in [y1, y2, y3, y4]] + x_tsig = pd.Series(x, index=pd.to_timedelta(t, 's')) + ysigs = [pd.Series(y, index=pd.to_timedelta(t, 's')) for y in [y1, y2, y3, y4]] ysigs_df = pd.DataFrame(np.array(ysigs).T, columns=[0, 1, 2, 3], index=ysigs[0].index) navgs = 5 @@ -378,8 +378,8 @@ def test_averaged_tf_multiin(): y2 = np.roll(x, int(2*delay * fs)) y3 = np.roll(x, int(3*delay * fs)) y4 = np.roll(x, int(4*delay * fs)) - x_tsig = pd.Series(x, index=pd.TimedeltaIndex(t, 's')) - ysigs = [pd.Series(y, index=pd.TimedeltaIndex(t, 's')) for y in [y1, y2, y3, y4]] + x_tsig = pd.Series(x, index=pd.to_timedelta(t, 's')) + ysigs = [pd.Series(y, index=pd.to_timedelta(t, 's')) for y in [y1, y2, y3, y4]] ysigs_df = pd.DataFrame(np.array(ysigs[0]).T, columns=[0], index=ysigs[0].index) xsigs = [x_tsig, ysigs[0], ysigs[1], ysigs[2]] @@ -416,8 +416,8 @@ def test_averaged_tf_multiboth(): y2 = np.roll(x, int(2*delay * fs)) y3 = np.roll(x, int(3*delay * fs)) y4 = np.roll(x, int(4*delay * fs)) - x_tsig = pd.Series(x, index=pd.TimedeltaIndex(t, 's')) - ysigs = [pd.Series(y, index=pd.TimedeltaIndex(t, 's')) for y in [y1, y2, y3, y4]] + x_tsig = pd.Series(x, index=pd.to_timedelta(t, 's')) + ysigs = [pd.Series(y, index=pd.to_timedelta(t, 's')) for y in [y1, y2, y3, y4]] ysigs_df = pd.DataFrame(np.array(ysigs).T, columns=[0, 1, 2, 3], index=ysigs[0].index) xsigs = [x_tsig, ysigs[0], ysigs[1], ysigs[2]] @@ -464,8 +464,8 @@ def test_compute_delays(delay, compute_delays_modes): ys.append(yi) delay_ins.append(deli) - x_tsig = pd.Series(x, index=pd.TimedeltaIndex(t, 's')) - ysigs = [pd.Series(y, index=pd.TimedeltaIndex(t, 's')) for y in ys] + x_tsig = pd.Series(x, index=pd.to_timedelta(t, 's')) + ysigs = [pd.Series(y, index=pd.to_timedelta(t, 's')) for y in ys] xsigs = [x_tsig for y in ys] xsigs = pd.DataFrame(np.array(xsigs).T, index=x_tsig.index)