bio 1.3.0 → 1.3.1

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 (75) hide show
  1. data/COPYING +56 -0
  2. data/COPYING.ja +51 -0
  3. data/ChangeLog +540 -0
  4. data/GPL +340 -0
  5. data/LEGAL +141 -0
  6. data/LGPL +504 -0
  7. data/README.rdoc +4 -2
  8. data/Rakefile +2 -2
  9. data/bioruby.gemspec +17 -29
  10. data/doc/Tutorial.rd +118 -90
  11. data/doc/Tutorial.rd.html +124 -87
  12. data/lib/bio/appl/blast.rb +2 -2
  13. data/lib/bio/appl/blast/format0.rb +1 -1
  14. data/lib/bio/appl/fasta.rb +5 -12
  15. data/lib/bio/appl/fasta/format10.rb +96 -6
  16. data/lib/bio/appl/gcg/msf.rb +11 -14
  17. data/lib/bio/appl/pts1.rb +0 -4
  18. data/lib/bio/appl/sim4/report.rb +50 -17
  19. data/lib/bio/db/biosql/biosql_to_biosequence.rb +10 -0
  20. data/lib/bio/db/biosql/sequence.rb +234 -298
  21. data/lib/bio/db/embl/embl.rb +0 -3
  22. data/lib/bio/db/genbank/common.rb +3 -1
  23. data/lib/bio/io/biosql/ar-biosql.rb +257 -0
  24. data/lib/bio/io/biosql/biosql.rb +39 -0
  25. data/lib/bio/io/biosql/config/database.yml +5 -4
  26. data/lib/bio/io/ncbirest.rb +12 -5
  27. data/lib/bio/io/pubmed.rb +5 -1
  28. data/lib/bio/io/sql.rb +43 -150
  29. data/lib/bio/sequence/compat.rb +5 -1
  30. data/lib/bio/util/restriction_enzyme/range/sequence_range/calculated_cuts.rb +6 -4
  31. data/lib/bio/version.rb +1 -1
  32. data/test/data/gcg/pileup-aa.msf +67 -0
  33. data/test/data/sim4/complement-A4.sim4 +43 -0
  34. data/test/data/sim4/simple-A4.sim4 +25 -0
  35. data/test/data/sim4/simple2-A4.sim4 +25 -0
  36. data/test/functional/bio/io/test_pubmed.rb +129 -0
  37. data/test/unit/bio/appl/bl2seq/test_report.rb +5 -5
  38. data/test/unit/bio/appl/gcg/test_msf.rb +154 -0
  39. data/test/unit/bio/appl/hmmer/test_report.rb +2 -2
  40. data/test/unit/bio/appl/sim4/test_report.rb +869 -0
  41. data/test/unit/bio/appl/test_blast.rb +1 -1
  42. data/test/unit/bio/db/biosql/tc_biosql.rb +110 -0
  43. data/test/unit/bio/db/biosql/ts_suite_biosql.rb +8 -0
  44. data/test/unit/bio/test_feature.rb +18 -17
  45. data/test/unit/bio/test_reference.rb +18 -18
  46. data/test/unit/bio/test_sequence.rb +1 -1
  47. metadata +18 -30
  48. data/lib/bio/io/biosql/biodatabase.rb +0 -64
  49. data/lib/bio/io/biosql/bioentry.rb +0 -29
  50. data/lib/bio/io/biosql/bioentry_dbxref.rb +0 -11
  51. data/lib/bio/io/biosql/bioentry_path.rb +0 -12
  52. data/lib/bio/io/biosql/bioentry_qualifier_value.rb +0 -10
  53. data/lib/bio/io/biosql/bioentry_reference.rb +0 -10
  54. data/lib/bio/io/biosql/bioentry_relationship.rb +0 -10
  55. data/lib/bio/io/biosql/biosequence.rb +0 -11
  56. data/lib/bio/io/biosql/comment.rb +0 -7
  57. data/lib/bio/io/biosql/dbxref.rb +0 -13
  58. data/lib/bio/io/biosql/dbxref_qualifier_value.rb +0 -12
  59. data/lib/bio/io/biosql/location.rb +0 -32
  60. data/lib/bio/io/biosql/location_qualifier_value.rb +0 -11
  61. data/lib/bio/io/biosql/ontology.rb +0 -10
  62. data/lib/bio/io/biosql/reference.rb +0 -9
  63. data/lib/bio/io/biosql/seqfeature.rb +0 -32
  64. data/lib/bio/io/biosql/seqfeature_dbxref.rb +0 -11
  65. data/lib/bio/io/biosql/seqfeature_path.rb +0 -11
  66. data/lib/bio/io/biosql/seqfeature_qualifier_value.rb +0 -20
  67. data/lib/bio/io/biosql/seqfeature_relationship.rb +0 -11
  68. data/lib/bio/io/biosql/taxon.rb +0 -12
  69. data/lib/bio/io/biosql/taxon_name.rb +0 -9
  70. data/lib/bio/io/biosql/term.rb +0 -27
  71. data/lib/bio/io/biosql/term_dbxref.rb +0 -11
  72. data/lib/bio/io/biosql/term_path.rb +0 -12
  73. data/lib/bio/io/biosql/term_relationship.rb +0 -13
  74. data/lib/bio/io/biosql/term_relationship_term.rb +0 -11
  75. data/lib/bio/io/biosql/term_synonym.rb +0 -10
@@ -5,7 +5,7 @@
5
5
  # Naohisa Goto <ng@bioruby.org>
6
6
  # License:: The Ruby License
7
7
  #
8
- # $Id: msf.rb,v 1.2 2007/04/05 23:35:39 trevor Exp $
8
+ # $Id:$
9
9
  #
10
10
  # = About Bio::GCG::Msf
11
11
  #
@@ -30,14 +30,13 @@ module Bio
30
30
  # Creates a new Msf object.
31
31
  def initialize(str)
32
32
  str = str.sub(/\A[\r\n]+/, '')
