sequenceserver 0.8.9 → 1.0.0.pre.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 (213) hide show
  1. checksums.yaml +4 -4
  2. data/{README.txt → README.md} +2 -0
  3. data/bin/sequenceserver +255 -55
  4. data/config.ru +2 -4
  5. data/lib/sequenceserver.rb +293 -447
  6. data/lib/sequenceserver/blast.rb +464 -64
  7. data/lib/sequenceserver/database.rb +185 -19
  8. data/lib/sequenceserver/links.rb +114 -0
  9. data/lib/sequenceserver/logger.rb +27 -0
  10. data/lib/sequenceserver/sequence.rb +141 -0
  11. data/public/css/bootstrap.min.css +8 -413
  12. data/public/css/custom.css +363 -122
  13. data/public/css/font-awesome.min.css +4 -0
  14. data/public/fonts/FontAwesome.otf +0 -0
  15. data/public/fonts/fontawesome-webfont.eot +0 -0
  16. data/public/fonts/fontawesome-webfont.svg +565 -0
  17. data/public/fonts/fontawesome-webfont.ttf +0 -0
  18. data/public/fonts/fontawesome-webfont.woff +0 -0
  19. data/public/fonts/fontawesome-webfont.woff2 +0 -0
  20. data/public/js/bootstrap.min.js +11 -0
  21. data/public/js/d3.v3.min.js +5 -0
  22. data/public/js/html5shiv.min.js +4 -0
  23. data/public/js/jquery.scrollspy.js +74 -0
  24. data/public/js/jquery.t.js +353 -0
  25. data/public/js/sequence.js +2419 -0
  26. data/public/js/sequenceserver.blast.js +29 -30
  27. data/public/js/sequenceserver.js +544 -120
  28. data/public/js/underscore.min.js +6 -0
  29. data/public/js/webshims/polyfiller.js +1 -0
  30. data/public/js/webshims/shims/FlashCanvas/canvas2png.js +1 -0
  31. data/public/js/webshims/shims/FlashCanvas/flashcanvas.js +1 -0
  32. data/public/js/webshims/shims/FlashCanvas/flashcanvas.swf +0 -0
  33. data/public/js/webshims/shims/FlashCanvasPro/canvas2png.js +1 -0
  34. data/public/js/webshims/shims/FlashCanvasPro/flash10canvas.swf +0 -0
  35. data/public/js/webshims/shims/FlashCanvasPro/flash9canvas.swf +0 -0
  36. data/public/js/webshims/shims/FlashCanvasPro/flashcanvas.js +1 -0
  37. data/public/js/webshims/shims/canvas-blob.js +1 -0
  38. data/public/js/webshims/shims/color-picker.js +2 -0
  39. data/public/js/webshims/shims/combos/1.js +6 -0
  40. data/public/js/webshims/shims/combos/10.js +2 -0
  41. data/public/js/webshims/shims/combos/11.js +2 -0
  42. data/public/js/webshims/shims/combos/12.js +6 -0
  43. data/public/js/webshims/shims/combos/13.js +1 -0
  44. data/public/js/webshims/shims/combos/14.js +1 -0
  45. data/public/js/webshims/shims/combos/15.js +2 -0
  46. data/public/js/webshims/shims/combos/16.js +7 -0
  47. data/public/js/webshims/shims/combos/17.js +2 -0
  48. data/public/js/webshims/shims/combos/18.js +3 -0
  49. data/public/js/webshims/shims/combos/2.js +7 -0
  50. data/public/js/webshims/shims/combos/21.js +2 -0
  51. data/public/js/webshims/shims/combos/22.js +1 -0
  52. data/public/js/webshims/shims/combos/23.js +6 -0
  53. data/public/js/webshims/shims/combos/25.js +2 -0
  54. data/public/js/webshims/shims/combos/27.js +1 -0
  55. data/public/js/webshims/shims/combos/28.js +1 -0
  56. data/public/js/webshims/shims/combos/29.js +1 -0
  57. data/public/js/webshims/shims/combos/3.js +1 -0
  58. data/public/js/webshims/shims/combos/30.js +2 -0
  59. data/public/js/webshims/shims/combos/31.js +1 -0
  60. data/public/js/webshims/shims/combos/33.js +1 -0
  61. data/public/js/webshims/shims/combos/34.js +1 -0
  62. data/public/js/webshims/shims/combos/4.js +1 -0
  63. data/public/js/webshims/shims/combos/5.js +2 -0
  64. data/public/js/webshims/shims/combos/6.js +2 -0
  65. data/public/js/webshims/shims/combos/7.js +7 -0
  66. data/public/js/webshims/shims/combos/8.js +7 -0
  67. data/public/js/webshims/shims/combos/9.js +2 -0
  68. data/public/js/webshims/shims/combos/97.js +1 -0
  69. data/public/js/webshims/shims/combos/98.js +1 -0
  70. data/public/js/webshims/shims/combos/99.js +1 -0
  71. data/public/js/webshims/shims/details.js +1 -0
  72. data/public/js/webshims/shims/dom-extend.js +1 -0
  73. data/public/js/webshims/shims/es5.js +1 -0
  74. data/public/js/webshims/shims/es6.js +1 -0
  75. data/public/js/webshims/shims/excanvas.js +1 -0
  76. data/public/js/webshims/shims/filereader-xhr.js +1 -0
  77. data/public/js/webshims/shims/form-combat.js +1 -0
  78. data/public/js/webshims/shims/form-core.js +1 -0
  79. data/public/js/webshims/shims/form-datalist-lazy.js +1 -0
  80. data/public/js/webshims/shims/form-datalist.js +1 -0
  81. data/public/js/webshims/shims/form-fixrangechange.js +1 -0
  82. data/public/js/webshims/shims/form-inputmode.js +1 -0
  83. data/public/js/webshims/shims/form-message.js +1 -0
  84. data/public/js/webshims/shims/form-native-extend.js +1 -0
  85. data/public/js/webshims/shims/form-number-date-api.js +1 -0
  86. data/public/js/webshims/shims/form-number-date-ui.js +1 -0
  87. data/public/js/webshims/shims/form-shim-extend.js +1 -0
  88. data/public/js/webshims/shims/form-shim-extend2.js +1 -0
  89. data/public/js/webshims/shims/form-validation.js +1 -0
  90. data/public/js/webshims/shims/form-validators.js +1 -0
  91. data/public/js/webshims/shims/forms-picker.js +1 -0
  92. data/public/js/webshims/shims/geolocation.js +1 -0
  93. data/public/js/webshims/shims/i18n/formcfg-ar.js +1 -0
  94. data/public/js/webshims/shims/i18n/formcfg-ch-CN.js +1 -0
  95. data/public/js/webshims/shims/i18n/formcfg-cs.js +1 -0
  96. data/public/js/webshims/shims/i18n/formcfg-de.js +1 -0
  97. data/public/js/webshims/shims/i18n/formcfg-el.js +1 -0
  98. data/public/js/webshims/shims/i18n/formcfg-en.js +1 -0
  99. data/public/js/webshims/shims/i18n/formcfg-es.js +1 -0
  100. data/public/js/webshims/shims/i18n/formcfg-fa.js +1 -0
  101. data/public/js/webshims/shims/i18n/formcfg-fr.js +1 -0
  102. data/public/js/webshims/shims/i18n/formcfg-he.js +1 -0
  103. data/public/js/webshims/shims/i18n/formcfg-hi.js +1 -0
  104. data/public/js/webshims/shims/i18n/formcfg-hu.js +1 -0
  105. data/public/js/webshims/shims/i18n/formcfg-it.js +1 -0
  106. data/public/js/webshims/shims/i18n/formcfg-ja.js +1 -0
  107. data/public/js/webshims/shims/i18n/formcfg-lt.js +1 -0
  108. data/public/js/webshims/shims/i18n/formcfg-nl.js +1 -0
  109. data/public/js/webshims/shims/i18n/formcfg-pl.js +1 -0
  110. data/public/js/webshims/shims/i18n/formcfg-pt-BR.js +1 -0
  111. data/public/js/webshims/shims/i18n/formcfg-pt-PT.js +1 -0
  112. data/public/js/webshims/shims/i18n/formcfg-pt.js +1 -0
  113. data/public/js/webshims/shims/i18n/formcfg-ru.js +1 -0
  114. data/public/js/webshims/shims/i18n/formcfg-sv.js +1 -0
  115. data/public/js/webshims/shims/i18n/formcfg-zh-CN.js +1 -0
  116. data/public/js/webshims/shims/i18n/formcfg-zh-TW.js +1 -0
  117. data/public/js/webshims/shims/jme/alternate-media.js +1 -0
  118. data/public/js/webshims/shims/jme/base.js +1 -0
  119. data/public/js/webshims/shims/jme/controls.css +1 -0
  120. data/public/js/webshims/shims/jme/jme.eot +0 -0
  121. data/public/js/webshims/shims/jme/jme.svg +36 -0
  122. data/public/js/webshims/shims/jme/jme.ttf +0 -0
  123. data/public/js/webshims/shims/jme/jme.woff +0 -0
  124. data/public/js/webshims/shims/jme/mediacontrols-lazy.js +1 -0
  125. data/public/js/webshims/shims/jme/mediacontrols.js +1 -0
  126. data/public/js/webshims/shims/jme/playlist.js +1 -0
  127. data/public/js/webshims/shims/jpicker/images/AlphaBar.png +0 -0
  128. data/public/js/webshims/shims/jpicker/images/Bars.png +0 -0
  129. data/public/js/webshims/shims/jpicker/images/Maps.png +0 -0
  130. data/public/js/webshims/shims/jpicker/images/NoColor.png +0 -0
  131. data/public/js/webshims/shims/jpicker/images/bar-opacity.png +0 -0
  132. data/public/js/webshims/shims/jpicker/images/map-opacity.png +0 -0
  133. data/public/js/webshims/shims/jpicker/images/mappoint.gif +0 -0
  134. data/public/js/webshims/shims/jpicker/images/picker.gif +0 -0
  135. data/public/js/webshims/shims/jpicker/images/preview-opacity.png +0 -0
  136. data/public/js/webshims/shims/jpicker/images/rangearrows.gif +0 -0
  137. data/public/js/webshims/shims/jpicker/jpicker.css +1 -0
  138. data/public/js/webshims/shims/matchMedia.js +3 -0
  139. data/public/js/webshims/shims/mediacapture-picker.js +1 -0
  140. data/public/js/webshims/shims/mediacapture.js +1 -0
  141. data/public/js/webshims/shims/mediaelement-core.js +1 -0
  142. data/public/js/webshims/shims/mediaelement-debug.js +1 -0
  143. data/public/js/webshims/shims/mediaelement-jaris.js +1 -0
  144. data/public/js/webshims/shims/mediaelement-native-fix.js +1 -0
  145. data/public/js/webshims/shims/mediaelement-yt.js +1 -0
  146. data/public/js/webshims/shims/moxie/flash/Moxie.cdn.swf +0 -0
  147. data/public/js/webshims/shims/moxie/flash/Moxie.min.swf +0 -0
  148. data/public/js/webshims/shims/moxie/js/moxie-html4.js +3 -0
  149. data/public/js/webshims/shims/moxie/js/moxie-swf.js +2 -0
  150. data/public/js/webshims/shims/picture.js +1 -0
  151. data/public/js/webshims/shims/plugins/jquery.ui.position.js +11 -0
  152. data/public/js/webshims/shims/range-ui.js +1 -0
  153. data/public/js/webshims/shims/sizzle.js +11 -0
  154. data/public/js/webshims/shims/sticky.js +1 -0
  155. data/public/js/webshims/shims/styles/color-picker.png +0 -0
  156. data/public/js/webshims/shims/styles/forms-ext.css +1 -0
  157. data/public/js/webshims/shims/styles/forms-picker.css +1 -0
  158. data/public/js/webshims/shims/styles/progress.gif +0 -0
  159. data/public/js/webshims/shims/styles/progress.png +0 -0
  160. data/public/js/webshims/shims/styles/shim-ext.css +1 -0
  161. data/public/js/webshims/shims/styles/shim.css +1 -0
  162. data/public/js/webshims/shims/styles/transparent.png +0 -0
  163. data/public/js/webshims/shims/styles/widget.eot +0 -0
  164. data/public/js/webshims/shims/styles/widget.svg +12 -0
  165. data/public/js/webshims/shims/styles/widget.ttf +0 -0
  166. data/public/js/webshims/shims/styles/widget.woff +0 -0
  167. data/public/js/webshims/shims/swf/JarisFLVPlayer.swf +0 -0
  168. data/public/js/webshims/shims/swfmini-embed.js +1 -0
  169. data/public/js/webshims/shims/swfmini.js +6 -0
  170. data/public/js/webshims/shims/track-ui.js +1 -0
  171. data/public/js/webshims/shims/track.js +1 -0
  172. data/public/js/webshims/shims/url.js +1 -0
  173. data/public/js/webshims/shims/usermedia-core.js +1 -0
  174. data/public/js/webshims/shims/usermedia-shim.js +1 -0
  175. data/sequenceserver.gemspec +16 -13
  176. data/views/400.erb +28 -0
  177. data/views/500.erb +35 -19
  178. data/views/_options.erb +6 -15
  179. data/views/result.erb +218 -0
  180. data/views/search.erb +354 -151
  181. metadata +254 -62
  182. data/example.config.yml +0 -39
  183. data/lib/sequenceserver/customisation.rb +0 -60
  184. data/lib/sequenceserver/database_formatter.rb +0 -190
  185. data/lib/sequenceserver/helpers.rb +0 -136
  186. data/lib/sequenceserver/sequencehelpers.rb +0 -93
  187. data/lib/sequenceserver/sinatralikeloggerformatter.rb +0 -12
  188. data/lib/sequenceserver/version.rb +0 -9
  189. data/public/css/beige.css.css +0 -254
  190. data/public/css/bootstrap.dropdown.css +0 -29
  191. data/public/css/bootstrap.icons.css +0 -155
  192. data/public/css/bootstrap.modal.css +0 -28
  193. data/public/js/bootstrap.dropdown.js +0 -92
  194. data/public/js/bootstrap.modal.js +0 -7
  195. data/public/js/bootstrap.transition.js +0 -7
  196. data/public/js/jquery-scrollspy.js +0 -98
  197. data/public/js/jquery.activity.js +0 -10
  198. data/public/js/jquery.enablePlaceholder.min.js +0 -10
  199. data/public/js/store.min.js +0 -2
  200. data/public/sequence.html +0 -28
  201. data/tests/database/nucleotide/Sinvicta2-2-3.cdna.subset.fasta +0 -5486
  202. data/tests/database/nucleotide/Sinvicta2-2-3.cdna.subset.fasta.nhr +0 -0
  203. data/tests/database/nucleotide/Sinvicta2-2-3.cdna.subset.fasta.nin +0 -0
  204. data/tests/database/nucleotide/Sinvicta2-2-3.cdna.subset.fasta.nsq +0 -0
  205. data/tests/database/protein/Sinvicta2-2-3.prot.subset.fasta +0 -6449
  206. data/tests/database/protein/Sinvicta2-2-3.prot.subset.fasta.phr +0 -0
  207. data/tests/database/protein/Sinvicta2-2-3.prot.subset.fasta.pin +0 -0
  208. data/tests/database/protein/Sinvicta2-2-3.prot.subset.fasta.psq +0 -0
  209. data/tests/run +0 -26
  210. data/tests/test_sequencehelpers.rb +0 -77
  211. data/tests/test_sequenceserver_blast.rb +0 -60
  212. data/tests/test_ui.rb +0 -104
  213. data/tests/ui.specs.todo +0 -10
