From a4ce8584b85b9787d16044ab6fe35adf7a1364d8 Mon Sep 17 00:00:00 2001 From: veenstrajelmer Date: Fri, 11 Mar 2022 12:47:20 +0000 Subject: [PATCH] Updated documentation --- docs/hatyan/analysis_prediction.html | 4 +- docs/hatyan/foreman.html | 488 ++++++++++++--------------- docs/hatyan/hatyan_core.html | 130 +++++-- docs/hatyan/index.html | 2 +- docs/hatyan/schureman.html | 196 +++-------- 5 files changed, 374 insertions(+), 446 deletions(-) diff --git a/docs/hatyan/analysis_prediction.html b/docs/hatyan/analysis_prediction.html index 92d19dee..c066120e 100644 --- a/docs/hatyan/analysis_prediction.html +++ b/docs/hatyan/analysis_prediction.html @@ -546,7 +546,7 @@

Module hatyan.analysis_prediction

print('PREDICTION started') omega_i_rads = t_const_speed_all.T/3600 #angular frequency, 2pi/T, in rad/s, https://en.wikipedia.org/wiki/Angular_frequency (2*np.pi)/(1/x*3600) = 2*np.pi*x/3600 - if ~isinstance(times_pred_all_pdDTI,pd.DatetimeIndex) & (version.parse(pd.__version__) >= version.parse('1.2.0')): #fix for non-backwards compatible change in pandas, pandas version 1.1.2 is used for RWS version. + if ~isinstance(times_pred_all_pdDTI,pd.DatetimeIndex) & (version.parse(pd.__version__) >= version.parse('1.2.0')): #fix for non-backwards compatible change in pandas, pandas version 1.1.2 is used for RWS version. TODO: remove this fix once pandas>=1.2.0 can be used (probably py3.7 required) times_from0allpred_s_orig = (times_pred_all_pdDTI-dood_date_start).total_seconds().values else: times_from0allpred_s_orig = (times_pred_all_pdDTI-dood_date_start[0]).total_seconds().values @@ -1113,7 +1113,7 @@

Returns

print('PREDICTION started') omega_i_rads = t_const_speed_all.T/3600 #angular frequency, 2pi/T, in rad/s, https://en.wikipedia.org/wiki/Angular_frequency (2*np.pi)/(1/x*3600) = 2*np.pi*x/3600 - if ~isinstance(times_pred_all_pdDTI,pd.DatetimeIndex) & (version.parse(pd.__version__) >= version.parse('1.2.0')): #fix for non-backwards compatible change in pandas, pandas version 1.1.2 is used for RWS version. + if ~isinstance(times_pred_all_pdDTI,pd.DatetimeIndex) & (version.parse(pd.__version__) >= version.parse('1.2.0')): #fix for non-backwards compatible change in pandas, pandas version 1.1.2 is used for RWS version. TODO: remove this fix once pandas>=1.2.0 can be used (probably py3.7 required) times_from0allpred_s_orig = (times_pred_all_pdDTI-dood_date_start).total_seconds().values else: times_from0allpred_s_orig = (times_pred_all_pdDTI-dood_date_start[0]).total_seconds().values diff --git a/docs/hatyan/foreman.html b/docs/hatyan/foreman.html index 56a581db..2916e674 100644 --- a/docs/hatyan/foreman.html +++ b/docs/hatyan/foreman.html @@ -74,6 +74,7 @@

Module hatyan.foreman

file_path = os.path.realpath(__file__) + ################################################# ################# FILECONTENTS ################## ################################################# @@ -112,19 +113,27 @@

Module hatyan.foreman

R1 = 0.36309*(1.-5.*np.sin(lat_rad)*np.sin(lat_rad))/np.sin(lat_rad) #-1 #for lat=50N R2 = 2.59808*np.sin(lat_rad) #2 #for lat=50N - + #get all forman harmonic doodson values (first occurences of duplicated component names) - foreman_doodson_harmonic = foreman_harmonic_raw.loc[~bool_dupl_index,:8].astype(float) - foreman_doodson_harmonic.columns = ['T','S','H','P','N','P1','EDN','nsats'] + foreman_doodson_harmonic_lun = foreman_harmonic_raw.loc[~bool_dupl_index].dropna(axis=1) + foreman_doodson_harmonic_lun[5] = foreman_doodson_harmonic_lun[5].astype(float) #for some reason, column 5/N remains dtype object + if not len(foreman_doodson_harmonic_lun.columns) == 8: + raise Exception('unexpected amount of columns for harmonics, inconsistent file') + foreman_doodson_harmonic_lun.columns = ['T','S','H','P','N','P1','EDN','nsats'] + foreman_doodson_harmonic_lun.index.name = None + + #convert from lunar to solar and reverse automatic column sorting + omega1 = foreman_doodson_harmonic_lun.loc[:,'T'] + corr_array = pd.DataFrame({'S':-omega1,'H':omega1}) + foreman_doodson_harmonic = foreman_doodson_harmonic_lun.add(corr_array,fill_value=0) + foreman_doodson_harmonic = foreman_doodson_harmonic[foreman_doodson_harmonic_lun.columns] #get all foreman harmonic nodal values (non-first occurences of duplicated component names) foreman_nodal_harmonic_wide = foreman_harmonic_raw.loc[bool_dupl_index] - #reshape from 15 to 5 columns - foreman_nodal_harmonic_withna = pd.DataFrame(foreman_nodal_harmonic_wide.values.reshape(207,5), - index=foreman_nodal_harmonic_wide.index.repeat(3), - columns=['P','N','P1','EDN','factor']) - #drop nan lines - foreman_nodal_harmonic = foreman_nodal_harmonic_withna.loc[~foreman_nodal_harmonic_withna.isnull().all(axis=1)] + #reshape from 15 to 5 columns and drop nan lines + foreman_nodal_harmonic = pd.DataFrame(foreman_nodal_harmonic_wide.values.reshape(207,5), + index=foreman_nodal_harmonic_wide.index.repeat(3), + columns=['P','N','P1','EDN','factor']).dropna(axis=0) #multiply with R1/R2 if applicable and convert entire dataframe to floats bool_R1 = foreman_nodal_harmonic['factor'].str.contains('R1') @@ -132,11 +141,13 @@

Module hatyan.foreman

foreman_nodal_harmonic.loc[bool_R1,'factor'] = foreman_nodal_harmonic.loc[bool_R1,'factor'].str.replace('R1','').astype(float)*R1 foreman_nodal_harmonic.loc[bool_R2,'factor'] = foreman_nodal_harmonic.loc[bool_R2,'factor'].str.replace('R2','').astype(float)*R2 foreman_nodal_harmonic = foreman_nodal_harmonic.astype(float) - + foreman_nodal_harmonic.index.name = None + return foreman_doodson_harmonic, foreman_nodal_harmonic -def get_foreman_shallowrelations(pd_series=False): +@functools.lru_cache() #caching useful since reading file and internal consistency check once is sufficient +def get_foreman_shallowrelations(): """ Omzetten van het derde deel van de foremantabel in een pandas DataFrame met shallow water relations. @@ -148,78 +159,58 @@

Module hatyan.foreman

