bel 0.3.3 → 0.4.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.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +53 -8
  3. data/bel.gemspec +10 -15
  4. data/bin/bel +63 -4
  5. data/bin/bel2rdf.rb +1 -1
  6. data/bin/bel_compare.rb +1 -1
  7. data/bin/bel_parse.rb +1 -1
  8. data/bin/bel_rdfschema.rb +1 -1
  9. data/bin/bel_summarize.rb +1 -1
  10. data/bin/bel_upgrade.rb +1 -1
  11. data/lib/bel.rb +8 -10
  12. data/lib/bel/completion.rb +3 -2
  13. data/lib/bel/completion/value_match_rule.rb +10 -0
  14. data/lib/bel/evidence_model/citation.rb +101 -43
  15. data/lib/bel/evidence_model/evidence.rb +2 -2
  16. data/lib/bel/evidence_model/experiment_context.rb +1 -0
  17. data/lib/bel/evidence_model/metadata.rb +15 -2
  18. data/lib/bel/evidence_model/references.rb +10 -10
  19. data/lib/bel/json.rb +63 -0
  20. data/lib/bel/json/adapter/multi_json.rb +36 -0
  21. data/lib/bel/json/adapter/oj.rb +65 -0
  22. data/lib/bel/json/adapter/ruby_json.rb +28 -0
  23. data/lib/bel/json/reader.rb +9 -0
  24. data/lib/bel/json/writer.rb +9 -0
  25. data/lib/bel/libbel.rb +1 -4
  26. data/lib/bel/parser.rb +2 -2
  27. data/lib/bel/rdf_repository.rb +18 -0
  28. data/lib/bel/rdf_repository/plugins/memory.rb +28 -0
  29. data/lib/bel/rdf_repository/plugins/mongo.rb +28 -0
  30. data/lib/bel/resource.rb +24 -0
  31. data/lib/bel/resource/namespace.rb +122 -0
  32. data/lib/bel/resource/namespace_value.rb +69 -0
  33. data/lib/bel/resource/namespaces.rb +83 -0
  34. data/lib/bel/resource/search.rb +26 -0
  35. data/lib/bel/resource/search/api.rb +36 -0
  36. data/lib/bel/resource/search/search_result.rb +32 -0
  37. data/lib/bel/translate.rb +108 -0
  38. data/lib/bel/translator.rb +69 -0
  39. data/lib/bel/translator/plugins/bel_script.rb +36 -0
  40. data/lib/bel/translator/plugins/bel_script/bel_yielder.rb +144 -0
  41. data/lib/bel/translator/plugins/bel_script/evidence_yielder.rb +95 -0
  42. data/lib/bel/translator/plugins/bel_script/translator.rb +24 -0
  43. data/lib/bel/translator/plugins/jgf.rb +37 -0
  44. data/lib/bel/translator/plugins/jgf/translator.rb +160 -0
  45. data/lib/bel/translator/plugins/json_evidence.rb +38 -0
  46. data/lib/bel/translator/plugins/json_evidence/translator.rb +90 -0
  47. data/lib/bel/translator/plugins/rdf.rb +48 -0
  48. data/lib/bel/translator/plugins/rdf/bel_schema.rb +339 -0
  49. data/lib/bel/translator/plugins/rdf/monkey_patch.rb +310 -0
  50. data/lib/bel/translator/plugins/rdf/reader.rb +173 -0
  51. data/lib/bel/translator/plugins/rdf/translator.rb +40 -0
  52. data/lib/bel/translator/plugins/rdf/writer.rb +45 -0
  53. data/lib/bel/translator/plugins/xbel.rb +36 -0
  54. data/lib/bel/translator/plugins/xbel/evidence_handler.rb +468 -0
  55. data/lib/bel/translator/plugins/xbel/evidence_yielder.rb +24 -0
  56. data/lib/bel/translator/plugins/xbel/translator.rb +24 -0
  57. data/lib/bel/translator/plugins/xbel/xbel_yielder.rb +414 -0
  58. data/lib/bel/vendor/little-plugger.rb +323 -0
  59. data/lib/bel/version.rb +1 -1
  60. metadata +44 -158
  61. data/lib/bel/extension.rb +0 -37
  62. data/lib/bel/extension_format.rb +0 -207
  63. data/lib/bel/extensions/bel.rb +0 -258
  64. data/lib/bel/extensions/jgf.rb +0 -219
  65. data/lib/bel/extensions/json/jrjackson.rb +0 -31
  66. data/lib/bel/extensions/json/json.rb +0 -133
  67. data/lib/bel/extensions/json/multi_json.rb +0 -29
  68. data/lib/bel/extensions/json/oj.rb +0 -68
  69. data/lib/bel/extensions/json/ruby_json.rb +0 -29
  70. data/lib/bel/extensions/rdf/bel_rdf.rb +0 -338
  71. data/lib/bel/extensions/rdf/rdf.rb +0 -584
  72. data/lib/bel/extensions/xbel.rb +0 -923
  73. data/lib/bel/format.rb +0 -58
