Class: KnowledgeBase

Inherits:
Object
  • Object
show all
Defined in:
lib/rbbt/knowledge_base.rb

Class Attribute Summary collapse

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(dir, namespace = nil) ⇒ KnowledgeBase

Returns a new instance of KnowledgeBase.



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/rbbt/knowledge_base.rb', line 19

def initialize(dir, namespace = nil)
  @dir = Path.setup dir

  @namespace = namespace
  @format = IndiferentHash.setup({})

  @registry = IndiferentHash.setup({})
  @entity_options = IndiferentHash.setup({})

  @indices = IndiferentHash.setup({})
  @databases = IndiferentHash.setup({})
  @identifiers = IndiferentHash.setup({})
  @descriptions = {}
  @databases = {}
end

Class Attribute Details

.knowledge_base_dirObject

Returns the value of attribute knowledge_base_dir.



7
8
9
# File 'lib/rbbt/knowledge_base.rb', line 7

def knowledge_base_dir
  @knowledge_base_dir
end

.registryObject

Returns the value of attribute registry.



7
8
9
# File 'lib/rbbt/knowledge_base.rb', line 7

def registry
  @registry
end

Instance Attribute Details

#databasesObject

Returns the value of attribute databases.



18
19
20
# File 'lib/rbbt/knowledge_base.rb', line 18

def databases
  @databases
end

#dirObject

Returns the value of attribute dir.



18
19
20
# File 'lib/rbbt/knowledge_base.rb', line 18

def dir
  @dir
end

#entity_optionsObject

Returns the value of attribute entity_options.



18
19
20
# File 'lib/rbbt/knowledge_base.rb', line 18

def entity_options
  @entity_options
end

#formatObject

Returns the value of attribute format.



18
19
20
# File 'lib/rbbt/knowledge_base.rb', line 18

def format
  @format
end

#indicesObject

Returns the value of attribute indices.



18
19
20
# File 'lib/rbbt/knowledge_base.rb', line 18

def indices
  @indices
end

#namespaceObject

Returns the value of attribute namespace.



18
19
20
# File 'lib/rbbt/knowledge_base.rb', line 18

def namespace
  @namespace
end

#registryObject

Returns the value of attribute registry.



18
19
20
# File 'lib/rbbt/knowledge_base.rb', line 18

def registry
  @registry
end

Instance Method Details

#add(name, source, target, *rest) ⇒ Object



149
150
151
152
153
# File 'lib/rbbt/knowledge_base.rb', line 149

def add(name, source, target, *rest)
  code = [source, target] * "~"
  repo = @indices[name]
  repo[code] = rest
end

#add_index(name, source_type, target_type, *fields) ⇒ Object

