agwx_biophys 0.0.1 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,105 @@
1
+ # while ((doy<171)); do echo "$doy => `getstndd 2012 $doy $doy Rect 50 WIMN 43.9 -95.6`,"; ((doy+=1)); done
2
+ ANDI_DDS = {
3
+ 69 => 0,
4
+ 70 => 2,
5
+ 71 => 0,
6
+ 72 => 0,
7
+ 73 => 2,
8
+ 74 => 1,
9
+ 75 => 2,
10
+ 76 => 9,
11
+ 77 => 17,
12
+ 78 => 21,
13
+ 79 => 14,
14
+ 80 => 1,
15
+ 81 => 2,
16
+ 82 => 7,
17
+ 83 => 6,
18
+ 84 => 6,
19
+ 85 => 0,
20
+ 86 => 0,
21
+ 87 => 4,
22
+ 88 => 0,
23
+ 89 => 3,
24
+ 90 => 5,
25
+ 91 => 10,
26
+ 92 => 12,
27
+ 93 => 15,
28
+ 94 => 3,
29
+ 95 => 0,
30
+ 96 => 0,
31
+ 97 => 0,
32
+ 98 => 0,
33
+ 99 => 0,
34
+ 100 => 0,
35
+ 101 => 0,
36
+ 102 => 0,
37
+ 103 => 0,
38
+ 104 => 1,
39
+ 105 => 7,
40
+ 106 => 3,
41
+ 107 => 0,
42
+ 108 => 0,
43
+ 109 => 1,
44
+ 110 => 0,
45
+ 111 => 0,
46
+ 112 => 1,
47
+ 113 => 0,
48
+ 114 => 1,
49
+ 115 => 13,
50
+ 116 => 18,
51
+ 117 => 2,
52
+ 118 => 0,
53
+ 119 => 0,
54
+ 120 => 0,
55
+ 121 => 6,
56
+ 122 => 17,
57
+ 123 => 15,
58
+ 124 => 18,
59
+ 125 => 14,
60
+ 126 => 9,
61
+ 127 => 8,
62
+ 128 => 5,
63
+ 129 => 0,
64
+ 130 => 4,
65
+ 131 => 12,
66
+ 132 => 6,
67
+ 133 => 6,
68
+ 134 => 8,
69
+ 135 => 18,
70
+ 136 => 10,
71
+ 137 => 9,
72
+ 138 => 25,
73
+ 139 => 29,
74
+ 140 => 16,
75
+ 141 => 6,
76
+ 142 => 12,
77
+ 143 => 20,
78
+ 144 => 19,
79
+ 145 => 6,
80
+ 146 => 5,
81
+ 147 => 14,
82
+ 148 => 24,
83
+ 149 => 13,
84
+ 150 => 3,
85
+ 151 => 0,
86
+ 152 => 3,
87
+ 153 => 6,
88
+ 154 => 12,
89
+ 155 => 19,
90
+ 156 => 19,
91
+ 157 => 20,
92
+ 158 => 22,
93
+ 159 => 23,
94
+ 160 => 27,
95
+ 161 => 28,
96
+ 162 => 21,
97
+ 163 => 12,
98
+ 164 => 7,
99
+ 165 => 17,
100
+ 166 => 25,
101
+ 167 => 19,
102
+ 168 => 19,
103
+ 169 => 20,
104
+ 170 => 30
105
+ }
@@ -0,0 +1,96 @@
1
+ require "test/unit"
2
+ require "agwx_biophys"
3
+ require "agwx_grids"
4
+
5
+ class TestAgwxBiophys < Test::Unit::TestCase
6
+ include AgwxBiophys::DegreeDays
7
+ include AgwxGrids
8
+
9
+ def setup
10
+ @min_grid = Grid.new(File.join(File.dirname(__FILE__),'grids','WIMNTMin2012'),Grid::DAILY)
11
+ @max_grid = Grid.new(File.join(File.dirname(__FILE__),'grids','WIMNTMax2012'),Grid::DAILY)
12
+ end
13
+
14
+ def test_rect_DD
15
+ assert_equal(18, rect_DD(50,86))
16
+ assert_equal(27, rect_DD(50,86,41))
17
+ end
18
+
19
+ def test_sine_DD
20
+ assert(sine_DD(10,20), "Could not even call sine_DD")
21
+ end
22
+
23
+ def get_temps_for(longitude = -95.6, latitude = 43.90)
24
+ max_grid = Grid.new(File.join(File.dirname(__FILE__),'grids','WIMNTMax2012'),Grid::DAILY)
25
+ min_grid = Grid.new(File.join(File.dirname(__FILE__),'grids','WIMNTMin2012'),Grid::DAILY)
26
+ mins = min_grid.at_by_long_lat(longitude,latitude).inject({}) {|hash,(doy,val)| hash.merge({doy => to_fahrenheit(val)}) }
27
+ maxes = max_grid.at_by_long_lat(longitude,latitude).inject({}) {|hash,(doy,val)| hash.merge({doy => to_fahrenheit(val)}) }
28
+ [mins,maxes]
29
+
30
+ end
31
+
32
+ def test_get_temps_for
33
+ mins,maxes = get_temps_for
34
+ assert_equal(Hash,mins.class)
35
+ assert_equal(Hash, maxes.class)
36
+ assert_equal(to_fahrenheit(-7.53),mins[1])
37
+ assert_equal(to_fahrenheit(21.20), mins[170]) # this does appear to be 21.20 in the grid file...???
38
+ assert_equal(to_fahrenheit(32.06), maxes[170])
39
+ assert_equal(366, mins.keys.size)
40
+ mins.keys.sort.each { |doy| assert mins[doy] < maxes[doy] }
41
+ end
42
+
43
+ def test_rect_one_day
44
+ mins,maxes = get_temps_for
45
+ assert_equal(to_fahrenheit(21.20), mins[170]) # this does appear to be 21.20 in the grid file...???
46
+ assert_equal(to_fahrenheit(32.06), maxes[170])
47
+ assert_in_delta(29.934, rect_DD(mins[170],maxes[170]),0.00001)
48
+ assert_in_delta(0.0, rect_DD(mins[71],maxes[71],50), 2 ** -20)
49
+ end
50
+
51
+ def test_rect_sequence
52
+ mins,maxes = get_temps_for
53
+ # loads up andi_dds as a hash of doy => getstndd value
54
+ andi_dds = eval(File.open(File.join(File.dirname(__FILE__),'rect_dd_seq_2012.rb')).read)
55
+ doys = andi_dds.keys.sort
56
+ (doys.first..doys.last).each { |doy| assert_equal(ANDI_DDS[doy], rect_DD(mins[doy],maxes[doy],50).round) }
57
+ end
58
+
59
+ def test_sine_one_day
60
+ mins,maxes = get_temps_for
61
+ assert_in_delta(17.3, sine_DD(mins[170],maxes[170],50,86),0.001)
62
+ end
63
+
64
+ def test_cumulate_rect
65
+ mins,maxes = get_temps_for
66
+ expected = {50 => 0, 100 => 142, 150 => 549, 170 => 898, 230 => 2320, 270 => 2919}
67
+ expected.each do |doy,dd|
68
+ cumulated,days_found = cumulate(mins,maxes,1,doy,50) {|min,max,base,upper| rect_DD(min,max,base).round}
69
+ assert_equal(doy, days_found,"Wrong number of days found in data")
70
+ assert_in_delta(dd, cumulated,cumulated * 0.006,"Wrong DD values for DOY #{doy}")
71
+ end
72
+ end
73
+
74
+ def test_cumulate_sine
75
+ mins,maxes = get_temps_for
76
+ # for doy in $DOYS; do echo "$doy => `getstndd 2012 1 $doy Sine 50 WIMN $LATLONG`,"; done
77
+ expected = {50 => 2, 100 => 203, 150 => 619, 170 => 937, 230 => 2039, 270 => 2562}
78
+ expected.each do |doy,dd|
79
+ cumulated,days_found = cumulate(mins,maxes,1,doy,50) {|min,max,base,upper| sine_DD(min,max,base).round}
80
+ assert_equal(doy, days_found,"Wrong number of days found in data")
81
+ assert_in_delta(dd, cumulated,cumulated * 0.007,"Wrong DD values for DOY #{doy}")
82
+ end
83
+ end
84
+
85
+ def test_cumulate_modb
86
+ mins,maxes = get_temps_for
87
+ # for doy in $DOYS; do echo "$doy => `getstndd 2012 1 $doy Sine 50 WIMN $LATLONG`,"; done
88
+ expected = { 50 => 4, 100 => 254, 150 => 723, 170 => 1077, 230 => 2449, 270 => 3085 }
89
+ expected.each do |doy,dd|
90
+ cumulated,days_found = cumulate(mins,maxes,1,doy,50) {|min,max,base,upper| modB_DD(min,max,base,upper).round}
91
+ assert_equal(doy, days_found,"Wrong number of days found in data")
92
+ assert_in_delta(dd, cumulated,cumulated * 0.006,"Wrong DD values for DOY #{doy}")
93
+ end
94
+ end
95
+
96
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: agwx_biophys
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - RickWayne
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-12-04 00:00:00.000000000 Z
11
+ date: 2013-12-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - '>='
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: agwx_grids
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: 0.0.4
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: 0.0.4
41
55
  description: Biophysical calculators primarily useful in agriculture and land management
