seis_ruby 0.0.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.
- data/bin/seis_ruby +17 -0
- data/lib/seis_ruby/data/cmtsolution.rb +62 -0
- data/lib/seis_ruby/data/sac.rb +6 -0
- data/lib/seis_ruby/data.rb +6 -0
- data/lib/seis_ruby/io/gcmt_catalog/custom_html_parser.rb +13 -0
- data/lib/seis_ruby/io/gcmt_catalog.rb +42 -0
- data/lib/seis_ruby/io.rb +5 -0
- data/lib/seis_ruby/version.rb +3 -0
- data/lib/seis_ruby.rb +5 -0
- data/rakefile +8 -0
- data/seis_ruby.gemspec +18 -0
- data/spec/seis_ruby/data/cmtsolution_spec.rb +98 -0
- data/spec/seis_ruby/io/gcmt_catalog_spec.rb +20 -0
- data/spec/seis_ruby/io/scrape.yaml +3970 -0
- data/spec/spec_helper.rb +16 -0
- metadata +121 -0
data/bin/seis_ruby
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'thor'
|
4
|
+
class SeisRubyRunner < Thor
|
5
|
+
require 'seis_ruby'
|
6
|
+
require 'ruby_patch'
|
7
|
+
require 'yaml'
|
8
|
+
|
9
|
+
desc 'gcmt_catalog_scrape URL', 'scrape cmtsolution data from GCMT catalog search result pages.'
|
10
|
+
def gcmt_catalog_scrape(url)
|
11
|
+
file = "#{__METHOD__}_#{Time.now.ymdhms}.yaml"
|
12
|
+
open(file, 'w').write(SeisRuby::Io::GcmtCatalog.scrape(url).to_yaml)
|
13
|
+
puts file
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
SeisRubyRunner.start
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module SeisRuby
|
2
|
+
module Data
|
3
|
+
module Cmtsolution
|
4
|
+
require 'rainbow'
|
5
|
+
require 'ruby_patch/string'
|
6
|
+
|
7
|
+
ParseError = Class.new(StandardError)
|
8
|
+
|
9
|
+
module_function
|
10
|
+
|
11
|
+
def _preprocess_for_parse(text_for_one_event)
|
12
|
+
text_for_one_event\
|
13
|
+
.sub(/\A\n*/, '')\
|
14
|
+
.sub(/\n*\z/, '')\
|
15
|
+
.split("\n")
|
16
|
+
end
|
17
|
+
|
18
|
+
def _parse_lines(lines)
|
19
|
+
h = {hypocenter: {}, centroid: {}}
|
20
|
+
|
21
|
+
line0 = lines[0]
|
22
|
+
h[:hypocenter][:data_source] = line0[0..4].strip
|
23
|
+
line0_rest = line0[5..-1].split
|
24
|
+
[:year, :month, :day, :hour, :minute].each{|k|
|
25
|
+
raise ParseError if line0_rest.empty?
|
26
|
+
h[:hypocenter][k] = line0_rest.shift.to_i
|
27
|
+
}
|
28
|
+
[:second, :latitude, :longitude, :depth, :mb, :ms].each{|k|
|
29
|
+
raise ParseError if line0_rest.empty?
|
30
|
+
h[:hypocenter][k] = line0_rest.shift.to_f
|
31
|
+
}
|
32
|
+
h[:hypocenter][:region_name] = line0_rest.join(' ')
|
33
|
+
h[:event_name] = lines[1].split(':')[1].strip
|
34
|
+
values = lines[2..-1].map{|line| line.split(':')[1].to_f}
|
35
|
+
[
|
36
|
+
:time_shift, :half_duration,
|
37
|
+
:latitude, :longitude, :depth,
|
38
|
+
:mrr, :mtt, :mpp, :mrt, :mrp, :mtp,
|
39
|
+
].zip(values).each{|k, v| h[:centroid][k] = v}
|
40
|
+
|
41
|
+
|
42
|
+
h
|
43
|
+
end
|
44
|
+
|
45
|
+
def parse(text_for_one_event)
|
46
|
+
begin
|
47
|
+
lines = _preprocess_for_parse(text_for_one_event)
|
48
|
+
_parse_lines(lines)
|
49
|
+
rescue
|
50
|
+
raise ParseError, text_for_one_event\
|
51
|
+
.split("\n")\
|
52
|
+
.map{|line| line.quote('|'.color(:red))}\
|
53
|
+
.join("\n")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def parse_list(events)
|
58
|
+
events.map{|ev| parse(ev)}
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module SeisRuby
|
2
|
+
module Io
|
3
|
+
module GcmtCatalog
|
4
|
+
require 'mechanize'
|
5
|
+
|
6
|
+
class CustomHtmlParser < ::Mechanize::Page
|
7
|
+
def initialize(uri = nil, response = nil, body = nil, code = nil, mech = nil)
|
8
|
+
super(uri, response, body.gsub(/<=/, '<='), code, mech)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module SeisRuby
|
2
|
+
module Io
|
3
|
+
module GcmtCatalog
|
4
|
+
require 'rainbow'
|
5
|
+
require 'mechanize'
|
6
|
+
require 'seis_ruby/io/gcmt_catalog/custom_html_parser'
|
7
|
+
require 'seis_ruby/data/cmtsolution'
|
8
|
+
|
9
|
+
module_function
|
10
|
+
|
11
|
+
def scrape(url)
|
12
|
+
agent = Mechanize.new{|a|
|
13
|
+
a.pluggable_parser.html = ::SeisRuby::Io::GcmtCatalog::CustomHtmlParser
|
14
|
+
}
|
15
|
+
|
16
|
+
event_list = []
|
17
|
+
while url
|
18
|
+
agent.get(url)
|
19
|
+
agent.page.search('pre')\
|
20
|
+
.find{|e| e.text =~ /event name:/}\
|
21
|
+
.text.split("\n\n")\
|
22
|
+
.each{|event|
|
23
|
+
begin
|
24
|
+
event_list << ::SeisRuby::Data::Cmtsolution.parse(event) unless event.strip.empty?
|
25
|
+
rescue ::SeisRuby::Data::Cmtsolution::ParseError => e
|
26
|
+
$stderr.puts e.class.to_s.color(:red)
|
27
|
+
$stderr.puts e.message
|
28
|
+
end
|
29
|
+
}
|
30
|
+
|
31
|
+
url = nil
|
32
|
+
if next_link = agent.page.links\
|
33
|
+
.find{|e| e.text == 'More solutions'}
|
34
|
+
url = next_link.uri
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
event_list
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/seis_ruby/io.rb
ADDED
data/lib/seis_ruby.rb
ADDED
data/rakefile
ADDED
data/seis_ruby.gemspec
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
gem_name = File.basename(Dir.pwd)
|
2
|
+
require "./lib/#{gem_name}/version"
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.files = `git ls-files`.split
|
6
|
+
s.name = gem_name
|
7
|
+
s.summary = "Ruby library for earthquake science."
|
8
|
+
s.version = SeisRuby::VERSION
|
9
|
+
s.add_development_dependency 'rspec', '~> 2'
|
10
|
+
s.add_development_dependency 'simplecov', '~> 0'
|
11
|
+
s.add_runtime_dependency 'rainbow', '~>1'
|
12
|
+
s.add_runtime_dependency 'mechanize', '~>2'
|
13
|
+
s.add_runtime_dependency 'ruby_patch', ['>= 0.1.0', '< 1.0.0']
|
14
|
+
s.author = 'kshramt'
|
15
|
+
s.description = "Ruby library for earthquake science. Provides Parser for various data formats used in seismology."
|
16
|
+
s.required_ruby_version = '>= 1.9.0'
|
17
|
+
s.test_files.concat `git ls-files spec`.split.select{|path| path =~ /_spec\.rb/}
|
18
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'seis_ruby/data/cmtsolution'
|
3
|
+
|
4
|
+
describe ::SeisRuby::Data::Cmtsolution do
|
5
|
+
before :each do
|
6
|
+
@valid_data = <<-EOS
|
7
|
+
1980 12 7 17 37 9.70 36.0300 1.2300 10.0 0.0 0.0
|
8
|
+
event name: 120780A
|
9
|
+
time shift: 1.7000
|
10
|
+
half duration: 2.0000
|
11
|
+
latitude: 36.0200
|
12
|
+
longitude: 0.9400
|
13
|
+
depth: 25.8000
|
14
|
+
Mrr: 1.747000e+24
|
15
|
+
Mtt: -2.197000e+24
|
16
|
+
Mpp: 4.500000e+23
|
17
|
+
Mrt: 7.430000e+23
|
18
|
+
Mrp: 1.376000e+24
|
19
|
+
Mtp: -1.491000e+24
|
20
|
+
EOS
|
21
|
+
|
22
|
+
@parsed_valid_data = {
|
23
|
+
hypocenter: {
|
24
|
+
data_source: '',
|
25
|
+
year: 1980,
|
26
|
+
month: 12,
|
27
|
+
day: 7,
|
28
|
+
hour: 17,
|
29
|
+
minute: 37,
|
30
|
+
second: 9.70,
|
31
|
+
latitude: 36.03,
|
32
|
+
longitude: 1.23,
|
33
|
+
depth: 10.0,
|
34
|
+
mb: 0.0,
|
35
|
+
ms: 0.0,
|
36
|
+
region_name: ''
|
37
|
+
},
|
38
|
+
event_name: '120780A',
|
39
|
+
centroid: {
|
40
|
+
time_shift: 1.7,
|
41
|
+
half_duration: 2.0,
|
42
|
+
latitude: 36.02,
|
43
|
+
longitude: 0.94,
|
44
|
+
depth: 25.8,
|
45
|
+
mrr: 1.747e+24,
|
46
|
+
mtt: -2.197e+24,
|
47
|
+
mpp: 4.5e+23,
|
48
|
+
mrt: 7.43e+23,
|
49
|
+
mrp: 1.376e+24,
|
50
|
+
mtp: -1.491e+24,
|
51
|
+
},
|
52
|
+
}
|
53
|
+
|
54
|
+
@wrong_data = <<-EOS
|
55
|
+
1980 12 7 17 37 9.70 36.0300 1.2300 10.0 0.0
|
56
|
+
event name: 120780A
|
57
|
+
time shift: 1.7000
|
58
|
+
half duration: 2.0000
|
59
|
+
latitude: 36.0200
|
60
|
+
longitude: 0.9400
|
61
|
+
depth: 25.8000
|
62
|
+
Mrr: 1.747000e+24
|
63
|
+
Mtt: -2.197000e+24
|
64
|
+
Mpp: 4.500000e+23
|
65
|
+
Mrt: 7.430000e+23
|
66
|
+
Mrp: 1.376000e+24
|
67
|
+
Mtp: -1.491000e+24
|
68
|
+
EOS
|
69
|
+
end
|
70
|
+
|
71
|
+
describe '.parse' do
|
72
|
+
context 'normal case' do
|
73
|
+
it do
|
74
|
+
::SeisRuby::Data::Cmtsolution.parse(@valid_data).should == @parsed_valid_data
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context 'wrong case' do
|
79
|
+
it do
|
80
|
+
lambda{::SeisRuby::Data::Cmtsolution.parse(@wrong_data)}.should raise_error(::SeisRuby::Data::Cmtsolution::ParseError)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe '.parse_list' do
|
86
|
+
context 'normal case' do
|
87
|
+
it do
|
88
|
+
::SeisRuby::Data::Cmtsolution.parse_list([@valid_data, @valid_data]).should == [@parsed_valid_data, @parsed_valid_data]
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context 'wrong case' do
|
93
|
+
it do
|
94
|
+
lambda{::SeisRuby::Data::Cmtsolution.parse_list([@valid_data, @wrong_data])}.should raise_error(::SeisRuby::Data::Cmtsolution::ParseError)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'ruby_patch'
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'seis_ruby'
|
5
|
+
|
6
|
+
describe ::SeisRuby::Io::GcmtCatalog do
|
7
|
+
describe '.scrape' do
|
8
|
+
context 'normal case' do
|
9
|
+
it do
|
10
|
+
::SeisRuby::Io::GcmtCatalog.scrape('http://www.globalcmt.org/cgi-bin/globalcmt-cgi-bin/CMT4/form?itype=ymd&yr=1976&mo=1&day=1&oyr=1976&omo=1&oday=1&jyr=1976&jday=1&ojyr=1&ojday=1&otype=nd&nday=400&lmw=0&umw=10&lms=0&ums=10&lmb=0&umb=10&llat=-90&ulat=90&llon=-180&ulon=180&lhd=0&uhd=1000<s=-9999&uts=9999&lpe1=0&upe1=90&lpe2=0&upe2=90&list=4').should == YAML.load_file(File.join(__DIR__, 'scrape.yaml'))
|
11
|
+
end
|
12
|
+
|
13
|
+
context 'wrong case' do
|
14
|
+
it do
|
15
|
+
lambda{::SeisRuby::Io::GcmtCatalog.scrape('http://www.globalcmt.org/cgi-bin/globalcmt-cgi-bin/CMT4/form?itype=ymd&yr=1976&mo=1&day=1&oyr=1976&omo=1&oday=1&jyr=1976&jday=1&ojyr=1&ojday=1&otype=nd&nday=400&lmw=0&umw=10&lms=0&ums=10&lmb=0&umb=10&llat=-90&ulat=90&llon=-180&ulon=180&lhd=0&uhd=1000<s=-9999&uts=9999&lpe1=0&upe1=90&lpe2=0&upe2=90&list=3')}.should raise_error
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|