33
- if /^\!\![A-Z]+\_MULTIPLE\_ALIGNMNENT/ =~ str[/.*/] then
34
- @heading = str[/.*/] # '!!NA_MULTIPLE_ALIGNMENT 1.0' or like this
35
- str.sub!(/.*/, '')
36
- end
37
- str.sub!(/.*\.\.$/m, '')
38
- @description = $&.to_s.sub(/^.*\.\.$/, '').to_s
33
+ preamble, @data = str.split(/^\/\/$/, 2)
34
+ preamble.sub!(/\A\!\![A-Z]+\_MULTIPLE\_ALIGNMENT.*/, '')
35
+ @heading = $& # '!!NA_MULTIPLE_ALIGNMENT 1.0' or like this
36
+ preamble.sub!(/.*\.\.\s*$/m, '')
37
+ @description = $&.to_s.sub(/^.*\.\.\s*$/, '').to_s
39
38
  d = $&.to_s
40
- if m = /(.+)\s+MSF\:\s+(\d+)\s+Type\:\s+(\w)\s+(.+)\s+(Comp)?Check\:\s+(\d+)/.match(d) then
39
+ if m = /^(?:(.+)\s+)?MSF\:\s+(\d+)\s+Type\:\s+(\w)\s+(.+)\s+(Comp)?Check\:\s+(\d+)/.match(d) then
41
40
  @entry_id = m[1].to_s.strip
42
41
  @length = (m[2] ? m[2].to_i : nil)
43
42
  @seq_type = m[3]
@@ -45,10 +44,8 @@ module Bio
45
44
  @checksum = (m[6] ? m[6].to_i : nil)
46
45
  end
47
46
 
48
- str.sub!(/.*\/\/$/m, '')
49
- a = $&.to_s.split(/^/)
50
47
  @seq_info = []
51
- a.each do |x|
48
+ preamble.each_line do |x|
52
49
  if /Name\: / =~ x then
53
50
  s = {}
54
51
  x.scan(/(\S+)\: +(\S*)/) { |y| s[$1] = $2 }
@@ -56,7 +53,6 @@ module Bio
56
53
  end
57
54
  end
58
55
 
59
- @data = str
60
56
  @description.sub!(/\A(\r\n|\r|\n)/, '')
61
57
  @align = nil
62
58
  end
@@ -133,11 +129,12 @@ module Bio
133
129
  # parsing
134
130
  def do_parse
135
131
  return if @align
136
- a = @data.strip.split(/\n\n/)
132
+ a = @data.split(/\r?\n\r?\n/)
137
133
  @seq_data = Array.new(@seq_info.size)
138
134
  @seq_data.collect! { |x| Array.new }
139
135
  a.each do |x|
140
- b = x.split(/\n/)
136
+ next if x.strip.empty?
137
+ b = x.sub(/\A[\r\n]+/, '').split(/[\r\n]+/)
141
138
  nw = 0
142
139
  if b.size > @seq_info.size then
143
140
  if /^ +/ =~ b.shift.to_s
@@ -65,10 +65,6 @@ class PTS1
65
65
  # Output report.
66
66
  attr_reader :output
67
67
 
68
- # Used function name (Integer).
69
- # function_name = Bio::PTS1::FUNCTION.find_all {|k,v| v == pts1.function }[0][0]
70
- attr_reader :function
71
-
72
68
  # Short-cut for Bio::PTS1.new(Bio::PTS1::FUNCTION['METAZOA-specific'])
73
69
  def self.new_with_metazoa_function
74
70
  self.new('METAZOA-specific')
@@ -4,7 +4,7 @@
4
4
  # Copyright:: Copyright (C) 2004 GOTO Naohisa <ng@bioruby.org>
5
5
  # License:: The Ruby License
6
6
  #
7
- # $Id: report.rb,v 1.9 2007/04/05 23:35:40 trevor Exp $
7
+ # $Id:$
8
8
  #
9
9
  # The sim4 report parser classes.
10
10
  #
@@ -43,7 +43,7 @@ module Bio
43
43
  @hits = []
44
44
  @all_hits = []
45
45
  overrun = ''
46
- text.each("\n\nseq1 = ") do |str|
46
+ text.each_line("\n\nseq1 = ") do |str|
47
47
  str = str.sub(/\A\s+/, '')
48
48
  str.sub!(/\n(^seq1 \= .*)/m, "\n") # remove trailing hits for sure
49
49
  tmp = $1.to_s
@@ -161,7 +161,7 @@ module Bio
161
161
  attr_reader :percent_identity
162
162
 
163
163
  # Returns directions of mapping.
164
- # Maybe one of "->", "<-" or "" or nil.
164
+ # Maybe one of "->", "<-", "==" or "" or nil.
165
165
  # This would be a Bio::Sim4 specific method.
166
166
  attr_reader :direction
167
167
 
@@ -170,7 +170,7 @@ module Bio
170
170
  # Bio::Sim4::Report::Hit class.
171
171
  # Users shall not use it directly.
172
172
  def self.parse(str, aln)
173
- /^(\d+)\-(\d+)\s*\((\d+)\-(\d+)\)\s*([\d\.]+)\%\s*([\-\<\>]*)/ =~ str
173
+ /^(\d+)\-(\d+)\s*\((\d+)\-(\d+)\)\s*([\d\.]+)\%\s*([\-\<\>\=]*)/ =~ str
174
174
  self.new(Segment.new($1, $2, aln[0]),
175
175
  Segment.new($3, $4, aln[2]),
176
176
  aln[1], $5, $6)
@@ -198,6 +198,17 @@ module Bio
198
198
  aln[1])
199
199
  end
200
200
 
201
+ # Parses part of sim4 result text and creates a new SegmentPair
202
+ # object for regions which can not be aligned correctly.
203
+ # It is designed to be called internally from
204
+ # Bio::Sim4::Report::Hit class.
205
+ # Users shall not use it directly.
206
+ def self.both_intron(prev_e, e, aln)
207
+ self.new(Segment.new(prev_e.seq1.to+1, e.seq1.from-1, aln[0]),
208
+ Segment.new(prev_e.seq2.to+1, e.seq2.from-1, aln[2]),
209
+ aln[1])
210
+ end
211
+
201
212
  #--
202
213
  # Bio::BLAST::*::Report::Hsp compatible methods
203
214
  # Methods already defined: midline, percent_identity
@@ -318,7 +329,9 @@ module Bio
318
329
  exo << e
319
330
  if ai then
320
331
  # intron data in alignment
321
- if ai[2].strip.empty? then
332
+ if ai[1].strip.empty? then
333
+ i = SegmentPair.both_intron(prev_e, e, ai)
334
+ elsif ai[2].strip.empty? then
322
335
  i = SegmentPair.seq1_intron(prev_e, e, ai)
323
336
  else
324
337
  i = SegmentPair.seq2_intron(prev_e, e, ai)
