Module: ETCalculator
- Defined in:
- lib/asigbiophys/et_calculator.rb
Overview
Calculates adjusted evapotranspiration (hereinafter ET) from a “reference ET” number and other stuff like percent canopy cover or leaf-area index.
- Created
-
31May2011
- Authors
-
P Kaarakka, Rick Wayne
Instance Method Summary collapse
-
#adj_et_from_lai_corn(ref_et, lai) ⇒ Object
Return adjusted ET from the reference ET if the leaf area index is already in hand Crop coeff math is from WI_Irrigation_Scheduler_(WIS)_VV6.3.11.xls.
-
#adj_et_lai_corn(ref_et, days_since_emergence) ⇒ Object
Return adjusted ET from the reference ET and the days sinçe emergence Crop coeff math is from WI_Irrigation_Scheduler_(WIS)_VV6.3.11.xls.
-
#adj_et_pct_cover(ref_et, pctCover) ⇒ Object
Return the adjusted ET.
-
#calc_adj_ET(day) ⇒ Object
Duck Typing at work here; “day” can be anything that responds to the methods: “et_method”, “ref_et”, “leaf_area_index”, and “pct_cover”.
-
#lai_corn(days_since_emergence) ⇒ Object
LAI growth curve function for corn from WI_Irrigation_Scheduler_(WIS)_VV6.3.11.xls.
- #linear_increment(start_val, finish_val, n_vals) ⇒ Object
- #linear_interpolation(wx_arr, start, finish, entered_method, calc_method) ⇒ Object
-
#surrounding(wx_arr, middle, parameter) ⇒ Object
Percent Cover methods.
-
#update_adj_et_single_day(day) ⇒ Object
In addition to the four methods expected above for “day”, this one expects “day” to have a adj_et=(et_value) method.
Instance Method Details
#adj_et_from_lai_corn(ref_et, lai) ⇒ Object
Return adjusted ET from the reference ET if the leaf area index is already in hand Crop coeff math is from WI_Irrigation_Scheduler_(WIS)_VV6.3.11.xls
65 66 67 68 |
# File 'lib/asigbiophys/et_calculator.rb', line 65 def adj_et_from_lai_corn(ref_et,lai) crop_coeff = 1.1*(1-Math.exp(-1.5*(lai))) adj_et = ref_et * crop_coeff end |
#adj_et_lai_corn(ref_et, days_since_emergence) ⇒ Object
Return adjusted ET from the reference ET and the days sinçe emergence Crop coeff math is from WI_Irrigation_Scheduler_(WIS)_VV6.3.11.xls
58 59 60 61 |
# File 'lib/asigbiophys/et_calculator.rb', line 58 def adj_et_lai_corn(ref_et,days_since_emergence) crop_coeff = 1.1*(1-Math.exp(-1.5*(lai_corn(days_since_emergence)))) adj_et = ref_et * crop_coeff end |
#adj_et_pct_cover(ref_et, pctCover) ⇒ Object
Return the adjusted ET. Uses regression coefficients derived by J. Panuska from the UW Extension pub A3600.
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/asigbiophys/et_calculator.rb', line 12 def adj_et_pct_cover(ref_et,pctCover) ref_et = 0.0 if ref_et == nil pctCover = 0.0 if pctCover == nil return 0.0 if pctCover < 0.000001 # regression coefficients from J. Panuska in Linear_Regressions_for_A3600_Table.doc and based on Table C of UW Extension pub A3600, "Irrigation Management in Wisconsin - the Wisconsin Irrigation Scheduling Program (WISP)" coeff = [[0,0],[-0.002263,0.2377],[-0.002789,0.3956],[-0.002368,0.5395],[-0.000316,0.6684],[-0.000053,0.7781],[0.001053,0.8772],[0.001947,0.9395],[0.000000,1.000]] #NOTE: coeffIndex and interpolations assume pctCover curves are all exactly 10% apart. coeffIndex = (pctCover/10).floor case coeffIndex when 0 # Get zero %cover adj_et case ref_et when 0.0 return 0.0 when 0..0.159 adj_etLow = 0.0 when 0.160..0.319 adj_etLow = 0.010 else adj_etLow = 0.020 end # Get 10 %cover adj_et adj_etHigh = coeff[1][0] + ref_et*coeff[1][1] # Interpolate adj_et between zero and 10 %cover adj_et = adj_etLow + ((pctCover/10)*(adj_etHigh-adj_etLow)) when 1..7 # Get low end adj_et adj_etLow = coeff[coeffIndex][0] + ref_et*coeff[coeffIndex][1] # Get high end adj_et adj_etHigh = coeff[coeffIndex+1][0] + ref_et*coeff[coeffIndex+1][1] # Interpolate adj_et between low and high %cover adj_et = adj_etLow + (((pctCover - coeffIndex*10)/10) * (adj_etHigh-adj_etLow)) else # At 80% cover and above there is no adjustment to the ref_et adj_et = ref_et end return adj_et end |
#calc_adj_ET(day) ⇒ Object
Duck Typing at work here; “day” can be anything that responds to the methods: “et_method”, “ref_et”, “leaf_area_index”, and “pct_cover”. So an ActiveRecord class instance with those table columns will work, or a mock object for testing, or wrapper around some other class that calls them referenceET and leafAreaIndex.
74 75 76 77 78 79 80 |
# File 'lib/asigbiophys/et_calculator.rb', line 74 def calc_adj_ET(day) if day.respond_to?('et_method') day.et_method.adj_et(day) else raise "Can't get ET method" end end |
#lai_corn(days_since_emergence) ⇒ Object
LAI growth curve function for corn from WI_Irrigation_Scheduler_(WIS)_VV6.3.11.xls
52 53 54 |
# File 'lib/asigbiophys/et_calculator.rb', line 52 def lai_corn(days_since_emergence) (0.000000000009*(days_since_emergence)**7.95)*(Math.exp(-0.1*(days_since_emergence))) end |
#linear_increment(start_val, finish_val, n_vals) ⇒ Object
114 115 116 |
# File 'lib/asigbiophys/et_calculator.rb', line 114 def linear_increment(start_val,finish_val,n_vals) (finish_val - start_val) / (n_vals - 1) end |
#linear_interpolation(wx_arr, start, finish, entered_method, calc_method) ⇒ Object
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/asigbiophys/et_calculator.rb', line 118 def linear_interpolation(wx_arr,start,finish,entered_method,calc_method) return unless wx_arr && wx_arr.size > 2 # Can't interpolate nothin', or if arr has fewer than 3 values return unless (n_vals = 1 + finish - start) > 1 # Finish and start have to be far enough apart return if start >= finish && start < 0 && finish > wx_arr.size - 1 start_val = wx_arr[start][entered_method] || wx_arr[start][calc_method] || 0.0 finish_val = wx_arr[finish][entered_method] || wx_arr[finish][calc_method] || 0.0 incr = linear_increment(start_val,finish_val,n_vals) start.upto(finish).each do |ii| # Note that this sets the calculated_pct_cover fields of the days with entered_pct_cover, # but should be to the same value wx_arr[ii][calc_method] = start_val + (ii - start)*incr if wx_arr[ii].respond_to?('save!') begin wx_arr[ii].save! rescue Exception => e dbg = <<-END ETCalculator::linear_interpolation: Could not save wx_arr[#{ii}] start #{start} finish #{finish} entered_method #{entered_method} calc_method #{calc_method} start_val #{start_val} finish_val #{finish_val} incr #{incr} #{wx_arr[ii].inspect} END logger.warn dbg end end end end |
#surrounding(wx_arr, middle, parameter) ⇒ Object
Percent Cover methods
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/asigbiophys/et_calculator.rb', line 91 def surrounding(wx_arr,middle,parameter) max_index = wx_arr.size - 1 return nil if max_index < 2 || middle > max_index || middle < 0 res = [0,max_index] if middle > 0 (middle - 1).downto(0) do |ii| if wx_arr[ii].respond_to?('[]') && (wx_arr[ii][parameter]) res[0] = ii break end end end if middle < max_index (middle + 1).upto(max_index) do |ii| if wx_arr[ii].respond_to?('[]') && (wx_arr[ii][parameter]) res[1] = ii break end end end res end |
#update_adj_et_single_day(day) ⇒ Object
In addition to the four methods expected above for “day”, this one expects “day” to have a adj_et=(et_value) method
84 85 86 |
# File 'lib/asigbiophys/et_calculator.rb', line 84 def update_adj_et_single_day(day) day.adj_et = calc_adj_ET(day) end |