""" foreman_file = os.path.join(os.path.dirname(file_path),'data','data_foreman_shallowrelations.txt') - foreman_shallowrelations_raw = pd.read_csv(foreman_file, comment='#', names=[0], skip_blank_lines=True)[0] - - foreman_shallowrelations = foreman_shallowrelations_raw.str.split(' ', expand=True) - foreman_shallowrelations = foreman_shallowrelations.set_index(0, drop=True) + foreman_shallowrelations = pd.read_csv(foreman_file, comment='#', names=range(10), index_col=0, delim_whitespace=True) foreman_shallowrelations.index.name = None - if not pd_series: - return foreman_shallowrelations - - foreman_shallowrelations_pd = pd.Series() - for iC,const in enumerate(foreman_shallowrelations.index): - foreman_shallow_const = foreman_shallowrelations.loc[const].tolist() - num_dependencies = int(foreman_shallow_const[0]) - shallowrelation_str = '' - for iD in range(num_dependencies): - id_factor = iD*2+1 - id_constname = iD*2+2 - harm_factor = float(foreman_shallow_const[id_factor]) - #if harm_factor%1==0: - # harm_factor = int(harm_factor) - harm_const = foreman_shallow_const[id_constname] - if harm_factor>=0: - shallowrelation_str += (f' +{harm_factor}*{harm_const}') - else: - shallowrelation_str += (f' {harm_factor}*{harm_const}') - foreman_shallowrelations_pd[const] = shallowrelation_str - return foreman_shallowrelations_pd - + #check for internal numdependencies consistency + for const in foreman_shallowrelations.index: + foreman_shallow_const = foreman_shallowrelations.loc[const].dropna().values + num_dependencies = foreman_shallow_const[0] + list_shallow_facs = foreman_shallow_const[1::2] + list_shallow_deps = foreman_shallow_const[2::2] + if not list_shallow_deps.shape == list_shallow_facs.shape == (num_dependencies,): + raise Exception(f'ERROR: shallow relations not internally consistent:\n{foreman_shallowrelations.loc[const]}') + + #check whether all dependencies are available as harmonic components + foreman_doodson_harmonic, foreman_nodal_harmonic = get_foreman_doodson_nodal_harmonic() + list_shallowdependencies = foreman_shallowrelations[[3,5,7,9]].melt()['value'].dropna().unique() + bool_shallowdependencies_isin_harmonics = pd.Series(list_shallowdependencies).isin(foreman_doodson_harmonic.index) + if not bool_shallowdependencies_isin_harmonics.all(): + raise Exception(f'ERROR: not all required shallow dependency components are available:\n{list_shallowdependencies[~bool_shallowdependencies_isin_harmonics]}') + + return foreman_shallowrelations, list_shallowdependencies ################################################# #################### FREQ V0 #################### ################################################# -@functools.lru_cache() #only caching this already makes foreman slightly faster -def get_foreman_table(): #TODO: only harmonic and only v0 - - foreman_doodson_harmonic, foreman_nodal_harmonic = get_foreman_doodson_nodal_harmonic() - t_const_doodson_lun = foreman_doodson_harmonic.copy() - omega1 = t_const_doodson_lun.loc[:,'T'] - corr_array = pd.DataFrame({'S':-omega1,'H':omega1}) - t_const_doodson_sol = t_const_doodson_lun.add(corr_array,fill_value=0) - v0_baseT_for = t_const_doodson_sol[['T','S','H','P','N','P1','EDN']] - - return v0_baseT_for - def get_foreman_v0_freq(const_list, dood_date=pd.DatetimeIndex([dt.datetime(1900,1,1)])): """ Zoekt voor iedere component uit de lijst de v op basis van harmonische doodson getallen en de frequentie rechtstreeks uit de foreman tabel. Shallow water componenten worden afgeleid met de relaties beschreven in de foreman tabel. """ - #get freq/v0 for harmonic components - from hatyan.hatyan_core import get_doodson_eqvals # local import since otherwise cross-dependency - - t_const_doodson_sol = get_foreman_table() + from hatyan.hatyan_core import get_doodson_eqvals, check_requestedconsts # local import since otherwise cross-dependency + check_requestedconsts(tuple(const_list),source='foreman') #TODO: move check to central location when part of hatyan_settings()? + + #get freq/v0 for harmonic components + foreman_doodson_harmonic, foreman_nodal_harmonic = get_foreman_doodson_nodal_harmonic() + doodson_pd = get_doodson_eqvals(dood_date=pd.DatetimeIndex([dt.datetime(1900,1,1)]), mode='freq') #TODO: get freq on multiple dates? multiply_variables = doodson_pd.loc[['T','S','H','P','P1'],:] - t_const_freq_dood = np.dot(t_const_doodson_sol.loc[:,['T','S','H','P','P1']],multiply_variables) / (2*np.pi) - foreman_freqs = pd.DataFrame({'freq':t_const_freq_dood[:,0]},index=t_const_doodson_sol.index) + t_const_freq_dood = np.dot(foreman_doodson_harmonic.loc[:,['T','S','H','P','P1']],multiply_variables) / (2*np.pi) + foreman_freqs = pd.DataFrame({'freq':t_const_freq_dood[:,0]},index=foreman_doodson_harmonic.index) doodson_pd = get_doodson_eqvals(dood_date=dood_date, mode=None) multiply_variables = doodson_pd.loc[['T','S','H','P','N','P1'],:] - v_0i_rad = np.dot(t_const_doodson_sol.loc[:,['T','S','H','P','N','P1']],multiply_variables) + 2*np.pi*t_const_doodson_sol.loc[:,['EDN']].values - v_0i_rad_harmonic_pd = pd.DataFrame(v_0i_rad,index=t_const_doodson_sol.index) + v_0i_rad = np.dot(foreman_doodson_harmonic.loc[:,['T','S','H','P','N','P1']],multiply_variables) + 2*np.pi*foreman_doodson_harmonic.loc[:,['EDN']].values + v_0i_rad_harmonic_pd = pd.DataFrame(v_0i_rad,index=foreman_doodson_harmonic.index) #derive freq/v0 for shallow water components - foreman_shallowrelations = get_foreman_shallowrelations() - #foreman_shallowrelations_pd = get_foreman_shallowrelations(pd_series=True) - + foreman_shallowrelations, list_shallowdependencies = get_foreman_shallowrelations() v_0i_rad = pd.DataFrame(np.zeros((len(const_list),len(dood_date))),index=const_list) t_const_freq = pd.DataFrame({'freq':np.zeros((len(const_list)))},index=const_list) @@ -231,21 +222,16 @@

Module hatyan.foreman

elif const in foreman_shallowrelations.index: #or is not in foreman_harmonic_doodson_all_list v_0i_rad_temp = 0 t_const_freq_temp = 0 - foreman_shallow_const = foreman_shallowrelations.loc[const].tolist() - num_dependencies = int(foreman_shallow_const[0]) - for iD in range(num_dependencies): - id_factor = iD*2+1 - id_constname = iD*2+2 - harm_factor = float(foreman_shallow_const[id_factor]) - harm_const = foreman_shallow_const[id_constname] + foreman_shallow_const = foreman_shallowrelations.loc[const].dropna().values + list_shallow_facs = foreman_shallow_const[1::2] + list_shallow_deps = foreman_shallow_const[2::2] + for harm_factor,harm_const in zip(list_shallow_facs,list_shallow_deps): v_dependency = v_0i_rad_harmonic_pd.loc[harm_const].values freq_dependency = foreman_freqs.loc[harm_const,'freq'] #should be dependent on harmonic doodson numbers (make foreman_freqs_dood_all variable in foreman.py, in freq or harmonic definition) v_0i_rad_temp += harm_factor*v_dependency t_const_freq_temp += harm_factor*freq_dependency - v_0i_rad.loc[const] = v_0i_rad_temp + v_0i_rad.loc[const,:] = v_0i_rad_temp t_const_freq.loc[const,'freq'] = t_const_freq_temp - else: - raise Exception('ERROR: constituent %s is not in v_0i_rad_harmonic_pd.index and foreman_shallowrelations.index, this is invalid.'%(const)) return v_0i_rad, t_const_freq @@ -253,25 +239,6 @@

Module hatyan.foreman

################################################# ################# NODALFACTORS ################## ################################################# -def get_foreman_nodalfactors_fromharmonic_oneconst(foreman_harmonic_nodal_const, dood_date): - - from hatyan.hatyan_core import get_doodson_eqvals # local import since otherwise cross-dependency - - doodson_pd = get_doodson_eqvals(dood_date) - - fore_delta_jk_rad_all = np.dot(foreman_harmonic_nodal_const.loc[:,['P','N','P1']],doodson_pd.loc[['P','N','P1'],:]) - fore_alpha_jk_all = foreman_harmonic_nodal_const.loc[:,['EDN']].values * 2*np.pi #phase correction satellite. 0.5=90 voor M2 en N2, 0=0 voor S2 - fore_r_jk_all = foreman_harmonic_nodal_const.loc[:,['factor']].values #amplitude ratio for satellite. 0.0373 voor M2 en N2, 0.0022 voor S2 - fore_fj_left_all = 1 * fore_r_jk_all * np.cos(fore_delta_jk_rad_all + fore_alpha_jk_all) #should be sum for n sattelites - fore_fj_right_all = 1 * fore_r_jk_all * np.sin(fore_delta_jk_rad_all + fore_alpha_jk_all) #should be sum for n sattelites - fore_fj_left = fore_fj_left_all.sum(axis=0) - fore_fj_right = fore_fj_right_all.sum(axis=0) - - f_i_FOR = ( (1+fore_fj_left)**2 + (fore_fj_right)**2)**(1/2.) - u_i_rad_FOR = -np.arctan2(fore_fj_right,1+fore_fj_left) #TODO: added minus to get sign comparable to hatyan - - return f_i_FOR, u_i_rad_FOR - def get_foreman_nodalfactors(const_list, dood_date): """ @@ -279,49 +246,62 @@

Module hatyan.foreman