@@ -338,29 +351,49 @@ module Bio
338
351
  # Parses alignment.
339
352
  def parse_align
340
353
  s1 = []; ml = []; s2 = []
354
+ blocks = []
355
+ blocks.push [ s1, ml, s2 ]
341
356
  dat = @data[1..-1]
342
357
  return unless dat
343
358
  dat.each do |str|
344
359
  a = str.split(/\r?\n/)
345
- a.shift
346
- if /^(\s*\d+\s*)(.+)$/ =~ a[0] then
347
- range = ($1.length)..($1.length + $2.strip.length - 1)
360
+ ruler = a.shift
361
+ # First line, for example,
362
+ # " 50 . : . : . : . : . :"
363
+ # When the number is 0, forced to be a separated block
364
+ if /^\s*(\d+)/ =~ ruler and $1.to_i == 0 and !ml.empty? then
365
+ s1 = []; ml = []; s2 = []
366
+ blocks.push [ s1, ml, s2 ]
367
+ end
368
+ # For example,
369
+ # " 190 GAGTCATGCATGATACAA CTTATATATGTACTTAGCGGCA"
370
+ # " ||||||||||||||||||<<<...<<<-||-|||||||||||||||||||"
371
+ # " 400 GAGTCATGCATGATACAACTT...AGCGCT ATATATGTACTTAGCGGCA"
372
+ if /^(\s*\d+\s)(.+)$/ =~ a[0] then
373
+ range = ($1.length)..($1.length + $2.chomp.length - 1)
348
374
  a.collect! { |x| x[range] }
349
375
  s1 << a.shift
350
376
  ml << a.shift
351
377
  s2 << a.shift
352
378
  end
353
379
  end #each
354
- alx = ml.join('').split(/([\<\>]+\.+[\<\>]+)/)
355
- seq1 = s1.join(''); seq2 = s2.join('')
356
- i = 0
357
- alx.collect! do |x|
358
- len = x.length
359
- y = [ seq1[i, len], x, seq2[i, len] ]
360
- i += len
361
- y
380
+ alx_all = []
381
+ blocks.each do |ary|
382
+ s1, ml, s2 = ary
383
+ alx = ml.join('').split(/([\<\>]+\.+[\<\>]+)/)
384
+ seq1 = s1.join(''); seq2 = s2.join('')
385
+ i = 0
386
+ alx.collect! do |x|
387
+ len = x.length
388
+ y = [ seq1[i, len], x, seq2[i, len] ]
389
+ i += len
390
+ y
391
+ end
392
+ # adds virtual intron information if necessary
393
+ alx_all.push([ '', '', '' ]) unless alx_all.empty?
394
+ alx_all.concat alx
362
395
  end
363
- @align = alx
396
+ @align = alx_all
364
397
  end
365
398
  private :parse_align
366
399
 
@@ -46,6 +46,9 @@ module Bio::Sequence::Adapter::BioSQL
46
46
  def_biosequence_adapter :date_created
47
47
 
48
48
  def_biosequence_adapter :date_modified
49
+ #do |bs|
50
+ # Date.parse(bs.date_modified.to_s).strftime("%d-%b-%Y").upcase
51
+ # end
49
52
 
50
53
  def_biosequence_adapter :division
51
54
 
@@ -63,5 +66,12 @@ module Bio::Sequence::Adapter::BioSQL
63
66
 
64
67
  def_biosequence_adapter :comments
65
68
 
69
+ def_biosequence_adapter :other_seqids do |orig|
70
+ orig.identifier.split(',').collect do |dblink|
71
+ database, id = dblink.split(':')
72
+ Bio::Sequence::DBLink.new(database,id)
73
+ end
74
+ end
75
+
66
76
  end #module Bio::Sequence::Adapter::BioSQL
67
77
 
@@ -1,8 +1,10 @@
1
1
 
2
2
  #TODO save on db reading from a genbank or embl object
3
3
  module Bio
4
- class SQL
5
-
4
+ class SQL
5
+
6
+
7
+
6
8
  class Sequence
7
9
  private
8
10
  # example
@@ -12,10 +14,10 @@ module Bio
12
14
  #molecule_type=value add a bioentry_qualifier value to the table
13
15
  #molecule_type_update(value, rank) update an entry of the table with an existing rank
14
16
  #the method inferr the qualifier term from the name of the first symbol, or you can specify a synonym to use
15
-
17
+
16
18
  #creating an object with to_biosql is transaction safe.
17
-
18
- #TODO: implement setting for more than a qualifier-vale.
19
+
20
+ #TODO: implement setting for more than a qualifier-vale.
19
21
  def self.bioentry_qualifier_anchor(sym, *args)
20
22
  options = args.first || Hash.new
21
23
  #options.assert_valid_keys(:rank,:synonym,:multi)
@@ -23,278 +25,305 @@ module Bio
23
25
  method_writer_operator = (sym.to_s+"=").to_sym
24
26
  method_writer_modder = (sym.to_s+"_update").to_sym
25
27
  synonym = options[:synonym].nil? ? sym.to_s : options[:synonym]
26
-
27
- #Bio::SQL::Term.create(:name=>synonym, :ontology=> Bio::SQL::Ontology.find_by_name('Annotation Tags')) unless Bio::SQL::Term.exists?(:name =>synonym)
28
+
29
+ #DELETE #Bio::SQL::Term.create(:name=>synonym, :ontology=> Bio::SQL::Ontology.find_by_name('Annotation Tags')) unless Bio::SQL::Term.exists?(:name =>synonym)
28
30
  send :define_method, method_reader do
29
31
  #return an array of bioentry_qualifier_values
30
32
  begin
31
- ontology_annotation_tags = Ontology.find_or_create_by_name('Annotation Tags')
32
- term = Term.find_or_create_by_name(:name => synonym, :ontology=> ontology_annotation_tags)
33
- bioentry_qualifier_values = @entry.bioentry_qualifier_values.find_all_by_term_id(term)
34
- bioentry_qualifier_values.map{|row| row.value} unless bioentry_qualifier_values.nil?
35
- rescue Exception => e
33
+ #DELETE ontology_annotation_tags = Ontology.find_or_create({:name=>'Annotation Tags'})
34
+ term = Term.first(:conditions=>["name = ?",synonym]) || Term.create({:name => synonym, :ontology=> Ontology.first(:conditions=>["name = ?",'Annotation Tags'])})
35
+ bioentry_qualifier_values = @entry.bioentry_qualifier_values.all(:conditions=>["term_id = ?",term.term_id])
36
+ data = bioentry_qualifier_values.map{|row| row.value} unless bioentry_qualifier_values.nil?
37
+ begin
38
+ # this block try to check if the data retrived is a
39
+ # Date or not and change it according to GenBank/EMBL format
40
+ # in that case return a string
41
+ # otherwise the []
42
+ Date.parse(data.to_s).strftime("%d-%b-%Y").upcase
43
+ rescue ArgumentError, TypeError, NoMethodError, NameError
44
+ data
45
+ end
46
+ rescue Exception => e
36
47
  puts "Reader Error: #{synonym} #{e.message}"