@@ -1,60 +0,0 @@
1
- module SequenceServer
2
- module Customisation
3
- ## When not commented out, this method is used to take a
4
- ## sequence ID, and return a hyperlink that
5
- ## replaces the hit in the BLAST output.
6
- ##
7
- ## Return the hyperlink to link to, or nil
8
- ## to not not include a hyperlink.
9
- ##
10
- ## When this method
11
- ## is commented out, the default link is used. The default
12
- ## is a link to the full sequence of
13
- ## the hit is displayed (if makeblastdb has been run with
14
- ## -parse_seqids), or no link at all otherwise.
15
- # def construct_custom_sequence_hyperlink(options)
16
- # ## Example:
17
- # ## sequence_id comes in like "psu|MAL13P1.200 | organism=Plasmodium_falciparum_3D7 | product=mitochondrial"
18
- # ## output: "http://apiloc.bio21.unimelb.edu.au/apiloc/gene/MAL13P1.200"
19
- # matches = options[:sequence_id].match(/^\s*psu\|(\S+) /)
20
- # if matches #if the sequence_id conforms to our expectations
21
- # # All is good. Return the hyperlink.
22
- # return "http://apiloc.bio21.unimelb.edu.au/apiloc/gene/#{matches[1]}"
23
- # else
24
- # # Parsing the sequence_id didn't work. Don't include a hyperlink for this
25
- # # sequence_id, but log that there has been a problem.
26
- # settings.log.warn "Unable to parse sequence id `#{options[:sequence_id]}'"
27
- # # Return nil so no hyperlink is generated.
28
- # return nil
29
- # end
30
- # end
31
-
32
- ## Much like construct_custom_sequence_hyperlink, except
33
- ## instead of just a hyperlink being defined, the whole
34
- ## line as it appears in the blast results is generated.
35
- ##
36
- ## This is a therefore more flexible setup than is possible
37
- ## with construct_custom_sequence_hyperlink, because doing
38
- ## things such as adding two hyperlinks for the one hit
39
- ## are possible.
40
- ##
41
- ## When this method is commented out, the behaviour is that
42
- ## the construct_custom_sequence_hyperlink method is used,
43
- ## or failing that the default method of that is used.
44
- # def construct_custom_sequence_hyperlinking_line(options)
45
- # matches = options[:sequence_id].match(/^\s*psu\|(\S+) /)
46
- # if matches #if the sequence_id conforms to our expectations
47
- # # All is good. Return the hyperlink.
48
- # link1 = "http://apiloc.bio21.unimelb.edu.au/apiloc/gene/#{matches[1]}"
49
- # link2 = "http://google.com/?q=#{matches[1]}"
50
- # return "<a href='#{link1}'>ApiLoc page</a>, <a href='#{link2}'>Google search</a>"
51
- # else
52
- # # Parsing the sequence_id didn't work. Don't include a hyperlink for this
53
- # # sequence_id, but log that there has been a problem.
54
- # settings.log.warn "Unable to parse sequence id `#{options[:sequence_id]}'"
55
- # # Return nil so no hyperlink is generated.
56
- # return nil
57
- # end
58
- # end
59
- end
60
- 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
@@ -1,136 +0,0 @@
1
- require 'sequenceserver/database'
2
-
3
- module SequenceServer
4
- module Helpers
5
- module SystemHelpers
6
- # Scan the given directory for blast executables. Passing `nil` scans the
7
- # system `PATH`.
8
- # ---
9
- # Arguments:
10
- # * bin(String) - absolute path to the directory containing blast binaries
11
- # ---
12
- # Returns:
13
- # * a hash of blast methods, and their corresponding absolute path
14
- # ---
15
- # Raises:
16
- # * IOError - if the executables can't be found
17
- #
18
- # > scan_blast_executables('/home/yeban/bin')
19
- # => { "blastx"=>"/home/yeban/bin/blastx",
20
- # "blastn"=>"/home/yeban/bin/blastn",
21
- # ...
22
- # }
23
- def scan_blast_executables(bin)
24
- if bin and not File.directory?(bin)
25
- raise IOError, "Could not find '#{bin}' defined in config.yml."
26
- end
27
-
28
- binaries = {}
29
- %w|blastn blastp blastx tblastn tblastx blastdbcmd makeblastdb blast_formatter|.each do |method|
30
- path = File.join(bin, method) rescue method
31
- if command?(path)
32
- binaries[method] = path
33
- else
34
- blasturl = 'http://www.ncbi.nlm.nih.gov/blast/Blast.cgi?CMD=Web&PAGE_TYPE=BlastDocs&DOC_TYPE=Download'
35
- raise IOError, "Could not find blast binaries." +
36
- "\n\nYou may need to download BLAST+ from #{blasturl}." +
37
- " And/or edit #{settings.config_file} to indicate the location of BLAST+ binaries."
38
- end
39
- end
40
-
41
- #LOG.info("Config bin dir: #{bin}")
42
- binaries
43
- end
44
-
45
- # Scan the given directory (including subdirectory) for blast databases.
46
- # ---
47
- # Arguments:
48
- # * db_root(String) - absolute path to the blast databases
49
- # ---
50
- # Returns:
51
- # * a hash of sorted blast databases grouped by database type:
52
- # protein, or nucleotide
53
- # ---
54
- # Raises:
55
- # * IOError - if no database can be found
56
- #
57
- # > scan_blast_db('/home/yeban/blast_db')
58
- # => { "protein" => [], "nucleotide" => [] }
59
- def scan_blast_db(db_root, blastdbcmd = 'blastdbcmd')
60
- raise IOError, "Database directory doesn't exist: #{db_root}" unless File.directory?( db_root )
61
-
62
- find_dbs_command = %|#{blastdbcmd} -recursive -list #{db_root} -list_outfmt "%p %f %t" 2>&1|
63
-
64
- begin
65
- db_list = %x|#{find_dbs_command}|
66
- if db_list.empty?
67
- raise IOError, "No formatted blast databases found in '#{ db_root }'."
68
- end
69
- rescue => e
70
- puts '', e.to_s
71
-
72
- print "Do you want to format your blast databases now? [Y/n]: "
73
- choice = gets.chomp[0,1].downcase
74
-
75
- unless choice == 'n'
76
- database_formatter = File.join(settings.root, 'lib', 'sequenceserver', 'database_formatter.rb')
77
- require database_formatter
78
- retry
79
- else
80
- raise # let the caller decide what to do if database discovery fails
81
- end
82
- end
83
-
84
- if db_list.match(/BLAST Database error/)
85
- raise IOError, "Error parsing blast databases.\n" + "Tried: '#{find_dbs_command}'\n"+
86
- "It crashed with the following error: '#{db_list}'\n" +
87
- "Try reformatting databases using makeblastdb.\n"
88
- end
89
-
90
- db = {}
91
-
92
- db_list.each_line do |line|
93
- next if line.empty? # required for BLAST+ 2.2.22
94
- type, name, *title = line.split(' ')
95
- type = type.downcase.intern
96
- name = name.freeze
97
- title = title.join(' ').freeze
98
-
99
- # skip past all but alias file of a NCBI multi-part BLAST database
100
- if multipart_database_name?(name)
101
- log.info(%|Found a multi-part database volume at #{name} - ignoring it.|)
102
- next
103
- end
104
-
105
- #LOG.info("Found #{type} database: #{title} at #{name}")
106
- database = Database.new(name, title, type)
107
- db[database.hash] = database
108
- end
109
-
110
- db
111
- end
112
-
113
- private
114
-
115
- # check if the given command exists and is executable
116
- # returns True if all is good.
117
- def command?(command)
118
- system("which #{command} > /dev/null 2>&1")
119
- end
120
-
121
- # Returns true if the database name appears to be a multi-part database name.
122
- #
123
- # e.g.
124
- # /home/ben/pd.ben/sequenceserver/db/nr.00 => yes
125
- # /home/ben/pd.ben/sequenceserver/db/nr => no
126
- # /home/ben/pd.ben/sequenceserver/db/img3.5.finished.faa.01 => yes
127
- def multipart_database_name?(db_name)
128
- !(db_name.match(/.+\/\S+\d{2}$/).nil?)
129
- end
130
- end
131
-
132
- def self.included(klass)
133
- klass.extend SystemHelpers
134
- end
135
- end
136
- end
@@ -1,93 +0,0 @@
1
- module SequenceServer
2
- # Module to collect some sequence-related helper functions
3
- module SequenceHelpers
4
-
5
- # copied from bioruby's Bio::Sequence
6
- # returns a Hash. Eg: composition("asdfasdfffffasdf")
7
- # => {"a"=>3, "d"=>3, "f"=>7, "s"=>3}
8
- def composition(sequence_string)
9
- count = Hash.new(0)
10
- sequence_string.scan(/./) do |x|
11
- count[x] += 1
12
- end
13
- return count
14
- end
15
-
16
- # Strips all non-letter characters. guestimates sequence based on that.
17
- # If less than 10 useable characters... returns nil
18
- # If more than 90% ACGTU returns :nucleotide. else returns :protein
19
- def guess_sequence_type(sequence_string)
20
- cleaned_sequence = sequence_string.gsub(/[^A-Z]/i, '') # removing non-letter characters
21
- cleaned_sequence.gsub!(/[NX]/i, '') # removing ambiguous characters
22
-
23
- return nil if cleaned_sequence.length < 10 # conservative
24
-
25
- composition = composition(cleaned_sequence)
26
- composition_NAs = composition.select { |character, count|character.match(/[ACGTU]/i) } # only putative NAs
27
- putative_NA_counts = composition_NAs.collect { |key_value_array| key_value_array[1] } # only count, not char
28
- putative_NA_sum = putative_NA_counts.inject { |sum, n| sum + n } # count of all putative NA
29
- putative_NA_sum = 0 if putative_NA_sum.nil?
30
-
31
- if putative_NA_sum > (0.9 * cleaned_sequence.length)
32
- return :nucleotide
33
- else
34
- return :protein
35
- end
36
- end
37
-
38
- # splits input at putative fasta definition lines (like ">adsfadsf"), guesses sequence type for each sequence.
39
- # if not enough sequence to determine, returns nil.
40
- # if 2 kinds of sequence mixed together, raises ArgumentError
41
- # otherwise, returns :nucleotide or :protein
42
- def type_of_sequences(fasta_format_string)
43
- # the first sequence does not need to have a fasta definition line
44
- sequences = fasta_format_string.split(/^>.*$/).delete_if { |seq| seq.empty? }
45
-
46
- # get all sequence types
47
- sequence_types = sequences.collect { |seq| guess_sequence_type(seq) }.uniq.compact
48
-
49
- return nil if sequence_types.empty?
50
-
51
- if sequence_types.length == 1
52
- return sequence_types.first # there is only one (but yes its an array)
53
- else
54
- raise ArgumentError, "Insufficient info to determine sequence type. Cleaned queries are: #{ sequences.to_s }"
55
- end
56
- end
57
-
58
- def sequence_from_blastdb(ids, db) # helpful when displaying parsed blast results
59
- # we know how to handle an Array of ids
60
- ids = ids.join(',') if ids.is_a? Array
61
-
62
- # we don't know what to do if the arguments ain't String
63
- raise TypeError unless ids.is_a? String and db.is_a? String
64
-
65
- # query now!
66
- #
67
- # If `blastdbcmd` throws error, we assume sequence not found.
68
- blastdbcmd = settings.binaries['blastdbcmd']
69
- %x|#{blastdbcmd} -db #{db} -entry '#{ids}' 2> /dev/null|
70
- end
71
-
72
- # Given a sequence_id and databases, apply the default (standard)
73
- # way to convert a sequence_id into a hyperlink, so that the
74
- # blast results include hyperlinks.
75
- def construct_standard_sequence_hyperlink(options)
76
- if options[:sequence_id].match(/^[^ ]/) #if there is a space right after the '>', makeblastdb was run without -parse_seqids
77
- # By default, add a link to a fasta file of the sequence (if makeblastdb was called with -parse_seqids)
78
-
79
- sid = options[:sequence_id].gsub(/<\/?[^>]*>/, '') # strip html
80
- cid = sid[/^(\S+)\s*.*/, 1] # get id part
81
- id = cid.include?('|') ? cid.split('|')[1] : cid.split('|')[0]
82
- @all_retrievable_ids ||= []
83
- @all_retrievable_ids.push(id)
84
-
85
- link = "/get_sequence/?id=#{id}&db=#{options[:databases].join(' ')}" # several dbs... separate by ' '
86
- return link
87
- else
88
- # do nothing - link == nil means no link will be incorporated
89
- return nil
90
- end
91
- end
92
- end
93
- end