@@ -0,0 +1,122 @@
1
+ require_relative '../resource'
2
+ require_relative 'namespace_value'
3
+
4
+ module BEL
5
+ module Resource
6
+
7
+ # TODO Document
8
+ class Namespace
9
+
10
+ attr_reader :uri
11
+
12
+ # TODO Document
13
+ def initialize(rdf_repository, uri)
14
+ @rdf_repository = rdf_repository
15
+ @uri = uri
16
+ @uri_hash = uri.hash
17
+ @concept_query = [
18
+ :predicate => RDF::SKOS.inScheme,
19
+ :object => uri
20
+ ]
21
+ @predicates = @rdf_repository.query(:subject => uri).
22
+ each.map(&:predicate)
23
+ end
24
+
25
+ # TODO Document
26
+ def each
27
+ return to_enum(:each) unless block_given?
28
+ @rdf_repository.
29
+ query(@concept_query) { |solution|
30
+ yield NamespaceValue.new(@rdf_repository, solution.subject)
31
+ }
32
+ end
33
+
34
+ def find(*values)
35
+ return to_enum(:find, *values) unless block_given?
36
+
37
+ values.flatten.each do |v|
38
+ yield find_value(v)
39
+ end
40
+ end
41
+
42
+ def hash
43
+ @uri_hash
44
+ end
45
+
46
+ def ==(other)
47
+ return false if other == nil
48
+ @uri == other.uri
49
+ end
50
+ alias_method :eql?, :'=='
51
+
52
+ protected
53
+
54
+ def find_value(value)
55
+ # nil input always yield nil
56
+ return nil if value == nil
57
+
58
+ # RDF::URI input handled as a special case
59
+ return find_namespace_value_uri(value) if value.is_a?(RDF::URI)
60
+
61
+ # input handled as literal identifier; empty literals match in a
62
+ # pattern as if it was nil so return nil if empty string
63
+ vstr = value.to_s
64
+ return nil if vstr.empty?
65
+
66
+ # match input as namespace value prefLabel
67
+ vlit = RDF::Literal(vstr)
68
+ label = value_query(
69
+ :predicate => RDF::SKOS.prefLabel,
70
+ :object => vlit
71
+ )
72
+ return NamespaceValue.new(@rdf_repository, label.subject) if label
73
+
74
+ # match input as namespace value identifier
75
+ ident = value_query(
76
+ :predicate => RDF::DC.identifier,
77
+ :object => vlit
78
+ )
79
+ return NamespaceValue.new(@rdf_repository, ident.subject) if ident
80
+
81
+ # match input as namespace value title
82
+ title = value_query(
83
+ :predicate => RDF::DC.title,
84
+ :object => vlit
85
+ )
86
+ return NamespaceValue.new(@rdf_repository, title.subject) if title
87
+ end
88
+
89
+ def find_namespace_value_uri(uri)
90
+ in_namespace_check = @rdf_repository.has_statement?(
91
+ RDF::Statement(uri, RDF::SKOS.inScheme, @uri)
92
+ )
93
+ return nil if !in_namespace_check
94
+
95
+ type_check = RDF::Statement(uri, RDF.type, BELV.NamespaceConcept)
96
+ if @rdf_repository.has_statement?(type_check)
97
+ return NamespaceValue.new(@rdf_repository, uri)
98
+ end
99
+ end
100
+
101
+ def value_query(pattern)
102
+ @rdf_repository.query(pattern).find { |solution|
103
+ @rdf_repository.has_statement?(
104
+ RDF::Statement(solution.subject, RDF::SKOS.inScheme, @uri)
105
+ )
106
+ }
107
+ end
108
+
109
+ def method_missing(method)
110
+ method_predicate = @predicates.find { |p|
111
+ p.qname[1].to_sym == method.to_sym
112
+ }
113
+ return nil unless method_predicate
114
+ objects = @rdf_repository.query(
115
+ :subject => @uri,
116
+ :predicate => method_predicate
117
+ ).each.map(&:object)
118
+ objects.size == 1 ? objects.first : objects.to_a
119
+ end
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,69 @@
1
+ require_relative '../resource'
2
+
3
+ module BEL
4
+ module Resource
5
+
6
+ # TODO Document
7
+ class NamespaceValue
8
+
9
+ attr_reader :uri
10
+
11
+ # TODO Document
12
+ def initialize(rdf_repository, uri)
13
+ @rdf_repository = rdf_repository
14
+ @uri = uri
15
+ @uri_hash = uri.hash
16
+ @eq_query = [
17
+ :subject => uri,
18
+ :predicate => RDF::SKOS.exactMatch
19
+ ]
20
+ @ortho_query = [
21
+ :subject => uri,
22
+ :predicate => BELV.orthologousMatch
23
+ ]
24
+ @predicates = @rdf_repository.query(:subject => uri).
25
+ each.map(&:predicate).uniq
26
+ end
27
+
28
+ def equivalents
29
+ return to_enum(:equivalents) unless block_given?
30
+ @rdf_repository.
31
+ query(@eq_query) { |solution|
32
+ yield NamespaceValue.new(@rdf_repository, solution.object)
33
+ }
34
+ end
35
+
36
+ def orthologs
37
+ return to_enum(:orthologs) unless block_given?
38
+ @rdf_repository.
39
+ query(@ortho_query) { |solution|
40
+ yield NamespaceValue.new(@rdf_repository, solution.object)
41
+ }
42
+ end
43
+
44
+ def hash
45
+ @uri_hash
46
+ end
47
+
48
+ def ==(other)
49
+ return false if other == nil
50
+ @uri == other.uri
51
+ end
52
+ alias_method :eql?, :'=='
53
+
54
+ protected
55
+
56
+ def method_missing(method)
57
+ method_predicate = @predicates.find { |p|
58
+ p.qname[1].to_sym == method.to_sym
59
+ }
60
+ return nil unless method_predicate
61
+ objects = @rdf_repository.query(
62
+ :subject => @uri,
63
+ :predicate => method_predicate
64
+ ).each.map(&:object)
65
+ objects.size == 1 ? objects.first : objects.to_a
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,83 @@
1
+ require_relative '../resource'
2
+ require_relative 'namespace'
3
+
4
+ module BEL
5
+ module Resource
6
+
7
+ # TODO Document
8
+ class Namespaces
9
+
10
+ # TODO Document
11
+ QUERY_NAMESPACES = RDF::Query.new do
12
+ pattern [:uri, RDF.type, BELV.NamespaceConceptScheme]
13
+ end
14
+
15
+ # TODO Document
16
+ def initialize(rdf_repository)
17
+ @rdf_repository = rdf_repository
18
+ end
19
+
20
+ # TODO Document
21
+ def each
22
+ return to_enum(:each) unless block_given?
23
+ @rdf_repository.
24
+ query(QUERY_NAMESPACES) { |solution|
25
+ yield Namespace.new(@rdf_repository, solution.uri)
26
+ }
27
+ end
28
+
29
+ def find(*namespaces)
30
+ return to_enum(:find, *namespaces) unless block_given?
31
+
32
+ namespaces.flatten.each do |ns|
33
+ yield find_namespace(ns)
34
+ end
35
+ end
36
+
37
+ protected
38
+
39
+ def find_namespace(namespace)
40
+ # nil input always yield nil
41
+ return nil if namespace == nil
42
+
43
+ # RDF::URI input handled as a special case
44
+ return find_namespace_uri(namespace) if namespace.is_a?(RDF::URI)
45
+
46
+ # input handled as literal identifier; empty literals will match
47
+ # in a pattern as if it was nil so return nil if empty string
48
+ nstr = namespace.to_s
49
+ return nil if nstr.empty?
50
+
51
+ # match input as namespace prefix
52
+ nlit = RDF::Literal(nstr)
53
+ prefix = namespace_query(
54
+ :predicate => BELV.prefix,
55
+ :object => nlit
56
+ )
57
+ return Namespace.new(@rdf_repository, prefix.subject) if prefix
58
+
59
+ # match input as namespace prefLabel
60
+ label = namespace_query(
61
+ :predicate => RDF::SKOS.prefLabel,
62
+ :object => nlit
63
+ )
64
+ return Namespace.new(@rdf_repository, label.subject) if label
65
+ end
66
+
67
+ def find_namespace_uri(uri)
68
+ type_check = RDF::Statement(uri, RDF.type, BELV.NamespaceConceptScheme)
69
+ if @rdf_repository.has_statement?(type_check)
70
+ return Namespace.new(@rdf_repository, uri)
71
+ end
72
+ end
73
+
74
+ def namespace_query(pattern)
75
+ @rdf_repository.query(pattern).find { |solution|
76
+ @rdf_repository.has_statement?(
77
+ RDF::Statement(solution.subject, RDF.type, BELV.NamespaceConceptScheme)
78
+ )
79
+ }
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,26 @@
1
+ require_relative 'search/search_result'
2
+ require_relative 'search/api'
3
+
4
+ module BEL
5
+ module Resource
6
+
7
+ module Search
8
+
9
+ module Plugins; end
10
+
11
+ extend LittlePlugger(
12
+ :path => 'bel/resource/search/plugins',
13
+ :module => BEL::Resource::Search::Plugins
14
+ )
15
+
16
+ module ClassMethods
17
+
18
+ # @param [Hash<Symbol => Object>] options
19
+ # @return
20
+ def self.create_search(options = {})
21
+ fail NotImplementedError.new, "#{__method__} is not implemented"
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,36 @@
1
+ module BEL::Resource::Search
2
+
3
+ module API
4
+
5
+ # Search identifiers based on +query_expression+.
6
+ #
7
+ # Additional parameters
8
+ #
9
+ # +concept_type+:
10
+ # Searches on namespace values when set to +namespace_concept+.
11
+ # Searches on annotation values when set to +annotation_concept+.
12
+ # Otherwise, searches either namespace values or annotation values. This is the default.
13
+ #
14
+ # +scheme_uri+:
15
+ # Searches within a specific namespace or annotation identified by this URI.
16
+ # Otherwise, searches across all namespaces or annotations. This is the default.
17
+ #
18
+ # +species+:
19
+ # Searches for namespace values or annotation values represented within the provided species. Values from
20
+ # the NCBI Taxonomy are recognized (e.g. 9606, Homo sapiens, Human, etc.).
21
+ # Otherwise, searches across all values regardless of species.
22
+ #
23
+ # +options+:
24
+ # Options hash used to provide additional parameters to the search.
25
+ #
26
+ # @param query_expression [responds to #to_s] query expression
27
+ # @param concept_type [responds to #to_s] concept type
28
+ # @param scheme_uri [responds to #to_s] scheme uri
29
+ # @param species [responds to #to_s] species
30
+ # @param options [responds to #[] ] options hash
31
+ # @return [Array<SearchResult>, nil]
32
+ def search(query_expression, concept_type = nil, scheme_uri = nil, species = nil, options = {})
33
+ fail NotImplementedError.new, "#{__method__} is not implemented"
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,32 @@
1
+ module BEL
2
+ module Resource
3
+ module Search
4
+
5
+ # Represents an identifier search result.
6
+ #
7
+ # @example Create with all parameters
8
+ # SearchResult.new(
9
+ # 'viral <b>oncogene</b> homolog',
10
+ # 'http://www.openbel.org/bel/namespace/hgnc-human-genes/391',
11
+ # 'http://www.openbel.org/bel/namespace/hgnc-human-genes',
12
+ # '391',
13
+ # 'AKT1',
14
+ # 'v-akt murine thymoma viral oncogene homolog 1',
15
+ # ['AKT', 'PKB', 'PRKBA', 'RAC']
16
+ # )
17
+ #
18
+ # @example Create from hash
19
+ # SearchResult.new({ :pref_label => 'AKT1' })
20
+ class SearchResult < Struct.new(:snippet, :uri, :scheme_uri, :identifier, :pref_label, :title, :alt_labels)
21
+ def initialize(*args)
22
+ if args.length == 1 && args.first.is_a?(Hash)
23
+ hash = args.first
24
+ super(*hash.values_at(*self.class.members))
25
+ else
26
+ super
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,108 @@
1
+ module BEL
2
+
3
+ # Translate module defines translation capabilities in the library. This
4
+ # module provides the API to use translator plugins.
5
+ #
6
+ # @see ::BEL::Translator::Plugins
7
+ module Translate
8
+
9
+ # Defines the translate API that is provided under the {BEL} module as a
10
+ # mixin.
11
+ module ClassMethods
12
+
13
+ # Return a stream of {::BEL::Model::Evidence} objects for the input.
14
+ #
15
+ # @param [IO] input the IO to read from
16
+ # @param [Symbol] input_format the symbol that can be
17
+ # used to identify the translator plugin that can read the
18
+ # +input+
19
+ # @param [Hash{Symbol => Object}] options
20
+ # @return [#each] an object that responds to +each+ and
21
+ # provides {::BEL::Model::Evidence} objects
22
+ def evidence(input, input_format, options = {})
23
+ prepared_input = process_input(input)
24
+
25
+ in_translator = self.translator(input_format) or
26
+ raise TranslateError.new(input_format)
27
+
28
+ in_translator.read(prepared_input)
29
+ end
30
+
31
+ # Translate from one file format to another using
32
+ # {::BEL::Model::Evidence} as a shared model. The translation is written
33
+ # to the IO +writer+ directly.
34
+ #
35
+ # @param [IO] input the IO to read from
36
+ # @param [#to_sym] input_format the identifier for the
37
+ # translator plugin that will read the +input+
38
+ # @param [#to_sym] output_format the identifier for the
39
+ # translator plugin that will write to +writer+
40
+ # @param [Hash{Symbol => Object}] options
41
+ # @return [IO ] the IO +writer+ that the translation
42
+ # was written to
43
+ def translate(input, input_format, output_format, writer = StringIO.new, options = {})
44
+ prepared_input = process_input(input)
45
+
46
+ in_translator = self.translator(input_format) or
47
+ raise TranslateError.new(input_format)
48
+
49
+ out_translator = self.translator(output_format) or
50
+ raise TranslateError.new(output_format)
51
+
52
+ evidence = in_translator.read(prepared_input)
53
+ output = out_translator.write(evidence, writer)
54
+ writer
55
+ end
56
+
57
+ # Return the {::BEL::Translator} plugin given an identifier.
58
+ #
59
+ # @param [#to_sym] input_format the identifier for the
60
+ # translator plugin
61
+ # @param [Hash{Symbol => Object}] options
62
+ # @return [::BEL::Translator] the translator instance that is
63
+ # responds to {::BEL::Translator#read} and
64
+ # {::BEL::Translator#write}
65
+ def translator(input_format, options = {})
66
+ return nil unless input_format
67
+
68
+ id = input_format.to_sym
69
+ plugins = BEL::Translator.plugins
70
+
71
+ plugin = plugins[id]
72
+ if plugin
73
+ plugin.create_translator(options)
74
+ else
75
+ match = BEL::Translator.plugins.values.find { |t|
76
+ match = false
77
+ match |= (id == t.name.to_sym)
78
+ match |= (t.media_types.include?(id))
79
+ match |= (t.file_extensions.include?(id))
80
+ match
81
+ }
82
+ match.create_translator(options) if match
83
+ end
84
+ end
85
+
86
+ def process_input(input)
87
+ if input.respond_to? :read
88
+ input
89
+ elsif File.exist?(input)
90
+ File.open(input, :ext_enc => Encoding::UTF_8)
91
+ elsif input.respond_to? :to_s
92
+ input.to_s
93
+ end
94
+ end
95
+ end
96
+
97
+ # TranslateError represents an error when the specified format is not
98
+ # supported by any translator plugin.
99
+ class TranslateError < StandardError
100
+
101
+ FORMAT_ERROR = %Q{Format "%s" is not supported.}
102
+
103
+ def initialize(format)
104
+ super(FORMAT_ERROR % format)
105
+ end
106
+ end
107
+ end
108
+ end