37
48
  end
38
49
  end
39
-
50
+
40
51
  send :define_method, method_writer_operator do |value|
41
52
  begin
42
- ontology_annotation_tags = Ontology.find_or_create_by_name('Annotation Tags')
43
- term = Term.find_or_create_by_name(:name => synonym, :ontology=> ontology_annotation_tags)
44
- datas = @entry.bioentry_qualifier_values.find_all_by_term_id(term.term_id)
53
+ #DELETE ontology_annotation_tags = Ontology.find_or_create({:name=>'Annotation Tags'})
54
+ term = Term.first(:conditions=>["name = ?",synonym]) || Term.create({:name => synonym, :ontology=> Ontology.first(:conditions=>["name = ?",'Annotation Tags'])})
55
+ datas = @entry.bioentry_qualifier_values.all(:conditions=>["term_id = ?",term.term_id])
45
56
  #add an element incrementing the rank or setting the first to 1
46
- @entry.bioentry_qualifier_values.create(:term_id=>term.term_id, :rank=>datas.empty? ? 1 : datas.last.rank.succ, :value=>value)
47
- rescue Exception => e
57
+ be_qu_va=@entry.bioentry_qualifier_values.build({:term=>term, :rank=>(datas.empty? ? 1 : datas.last.rank.succ), :value=>value})
58
+ be_qu_va.save
59
+ rescue Exception => e
48
60
  puts "WriterOperator= Error: #{synonym} #{e.message}"
49
61
  end
50
62
  end
51
-
63
+
52
64
  send :define_method, method_writer_modder do |value, rank|
53
65
  begin
54
- ontology_annotation_tags = Ontology.find_or_create_by_name('Annotation Tags')
55
- term = Term.find_or_create_by_name(:name => synonym, :ontology=> ontology_annotation_tags)
56
- data = @entry.bioentry_qualifier_values.find_by_term_id_and_rank(term.term_id, rank)
66
+ #DELETE ontology_annotation_tags = Ontology.find_or_create({:name=>'Annotation Tags'})
67
+ term = Term.first(:conditions=>["name = ?",synonym]) || Term.create({:name => synonym, :ontology=> Ontology.first(:conditions=>["name = ?",'Annotation Tags'])})
68
+ data = @entry.bioentry_qualifier_values.all(:term_id=>term.term_id, :rank=>rank)
57
69
  if data.nil?
58
70
  send method_writer_operator, value
59
71
  else
60
72
  data.value=value
61
- data.save!
73
+ data.save
62
74
  end
63
75
  rescue Exception => e
64
76
  puts "WriterModder Error: #{synonym} #{e.message}"
65
77
  end
66
78
  end
67
-
79
+
68
80
  end
81
+
69
82
  public
70
83
  attr_reader :entry
71
-
84
+
72
85
  def delete
86
+ #TODO: check is references connected to this bioentry are leaf or not.
87
+ #actually I think it should be more sofisticated, check if there are
88
+ #other bioentries connected to references; if not delete 'em
89
+ @entry.references.each { |ref| ref.delete if ref.bioentries.size==1}
73
90
  @entry.destroy
74
91
  end
75
-
92
+
76
93
  def get_seqfeature(sf)
77
-
94
+
78
95
  #in seqfeature BioSQL class
79
96
  locations_str = sf.locations.map{|loc| loc.to_s}.join(',')
80
97
  #pp sf.locations.inspect
81
- locations_str = "join(#{locations_str})" if sf.locations.count>1
98
+ locations_str = "join(#{locations_str})" if sf.locations.count>1
82
99
  Bio::Feature.new(sf.type_term.name, locations_str,sf.seqfeature_qualifier_values.collect{|sfqv| Bio::Feature::Qualifier.new(sfqv.term.name,sfqv.value)})
83
100
  end
84
-
101
+
85
102
  def length=(len)
86
103
  @entry.biosequence.length=len
87
104
  end
88
-
105
+
89
106
  def initialize(options={})
90
- options.assert_valid_keys(:entry, :biodatabase_id,:biosequence)
107
+ #options.assert_valid_keys(:entry, :biodatabase,:biosequence)
91
108
  return @entry = options[:entry] unless options[:entry].nil?
92
-
93
- return to_biosql(options[:biosequence], options[:biodatabase_id]) unless options[:biosequence].nil? or options[:biodatabase_id].nil?
94
-
109
+
110
+ return to_biosql(options[:biosequence], options[:biodatabase]) unless options[:biosequence].nil? or options[:biodatabase].nil?
111
+
95
112
  end
96
-
97
- def to_biosql(bs,biodatabase_id)
98
- #Transcaction works greatly!!!
99
113
 
100
- #
114
+ def to_biosql(bs,biodatabase)
115
+ #DELETE #Transcaction works greatly!!!
101
116
  begin
