agwx_biophys 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +9 -0
- data/agwx_biophys.gemspec +23 -0
- data/lib/agwx_biophys/et.rb +149 -0
- data/lib/agwx_biophys/version.rb +3 -0
- data/lib/agwx_biophys.rb +6 -0
- data/test/Et_testing.java +117 -0
- data/test/TestValues.xls +0 -0
- data/test/test_et.rb +232 -0
- metadata +87 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f9f340d516a0d61d5d391d7f346540c6af7e38e3
|
4
|
+
data.tar.gz: 29dd22ef00cc3ec68b4a9aff760b7324fdb624a2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 991e2c2afbeb889135e0c71344c2fdd6de0a53b339e969d5984c7f89d223b5ce41f8177c97afec6354e0b84adf8ce5b95a3ae9a5e579bf86ad5773ad3dbf6efc
|
7
|
+
data.tar.gz: 8abb2837d359283f91762f624c31f63a1b94d7d559ee524b894cbda52db001b8a95ebe1199c29f353869d03029a0a82bf31b51490073bbe2550fa12999ceab85
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 RickWayne
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# AgwxBiophys
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'agwx_biophys'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install agwx_biophys
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'agwx_biophys/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "agwx_biophys"
|
8
|
+
spec.version = AgwxBiophys::VERSION
|
9
|
+
spec.authors = ["RickWayne"]
|
10
|
+
spec.email = ["fewayne@wisc.edu"]
|
11
|
+
spec.description = %q{Biophysical calculators primarily useful in agriculture and land management}
|
12
|
+
spec.summary = %q{So far, just an ET calculator (Priestly-Taylor)}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
module AgwxBiophys
|
2
|
+
module ET
|
3
|
+
SOLCON = 1367.0
|
4
|
+
STEFAN = (0.0864*0.0000000567)
|
5
|
+
SFCEMISS = 0.96
|
6
|
+
ALBEDO = 0.25
|
7
|
+
KELVIN = 273.15
|
8
|
+
|
9
|
+
def rad_lat(lat); lat * Math::PI / 180.0;end
|
10
|
+
|
11
|
+
def daily_to_sol(total_sol); 0.0864 * total_sol; end
|
12
|
+
|
13
|
+
def declin(doy)
|
14
|
+
0.41 *
|
15
|
+
Math::cos(
|
16
|
+
2 * Math::PI * ( doy - 172.0 ) / 365.0
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
20
|
+
def sunrise_angle(doy,lat)
|
21
|
+
Math.acos(
|
22
|
+
-1 *
|
23
|
+
Math.tan(declin(doy)) *
|
24
|
+
Math.tan(rad_lat(lat))
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
def sunrise_hour(doy,lat); 12 - ( 12 / Math::PI ) * sunrise_angle(doy,lat); end
|
29
|
+
|
30
|
+
def day_hours(doy,lat); 24 - 2 * sunrise_hour(doy,lat); end
|
31
|
+
|
32
|
+
def av_eir(doy)
|
33
|
+
SOLCON * ( 1 + 0.035 * Math.cos( 2 * Math::PI * doy / 365.0 ) )
|
34
|
+
end
|
35
|
+
|
36
|
+
def to_eir(doy,lat)
|
37
|
+
( 0.0864 / Math::PI ) * av_eir(doy) *
|
38
|
+
|
39
|
+
(
|
40
|
+
sunrise_angle(doy,lat) *
|
41
|
+
Math.sin( declin(doy) ) *
|
42
|
+
Math.sin( rad_lat(lat) ) +
|
43
|
+
|
44
|
+
Math.cos( declin(doy) ) *
|
45
|
+
Math.cos( rad_lat(lat) ) *
|
46
|
+
Math.sin( sunrise_angle(doy,lat) )
|
47
|
+
)
|
48
|
+
end
|
49
|
+
|
50
|
+
def to_clr(doy,lat)
|
51
|
+
to_eir(doy,lat) * (-0.7 + 0.86*day_hours(doy,lat)) / day_hours(doy,lat)
|
52
|
+
end
|
53
|
+
|
54
|
+
def c_to_k(temperature); temperature + KELVIN; end
|
55
|
+
|
56
|
+
# Temps are in Deg C
|
57
|
+
|
58
|
+
def lwu(min_temp,max_temp)
|
59
|
+
avg = (min_temp+max_temp) / 2.0
|
60
|
+
SFCEMISS * STEFAN * (273.15+avg) ** 4
|
61
|
+
end
|
62
|
+
|
63
|
+
def sfactor(min_temp,max_temp)
|
64
|
+
avg = (min_temp+max_temp) / 2.0
|
65
|
+
0.398 + 0.0171 * avg - 0.000142 * avg * avg
|
66
|
+
end
|
67
|
+
|
68
|
+
def sky_emiss(avg_v_press,min_temp,max_temp,avg_temp)
|
69
|
+
|
70
|
+
if ( avg_v_press > 0.5)
|
71
|
+
0.7 + (5.95e-4) * avg_v_press * Math.exp( 1500/(273+avg_temp) )
|
72
|
+
else
|
73
|
+
avg_t = (min_temp+max_temp) / 2.0
|
74
|
+
(1 - 0.261*Math.exp(-0.000777*avg_t*avg_t))
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def angstrom(avg_v_press,min_temp,max_temp,avg_temp)
|
79
|
+
1.0 - sky_emiss(avg_v_press,min_temp,max_temp,avg_temp) / SFCEMISS
|
80
|
+
end
|
81
|
+
|
82
|
+
def clr_ratio(d_to_sol,doy,lat)
|
83
|
+
dts = daily_to_sol(d_to_sol)
|
84
|
+
tc = to_clr(doy,lat)
|
85
|
+
# Never return higher than 1
|
86
|
+
[dts/tc,1.0].min
|
87
|
+
end
|
88
|
+
|
89
|
+
def lwnet(avg_v_press,min_temp,max_temp,avg_temp,d_to_sol,doy,lat)
|
90
|
+
angstrom(avg_v_press,min_temp,max_temp,avg_temp) * lwu(min_temp,max_temp) * clr_ratio(d_to_sol,doy,lat)
|
91
|
+
end
|
92
|
+
|
93
|
+
def et(max_temp,min_temp,avg_temp,avg_v_press,d_to_sol,doy,lat)
|
94
|
+
lwnet = lwnet(avg_v_press,min_temp,max_temp,avg_temp,d_to_sol,doy,lat )
|
95
|
+
lwd = lwu(min_temp,max_temp) - lwnet
|
96
|
+
r_net_1 = (1.0 - ALBEDO) * daily_to_sol(d_to_sol) - lwnet
|
97
|
+
ret1 = 1.28 * sfactor(min_temp,max_temp) * r_net_1
|
98
|
+
# puts "lwnet #{lwnet}, lwd #{lwd}, r_net_1 #{r_net_1}, ret1 #{ret1} refet #{ret1 / 62.3}"
|
99
|
+
[ret1 / 62.3,clr_ratio(d_to_sol,doy,lat) * 100.0]
|
100
|
+
end
|
101
|
+
# double LWD = LWU - LWnet;
|
102
|
+
# double Rnet1 = ( 1-ALBEDO ) * DailyToSol - LWnet; /* ;(RESULTANT ET)=MJ/M2/DY
|
103
|
+
# ;(RESULTANT ET)=REFN ET IN/DY */
|
104
|
+
# double RET1 = 1.28 * Sfactor * Rnet1;
|
105
|
+
# DRefET = RET1 / 62.3;
|
106
|
+
# DClrRatio = ClrRatio*100;
|
107
|
+
|
108
|
+
# Here's the old Java code
|
109
|
+
# double rad_lat = lat *Math.PI/180.0;
|
110
|
+
# double DailyToSol = 0.0864 * DToSol;
|
111
|
+
# double Declin = 0.41 *Math.cos( 2 * Math.PI * ( dayOfYear -172. ) / 365. );
|
112
|
+
# double Sunrise_Angle = Math.acos( -1*Math.tan(Declin) * Math.tan(rad_lat));
|
113
|
+
# double Sunrise_Hour = 12 - ( 12 / Math.PI ) * Sunrise_Angle;
|
114
|
+
# double Day_Hours = 24 - 2 * Sunrise_Hour;
|
115
|
+
|
116
|
+
# double AvEIR = SOLCON * ( 1 + 0.035 * Math.cos( 2 * Math.PI * dayOfYear / 365. ) );
|
117
|
+
# double ToEIR = ( 0.0864 / Math.PI ) * AvEIR *
|
118
|
+
# ( Sunrise_Angle * Math.sin( Declin ) * Math.sin( rad_lat )
|
119
|
+
# + Math.cos( Declin ) * Math.cos( rad_lat ) * Math.sin( Sunrise_Angle ) );
|
120
|
+
# /* MJ/SQM/DY */
|
121
|
+
#
|
122
|
+
# double ToClr = ToEIR * (-.7 + 0.86*Day_Hours) / Day_Hours ;
|
123
|
+
#
|
124
|
+
# double T = ( DMxTAir + DMnTAir ) / 2;
|
125
|
+
# double LWU = SFCEMISS * STEFAN * Math.pow( 273.15+T,4 ); /*LONG WAVE RAD
|
126
|
+
# EMITTED OUT */
|
127
|
+
# double Sfactor = 0.398 + 0.0171 * T - 0.000142 * T * T;
|
128
|
+
#
|
129
|
+
# double Angstrom = 1 - SkyEmiss / SFCEMISS;
|
130
|
+
#
|
131
|
+
# double ClrRatio;
|
132
|
+
# if (DailyToSol <= ToClr) { /*CLRRATIO = PCTCLR, < 100%
|
133
|
+
# 100 added to relieve problem */
|
134
|
+
# ClrRatio = DailyToSol / ToClr;
|
135
|
+
# }
|
136
|
+
# else {
|
137
|
+
# ClrRatio = 1.0;
|
138
|
+
# }
|
139
|
+
#
|
140
|
+
# double LWnet = Angstrom * LWU * ClrRatio;
|
141
|
+
# double LWD = LWU - LWnet;
|
142
|
+
# double Rnet1 = ( 1-ALBEDO ) * DailyToSol - LWnet; /* ;(RESULTANT ET)=MJ/M2/DY
|
143
|
+
# ;(RESULTANT ET)=REFN ET IN/DY */
|
144
|
+
# double RET1 = 1.28 * Sfactor * Rnet1;
|
145
|
+
# DRefET = RET1 / 62.3;
|
146
|
+
# DClrRatio = ClrRatio*100;
|
147
|
+
|
148
|
+
end # module ET
|
149
|
+
end # AgwxBiophys
|
data/lib/agwx_biophys.rb
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
public class Et_testing {
|
2
|
+
|
3
|
+
static final double SOLCON = 1367.0;
|
4
|
+
static final double STEFAN = (0.0864*0.0000000567);
|
5
|
+
static final double SFCEMISS = 0.96;
|
6
|
+
static final double ALBEDO = 0.25;
|
7
|
+
|
8
|
+
double DRefET, DClrRatio;
|
9
|
+
|
10
|
+
public Et_testing() {
|
11
|
+
DRefET = -1.0;
|
12
|
+
DClrRatio = -1.0;
|
13
|
+
}
|
14
|
+
public Et_testing(double DToSol, int dayOfYear, double DMnTAir, double DMxTAir,
|
15
|
+
double DAvVPre, double DAvTAir, double lat) {
|
16
|
+
this();
|
17
|
+
if (lat < 1.0 || lat > 90.0) /* Dont use this in Indonesia!!! */
|
18
|
+
return;
|
19
|
+
// wha***k?
|
20
|
+
/*
|
21
|
+
if ( ( dayOfYear >= 91 ) && ( dayOfYear <= 273 ) )
|
22
|
+
return;
|
23
|
+
*/
|
24
|
+
|
25
|
+
double rad_lat = lat *Math.PI/180.0;
|
26
|
+
double DailyToSol = 0.0864 * DToSol;
|
27
|
+
double Declin = 0.41 *Math.cos( 2 * Math.PI * ( dayOfYear -172. ) / 365. );
|
28
|
+
|
29
|
+
/*-----
|
30
|
+
* The Old sunrise angle was given by
|
31
|
+
* Sunrise_Angle=acos(tan(Declin)*tan(rad_lat);formula used for ET days
|
32
|
+
* + 0.0145/(cos(Declin)*cos(rad_lat))) ;other than months ?? (4-9)
|
33
|
+
*/
|
34
|
+
|
35
|
+
double Sunrise_Angle = Math.acos( -1*Math.tan(Declin) * Math.tan(rad_lat));
|
36
|
+
double Sunrise_Hour = 12 - ( 12 / Math.PI ) * Sunrise_Angle;
|
37
|
+
double Day_Hours = 24 - 2 * Sunrise_Hour;
|
38
|
+
double AvEIR = SOLCON * ( 1 + 0.035 * Math.cos( 2 * Math.PI * dayOfYear / 365. ) );
|
39
|
+
double ToEIR = ( 0.0864 / Math.PI ) * AvEIR *
|
40
|
+
( Sunrise_Angle * Math.sin( Declin ) * Math.sin( rad_lat )
|
41
|
+
+ Math.cos( Declin ) * Math.cos( rad_lat ) * Math.sin( Sunrise_Angle ) );
|
42
|
+
/* MJ/SQM/DY */
|
43
|
+
|
44
|
+
double ToClr = ToEIR * (-.7 + 0.86*Day_Hours) / Day_Hours ;
|
45
|
+
|
46
|
+
double T = ( DMxTAir + DMnTAir ) / 2;
|
47
|
+
double LWU = SFCEMISS * STEFAN * Math.pow( 273.15+T,4 ); /*LONG WAVE RAD
|
48
|
+
EMITTED OUT */
|
49
|
+
double Sfactor = 0.398 + 0.0171 * T - 0.000142 * T * T;
|
50
|
+
/*-------
|
51
|
+
* Old Sky Emiss equation
|
52
|
+
* SkyEmiss = ( 1 - 0.261 * Exp ( -0.000777 * T * T ) )
|
53
|
+
*/ double SkyEmiss;
|
54
|
+
if ( DAvVPre > 0.5) {
|
55
|
+
SkyEmiss = 0.7 + (5.95e-4)*DAvVPre*
|
56
|
+
Math.exp(1500/(273+DAvTAir));
|
57
|
+
}
|
58
|
+
else {
|
59
|
+
SkyEmiss = (1-0.261*Math.exp(-0.000777*T*T));
|
60
|
+
}
|
61
|
+
double Angstrom = 1 - SkyEmiss / SFCEMISS;
|
62
|
+
|
63
|
+
double ClrRatio;
|
64
|
+
if (DailyToSol <= ToClr) { /*CLRRATIO = PCTCLR, < 100%
|
65
|
+
100 added to relieve problem */
|
66
|
+
ClrRatio = DailyToSol / ToClr;
|
67
|
+
}
|
68
|
+
else {
|
69
|
+
ClrRatio = 1.0;
|
70
|
+
}
|
71
|
+
|
72
|
+
double LWnet = Angstrom * LWU * ClrRatio;
|
73
|
+
double LWD = LWU - LWnet;
|
74
|
+
double Rnet1 = ( 1-ALBEDO ) * DailyToSol - LWnet; /* ;(RESULTANT ET)=MJ/M2/DY
|
75
|
+
;(RESULTANT ET)=REFN ET IN/DY */
|
76
|
+
double RET1 = 1.28 * Sfactor * Rnet1;
|
77
|
+
System.out.print("ToEIR: "); System.out.println(ToEIR);
|
78
|
+
System.out.print("AvEIR: "); System.out.println(AvEIR);
|
79
|
+
System.out.print("SkyEmiss: "); System.out.println(SkyEmiss);
|
80
|
+
System.out.print("LWnet: "); System.out.println(LWnet);
|
81
|
+
System.out.print("Angstrom: "); System.out.println(Angstrom);
|
82
|
+
System.out.print("LWU: "); System.out.println(LWU);
|
83
|
+
System.out.print("ClrRatio: "); System.out.println(ClrRatio);
|
84
|
+
System.out.print("LWD: "); System.out.println(LWD);
|
85
|
+
System.out.print("Rnet1: "); System.out.println(Rnet1);
|
86
|
+
System.out.print("RET1: "); System.out.println(RET1);
|
87
|
+
DRefET = RET1 / 62.3;
|
88
|
+
DClrRatio = ClrRatio*100;
|
89
|
+
} // ET ctor
|
90
|
+
|
91
|
+
public double getET() {
|
92
|
+
return DRefET;
|
93
|
+
}
|
94
|
+
public double getPctClr() {
|
95
|
+
return DClrRatio;
|
96
|
+
}
|
97
|
+
|
98
|
+
public static void main(String[] args) {
|
99
|
+
// public Et_testing(double DToSol, int dayOfYear, double DMnTAir, double DMxTAir,
|
100
|
+
// double DAvVPre, double DAvTAir, float lat) {
|
101
|
+
Et_testing eT = new Et_testing(336.0,172,16.0,24.0,1.0,(16.0+24.0)/2.0,45.0);
|
102
|
+
System.out.println(eT.getET());
|
103
|
+
System.out.println();
|
104
|
+
System.out.println();
|
105
|
+
System.out.println();
|
106
|
+
// double[] et_obs1 = {244.40,10.80,24.88,1.49,152,44.12,0.18,63.05};
|
107
|
+
eT = new Et_testing(285.40,153,5.23,15.91,0.86,10.60,44.12);
|
108
|
+
System.out.println(eT.getET());
|
109
|
+
System.out.println(eT.getET() - 0.18);
|
110
|
+
double[] et_obs2 = {285.40,5.23,15.91,0.86,153,44.12,0.17,73.49};
|
111
|
+
double[] et_obs3 = {319.60,3.63,21.95,0.92,154,44.12,0.20,82.15};
|
112
|
+
double[] et_obs4 = {45.76,9.95,13.56,1.25,155,44.12,0.03,11.74};
|
113
|
+
|
114
|
+
eT.invokedStandalone = true;
|
115
|
+
}
|
116
|
+
private boolean invokedStandalone = false;
|
117
|
+
}
|
data/test/TestValues.xls
ADDED
Binary file
|
data/test/test_et.rb
ADDED
@@ -0,0 +1,232 @@
|
|
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
|
metadata
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: agwx_biophys
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- RickWayne
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-12-04 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: Biophysical calculators primarily useful in agriculture and land management
|
42
|
+
email:
|
43
|
+
- fewayne@wisc.edu
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- .gitignore
|
49
|
+
- Gemfile
|
50
|
+
- LICENSE.txt
|
51
|
+
- README.md
|
52
|
+
- Rakefile
|
53
|
+
- agwx_biophys.gemspec
|
54
|
+
- lib/agwx_biophys.rb
|
55
|
+
- lib/agwx_biophys/et.rb
|
56
|
+
- lib/agwx_biophys/version.rb
|
57
|
+
- test/Et_testing.java
|
58
|
+
- test/TestValues.xls
|
59
|
+
- test/test_et.rb
|
60
|
+
homepage: ''
|
61
|
+
licenses:
|
62
|
+
- MIT
|
63
|
+
metadata: {}
|
64
|
+
post_install_message:
|
65
|
+
rdoc_options: []
|
66
|
+
require_paths:
|
67
|
+
- lib
|
68
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - '>='
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: '0'
|
73
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
requirements: []
|
79
|
+
rubyforge_project:
|
80
|
+
rubygems_version: 2.0.6
|
81
|
+
signing_key:
|
82
|
+
specification_version: 4
|
83
|
+
summary: So far, just an ET calculator (Priestly-Taylor)
|
84
|
+
test_files:
|
85
|
+
- test/Et_testing.java
|
86
|
+
- test/TestValues.xls
|
87
|
+
- test/test_et.rb
|