gribr 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. data/.document +5 -0
  2. data/.gitignore +11 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +42 -0
  5. data/Rakefile +43 -0
  6. data/VERSION +1 -0
  7. data/gribr.gemspec +68 -0
  8. data/lib/gribr/core_ext/file.rb +38 -0
  9. data/lib/gribr/core_ext.rb +1 -0
  10. data/lib/gribr/degrib/cube.rb +15 -0
  11. data/lib/gribr/degrib/file.rb +78 -0
  12. data/lib/gribr/degrib/index.rb +51 -0
  13. data/lib/gribr/degrib/inventory.rb +24 -0
  14. data/lib/gribr/degrib/inventory_record.rb +44 -0
  15. data/lib/gribr/degrib/probe_record.rb +56 -0
  16. data/lib/gribr/degrib.rb +21 -0
  17. data/lib/gribr/executeable.rb +26 -0
  18. data/lib/gribr/inventory.rb +62 -0
  19. data/lib/gribr/utils.rb +23 -0
  20. data/lib/gribr/wgrib/inventory.rb +24 -0
  21. data/lib/gribr/wgrib/inventory_record.rb +51 -0
  22. data/lib/gribr/wgrib.rb +15 -0
  23. data/lib/gribr.rb +6 -0
  24. data/spec/fixtures/wind.grib +0 -0
  25. data/spec/gribr_spec.rb +9 -0
  26. data/spec/lib/gribr/core_ext/file_spec.rb +48 -0
  27. data/spec/lib/gribr/degrib/cube_spec.rb +20 -0
  28. data/spec/lib/gribr/degrib/file_spec.rb +69 -0
  29. data/spec/lib/gribr/degrib/index_spec.rb +83 -0
  30. data/spec/lib/gribr/degrib/inventory_record_spec.rb +121 -0
  31. data/spec/lib/gribr/degrib/inventory_spec.rb +47 -0
  32. data/spec/lib/gribr/degrib/probe_record_spec.rb +103 -0
  33. data/spec/lib/gribr/degrib_spec.rb +17 -0
  34. data/spec/lib/gribr/executeable_spec.rb +25 -0
  35. data/spec/lib/gribr/inventory_spec.rb +21 -0
  36. data/spec/lib/gribr/wgrib/inventory_record_spec.rb +60 -0
  37. data/spec/lib/gribr/wgrib/inventory_spec.rb +17 -0
  38. data/spec/lib/gribr/wgrib_spec.rb +17 -0
  39. data/spec/spec_helper.rb +9 -0
  40. metadata +127 -0
