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 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,6 @@
1
+ module SeisRuby
2
+ module Data
3
+ module Sac
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module SeisRuby
2
+ module Data
3
+ require 'seis_ruby/data/cmtsolution'
4
+ require 'seis_ruby/data/sac'
5
+ end
6
+ 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(/<=/, '&lt;='), 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
@@ -0,0 +1,5 @@
1
+ module SeisRuby
2
+ module Io
3
+ require 'seis_ruby/io/gcmt_catalog'
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ module SeisRuby
2
+ VERSION = '0.0.0'
3
+ end
data/lib/seis_ruby.rb ADDED
@@ -0,0 +1,5 @@
1
+ module SeisRuby
2
+ require 'seis_ruby/version'
3
+ require 'seis_ruby/data'
4
+ require 'seis_ruby/io'
5
+ end
data/rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'rspec/core/rake_task'
2
+
3
+ task default: :spec
4
+
5
+ desc "Run specs"
6
+ RSpec::Core::RakeTask.new(:spec){|s|
7
+ s.rspec_opts = '-c'
8
+ }
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&lts=-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&lts=-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