Shallow water componenten worden afgeleid met de relaties beschreven in de foreman tabel. """ - foreman_shallowrelations = get_foreman_shallowrelations() - #foreman_shallowrelations_pd = get_foreman_shallowrelations(pd_series=True) - foreman_doodson_harmonic, foreman_nodal_harmonic = get_foreman_doodson_nodal_harmonic() - - f_i_FOR = pd.DataFrame(np.ones((len(const_list),len(dood_date))), index=const_list) - u_i_rad_FOR = pd.DataFrame(np.zeros((len(const_list),len(dood_date))), index=const_list) + from hatyan.hatyan_core import get_doodson_eqvals, check_requestedconsts # local import since otherwise cross-dependency + check_requestedconsts(tuple(const_list),source='foreman') #TODO: move check to central location when part of hatyan_settings()? + + doodson_pd = get_doodson_eqvals(dood_date) + foreman_doodson_harmonic, foreman_nodal_harmonic = get_foreman_doodson_nodal_harmonic() + foreman_shallowrelations, list_shallowdependencies = get_foreman_shallowrelations() + + #extent const_list with missing but required harmonic components + bool_shallowrequired = pd.Series(foreman_shallowrelations.index).isin(pd.Series(const_list)) + bool_dependencyalready = pd.Series(list_shallowdependencies).isin(pd.Series(const_list)) + if bool_shallowrequired.any() and not bool_dependencyalready.all(): #if any shallow constituent is requested and if not all dependent constituents are in const_list + const_list_extra = list_shallowdependencies[~bool_dependencyalready] + const_list_inclshallow = const_list + const_list_extra.tolist() # const_list + not yet available shallowdependencies + else: + const_list_inclshallow = const_list + + #allocate dataframes including potential exta constituents (are removed before return) + #TODO: creating empty dataframe with {} and columns/index takes way more time than below, check if this is done somewhere in the code + nodal_shape = (len(const_list_inclshallow),len(dood_date)) + f_i_FOR_inclshallow = pd.DataFrame(np.ones(nodal_shape), index=const_list_inclshallow) + u_i_rad_FOR_inclshallow = pd.DataFrame(np.zeros(nodal_shape), index=const_list_inclshallow) + #f and u for harmonic constituents - for iC,const in enumerate(const_list): - if const in foreman_doodson_harmonic.index: - if const not in foreman_nodal_harmonic.index.unique(): # if harmonic constituent has no nodal factors - continue + for const in const_list_inclshallow: + if const in foreman_nodal_harmonic.index.unique(): # if harmonic constituent has nodal factors foreman_harmonic_nodal_const = foreman_nodal_harmonic.loc[[const]] - f_i_FOR.loc[const,:], u_i_rad_FOR.loc[const,:] = get_foreman_nodalfactors_fromharmonic_oneconst(foreman_harmonic_nodal_const, dood_date) - elif const in foreman_shallowrelations.index: # component has satellites based on shallow water relations + fore_delta_jk_rad_all = np.dot(foreman_harmonic_nodal_const.loc[:,['P','N','P1']],doodson_pd.loc[['P','N','P1'],:]) + fore_alpha_jk_all = foreman_harmonic_nodal_const.loc[:,['EDN']].values * 2*np.pi #phase correction satellite. 0.5=90 voor M2 en N2, 0=0 voor S2 + fore_r_jk_all = foreman_harmonic_nodal_const.loc[:,['factor']].values #amplitude ratio for satellite. 0.0373 voor M2 en N2, 0.0022 voor S2 + fore_fj_left_all = 1 * fore_r_jk_all * np.cos(fore_delta_jk_rad_all + fore_alpha_jk_all) #should be sum for n sattelites + fore_fj_right_all = 1 * fore_r_jk_all * np.sin(fore_delta_jk_rad_all + fore_alpha_jk_all) #should be sum for n sattelites + fore_fj_left = fore_fj_left_all.sum(axis=0) + fore_fj_right = fore_fj_right_all.sum(axis=0) + f_i_FOR_inclshallow.loc[const,:] = ( (1+fore_fj_left)**2 + (fore_fj_right)**2)**(1/2.) + u_i_rad_FOR_inclshallow.loc[const,:] = -np.arctan2(fore_fj_right,1+fore_fj_left) #TODO: added minus to get sign comparable to hatyan + elif const in foreman_doodson_harmonic.index: #if harmonic constituent has no nodal factors, default values 1 and 0 are applicable + continue + + #f and u for shallow constituents + for const in const_list_inclshallow: + if const in foreman_shallowrelations.index: # component has satellites based on shallow water relations f_i_FOR_temp = 1.0 u_i_rad_FOR_temp = 0.0 - #temp_nodal_df = pd.DataFrame() - foreman_shallow_const = foreman_shallowrelations.loc[const].tolist() - #foreman_shallow_const_pd = foreman_shallowrelations_pd.loc[const] - num_dependencies = int(foreman_shallow_const[0]) - for iD in range(num_dependencies): - id_factor = iD*2+1 - id_constname = iD*2+2 - harm_factor = float(foreman_shallow_const[id_factor]) - harm_const = foreman_shallow_const[id_constname] - if harm_const not in foreman_nodal_harmonic.index.unique(): - raise Exception('ERROR: harmonic component %s for shallow water component %s is not available in the harmonic nodal factors (foreman_nodal_harmonic)'%(harm_const,const)) - foreman_harmonic_nodal_const = foreman_nodal_harmonic.loc[[harm_const]] - #temp_nodal_df_onestep = pd.concat([harm_factor*foreman_nodal_all.loc[harm_const,:3],foreman_nodal_all.loc[harm_const,[4]]],axis=1) - #temp_nodal_df = temp_nodal_df.append(temp_nodal_df_onestep) - f_i_dependency, u_i_rad_dependency = get_foreman_nodalfactors_fromharmonic_oneconst(foreman_harmonic_nodal_const, dood_date)#foreman_harmonic_nodal_all[foreman_harmonic_nodal_all_list.index()][iS] - f_i_FOR_temp *= f_i_dependency**abs(harm_factor) - u_i_rad_FOR_temp += harm_factor*u_i_rad_dependency - f_i_FOR.loc[const,:] = f_i_FOR_temp - u_i_rad_FOR.loc[const,:] = u_i_rad_FOR_temp - #temp_nodal_df.index = ['M4']*len(temp_nodal_df.index) - #f_i_FOR2[iC,:], u_i_rad_FOR2[iC,:] = get_foreman_nodalfactors_fromharmonic_oneconst(temp_nodal_df, dood_date) - else: - raise Exception('ERROR: constituent %s is not in foreman_doodson_harmonic.index and foreman_shallowrelations.index, this is invalid.'%(const)) - - #print(f_i_FOR-f_i_FOR2) - #print(u_i_rad_FOR-u_i_rad_FOR2) + foreman_shallow_const = foreman_shallowrelations.loc[const].dropna().values + list_shallow_facs = foreman_shallow_const[1::2] + list_shallow_deps = foreman_shallow_const[2::2] + for harm_factor,harm_const in zip(list_shallow_facs,list_shallow_deps): + f_i_FOR_temp *= f_i_FOR_inclshallow.loc[harm_const,:].values ** abs(harm_factor) + u_i_rad_FOR_temp += u_i_rad_FOR_inclshallow.loc[harm_const,:].values * harm_factor + f_i_FOR_inclshallow.loc[const,:] = f_i_FOR_temp + u_i_rad_FOR_inclshallow.loc[const,:] = u_i_rad_FOR_temp + + #drop extra added constituents + f_i_FOR = f_i_FOR_inclshallow.loc[const_list,:] + u_i_rad_FOR = u_i_rad_FOR_inclshallow.loc[const_list,:] return f_i_FOR, u_i_rad_FOR @@ -392,19 +372,27 @@

Returns

R1 = 0.36309*(1.-5.*np.sin(lat_rad)*np.sin(lat_rad))/np.sin(lat_rad) #-1 #for lat=50N R2 = 2.59808*np.sin(lat_rad) #2 #for lat=50N - + #get all forman harmonic doodson values (first occurences of duplicated component names) - foreman_doodson_harmonic = foreman_harmonic_raw.loc[~bool_dupl_index,:8].astype(float) - foreman_doodson_harmonic.columns = ['T','S','H','P','N','P1','EDN','nsats'] + foreman_doodson_harmonic_lun = foreman_harmonic_raw.loc[~bool_dupl_index].dropna(axis=1) + foreman_doodson_harmonic_lun[5] = foreman_doodson_harmonic_lun[5].astype(float) #for some reason, column 5/N remains dtype object + if not len(foreman_doodson_harmonic_lun.columns) == 8: + raise Exception('unexpected amount of columns for harmonics, inconsistent file') + foreman_doodson_harmonic_lun.columns = ['T','S','H','P','N','P1','EDN','nsats'] + foreman_doodson_harmonic_lun.index.name = None + + #convert from lunar to solar and reverse automatic column sorting + omega1 = foreman_doodson_harmonic_lun.loc[:,'T'] + corr_array = pd.DataFrame({'S':-omega1,'H':omega1}) + foreman_doodson_harmonic = foreman_doodson_harmonic_lun.add(corr_array,fill_value=0) + foreman_doodson_harmonic = foreman_doodson_harmonic[foreman_doodson_harmonic_lun.columns] #get all foreman harmonic nodal values (non-first occurences of duplicated component names) foreman_nodal_harmonic_wide = foreman_harmonic_raw.loc[bool_dupl_index] - #reshape from 15 to 5 columns - foreman_nodal_harmonic_withna = pd.DataFrame(foreman_nodal_harmonic_wide.values.reshape(207,5), - index=foreman_nodal_harmonic_wide.index.repeat(3), - columns=['P','N','P1','EDN','factor']) - #drop nan lines - foreman_nodal_harmonic = foreman_nodal_harmonic_withna.loc[~foreman_nodal_harmonic_withna.isnull().all(axis=1)] + #reshape from 15 to 5 columns and drop nan lines + foreman_nodal_harmonic = pd.DataFrame(foreman_nodal_harmonic_wide.values.reshape(207,5), + index=foreman_nodal_harmonic_wide.index.repeat(3), + columns=['P','N','P1','EDN','factor']).dropna(axis=0) #multiply with R1/R2 if applicable and convert entire dataframe to floats bool_R1 = foreman_nodal_harmonic['factor'].str.contains('R1') @@ -412,12 +400,13 @@

Returns

foreman_nodal_harmonic.loc[bool_R1,'factor'] = foreman_nodal_harmonic.loc[bool_R1,'factor'].str.replace('R1','').astype(float)*R1 foreman_nodal_harmonic.loc[bool_R2,'factor'] = foreman_nodal_harmonic.loc[bool_R2,'factor'].str.replace('R2','').astype(float)*R2 foreman_nodal_harmonic = foreman_nodal_harmonic.astype(float) - + foreman_nodal_harmonic.index.name = None + return foreman_doodson_harmonic, foreman_nodal_harmonic
-def get_foreman_shallowrelations(pd_series=False) +def get_foreman_shallowrelations()

Omzetten van het derde deel van de foremantabel in een pandas DataFrame met shallow water relations.

@@ -430,7 +419,8 @@

Returns

Expand source code -
def get_foreman_shallowrelations(pd_series=False):
+
@functools.lru_cache() #caching useful since reading file and internal consistency check once is sufficient
+def get_foreman_shallowrelations():
     """
     Omzetten van het derde deel van de foremantabel in een pandas DataFrame met shallow water relations.
 
@@ -442,55 +432,26 @@ 

Returns