102
- Bioentry.transaction do
103
-
104
- @entry = Bioentry.new(:biodatabase_id=>biodatabase_id, :name=>bs.entry_id)
105
-
106
- puts "primary" if $DEBUG
107
- self.primary_accession = bs.primary_accession
108
-
109
- puts "def" if $DEBUG
110
- self.definition = bs.definition unless bs.definition.nil?
111
-
112
- puts "seqver" if $DEBUG
113
- self.sequence_version = bs.sequence_version || 0
114
-
115
- puts "divi" if $DEBUG
116
- self.division = bs.division unless bs.division.nil?
117
-
118
- @entry.save!
119
- puts "secacc" if $DEBUG
120
-
121
- bs.secondary_accessions.each do |sa|
122
- #write as qualifier every secondary accession into the array
123
- self.secondary_accessions = sa
124
- end unless bs.secondary_accessions.nil?
125
-
126
-
127
- #to create the sequence entry needs to exists
128
- puts "seq" if $DEBUG
129
- puts bs.seq if $DEBUG
130
- self.seq = bs.seq unless bs.seq.nil?
131
- puts "mol" if $DEBUG
132
-
133
- self.molecule_type = bs.molecule_type unless bs.molecule_type.nil?
134
- puts "dc" if $DEBUG
135
-
136
- self.data_class = bs.data_class unless bs.data_class.nil?
137
- puts "top" if $DEBUG
138
- self.topology = bs.topology unless bs.topology.nil?
139
- puts "datec" if $DEBUG
140
- self.date_created = bs.date_created unless bs.date_created.nil?
141
- puts "datemod" if $DEBUG
142
- self.date_modified = bs.date_modified unless bs.date_modified.nil?
143
- puts "key" if $DEBUG
144
-
145
- bs.keywords.each do |kw|
146
- #write as qualifier every secondary accessions into the array
147
- self.keywords = kw
148
- end unless bs.keywords.nil?
149
- #FIX: problem settinf taxon_name: embl has "Arabidopsis thaliana (thale cress)" but in taxon_name table there isn't this name. I must check if there is a new version of the table
150
- puts "spec" if $DEBUG
151
- self.species = bs.species unless bs.species.nil?
152
- puts "Debug: #{bs.species}" if $DEBUG
153
- puts "Debug: feat..start" if $DEBUG
154
-
155
- bs.features.each do |feat|
156
- self.feature=feat
157
- end unless bs.features.nil?
158
- puts "Debug: feat...end" if $DEBUG
159
-
160
- #TODO: add comments and references
161
- bs.references.each do |reference|
162
- # puts reference.inspect
163
- self.reference=reference
164
- end unless bs.references.nil?
165
-
166
- bs.comments.each do |comment|
167
- self.comment=comment
168
- end unless bs.comments.nil?
169
-
170
- end #transaction
117
+ #DELETE Bioentry.transaction do
118
+ @entry = biodatabase.bioentries.build({:name=>bs.entry_id})
119
+
120
+ puts "primary" if $DEBUG
121
+ self.primary_accession = bs.primary_accession
122
+
123
+ puts "def" if $DEBUG
124
+ self.definition = bs.definition unless bs.definition.nil?
125
+
126
+ puts "seqver" if $DEBUG
127
+ self.sequence_version = bs.sequence_version || 0
128
+
129
+ puts "divi" if $DEBUG
130
+ self.division = bs.division unless bs.division.nil?
131
+
132
+ puts "identifier" if $DEBUG
133
+ self.identifier = bs.other_seqids.collect{|dblink| "#{dblink.database}:#{dblink.id}"}.join(';') unless bs.other_seqids.nil?
134
+ @entry.save
135
+ puts "secacc" if $DEBUG
136
+
137
+ bs.secondary_accessions.each do |sa|
138
+ puts "#{sa}" if $DEBUG
139
+ #write as qualifier every secondary accession into the array
140
+ self.secondary_accessions = sa
141
+ end unless bs.secondary_accessions.nil?
142
+
143
+
144
+ #to create the sequence entry needs to exists
145
+ puts "seq" if $DEBUG
146
+ puts bs.seq if $DEBUG
147
+ self.seq = bs.seq unless bs.seq.nil?
148
+ puts "mol" if $DEBUG
149
+
150
+ self.molecule_type = bs.molecule_type unless bs.molecule_type.nil?
151
+ puts "dc" if $DEBUG
152
+
153
+ self.data_class = bs.data_class unless bs.data_class.nil?
154
+ puts "top" if $DEBUG
155
+ self.topology = bs.topology unless bs.topology.nil?
156
+ puts "datec" if $DEBUG
157
+ self.date_created = bs.date_created unless bs.date_created.nil?
158
+ puts "datemod" if $DEBUG
159
+ self.date_modified = bs.date_modified unless bs.date_modified.nil?
160
+ puts "key" if $DEBUG
161
+
162
+ bs.keywords.each do |kw|
163
+ #write as qualifier every secondary accessions into the array
164
+ self.keywords = kw
165
+ end unless bs.keywords.nil?
166
+
167
+ puts "spec" if $DEBUG
168
+ #self.species = bs.species unless bs.species.nil?
169
+ self.species = bs.species unless bs.species.empty?
170
+ puts "Debug: #{bs.species}" if $DEBUG
171
+ puts "Debug: feat..start" if $DEBUG
172
+
173
+ bs.features.each do |feat|
174
+ self.feature=feat
175
+ end unless bs.features.nil?
176
+
177
+ puts "Debug: feat...end" if $DEBUG
178
+ bs.references.each do |reference|
179
+ self.reference=reference
180
+ end unless bs.references.nil?
181
+
182
+ bs.comments.each do |comment|
183
+ self.comment=comment
184
+ end unless bs.comments.nil?
185
+
186
+ #DELETE end #transaction
171
187
  return self
172
188
  rescue Exception => e
173
189
  puts "to_biosql exception: #{e}"
174
190
  puts $!
175
- end #rescue
191
+ end #rescue
176
192
  end #to_biosql
177
-
178
-
179
- def name
193
+
194
+
195
+ def name
180
196
  @entry.name
181
197
  end
182
198
  alias entry_id name
183
-
199
+
184
200
  def name=(value)
185
201
  @entry.name=value
186
202
  end
187
203
  alias entry_id= name=
188
-
204
+
189
205
  def primary_accession
190
206
  @entry.accession
191
207
  end
192
-
208
+
193
209
  def primary_accession=(value)
194
210
  @entry.accession=value
195
211
  end
196
-
212
+
197
213
  #TODO def secondary_accession
198
214
  # @entry.bioentry_qualifier_values
199
215
  # end
200
-
216
+
201
217
  def organism
202
218
  @entry.taxon.nil? ? "" : "#{@entry.taxon.taxon_scientific_name.name}"+ (@entry.taxon.taxon_genbank_common_name ? "(#{@entry.taxon.taxon_genbank_common_name.name})" : '')
203
219
  end
204
220
  alias species organism
205
-
221
+
206
222
  def organism=(value)
207
- taxon_name=TaxonName.find_by_name_and_name_class(value.gsub(/\s+\(.+\)/,''),'scientific name')
223
+ #FIX there is a shortcut
224
+ taxon_name=TaxonName.first(:conditions=>["name = ? and name_class = ?",value.gsub(/\s+\(.+\)/,''),'scientific name'])
208
225
  if taxon_name.nil?