{{{ Add manual database



137
138
139
140
141
142
143
144
145
146
147
# File 'lib/rbbt/knowledge_base.rb', line 137

def add_index(name, source_type, target_type, *fields)
  options = fields.pop if Hash === fields.last
  options ||= {}
  undirected = Misc.process_options options, :undirected 

  undirected = nil unless undirected 

  repo_file = dir[name].find
  index = Association.index(nil, {:namespace => namespace, :key_field => [source_type, target_type, undirected].compact * "~", :fields => fields}.merge(options), :file => repo_file, :update => true)
  @indices[name] = index
end

#all(name, options = {}) ⇒ Object



234
235
236
237
# File 'lib/rbbt/knowledge_base.rb', line 234

def all(name, options={})
  repo = get_index name, options
  setup name, repo.keys
end

#all_databasesObject



56
57
58
# File 'lib/rbbt/knowledge_base.rb', line 56

def all_databases
  (@indices.keys + @registry.keys).uniq
end

#annotate(entities, type) ⇒ Object



171
172
173
# File 'lib/rbbt/knowledge_base.rb', line 171

def annotate(entities, type)
  Misc.prepare_entity(entities, type, entity_options_for(type))
end

#children(name, entity) ⇒ Object



239
240
241
242
# File 'lib/rbbt/knowledge_base.rb', line 239

def children(name, entity)
  repo = get_index name
  setup(name, repo.match(entity))
end

#description(name) ⇒ Object



60
61
62
# File 'lib/rbbt/knowledge_base.rb', line 60

def description(name)
  @descriptions[name] ||= get_index(name).key_field.split("~")
end

#entitiesObject



88
89
90
# File 'lib/rbbt/knowledge_base.rb', line 88

def entities
  all_databases.inject([]){|acc,name| acc << source(name); acc << target(name)}.uniq
end

#entity_options_for(type) ⇒ Object

{{{ Annotate



164
165
166
167
168
169
# File 'lib/rbbt/knowledge_base.rb', line 164

def entity_options_for(type)
  options = entity_options[Entity.formats[type]] || {}
  options[:format] = @format[type] if @format.include? :type
  options = {:organism => namespace}.merge(options)
  options
end

#entity_typesObject



92
93
94
# File 'lib/rbbt/knowledge_base.rb', line 92

def entity_types
  entities.collect{|entity| Entity.formats[entity] }.uniq
end

#get_database(name, options = {}) ⇒ Object



102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/rbbt/knowledge_base.rb', line 102

def get_database(name, options = {})
  persist_options = Misc.pull_keys options, :persist

  file, registered_options = registry[name]
  options = open_options.merge(registered_options || {}).merge(options)
  raise "Repo #{ name } not found and not registered" if file.nil?

  @databases[name] ||= begin 
                         Log.debug "Opening database #{ name } from #{ Misc.fingerprint file }. #{options}"
                         Association.open(file, options, persist_options).
                           tap{|tsv| tsv.namespace = self.namespace}
                       end
end

#get_index(name, options = {}) ⇒ Object



117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/rbbt/knowledge_base.rb', line 117

def get_index(name, options = {})
  persist_options = Misc.pull_keys options, :persist

  file, registered_options = registry[name]
  options = open_options.merge(registered_options || {}).merge(options)
  raise "Repo #{ name } not found and not registered" if file.nil?

  @indices[name] ||= begin 
                         Log.debug "Opening index #{ name } from #{ Misc.fingerprint file }. #{options}"
                         Association.index(file, options, persist_options).
                           tap{|tsv| tsv.namespace = self.namespace}
                       end
end

#identify(name, entity) ⇒ Object



224
225
226
# File 'lib/rbbt/knowledge_base.rb', line 224

def identify(name, entity)
  identify_source(name, entity) || identify_target(name, entity)
end

#identify_source(name, entity) ⇒ Object

{{{ Identify



177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/rbbt/knowledge_base.rb', line 177

def identify_source(name, entity)
  database = get_database(name, :persist => true)
  return entity if database.include? entity
  source = source(name)
  @identifiers[name] ||= {}
  @identifiers[name]['source'] ||= begin
                                     if database.identifier_files.any?
                                       if TSV.parse_header(database.identifier_files.first).all_fields.include? source
                                         TSV.index(database.identifiers, :target => source, :persist => true)
                                       else
                                         {}
                                       end
                                     else
                                       if TSV.parse_header(Organism.identifiers(namespace)).all_fields.include? source
                                         Organism.identifiers(namespace).index(:target => source, :persist => true)
                                       else
                                         {}
                                       end
                                     end
                                   end

  @identifiers[name]['source'][entity]
end

#identify_target(name, entity) ⇒ Object



201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
# File 'lib/rbbt/knowledge_base.rb', line 201

def identify_target(name, entity)
  database = get_database(name, :persist => true)
  target = target(name)

  @identifiers[name] ||= {}
  @identifiers[name]['target'] ||= begin
                                     if database.identifier_files.any?
                                       if TSV.parse_header(database.identifier_files.first).all_fields.include? target
                                         TSV.index(database.identifiers, :target => target, :persist => true)
                                       else
                                         {}
                                       end
                                     else
                                       if TSV.parse_header(Organism.identifiers(namespace)).all_fields.include? target
                                         Organism.identifiers(namespace).index(:target => target, :persist => true)
                                       else
                                        database.index(:target => database.fields.first, :fields => [database.fields.first], :persist => true)
                                       end
                                     end
                                   end
  @identifiers[name]['target'][entity]
end

#index(name, file, options = {}, persist_options = {}) ⇒ Object



131
132
133
# File 'lib/rbbt/knowledge_base.rb', line 131

def index(name, file, options = {}, persist_options = {})
  @indices[name] = Association.index(file, open_options.merge(options), persist_options)
end

#index_fields(name) ⇒ Object



84
85
86
# File 'lib/rbbt/knowledge_base.rb', line 84

def index_fields(name)
  get_index(name).fields
end

#neighbours(name, entity) ⇒ Object



249
250
251
252
253
254
255
# File 'lib/rbbt/knowledge_base.rb', line 249

def neighbours(name, entity)
  if undirected(name)
    IndiferentHash.setup({:children => children(name, entity)})
  else
    IndiferentHash.setup({:parents => parents(name, entity), :children => children(name, entity)})
  end
end

#open_optionsObject

{{{ Open and get



98
99
100
# File 'lib/rbbt/knowledge_base.rb', line 98

def open_options
  {:namespace => namespace, :format => @format}
end

#parents(name, entity) ⇒ Object



244
245
246
247
# File 'lib/rbbt/knowledge_base.rb', line 244

def parents(name, entity)
  repo = get_index name
  setup(name, repo.reverse.match(entity))
end

#register(name, file = nil, options = {}, &block) ⇒ Object

{{{ Descriptions



46
47
48
49
50
51
52
53
54
# File 'lib/rbbt/knowledge_base.rb', line 46

def register(name, file = nil, options = {}, &block)
  if block_given?
    Log.debug("Registering #{ name } from code block")
    @registry[name] = [block, options]
  else
    Log.debug("Registering #{ name }: #{ Misc.fingerprint file }")
    @registry[name] = [file, options]
  end
end

#setup(name, matches) ⇒ Object

{{{ Query



230
231
232
# File 'lib/rbbt/knowledge_base.rb', line 230

def setup(name, matches)
  AssociationItem.setup matches, self, name, false
end

#source(name) ⇒ Object



64
65
66
# File 'lib/rbbt/knowledge_base.rb', line 64

def source(name)
  description(name)[0]
end

#source_type(name) ⇒ Object



76
77
78
# File 'lib/rbbt/knowledge_base.rb', line 76

def source_type(name)
  Entity.formats[source(name)]
end

#subset(name, entities) ⇒ Object



257
258
259
260
261
262
263
264
265
266
267
268
269
# File 'lib/rbbt/knowledge_base.rb', line 257

def subset(name, entities)
  case entities
  when AnnotatedArray
    format = entities.format if entities.respond_to? :format 
    format ||= entities.base_entity.to_s
    {format => entities.clean_annotations}
  when Hash
  else
    raise "Entities are not a Hash or an AnnotatedArray: #{Misc.fingerprint entities}"
  end
  repo = get_index name
  setup(name, repo.subset_entities(entities))
end

#target(name) ⇒ Object



68
69
70
# File 'lib/rbbt/knowledge_base.rb', line 68

def target(name)
  description(name)[1]
end

#target_type(name) ⇒ Object



80
81
82
# File 'lib/rbbt/knowledge_base.rb', line 80

def target_type(name)
  Entity.formats[target(name)]
end

#translate(entities, type) ⇒ Object



271
272
273
274
275
276
277
# File 'lib/rbbt/knowledge_base.rb', line 271

def translate(entities, type)
  if format = @format[type] and format != entities.format
    entities.to format
  else
    entities
  end
end

#undirected(name) ⇒ Object



72
73
74
# File 'lib/rbbt/knowledge_base.rb', line 72

def undirected(name)
  description(name)[2]
end

#version(new_namespace, force = false) ⇒ Object



35
36
37
38
39
40
41
42
# File 'lib/rbbt/knowledge_base.rb', line 35

def version(new_namespace, force = false)
  return self if new_namespace == namespace and not force
  new_kb = KnowledgeBase.new dir[new_namespace], new_namespace
  new_kb.format.merge! self.format
  new_kb.entity_options.merge! self.entity_options
  new_kb.registry = self.registry
  new_kb
end

#write(name) ⇒ Object



155
156
157
158
159
160
# File 'lib/rbbt/knowledge_base.rb', line 155

def write(name)
  repo = @indices[name]
  repo.write_and_read do
    yield
  end
end