sequenceserver 0.8.5 → 0.8.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -506,7 +506,7 @@ HEADER
506
506
  return line
507
507
  else
508
508
  settings.log.debug('Added link for: `'+ sequence_id +'\''+ link)
509
- return "><a href='#{url(link)}'>#{sequence_id}</a> \n"
509
+ return "><a href='#{url(link)}' target='_blank'>#{sequence_id}</a> \n"
510
510
  end
511
511
 
512
512
  end
@@ -7,4 +7,4 @@
7
7
  * Author: Felix Gnass [fgnass at neteye dot de]
8
8
  * Version: 1.0.0
9
9
  */
10
- (function($){$.fn.activity=function(opts){this.each(function(){var $this=$(this);var el=$this.data("activity");if(el){clearInterval(el.data("interval"));el.remove();$this.removeData("activity");}if(opts!==false){opts=$.extend({color:$this.css("color")},$.fn.activity.defaults,opts);el=render($this,opts).css("position","absolute").prependTo(opts.outside?"body":$this);var h=$this.outerHeight()-el.height();var w=$this.outerWidth()-el.width();var margin={top:opts.valign=="top"?opts.padding:opts.valign=="bottom"?h-opts.padding:Math.floor(h/2),left:opts.align=="left"?opts.padding:opts.align=="right"?w-opts.padding:Math.floor(w/2)};var offset=$this.offset();if(opts.outside){el.css({top:offset.top+"px",left:offset.left+"px"});}else{margin.top-=el.offset().top-offset.top;margin.left-=el.offset().left-offset.left;}el.css({marginTop:margin.top+"px",marginLeft:margin.left+"px"});animate(el,opts.segments,Math.round(10/opts.speed)/10);$this.data("activity",el);}});return this;};$.fn.activity.defaults={segments:12,space:3,length:7,width:4,speed:1.2,align:"center",valign:"center",padding:4};$.fn.activity.getOpacity=function(opts,i){var steps=opts.steps||opts.segments-1;var end=opts.opacity!==undefined?opts.opacity:1/steps;return 1-Math.min(i,steps)*(1-end)/steps;};var render=function(){return $("<div>").addClass("busy");};var animate=function(){};function svg(tag,attr){var el=document.createElementNS("http://www.w3.org/2000/svg",tag||"svg");if(attr){$.each(attr,function(k,v){el.setAttributeNS(null,k,v);});}return $(el);}if(document.createElementNS&&document.createElementNS("http://www.w3.org/2000/svg","svg").createSVGRect){render=function(target,d){var innerRadius=d.width*2+d.space;var r=(innerRadius+d.length+Math.ceil(d.width/2)+1);var el=svg().width(r*2).height(r*2);var g=svg("g",{"stroke-width":d.width,"stroke-linecap":"round",stroke:d.color}).appendTo(svg("g",{transform:"translate("+r+","+r+")"}).appendTo(el));for(var i=0;i<d.segments;i++){g.append(svg("line",{x1:0,y1:innerRadius,x2:0,y2:innerRadius+d.length,transform:"rotate("+(360/d.segments*i)+", 0, 0)",opacity:$.fn.activity.getOpacity(d,i)}));}return $("<div>").append(el).width(2*r).height(2*r);};if(document.createElement("div").style.WebkitAnimationName!==undefined){var animations={};animate=function(el,steps,duration){if(!animations[steps]){var name="spin"+steps;var rule="@-webkit-keyframes "+name+" {";for(var i=0;i<steps;i++){var p1=Math.round(100000/steps*i)/1000;var p2=Math.round(100000/steps*(i+1)-1)/1000;var value="% { -webkit-transform:rotate("+Math.round(360/steps*i)+"deg); }\n";rule+=p1+value+p2+value;}rule+="100% { -webkit-transform:rotate(100deg); }\n}";document.styleSheets[0].insertRule(rule);animations[steps]=name;}el.css("-webkit-animation",animations[steps]+" "+duration+"s linear infinite");};}else{animate=function(el,steps,duration){var rotation=0;var g=el.find("g g").get(0);el.data("interval",setInterval(function(){g.setAttributeNS(null,"transform","rotate("+(++rotation%steps*(360/steps))+")");},duration*1000/steps));};}}else{var s=$("<shape>").css("behavior","url(#default#VML)").appendTo("body");if(s.get(0).adj){var sheet=document.createStyleSheet();$.each(["group","shape","stroke"],function(){sheet.addRule(this,"behavior:url(#default#VML);");});render=function(target,d){var innerRadius=d.width*2+d.space;var r=(innerRadius+d.length+Math.ceil(d.width/2)+1);var s=r*2;var o=-Math.ceil(s/2);var el=$("<group>",{coordsize:s+" "+s,coordorigin:o+" "+o}).css({top:o,left:o,width:s,height:s});for(var i=0;i<d.segments;i++){el.append($("<shape>",{path:"m "+innerRadius+",0 l "+(innerRadius+d.length)+",0"}).css({width:s,height:s,rotation:(360/d.segments*i)+"deg"}).append($("<stroke>",{color:d.color,weight:d.width+"px",endcap:"round",opacity:$.fn.activity.getOpacity(d,i)})));}return $("<group>",{coordsize:s+" "+s}).css({width:s,height:s,overflow:"hidden"}).append(el);};animate=function(el,steps,duration){var rotation=0;var g=el.get(0);el.data("interval",setInterval(function(){g.style.rotation=++rotation%steps*(360/steps);},duration*1000/steps));};}$(s).remove();}})(jQuery);
10
+ (function($){$.fn.activity=function(opts){this.each(function(){var $this=$(this);var el=$this.data("activity");if(el){clearInterval(el.data("interval"));el.remove();$this.removeData("activity");}if(opts!==false){opts=$.extend({color:$this.css("color")},$.fn.activity.defaults,opts);el=render($this,opts).css("position","absolute").prependTo(opts.outside?"body":$this);var h=$this.outerHeight()-el.height();var w=$this.outerWidth()-el.width();var margin={top:opts.valign=="top"?opts.padding:opts.valign=="bottom"?h-opts.padding:Math.floor(h/2),left:opts.align=="left"?opts.padding:opts.align=="right"?w-opts.padding:Math.floor(w/2)};var offset=$this.offset();if(opts.outside){el.css({top:offset.top+"px",left:offset.left+"px"});}else{margin.top-=el.offset().top-offset.top;margin.left-=el.offset().left-offset.left;}el.css({marginTop:margin.top+"px",marginLeft:margin.left+"px"});animate(el,opts.segments,Math.round(10/opts.speed)/10);$this.data("activity",el);}});return this;};$.fn.activity.defaults={segments:12,space:3,length:7,width:4,speed:1.2,align:"center",valign:"center",padding:4};$.fn.activity.getOpacity=function(opts,i){var steps=opts.steps||opts.segments-1;var end=opts.opacity!==undefined?opts.opacity:1/steps;return 1-Math.min(i,steps)*(1-end)/steps;};var render=function(){return $("<div>").addClass("busy");};var animate=function(){};function svg(tag,attr){var el=document.createElementNS("http://www.w3.org/2000/svg",tag||"svg");if(attr){$.each(attr,function(k,v){el.setAttributeNS(null,k,v);});}return $(el);}if(document.createElementNS&&document.createElementNS("http://www.w3.org/2000/svg","svg").createSVGRect){render=function(target,d){var innerRadius=d.width*2+d.space;var r=(innerRadius+d.length+Math.ceil(d.width/2)+1);var el=svg().width(r*2).height(r*2);var g=svg("g",{"stroke-width":d.width,"stroke-linecap":"round",stroke:d.color}).appendTo(svg("g",{transform:"translate("+r+","+r+")"}).appendTo(el));for(var i=0;i<d.segments;i++){g.append(svg("line",{x1:0,y1:innerRadius,x2:0,y2:innerRadius+d.length,transform:"rotate("+(360/d.segments*i)+", 0, 0)",opacity:$.fn.activity.getOpacity(d,i)}));}return $("<div>").append(el).width(2*r).height(2*r);};if(document.createElement("div").style.WebkitAnimationName!==undefined){var animations={};animate=function(el,steps,duration){if(!animations[steps]){var name="spin"+steps;var rule="@-webkit-keyframes "+name+" {";for(var i=0;i<steps;i++){var p1=Math.round(100000/steps*i)/1000;var p2=Math.round(100000/steps*(i+1)-1)/1000;var value="% { -webkit-transform:rotate("+Math.round(360/steps*i)+"deg); }\n";rule+=p1+value+p2+value;}rule+="100% { -webkit-transform:rotate(100deg); }\n}";document.styleSheets[0].insertRule(rule,0);animations[steps]=name;}el.css("-webkit-animation",animations[steps]+" "+duration+"s linear infinite");};}else{animate=function(el,steps,duration){var rotation=0;var g=el.find("g g").get(0);el.data("interval",setInterval(function(){g.setAttributeNS(null,"transform","rotate("+(++rotation%steps*(360/steps))+")");},duration*1000/steps));};}}else{var s=$("<shape>").css("behavior","url(#default#VML)").appendTo("body");if(s.get(0).adj){var sheet=document.createStyleSheet();$.each(["group","shape","stroke"],function(){sheet.addRule(this,"behavior:url(#default#VML);");});render=function(target,d){var innerRadius=d.width*2+d.space;var r=(innerRadius+d.length+Math.ceil(d.width/2)+1);var s=r*2;var o=-Math.ceil(s/2);var el=$("<group>",{coordsize:s+" "+s,coordorigin:o+" "+o}).css({top:o,left:o,width:s,height:s});for(var i=0;i<d.segments;i++){el.append($("<shape>",{path:"m "+innerRadius+",0 l "+(innerRadius+d.length)+",0"}).css({width:s,height:s,rotation:(360/d.segments*i)+"deg"}).append($("<stroke>",{color:d.color,weight:d.width+"px",endcap:"round",opacity:$.fn.activity.getOpacity(d,i)})));}return $("<group>",{coordsize:s+" "+s}).css({width:s,height:s,overflow:"hidden"}).append(el);};animate=function(el,steps,duration){var rotation=0;var g=el.get(0);el.data("interval",setInterval(function(){g.style.rotation=++rotation%steps*(360/steps);},duration*1000/steps));};}$(s).remove();}})(jQuery);
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
  # meta