42
56
  email:
43
57
  - fewayne@wisc.edu
@@ -51,12 +65,19 @@ files:
51
65
  - README.md
52
66
  - Rakefile
53
67
  - agwx_biophys.gemspec
68
+ - calccumdd.c
69
+ - getstndd.c
54
70
  - lib/agwx_biophys.rb
71
+ - lib/agwx_biophys/degree_days.rb
55
72
  - lib/agwx_biophys/et.rb
56
73
  - lib/agwx_biophys/version.rb
57
74
  - test/Et_testing.java
58
75
  - test/TestValues.xls
59
- - test/test_et.rb
76
+ - test/grids/WIMNTAvg2012
77
+ - test/grids/WIMNTMax2012
78
+ - test/grids/WIMNTMin2012
79
+ - test/rect_dd_seq_2012.rb
80
+ - test/test_dds.rb
60
81
  homepage: ''
61
82
  licenses:
62
83
  - MIT
@@ -84,4 +105,8 @@ summary: So far, just an ET calculator (Priestly-Taylor)
84
105
  test_files:
85
106
  - test/Et_testing.java
86
107
  - test/TestValues.xls
87
- - test/test_et.rb
108
+ - test/grids/WIMNTAvg2012
109
+ - test/grids/WIMNTMax2012
110
+ - test/grids/WIMNTMin2012
111
+ - test/rect_dd_seq_2012.rb
112
+ - test/test_dds.rb
@@ -1,232 +0,0 @@
1
- require 'test/unit'
2
- require 'agwx_biophys'
3
-
4
- class TestET < Test::Unit::TestCase
5
- include AgwxBiophys::ET
6
- def test_rad_lat
7
- [
8
- [0,0],
9
- [30,0.5235983333],
10
- [45,0.7853975],
11
- [60,1.0471966667],
12
- [90,1.570795],
13
- [180,3.14159]
14
- ].each do |lat,radians|
15
- assert_in_delta(radians, rad_lat(lat), 0.00001)
16
- end
17
- assert_equal(0, rad_lat(0.0))
18
- assert_equal(Math::PI, rad_lat(180.0))
19
- assert_equal(Math::PI/2.0, rad_lat(90.0))
20
- end
21
-
22
- def test_daily_to_sol
23
- assert_equal(0.0864, daily_to_sol(1.0))
24
- end
25
-
26
- def test_declin
27
- [
28
- [1,-0.4019921553],
29
- [150,0.3809480272],
30
- [172,0.41],
31
- [200,0.3632890322],
32
- [250,0.092707884]
33
- ].each do |doy,declination|
34
- assert_in_delta(declination, declin(doy), 2 ** -20)
35
- end
36
- end
37
-
38
- def test_sunrise_angle
39
- [
40
- [1,0,1.5707963268],
41
- [150,30,1.8041439502],
42
- [172,45,2.020424427],
43
- [200,60,2.2895663737],
44
- [1,60,0.7431090864],
45
- [150,45,1.9828717405],
46
- [172,30,1.8244415261],
47
- [200,0,1.5707963268]
48
-
49
- ].each do |doy,latitude,sun_angle|
50
- assert_in_delta(sun_angle, sunrise_angle(doy,latitude), 0.00001)
51
- end
52
- end
53
-
54
- def test_sunrise_hour
55
- [
56
- [1,0,5.999994932],
57
- [150,30,5.1086719137],
58
- [172,45,4.2825406486],
59
- [200,60,3.254493271]
60
- ].each do |doy,latitude,sun_hour|
61
- assert_in_delta(sun_hour, sunrise_hour(doy,latitude), 0.00001)
62
- end
63
- end
64
-
65
- def test_day_hours
66
- [
67
- [1,0,12.0],
68
- [150,30,13.7826561727],
69
- [172,45,15.4349187028],
70
- [200,60,17.491013458]
71
- ].each do |doy,latitude,day_hrs|
72
- assert_in_delta(day_hrs, day_hours(doy,latitude), 0.00002)
73
- end
74
- end
75
- def test_av_eir
76
- [
77
- [1,1414.8379112589],
78
- [150,1326.4494599268],
79
- [172,1319.9344503498],
80
- [200,1321.3095743309]
81
- ].each do |doy,aveir|
82
- assert_in_delta(aveir, av_eir(doy), 0.00006)
83
- end
84
- end
85
-
86
- def test_to_eir
87
- [
88
- [1,0,35.8090258247],
89
- [150,30,40.7680366801],
90
- [172,45,41.8737911],
91
- [200,60,38.3861488725]
92
- ].each do |doy,latitude,total_eir|
93
- assert_in_delta(total_eir, to_eir(doy,latitude), 0.00005)
94
- end
95
- end
96
-
97
- def test_to_clr
98
- [
99
- [1,0,28.7069041338],
100
- [150,30,32.9899653948],
101
- [172,45,34.1124418882],
102
- [200,60,31.4758531933]
103
- ].each { |doy,lat,clr| assert_in_delta(clr, to_clr(doy,lat), 0.0003) }
104
- end
105
-
106
- def test_lwu
107
- [
108
- [5,15,30.2297320891],
109
- [16,24,34.73182695],
110
- [18,27,35.9318491504],
111
- [16,24,34.7318269495]
112
- ].each do |min,max,exp_lwu|
113
- assert_in_delta(exp_lwu, lwu(min,max), 0.000001)
114
- end
115
- end
116
-
117
- def test_sfactor
118
- [
119
- [5,15,0.5548],
120
- [16,24,0.6832],
121
- [18,27,0.7108625]
122
- ].each do |min,max,exp_sfactor|
123
- assert_in_delta(exp_sfactor, sfactor(min,max), 2 ** -20)
124
- end
125
- end
126
-
127
- def test_exponentiation
128
- assert_in_delta(2.71828182845904, Math.exp(1), 2 ** -20)
129
- assert_in_delta(148.4131591026, Math.exp(5), 2 ** -20)
130
- [
131
- [5 ,15,10 ,283.0, 0.9252419575,200.4076128756],
132
- [16,24,20 ,293.0, 0.7328604333,167.2440168899],
133
- [18,27,22.5,295.5, 0.6747883114,160.1550057145]
134
- ].each do |min,max,avg,avg_kelvin,lo,hi|
135
- avg_temp = (min+max) / 2.0
136
- assert_in_delta(avg, avg_temp, 2 ** -20)
137
- assert_in_delta(avg_temp + 273.0, avg_kelvin, 2 ** -20)
138
- avg_kelvin = avg_temp + 273
139
- lo_exp = Math.exp(-0.000777*avg_temp*avg_temp)
140
- hi_exp = Math.exp( 1500.0/(273.0+avg_temp))
141
- assert_in_delta(hi, hi_exp, 2 ** -20)
142
- assert_in_delta(lo, lo_exp, 2 ** -20)
143
- end
144
- end
145
-
146
- def test_sky_emiss
147
- [
148
- [0.1,5,15 ,0.7585118491],
149
- [0.2,16,24 ,0.8087234269],
150
- [0.499,18,27 ,0.8238802507],
151
- [0.51,5,15 ,0.7608136901],
152
- [1,16,24 ,0.79951019],
153
- [2,18,27 ,0.8905844568],
154
- [1.0,16.0,24.0,0.79951019]
155
- ].each do |vp,min,max,sky|
156
- assert_in_delta(sky, sky_emiss(vp,min,max,(min+max)/2.0), 0.000001,"Out of range for vp #{vp} min #{min} max #{max}")
157
- end
158
- end
159
-
160
- def test_angstrom
161
- [
162
- [0.1,5,15 ,0.2098834905],
163
- [0.2,16,24 ,0.1575797636],
164
- [0.499,18,27 ,0.1417914055],
165
- [0.51,5,15 ,0.2074857395],
166
- [1,16,24 ,0.1671768854],
167
- [2,18,27 ,0.0723078575],
168
- [1.0,16.0,24.0,0.16718]
169
- ].each { |vp,min,max,angs| assert_in_delta(angs, angstrom(vp,min,max,(min+max)/2.0), 0.000004) }
170
-
171
- end
172
- def test_clr_ratio
173
- [
174
- [62,1,0,0.186603194],
175
- [142,150,30,0.3718949036],
176
- [336,172,45,0.8510208708],
177
- [62,200,60,0.1701876028]
178
- ].each { |dAvSol,doy,lat,clr_ratio| assert_in_delta(clr_ratio, clr_ratio(dAvSol,doy,lat), 2 ** -20) }
179
- end
180
-
181
- def test_lwnet
182
- [
183
- [0.1,5,15,142,150,30 ,2.35957],
184
- [0.2,16,24,336,172,45 ,4.65767],
185
- [0.499,18,27,62,200,60 ,0.86708],
186
- [1.0,16.0,24.0,336.0,172,45.0,4.94133]
187
- ].each do |vp,min,max,sol,doy,lat,lwnet|
188
- assert_in_delta(lwnet, lwnet(vp,min,max,(min+max)/2.0,sol,doy,lat), 0.000025,"lwnet for #{vp}")
189
- end
190
- end
191
-
192
- def test_ets_with_obs
193
- # DAvSol,DMnTAir,DMxTAir,DAvTAir,DAvVPre,theDate,latitude,DRefET,DPctClr
194
-
195
- et_obs = [
196
- [336.0,16.0,24.0,20.0,1.0,'2013-06-21',45.0,0.24,85.10],
197
- [244.40,10.80,24.88,18.32,1.49,'2013-06-01',44.12,0.18,63.05],
198
- [285.40,5.23,15.91,10.60,0.86,'2013-06-02',44.12,0.17,73.49],
199
- [319.60,3.63,21.95,13.82,0.92,'2013-06-03',44.12,0.20,82.15],
200
- [45.76,9.95,13.56,11.41,1.25,'2013-06-04',44.12,0.03,11.74],
201
- [97.60,9.88,15.20,11.28,1.27,'2013-06-05',44.12,0.07,25.01],
202
- [62.95,9.55,13.01,11.00,1.26,'2013-06-06',44.12,0.04,16.10],
203
- [176.90,8.48,19.95,13.43,1.28,'2013-06-07',44.12,0.12,45.20],
204
- [131.80,9.21,19.31,14.57,1.35,'2013-06-08',44.12,0.09,33.63],
205
- [158.40,11.08,23.55,17.22,1.51,'2013-06-09',44.12,0.12,40.37],
206
- [234.00,14.20,26.73,20.02,1.78,'2013-06-10',44.12,0.19,59.58],
207
- [220.00,12.74,26.06,20.13,1.84,'2013-06-11',44.12,0.18,55.96],
208
- [142.00,13.74,25.72,18.78,1.86,'2013-06-12',44.12,0.12,36.09],
209
- [329.10,13.61,24.73,19.16,1.46,'2013-06-13',44.12,0.25,83.57],
210
- [336.40,11.01,24.85,18.69,1.34,'2013-06-14',44.12,0.24,85.37],
211
- [190.20,14.12,26.06,18.89,1.93,'2013-06-15',44.12,0.16,48.24],
212
- [349.00,13.27,27.64,20.92,1.52,'2013-06-16',44.12,0.27,88.48],
213
- [297.40,13.74,27.97,20.09,1.55,'2013-06-17',44.12,0.23,75.37],
214
- [345.90,9.55,22.27,15.83,1.14,'2013-06-18',44.12,0.24,87.64],
215
- [348.00,6.63,25.58,17.61,1.24,'2013-06-19',44.12,0.24,88.16],
216
- [331.50,14.34,29.81,22.59,1.52,'2013-06-20',44.12,0.26,83.98],
217
- [130.30,16.84,25.53,20.66,2.06,'2013-06-21',44.12,0.11,33.01],
218
- [134.30,18.37,25.59,20.98,2.23,'2013-06-22',44.12,0.12,34.03],
219
- [297.30,17.58,29.69,23.44,2.24,'2013-06-23',44.12,0.26,75.35],
220
- [198.10,19.17,28.10,22.58,2.27,'2013-06-24',44.12,0.18,50.23],
221
- [195.10,17.85,25.98,21.67,2.30,'2013-06-25',44.12,0.17,49.49],
222
- [235.70,20.29,28.08,23.26,2.37,'2013-06-26',44.12,0.22,59.82],
223
- ].each { |arr| arr[5] = Date.parse(arr[5]).yday }
224
-
225
- et_obs.each do |sol,min,max,avg,vapr,yday,lat,et,pct|
226
- # max_temp,min_temp,avg_v_press,d_to_sol,doy,lat
227
- ref_et,pct_clr = et(max,min,avg,vapr,sol,yday,lat)
228
- assert_in_delta(et, ref_et.round(2), 0.00001,"ET bludgered for #{Date.civil(2013,1,1)+yday-1}")
229
- assert_in_delta(pct, pct_clr.round(2), 0.00001,"PctClr bludgered for #{Date.civil(2013,1,1)+yday-1}")
230
- end
231
- end
232
- end