bel 0.2.1 → 0.3.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
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