3
3
  s.name = 'sequenceserver'
4
- s.version = '0.8.5'
4
+ s.version = '0.8.6'
5
5
  s.authors = ['Anurag Priyam', 'Ben J Woodcroft', 'Yannick Wurm']
6
6
  s.email = 'anurag08priyam@gmail.com'
7
7
  s.homepage = 'http://sequenceserver.com'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequenceserver
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.5
4
+ version: 0.8.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2013-04-27 00:00:00.000000000 Z
14
+ date: 2013-11-28 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: bundler
@@ -152,75 +152,49 @@ extensions: []
152
152
  extra_rdoc_files: []
153
153
  files:
154
154
  - lib/sequenceserver/sequencehelpers.rb
155
- - lib/sequenceserver/helpers.rb
155
+ - lib/sequenceserver/customisation.rb
156
156
  - lib/sequenceserver/blast.rb
157
- - lib/sequenceserver/sinatralikeloggerformatter.rb
158
- - lib/sequenceserver/database_formatter.rb~
159
157
  - lib/sequenceserver/database.rb
160
158
  - lib/sequenceserver/version.rb
159
+ - lib/sequenceserver/helpers.rb
160
+ - lib/sequenceserver/sinatralikeloggerformatter.rb
161
161
  - lib/sequenceserver/database_formatter.rb