""" foreman_file = os.path.join(os.path.dirname(file_path),'data','data_foreman_shallowrelations.txt') - foreman_shallowrelations_raw = pd.read_csv(foreman_file, comment='#', names=[0], skip_blank_lines=True)[0] - - foreman_shallowrelations = foreman_shallowrelations_raw.str.split(' ', expand=True) - foreman_shallowrelations = foreman_shallowrelations.set_index(0, drop=True) + foreman_shallowrelations = pd.read_csv(foreman_file, comment='#', names=range(10), index_col=0, delim_whitespace=True) foreman_shallowrelations.index.name = None - if not pd_series: - return foreman_shallowrelations - - foreman_shallowrelations_pd = pd.Series() - for iC,const in enumerate(foreman_shallowrelations.index): - foreman_shallow_const = foreman_shallowrelations.loc[const].tolist() - num_dependencies = int(foreman_shallow_const[0]) - shallowrelation_str = '' - for iD in range(num_dependencies): - id_factor = iD*2+1 - id_constname = iD*2+2 - harm_factor = float(foreman_shallow_const[id_factor]) - #if harm_factor%1==0: - # harm_factor = int(harm_factor) - harm_const = foreman_shallow_const[id_constname] - if harm_factor>=0: - shallowrelation_str += (f' +{harm_factor}*{harm_const}') - else: - shallowrelation_str += (f' {harm_factor}*{harm_const}') - foreman_shallowrelations_pd[const] = shallowrelation_str - return foreman_shallowrelations_pd
- -
-
-def get_foreman_table() -
-
-
-
- -Expand source code - -
@functools.lru_cache() #only caching this already makes foreman slightly faster
-def get_foreman_table(): #TODO: only harmonic and only v0
-    
+    #check for internal numdependencies consistency
+    for const in foreman_shallowrelations.index:
+        foreman_shallow_const = foreman_shallowrelations.loc[const].dropna().values
+        num_dependencies = foreman_shallow_const[0]
+        list_shallow_facs = foreman_shallow_const[1::2]
+        list_shallow_deps = foreman_shallow_const[2::2]
+        if not list_shallow_deps.shape == list_shallow_facs.shape == (num_dependencies,):
+            raise Exception(f'ERROR: shallow relations not internally consistent:\n{foreman_shallowrelations.loc[const]}')
+        
+    #check whether all dependencies are available as harmonic components
     foreman_doodson_harmonic, foreman_nodal_harmonic = get_foreman_doodson_nodal_harmonic()
-    t_const_doodson_lun = foreman_doodson_harmonic.copy()
-    omega1 = t_const_doodson_lun.loc[:,'T']
-    corr_array = pd.DataFrame({'S':-omega1,'H':omega1})
-    t_const_doodson_sol = t_const_doodson_lun.add(corr_array,fill_value=0)
-    v0_baseT_for = t_const_doodson_sol[['T','S','H','P','N','P1','EDN']]
-    
-    return v0_baseT_for
+ list_shallowdependencies = foreman_shallowrelations[[3,5,7,9]].melt()['value'].dropna().unique() + bool_shallowdependencies_isin_harmonics = pd.Series(list_shallowdependencies).isin(foreman_doodson_harmonic.index) + if not bool_shallowdependencies_isin_harmonics.all(): + raise Exception(f'ERROR: not all required shallow dependency components are available:\n{list_shallowdependencies[~bool_shallowdependencies_isin_harmonics]}') + + return foreman_shallowrelations, list_shallowdependencies
@@ -509,25 +470,25 @@

Returns

Shallow water componenten worden afgeleid met de relaties beschreven in de foreman tabel. """ - #get freq/v0 for harmonic components - from hatyan.hatyan_core import get_doodson_eqvals # local import since otherwise cross-dependency - - t_const_doodson_sol = get_foreman_table() + from hatyan.hatyan_core import get_doodson_eqvals, check_requestedconsts # local import since otherwise cross-dependency + check_requestedconsts(tuple(const_list),source='foreman') #TODO: move check to central location when part of hatyan_settings()? + + #get freq/v0 for harmonic components + foreman_doodson_harmonic, foreman_nodal_harmonic = get_foreman_doodson_nodal_harmonic() + doodson_pd = get_doodson_eqvals(dood_date=pd.DatetimeIndex([dt.datetime(1900,1,1)]), mode='freq') #TODO: get freq on multiple dates? multiply_variables = doodson_pd.loc[['T','S','H','P','P1'],:] - t_const_freq_dood = np.dot(t_const_doodson_sol.loc[:,['T','S','H','P','P1']],multiply_variables) / (2*np.pi) - foreman_freqs = pd.DataFrame({'freq':t_const_freq_dood[:,0]},index=t_const_doodson_sol.index) + t_const_freq_dood = np.dot(foreman_doodson_harmonic.loc[:,['T','S','H','P','P1']],multiply_variables) / (2*np.pi) + foreman_freqs = pd.DataFrame({'freq':t_const_freq_dood[:,0]},index=foreman_doodson_harmonic.index) doodson_pd = get_doodson_eqvals(dood_date=dood_date, mode=None) multiply_variables = doodson_pd.loc[['T','S','H','P','N','P1'],:] - v_0i_rad = np.dot(t_const_doodson_sol.loc[:,['T','S','H','P','N','P1']],multiply_variables) + 2*np.pi*t_const_doodson_sol.loc[:,['EDN']].values - v_0i_rad_harmonic_pd = pd.DataFrame(v_0i_rad,index=t_const_doodson_sol.index) + v_0i_rad = np.dot(foreman_doodson_harmonic.loc[:,['T','S','H','P','N','P1']],multiply_variables) + 2*np.pi*foreman_doodson_harmonic.loc[:,['EDN']].values + v_0i_rad_harmonic_pd = pd.DataFrame(v_0i_rad,index=foreman_doodson_harmonic.index) #derive freq/v0 for shallow water components - foreman_shallowrelations = get_foreman_shallowrelations() - #foreman_shallowrelations_pd = get_foreman_shallowrelations(pd_series=True) - + foreman_shallowrelations, list_shallowdependencies = get_foreman_shallowrelations() v_0i_rad = pd.DataFrame(np.zeros((len(const_list),len(dood_date))),index=const_list) t_const_freq = pd.DataFrame({'freq':np.zeros((len(const_list)))},index=const_list) @@ -539,54 +500,20 @@

Returns

elif const in foreman_shallowrelations.index: #or is not in foreman_harmonic_doodson_all_list v_0i_rad_temp = 0 t_const_freq_temp = 0 - foreman_shallow_const = foreman_shallowrelations.loc[const].tolist() - num_dependencies = int(foreman_shallow_const[0]) - for iD in range(num_dependencies): - id_factor = iD*2+1 - id_constname = iD*2+2 - harm_factor = float(foreman_shallow_const[id_factor]) - harm_const = foreman_shallow_const[id_constname] + foreman_shallow_const = foreman_shallowrelations.loc[const].dropna().values + list_shallow_facs = foreman_shallow_const[1::2] + list_shallow_deps = foreman_shallow_const[2::2] + for harm_factor,harm_const in zip(list_shallow_facs,list_shallow_deps): v_dependency = v_0i_rad_harmonic_pd.loc[harm_const].values freq_dependency = foreman_freqs.loc[harm_const,'freq'] #should be dependent on harmonic doodson numbers (make foreman_freqs_dood_all variable in foreman.py, in freq or harmonic definition) v_0i_rad_temp += harm_factor*v_dependency t_const_freq_temp += harm_factor*freq_dependency - v_0i_rad.loc[const] = v_0i_rad_temp + v_0i_rad.loc[const,:] = v_0i_rad_temp t_const_freq.loc[const,'freq'] = t_const_freq_temp - else: - raise Exception('ERROR: constituent %s is not in v_0i_rad_harmonic_pd.index and foreman_shallowrelations.index, this is invalid.'%(const)) return v_0i_rad, t_const_freq
-
-def get_foreman_nodalfactors_fromharmonic_oneconst(foreman_harmonic_nodal_const, dood_date) -
-
-
-
- -Expand source code - -
def get_foreman_nodalfactors_fromharmonic_oneconst(foreman_harmonic_nodal_const, dood_date):
-
-    from hatyan.hatyan_core import get_doodson_eqvals # local import since otherwise cross-dependency
-
-    doodson_pd = get_doodson_eqvals(dood_date)
-    
-    fore_delta_jk_rad_all = np.dot(foreman_harmonic_nodal_const.loc[:,['P','N','P1']],doodson_pd.loc[['P','N','P1'],:])
-    fore_alpha_jk_all = foreman_harmonic_nodal_const.loc[:,['EDN']].values * 2*np.pi #phase correction satellite. 0.5=90 voor M2 en N2, 0=0 voor S2
-    fore_r_jk_all = foreman_harmonic_nodal_const.loc[:,['factor']].values #amplitude ratio for satellite. 0.0373 voor M2 en N2, 0.0022 voor S2
-    fore_fj_left_all = 1 * fore_r_jk_all * np.cos(fore_delta_jk_rad_all + fore_alpha_jk_all) #should be sum for n sattelites
-    fore_fj_right_all = 1 * fore_r_jk_all * np.sin(fore_delta_jk_rad_all + fore_alpha_jk_all) #should be sum for n sattelites
-    fore_fj_left = fore_fj_left_all.sum(axis=0)
-    fore_fj_right = fore_fj_right_all.sum(axis=0)
-    
-    f_i_FOR = ( (1+fore_fj_left)**2 + (fore_fj_right)**2)**(1/2.)
-    u_i_rad_FOR = -np.arctan2(fore_fj_right,1+fore_fj_left) #TODO: added minus to get sign comparable to hatyan
-
-    return f_i_FOR, u_i_rad_FOR
-
-
def get_foreman_nodalfactors(const_list, dood_date)
@@ -603,49 +530,62 @@

Returns

