Commit 8093b151 authored by Jenni Rinker's avatar Jenni Rinker

Merge branch 'fix_const_only' into 'master'

Fix bug when only constraints (issue 7)

Closes #7

See merge request pyconturb/pyconturb!40
parents 23f8f091 8d055c23
Pipeline #13618 passed with stage
in 1 minute and 11 seconds
......@@ -15,6 +15,22 @@ _HAWC2_BIN_FMT = '<f' # HAWC2 binary turbulence datatype
_HAWC2_TURB_COOR = {'u': -1, 'v': -1, 'w': 1} # hawc2 turb xyz to uvw
def check_sims_collocated(spat_df, con_tc):
"""Determine if the simulation points are all collocated with the
constraints. Returns boolean (True=all collocated)"""
if con_tc is None: # no constraints
return False
con_spat_df = con_tc.get_spat()
# numerical arrays for which rows
con_arr = con_spat_df.T.values
spat_arr = spat_df.T.values
# magic with broadcasting (thank you numpy)
sim_arr = spat_arr[:, np.newaxis, :] # [ns, 1, 4] array of sim pts
s_in_c = np.all(np.equal(sim_arr, con_arr), axis=2) # [ns, nc] array of if si is in cj
s_non_uniq = np.any(s_in_c, axis=1) # [ns] array of if s is non unique
return np.all(s_non_uniq)
def clean_turb(spat_df, all_spat_df, turb_df, decimals=10):
"""Remove the columns we don't return and rename the rest correctly. Will check only
to decimals places when removing duplicates (data unchanged)."""
......
......@@ -16,7 +16,8 @@ from pyconturb.magnitudes import get_magnitudes
from pyconturb.sig_models import iec_sig, data_sig
from pyconturb.spectral_models import kaimal_spectrum, data_spectrum
from pyconturb.wind_profiles import get_wsp_values, power_profile, data_profile
from pyconturb._utils import combine_spat_con, _spat_rownames, _DEF_KWARGS, clean_turb
from pyconturb._utils import (combine_spat_con, _spat_rownames, _DEF_KWARGS,
clean_turb, check_sims_collocated)
def gen_turb(spat_df, T=600, dt=1, con_tc=None, coh_model='iec',
......@@ -86,6 +87,11 @@ def gen_turb(spat_df, T=600, dt=1, con_tc=None, coh_model='iec',
# if asked to interpret but no data, throw warning
if (((interp_data == 'all') or isinstance(interp_data, list)) and (con_tc is None)):
raise ValueError('If "interp_data" is not "none", constraints must be given!')
# return None if all simulation points collocated with constraints
if check_sims_collocated(spat_df, con_tc):
print('All simulation points collocated with constraints! '
+ 'Nothing to simulate.')
return None
# add T, dt, con_tc to kwargs
kwargs = {**_DEF_KWARGS, **kwargs, 'T': T, 'dt': dt, 'con_tc': con_tc}
......
......@@ -37,12 +37,13 @@ def test_gen_turb_con():
"""mean & std of iec turbulence, con'd turb is regen'd, correct columns
"""
# given -- constraining points
con_spat_df = pd.DataFrame([[0, 0, 0, 70]], columns=_spat_rownames)
con_spat_df = pd.DataFrame([[0, 0, 0, 70]], columns=_spat_rownames).T
kwargs = {'u_ref': 10, 'turb_class': 'B', 'l_c': 340.2, 'z_ref': 70, 'T': 300,
'dt': 0.5, 'seed': 1337}
coh_model = 'iec'
con_turb_df = gen_turb(con_spat_df.T, coh_model=coh_model, **kwargs)
con_tc = TimeConstraint().from_con_data(con_spat_df=con_spat_df, con_turb_df=con_turb_df)
con_turb_df = gen_turb(con_spat_df, coh_model=coh_model, **kwargs)
con_tc = TimeConstraint().from_con_data(con_spat_df=con_spat_df.T,
con_turb_df=con_turb_df) # old spat_df was T
# given -- simulated, constrainted turbulence
y, z = 0, [70, 72]
spat_df = gen_spat_grid(y, z)
......@@ -171,6 +172,23 @@ def test_gen_turb_verbose():
pass
def test_gen_turb_sims_collocated():
"""Should return None if all sim pts collocated with constraints"""
# given -- constraining points
con_spat_df = pd.DataFrame([[0, 0, 0, 70]], columns=_spat_rownames).T
kwargs = {'u_ref': 10, 'turb_class': 'B', 'l_c': 340.2, 'z_ref': 70, 'T': 300,
'dt': 0.5, 'seed': 1337}
coh_model = 'iec'
con_turb_df = gen_turb(con_spat_df, coh_model=coh_model, **kwargs)
con_tc = TimeConstraint().from_con_data(con_spat_df=con_spat_df.T, con_turb_df=con_turb_df)
# given -- simulated, constrainted turbulence
spat_df = con_spat_df # simulate same points as constraint
# when
sim_turb_df = gen_turb(spat_df, con_tc=con_tc, coh_model=coh_model, **kwargs)
# then (std dev, mean, and regen'd time series should be close; right colnames)
assert sim_turb_df is None
if __name__ == '__main__':
test_iec_turb_mn_std_dev()
test_gen_turb_con()
......@@ -180,3 +198,4 @@ if __name__ == '__main__':
test_gen_turb_wsp_func()
test_gen_turb_sig_func()
test_gen_turb_spec_func()
test_gen_turb_sims_collocated()
......@@ -14,6 +14,25 @@ import pyconturb._utils as utils
_spat_rownames = utils._spat_rownames
def test_check_sims_collocated():
"""verify function works when no unique simulation points"""
# given -- constraining points
con_arr = np.array([[0, 0, 0, 70, 1], [1, 0, 0, 70, 1], [2, 0, 0, 70, 1]]).T
kwargs = {'u_ref': 10, 'turb_class': 'B', 'l_c': 340.2, 'z_ref': 70, 'T': 300,
'dt': 0.5, 'seed': 1337}
inp_out = [(0, 1, False), (0, 2, True)]
# given -- points to simulate
spat_df = pd.DataFrame([[0, 0, 0, 70],
[1, 0, 0, 70]], columns=_spat_rownames).T
for (start, stop, res_theo) in inp_out:
# given -- constraint
con_tc = TimeConstraint(con_arr[:, start:stop], index=_spat_rownames + [0])
# when
res = utils.check_sims_collocated(spat_df, con_tc)
# then
assert res == res_theo
def test_clean_turb():
"""verify correct columns are removed and others are renamed (also handle floats)"""
# given
......@@ -197,6 +216,7 @@ def test_interpolator_badinput():
if __name__ == '__main__':
test_check_sims_collocated()
test_clean_turb()
test_combine_spat_con_empty()
test_combine_spat_con_nonunique()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment