bulum 0.3.3.dev1__py3-none-any.whl → 0.3.4.dev1__py3-none-any.whl

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.
Files changed (65) hide show
  1. bulum/__init__.py +2 -2
  2. bulum/clim/__init__.py +1 -1
  3. bulum/clim/clim.py +148 -148
  4. bulum/clim/tests/test_clim.py +71 -71
  5. bulum/demo.py +5 -5
  6. bulum/io/__init__.py +6 -6
  7. bulum/io/csv_io.py +94 -94
  8. bulum/io/general_io.py +55 -55
  9. bulum/io/idx_io.py +341 -341
  10. bulum/io/iqqm_out_reader.py +367 -367
  11. bulum/io/lqn_io.py +75 -75
  12. bulum/io/res_csv_io.py +203 -203
  13. bulum/io/tests/test_csv_io.py +55 -55
  14. bulum/io/tests/test_general_io.py +22 -22
  15. bulum/io/tests/test_idx_io.py +112 -112
  16. bulum/io/tests/test_iqqm_out_reader.py +48 -48
  17. bulum/io/tests/test_lqn_io.py +52 -52
  18. bulum/io/tests/test_res_csv_io.py +60 -60
  19. bulum/maps/__init__.py +1 -1
  20. bulum/maps/station_maps.py +136 -136
  21. bulum/plots/__init__.py +4 -4
  22. bulum/plots/altair_plots.py +850 -850
  23. bulum/plots/ensemble_altair_plots.py +104 -104
  24. bulum/plots/node_diagrams.py +10 -10
  25. bulum/plots/plot_functions.py +106 -106
  26. bulum/plots/tests/__init__.py +1 -1
  27. bulum/plots/tests/test_plot_functions.py +222 -222
  28. bulum/stats/__init__.py +6 -6
  29. bulum/stats/aggregate_stats.py +196 -196
  30. bulum/stats/ensemble_stats.py +140 -140
  31. bulum/stats/negflo.py +783 -783
  32. bulum/stats/qastat2s/__init__.py +30 -0
  33. bulum/stats/qastat2s/reportcard_data.py +828 -0
  34. bulum/stats/qastat2s/reportcard_plot.py +774 -0
  35. bulum/stats/qastat2s/tests/test_qastat2s.py +112 -0
  36. bulum/stats/reliability_stats_class.py +282 -282
  37. bulum/stats/stochastic_data_check.py +541 -541
  38. bulum/stats/storage_level_assessment.py +838 -838
  39. bulum/stats/swflo2s/swflo2s.py +163 -163
  40. bulum/stats/swflo2s/tests/test_swflo2s.py +58 -58
  41. bulum/stats/tests/test_negflo.py +359 -359
  42. bulum/stats/tests/test_stats.py +365 -365
  43. bulum/stats/tests/test_storage_level_assessment.py +749 -749
  44. bulum/stoch/generate.py +91 -91
  45. bulum/stoch/tests/test_stoch.py +13 -13
  46. bulum/test_circular_import.py +26 -26
  47. bulum/trans/tests/test_trans.py +20 -20
  48. bulum/trans/transformers.py +100 -100
  49. bulum/utils/__init__.py +16 -16
  50. bulum/utils/dataframe_extensions.py +1224 -1224
  51. bulum/utils/dataframe_functions.py +399 -399
  52. bulum/utils/datetime_functions.py +790 -790
  53. bulum/utils/interpolation.py +62 -62
  54. bulum/utils/tests/test_ensembles.py +710 -710
  55. bulum/utils/tests/test_interpolation.py +87 -87
  56. bulum/utils/tests/test_parametrized.py +218 -218
  57. bulum/utils/tests/test_tsdf.py +540 -540
  58. bulum/utils/tests/test_utils.py +701 -701
  59. bulum/version.py +5 -5
  60. {bulum-0.3.3.dev1.dist-info → bulum-0.3.4.dev1.dist-info}/METADATA +139 -139
  61. bulum-0.3.4.dev1.dist-info/RECORD +69 -0
  62. {bulum-0.3.3.dev1.dist-info → bulum-0.3.4.dev1.dist-info}/licenses/LICENSE.md +595 -595
  63. bulum-0.3.3.dev1.dist-info/RECORD +0 -65
  64. {bulum-0.3.3.dev1.dist-info → bulum-0.3.4.dev1.dist-info}/WHEEL +0 -0
  65. {bulum-0.3.3.dev1.dist-info → bulum-0.3.4.dev1.dist-info}/top_level.txt +0 -0