209
226
  puts "Error value doesn't exists in taxon_name table with scientific name constraint."
210
227
  else
211
228
  @entry.taxon_id=taxon_name.taxon_id
212
- @entry.save!
229
+ @entry.save
213
230
  end
214
231
  end
215
232
  alias species= organism=
216
-
233
+
217
234
  def database
218
235
  @entry.biodatabase.name
219
236
  end
220
-
237
+
221
238
  def database_desc
222
239
  @entry.biodatabase.description
223
240
  end
224
-
241
+
225
242
  def version
226
243
  @entry.version
227
244
  end
228
- alias sequence_version version
229
-
245
+ alias sequence_version version
246
+
230
247
  def version=(value)
231
248
  @entry.version=value
232
249
  end
233
250
  alias sequence_version= version=
234
-
251
+
235
252
  def division
236
253
  @entry.division
237
254
  end
255
+
238
256
  def division=(value)
239
257
  @entry.division=value
240
258
  end
241
-
259
+
242
260
  def description
243
261
  @entry.description
244
262
  end
245
263
  alias definition description
246
-
264
+
247
265
  def description=(value)
248
266
  @entry.description=value
249
267
  end
250
268
  alias definition= description=
251
-
269
+
252
270
  def identifier
253
271
  @entry.identifier
254
272
  end
255
-
273
+ alias other_seqids identifier
274
+
256
275
  def identifier=(value)
257
276
  @entry.identifier=value
258
277
  end
259
-
278
+
260
279
  bioentry_qualifier_anchor :data_class
261
280
  bioentry_qualifier_anchor :molecule_type, :synonym=>'mol_type'
262
281
  bioentry_qualifier_anchor :topology
263
- bioentry_qualifier_anchor :date_created
282
+ bioentry_qualifier_anchor :date_created
264
283
  bioentry_qualifier_anchor :date_modified, :synonym=>'date_changed'
265
284
  bioentry_qualifier_anchor :keywords, :synonym=>'keyword'
266
285
  bioentry_qualifier_anchor :secondary_accessions, :synonym=>'secondary_accession'
267
-
286
+
268
287
  def features
269
- @entry.seqfeatures.collect {|sf|
270
- self.get_seqfeature(sf)}
288
+ @entry.seqfeatures.collect do |sf|
289
+ self.get_seqfeature(sf)
290
+ end
271
291
  end
272
-
292
+
273
293
  def feature=(feat)
274
- #ToDo: avoid Ontology find here, probably more efficient create class variables
275
- type_term_ontology = Ontology.find_or_create_by_name('SeqFeature Keys')
276
- type_term = Term.find_or_create_by_name(:name=>feat.feature, :ontology=>type_term_ontology)
277
- source_term_ontology = Ontology.find_or_create_by_name('SeqFeature Sources')
278
- source_term = Term.find_or_create_by_name(:name=>'EMBLGenBankSwit',:ontology=>source_term_ontology)
279
- seqfeature = Seqfeature.create(:bioentry=>@entry, :source_term=>source_term, :type_term=>type_term, :rank=>@entry.seqfeatures.count.succ, :display_name=>'')
280
- #seqfeature.save!
294
+ #ToDo: avoid Ontology find here, probably more efficient create class variables
295
+ #DELETE type_term_ontology = Ontology.find_or_create({:name=>'SeqFeature Keys'})
296
+ puts "feature:type_term = #{feat.feature}" if $DEBUG
297
+ type_term = Term.first(:conditions=>["name = ?", feat.feature]) || Term.create({:name=>feat.feature, :ontology=>Ontology.first(:conditions=>["name = ?",'SeqFeature Keys'])})
298
+ #DELETE source_term_ontology = Ontology.find_or_create({:name=>'SeqFeature Sources'})
299
+ puts "feature:source_term" if $DEBUG
300
+ source_term = Term.first(:conditions=>["name = ?",'EMBLGenBankSwit'])
301
+ puts "feature:seqfeature" if $DEBUG
302
+ seqfeature = @entry.seqfeatures.build({:source_term=>source_term, :type_term=>type_term, :rank=>@entry.seqfeatures.count.succ, :display_name=>''})
303
+ seqfeature.save
304
+ puts "feature:location" if $DEBUG
281
305
  feat.locations.each do |loc|
282
- location = Location.new(:seqfeature=>seqfeature, :start_pos=>loc.from, :end_pos=>loc.to, :strand=>loc.strand, :rank=>seqfeature.locations.count.succ)
283
- location.save!
306
+ location = seqfeature.locations.build({:seqfeature=>seqfeature, :start_pos=>loc.from, :end_pos=>loc.to, :strand=>loc.strand, :rank=>seqfeature.locations.count.succ})
307
+ location.save
284
308
  end
285
- qual_term_ontology = Ontology.find_or_create_by_name('Annotation Tags')
309
+
310
+ #DELETE qual_term_ontology = Ontology.find_or_create({:name=>'Annotation Tags'})
311
+
312
+ puts "feature:qualifier" if $DEBUG
286
313
  feat.each do |qualifier|
287
- qual_term = Term.find_or_create_by_name(:name=>qualifier.qualifier, :ontology=>qual_term_ontology)
288
- qual = SeqfeatureQualifierValue.new(:seqfeature=>seqfeature, :term=>qual_term, :value=>qualifier.value.to_s, :rank=>seqfeature.seqfeature_qualifier_values.count.succ)
289
- qual.save!
314
+ #DELETE qual_term = Term.find_or_create({:name=>qualifier.qualifier}, {:ontology=>qual_term_ontology})
315
+ qual_term = Term.first(:conditions=>["name = ?", qualifier.qualifier]) || Term.create({:name=>qualifier.qualifier, :ontology=>Ontology.first(:conditions=>["name = ?", 'Annotation Tags'])})
316
+ qual = seqfeature.seqfeature_qualifier_values.build({:seqfeature=>seqfeature, :term=>qual_term, :value=>qualifier.value.to_s, :rank=>seqfeature.seqfeature_qualifier_values.count.succ})
317
+ qual.save
318
+
290
319
  end
291
320
  end
292
-
321
+
293
322
  #return the seqfeature mapped from BioSQL with a type_term like 'CDS'
294
323
  def cdsfeatures
295
324
  @entry.cdsfeatures
296
325
  end
297
-
326
+
298
327
  # Returns the sequence.
