Class: ODDB::Substance

Inherits:
Object show all
Includes:
Comparable, Language, OddbYaml, Persistence, SequenceObserver
Defined in:
src/model/substance.rb,
ext/export/src/oddb_yaml.rb,
test/test_model/substance.rb

Constant Summary

ODBA_SERIALIZABLE =
[ '@descriptions', '@connection_keys', '@synonyms' ]
EXPORT_PROPERTIES =
[
  '@oid',
  '@descriptions',
  '@synonyms',
  '@swissmedic_code',
]

Constants included from OddbYaml

EXPORT_PROPERTIES, YAML_URI

Constants included from Persistence

ODBA_PREDEFINE_SERIALIZABLE

Instance Attribute Summary (collapse)

Class Method Summary (collapse)

Instance Method Summary (collapse)

Methods included from OddbYaml

#to_yaml_properties, #to_yaml_type

Methods included from Language

#all_descriptions, #has_description?, #init, #synonyms, #synonyms=

Methods included from SimpleLanguage

#description, #descriptions, #has_description?, #match, #method_missing, #respond_to?, #search_text

Methods included from PersistenceMethods

#data_origin, #data_origins, #diff, #init, #nil_if_empty, #parent, #structural_ancestors, #undiffable?

Methods included from SequenceObserver

#add_sequence, #remove_sequence

Constructor Details

- (Substance) initialize

A new instance of Substance



24
25
26
27
28
29
30
# File 'src/model/substance.rb', line 24

def initialize
  super()
  @sequences = []
  @substrate_connections = {}
  @connection_keys = []
  @chemical_forms = []
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class ODDB::SimpleLanguage

Instance Attribute Details

- (Object) casrn

Returns the value of attribute casrn



18
19
20
# File 'src/model/substance.rb', line 18

def casrn
  @casrn
end

- (Object) chemical_forms (readonly)

Returns the value of attribute chemical_forms



16
17
18
# File 'src/model/substance.rb', line 16

def chemical_forms
  @chemical_forms
end

- (Object) effective_form

Returns the value of attribute effective_form



16
17
18
# File 'src/model/substance.rb', line 16

def effective_form
  @effective_form
end

- (Object) narcotic

Returns the value of attribute narcotic



16
17
18
# File 'src/model/substance.rb', line 16

def narcotic
  @narcotic
end

- (Object) sequences

Returns the value of attribute sequences



16
17
18
# File 'src/model/substance.rb', line 16

def sequences
  @sequences
end

- (Object) substrate_connections

Returns the value of attribute substrate_connections



16
17
18
# File 'src/model/substance.rb', line 16

def substrate_connections
  @substrate_connections ||= {}
end

- (Object) swissmedic_code

Returns the value of attribute swissmedic_code



18
19
20
# File 'src/model/substance.rb', line 18

def swissmedic_code
  @swissmedic_code
end

Class Method Details

+ (Object) format_connection_key(key)



21
22
23
# File 'src/model/substance.rb', line 21

def Substance.format_connection_key(key)
  key.to_s.downcase.gsub(/[^a-z0-9]/u, '')
end

Instance Method Details

- (Object) <=>(other)



294
295
296
# File 'src/model/substance.rb', line 294

def <=>(other)
  to_s.downcase <=> other.to_s.downcase
end

- (Object) _interactions_with(other)



142
143
144
145
146
# File 'src/model/substance.rb', line 142

def _interactions_with(other)
  @substrate_connections.values.collect { |conn|
    conn.interactions_with(other)
  }.flatten
end

- (Object) _names



215
216
217
# File 'src/model/substance.rb', line 215

def _names
  self.descriptions.values + self.synonyms
end

- (Object) _search_keys



253
254
255
256
257
# File 'src/model/substance.rb', line 253

def _search_keys
  keys = self.descriptions.values + self.connection_keys \
    + self.synonyms
  keys.push(name).collect { |key| ODDB.search_term(key) }
end

- (Object) add_chemical_form(form)



31
32
33
34
35
36
37
38
# File 'src/model/substance.rb', line 31

def add_chemical_form(form)
  if(form && form != self && !@chemical_forms.include?(form))
    @chemical_forms.push(form)
    @chemical_forms.odba_isolated_store
  end
  odba_isolated_store
  form
end

- (Object) adjust_types(values, app = nil)



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'src/model/substance.rb', line 39

def adjust_types(values, app=nil)
  values.each { |key, value|
    if(key.to_s.size == 2)
      newval = value.to_s.gsub(/\S+/u) { |match|
        match.capitalize
      }
      newval.gsub!(/(?<=\s)[a-z]{1,4}[\s.]/iu) { |match|
        match.downcase 
      }
      newval.gsub!(/\bhcl\b/iu, 'HCl')
      newval.gsub!(/([\d\(\)\-].)|(\b[dl]{1,2}-.)|(\..)|(\b[IVX]+\b)/iu) { |match|
        match.upcase 
      }
      values[key] = newval
    else
      case key
      when :connection_keys
        values[key] = [ value ].flatten
      when :effective_form
        values[key] = value.resolve(app)
      end
    end
  }
  values