bulum/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
- from .version import __version__
2
- from .demo import *
1
+ from .version import __version__
2
+ from .demo import *
3
3
  #from .stoch import *
bulum/clim/__init__.py CHANGED
@@ -1 +1 @@
1
- from .clim import *
1
+ from .clim import *
bulum/clim/clim.py CHANGED
@@ -1,148 +1,148 @@
1
- import numpy as np
2
- import pandas as pd
3
-
4
-
5
- def derive_transformation_curves(original_ts: pd.Series, augmented_ts: pd.Series, season_start_months=[1,2,3,4,5,6,7,8,9,10,11,12], epsilon=1e-3) -> dict:
6
- """Returns a dictionary of exceedence-based transformation curves - one for
7
- each season with the season's start month as the key. These are tables that
8
- map from exceedance (cunnane plotting position as a fraction) to a scaling
9
- factor. These are intended to be used to effectively summarise
10
- climate-change adjustments, and allow them to be transported from one
11
- timeseries to another.
12
-
13
- Parameters
14
- ----------
15
- original_ts : pd.Series
16
- augmented_ts : pd.Series
17
- season_start_months : list, optional
18
- Defaults to [1,2,3,4,5,6,7,8,9,10,11,12].
19
-
20
- """
21
- df = pd.DataFrame()
22
- df["x"] = original_ts
23
- df["y"] = augmented_ts
24
- df = df.dropna() # Force common period
25
- answer = {}
26
- for i in range(len(season_start_months)):
27
- # Get a list of the months in this season
28
- start_month = season_start_months[i]
29
- season_len = (season_start_months + [m + 12 for m in season_start_months])[i + 1] - start_month
30
- months_in_this_season = [1,2,3,4,5,6,7,8,9,10,11,12,1,2,3,4,5,6,7,8,9,10,11,12][start_month - 1: start_month - 1 + season_len]
31
- # Find the data for this season
32
- df_m = df[[int(d[5:7]) in months_in_this_season for d in df.index]] #d[5:7] is the month part of the date string
33
- x = np.sort(df_m.x.values)
34
- y = np.sort(df_m.y.values)
35
- # The transformation factor is y/x except when the original value x is zero (<epsilon) in which case we default to 1.0
36
- f = np.where(x < epsilon, 1.0, y / x)
37
- n = len(x)
38
- ii = [i + 1 for i in range(n)] #index starting at 1
39
- p = [(i - 0.4)/(n + 0.2) for i in ii]
40
- answer[start_month] = [p,f]
41
- return answer
42
-
43
-
44
- def apply_transformation_curves(tranformation_curves: dict, series: pd.Series) -> pd.Series:
45
- """Applies seasonal transformation curves to an input series.
46
- Refer to the function `derive_transformation_curves`.
47
-
48
- Parameters
49
- ----------
50
- tranformation_curves : dict
51
- series : pd.Series
52
-
53
- Returns
54
- -------
55
- pd.Series
56
- """
57
- dates = series.index
58
- answer = series.copy()
59
- # Apply each transformation curves to the whole series. Splice the appropriate
60
- # parts (seasons) into the 'answer' series as we go.
61
- season_start_months = sorted(tranformation_curves.keys())
62
- for i in range(len(season_start_months)):
63
- # Identify the transform curve for this season
64
- start_month = season_start_months[i]
65
- t = tranformation_curves[start_month]
66
- xp = t[0]
67
- fp = t[1]
68
- # Get a list of the months in this season
69
- season_len = (season_start_months + [m + 12 for m in season_start_months])[i + 1] - start_month
70
- months_in_this_season = [1,2,3,4,5,6,7,8,9,10,11,12,1,2,3,4,5,6,7,8,9,10,11,12][start_month - 1: start_month - 1 + season_len]
71
- # Find the data for this season
72
- m = len(series)
73
- season_dates = pd.Series([d for d in dates if int(d[5:7]) in months_in_this_season]) #d[5:7] is the month part of the date string
74
- values = answer[season_dates]
75
- # And get their ranks and plotting positions
76
- rank_starting_at_one = values.rank(ascending=True) # This function is nice because equal values are assigned the same (averaged) rank.
77
- n = len(values)
78
- p = [(r - 0.4)/(n + 0.2) for r in rank_starting_at_one] # Cunnane plotting position
79
- f = np.interp(p, xp, fp) # interpolated scaling factors
80
- # Calcualte new values and update the answer
81
- new_values = pd.Series([values.iloc[i] * f[i] for i in range(n)], index=season_dates)
82
- answer.update(new_values)
83
- # Return a pd.Series so user can easily join it back into a dataframe
84
- return pd.Series(answer, index=dates, name=series.name)
85
-
86
-
87
- def derive_transformation_factors(original_ts: pd.Series, augmented_ts: pd.Series, season_start_months=[1,2,3,4,5,6,7,8,9,10,11,12], epsilon=1e-3) -> dict:
88
- """Returns a dictionary of transformation factors - one for each season
89
- with the season's start month as the key. These scaling factors are intended to
90
- be used to effectively summarise climate-change adjustments, and allow them to be
91
- transported from one timeseries to another.
92
-
93
- Parameters
94
- ----------
95
- original_ts : pd.Series
96
- augmented_ts : pd.Series
97
- season_start_months : list, optional
98
- [1,2,3,4,5,6,7,8,9,10,11,12].
99
- epsilon : float
100
- Threshold below which values are treated as zero, and the associated factor defaults to 1.
101
-
102
- """
103
- # Create a map of month -> season_start_month (for all months)
104
- month_to_season_map = {}
105
- key = max(season_start_months)
106
- for m in [1,2,3,4,5,6,7,8,9,10,11,12]:
107
- if m in season_start_months:
108
- key = m
109
- month_to_season_map[m] = key
110
- # Put the data in a dataframe, and groupby season start month
111
- df = pd.DataFrame()
112
- df["x"] = original_ts
113
- df["y"] = augmented_ts
114
- df = df.dropna() # Force common period
115
- df['m'] = df.index.month
116
- df['s'] = df['m'].map(month_to_season_map)
117
- df2 = df.groupby('s').agg('sum')
118
- df2['f'] = np.where(df2.x < epsilon, 1.0, df2.y / df2.x)
119
- return df2['f'].to_dict()
120
-
121
-
122
- def apply_transformation_factors(transformation_factors: dict, series: pd.Series) -> pd.Series:
123
- """Applies seasonal transformation factors to an input series.
124
- Refer to the function `derive_transformation_curves`.
125
-
126
- Parameters
127
- ----------
128
- transformation_curves : dict
129
- series : pd.Series
130
-
131
- """
132
- # Create a map of month -> factor (containing all months)
133
- season_start_months = sorted(transformation_factors.keys())
134
- month_to_factor_map = {}
135
- key = max(season_start_months)
136
- for m in [1,2,3,4,5,6,7,8,9,10,11,12]:
137
- if m in season_start_months:
138
- key = m
139
- month_to_factor_map[m] = transformation_factors[key]
140
- # Apply transformation factors to the whole series. Splice the appropriate
141
- df = pd.DataFrame()
142
- df['x'] = series
143
- df['m'] = df.index.month
144
- df['f'] = df['m'].map(month_to_factor_map)
145
- df['y'] = df['x'] * df['f']
146
- answer = df['y']
147
- answer.name = series.name
148
- return answer
1
+ import numpy as np
2
+ import pandas as pd
3
+
4
+
5
+ def derive_transformation_curves(original_ts: pd.Series, augmented_ts: pd.Series, season_start_months=[1,2,3,4,5,6,7,8,9,10,11,12], epsilon=1e-3) -> dict:
6
+ """Returns a dictionary of exceedence-based transformation curves - one for
7
+ each season with the season's start month as the key. These are tables that
8
+ map from exceedance (cunnane plotting position as a fraction) to a scaling
9
+ factor. These are intended to be used to effectively summarise
10
+ climate-change adjustments, and allow them to be transported from one
11
+ timeseries to another.
12
+
13
+ Parameters
14
+ ----------
15
+ original_ts : pd.Series
16
+ augmented_ts : pd.Series
17
+ season_start_months : list, optional
18
+ Defaults to [1,2,3,4,5,6,7,8,9,10,11,12].
19
+
20
+ """
21
+ df = pd.DataFrame()
22
+ df["x"] = original_ts
23
+ df["y"] = augmented_ts
24
+ df = df.dropna() # Force common period
25
+ answer = {}
26
+ for i in range(len(season_start_months)):
27
+ # Get a list of the months in this season
28
+ start_month = season_start_months[i]
29
+ season_len = (season_start_months + [m + 12 for m in season_start_months])[i + 1] - start_month
30
+ months_in_this_season = [1,2,3,4,5,6,7,8,9,10,11,12,1,2,3,4,5,6,7,8,9,10,11,12][start_month - 1: start_month - 1 + season_len]
31
+ # Find the data for this season
32
+ df_m = df[[int(d[5:7]) in months_in_this_season for d in df.index]] #d[5:7] is the month part of the date string
33
+ x = np.sort(df_m.x.values)
34
+ y = np.sort(df_m.y.values)
35
+ # The transformation factor is y/x except when the original value x is zero (<epsilon) in which case we default to 1.0
36
+ f = np.where(x < epsilon, 1.0, y / x)
37
+ n = len(x)
38
+ ii = [i + 1 for i in range(n)] #index starting at 1
39
+ p = [(i - 0.4)/(n + 0.2) for i in ii]
40
+ answer[start_month] = [p,f]
41
+ return answer
42
+
43
+
44
+ def apply_transformation_curves(tranformation_curves: dict, series: pd.Series) -> pd.Series:
45
+ """Applies seasonal transformation curves to an input series.
46
+ Refer to the function `derive_transformation_curves`.
47
+
48
+ Parameters
49
+ ----------
50
+ tranformation_curves : dict
51
+ series : pd.Series
52
+
53
+ Returns
54
+ -------
55
+ pd.Series
56
+ """
57
+ dates = series.index
58
+ answer = series.copy()
59
+ # Apply each transformation curves to the whole series. Splice the appropriate
60
+ # parts (seasons) into the 'answer' series as we go.
61
+ season_start_months = sorted(tranformation_curves.keys())
62
+ for i in range(len(season_start_months)):
63
+ # Identify the transform curve for this season
64
+ start_month = season_start_months[i]
65
+ t = tranformation_curves[start_month]
66
+ xp = t[0]
67
+ fp = t[1]
68
+ # Get a list of the months in this season
69
+ season_len = (season_start_months + [m + 12 for m in season_start_months])[i + 1] - start_month
70
+ months_in_this_season = [1,2,3,4,5,6,7,8,9,10,11,12,1,2,3,4,5,6,7,8,9,10,11,12][start_month - 1: start_month - 1 + season_len]
71
+ # Find the data for this season
72
+ m = len(series)
73
+ season_dates = pd.Series([d for d in dates if int(d[5:7]) in months_in_this_season]) #d[5:7] is the month part of the date string
74
+ values = answer[season_dates]
75
+ # And get their ranks and plotting positions
76
+ rank_starting_at_one = values.rank(ascending=True) # This function is nice because equal values are assigned the same (averaged) rank.
77
+ n = len(values)
78
+ p = [(r - 0.4)/(n + 0.2) for r in rank_starting_at_one] # Cunnane plotting position
79
+ f = np.interp(p, xp, fp) # interpolated scaling factors
80
+ # Calcualte new values and update the answer
81
+ new_values = pd.Series([values.iloc[i] * f[i] for i in range(n)], index=season_dates)
82
+ answer.update(new_values)
83
+ # Return a pd.Series so user can easily join it back into a dataframe
84
+ return pd.Series(answer, index=dates, name=series.name)
85
+
86
+
87
+ def derive_transformation_factors(original_ts: pd.Series, augmented_ts: pd.Series, season_start_months=[1,2,3,4,5,6,7,8,9,10,11,12], epsilon=1e-3) -> dict:
88
+ """Returns a dictionary of transformation factors - one for each season
89
+ with the season's start month as the key. These scaling factors are intended to
90
+ be used to effectively summarise climate-change adjustments, and allow them to be
91
+ transported from one timeseries to another.
92
+
93
+ Parameters
94
+ ----------
95
+ original_ts : pd.Series
96
+ augmented_ts : pd.Series
97
+ season_start_months : list, optional
98
+ [1,2,3,4,5,6,7,8,9,10,11,12].
99
+ epsilon : float
100
+ Threshold below which values are treated as zero, and the associated factor defaults to 1.
101
+
102
+ """
103
+ # Create a map of month -> season_start_month (for all months)
104
+ month_to_season_map = {}
105
+ key = max(season_start_months)
106
+ for m in [1,2,3,4,5,6,7,8,9,10,11,12]:
107
+ if m in season_start_months:
108
+ key = m
109
+ month_to_season_map[m] = key
110
+ # Put the data in a dataframe, and groupby season start month
111
+ df = pd.DataFrame()
112
+ df["x"] = original_ts
113
+ df["y"] = augmented_ts
114
+ df = df.dropna() # Force common period
115
+ df['m'] = df.index.month
116
+ df['s'] = df['m'].map(month_to_season_map)
117
+ df2 = df.groupby('s').agg('sum')
118
+ df2['f'] = np.where(df2.x < epsilon, 1.0, df2.y / df2.x)
119
+ return df2['f'].to_dict()
120
+
121
+
122
+ def apply_transformation_factors(transformation_factors: dict, series: pd.Series) -> pd.Series:
123
+ """Applies seasonal transformation factors to an input series.
124
+ Refer to the function `derive_transformation_curves`.
125
+
126
+ Parameters
127
+ ----------
128
+ transformation_curves : dict
129
+ series : pd.Series
130
+
131
+ """
132
+ # Create a map of month -> factor (containing all months)
133
+ season_start_months = sorted(transformation_factors.keys())
134
+ month_to_factor_map = {}
135
+ key = max(season_start_months)
136
+ for m in [1,2,3,4,5,6,7,8,9,10,11,12]:
137
+ if m in season_start_months:
138
+ key = m
139
+ month_to_factor_map[m] = transformation_factors[key]
140
+ # Apply transformation factors to the whole series. Splice the appropriate
141
+ df = pd.DataFrame()
142
+ df['x'] = series
143
+ df['m'] = df.index.month
144
+ df['f'] = df['m'].map(month_to_factor_map)
145
+ df['y'] = df['x'] * df['f']
146
+ answer = df['y']
147
+ answer.name = series.name
148
+ return answer
@@ -1,71 +1,71 @@
1
- import unittest
2
- import os
3
- import bulum.io as bio
4
- import bulum.clim as ocl
5
- import bulum.utils as out
6
- import pandas as pd
7
-
8
-
9
- class Tests(unittest.TestCase):
10
-
11
- @classmethod
12
- def setUpClass(cls):
13
- os.makedirs("./trash", exist_ok=True)
14
- return super().setUpClass()
15
-
16
- def test_load_data_into_df(self):
17
- """
18
- The purpose of this is just to test that if I load 2 different files as
19
- dataframes, and then simply put them together. I.e. does it join on the
20
- dates? YES IT APPEARS TO LEFT-JOIN on the dates from the first file.
21
- """
22
- df1 = bio.read_ts_csv("./src/bulum/clim/tests/Flow.out.withmissing.csv", date_format=r"%Y-%m-%d")["FRex_FR.qqm"]
23
- df2 = bio.read_ts_csv("./src/bulum/clim/tests/Flow.out.RCP85_P2050_GCM8.csv", date_format=r"%Y-%m-%d")["FRex_FR.qqm"]
24
- df3 = pd.DataFrame()
25
- df3["x"] = df1
26
- df3["y"] = df2
27
- # print(df3.head())
28
- # print(df3.tail())
29
- self.assertTrue(len(df3) == len(df1))
30
- self.assertAlmostEqual(df3.x.values[-1], 136) # these values should line up despite different starting dates for each file
31
- self.assertAlmostEqual(df3.y.values[-1], 62) # these values should line up despite different starting dates for each file
32
- # And now doe the same again with files loaded in the opposite order
33
- df1 = bio.read_ts_csv("./src/bulum/clim/tests/Flow.out.RCP85_P2050_GCM8.csv", date_format=r"%Y-%m-%d")["FRex_FR.qqm"]
34
- df2 = bio.read_ts_csv("./src/bulum/clim/tests/Flow.out.withmissing.csv", date_format=r"%Y-%m-%d")["FRex_FR.qqm"]
35
- df3 = pd.DataFrame()
36
- df3["x"] = df1
37
- df3["y"] = df2
38
- # print(df3.head())
39
- # print(df3.tail())
40
- self.assertTrue(len(df3) == len(df1))
41
- self.assertAlmostEqual(df3.x.values[-1], 62) # these values should line up despite different starting dates for each file
42
- self.assertAlmostEqual(df3.y.values[-1], 136) # these values should line up despite different starting dates for each file
43
-
44
- def test_get_exc_transform(self):
45
- """
46
- This gets transformation curves based on current & future climate datasets, and then checks that the transformation
47
- curves have the same total number of points regardless of whether we use default seasons (monthly) or define 3 custom
48
- seasons.
49
- """
50
- current_climate = bio.read_ts_csv("./src/bulum/clim/tests/Flow.out.withmissing.csv", date_format=r"%Y-%m-%d")
51
- future_climate = bio.read_ts_csv("./src/bulum/clim/tests/Flow.out.RCP85_P2050_GCM8.csv", date_format=r"%Y-%m-%d")
52
- answer1 = ocl.derive_transformation_curves(current_climate["FRex_FR.qqm"], future_climate["FRex_FR.qqm"])
53
- answer2 = ocl.derive_transformation_curves(current_climate["FRex_FR.qqm"], future_climate["FRex_FR.qqm"], season_start_months=[3, 7, 9])
54
- total_len_1 = sum([len(a[1]) for a in answer1.values()])
55
- total_len_2 = sum([len(a[1]) for a in answer2.values()])
56
- self.assertEqual(total_len_1, total_len_2)
57
- self.assertTrue(total_len_1 > 0)
58
-
59
- def test_apply_transformation_curves(self):
60
- current_climate = bio.read_ts_csv("./src/bulum/clim/tests/Flow.out.withmissing.csv", date_format=r"%Y-%m-%d")
61
- future_climate = bio.read_ts_csv("./src/bulum/clim/tests/Flow.out.RCP85_P2050_GCM8.csv", date_format=r"%Y-%m-%d")
62
- t = ocl.derive_transformation_curves(current_climate["FRex_FR.qqm"], future_climate["FRex_FR.qqm"])
63
- answer = pd.DataFrame()
64
- answer["RexCurrent"] = current_climate["FRex_FR.qqm"]
65
- answer["RexCurrent"] = future_climate["FRex_FR.qqm"]
66
- answer["Transf"] = ocl.apply_transformation_curves(t, current_climate["FRex_FR.qqm"])
67
- # print(answer["Current"].sum())
68
- # print(answer["Future"].sum())
69
- # print(answer["Transf"].sum())
70
- self.assertAlmostEqual(answer["Transf"].sum(), 4845710.795475168) # Actually haven't checked that this is the correct answer but looks plausible.
71
- answer.to_csv("./trash/transformed.csv")
1
+ import unittest
2
+ import os
3
+ import bulum.io as bio
4
+ import bulum.clim as ocl
5
+ import bulum.utils as out
6
+ import pandas as pd
7
+
8
+
9
+ class Tests(unittest.TestCase):
10
+
11
+ @classmethod
12
+ def setUpClass(cls):
13
+ os.makedirs("./trash", exist_ok=True)
14
+ return super().setUpClass()
15
+
16
+ def test_load_data_into_df(self):
17
+ """
18
+ The purpose of this is just to test that if I load 2 different files as
19
+ dataframes, and then simply put them together. I.e. does it join on the
20
+ dates? YES IT APPEARS TO LEFT-JOIN on the dates from the first file.
21
+ """
22
+ df1 = bio.read_ts_csv("./src/bulum/clim/tests/Flow.out.withmissing.csv", date_format=r"%Y-%m-%d")["FRex_FR.qqm"]
23
+ df2 = bio.read_ts_csv("./src/bulum/clim/tests/Flow.out.RCP85_P2050_GCM8.csv", date_format=r"%Y-%m-%d")["FRex_FR.qqm"]
24
+ df3 = pd.DataFrame()
25
+ df3["x"] = df1
26
+ df3["y"] = df2
27
+ # print(df3.head())
28
+ # print(df3.tail())
29
+ self.assertTrue(len(df3) == len(df1))
30
+ self.assertAlmostEqual(df3.x.values[-1], 136) # these values should line up despite different starting dates for each file
31
+ self.assertAlmostEqual(df3.y.values[-1], 62) # these values should line up despite different starting dates for each file
32
+ # And now doe the same again with files loaded in the opposite order
33
+ df1 = bio.read_ts_csv("./src/bulum/clim/tests/Flow.out.RCP85_P2050_GCM8.csv", date_format=r"%Y-%m-%d")["FRex_FR.qqm"]
34
+ df2 = bio.read_ts_csv("./src/bulum/clim/tests/Flow.out.withmissing.csv", date_format=r"%Y-%m-%d")["FRex_FR.qqm"]
35
+ df3 = pd.DataFrame()
36
+ df3["x"] = df1
37
+ df3["y"] = df2
38
+ # print(df3.head())
39
+ # print(df3.tail())
40
+ self.assertTrue(len(df3) == len(df1))
41
+ self.assertAlmostEqual(df3.x.values[-1], 62) # these values should line up despite different starting dates for each file
42
+ self.assertAlmostEqual(df3.y.values[-1], 136) # these values should line up despite different starting dates for each file
43
+
44
+ def test_get_exc_transform(self):
45
+ """
46
+ This gets transformation curves based on current & future climate datasets, and then checks that the transformation
47
+ curves have the same total number of points regardless of whether we use default seasons (monthly) or define 3 custom
48
+ seasons.
49
+ """
50
+ current_climate = bio.read_ts_csv("./src/bulum/clim/tests/Flow.out.withmissing.csv", date_format=r"%Y-%m-%d")
51
+ future_climate = bio.read_ts_csv("./src/bulum/clim/tests/Flow.out.RCP85_P2050_GCM8.csv", date_format=r"%Y-%m-%d")
52
+ answer1 = ocl.derive_transformation_curves(current_climate["FRex_FR.qqm"], future_climate["FRex_FR.qqm"])
53
+ answer2 = ocl.derive_transformation_curves(current_climate["FRex_FR.qqm"], future_climate["FRex_FR.qqm"], season_start_months=[3, 7, 9])
54
+ total_len_1 = sum([len(a[1]) for a in answer1.values()])
55
+ total_len_2 = sum([len(a[1]) for a in answer2.values()])
56
+ self.assertEqual(total_len_1, total_len_2)
57
+ self.assertTrue(total_len_1 > 0)
58
+
59
+ def test_apply_transformation_curves(self):
60
+ current_climate = bio.read_ts_csv("./src/bulum/clim/tests/Flow.out.withmissing.csv", date_format=r"%Y-%m-%d")
61
+ future_climate = bio.read_ts_csv("./src/bulum/clim/tests/Flow.out.RCP85_P2050_GCM8.csv", date_format=r"%Y-%m-%d")
62
+ t = ocl.derive_transformation_curves(current_climate["FRex_FR.qqm"], future_climate["FRex_FR.qqm"])
63
+ answer = pd.DataFrame()
64
+ answer["RexCurrent"] = current_climate["FRex_FR.qqm"]
65
+ answer["RexCurrent"] = future_climate["FRex_FR.qqm"]
66
+ answer["Transf"] = ocl.apply_transformation_curves(t, current_climate["FRex_FR.qqm"])
67
+ # print(answer["Current"].sum())
68
+ # print(answer["Future"].sum())
69
+ # print(answer["Transf"].sum())
70
+ self.assertAlmostEqual(answer["Transf"].sum(), 4845710.795475168) # Actually haven't checked that this is the correct answer but looks plausible.
71
+ answer.to_csv("./trash/transformed.csv")
bulum/demo.py CHANGED
@@ -1,6 +1,6 @@
1
- def hello_world():
2
- print("Hello world!")
3
-
4
- if __name__ == "__main__":
5
- print(type(hello_world))
1
+ def hello_world():
2
+ print("Hello world!")
3
+
4
+ if __name__ == "__main__":
5
+ print(type(hello_world))
6
6
  hello_world()
bulum/io/__init__.py CHANGED
@@ -1,6 +1,6 @@
1
- from .csv_io import *
2
- from .res_csv_io import *
3
- from .idx_io import *
4
- from .iqqm_out_reader import *
5
- from .lqn_io import *
6
- from .general_io import *
1
+ from .csv_io import *
2
+ from .res_csv_io import *
3
+ from .idx_io import *
4
+ from .iqqm_out_reader import *
5
+ from .lqn_io import *
6
+ from .general_io import *