162
- - lib/sequenceserver/customisation.rb
163
- - lib/blast.rb~
164
162
  - lib/sequenceserver.rb
165
- - views/500.erb
166
163
  - views/_options.erb
164
+ - views/500.erb
167
165
  - views/search.erb
168
- - views/search.erb~
169
- - public/js/bootstrap.modal.js
170
- - public/js/bootstrap.dropdown.js
171
- - public/js/bootstrap.transition.js
166
+ - public/js/jquery.activity.js
167
+ - public/js/sequenceserver.js
168
+ - public/js/jquery.js
172
169
  - public/js/jquery-scrollspy.js
173
- - public/js/jquery-ui.js
174
170
  - public/js/sequenceserver.blast.js
171
+ - public/js/bootstrap.dropdown.js
175
172
  - public/js/store.min.js
176
- - public/js/sequenceserver.js~
173
+ - public/js/bootstrap.modal.js
174
+ - public/js/bootstrap.transition.js
175
+ - public/js/jquery-ui.js
177
176
  - public/js/jquery.enablePlaceholder.min.js
178
- - public/js/jquery.activity.js
179
- - public/js/sequenceserver.js
180
- - public/js/jquery.js
181
- - public/img/glyphicons-halflings.png
182
- - public/img/glyphicons-halflings-white.png
183
- - public/css/bootstrap.dropdown.css
177
+ - public/css/bootstrap.min.css
178
+ - public/css/bootstrap.modal.css
184
179
  - public/css/bootstrap.icons.css
185
- - public/css/custom.css
186
- - public/css/beige.css~
180
+ - public/css/bootstrap.dropdown.css
187
181
  - public/css/beige.css.css
188
- - public/css/bootstrap.modal.css
189
- - public/css/bootstrap.min.css
190
- - tests/database/nucleotide/Sinvicta2-2-3.cdna.subset.fasta
191
- - tests/database/nucleotide/headVno_parse.archive.csv
192
- - tests/database/nucleotide/head.faVparse.html
193
- - tests/database/nucleotide/parse.info
194
- - tests/database/nucleotide/headVparse.archive.csv
195
- - tests/database/nucleotide/headVparse.archive
196
- - tests/database/nucleotide/parse.fa.nsi
197
- - tests/database/nucleotide/headVno_parse.archive
198
- - tests/database/nucleotide/parse.fa.nsd
199
- - tests/database/nucleotide/parse.fa.nsq
200
- - tests/database/nucleotide/parse.fa.nhr
201
- - tests/database/nucleotide/head.faVno_parse.html
202
- - tests/database/nucleotide/parse.fa.nog
203
- - tests/database/nucleotide/no_parse.fa
204
- - tests/database/nucleotide/parse.fa
205
- - tests/database/nucleotide/no_parse.fa.nsq
206
- - tests/database/nucleotide/parse.fa.nin
207
- - tests/database/nucleotide/Sinvicta2-2-3.cdna.subset.fasta.nsq
208
- - tests/database/nucleotide/Sinvicta2-2-3.cdna.subset.fasta.nhr
209
- - tests/database/nucleotide/Sinvicta2-2-3.cdna.subset.fasta.nin
210
- - tests/database/nucleotide/no_parse.fa.nin
211
- - tests/database/nucleotide/head.fa
212
- - tests/database/nucleotide/no_parse.info
213
- - tests/database/nucleotide/no_parse.fa.nhr
214
- - tests/database/protein/Sinvicta2-2-3.prot.subset.fasta.pin
215
- - tests/database/protein/Sinvicta2-2-3.prot.subset.fasta
216
- - tests/database/protein/Sinvicta2-2-3.prot.subset.fasta.psq
217
- - tests/database/protein/Sinvicta2-2-3.prot.subset.fasta.phr
218
- - tests/run
182
+ - public/css/custom.css
183
+ - public/img/glyphicons-halflings-white.png
184
+ - public/img/glyphicons-halflings.png
185
+ - tests/ui.specs.todo
219
186
  - tests/test_sequenceserver_blast.rb
