Drought-PET-Thornthwaite
view release on metacpan or search on metacpan
lib/Drought/PET/Thornthwaite.pm view on Meta::CPAN
sub pet_thornthwaite {
# Define a NaN value for later use
my $inf = exp(~0 >> 1);
my $nan = $inf / $inf;
# Make sure the caller supplied sufficient arguments
unless(@_ and @_ >= 5) { croak "Insufficient arguments supplied"; }
# Get the arguments
my $yday = shift;
my $ndays = shift;
my $lat = shift;
my $temperature = shift;
my $tei = shift;
my $missing_val = $nan;
# Replace the default missing value if the caller supplied one
if(@_) { $missing_val = shift; }
# Validate the non-data arguments
if(not looks_like_number($yday)) { croak "YDAY arg must be numeric"; }
$yday = int($yday);
if(not $yday >= 1 or not $yday <= 366) { croak "YDAY arg must be between 1 and 366"; }
if(not looks_like_number($ndays)) { croak "NDAYS arg must be numeric"; }
$ndays = int($ndays);
if(not $ndays >= 1) { croak "NDAYS arg must be 1 or greater"; }
if(not looks_like_number($lat)) { croak "LAT arg must be numeric"; }
if(not $lat >= 0 or not $lat <= 90) { croak "LAT arg must be between 0 and 90"; }
# Return the missing value if the data arguments are missing or invalid
if(
not defined($temperature) or
not defined($tei) or
not looks_like_number($temperature) or
not looks_like_number($tei) or
$temperature == $missing_val or
$tei == $missing_val or
not defined($temperature <=> 0) or
not defined($tei <=> 0)
) { return $missing_val; }
# Calculate the PET!
if($temperature <= 0) { return 0; }
elsif($temperature > 0 and $temperature < 26.5) {
# Calculate the hours of sunlight
my $lat_radians = (pi/180)*$lat;
my $solar_declination = 0.409*sin((2*pi/365)*$yday - 1.39);
my $sunset_angle = acos(-tan($lat_radians)*tan($solar_declination));
my $daylength = (24/pi)*$sunset_angle;
# Calculate alpha term
my $alpha = (6.75e-7)*($tei**3) - (7.71e-5)*($tei**2) + 0.01792*$tei + 0.49239;
# Apply the original Thornthwaite Equation
my $pet_gross = 16*((10*$temperature)/($tei))**$alpha;
return $pet_gross*($daylength/12)*($ndays/30);
}
else {
# Apply the hot temperature formula described in Huang et al. 1996
return (-415.85 + 32.25*$temperature - 0.43*($temperature**2))*($ndays/30);
}
}
=head2 tei_thornthwaite
my $tei = tei_thornthwaite($jan,$feb,$mar,$apr,$may,$jun,$jul,$aug,$sep,$oct,$nov,$dec);
Calculates and returns the temperature efficiency index (TEI, sometimes called the
Thornthwaite heat index) based on a monthly average temperature climatology for a given
location. Since the equation involves a summation of adjusted monthly temperatures, 12
arguments are required, consisting of the average temperature for each calendar month of
the year. An optional 13th argument can also be supplied to define a numeric value
interpreted as missing data. If not supplied, the default missing value is NaN.
The missing value will be returned if any of the temperature values are missing,
undef, or invalid (e.g., non-numeric).
=cut
sub tei_thornthwaite {
# Define a NaN value for later use
my $inf = exp(~0 >> 1);
my $nan = $inf / $inf;
# Make sure the caller supplied sufficient arguments
unless(@_ and @_ >= 12) { croak "Insufficient arguments supplied"; }
# Get the arguments
my @monthly_temperatures;
my $invalid = 0;
for(my $i=0; $i<12; $i++) { push(@monthly_temperatures,shift); }
my $missing_val = $nan;
# Replace the default missing value if the caller supplied one
if(@_) { $missing_val = shift; }
# Calculate the TEI!
my $tei = 0;
for(my $i=0; $i<12; $i++) {
# Return a missing value if any of the monthly temps are missing or invalid
if(
not defined($monthly_temperatures[$i]) or
not looks_like_number($monthly_temperatures[$i]) or
$monthly_temperatures[$i] == $missing_val or
not defined($monthly_temperatures[$i] <=> 0)
) { return $missing_val; }
# Set any monthly mean temp below 0 to 0
$monthly_temperatures[$i] = $monthly_temperatures[$i] > 0 ? $monthly_temperatures[$i] : 0;
$tei += ($monthly_temperatures[$i]/5)**1.514;
}
return $tei;
}
=head1 INSTALLATION
The best way to install this module is with a CPAN client, which will resolve and
( run in 1.966 second using v1.01-cache-2.11-cpan-b301d465b3d )