end

- (Object) atc_classes



64
65
66
# File 'src/model/substance.rb', line 64

def atc_classes
  @sequences.collect { |seq| seq.atc_class }.uniq
end

- (Object) checkout



67
68
69
70
71
72
# File 'src/model/substance.rb', line 67

def checkout
  @sequences.odba_delete
  self.narcotic = nil
  @substrate_connections.values.each { |conn| conn.odba_delete }
  @substrate_connections.odba_delete
end

- (Object) connection_keys



73
74
75
# File 'src/model/substance.rb', line 73

def connection_keys
  @connection_keys || self.update_connection_keys
end

- (Object) connection_keys=(keys)



76
77
78
79
# File 'src/model/substance.rb', line 76

def connection_keys=(keys)
  @connection_keys += keys
  self.connection_keys
end

- (Object) create_cyp450substrate(cyp_id)



80
81
82
83
84
85
# File 'src/model/substance.rb', line 80

def create_cyp450substrate(cyp_id)
  conn = ODDB::CyP450SubstrateConnection.new(cyp_id)
  conn.substance = self
  @substrate_connections.store(conn.cyp_id, conn)
  conn
end

- (Object) cyp450substrate(cyp_id)



86
87
88
# File 'src/model/substance.rb', line 86

def cyp450substrate(cyp_id)
  @substrate_connections[cyp_id]
end

- (Object) delete_cyp450substrate(cyp_id)



89
90
91
92
93
94
# File 'src/model/substance.rb', line 89

def delete_cyp450substrate(cyp_id)
  if(cyp = @substrate_connections.delete(cyp_id))
    @substrate_connections.odba_isolated_store
    cyp
  end
end

- (Boolean) empty?

Returns:

  • (Boolean)


104
105
106
107
# File 'src/model/substance.rb', line 104

def empty?
  @sequences.empty? && @narcotic.nil? \
    && @substrate_connections.empty? && !is_effective_form?
end

- (Object) format_connection_key(key)



108
109
110
# File 'src/model/substance.rb', line 108

def format_connection_key(key)
  Substance.format_connection_key(key)
end

- (Boolean) has_connection_key?(test_key)

Returns:

  • (Boolean)


111
112
113
114
# File 'src/model/substance.rb', line 111

def has_connection_key?(test_key)
  key = format_connection_key(test_key)
  !key.empty? && self.connection_keys.include?(key)
end

- (Boolean) has_effective_form?

Returns:

  • (Boolean)


115
116
117
# File 'src/model/substance.rb', line 115

def has_effective_form?
  !@effective_form.nil?
end

- (Object) interaction_connections(others)



118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'src/model/substance.rb', line 118

def interaction_connections(others)
  connections = {}
  @substrate_connections.each { |cyp450_id, subs_connection|
    others.each { |substance|
      interactions = subs_connection.interactions_with(substance)
      if(int_conn = connections[cyp450_id])
        int_conn.concat(interactions)
      else
        connections.store(cyp450_id, interactions)
      end
    }
  }
  connections
end

- (Object) interactions_with(other)



132
133
134
135
136
137
138
139
140
141
# File 'src/model/substance.rb', line 132

def interactions_with(other)
  interactions = _interactions_with(other) 
  if(has_effective_form? && !is_effective_form?)
    interactions += @effective_form.interactions_with(other)
  end
  if(other.has_effective_form? && !other.is_effective_form?)
    interactions += interactions_with(other.effective_form)
  end
  interactions.uniq
end

- (Boolean) is_effective_form?

Returns:

  • (Boolean)


147
148
149
# File 'src/model/substance.rb', line 147

def is_effective_form?
  @effective_form == self
end

- (Object) merge(other)



150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'src/model/substance.rb', line 150

def merge(other)
  if(@narcotic.nil? && other.narcotic)
    narc = other.narcotic
    other.narcotic = nil
    self.narcotic = narc
  end
  @swissmedic_code ||= other.swissmedic_code
  @casrn ||= other.casrn
  other.sequences.uniq.each { |sequence|
    sequence.compositions.dup.each do |composition|
      if(active_agent = composition.active_agent(other))
        if(active_agent.sequence.nil?)
          active_agent.odba_delete
        else
          active_agent.substance = self
          active_agent.odba_isolated_store
        end
      else
        warn("Substance.merge: no active agent, only removing sequence")
        other.remove_sequence(sequence)
      end
    end
  }
  ocons = other.substrate_connections
  ocons.dup.each { |key, substr_conn|
    unless(cyp450substrate(substr_conn.cyp_id))
      substr_conn.pointer = self.pointer + substr_conn.pointer.last_step
      substrate_connections.store(substr_conn.cyp_id, substr_conn)
      substr_conn.odba_isolated_store
      ocons.delete(key)
    end
  }
  substrate_connections.odba_isolated_store
  ocons.odba_isolated_store
  other.descriptions.dup.each { |key, value|
    unless(self.descriptions.has_key?(key))
      self.descriptions.update_values( { key => value } )
    end
  }
  # long format, because each of these methods are overridden
  self.synonyms = self.synonyms + other.synonyms \
    + other.descriptions.values - self.descriptions.values
  self.connection_keys = self.connection_keys + other.connection_keys
  self