Shallow water componenten worden afgeleid met de relaties beschreven in de foreman tabel. """ - foreman_shallowrelations = get_foreman_shallowrelations() - #foreman_shallowrelations_pd = get_foreman_shallowrelations(pd_series=True) - foreman_doodson_harmonic, foreman_nodal_harmonic = get_foreman_doodson_nodal_harmonic() - - f_i_FOR = pd.DataFrame(np.ones((len(const_list),len(dood_date))), index=const_list) - u_i_rad_FOR = pd.DataFrame(np.zeros((len(const_list),len(dood_date))), index=const_list) + from hatyan.hatyan_core import get_doodson_eqvals, check_requestedconsts # local import since otherwise cross-dependency + + check_requestedconsts(tuple(const_list),source='foreman') #TODO: move check to central location when part of hatyan_settings()? + doodson_pd = get_doodson_eqvals(dood_date) + foreman_doodson_harmonic, foreman_nodal_harmonic = get_foreman_doodson_nodal_harmonic() + foreman_shallowrelations, list_shallowdependencies = get_foreman_shallowrelations() + + #extent const_list with missing but required harmonic components + bool_shallowrequired = pd.Series(foreman_shallowrelations.index).isin(pd.Series(const_list)) + bool_dependencyalready = pd.Series(list_shallowdependencies).isin(pd.Series(const_list)) + if bool_shallowrequired.any() and not bool_dependencyalready.all(): #if any shallow constituent is requested and if not all dependent constituents are in const_list + const_list_extra = list_shallowdependencies[~bool_dependencyalready] + const_list_inclshallow = const_list + const_list_extra.tolist() # const_list + not yet available shallowdependencies + else: + const_list_inclshallow = const_list + + #allocate dataframes including potential exta constituents (are removed before return) + #TODO: creating empty dataframe with {} and columns/index takes way more time than below, check if this is done somewhere in the code + nodal_shape = (len(const_list_inclshallow),len(dood_date)) + f_i_FOR_inclshallow = pd.DataFrame(np.ones(nodal_shape), index=const_list_inclshallow) + u_i_rad_FOR_inclshallow = pd.DataFrame(np.zeros(nodal_shape), index=const_list_inclshallow) + #f and u for harmonic constituents - for iC,const in enumerate(const_list): - if const in foreman_doodson_harmonic.index: - if const not in foreman_nodal_harmonic.index.unique(): # if harmonic constituent has no nodal factors - continue + for const in const_list_inclshallow: + if const in foreman_nodal_harmonic.index.unique(): # if harmonic constituent has nodal factors foreman_harmonic_nodal_const = foreman_nodal_harmonic.loc[[const]] - f_i_FOR.loc[const,:], u_i_rad_FOR.loc[const,:] = get_foreman_nodalfactors_fromharmonic_oneconst(foreman_harmonic_nodal_const, dood_date) - elif const in foreman_shallowrelations.index: # component has satellites based on shallow water relations + fore_delta_jk_rad_all = np.dot(foreman_harmonic_nodal_const.loc[:,['P','N','P1']],doodson_pd.loc[['P','N','P1'],:]) + fore_alpha_jk_all = foreman_harmonic_nodal_const.loc[:,['EDN']].values * 2*np.pi #phase correction satellite. 0.5=90 voor M2 en N2, 0=0 voor S2 + fore_r_jk_all = foreman_harmonic_nodal_const.loc[:,['factor']].values #amplitude ratio for satellite. 0.0373 voor M2 en N2, 0.0022 voor S2 + fore_fj_left_all = 1 * fore_r_jk_all * np.cos(fore_delta_jk_rad_all + fore_alpha_jk_all) #should be sum for n sattelites + fore_fj_right_all = 1 * fore_r_jk_all * np.sin(fore_delta_jk_rad_all + fore_alpha_jk_all) #should be sum for n sattelites + fore_fj_left = fore_fj_left_all.sum(axis=0) + fore_fj_right = fore_fj_right_all.sum(axis=0) + f_i_FOR_inclshallow.loc[const,:] = ( (1+fore_fj_left)**2 + (fore_fj_right)**2)**(1/2.) + u_i_rad_FOR_inclshallow.loc[const,:] = -np.arctan2(fore_fj_right,1+fore_fj_left) #TODO: added minus to get sign comparable to hatyan + elif const in foreman_doodson_harmonic.index: #if harmonic constituent has no nodal factors, default values 1 and 0 are applicable + continue + + #f and u for shallow constituents + for const in const_list_inclshallow: + if const in foreman_shallowrelations.index: # component has satellites based on shallow water relations f_i_FOR_temp = 1.0 u_i_rad_FOR_temp = 0.0 - #temp_nodal_df = pd.DataFrame() - foreman_shallow_const = foreman_shallowrelations.loc[const].tolist() - #foreman_shallow_const_pd = foreman_shallowrelations_pd.loc[const] - num_dependencies = int(foreman_shallow_const[0]) - for iD in range(num_dependencies): - id_factor = iD*2+1 - id_constname = iD*2+2 - harm_factor = float(foreman_shallow_const[id_factor]) - harm_const = foreman_shallow_const[id_constname] - if harm_const not in foreman_nodal_harmonic.index.unique(): - raise Exception('ERROR: harmonic component %s for shallow water component %s is not available in the harmonic nodal factors (foreman_nodal_harmonic)'%(harm_const,const)) - foreman_harmonic_nodal_const = foreman_nodal_harmonic.loc[[harm_const]] - #temp_nodal_df_onestep = pd.concat([harm_factor*foreman_nodal_all.loc[harm_const,:3],foreman_nodal_all.loc[harm_const,[4]]],axis=1) - #temp_nodal_df = temp_nodal_df.append(temp_nodal_df_onestep) - f_i_dependency, u_i_rad_dependency = get_foreman_nodalfactors_fromharmonic_oneconst(foreman_harmonic_nodal_const, dood_date)#foreman_harmonic_nodal_all[foreman_harmonic_nodal_all_list.index()][iS] - f_i_FOR_temp *= f_i_dependency**abs(harm_factor) - u_i_rad_FOR_temp += harm_factor*u_i_rad_dependency - f_i_FOR.loc[const,:] = f_i_FOR_temp - u_i_rad_FOR.loc[const,:] = u_i_rad_FOR_temp - #temp_nodal_df.index = ['M4']*len(temp_nodal_df.index) - #f_i_FOR2[iC,:], u_i_rad_FOR2[iC,:] = get_foreman_nodalfactors_fromharmonic_oneconst(temp_nodal_df, dood_date) - else: - raise Exception('ERROR: constituent %s is not in foreman_doodson_harmonic.index and foreman_shallowrelations.index, this is invalid.'%(const)) - - #print(f_i_FOR-f_i_FOR2) - #print(u_i_rad_FOR-u_i_rad_FOR2) + foreman_shallow_const = foreman_shallowrelations.loc[const].dropna().values + list_shallow_facs = foreman_shallow_const[1::2] + list_shallow_deps = foreman_shallow_const[2::2] + for harm_factor,harm_const in zip(list_shallow_facs,list_shallow_deps): + f_i_FOR_temp *= f_i_FOR_inclshallow.loc[harm_const,:].values ** abs(harm_factor) + u_i_rad_FOR_temp += u_i_rad_FOR_inclshallow.loc[harm_const,:].values * harm_factor + f_i_FOR_inclshallow.loc[const,:] = f_i_FOR_temp + u_i_rad_FOR_inclshallow.loc[const,:] = u_i_rad_FOR_temp + + #drop extra added constituents + f_i_FOR = f_i_FOR_inclshallow.loc[const_list,:] + u_i_rad_FOR = u_i_rad_FOR_inclshallow.loc[const_list,:] return f_i_FOR, u_i_rad_FOR @@ -669,9 +609,7 @@

Index

diff --git a/docs/hatyan/hatyan_core.html b/docs/hatyan/hatyan_core.html index 06fa7cb2..25a8e2cd 100644 --- a/docs/hatyan/hatyan_core.html +++ b/docs/hatyan/hatyan_core.html @@ -72,7 +72,22 @@

Module hatyan.hatyan_core

import functools from hatyan.schureman import get_schureman_freqs, get_schureman_v0, get_schureman_u, get_schureman_f, get_schureman_table -from hatyan.foreman import get_foreman_v0_freq, get_foreman_shallowrelations, get_foreman_nodalfactors, get_foreman_table +from hatyan.foreman import get_foreman_v0_freq, get_foreman_doodson_nodal_harmonic, get_foreman_shallowrelations, get_foreman_nodalfactors + + +@functools.lru_cache() +def check_requestedconsts(const_list_tuple,source): + #TODO: move check to central location when part of hatyan_settings()? + if source=='schureman': + const_list_allforsource = get_schureman_table().index + elif source=='foreman': + foreman_doodson_harmonic, foreman_nodal_harmonic = get_foreman_doodson_nodal_harmonic() + foreman_shallowrelations, list_shallowdependencies = get_foreman_shallowrelations() + const_list_allforsource = pd.Series(foreman_doodson_harmonic.index.append(foreman_shallowrelations.index)) + + bool_constavailable = pd.Series(const_list_tuple).isin(const_list_allforsource) + if not bool_constavailable.all(): + raise Exception(f'ERROR: not all requested components available in schureman harmonics or shallowrelations:\n{pd.Series(const_list_tuple).loc[~bool_constavailable]}') def get_freqv0_generic(hatyan_settings, const_list, dood_date_mid, dood_date_start): @@ -87,7 +102,7 @@

Module hatyan.hatyan_core

t_const_freq_pd = get_schureman_freqs(const_list, dood_date=dood_date_mid) v_0i_rad = get_schureman_v0(const_list, dood_date_start).T #at start of timeseries elif hatyan_settings.source=='foreman': #TODO: this is probably quite slow since foreman is not cached - dummy, t_const_freq_pd = get_foreman_v0_freq(const_list=const_list, dood_date=dood_date_mid) + dummy, t_const_freq_pd = get_foreman_v0_freq(const_list=const_list, dood_date=dood_date_mid) #TODO: does this really matter, maybe just retrieve on dood_date_start? Otherwise maybe split definition? v_0i_rad, dummy = get_foreman_v0_freq(const_list=const_list, dood_date=dood_date_start) v_0i_rad = v_0i_rad.T @@ -223,6 +238,8 @@

Module hatyan.hatyan_core

DESCRIPTION. """ + #TODO: check if this is still necessary in newer pandas versions + #TODO: merging with robust_daterange_fromtimesextfreq() possible? if refdate_dt is None: refdate_dt = dt.datetime(1900,1,1) @@ -237,17 +254,35 @@

