add trial design store subclasses.
[sgn.git] / lib / CXGN / NOAANCDC.pm
blobed5a9c52a7abb294713e7747321cdb4947b12406
2 =head1 NAME
4 CXGN::NOAANCDC - helper class for getting weather data from NOAA NCDC weather stations
6 =head1 SYNOPSYS
8 my $noaa = CXGN::NOAANCDC->new({
9 bcs_schema => $schema,
10 data_types => ['TMIN', 'TMAX', 'PRCP'],
11 start_date => "2019-01-13", #YYYY-MM-DD
12 end_date => "2019-12-19", #YYYY-MM-DD
13 noaa_station_id => "GHCND:US1NCBC0005",
14 noaa_ncdc_access_token => $noaa_ncdc_access_token
15 });
16 my $temperature_averaged_growing_degree_days = $noaa->get_temperature_averaged_gdd($gdd_base_temperature);
18 # Musgrave stationid = GHCND:USC00300331
20 # Datatypes:
21 # PRCP Total Precipitation (+Musgrave)
22 # F2MN Faster 2 minute wind speed (-Musgrave)
23 # TMAX Maximum Temperature (+Musgrave)
24 # TMIN Minimum Temperature (+Musgrave)
25 # TOBS Temperatue at observation time (+Musgrave)
26 # TAVG Average Temperature (-Musgrave)
27 # F5SC Fastest 5 second wind speed (-Musgrave)
28 # AWND Average Wind Speed (-Musgrave)
29 # FSMI Fastest Mile (ddfff) (-Musgrave)
30 # FSMN Fastest One-minute Wind (ddfff) (-Musgrave)
31 # PRES Station Pressure (-Musgrave)
32 # RWND Resultant Wind Speed (-Musgrave)
33 # SLVP Sea Level Pressure (-Musgrave)
34 # TMPW Wet Bulb Temperature (-Musgrave)
35 # FSIN Fastest Instantaneous Wind (ddfff) (-Musgrave)
36 # WDMV 24_hour Wind Movement (-Musgrave)
37 # MNTP Average Temperature (-Musgrave)
38 # DPTP Dew Point Temperature (-Musgrave)
40 =head1 AUTHOR
42 Nicolas Morales <nm529@cornell.edu>
44 =head1 METHODS
46 =cut
48 package CXGN::NOAANCDC;
50 use Moose;
51 use Data::Dumper;
52 use Try::Tiny;
53 use SGN::Model::Cvterm;
54 use LWP::UserAgent;
55 use JSON;
56 use Math::Round;
58 has 'bcs_schema' => (
59 isa => 'Bio::Chado::Schema',
60 is => 'rw',
61 required => 1
64 has 'data_types' => (
65 isa => 'ArrayRef',
66 is => 'rw',
69 has 'start_date' => (
70 isa => 'Str',
71 is => 'rw',
72 required => 1
75 has 'end_date' => (
76 isa => 'Str',
77 is => 'rw',
78 required => 1
81 has 'noaa_station_id' => (
82 isa => 'Str',
83 is => 'rw',
84 required => 1
87 has 'noaa_ncdc_access_token' => (
88 isa => 'Str',
89 is => 'rw',
90 required => 1
93 sub get_noaa_data {
94 my $self = shift;
96 my $data_types_string = '&datatypeid=';
97 $data_types_string .= join '&datatypeid=', @{$self->data_types};
99 my $ua = LWP::UserAgent->new(
100 ssl_opts => { verify_hostname => 0 }
102 my $server_endpoint = "https://www.ncdc.noaa.gov/cdo-web/api/v2/data?stationid=".$self->noaa_station_id."&limit=1000&datasetid=GHCND".$data_types_string."&startdate=".$self->start_date."&enddate=".$self->end_date;
104 print STDERR $server_endpoint."\n";
105 my $resp = $ua->get($server_endpoint, "token"=>$self->noaa_ncdc_access_token);
107 my $message_hash = {};
108 if ($resp->is_success) {
109 my $message = $resp->decoded_content;
110 $message_hash = decode_json $message;
111 # print STDERR Dumper $message_hash;
113 else {
114 print STDERR Dumper $resp;
116 return $message_hash;
119 sub get_temperature_averaged_gdd {
120 my $self = shift;
121 my $gdd_base_temperature = shift || '50'; #For Maize use 50
122 my $result = 0;
124 $self->data_types(['TMIN','TMAX']);
126 my $message_hash = $self->get_noaa_data();
128 my %weather_hash;
129 foreach (@{$message_hash->{results}}) {
130 $weather_hash{$_->{date}}->{$_->{datatype}} = $_->{value};
132 foreach (values %weather_hash) {
133 if (defined($_->{TMIN}) & defined($_->{TMAX})) {
134 #TMAX and TMIN are in tenths of C
135 my $tmax_f = (9/5)*($_->{TMAX}/10) + 32;
136 my $tmin_f = (9/5)*($_->{TMIN}/10) + 32;
137 my $gdd_accumulation = (($tmax_f + $tmin_f)/2) - $gdd_base_temperature;
138 if ($gdd_accumulation > 0) {
139 $result = $result + $gdd_accumulation;
144 return round($result);
147 sub get_averaged_precipitation {
148 my $self = shift;
149 my $result = 0;
151 $self->data_types(['PRCP']);
153 my $message_hash = $self->get_noaa_data();
155 my %weather_hash;
156 foreach (@{$message_hash->{results}}) {
157 $weather_hash{$_->{date}}->{$_->{datatype}} = $_->{value};
159 foreach (values %weather_hash) {
160 if (defined($_->{PRCP})) {
161 $result = $result + $_->{PRCP};
165 return $result;