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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bc80587e750da30fa99b3a4b1309c3a67d792f86
4
- data.tar.gz: 42f6e928fc8c09c02ea0de356642884e16e10f30
3
+ metadata.gz: 2a5197a183958f87c3231d9794568fd71794c5b5
4
+ data.tar.gz: d33426c83219a0a7d813be7dea525a8426cc61ad
5
5
  SHA512:
6
- metadata.gz: aeb8bf4f69a32551e3c2e8cbebb96378979644eefcb8bb239c7d8035c79d489c4031d1a451de812b592140cd37daeee006bfe826578e5b381aa69ed742b42dd1
7
- data.tar.gz: 4ec0004fc10aad0a25b675c041eb975636dda8f8978952173da92f0a8f41938fa382730c60aa573747a1b3d04c688e1229ec7f4c24c1683f22ab321228552a3c
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, :wgrib2, :cache_dir, :records
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: "PRATE:surface",
11
- tmp: "TMP:2 m above ground",
12
- ugrd: "UGRD:10 m above ground",
13
- vgrd: "VGRD:10 m above ground",
14
- tcdc: "TCDC:entire atmosphere"
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
 
@@ -10,63 +10,45 @@ module Forecaster
10
10
  @hour_of_forecast = hour_of_forecast
11
11
  end
12
12
 
13
- def read(field, latitude: 0.0, longitude: 0.0)
14
- wgrib2 = Forecaster.configuration.wgrib2
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
- path = File.join(cachename, pathname, filename)
25
-
26
- raise "'#{path}' not found" unless File.exists?(path)
17
+ File.join(Forecaster.configuration.cache_dir, subdir)
18
+ end
27
19
 
28
- out = `#{wgrib2} #{path} -lon #{longitude} #{latitude} -match "#{record}"`
29
- lines = out.split("\n")
30
- fields = lines.first.split(":")
31
- params = Hash[*fields.last.split(",").map { |s| s.split("=") }.flatten]
20
+ def filename
21
+ "gfs.t%02dz.pgrb2.0p25.f%03d" % [
22
+ @hour_of_run, @hour_of_forecast
23
+ ]
24
+ end
32
25
 
33
- params["val"]
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
- cachename = Forecaster.configuration.cache_dir
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
- server = Forecaster.configuration.server
51
- cachename = Forecaster.configuration.cache_dir
52
- curl = "curl -f -s -S"
43
+ curl = Forecaster.configuration.curl_path
53
44
 
54
- pathname = "%04d%02d%02d%02d%" % [
55
- @year, @month, @day, @hour_of_run
56
- ]
57
- FileUtils.mkpath(File.join(cachename, pathname))
45
+ FileUtils.mkpath(File.join(dirname))
58
46
 
59
- filename = "gfs.t%02dz.pgrb2.0p25.f%03d" % [
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
- return self unless system(cmd)
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
- return self unless system(cmd)
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.1
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: 2015-05-04 00:00:00.000000000 Z
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.2.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