Module hatyan.hatyan_core

return dood_tstart_sec, fancy_pddt -@functools.lru_cache() #TODO: get_foreman_v0_freq is way slower than get_schureman_freqs because it is live, therefore caching this entire function -def full_const_list_withfreqs(): +def get_lunarSLSIHO_fromsolar(v0uf_base): #TODO: iets simpeler implementatie in foreman.get_foreman_doodson_nodal_harmonic(), maar dit is ook prima + + #conversion to lunar for comparison with SLS and IHO + v0uf_baseT_solar = v0uf_base.loc[['T','S','H','P','N','P1','EDN']].T + v0uf_baseT_lunar = v0uf_baseT_solar.copy() + v0uf_baseT_lunar['S'] = v0uf_baseT_solar['S'] + v0uf_baseT_solar['T'] #ib with relation ω1 =ω0 − ω2 +ω3 (stated in SLS book) + v0uf_baseT_lunar['H'] = v0uf_baseT_solar['H'] - v0uf_baseT_solar['T'] #ic with relation ω1 =ω0 − ω2 +ω3 (stated in SLS book) + #lunar IHO (compare to Sea Level Science book from Woodsworth and Pugh) + v0uf_baseT_lunar_SLS = v0uf_baseT_lunar.copy() + v0uf_baseT_lunar_SLS['EDN'] = -v0uf_baseT_lunar['EDN']%360 #klopt niet allemaal met tabel 4.1 uit SLS boek, moet dit wel? + #lunar IHO (compare to c + v0uf_baseT_lunar_IHO = v0uf_baseT_lunar.copy() + v0uf_baseT_lunar_IHO['EDN'] = -v0uf_baseT_lunar['EDN']/90 + 5 # (-90 lijkt 6 in IHO lijst, 90 is 4, 180 is 7) + v0uf_baseT_lunar_IHO.loc[v0uf_baseT_lunar_IHO['EDN']==3,'EDN'] = 7 # convert -180 (3) to +180 (7) + v0uf_baseT_lunar_IHO[['S','H','P','N','P1']] += 5 + return v0uf_baseT_lunar, v0uf_baseT_lunar_SLS, v0uf_baseT_lunar_IHO + + +@functools.lru_cache() #TODO: get_foreman_v0_freq is way slower than get_schureman_freqs because it is live, therefore caching this entire function (can also cache hatyan.foreman.get_foreman_v0_freq() but then const_list should be a tuple instead of a list) +def get_full_const_list_withfreqs(): dood_date = pd.DatetimeIndex([dt.datetime(1900,1,1)]) #dummy value v0uf_allT = get_schureman_table() freqs_pd_schu = get_schureman_freqs(const_list=v0uf_allT.index.tolist(),dood_date=dood_date) - v_0i_rad_harmonic_pd = get_foreman_table() #list with only harmonic components with more precision than file - foreman_shallowrelations = get_foreman_shallowrelations() - const_list_foreman = v_0i_rad_harmonic_pd.index.tolist() + foreman_shallowrelations.index.tolist() + foreman_doodson_harmonic, foreman_nodal_harmonic = get_foreman_doodson_nodal_harmonic() + foreman_shallowrelations, list_shallowdependencies = get_foreman_shallowrelations() + const_list_foreman = foreman_doodson_harmonic.index.tolist() + foreman_shallowrelations.index.tolist() v0_pd_for,freqs_pd_for = get_foreman_v0_freq(const_list=const_list_foreman,dood_date=dood_date) #TODO: this is slower than schureman, cache it instead of this definition. But then first always retrieve everything (currently foreman only retrieves requested components) freqs_pd_combined = pd.concat([freqs_pd_schu[['freq']],freqs_pd_for],axis=0) @@ -259,9 +294,7 @@

Module hatyan.hatyan_core

def sort_const_list(const_list): - from hatyan.hatyan_core import full_const_list_withfreqs # local import necessary since it is a cached function - - full_const_list_withfreqs = full_const_list_withfreqs() + full_const_list_withfreqs = get_full_const_list_withfreqs() const_list_sorted = full_const_list_withfreqs.loc[const_list].sort_values('freq').index.tolist() return const_list_sorted @@ -456,6 +489,30 @@

Module hatyan.hatyan_core

Functions

+
+def check_requestedconsts(const_list_tuple, source) +
+
+
+
+ +Expand source code + +
@functools.lru_cache()
+def check_requestedconsts(const_list_tuple,source):
+    #TODO: move check to central location when part of hatyan_settings()?
+    if source=='schureman':
+        const_list_allforsource = get_schureman_table().index
+    elif source=='foreman':
+        foreman_doodson_harmonic, foreman_nodal_harmonic = get_foreman_doodson_nodal_harmonic()
+        foreman_shallowrelations, list_shallowdependencies = get_foreman_shallowrelations()
+        const_list_allforsource = pd.Series(foreman_doodson_harmonic.index.append(foreman_shallowrelations.index))
+    
+    bool_constavailable = pd.Series(const_list_tuple).isin(const_list_allforsource)   
+    if not bool_constavailable.all():
+        raise Exception(f'ERROR: not all requested components available in schureman harmonics or shallowrelations:\n{pd.Series(const_list_tuple).loc[~bool_constavailable]}')
+
+
def get_freqv0_generic(hatyan_settings, const_list, dood_date_mid, dood_date_start)
@@ -477,7 +534,7 @@

Functions

t_const_freq_pd = get_schureman_freqs(const_list, dood_date=dood_date_mid) v_0i_rad = get_schureman_v0(const_list, dood_date_start).T #at start of timeseries elif hatyan_settings.source=='foreman': #TODO: this is probably quite slow since foreman is not cached - dummy, t_const_freq_pd = get_foreman_v0_freq(const_list=const_list, dood_date=dood_date_mid) + dummy, t_const_freq_pd = get_foreman_v0_freq(const_list=const_list, dood_date=dood_date_mid) #TODO: does this really matter, maybe just retrieve on dood_date_start? Otherwise maybe split definition? v_0i_rad, dummy = get_foreman_v0_freq(const_list=const_list, dood_date=dood_date_start) v_0i_rad = v_0i_rad.T @@ -699,6 +756,8 @@

Returns