@@ -0,0 +1,51 @@
1
+ require 'gribr/utils'
2
+
3
+ module Gribr
4
+ module Wgrib
5
+
6
+ class InventoryRecord < Struct.new(:element, :end_position, :number, :start_position, :reference_time, :valid_time)
7
+
8
+ include Gribr::RegexpParser
9
+
10
+ def end_position_of_previous
11
+ start_position - 1 if number > 1
12
+ end
13
+
14
+ end
15
+
16
+ class ShortInventoryRecord < InventoryRecord
17
+
18
+ REGEX_TIMESTAMP = Regexp.new("(d=(\\d{2,4})(\\d{2})(\\d{2})(\\d{2}))").freeze
19
+
20
+ def self.build(match_data)
21
+
22
+ if match_data
23
+
24
+ record = new
25
+ record.number = match_data[1].to_i
26
+ record.start_position = match_data[2].to_i
27
+ record.element = match_data[8]
28
+
29
+ year = (match_data[4].size == 4 ? match_data[4] : Time.now.utc.year.to_s.gsub(/\d{2}$/, match_data[4])).to_i
30
+ record.valid_time = Time.utc(year, match_data[5].to_i, match_data[6].to_i, match_data[7].to_i)
31
+
32
+ # Calculte reference time
33
+ offset = match_data[10].split.first.to_i * 60 * 60
34
+ record.reference_time = record.valid_time + offset
35
+
36
+ record
37
+
38
+ end
39
+
40
+ end
41
+
42
+ def self.regexp
43
+ @regexp ||= Regexp.new("(\\d+):(\\d+):#{REGEX_TIMESTAMP}:(.+):(.+):(.+):(.+)").freeze
44
+ end
45
+
46
+ end
47
+
48
+ end
49
+
50
+ end
51
+
@@ -0,0 +1,15 @@
1
+ require 'gribr/wgrib/inventory'
2
+ require 'gribr/wgrib/inventory_record'
3
+
4
+ module Gribr
5
+
6
+ module Wgrib
7
+
8
+ def self.executeable
9
+ @executeable ||= Executable.new("wgrib")
10
+ end
11
+
12
+ end
13
+
14
+ end
15
+
data/lib/gribr.rb ADDED
@@ -0,0 +1,6 @@
1
+ require 'gribr/core_ext'
2
+ require 'gribr/degrib'
3
+ require 'gribr/executeable'
4
+ require 'gribr/inventory'
5
+ require 'gribr/wgrib'
6
+ require 'gribr/utils'
Binary file
@@ -0,0 +1,9 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "Gribr" do
4
+
5
+ it "should define the 'Gribr' module" do
6
+ Gribr.should be_kind_of(Module)
7
+ end
8
+
9
+ end
@@ -0,0 +1,48 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
2
+ require 'gribr/core_ext/file'
3
+
4
+ module Gribr::CoreExt
5
+
6
+ describe File do
7
+
8
+ before(:each) do
9
+ @filename = ::File.expand_path(::File.dirname(__FILE__) + '/../../../fixtures/wind.grib')
10
+ end
11
+
12
+ it "should exist" do
13
+ ::File.exists?(@filename).should be_true
14
+ end
15
+
16
+ it "should return true if the given file is a gribfile" do
17
+ ::File.gribfile?(@filename).should be_true
18
+ ::File.gribfile?(::File.new(@filename)).should be_true
19
+ end
20
+
21
+ it "should return false if the given file is not a gribfile" do
22
+ ::File.gribfile?(::File.new(__FILE__)).should be_false
23
+ ::File.gribfile?(__FILE__).should be_false
24
+ end
25
+
26
+ end
27
+
28
+ describe "An existing file" do
29
+
30
+ before(:each) do
31
+ @file = ::File.new("test", "w")
32
+ end
33
+
34
+ it "should exists" do
35
+ @file.exist?
36
+ end
37
+
38
+ it "should delete the file" do
39
+ @file.delete
40
+ end
41
+
42
+ it "should unlink the file" do
43
+ @file.unlink
44
+ end
45
+
46
+ end
47
+
48
+ end
@@ -0,0 +1,20 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
2
+
3
+ module Gribr::Degrib
4
+
5
+ describe Cube do
6
+
7
+ before(:each) do
8
+ @cube = File.new(File.dirname(__FILE__) + '/../../../fixtures/wind.grib').index.cube
9
+ end
10
+
11
+ it "should return the file extension name" do
12
+ Cube.extname.should == "dat"
13
+ end
14
+
15
+ it "should be kind of a ::File" do
16
+ @cube.should be_kind_of(::File)
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,69 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
2
+
3
+ module Gribr::Degrib
4
+
5
+ describe File do
6
+
7
+ before(:each) do
8
+ @latitude, @longitude = 0, 0
9
+ @filename = File.expand_path(File.dirname(__FILE__) + '/../../../fixtures/wind.grib')
10
+ @file = Gribr::Degrib::File.new(@filename)
11
+ end
12
+
13
+ after(:each) do
14
+ FileUtils.rm_f(@file.indexname)
15
+ end
16
+
17
+ it "should be kind of ::File" do
18
+ @file.should be_kind_of(::File)
19
+ end
20
+
21
+ it "should exists" do
22
+ File.exists?(@file).should be_true
23
+ end
24
+
25
+ it "should return the indexname (unix path)" do
26
+ @file.stub!(:path).and_return("/tmp/wind.grib")
27
+ @file.indexname.should == "/tmp/wind.idx"
28
+ end
29
+
30
+ it "should return the indexname (end-of-line bug)" do
31
+ @file.stub!(:path).and_return("/home/roman/workspace/gribr/spec/fixtures/t12z.HTSGW.grib")
32
+ @file.indexname.should == "/home/roman/workspace/gribr/spec/fixtures/t12z.HTSGW.idx"
33
+ end
34
+
35
+ it "should return the indexname (windows path)" do
36
+ @file.stub!(:path).and_return('C:\tmp\wind.grib')
37
+ @file.indexname.should == 'C:\tmp\wind.idx'
38
+ end
39
+
40
+ it "should not be indexed" do
41
+ @file.should_not be_indexed
42
+ end
43
+
44
+ it "should build the index" do
45
+ @file.index!.should be_true
46
+ @file.should be_indexed
47
+ end
48
+
49
+ it "should return the inventory" do
50
+ @file.inventory.should be_kind_of(Inventory)
51
+ end
52
+
53
+ it "should probe at the given position and return the records in an array" do
54
+ @file.probe(@latitude, @longitude).should be_kind_of(Array)
55
+ end
56
+
57
+ it "should probe at the given position and yield the records" do
58
+ @file.probe(@latitude, @longitude) { |record| record.should be_kind_of(ProbeRecord) }
59
+ end
60
+
61
+ it "should probe at the given position and yield the records" do
62
+ @file.index!
63
+ @file.probe(@latitude, @longitude) { |record| record.should be_kind_of(ProbeRecord) }
64
+ # @file.probe(@latitude, @longitude) { |record| puts record }
65
+ end
66
+
67
+ end
68
+
69
+ end
@@ -0,0 +1,83 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
2
+
3
+ module Gribr::Degrib
4
+
5
+ describe Index do
6
+
7
+ before(:each) do
8
+ @grib_filename = File.expand_path(File.dirname(__FILE__) + '/../../../fixtures/wind.grib')
9
+ end
10
+
11
+ it "should return the file extension name" do
12
+ Index.extname.should == "idx"
13
+ end
14
+
15
+ [::File, Pathname, String].each do |clazz|
16
+
17
+ it "should return the index command for the file given as #{clazz}" do
18
+ Index.command(clazz.new(@grib_filename)).should == "#{Gribr::Degrib.executeable.name} #{@grib_filename} -Data -Index #{File.new(@grib_filename).indexname}"
19
+ end
20
+
21
+ it "should create the index command for the file given as #{clazz}" do
22
+ Index.create(clazz.new(@grib_filename)).should be_kind_of(Index)
23
+ end
24
+
25
+ it "should create the index command for the file given as #{clazz} with bang" do
26
+ Index.create!(clazz.new(@grib_filename)).should be_kind_of(Index)
27
+ end
28
+
29
+ end
30
+
31
+ describe "A degrib index" do
32
+
33
+ before(:each) do
34
+ @file = File.new(File.expand_path(File.dirname(__FILE__) + '/../../../fixtures/wind.grib'))
35
+ @file.index!
36
+ @index = @file.index
37
+ end
38
+
39
+ it "should be kind of a ::File" do
40
+ @file.should be_kind_of(::File)
41
+ end
42
+
43
+ it "should exist" do
44
+ ::File.exist?(@file).should be_true
45
+ end
46
+
47
+ it "should return the cubename (unix path)" do
48
+ @index.stub!(:path).and_return("/tmp/wind.grib")
49
+ @index.cubename.should == "/tmp/wind.dat"
50
+ end
51
+
52
+ it "should return the cubename (end-of-line bug)" do
53
+ @index.stub!(:path).and_return("/home/roman/workspace/gribr/spec/fixtures/t12z.HTSGW.grib")
54
+ @index.cubename.should == "/home/roman/workspace/gribr/spec/fixtures/t12z.HTSGW.dat"
55
+ end
56
+
57
+ it "should return the cubename (windows path)" do
58
+ @index.stub!(:path).and_return('C:\tmp\wind.grib')
59
+ @index.cubename.should == 'C:\tmp\wind.dat'
60
+ end
61
+
62
+ it "should return the cube file" do
63
+ @index.cube.should be_kind_of(Cube)
64
+ end
65
+
66
+ it "should have an existing cube" do
67
+ ::File.exist?(@index.cubename).should be_true
68
+ end
69
+
70
+ it "should delete the index file" do
71
+ @index.delete
72
+ ::File.exist?(@index.path).should be_false
73
+ end
74
+
75
+ it "should delete the cube file with the index" do
76
+ @index.delete
77
+ ::File.exist?(@index.cubename).should be_false
78
+ end
79
+
80
+ end
81
+
82
+ end
83
+ end
@@ -0,0 +1,121 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
2
+
3
+ module Gribr::Degrib
4
+
5
+ describe InventoryRecord do
6
+
7
+ before(:each) do
8
+ @raw = '61.0, 3025800, 1, WIND="Wind speed [m/s]", 1-SFC, 09/10/2009 12:00, 09/18/2009 00:00, 180.00'
9
+ end
10
+
11
+ it "should parse degrib inventory record" do
12
+ InventoryRecord.parse(@raw).should be_kind_of(InventoryRecord)
13
+ end
14
+
15
+ it "should parse a degrib record (with bang)" do
16
+ InventoryRecord.parse!(@raw).should be_kind_of(InventoryRecord)
17
+ end
18
+
19
+ it "should return nil when parsing an invalid degrib inventory record" do
20
+ InventoryRecord.parse(@raw.reverse).should be_nil
21
+ end
22
+
23
+ it "should raise an ArgumentError when parsing an invalid degrib inventory record (with bang)" do
24
+ lambda { InventoryRecord.parse!(@raw.reverse) }.should raise_error(ArgumentError)
25
+ end
26
+
27
+ shared_examples_for "An inventory record" do
28
+
29
+ [:number, :start_position, :version].each do |attribute|
30
+
31
+ it "should have a Fixnum object as #{attribute} attribute" do
32
+ @record.send(attribute).should be_kind_of(Fixnum)
33
+ end
34
+
35
+ end
36
+
37
+ [ :description, :element, :unit, :level].each do |attribute|
38
+
39
+ it "should have a String object as #{attribute} attribute" do
40
+ @record.send(attribute).should be_kind_of(String)
41
+ end
42
+
43
+ end
44
+
45
+ [ :reference_time, :valid_time].each do |attribute|
46
+
47
+ it "should have a Time object as #{attribute} attribute" do
48
+ @record.send(attribute).should be_kind_of(Time)
49
+ end
50
+
51
+ it "should have a Time object in the UTC timezone as #{attribute} attribute" do
52
+ @record.send(attribute).zone.should == "UTC"
53
+ end
54
+
55
+ end
56
+
57
+ end
58
+
59
+ describe "Parsing a degrib inventory record" do
60
+
61
+ before(:each) do
62
+ @record = InventoryRecord.parse(@raw)
63
+ end
64
+
65
+ it_should_behave_like "An inventory record"
66
+
67
+ it "should assign the number" do
68
+ @record.number.should == 61
69
+ end
70
+
71
+ it "should assign the start position" do
72
+ @record.start_position.should == 3025800
73
+ end
74
+
75
+ it "should assign nil as end position" do
76
+ @record.end_position.should be_nil
77
+ end
78
+
79
+ it "should assign the end position of the previous record" do
80
+ @record.end_position_of_previous.should == 3025800 - 1
81
+ end
82
+
83
+ it "should not assign the end position of the previous record if first record" do
84
+ @record.number = 1
85
+ @record.end_position_of_previous.should be_nil
86
+ end
87
+
88
+ it "should assign the version" do
89
+ @record.version.should == 1
90
+ end
91
+
92
+ it "should assign the element" do
93
+ @record.element.should == "WIND"
94
+ end
95
+
96
+ it "should assign the description" do
97
+ @record.description.should == "Wind speed [m/s]"
98
+ end
99
+
100
+ it "should assign the unit" do
101
+ @record.unit.should == "m/s"
102
+ end
103
+
104
+ it "should assign the level" do
105
+ @record.level.should == "1-SFC"
106
+ end
107
+
108
+ it "should assign the reference time" do
109
+ @record.reference_time.should == Time.utc(2009, 9, 10, 12)
110
+ end
111
+
112
+ it "should assign the valid time" do
113
+ @record.valid_time.should == Time.utc(2009, 9, 18, 0)
114
+ end
115
+
116
+ end
117
+
118
+ end
119
+
120
+ end
121
+
@@ -0,0 +1,47 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
2
+ require File.expand_path(File.dirname(__FILE__) + '/../inventory_spec')
3
+ require 'tempfile'
4
+
5
+ module Gribr::Degrib
6
+
7
+ describe "A degrib inventory" do
8
+
9
+ before(:each) do
10
+ @inventory = Inventory.file(File.expand_path(File.dirname(__FILE__) + '/../../../fixtures/wind.grib'))
11
+ end
12
+
13
+ it_should_behave_like "An inventory"
14
+
15
+ end
16
+
17
+ describe Inventory do
18
+
19
+ before(:each) do
20
+ @gribfile = File.expand_path(File.dirname(__FILE__) + '/../../../fixtures/wind.grib')
21
+ end
22
+
23
+ it "should return the inventory for the given io" do
24
+ IO.popen("degrib #{@gribfile} -I") { |io| Inventory.io(io).should be_kind_of(Inventory) }
25
+ end
26
+
27
+ [::File, Pathname, String].each do |clazz|
28
+
29
+ it "should return the inventory command for the file given as #{clazz}" do
30
+ Inventory.command(clazz.new(@gribfile)).should == "degrib #{@gribfile} -I"
31
+ end
32
+
33
+ it "should parse the inventory from the given grib file" do
34
+ Inventory.file(clazz.new(@gribfile)).should be_kind_of(Inventory)
35
+ end
36
+
37
+ it "should parse the inventory from the content of the given file" do
38
+ Tempfile.open("inventory") do |tempfile|
39
+ system("degrib #{@gribfile} -I > #{tempfile.path}")
40
+ Inventory.file(clazz.new(tempfile.path)).should be_kind_of(Inventory)
41
+ end
42
+ end
43
+
44
+ end
45
+
46
+ end
47
+ end
@@ -0,0 +1,103 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
2
+
3
+ module Gribr::Degrib
4
+
5
+ describe ProbeRecord do
6
+
7
+ before(:each) do
8
+ @raw = "(43.421000,-2.684000), WIND[m/s], 200808041200, 200808041800, 1234.567"
9
+ end
10
+
11
+ it "should parse a valid a degrib record" do
12
+ ProbeRecord.parse(@raw).should be_kind_of(ProbeRecord)
13
+ end
14
+
15
+ it "should parse an invalid degrib record and return nil" do
16
+ ProbeRecord.parse(@raw.reverse).should be_nil
17
+ end
18
+
19
+ it "should parse a valid a degrib record (with bang)" do
20
+ ProbeRecord.parse!(@raw).should be_kind_of(ProbeRecord)
21
+ end
22
+
23
+ it "should parse an invalid degrib record and raise an ArgumentError" do
24
+ lambda { ProbeRecord.parse!(@raw.reverse) }.should raise_error(ArgumentError)
25
+ end
26
+
27
+ shared_examples_for "A degrib record" do
28
+
29
+ it "should have a latitude" do
30
+ @record.latitude.should be_kind_of(Float)
31
+ end
32
+
33
+ it "should have a longitude" do
34
+ @record.longitude.should be_kind_of(Float)
35
+ end
36
+
37
+ it "should have a element" do
38
+ @record.element.should be_kind_of(String)
39
+ end
40
+
41
+ it "should have a unit" do
42
+ @record.unit.should be_kind_of(String)
43
+ end
44
+
45
+ it "should have a reference time" do
46
+ @record.reference_time.should be_kind_of(::Time)
47
+ end
48
+
49
+ it "should have a valid time" do
50
+ @record.valid_time.should be_kind_of(::Time)
51
+ end
52
+
53
+ it "should have a value" do
54
+ @record.value.should be_kind_of(Float)
55
+ end
56
+
57
+ end
58
+
59
+ describe "A parsed degrib record representing wind speed" do
60
+
61
+ before(:each) do
62
+ @record = ProbeRecord.parse(@raw)
63
+ end
64
+
65
+ it_should_behave_like "A degrib record"
66
+
67
+ it "should have the expected latitude" do
68
+ @record.latitude.should == 43.421000
69
+ end
70
+
71
+ it "should have the expected longitude" do
72
+ @record.longitude.should == -2.684000
73
+ end
74
+
75
+ it "should have the expected element" do
76
+ @record.element.should == "WIND"
77
+ end
78
+
79
+ it "should have the expected unit" do
80
+ @record.unit.should == "m/s"
81
+ end
82
+
83
+ it "should have the expected reference time" do
84
+ @record.reference_time.should == ::Time.utc(2008, 8, 4, 12, 0)
85
+ end
86
+
87
+ it "should have the expected valid time" do
88
+ @record.valid_time.should == ::Time.utc(2008, 8, 4, 18, 0)
89
+ end
90
+
91
+ it "should have the expected value" do
92
+ @record.value.should == 1234.567
93
+ end
94
+
95
+ it "should return the expected string represantation" do
96
+ @record.to_s.should == "43.421\t-2.684\tWIND\tm/s\t2008-08-04 12:00:00\t2008-08-04 18:00:00\t1234.567"
97
+ end
98
+
99
+ end
100
+
101
+ end
102
+
103
+ end
@@ -0,0 +1,17 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ module Gribr
4
+
5
+ describe Degrib do
6
+
7
+ it "should return executeable" do
8
+ Degrib.executeable.should be_kind_of(Executable)
9
+ end
10
+
11
+ it "should return the wgrib executeable" do
12
+ Degrib.executeable.name.should == "degrib"
13
+ end
14
+
15
+ end
16
+
17
+ end
@@ -0,0 +1,25 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ module Gribr
4
+
5
+ describe "The 'ls' executable" do
6
+
7
+ before(:each) do
8
+ @executable = Executable.new("ls")
9
+ end
10
+
11
+ it "should return the name" do
12
+ @executable.name.should == "ls"
13
+ end
14
+
15
+ it "should return the full path" do
16
+ @executable.path.should == "/bin/ls"
17
+ end
18
+
19
+ it "should exist" do
20
+ @executable.should be_exist
21
+ end
22
+
23
+ end
24
+
25
+ end
@@ -0,0 +1,21 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ module Gribr
4
+
5
+ shared_examples_for "An inventory" do
6
+
7
+ it "should be an inventory" do
8
+ @inventory.should be_kind_of(Inventory)
9
+ end
10
+
11
+ it "should return the messages as an array" do
12
+ @inventory.messages.should be_kind_of(Array)
13
+ end
14
+
15
+ it "should return the messages sorted by number" do
16
+ @inventory.messages.each_cons(2) { |cons| cons.first.number.should < cons.last.number }
17
+ end
18
+
19
+ end
20
+
21
+ end