forecaster 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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