299
328
  # Returns a Bio::Sequence::Generic object.
300
329
 
@@ -302,39 +331,41 @@ module Bio
302
331
  s = @entry.biosequence
303
332
  Bio::Sequence::Generic.new(s ? s.seq : '')
304
333
  end
305
-
306
- def seq=(value)
307
334
 
335
+ def seq=(value)
336
+ #TODO: revise this piece of code.
308
337
  #chk which type of alphabet is, NU/NA/nil
309
338
  if @entry.biosequence.nil?
310
- # puts "intoseq1"
339
+ #DELETE puts "intoseq1"
311
340
  @entry.biosequence = Biosequence.new(:seq=>value)
312
- @entry.biosequence.save!
313
-
341
+ # biosequence = @entry.biosequence.build({:seq=>value})
342
+ @entry.biosequence.save
343
+ # biosequence.save
314
344
  else
315
345
  @entry.biosequence.seq=value
316
346
  end
317
347
  self.length=value.length
318
- #@entry.biosequence.length=value.length
319
- #break
320
- @entry.save!
348
+ #DELETE #@entry.biosequence.length=value.length
349
+ #DELETE #break
350
+ @entry.save
321
351
  end
322
-
352
+
353
+ #report parents and exclude info with "no rank". Now I report rank == class but ... Question ? Have to be reported taxonomy with rank=="class"?
323
354
  def taxonomy
324
355
  tax = []
325
- taxon = @entry.taxon
326
- while taxon and taxon.taxon_id != taxon.parent_taxon_id
327
- tax << taxon.taxon_scientific_name.name
356
+ taxon = Taxon.first(:conditions=>["taxon_id = ?",@entry.taxon.parent_taxon_id])
357
+ while taxon and taxon.taxon_id != taxon.parent_taxon_id and taxon.node_rank!='no rank'
358
+ tax << taxon.taxon_scientific_name.name if taxon.node_rank!='class'
328
359
  #Note: I don't like this call very much, correct with a relationship in the ref class.
329
- taxon = Taxon.find(taxon.parent_taxon_id)
360
+ taxon = Taxon.first(:conditions=>["taxon_id = ?",taxon.parent_taxon_id])
330
361
  end
331
362
  tax.reverse
332
363
  end
333
-
334
- def length
364
+
365
+ def length
335
366
  @entry.biosequence.length
336
367
  end
337
-
368
+
338
369
  def references
339
370
  #return and array of hash, hash has these keys ["title", "dbxref_id", "reference_id", "authors", "crc", "location"]
340
371
  #probably would be better to d a class refrence to collect these informations
@@ -342,7 +373,7 @@ module Bio
342
373
  hash = Hash.new
343
374
  hash['authors'] = bio_ref.reference.authors.gsub(/\.\s/, "\.\s\|").split(/\|/)
344
375
 
345
- hash['sequence_position'] = "#{bio_ref.start_pos}-#{bio_ref.end_pos}" if (bio_ref.start_pos and bio_ref.end_pos)
376
+ hash['sequence_position'] = "#{bio_ref.start_pos}-#{bio_ref.end_pos}" if (bio_ref.start_pos and bio_ref.end_pos)
346
377
  hash['title'] = bio_ref.reference.title
347
378
  hash['embl_gb_record_number'] = bio_ref.rank
348
379
  #TODO: solve the problem with specific comment per reference.
@@ -350,159 +381,64 @@ module Bio
350
381
  #take a look when location is build up in def reference=(value)
351
382
 
352
383
  bio_ref.reference.location.split('|').each do |element|
353
- key,value=element.split('=')
354
- hash[key]=value
384
+ key,value=element.split('=')
385
+ hash[key]=value
355
386
  end unless bio_ref.reference.location.nil?
356
387
 
357
388
  hash['xrefs'] = bio_ref.reference.dbxref ? "#{bio_ref.reference.dbxref.dbname}; #{bio_ref.reference.dbxref.accession}." : ''
358
389
  Bio::Reference.new(hash)
359
- end
390
+ end
360
391
  end
361
-
392
+
362
393
  def comments
363
394
  @entry.comments.map do |comment|
364
395
  comment.comment_text
365
396
  end
366
397
  end
367
398
 
368
-
369
- def reference=(value)
370
-
371
- locations=Array.new
372
- locations << "journal=#{value.journal}" unless value.journal.empty?
373
- locations << "volume=#{value.volume}" unless value.volume.empty?
374
- locations << "issue=#{value.issue}" unless value.issue.empty?
375
- locations << "pages=#{value.pages}" unless value.pages.empty?
376
- locations << "year=#{value.year}" unless value.year.empty?
377
- locations << "pubmed=#{value.pubmed}" unless value.pubmed.empty?
378
- locations << "medline=#{value.medline}" unless value.medline.empty?
379
- locations << "doi=#{value.doi}" unless value.doi.nil?
380
- locations << "abstract=#{value.abstract}" unless value.abstract.empty?
381
- locations << "url=#{value.url}" unless value.url.nil?
382
- locations << "mesh=#{value.mesh}" unless value.mesh.empty?
383
- locations << "affiliations=#{value.affiliations}" unless value.affiliations.empty?
384
- locations << "comments=#{value.comments.join('~')}"unless value.comments.nil?
385
- start_pos, end_pos = value.sequence_position ? value.sequence_position.gsub(/\s*/,'').split('-') : [nil,nil]
386
- reference=Reference.find_or_create_by_title(:title=>value.title, :authors=>value.authors.join(' '), :location=>locations.join('|'))
387
-
388
- bio_reference=BioentryReference.new(:bioentry=>@entry,:reference=>reference,:rank=>value.embl_gb_record_number, :start_pos=>start_pos, :end_pos=>end_pos)
389
- bio_reference.save!
390
- end
391
-
399
+ def reference=(value)
400
+ locations=Array.new
401
+ locations << "journal=#{value.journal}" unless value.journal.empty?
402
+ locations << "volume=#{value.volume}" unless value.volume.empty?
403
+ locations << "issue=#{value.issue}" unless value.issue.empty?
404
+ locations << "pages=#{value.pages}" unless value.pages.empty?
405
+ locations << "year=#{value.year}" unless value.year.empty?
406
+ locations << "pubmed=#{value.pubmed}" unless value.pubmed.empty?
407
+ locations << "medline=#{value.medline}" unless value.medline.empty?
408
+ locations << "doi=#{value.doi}" unless value.doi.nil?
409
+ locations << "abstract=#{value.abstract}" unless value.abstract.empty?
410
+ locations << "url=#{value.url}" unless value.url.nil?
411
+ locations << "mesh=#{value.mesh}" unless value.mesh.empty?
412
+ locations << "affiliations=#{value.affiliations}" unless value.affiliations.empty?
413
+ locations << "comments=#{value.comments.join('~')}"unless value.comments.nil?
414
+ start_pos, end_pos = value.sequence_position ? value.sequence_position.gsub(/\s*/,'').split('-') : [nil,nil]
415
+ reference= Reference.first(:conditions=>["title = ?",value.title]) || Reference.create({:title=>value.title,:authors=>value.authors.join(' '), :location=>locations.join('|')})
416
+ bio_reference=@entry.bioentry_references.build({:reference=>reference,:rank=>value.embl_gb_record_number, :start_pos=>start_pos, :end_pos=>end_pos})
417
+ bio_reference.save
418
+ end
419
+
392
420
  def comment=(value)
