sequenceserver 0.8.5 → 0.8.6

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of sequenceserver might be problematic. Click here for more details.

@@ -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