end

- (Object) name Also known as: pointer_descr



195
196
197
198
199
200
201
202
# File 'src/model/substance.rb', line 195

def name
  # First call to descriptions should go to lazy-initialisator
  if(lt = self.descriptions['lt']) && !lt.empty?
    lt
  else
    @descriptions['en'].to_s
  end
end

- (Object) names



204
205
206
207
208
209
210
211
212
213
214
# File 'src/model/substance.rb', line 204

def names
  names = self._names
  if(has_effective_form? && !is_effective_form?)
    names += @effective_form.names
  end
  names.compact!
  names.delete_if { |name|
    name.empty?
  }
  names
end

- (Object) primary_connection_key



227
228
229
# File 'src/model/substance.rb', line 227

def primary_connection_key
  @primary_connection_key ||= format_connection_key(self.name)
end

- (Object) remove_chemical_form(form)



230
231
232
233
234
235
# File 'src/model/substance.rb', line 230

def remove_chemical_form(form)
  if(@chemical_forms.delete(form))
    @chemical_forms.odba_isolated_store
  end
  form
end

- (Boolean) same_as?(substance)

Returns:

  • (Boolean)


236
237
238
239
240
241
# File 'src/model/substance.rb', line 236

def same_as?(substance)
  teststr = ODDB.search_term(substance.to_s.downcase)
  _search_keys.any? { |desc|
    desc.downcase == teststr
  } || (connection_keys.include?(format_connection_key(teststr)))
end

- (Object) search_keys



242
243
244
245
246
247
248
249
250
251
252
# File 'src/model/substance.rb', line 242

def search_keys
  keys = self._search_keys
  if(has_effective_form? && !is_effective_form?)
    keys += @effective_form.search_keys
  end
  keys.compact!
  keys.delete_if { |key|
    key.empty?
  }
  ODDB.search_terms(keys).uniq
end

- (Boolean) similar_name?(astring)

Returns:

  • (Boolean)


258
259
260
# File 'src/model/substance.rb', line 258

def similar_name?(astring)
  name.length/3.0 >= name.downcase.ld(astring.downcase)
end

- (Object) soundex_keys



261
262
263
264
265
266
267
268
# File 'src/model/substance.rb', line 261

def soundex_keys
  keys = self.search_keys.collect { |key|
    parts = ODDB.search_term(key).split(/\s/u)
    soundex = Text::Soundex.soundex(parts)
    soundex.join(' ')
  }
  keys.compact.uniq
end

- (Object) to_i



272
273
274
# File 'src/model/substance.rb', line 272

def to_i
  oid
end

- (Object) to_s



275
276
277
# File 'src/model/substance.rb', line 275

def to_s
  name
end

- (Object) to_yaml(opts = {})



507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
# File 'ext/export/src/oddb_yaml.rb', line 507

def to_yaml( opts = {} )
  YAML::quick_emit( self.object_id, opts ) { |out|
    out.map( taguri ) { |map|
      to_yaml_properties.each { |m|
        map.add( m[1..-1], instance_variable_get( m ) )
      }
      if(@narcotic)
        map.add('narcotic', @narcotic.casrn)
      end
      if @effective_form && @effective_form != self
        map.add('effective_form', @effective_form)
      end
    }
  }
end

- (Boolean) unique_compare?(other)

Returns:

  • (Boolean)


278
279
280
281
282
# File 'src/model/substance.rb', line 278

def unique_compare?(other)
  other_keys = other.connection_keys + other._search_keys
  own_keys = self.connection_keys + self.search_keys
  !(other_keys & own_keys).empty? # intersection
end

- (Object) update_connection_keys



283
284
285
286
287
288
289
# File 'src/model/substance.rb', line 283

def update_connection_keys
  keys = (@connection_keys || []) + self.descriptions.values \
    + self.synonyms  + [self.name]
  @connection_keys = keys.collect { |key|
      format_connection_key(key)
  }.delete_if { |key| key.empty? }.uniq.sort
end

- (Object) update_values(values, origin = nil)



290
291
292
293
# File 'src/model/substance.rb', line 290

def update_values(values, origin=nil)
  super
  update_connection_keys
end