bel 0.2.1 → 0.3.0.beta1

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/bel2rdf ADDED
@@ -0,0 +1,134 @@
1
+ #!/usr/bin/env ruby
2
+ # bel2rdf: Convert BEL to RDF triples.
3
+ #
4
+ # From BEL file
5
+ # usage: bel2rdf -b file.bel
6
+ #
7
+ # From file
8
+ # usage: bel2rdf --bel [FILE]
9
+ #
10
+ # From standard in
11
+ # usage: echo "<BEL DOCUMENT STRING>" | bel2rdf
12
+ #
13
+ # Format option
14
+ # usage: bel2rdf --bel [FILE] --format [ntriples | nquads | turtle]
15
+
16
+ require 'bel'
17
+ require 'optparse'
18
+ require 'set'
19
+ require 'open-uri'
20
+
21
+ # setup and parse options
22
+ options = {
23
+ format: 'ntriples',
24
+ schema: false
25
+ }
26
+ OptionParser.new do |opts|
27
+ opts.banner = '''Converts BEL statements to RDF triples.
28
+ Usage: bel2rdf --bel [FILE]'''
29
+
30
+ opts.on('-b', '--bel FILE', 'BEL file to convert. STDIN (standard in) can also be used for BEL content.') do |bel|
31
+ options[:bel] = bel
32
+ end
33
+
34
+ opts.on('-f', '--format FORMAT', 'RDF file format.') do |format|
35
+ options[:format] = format.downcase
36
+ end
37
+
38
+ opts.on('-s', '--[no-]schema', 'Write BEL RDF schema?') do |schema|
39
+ options[:schema] = schema
40
+ end
41
+ end.parse!
42
+
43
+ # option guards
44
+ unless options[:bel] or not STDIN.tty?
45
+ $stderr.puts "No bel content provided. Either use --bel option or STDIN (standard in). Use -h / --help for details."
46
+ exit 1
47
+ end
48
+ if options[:bel] and not File.exists? options[:bel]
49
+ $stderr.puts "No file for bel, #{options[:bel]}"
50
+ exit 1
51
+ end
52
+ unless ['ntriples', 'nquads', 'turtle'].include? options[:format]
53
+ $stderr.puts "Format was not one of: ntriples, nquads, or turtle"
54
+ exit 1
55
+ end
56
+
57
+
58
+ class Main
59
+ include BEL::Language
60
+
61
+ def initialize(content, writer)
62
+ BEL::Script.parse(content).find_all { |obj|
63
+ obj.is_a? Statement
64
+ }.each do |stmt|
65
+ triples = stmt.to_rdf[1]
66
+ triples.each do |triple|
67
+ writer << triple
68
+ end
69
+ end
70
+ end
71
+ end
72
+
73
+ class Serializer
74
+ attr_reader :writer
75
+
76
+ def initialize(stream, format)
77
+ rdf_writer = find_writer(format)
78
+ @writer = rdf_writer.new($stdout, {
79
+ :stream => stream
80
+ }
81
+ )
82
+ end
83
+
84
+ def <<(trpl)
85
+ @writer.write_statement(RDF::Statement(*trpl))
86
+ end
87
+
88
+ def done
89
+ @writer.write_epilogue
90
+ end
91
+
92
+ private
93
+
94
+ def find_writer(format)
95
+ case format
96
+ when 'nquads'
97
+ BEL::RDF::RDF::NQuads::Writer
98
+ when 'turtle'
99
+ begin
100
+ require 'rdf/turtle'
101
+ BEL::RDF::RDF::Turtle::Writer
102
+ rescue LoadError
103
+ $stderr.puts """Turtle format not supported.
104
+ Install the 'rdf-turtle' gem."""
105
+ raise
106
+ end
107
+ when 'ntriples'
108
+ BEL::RDF::RDF::NTriples::Writer
109
+ end
110
+ end
111
+ end
112
+
113
+ # create writer for format
114
+ rdf_writer = ::Serializer.new(true, options[:format])
115
+
116
+ # first write schema if desired
117
+ if options[:schema]
118
+ BEL::RDF::vocabulary_rdf.each do |trpl|
119
+ rdf_writer << trpl
120
+ end
121
+ end
122
+
123
+ # read bel content
124
+ content =
125
+ if options[:bel]
126
+ File.open(options[:bel]).read
127
+ else
128
+ $stdin.read
129
+ end
130
+
131
+ # parse and write rdf
132
+ Main.new(content, rdf_writer)
133
+ # vim: ts=2 sw=2:
134
+ # encoding: utf-8
data/bin/bel_compare ADDED
@@ -0,0 +1,177 @@
1
+ #!/usr/bin/env ruby
2
+ # vim: ts=2 sw=2
3
+
4
+ require 'optparse'
5
+ require 'bel'
6
+ include BEL::Language
7
+ include BEL::Namespace
8
+
9
+ USAGE = "Usage: #{File.basename(__FILE__)} [options] [file] [file]"
10
+
11
+ options = {}
12
+ OptionParser.new do |opts|
13
+ opts.banner = USAGE
14
+
15
+ opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
16
+ options[:verbose] = v
17
+ end
18
+ opts.on_tail("-h", "--help", "Show usage and options") do
19
+ puts opts
20
+ exit
21
+ end
22
+ end.parse!
23
+
24
+ if ARGV.length != 2
25
+ $stderr.puts "Need to specify two BEL files."
26
+ $stderr.puts USAGE
27
+ exit 1
28
+ end
29
+
30
+ def fetch_groups(bel)
31
+ groups = {}
32
+ active_group = nil
33
+ BEL::Script.parse(bel) do |obj|
34
+ if obj.is_a? BEL::Language::StatementGroup
35
+ active_group = obj
36
+ end
37
+ if obj.is_a? BEL::Language::UnsetStatementGroup
38
+ groups[obj.name] = active_group
39
+ end
40
+ end
41
+ groups
42
+ end
43
+
44
+ threads = []
45
+ first_groups = {}
46
+ second_groups = {}
47
+ threads << Thread.new {
48
+ first_groups.update(fetch_groups(File.read(ARGV[0])))
49
+ }
50
+
51
+ threads << Thread.new {
52
+ second_groups.update(fetch_groups(File.read(ARGV[1])))
53
+ }
54
+
55
+ threads.each { |t| t.join }
56
+
57
+ group_diff = second_groups.length - first_groups.length
58
+ if group_diff == 0
59
+ puts "Equal number of statement groups."
60
+ elsif group_diff > 0
61
+ puts "Second file has #{group_diff} more statement groups."
62
+ else
63
+ puts "Second file has #{group_diff.abs} less statement groups."
64
+ end
65
+
66
+ first_statements = first_groups.values.
67
+ map {|group| group.statements.map {|s| s.to_bel} }.flatten
68
+ puts "First file has #{first_statements.length} statements."
69
+ second_statements = second_groups.values.
70
+ map {|group| group.statements.map {|s| s.to_bel}}.flatten
71
+ puts "Second file has #{second_statements.length} statements."
72
+
73
+ # statement groups in 1st, but not 2nd
74
+ first_groups.each do |name,first|
75
+ second = second_groups[name]
76
+ if not second
77
+ puts "#{name}, in 1st but not 2nd."
78
+ end
79
+ end
80
+
81
+ # statement groups in 2nd, but not 1st
82
+ second_groups.each do |name,second|
83
+ first = first_groups[name]
84
+ if not first
85
+ puts "#{name}, in 2nd but not 1st."
86
+ end
87
+ end
88
+
89
+ # differences between statement group intersection
90
+ first_groups.each do |name,first|
91
+ second = second_groups[name]
92
+ if second
93
+ first_stmt = first.statements ? first.statements.map {|s| s.to_bel } : []
94
+ second_stmt = second.statements ? second.statements.map {|s| s.to_bel } : []
95
+ if first_stmt == second_stmt
96
+ if options[:verbose]
97
+ puts "#{name}, both contain zero statements" if first_stmt.empty?
98
+ puts "#{name}, both contain #{first_stmt.length} statements"
99
+ end
100
+ else
101
+ puts "#{name}:"
102
+ if options[:verbose]
103
+ puts " 1st contains #{first_stmt.length} statements"
104
+ puts " 2nd contains #{second_stmt.length} statements"
105
+ puts " common to both, #{(first_stmt & second_stmt).length}"
106
+ puts (first_stmt & second_stmt).map {|stmt| stmt.to_s}.join("\n ").prepend(" ")
107
+ end
108
+
109
+ ab = first_stmt - second_stmt
110
+ puts " statements only in 1st, #{ab.length} (1st - 2nd)"
111
+ if ab.length > 0
112
+ puts ab.map {|stmt| stmt.to_s}.join("\n ").prepend(" ")
113
+ end
114
+
115
+ ba = second_stmt - first_stmt
116
+ puts " statements only in 2nd, #{ba.length} (2nd - 1st)"
117
+ if ba.length > 0
118
+ puts ba.map {|stmt| stmt.to_s}.join("\n ").prepend(" ")
119
+ end
120
+ end
121
+ end
122
+ end
123
+
124
+ first_terms = first_groups.values.
125
+ map { |group| group.statements }.flatten.
126
+ map { |stmt|
127
+ l = [stmt.subject.to_bel]
128
+ if stmt.simple?
129
+ l << stmt.object.to_bel
130
+ elsif stmt.nested?
131
+ l << stmt.object.subject.to_bel
132
+ l << stmt.object.object.to_bel
133
+ end
134
+ l
135
+ }.flatten.uniq.
136
+ sort {|term1,term2| term1.to_s <=> term2.to_s}
137
+ second_terms = second_groups.values.
138
+ map { |group| group.statements }.flatten.
139
+ map { |stmt|
140
+ l = [stmt.subject.to_bel]
141
+ if stmt.simple?
142
+ l << stmt.object.to_bel
143
+ elsif stmt.nested?
144
+ l << stmt.object.subject.to_bel
145
+ l << stmt.object.object.to_bel
146
+ end
147
+ l
148
+ }.flatten.uniq.
149
+ sort {|term1,term2| term1.to_s <=> term2.to_s}
150
+
151
+ # statements
152
+ puts "Statements:"
153
+ ab = first_statements - second_statements
154
+ puts " only in 1st, #{ab.length} (1st - 2nd)"
155
+ if ab.length > 0
156
+ puts ab.map {|t| t.to_s}.join("\n ").prepend(" ")
157
+ end
158
+
159
+ ba = second_statements - first_statements
160
+ puts " only in 2nd, #{ba.length} (2nd - 1st)"
161
+ if ba.length > 0
162
+ puts ba.map {|t| t.to_s}.join("\n ").prepend(" ")
163
+ end
164
+
165
+ # terms
166
+ puts "Terms:"
167
+ ab = first_terms - second_terms
168
+ puts " only in 1st, #{ab.length} (1st - 2nd)"
169
+ if ab.length > 0
170
+ puts ab.map {|t| t.to_s}.join("\n ").prepend(" ")
171
+ end
172
+
173
+ ba = second_terms - first_terms
174
+ puts " only in 2nd, #{ba.length} (2nd - 1st)"
175
+ if ba.length > 0
176
+ puts ba.map {|t| t.to_s}.join("\n ").prepend(" ")
177
+ end
data/bin/bel_parse ADDED
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env ruby
2
+ # bel_parse: Show parsed objects from BEL content for debugging purposes.
3
+ #
4
+ # From BEL file
5
+ # usage: bel_parse -b file.bel
6
+ #
7
+ # From standard in
8
+ # usage: echo "<BEL DOCUMENT STRING>" | bel_parse
9
+
10
+ require 'bel'
11
+ require 'optparse'
12
+
13
+ # additive String helpers
14
+ class String
15
+ def rjust_relative(distance, string)
16
+ rjust(distance - string.size + size)
17
+ end
18
+ end
19
+
20
+ # setup and parse options
21
+ options = {}
22
+ OptionParser.new do |opts|
23
+ opts.banner = "Usage: bel_parse [options] [.bel file]"
24
+ opts.on('-b', '--bel FILE', 'BEL file to parse. STDIN (standard in) can also be used for BEL content.') do |bel|
25
+ options[:bel] = bel
26
+ end
27
+ end.parse!
28
+
29
+ # option guards
30
+ unless options[:bel] or not STDIN.tty?
31
+ $stderr.puts "No bel content provided. Either use --bel option or STDIN (standard in). Use -h / --help for details."
32
+ exit 1
33
+ end
34
+
35
+ if options[:bel] and not File.exists? options[:bel]
36
+ $stderr.puts "No file for bel, #{options[:bel]}"
37
+ exit 1
38
+ end
39
+
40
+ # read bel content
41
+ content =
42
+ if options[:bel]
43
+ File.open(options[:bel]).read
44
+ else
45
+ $stdin.read
46
+ end
47
+
48
+ class Main
49
+
50
+ def initialize(content)
51
+ BEL::Script.parse(content) do |obj|
52
+ object_desc = obj.class.name.split('::').last
53
+ object_desc << obj.to_bel.rjust_relative(25, object_desc)
54
+ puts object_desc
55
+ end
56
+ end
57
+ end
58
+ Main.new(content)
59
+ # vim: ts=2 sw=2:
60
+ # encoding: utf-8
data/bin/bel_rdfschema ADDED
@@ -0,0 +1,72 @@
1
+ #!/usr/bin/env ruby
2
+ # bel_rdfschema: Dump RDF schema for BEL.
3
+ # usage: bel_rdfschema --format [ntriples | nquads | turtle]
4
+
5
+ require 'bel'
6
+ require 'optparse'
7
+ require 'set'
8
+ require 'open-uri'
9
+
10
+ options = {
11
+ format: 'ntriples'
12
+ }
13
+ OptionParser.new do |opts|
14
+ opts.banner = '''Dumps RDF schema for BEL.
15
+ Usage: bel_rdfschema'''
16
+
17
+ opts.on('-f', '--format FORMAT', 'RDF file format.') do |format|
18
+ options[:format] = format.downcase
19
+ end
20
+ end.parse!
21
+
22
+ unless ['ntriples', 'nquads', 'turtle'].include? options[:format]
23
+ $stderr.puts "Format was not one of: ntriples, nquads, or turtle"
24
+ exit 1
25
+ end
26
+
27
+ class Serializer
28
+ attr_reader :writer
29
+
30
+ def initialize(stream, format)
31
+ rdf_writer = find_writer(format)
32
+ @writer = rdf_writer.new($stdout, {
33
+ :stream => stream
34
+ }
35
+ )
36
+ end
37
+
38
+ def <<(trpl)
39
+ @writer.write_statement(RDF::Statement(*trpl))
40
+ end
41
+
42
+ def done
43
+ @writer.write_epilogue
44
+ end
45
+
46
+ private
47
+
48
+ def find_writer(format)
49
+ case format
50
+ when 'nquads'
51
+ BEL::RDF::RDF::NQuads::Writer
52
+ when 'turtle'
53
+ begin
54
+ require 'rdf/turtle'
55
+ BEL::RDF::RDF::Turtle::Writer
56
+ rescue LoadError
57
+ $stderr.puts """Turtle format not supported.
58
+ Install the 'rdf-turtle' gem."""
59
+ raise
60
+ end
61
+ when 'ntriples'
62
+ BEL::RDF::RDF::NTriples::Writer
63
+ end
64
+ end
65
+ end
66
+
67
+ @rdf_writer = ::Serializer.new(true, options[:format])
68
+ BEL::RDF::vocabulary_rdf.each do |trpl|
69
+ @rdf_writer << trpl
70
+ end
71
+ # vim: ts=2 sw=2:
72
+ # encoding: utf-8
data/bin/bel_summarize ADDED
@@ -0,0 +1,86 @@
1
+ #!/usr/bin/env ruby
2
+ # vim: ts=2 sw=2
3
+
4
+ require 'bel'
5
+ require 'csv'
6
+ require 'optparse'
7
+ include BEL::Language
8
+ include BEL::Namespace
9
+
10
+ options = {}
11
+ OptionParser.new do |opts|
12
+ opts.banner = '''Statistic report for BEL script.
13
+ Usage: bel_summarize --bel [FILE]'''
14
+
15
+ opts.on('-b', '--bel FILE', 'BEL file to summarize. STDIN (standard in) can also be used for BEL content.') do |bel|
16
+ options[:bel] = bel
17
+ end
18
+ end.parse!
19
+
20
+ # read bel content
21
+ content =
22
+ if options[:bel]
23
+ File.open(options[:bel]).read
24
+ else
25
+ $stdin.read
26
+ end
27
+
28
+ CSV do |csv_out|
29
+ report = {
30
+ statement_group_count: 0,
31
+ empty_statement_groups: 0,
32
+ statement_count: 0,
33
+ evidence_count: 0
34
+ }
35
+
36
+ FUNCTIONS.each do |k, v|
37
+ report['fx_' + v[:long_form].to_s] = 0
38
+ end
39
+
40
+ RELATIONSHIPS.each do |r|
41
+ report['rel_' + r.to_s] = 0
42
+ end
43
+
44
+ active_group = nil
45
+ BEL::Script.parse(content) do |obj|
46
+ if obj.is_a? BEL::Language::StatementGroup
47
+ report[:statement_group_count] += 1
48
+ active_group = obj
49
+ end
50
+ if obj.is_a? BEL::Language::UnsetStatementGroup
51
+ if active_group.statements.empty?
52
+ report[:empty_statement_groups] += 1
53
+ end
54
+ end
55
+ if obj.is_a? BEL::Language::Term
56
+ report['fx_' + obj.fx[:long_form].to_s] += 1
57
+ end
58
+ if obj.is_a? BEL::Language::Statement
59
+ report[:statement_count] += 1
60
+ obj.relationship = case obj.relationship
61
+ when :"->"
62
+ :increases
63
+ when :"-|"
64
+ :decreases
65
+ when :"=>"
66
+ :directlyIncreases
67
+ when :"=|"
68
+ :directlyDecreases
69
+ when :"--"
70
+ :association
71
+ else
72
+ obj.relationship
73
+ end
74
+
75
+ if obj.relationship
76
+ report['rel_' + obj.relationship.to_s] += 1
77
+ end
78
+ end
79
+ if obj.is_a? BEL::Language::Annotation
80
+ report[:evidence_count] += 1 if obj.name == 'Evidence'
81
+ end
82
+ end
83
+
84
+ csv_out << report.keys
85
+ csv_out << report.values
86
+ end