forecaster 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/forecaster/configuration.rb +13 -7
- data/lib/forecaster/forecast.rb +43 -43
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2a5197a183958f87c3231d9794568fd71794c5b5
|
4
|
+
data.tar.gz: d33426c83219a0a7d813be7dea525a8426cc61ad
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f7c2cda2ff2a646779c9326ef40b93c8e12593753dd62c3418f7def70b4bc9104640a1353652259a613b17dfb686bce95486bf9f6b286511a0a15f1da966b2d3
|
7
|
+
data.tar.gz: 973f053a188acd33f48f4305280f5106181749d65942c86bff946c98921fe8b18377d9b35c3687fb1c0107bf286ac8082e77aa36fac4b98539c66a72cfa5d009
|
@@ -1,17 +1,23 @@
|
|
1
1
|
module Forecaster
|
2
2
|
class Configuration
|
3
|
-
attr_accessor :server, :
|
3
|
+
attr_accessor :server, :cache_dir, :curl_path, :wgrib2_path, :records
|
4
4
|
|
5
5
|
def initialize
|
6
6
|
@server = "http://www.ftp.ncep.noaa.gov/data/nccf/com/gfs/prod"
|
7
|
-
@wgrib2 = "/usr/bin/wgrib2"
|
8
7
|
@cache_dir = "/tmp/forecaster"
|
8
|
+
@curl_path = "curl"
|
9
|
+
@wgrib2_path = "wgrib2"
|
10
|
+
|
11
|
+
# See: http://www.nco.ncep.noaa.gov/pmb/products/gfs/gfs_upgrade/gfs.t06z.pgrb2.0p25.f006.shtml
|
12
|
+
# See: http://www.cpc.ncep.noaa.gov/products/wesley/wgrib2/
|
13
|
+
# Use `variable` and `level` attributes separated by colons to identify
|
14
|
+
# the records to download and read.
|
9
15
|
@records = {
|
10
|
-
prate
|
11
|
-
tmp
|
12
|
-
ugrd
|
13
|
-
vgrd
|
14
|
-
tcdc
|
16
|
+
:prate => ":PRATE:surface:",
|
17
|
+
:tmp => ":TMP:2 m above ground:",
|
18
|
+
:ugrd => ":UGRD:10 m above ground:",
|
19
|
+
:vgrd => ":VGRD:10 m above ground:",
|
20
|
+
:tcdc => ":TCDC:entire atmosphere:"
|
15
21
|
}
|
16
22
|
end
|
17
23
|
|
data/lib/forecaster/forecast.rb
CHANGED
@@ -10,63 +10,45 @@ module Forecaster
|
|
10
10
|
@hour_of_forecast = hour_of_forecast
|
11
11
|
end
|
12
12
|
|
13
|
-
def
|
14
|
-
|
15
|
-
record = Forecaster.configuration.records[field]
|
16
|
-
cachename = Forecaster.configuration.cache_dir
|
17
|
-
|
18
|
-
filename = "gfs.t%02dz.pgrb2.0p25.f%03d" % [
|
19
|
-
@hour_of_run, @hour_of_forecast
|
20
|
-
]
|
21
|
-
pathname = "%04d%02d%02d%02d%" % [
|
13
|
+
def dirname
|
14
|
+
subdir = "%04d%02d%02d%02d" % [
|
22
15
|
@year, @month, @day, @hour_of_run
|
23
16
|
]
|
24
|
-
|
25
|
-
|
26
|
-
raise "'#{path}' not found" unless File.exists?(path)
|
17
|
+
File.join(Forecaster.configuration.cache_dir, subdir)
|
18
|
+
end
|
27
19
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
20
|
+
def filename
|
21
|
+
"gfs.t%02dz.pgrb2.0p25.f%03d" % [
|
22
|
+
@hour_of_run, @hour_of_forecast
|
23
|
+
]
|
24
|
+
end
|
32
25
|
|
33
|
-
|
26
|
+
def url
|
27
|
+
server = Forecaster.configuration.server
|
28
|
+
"%s/gfs.%04d%02d%02d%02d/%s" % [
|
29
|
+
server, @year, @month, @day, @hour_of_run, filename
|
30
|
+
]
|
34
31
|
end
|
35
32
|
|
36
33
|
def fetched?
|
37
|
-
|
38
|
-
pathname = "%04d%02d%02d%02d%" % [
|
39
|
-
@year, @month, @day, @hour_of_run
|
40
|
-
]
|
41
|
-
filename = "gfs.t%02dz.pgrb2.0p25.f%03d" % [
|
42
|
-
@hour_of_run, @hour_of_forecast
|
43
|
-
]
|
44
|
-
File.exist?(File.join(cachename, pathname, filename))
|
34
|
+
File.exist?(File.join(dirname, filename))
|
45
35
|
end
|
46
36
|
|
37
|
+
# This method will save the forecast file in the cache directory.
|
38
|
+
# But only the parts of the file containing the fields defined in
|
39
|
+
# the configuration will be downloaded.
|
47
40
|
def fetch
|
48
41
|
return self if fetched?
|
49
42
|
|
50
|
-
|
51
|
-
cachename = Forecaster.configuration.cache_dir
|
52
|
-
curl = "curl -f -s -S"
|
43
|
+
curl = Forecaster.configuration.curl_path
|
53
44
|
|
54
|
-
|
55
|
-
@year, @month, @day, @hour_of_run
|
56
|
-
]
|
57
|
-
FileUtils.mkpath(File.join(cachename, pathname))
|
45
|
+
FileUtils.mkpath(File.join(dirname))
|
58
46
|
|
59
|
-
|
60
|
-
@hour_of_run, @hour_of_forecast
|
61
|
-
]
|
62
|
-
url = "%s/gfs.%04d%02d%02d%02d/%s" % [
|
63
|
-
server, @year, @month, @day, @hour_of_run, filename
|
64
|
-
]
|
65
|
-
path = File.join(cachename, pathname, filename)
|
47
|
+
path = File.join(dirname, filename)
|
66
48
|
|
67
49
|
# puts "Downloading '#{url}.idx' ..."
|
68
|
-
cmd = "#{curl} -o #{path}.idx #{url}.idx"
|
69
|
-
|
50
|
+
cmd = "#{curl} -fsS -o #{path}.idx #{url}.idx"
|
51
|
+
raise "Download of '#{url}.idx' failed" unless system(cmd)
|
70
52
|
|
71
53
|
lines = IO.readlines("#{path}.idx")
|
72
54
|
n = lines.count
|
@@ -90,10 +72,28 @@ module Forecaster
|
|
90
72
|
system("rm #{path}.idx")
|
91
73
|
|
92
74
|
# puts "Downloading '#{url}' ..."
|
93
|
-
cmd = "#{curl} -r #{ranges.join(",")} -o #{path} #{url}"
|
94
|
-
|
75
|
+
cmd = "#{curl} -fsS -r #{ranges.join(",")} -o #{path} #{url}"
|
76
|
+
raise "Download of '#{url}' failed" unless system(cmd)
|
95
77
|
|
96
78
|
self
|
97
79
|
end
|
80
|
+
|
81
|
+
def read(field, latitude: 0.0, longitude: 0.0)
|
82
|
+
wgrib2 = Forecaster.configuration.wgrib2_path
|
83
|
+
record = Forecaster.configuration.records[field]
|
84
|
+
path = File.join(dirname, filename)
|
85
|
+
|
86
|
+
raise "'#{path}' not found" unless File.exists?(path)
|
87
|
+
|
88
|
+
coords = "#{longitude} #{latitude}"
|
89
|
+
output = `#{wgrib2} #{path} -lon #{coords} -match "#{record}"`
|
90
|
+
|
91
|
+
raise "Could not read '#{record}' in '#{path}'" if output.empty?
|
92
|
+
|
93
|
+
fields = output.split("\n").first.split(":")
|
94
|
+
params = Hash[*fields.last.split(",").map { |s| s.split("=") }.flatten]
|
95
|
+
|
96
|
+
params["val"]
|
97
|
+
end
|
98
98
|
end
|
99
99
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: forecaster
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vincent Ollivier
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-06-09 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Wrapper around curl and wgrib2 to fetch and read GFS data
|
14
14
|
email: v@vinc.cc
|
@@ -39,7 +39,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
39
39
|
version: '0'
|
40
40
|
requirements: []
|
41
41
|
rubyforge_project:
|
42
|
-
rubygems_version: 2.
|
42
|
+
rubygems_version: 2.4.5.1
|
43
43
|
signing_key:
|
44
44
|
specification_version: 4
|
45
45
|
summary: Wrapper around curl and wgrib2 to fetch and read GFS data
|