220
187
  - tests/test_ui.rb
221
- - tests/ui.specs.todo
222
- - tests/chromedriver.log
223
188
  - tests/test_sequencehelpers.rb
189
+ - tests/database/protein/Sinvicta2-2-3.prot.subset.fasta.psq
190
+ - tests/database/protein/Sinvicta2-2-3.prot.subset.fasta.pin
191
+ - tests/database/protein/Sinvicta2-2-3.prot.subset.fasta.phr
192
+ - tests/database/protein/Sinvicta2-2-3.prot.subset.fasta
193
+ - tests/database/nucleotide/Sinvicta2-2-3.cdna.subset.fasta.nhr
194
+ - tests/database/nucleotide/Sinvicta2-2-3.cdna.subset.fasta.nin
195
+ - tests/database/nucleotide/Sinvicta2-2-3.cdna.subset.fasta.nsq
196
+ - tests/database/nucleotide/Sinvicta2-2-3.cdna.subset.fasta
197
+ - tests/run
224
198
  - config.ru
225
199
  - example.config.yml
226
200
  - LICENSE.txt
@@ -228,8 +202,7 @@ files:
228
202
  - README.txt
229
203
  - Gemfile
230
204
  - sequenceserver.gemspec
231
- - !binary |-
232
- YmluL3NlcXVlbmNlc2VydmVy
205
+ - bin/sequenceserver
233
206
  homepage: http://sequenceserver.com
234
207
  licenses:
235
208
  - SequenceServer (custom)
@@ -254,9 +227,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
254
227
  version: '0'
255
228
  requirements: []
256
229
  rubyforge_project:
257
- rubygems_version: 1.8.24
230
+ rubygems_version: 1.8.23
258
231
  signing_key:
259
232
  specification_version: 3
260
233
  summary: BLAST search made easy!
261
234
  test_files: []