DESCRIPTION. """ + #TODO: check if this is still necessary in newer pandas versions + #TODO: merging with robust_daterange_fromtimesextfreq() possible? if refdate_dt is None: refdate_dt = dt.datetime(1900,1,1) @@ -713,8 +772,35 @@

Returns

return dood_tstart_sec, fancy_pddt -
-def full_const_list_withfreqs() +
+def get_lunarSLSIHO_fromsolar(v0uf_base) +
+
+
+
+ +Expand source code + +
def get_lunarSLSIHO_fromsolar(v0uf_base): #TODO: iets simpeler implementatie in foreman.get_foreman_doodson_nodal_harmonic(), maar dit is ook prima
+    
+    #conversion to lunar for comparison with SLS and IHO
+    v0uf_baseT_solar = v0uf_base.loc[['T','S','H','P','N','P1','EDN']].T
+    v0uf_baseT_lunar = v0uf_baseT_solar.copy()
+    v0uf_baseT_lunar['S'] = v0uf_baseT_solar['S'] + v0uf_baseT_solar['T'] #ib with relation ω1 =ω0 − ω2 +ω3 (stated in SLS book)
+    v0uf_baseT_lunar['H'] = v0uf_baseT_solar['H'] - v0uf_baseT_solar['T'] #ic with relation ω1 =ω0 − ω2 +ω3 (stated in SLS book)
+    #lunar IHO (compare to Sea Level Science book from Woodsworth and Pugh)
+    v0uf_baseT_lunar_SLS = v0uf_baseT_lunar.copy()
+    v0uf_baseT_lunar_SLS['EDN'] = -v0uf_baseT_lunar['EDN']%360 #klopt niet allemaal met tabel 4.1 uit SLS boek, moet dit wel?
+    #lunar IHO (compare to c
+    v0uf_baseT_lunar_IHO = v0uf_baseT_lunar.copy()
+    v0uf_baseT_lunar_IHO['EDN'] = -v0uf_baseT_lunar['EDN']/90 + 5 # (-90 lijkt 6 in IHO lijst, 90 is 4, 180 is 7)
+    v0uf_baseT_lunar_IHO.loc[v0uf_baseT_lunar_IHO['EDN']==3,'EDN'] = 7 # convert -180 (3) to +180 (7)
+    v0uf_baseT_lunar_IHO[['S','H','P','N','P1']] += 5
+    return v0uf_baseT_lunar, v0uf_baseT_lunar_SLS, v0uf_baseT_lunar_IHO
+
+
+
+def get_full_const_list_withfreqs()
@@ -722,17 +808,17 @@

Returns

Expand source code -
@functools.lru_cache() #TODO: get_foreman_v0_freq is way slower than get_schureman_freqs because it is live, therefore caching this entire function
-def full_const_list_withfreqs():
+
@functools.lru_cache() #TODO: get_foreman_v0_freq is way slower than get_schureman_freqs because it is live, therefore caching this entire function (can also cache hatyan.foreman.get_foreman_v0_freq() but then const_list should be a tuple instead of a list)
+def get_full_const_list_withfreqs():
 
     dood_date = pd.DatetimeIndex([dt.datetime(1900,1,1)]) #dummy value
     
     v0uf_allT = get_schureman_table()
     freqs_pd_schu = get_schureman_freqs(const_list=v0uf_allT.index.tolist(),dood_date=dood_date)
     
-    v_0i_rad_harmonic_pd = get_foreman_table() #list with only harmonic components with more precision than file
-    foreman_shallowrelations = get_foreman_shallowrelations()
-    const_list_foreman = v_0i_rad_harmonic_pd.index.tolist() + foreman_shallowrelations.index.tolist()
+    foreman_doodson_harmonic, foreman_nodal_harmonic = get_foreman_doodson_nodal_harmonic()
+    foreman_shallowrelations, list_shallowdependencies = get_foreman_shallowrelations()
+    const_list_foreman = foreman_doodson_harmonic.index.tolist() + foreman_shallowrelations.index.tolist()
     v0_pd_for,freqs_pd_for = get_foreman_v0_freq(const_list=const_list_foreman,dood_date=dood_date) #TODO: this is slower than schureman, cache it instead of this definition. But then first always retrieve everything (currently foreman only retrieves requested components)
     
     freqs_pd_combined = pd.concat([freqs_pd_schu[['freq']],freqs_pd_for],axis=0)
@@ -753,9 +839,7 @@ 

Returns

Expand source code
def sort_const_list(const_list):
-    from hatyan.hatyan_core import full_const_list_withfreqs # local import necessary since it is a cached function
-    
-    full_const_list_withfreqs = full_const_list_withfreqs()
+    full_const_list_withfreqs = get_full_const_list_withfreqs()
     const_list_sorted = full_const_list_withfreqs.loc[const_list].sort_values('freq').index.tolist()
     return const_list_sorted
@@ -995,12 +1079,14 @@

Index

  • Functions

    diff --git a/docs/hatyan/index.html b/docs/hatyan/index.html index 690a04cf..de6e97fb 100644 --- a/docs/hatyan/index.html +++ b/docs/hatyan/index.html @@ -128,7 +128,7 @@

    Getting Started

    __author__ = """Jelmer Veenstra""" __email__ = 'jelmer.veenstra@deltares.nl' -__version__ = '2.5.41' +__version__ = '2.5.42' from hatyan.analysis_prediction import * from hatyan.astrog import * diff --git a/docs/hatyan/schureman.html b/docs/hatyan/schureman.html index ba53c354..83056b92 100644 --- a/docs/hatyan/schureman.html +++ b/docs/hatyan/schureman.html @@ -75,53 +75,6 @@

    Module hatyan.schureman

    file_path = os.path.realpath(__file__) -def get_v0uf_sel(const_list): - """ - get_v0uf_sel - - Parameters - ---------- - const_list : TYPE - DESCRIPTION. - - Returns - ------- - v0uf_sel : TYPE - DESCRIPTION. - - """ - - v0uf_allT = get_schureman_table() - - const_list_pd = pd.Series(const_list,index=const_list) - const_list_avaibool = const_list_pd.isin(v0uf_allT.index) - - if not const_list_avaibool.all(): - const_list_notavailable = const_list_avaibool.loc[~const_list_avaibool] - raise Exception('ERROR: not all requested constituents are available:\n%s'%(const_list_notavailable)) - else: - v0uf_sel = v0uf_allT.loc[const_list] - - return v0uf_sel - - -def get_lunarSLSIHO_fromsolar(v0uf_base): - #conversion to lunar for comparison with SLS and IHO - v0uf_baseT_solar = v0uf_base.loc[['T','S','H','P','N','P1','EDN']].T - v0uf_baseT_lunar = v0uf_baseT_solar.copy() - v0uf_baseT_lunar['S'] = v0uf_baseT_solar['S'] + v0uf_baseT_solar['T'] #ib with relation ω1 =ω0 − ω2 +ω3 (stated in SLS book) - v0uf_baseT_lunar['H'] = v0uf_baseT_solar['H'] - v0uf_baseT_solar['T'] #ic with relation ω1 =ω0 − ω2 +ω3 (stated in SLS book) - #lunar IHO (compare to Sea Level Science book from Woodsworth and Pugh) - v0uf_baseT_lunar_SLS = v0uf_baseT_lunar.copy() - v0uf_baseT_lunar_SLS['EDN'] = -v0uf_baseT_lunar['EDN']%360 #klopt niet allemaal met tabel 4.1 uit SLS boek, moet dit wel? - #lunar IHO (compare to c - v0uf_baseT_lunar_IHO = v0uf_baseT_lunar.copy() - v0uf_baseT_lunar_IHO['EDN'] = -v0uf_baseT_lunar['EDN']/90 + 5 # (-90 lijkt 6 in IHO lijst, 90 is 4, 180 is 7) - v0uf_baseT_lunar_IHO.loc[v0uf_baseT_lunar_IHO['EDN']==3,'EDN'] = 7 # convert -180 (3) to +180 (7) - v0uf_baseT_lunar_IHO[['S','H','P','N','P1']] += 5 - return v0uf_baseT_lunar, v0uf_baseT_lunar_SLS, v0uf_baseT_lunar_IHO - - @functools.lru_cache() def get_schureman_table(): """ @@ -161,6 +114,7 @@

    Module hatyan.schureman

    v0uf_all.rename(columns=shallow_eqs_pd['shallow_const'],inplace=True) v0uf_allT = v0uf_all.T + #from hatyan.hatyan_core import get_lunarSLSIHO_fromsolar # local import since otherwise cross-dependency #v0uf_allT_lunar, v0uf_allT_lunar_SLS, v0uf_allT_lunar_IHO = get_lunarSLSIHO_fromsolar(v0uf_all) return v0uf_allT @@ -187,12 +141,15 @@

    Module hatyan.schureman

    """ - from hatyan.hatyan_core import get_doodson_eqvals # local import since otherwise cross-dependency - + from hatyan.hatyan_core import get_doodson_eqvals, check_requestedconsts # local import since otherwise cross-dependency + + check_requestedconsts(tuple(const_list),source='schureman') #TODO: move check to central location when part of hatyan_settings()? + doodson_pd = get_doodson_eqvals(dood_date=dood_date, mode='freq') #N is not used here multiply_variables = doodson_pd.loc[['T','S','H','P','P1'],:] - v0uf_sel = get_v0uf_sel(const_list=const_list) + v0uf_allT = get_schureman_table() + v0uf_sel = v0uf_allT.loc[const_list] v0uf_sel_freq = v0uf_sel[['T','S','H','P','P1']] DOMEGA_speed = np.dot(v0uf_sel_freq,multiply_variables) @@ -227,12 +184,15 @@

    Module hatyan.schureman

    """ - from hatyan.hatyan_core import get_doodson_eqvals # local import since otherwise cross-dependency + from hatyan.hatyan_core import get_doodson_eqvals, check_requestedconsts # local import since otherwise cross-dependency + + check_requestedconsts(tuple(const_list),source='schureman') #TODO: move check to central location when part of hatyan_settings()? doodson_pd = get_doodson_eqvals(dood_date=dood_date) #N is not used here multiply_variables = doodson_pd.loc[['T','S','H','P','P1'],:] - v0uf_sel = get_v0uf_sel(const_list=const_list) + v0uf_allT = get_schureman_table() + v0uf_sel = v0uf_allT.loc[const_list] DV0 = np.dot(v0uf_sel.loc[:,['T','S','H','P','P1']],multiply_variables) + np.deg2rad(v0uf_sel.loc[:,['EDN']]).values DV0_pd = pd.DataFrame(DV0,index=const_list) @@ -262,7 +222,8 @@

    Module hatyan.schureman

    DESCRIPTION. """ - + + #TODO: robust_timedelta_sec might also be necesary in other definitions, but is not there yet. Align? (also check if newer pandas version do not have this problem anymore) from hatyan.hatyan_core import robust_timedelta_sec # local import since otherwise cross-dependency #bercon.f: HET BEREKENEN VAN DE 'CONSTANTEN' .0365, .1681 EN .5023, DIE GEBRUIKT WORDEN BIJ DE BEREKENING VAN DE U- EN F-FACTOREN VAN DE GETIJCOMPONENTEN K1 EN K2 @@ -312,7 +273,9 @@

    Module hatyan.schureman

    """ - from hatyan.hatyan_core import get_doodson_eqvals # local import since otherwise cross-dependency + from hatyan.hatyan_core import get_doodson_eqvals, check_requestedconsts # local import since otherwise cross-dependency + + check_requestedconsts(tuple(const_list),source='schureman') #TODO: move check to central location when part of hatyan_settings()? doodson_pd = get_doodson_eqvals(dood_date=dood_date) N_rad = doodson_pd.loc['N',:].values @@ -346,7 +309,8 @@

    Module hatyan.schureman

    DUK2 = -D2NU2A multiply_variables = np.stack([DKSI, DNU, DQ, DQU, DR, DUK1, DUK2]) - v0uf_sel = get_v0uf_sel(const_list=const_list) + v0uf_allT = get_schureman_table() + v0uf_sel = v0uf_allT.loc[const_list] v0uf_sel_u = v0uf_sel[['DKSI','DNU', 'DQ', 'DQU', 'DR', 'DUK1', 'DUK2']] DU = np.dot(v0uf_sel_u.values,multiply_variables) @@ -376,7 +340,9 @@

    Module hatyan.schureman

    """ - from hatyan.hatyan_core import get_doodson_eqvals # local import since otherwise cross-dependency + from hatyan.hatyan_core import get_doodson_eqvals, check_requestedconsts # local import since otherwise cross-dependency + + check_requestedconsts(tuple(const_list),source='schureman') #TODO: move check to central location when part of hatyan_settings()? doodson_pd = get_doodson_eqvals(dood_date=dood_date) N_rad = doodson_pd.loc['N',:].values @@ -437,14 +403,15 @@

    Module hatyan.schureman

    multiply_variables = np.stack([DND73,DND74,DND75,DND76,DND77,DND78,DND79,DFM1,DFK1,DFL2,DFK2,DFM1C]) sel_cols = ['DND73','DND74','DND75','DND76','DND77','DND78','DND79','DFM1','DFK1','DFL2','DFK2','DFM1C'] - v0uf_sel = get_v0uf_sel(const_list=const_list) + v0uf_allT = get_schureman_table() + v0uf_sel = v0uf_allT.loc[const_list] f_i = np.ones(shape=(len(const_list), len(dood_date))) for variable, colname in zip(multiply_variables, sel_cols): #this loop is faster than array multiplications, since it only calculates the necessary factors (saves a lot of overhead) power = v0uf_sel[colname].values idnozero = power!=0 f_i[idnozero,:] *= variable**power[idnozero][np.newaxis].T - v0uf_M2 = get_v0uf_sel(const_list=['M2']) + v0uf_M2 = v0uf_allT.loc[['M2']] f_i_M2 = np.ones(shape=(len(['M2']), len(dood_date))) for variable, colname in zip(multiply_variables, sel_cols): power = v0uf_M2[colname].values @@ -514,81 +481,6 @@

    Module hatyan.schureman

    Functions

    -
    -def get_v0uf_sel(const_list) -
    -
    -

    get_v0uf_sel

    -

    Parameters

    -
    -
    const_list : TYPE
    -
    DESCRIPTION.
    -
    -

    Returns

    -
    -
    v0uf_sel : TYPE
    -
    DESCRIPTION.
    -
    -
    - -Expand source code - -
    def get_v0uf_sel(const_list):
    -    """
    -    get_v0uf_sel
    -
    -    Parameters
    -    ----------
    -    const_list : TYPE
    -        DESCRIPTION.
    -    
    -    Returns
    -    -------
    -    v0uf_sel : TYPE
    -        DESCRIPTION.
    -
    -    """
    -    
    -    v0uf_allT = get_schureman_table()
    -    
    -    const_list_pd = pd.Series(const_list,index=const_list)
    -    const_list_avaibool = const_list_pd.isin(v0uf_allT.index)
    -    
    -    if not const_list_avaibool.all():
    -        const_list_notavailable = const_list_avaibool.loc[~const_list_avaibool]
    -        raise Exception('ERROR: not all requested constituents are available:\n%s'%(const_list_notavailable))
    -    else:
    -        v0uf_sel = v0uf_allT.loc[const_list]
    -    
    -    return v0uf_sel
    -
    -
    -
    -def get_lunarSLSIHO_fromsolar(v0uf_base) -
    -
    -
    -
    - -Expand source code - -
    def get_lunarSLSIHO_fromsolar(v0uf_base):
    -    #conversion to lunar for comparison with SLS and IHO
    -    v0uf_baseT_solar = v0uf_base.loc[['T','S','H','P','N','P1','EDN']].T
    -    v0uf_baseT_lunar = v0uf_baseT_solar.copy()
    -    v0uf_baseT_lunar['S'] = v0uf_baseT_solar['S'] + v0uf_baseT_solar['T'] #ib with relation ω1 =ω0 − ω2 +ω3 (stated in SLS book)
    -    v0uf_baseT_lunar['H'] = v0uf_baseT_solar['H'] - v0uf_baseT_solar['T'] #ic with relation ω1 =ω0 − ω2 +ω3 (stated in SLS book)
    -    #lunar IHO (compare to Sea Level Science book from Woodsworth and Pugh)
    -    v0uf_baseT_lunar_SLS = v0uf_baseT_lunar.copy()
    -    v0uf_baseT_lunar_SLS['EDN'] = -v0uf_baseT_lunar['EDN']%360 #klopt niet allemaal met tabel 4.1 uit SLS boek, moet dit wel?
    -    #lunar IHO (compare to c
    -    v0uf_baseT_lunar_IHO = v0uf_baseT_lunar.copy()
    -    v0uf_baseT_lunar_IHO['EDN'] = -v0uf_baseT_lunar['EDN']/90 + 5 # (-90 lijkt 6 in IHO lijst, 90 is 4, 180 is 7)
    -    v0uf_baseT_lunar_IHO.loc[v0uf_baseT_lunar_IHO['EDN']==3,'EDN'] = 7 # convert -180 (3) to +180 (7)
    -    v0uf_baseT_lunar_IHO[['S','H','P','N','P1']] += 5
    -    return v0uf_baseT_lunar, v0uf_baseT_lunar_SLS, v0uf_baseT_lunar_IHO
    -
    -
    def get_schureman_table()
    @@ -642,6 +534,7 @@

    Returns

    v0uf_all.rename(columns=shallow_eqs_pd['shallow_const'],inplace=True) v0uf_allT = v0uf_all.T + #from hatyan.hatyan_core import get_lunarSLSIHO_fromsolar # local import since otherwise cross-dependency #v0uf_allT_lunar, v0uf_allT_lunar_SLS, v0uf_allT_lunar_IHO = get_lunarSLSIHO_fromsolar(v0uf_all) return v0uf_allT
  • @@ -692,12 +585,15 @@

    Returns

    """ - from hatyan.hatyan_core import get_doodson_eqvals # local import since otherwise cross-dependency - + from hatyan.hatyan_core import get_doodson_eqvals, check_requestedconsts # local import since otherwise cross-dependency + + check_requestedconsts(tuple(const_list),source='schureman') #TODO: move check to central location when part of hatyan_settings()? + doodson_pd = get_doodson_eqvals(dood_date=dood_date, mode='freq') #N is not used here multiply_variables = doodson_pd.loc[['T','S','H','P','P1'],:] - v0uf_sel = get_v0uf_sel(const_list=const_list) + v0uf_allT = get_schureman_table() + v0uf_sel = v0uf_allT.loc[const_list] v0uf_sel_freq = v0uf_sel[['T','S','H','P','P1']] DOMEGA_speed = np.dot(v0uf_sel_freq,multiply_variables) @@ -753,12 +649,15 @@

    Returns

    """ - from hatyan.hatyan_core import get_doodson_eqvals # local import since otherwise cross-dependency + from hatyan.hatyan_core import get_doodson_eqvals, check_requestedconsts # local import since otherwise cross-dependency + + check_requestedconsts(tuple(const_list),source='schureman') #TODO: move check to central location when part of hatyan_settings()? doodson_pd = get_doodson_eqvals(dood_date=dood_date) #N is not used here multiply_variables = doodson_pd.loc[['T','S','H','P','P1'],:] - v0uf_sel = get_v0uf_sel(const_list=const_list) + v0uf_allT = get_schureman_table() + v0uf_sel = v0uf_allT.loc[const_list] DV0 = np.dot(v0uf_sel.loc[:,['T','S','H','P','P1']],multiply_variables) + np.deg2rad(v0uf_sel.loc[:,['EDN']]).values DV0_pd = pd.DataFrame(DV0,index=const_list) @@ -815,7 +714,8 @@

    Returns

    DESCRIPTION. """ - + + #TODO: robust_timedelta_sec might also be necesary in other definitions, but is not there yet. Align? (also check if newer pandas version do not have this problem anymore) from hatyan.hatyan_core import robust_timedelta_sec # local import since otherwise cross-dependency #bercon.f: HET BEREKENEN VAN DE 'CONSTANTEN' .0365, .1681 EN .5023, DIE GEBRUIKT WORDEN BIJ DE BEREKENING VAN DE U- EN F-FACTOREN VAN DE GETIJCOMPONENTEN K1 EN K2 @@ -886,7 +786,9 @@

    Returns

    """ - from hatyan.hatyan_core import get_doodson_eqvals # local import since otherwise cross-dependency + from hatyan.hatyan_core import get_doodson_eqvals, check_requestedconsts # local import since otherwise cross-dependency + + check_requestedconsts(tuple(const_list),source='schureman') #TODO: move check to central location when part of hatyan_settings()? doodson_pd = get_doodson_eqvals(dood_date=dood_date) N_rad = doodson_pd.loc['N',:].values @@ -920,7 +822,8 @@

    Returns

    DUK2 = -D2NU2A multiply_variables = np.stack([DKSI, DNU, DQ, DQU, DR, DUK1, DUK2]) - v0uf_sel = get_v0uf_sel(const_list=const_list) + v0uf_allT = get_schureman_table() + v0uf_sel = v0uf_allT.loc[const_list] v0uf_sel_u = v0uf_sel[['DKSI','DNU', 'DQ', 'DQU', 'DR', 'DUK1', 'DUK2']] DU = np.dot(v0uf_sel_u.values,multiply_variables) @@ -971,7 +874,9 @@

    Returns

    """ - from hatyan.hatyan_core import get_doodson_eqvals # local import since otherwise cross-dependency + from hatyan.hatyan_core import get_doodson_eqvals, check_requestedconsts # local import since otherwise cross-dependency + + check_requestedconsts(tuple(const_list),source='schureman') #TODO: move check to central location when part of hatyan_settings()? doodson_pd = get_doodson_eqvals(dood_date=dood_date) N_rad = doodson_pd.loc['N',:].values @@ -1032,14 +937,15 @@

    Returns

    multiply_variables = np.stack([DND73,DND74,DND75,DND76,DND77,DND78,DND79,DFM1,DFK1,DFL2,DFK2,DFM1C]) sel_cols = ['DND73','DND74','DND75','DND76','DND77','DND78','DND79','DFM1','DFK1','DFL2','DFK2','DFM1C'] - v0uf_sel = get_v0uf_sel(const_list=const_list) + v0uf_allT = get_schureman_table() + v0uf_sel = v0uf_allT.loc[const_list] f_i = np.ones(shape=(len(const_list), len(dood_date))) for variable, colname in zip(multiply_variables, sel_cols): #this loop is faster than array multiplications, since it only calculates the necessary factors (saves a lot of overhead) power = v0uf_sel[colname].values idnozero = power!=0 f_i[idnozero,:] *= variable**power[idnozero][np.newaxis].T - v0uf_M2 = get_v0uf_sel(const_list=['M2']) + v0uf_M2 = v0uf_allT.loc[['M2']] f_i_M2 = np.ones(shape=(len(['M2']), len(dood_date))) for variable, colname in zip(multiply_variables, sel_cols): power = v0uf_M2[colname].values @@ -1141,8 +1047,6 @@

    Index

  • Functions