393
- comment=Comment.new(:bioentry=>@entry, :comment_text=>value, :rank=>@entry.comments.count.succ)
394
- comment.save!
421
+ #DELETE comment=Comment.new({:bioentry=>@entry, :comment_text=>value, :rank=>@entry.comments.count.succ})
422
+ comment = @entry.comments.build({:comment_text=>value, :rank=>@entry.comments.count.succ})
423
+ comment.save
395
424
  end
396
-
425
+
397
426
  def save
398
427
  #I should add chks for SQL errors
399
- @entry.biosequence.save!
400
- @entry.save!
428
+ @entry.biosequence.save
429
+ @entry.save
401
430
  end
402
431
  def to_fasta
403
- #prima erano 2 print in stdout, meglio ritornare una stringa in modo che poi ci si possa fare quello che si vuole
404
- #print ">" + accession + "\n"
405
- #print seq.gsub(Regexp.new(".{1,#{60}}"), "\\0\n")
406
- ">" + accession + "\n" + seq.gsub(Regexp.new(".{1,#{60}}"), "\\0\n")
432
+ ">" + accession + "\n" + seq.gsub(Regexp.new(".{1,#{60}}"), "\\0\n")
407
433
  end
408
-
434
+
409
435
  def to_fasta_reverse_complememt
410
- ">" + accession + "\n" + seq.reverse_complement.gsub(Regexp.new(".{1,#{60}}"), "\\0\n")
436
+ ">" + accession + "\n" + seq.reverse_complement.gsub(Regexp.new(".{1,#{60}}"), "\\0\n")
411
437
  end
412
-
413
-
414
-
438
+
415
439
  def to_biosequence
416
- Bio::Sequence.adapter(self,Bio::Sequence::Adapter::BioSQL)
440
+ Bio::Sequence.adapter(self,Bio::Sequence::Adapter::BioSQL)
417
441
  end
418
442
  end #Sequence
419
-
420
-
421
443
  end #SQL
422
444
  end #Bio
423
-
424
- #TODO create tests for sequence object, roundtrip of informations
425
-
426
- if __FILE__ == $0
427
-
428
- require 'bio'
429
- require 'bio/io/sql'
430
- require 'pp'
431
-
432
- # connection = Bio::SQL.establish_connection('bio/io/biosql/config/database.yml','development')
433
- connection = Bio::SQL.establish_connection({'development'=>{'database'=>"biorails_development", 'adapter'=>"postgresql", 'username'=>"rails", 'password'=>nil}},'development')
434
- databases = Bio::SQL.list_databases
435
-
436
- # parser = Bio::FlatFile.auto('/home/febo/Desktop/aj224122.embl')
437
- parser = Bio::FlatFile.auto('/home/febo/Desktop/aj224122.gb')
438
- #parser = Bio::FlatFile.auto('/home/febo/Desktop/aj224122.fasta')
439
-
440
- parser.each do |entry|
441
- biosequence = entry.to_biosequence
442
- result = Bio::SQL::Sequence.new(:biosequence=>biosequence,:biodatabase_id=>databases.first[:id]) unless Bio::SQL.exists_accession(biosequence.primary_accession)
443
-
444
- if result.nil?
445
- pp "The sequence is already present into the biosql database"
446
- else
447
- # pp "Sequence"
448
- puts result.to_biosequence.output(:genbank) #:embl
449
- result.delete
450
- end
451
- end
452
-
453
- if false
454
- sqlseq = Bio::SQL.fetch_accession('AJ224122')
455
- #only output tests.
456
- pp "Connection"
457
- pp connection
458
- pp "Seq in dbs"
459
- pp Bio::SQL.list_entries
460
- #; NC_003098
461
-
462
-
463
- #pp sqlseq
464
- pp sqlseq.entry.inspect
465
- pp "sequence"
466
- #pp Bio::Sequence.auto(sqlseq.seq)
467
- pp "entry_id"
468
- pp sqlseq.entry_id
469
-
470
- pp "primary"
471
- pp sqlseq.accession
472
- pp "secondary_accessions"
473
- pp sqlseq.secondary_accessions
474
- pp "molecule type"
475
- pp sqlseq.molecule_type
476
- pp "data_class"
477
- pp sqlseq.data_class
478
- pp "division"
479
- pp sqlseq.division
480
- # NOTE : Topology is not represented in biosql?
481
- pp "topology"
482
- #TODO: CIRCULAR this at present maps to bioentry_qualifier_value, though there are plans to make it a column in table biosequence.
483
- pp sqlseq.topology
484
- pp "version"
485
- pp sqlseq.version
486
- #sequence.date_created = nil #????
487
- pp "date modified"
488
- pp sqlseq.date_modified
489
- pp "definition"
490
- pp sqlseq.definition
491
- pp "keywords"
492
- pp sqlseq.keywords
493
- pp "species"
494
- pp sqlseq.organism
495
- #sequence.classification = self.taxonomy.to_s.sub(/\.\z/, '').split(/\s*\;\s*/)"
496
- pp "classification"
497
- pp sqlseq.taxonomy
498
- #sequence.organnella = nil # not used
499
- pp "comments"
500
- pp sqlseq.comments
501
- pp "references"
502
- pp sqlseq.references
503
- pp "features"
504
- pp sqlseq.features
505
- puts sqlseq.to_biosequence.output(:embl)
506
- end
507
- ##
508
- end