262
- has_rdoc:
data/lib/blast.rb~ DELETED
@@ -1,200 +0,0 @@
1
- require 'tempfile'
2
- require 'open3'
3
-
4
- module SequenceServer
5
- # Simple ncbi-blast wrapper. Check examples below.
6
- class Blast
7
- # blast method
8
- attr_accessor :method
9
-
10
- # database name
11
- attr_accessor :db
12
-
13
- # query sequence string
14
- attr_accessor :qstring
15
-
16
- # query file name
17
- attr_accessor :qfile
18
-
19
- # advanced blast options
20
- attr_accessor :options
21
-
22
- # command string to be executed
23
- attr_reader :command
24
-
25
- # result of executing command
26
- attr_reader :result
27
-
28
- # blast archive file output
29
- attr_reader :blast_archive_tempfile
30
-
31
- # errors if any while executing command
32
- attr_reader :error
33
-
34
- # Initialize a new blast search.
35
- # ---
36
- # Arguments(optional):
37
- # * method(String) - blast executable (shell executable, or absolute path)
38
- # * db(String) - database name as returned by 'blastdbcmd -list'
39
- # * query(Hash) - query string/file, and options.
40
- #
41
- # In the query Hash, use:
42
- # * :qfile(String) - to run Blast against a file.
43
- # * :qstrin(String) - to run Blast against a string.
44
- # * :options(String) - to specify multiple blast options.
45
- #
46
- # Either :qfile, or :qstring should be used. If both are given, by design
47
- # :qstring will be used to run blast.
48
- # ---
49
- # Examples:
50
- #
51
- # b = Blast.new("blastn", "S.cdna.fasta", :qfile => 'query.seq', :options => "-html -num_threads 4")
52
- # b = Blast.new("blastn", "S.cdna.fasta", :qstring => 'ATGTCCGCGAATCGATTGAACGTGCTGGTGACCCTGATGCTCGCCGTCGCGCTTCTTGTG')
53
- #
54
- # b.run! => true
55
- # b.result => "blast output"
56
- #
57
- # # change the blast method.
58
- # b.method = 'blastp'
59
- #
60
- # b.run! => false
61
- # b.error => "blast error output"
62
- def initialize(method = nil, db = nil, query = {})
63
- @method = method
64
- @db = db
65
- @qstring = query[:qstring]
66
- @qfile = query[:qfile]
67
- @options = query[:options]
68
- end
69
-
70
- # Run blast everytime it is called. Returns the success
71
- # status - true, or false. Blast method, db, and qfile/qstring
72
- # need to be set before calling this method, else blast will fail.
73
- #
74
- # b = Blast.new
75
- # b.run! => false
76
- #
77
- # # set blast method, and db
78
- # b.method = 'blastn'
79
- # b.db = 'S.cdna.fasta'
80
- #
81
- # b.run! => false
82
- # b.errors => "blast error output"
83
- #
84
- # # set qfile
85
- # b.qfile = 'query1.seq'
86
- #
87
- # b.run! => true
88
- # b.reuslt => "blast output"
89
- def run!
90
- # can not run blast if method is not specified
91
- return false unless @method
92
-
93
- # create a tempfile if qstring is given
94
- if @qstring
95
- @tempfile = Tempfile.new('qfile')
96
- @tempfile.puts(qstring)
97
- @tempfile.close
98
- @qfile = @tempfile.path
99
- end
100
-
101
- # form command to execute
102
- @command = to_s
103
-
104
- # execute command and capture both stdout, and stderr
105
- Open3.popen3(@command) do |stdin, stdout, stderr|
106
- @result = stdout.readlines # convert to string?
107
- @error = stderr.readlines
108
- end
109
-
110
- # set and return success status
111
- return @success = @error.empty?
112
-
113
- ensure
114
- # delete tempfile if it was created
115
- @tempfile.unlink if @tempfile
116
- end
117
-
118
- # Return the blast type used as a String.
119
- #
120
- # b.method = '/home/yeban/opt/blastn'
121
- # b.type => 'blastn'
122
- def type
123
- @type ||= @method[(@method.rindex('/') + 1)..-1]
124
- end
125
-
126
- # Return success status - true, false, or nil.
127
- # 'nil' implies that blast has not been run yet.
128
- def success?
129
- @success
130
- end
131
-
132
- # String representation of the blast object - same as
133
- # the command to be executed.
134
- def to_s
135
- s = "#@method "
136
- s << "-db '#@db' " if @db
137
- s << "-query #@qfile " if @qfile
138
- s << @options.to_s if @options
139
- s
140
- end
141
-
142
- # Especially helpful in irb - "status : command"
143
- def inspect
144
- return to_s if success?.nil?
145
- (success? ? "success : " : "fail : ") + @command
146
- end
147
-
148
- # Run the blast with the options specified by the user, returning a blast archive file, which can be further transformed into other formats
149
- def run_to_blast_archive!
150
- @blast_archive_tempfile = Tempfile.open('seqserve_formatter')
151
-
152
- # Add -outfmt 11 to list of options so that it outputs a blast archive
153
- @options ||= ''
154
- @options += " -outfmt 11 -out #{@blast_archive_tempfile.path}"
155
-
156
- # Run the blast
157
- run!
158
- return @success unless @success
159
- end
160
-
161
- # convert the blast archive to a regular HTML result, stored
162
- # as an instance variable Blast#result
163
- def convert_blast_archive_to_html_result(blast_formatter_path)
164
- @command = "#{blast_formatter_path} -archive #{blast_archive_tempfile.path} -html"
165
-
166
- # execute command and capture both stdout, and stderr
167
- Open3.popen3(@command) do |stdin, stdout, stderr|
168
- @result = stdout.readlines # convert to string?
169
- @error = stderr.readlines
170
- end
171
- end
172
-
173
- class << self
174
- # shortcut method to run blast against a query file
175
- def blast_file(method, db, qfile, options = nil)
176
- b = Blast.new(method, db, :qfile => qfile, :options => options)
177
- b.run!
178
- b
179
- end
180
-
181
- # shortcut method to run blast against a query string
182
- def blast_string(method, db, qstring, options = nil)
183
- b = Blast.new(method, db, :qstring => qstring, :options => options)
184
- b.run!
185
- b
186
- end
187
-
188
- # shortcut method to run blast with a query string and return a
189
- # blast archive, which can then be further processed into other useful
190
- # output forms (e.g. HTML, GFF). If it ran successfully, the blast archive
191
- # is a Tempfile accessible as an instance variable of the returned
192
- # Blast object.
193
- def blast_string_to_blast_archive(method, db, qstring, options = nil)
194
- b = Blast.new(method, db, :qstring => qstring, :options => options)
195
- b.run_to_blast_archive!
196
- b
197
- end
198
- end
199
- end
200
- end
@@ -1,190 +0,0 @@
1
- # copyright yannick . wurm at unil . ch
2
- # Finds files, reads first char. if its '>', read 500 lines. Guess sequence type, ask user for title to format as blast database.
3
-
4
- # TODO: bring it under SequenceServer namespace
5
- # TODO: move the file to a 'command/' sub-directory (probably makes more sense if we have several subcommands)
6
- # TODO: needs more love (read refactoring) overall
7
-
8
- require 'ptools' # for File.binary?(file)
9
- require 'find'
10
- require 'logger'
11
- require 'optparse'
12
- require 'sequenceserver'
13
- require 'sequenceserver/helpers.rb'
14
- require 'sequenceserver/sequencehelpers.rb'
15
-
16
- LOG = Logger.new(STDOUT)
17
- LOG.level = Logger::INFO
18
-
19
- class DatabaseFormatter
20
- include SequenceServer
21
- include Helpers
22
- include SystemHelpers
23
- include SequenceHelpers
24
-
25
- attr_accessor :db_path
26
-
27
- def initialize(db_path = nil)
28
- @app = SequenceServer::App
29
- @app.config = @app.parse_config
30
- @app.binaries = @app.scan_blast_executables(@app.bin).freeze
31
-
32
- @db_path = (db_path or @app.database)
33
- end
34
-
35
- def format_databases
36
- unless File.directory?(db_path)
37
- LOG.fatal("Database directory #{db_path} not found. See './database_formatter --help' for instructions.")
38
- exit
39
- end
40
-
41
- formatted_dbs = %x|#{@app.binaries['blastdbcmd']} -recursive -list #{db_path} -list_outfmt "%f" 2>&1|.split("\n")
42
- commands = []
43
- Find.find(db_path) do |file|
44
- LOG.debug("Assessing file #{file}..")
45
- if File.directory?(file)
46
- LOG.debug("Ignoring file #{file} since it is a directory")
47
- next
48
- end
49
- if formatted_dbs.include?(file)
50
- LOG.debug("Ignoring file #{file} since it is already a blast database")
51
- next
52
- end
53
- if File.binary?(file)
54
- LOG.debug("Ignoring file #{file} since it is a binary file, not plaintext as FASTA files are")
55
- next
56
- end
57
-
58
- if probably_fasta?(file)
59
- LOG.info("Found #{file}")
60
- ## guess whether protein or nucleotide based on first 500 lines
61
- first_lines = ''
62
- File.open(file, 'r') do |file_stream|
63
- file_stream.each do |line|
64
- first_lines += line
65
- break if file_stream.lineno == 500
66
- end
67
- end
68
- begin
69
- sequence_type = type_of_sequences(first_lines) # returns :protein or :nucleotide
70
- rescue
71
- LOG.warn("Unable to guess sequence type for #{file}. Skipping")
72
- end
73
- if [ :protein, :nucleotide ].include?(sequence_type)
74
- command = ask_make_db_command(file, sequence_type)
75
- unless command.nil?
76
- commands.push(command)
77
- end
78
- else
79
- LOG.warn("Unable to guess sequence type for #{file}. Skipping")
80
- end
81
- else
82
- LOG.debug("Ignoring file #{file} since it was not judged to be a FASTA file.")
83
- end
84
- end
85
- LOG.info("Will now create DBs")
86
- if commands.empty?
87
- puts "", "#{db_path} does not contain any unformatted database."
88
- exit
89
- end
90
- commands.each do |command|
91
- LOG.info("Will run: " + command.to_s)
92
- system(command)
93
- end
94
- LOG.info("Done formatting databases. ")
95
- db_table(db_path)
96
- end
97
-
98
- def db_table(db_path)
99
- LOG.info("Summary of formatted blast databases:\n")
100
- output = %x|#{@app.binaries['blastdbcmd']} -recursive -list #{db_path} -list_outfmt "%p %f %t" &2>1 |
101
- LOG.info(output)
102
- end
103
-
104
- def probably_fasta?(file)
105
- return FALSE if File.zero?(file)
106
- File.open(file, 'r') do |file_stream|
107
- first_line = file_stream.readline
108
- if first_line.slice(0,1) == '>'
109
- return TRUE
110
- else
111
- return FALSE
112
- end
113
- end
114
- end
115
-
116
-
117
- # returns command than needs to be run to make db
118
- def ask_make_db_command(file, type)
119
- LOG.info("FASTA file: #{file}")
120
- LOG.info("Fasta type: " + type.to_s)
121
-
122
- response = ''
123
- until response.match(/^[yn]$/i) do
124
- LOG.info("Proceed? [y/n]: ")
125
- response = STDIN.gets.chomp
126
- end
127
-
128
- if response.match(/y/i)
129
- LOG.info("Enter a database title (or will use '#{File.basename(file)})'")
130
- title = STDIN.gets.chomp
131
- title.gsub!('"', "'")
132
- title = File.basename(file) if title.empty?
133
-
134
- return make_db_command(file,type,title)
135
- end
136
- end
137
-
138
- def make_db_command(file,type, title)
139
- LOG.info("Will make #{type.to_s} database from #{file} with #{title}")
140
- command = %|#{@app.binaries['makeblastdb']} -in #{file} -dbtype #{ type.to_s.slice(0,4)} -title "#{title}" -parse_seqids|
141
- LOG.info("Returning: #{command}")
142
- return(command)
143
- end
144
- end
145
-
146
- OptionParser.new do |opts|
147
- opts.banner =<<BANNER
148
-
149
- SUMMARY
150
-
151
- prepare BLAST databases for SequenceServer
152
-
153
- USAGE
154
-
155
- sequenceserver format-databases [--verbose] [blast_database_directory]
156
-
157
- Example:
158
-
159
- $ sequenceserver format-databases ~/db # explicitly specify a database directory
160
- $ sequenceserver format-databases # use the database directory in config.yml
161
-
162
- DESCRIPTION
163
-
164
- Recursively scan the given 'blast_database_directory' for BLAST databases and
165
- formats them for use with SequenceServer.
166
-
167
- It automagically detects the database type, and ignores non-db files and
168
- pre-formatted databases. The 'parse_seqids' makeblastdb options is used.
169
-
170
- 'blast_database_directory' can be passed as a command line parameter or
171
- through a configuration file by setting the 'database' key (the same option
172
- used by SequenceServer). Configuration file will be checked only if the
173
- command line parameter is missing.
174
-
175
- OPTIONS
176
-
177
- BANNER
178
-
179
- opts.on_tail('-h', '--help', 'Show this message') do
180
- puts opts
181
- exit
182
- end
183
-
184
- opts.on('-v', '--verbose', 'Print lots of output') do
185
- LOG.level = Logger::DEBUG
186
- end
187
- end.parse!
188
-
189
- app = DatabaseFormatter.new(ARGV[0])
190
- app.format_databases