Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save pangyre/316989 to your computer and use it in GitHub Desktop.
Save pangyre/316989 to your computer and use it in GitHub Desktop.
GHCN v2 Raw Global Mean Temperatures Google Chart Generator
#!/usr/bin/env perl
use warnings;
use strict;
use List::Util qw( first );
use Statistics::Descriptive;
use HTML::Entities;
use Time::Progress;
use URI::GoogleChart;
use LWP::Simple qw( mirror );
use File::HomeDir;
use File::Spec;
$| = 1; # For Time::Progress
#---------------------------------------------------------------------
my $home_dir = File::HomeDir->my_home;
my $v2_mean_file = File::Spec->catfile($home_dir,"v2.mean");
unless ( -s $v2_mean_file )
{
my $ghcn_v2_mean_uri = "ftp://ftp.ncdc.noaa.gov/pub/data/ghcn/v2/v2.mean.Z";
my $v2_mean_file_z = File::Spec->catfile($home_dir,"v2.mean.Z");
print "Mirroring $ghcn_v2_mean_uri...\n";
mirror($ghcn_v2_mean_uri, $v2_mean_file_z);
print "Gunzipping $v2_mean_file_z...\n";
system("gunzip", $v2_mean_file_z) == 0
or die "Couldn't gunzip $v2_mean_file_z: $?";
}
open my $fh, "<", $v2_mean_file
or die "Couldn't open $v2_mean_file for reading: $!";
# Data lines are 78 chars long.
my $progress = Time::Progress->new;
$progress->attr( min => 1, max => int( ( -s $fh ) / 78 ) );
my %years;
my $line = 1;
while ( <$fh> )
{
chomp;
my ( $station, $year, @months ) = unpack("A12A4(A5)*", $_);
# next if $year =~ /2010/;
# Contains a missing record, so toss the whole year.
next if first { /-9999/ } @months;
my $stat = $years{$year} ||= Statistics::Descriptive::Full->new();
for ( 0 .. 11 )
{
$months[$_] /= 10;
$stat->add_data($months[$_]);
}
# last if $line++ > 15000; # For faster testing.
print $progress->report("Parsing temperature data %40b%p%L%E\r", $line++);
}
my @years = sort keys %years;
for my $year ( @years )
{
printf("%d %5.2f %5.2s %5.1f %5.1f\n",
$year,
$years{$year}->mean,
$years{$year}->variance,
$years{$year}->min,
$years{$year}->max,
);
}
my $title = "GHCN v2 Raw Global Mean Temperatures in \x{B0}F $years[0]\x{2013}$years[-1]";
my $chart = URI::GoogleChart
->new("lines", 500, 150,
# label => [ @years ],
data => [ map { $years{$_}->mean * 9 / 5 + 32 } sort keys %years ],
title => $title,
range_show => "left",
encoding => "s",
color => "CC0033",
chxt => "x",
chxl => join("|",
"0:",
$years[0],
$years[@years*.125],
$years[@years*.25],
$years[@years*.375],
$years[@years*.5],
$years[@years*.625],
$years[@years*.75],
$years[@years*.875],
$years[-1])
);
print "\nURI\n$chart\n\n";
printf(qq{Image\n<img src="%s" alt="%s" />\n\n},
encode_entities($chart),
encode_entities($title),
);
exit 0;
__DATA__
=pod
=head1 NAME
GHCN v2 Raw Global Mean Temperatures Google Chart Generator
=head1 USAGE
The script will take several minutes or longer to run. It provides output of its progress and estimated run time.
The output is a summary of the yearly data and Google chart URI composed from the data with a corresponding HTML image tag.
=head1 INSTALL
You might need to install some of these modules: L<List::Util> L<Statistics::Descriptive>,
L<Time::Progress>, L<URI::GoogleChart>, L<LWP::Simple>, L<HTML::Entities>,
L<File::HomeDir>, L<File::Spec>. A couple of them are core so should be present already no matter your setup.
The script relies upon the tool C<gunzip> being available. If it's not, you'll need to uncompress the data file yourself.
=head1 GENERATED URI
http://chart.apis.google.com/chart?cht=lc&chs=500x150&chco=CC0033&chtt=GHCN+v2+Raw+Global+Mean+Temperatures+in+%C2%B0F+1702%E2%80%932009&chxl=0:%7C1702%7C1742%7C1780%7C1818%7C1857%7C1895%7C1933%7C1971%7C2009&chxr=1,42,57&chxt=x,y&chd=s:IMRRcUaZXQWYOTYZWUaZZPScXaaXWkZaZZYNAPNXGUMPQQcGGNHLMSNYUWTVaUZSTUTUaaYYNNXXTcQbPMOXVXbbZbgWZfcRejfZbTgYTWWgQXRWPUYaRXgTYcbWXLUUTWaTSQMQQVSWRScTUTVZcafYZeegadXcXefdhfhgkikgmpupqpqkkhkljnokjioknoporommlorpsprrosqplipppvrpmqpnplquqqupmmpoknnmmjmllnntvzxwuwuvuxyywwwxxwvvsvttptssrpmokkmnnm41wuyyww20uv0vxz049z
=head1 SEE ALSO
L<ftp://ftp.ncdc.noaa.gov/pub/data/ghcn/v2/> and L<ftp://ftp.ncdc.noaa.gov/pub/data/ghcn/v2/v2.temperature.readme>.
=head1 LICENSE
Copyright (E<copy>) 2008 Ashley Pond V.
This program is free software; you can redistribute it or modify it or
both under the same terms as Perl itself.
=head1 DISCLAIMER OF WARRANTY
Because this software is licensed free of charge, there is no warranty
for the software, to the extent permitted by applicable law. Except
when otherwise stated in writing the copyright holders or other
parties provide the software "as is" without warranty of any kind,
either expressed or implied, including, but not limited to, the
implied warranties of merchantability and fitness for a particular
purpose. The entire risk as to the quality and performance of the
software is with you. Should the software prove defective, you assume
the cost of all necessary servicing, repair, or correction.
In no event unless required by applicable law or agreed to in writing
will any copyright holder, or any other party who may modify and/or
redistribute the software as permitted by the above license, be liable
to you for damages, including any general, special, incidental, or
consequential damages arising out of the use or inability to use the
software (including but not limited to loss of data or data being
rendered inaccurate or losses sustained by you or third parties or a
failure of the software to operate with any other software), even if
such holder or other party has been advised of the possibility of such
damages.
=cut
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment