gribr 0.2.0

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.
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