neurohmmerapp 0.0.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.
- checksums.yaml +7 -0
- data/.gitignore +24 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +81 -0
- data/LICENSE.txt +661 -0
- data/README.md +96 -0
- data/Rakefile +21 -0
- data/bin/neurohmmerapp +166 -0
- data/config.ru +3 -0
- data/lib/neurohmmerapp/config.rb +87 -0
- data/lib/neurohmmerapp/exceptions.rb +77 -0
- data/lib/neurohmmerapp/logger.rb +24 -0
- data/lib/neurohmmerapp/neurohmmer.rb +158 -0
- data/lib/neurohmmerapp/routes.rb +79 -0
- data/lib/neurohmmerapp/server.rb +63 -0
- data/lib/neurohmmerapp/version.rb +3 -0
- data/lib/neurohmmerapp.rb +207 -0
- data/neurohmmerapp.gemspec +50 -0
- data/public/NeuroHmmer/loading.html +12 -0
- data/public/src/css/bootstrap1.min.css +7 -0
- data/public/src/css/custom.css +189 -0
- data/public/src/css/custom.min.css +1 -0
- data/public/src/css/font-awesome.min.css +4 -0
- data/public/src/js/bionode-seq.min.js +1 -0
- data/public/src/js/bootstrap.min.js +6 -0
- data/public/src/js/jquery.cookie.min.js +1 -0
- data/public/src/js/jquery.min.js +4 -0
- data/public/src/js/jquery.validate.min.js +4 -0
- data/public/src/js/neurohmmer.js +228 -0
- data/public/src/js/neurohmmer.min.js +1 -0
- data/public/web_files/css/nh_compiled_css.min.css +14 -0
- data/public/web_files/fonts/FontAwesome.otf +0 -0
- data/public/web_files/fonts/fontawesome-webfont.eot +0 -0
- data/public/web_files/fonts/fontawesome-webfont.svg +504 -0
- data/public/web_files/fonts/fontawesome-webfont.ttf +0 -0
- data/public/web_files/fonts/fontawesome-webfont.woff +0 -0
- data/public/web_files/js/nh_compiled_js.min.js +20 -0
- data/spec/empty_config.yml +0 -0
- data/spec/route_spec.rb +72 -0
- data/views/500.slim +5 -0
- data/views/index.slim +38 -0
- data/views/layout.slim +74 -0
- data/views/results.slim +9 -0
- metadata +281 -0
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
require 'sinatra/cross_origin'
|
3
|
+
require 'neurohmmer/version'
|
4
|
+
require 'neurohmmerapp/version'
|
5
|
+
require 'slim'
|
6
|
+
|
7
|
+
module NeuroHmmerApp
|
8
|
+
# The Sinatra Routes
|
9
|
+
class Routes < Sinatra::Base
|
10
|
+
register Sinatra::CrossOrigin
|
11
|
+
|
12
|
+
configure do
|
13
|
+
# We don't need Rack::MethodOverride. Let's avoid the overhead.
|
14
|
+
disable :method_override
|
15
|
+
|
16
|
+
# Ensure exceptions never leak out of the app. Exceptions raised within
|
17
|
+
# the app must be handled by the app. We do this by attaching error
|
18
|
+
# blocks to exceptions we know how to handle and attaching to Exception
|
19
|
+
# as fallback.
|
20
|
+
disable :show_exceptions, :raise_errors
|
21
|
+
|
22
|
+
# Make it a policy to dump to 'rack.errors' any exception raised by the
|
23
|
+
# app so that error handlers don't have to do it themselves. But for it
|
24
|
+
# to always work, Exceptions defined by us should not respond to `code`
|
25
|
+
# or http_status` methods. Error blocks errors must explicitly set http
|
26
|
+
# status, if needed, by calling `status` method.
|
27
|
+
enable :dump_errors
|
28
|
+
|
29
|
+
# We don't want Sinatra do setup any loggers for us. We will use our own.
|
30
|
+
set :logging, nil
|
31
|
+
|
32
|
+
# This is the app root...
|
33
|
+
set :root, lambda { NeuroHmmerApp.root }
|
34
|
+
|
35
|
+
# This is the full path to the public folder...
|
36
|
+
set :public_folder, lambda { NeuroHmmerApp.public_dir }
|
37
|
+
end
|
38
|
+
|
39
|
+
# Set up global variables for the templates...
|
40
|
+
before '/' do
|
41
|
+
@max_characters = NeuroHmmerApp.config[:max_characters]
|
42
|
+
@current_neurohmmer_version = '0.1'
|
43
|
+
end
|
44
|
+
|
45
|
+
get '/' do
|
46
|
+
slim :index
|
47
|
+
end
|
48
|
+
|
49
|
+
post '/' do
|
50
|
+
cross_origin # Required for the API to work...
|
51
|
+
RunNeuroHmmer.init(request.url, params)
|
52
|
+
@neurohmmer_results = RunNeuroHmmer.run
|
53
|
+
slim :results, layout: false
|
54
|
+
end
|
55
|
+
|
56
|
+
# This error block will only ever be hit if the user gives us a funny
|
57
|
+
# sequence or incorrect advanced parameter. Well, we could hit this block
|
58
|
+
# if someone is playing around with our HTTP API too.
|
59
|
+
error RunNeuroHmmer::ArgumentError do
|
60
|
+
status 400
|
61
|
+
slim :"500", layout: false
|
62
|
+
end
|
63
|
+
|
64
|
+
# This will catch any unhandled error and some very special errors. Ideally
|
65
|
+
# we will never hit this block. If we do, there's a bug in NeuroHmmerApp
|
66
|
+
# or something really weird going on.
|
67
|
+
# TODO: If we hit this error block we show the stacktrace to the user
|
68
|
+
# requesting them to post the same to our Google Group.
|
69
|
+
error Exception, RunNeuroHmmer::RuntimeError do
|
70
|
+
status 500
|
71
|
+
slim :"500", layout: false
|
72
|
+
end
|
73
|
+
|
74
|
+
not_found do
|
75
|
+
status 404
|
76
|
+
slim :"500" # TODO: Create another Template
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'rack/handler/webrick'
|
2
|
+
|
3
|
+
module NeuroHmmerApp
|
4
|
+
# Simple wrapper around WEBrick and Rack::Handler::WEBrick to host
|
5
|
+
# NeuroHmmerApp standalone.
|
6
|
+
class Server
|
7
|
+
class << self
|
8
|
+
def run(*args)
|
9
|
+
new(*args).start
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(app)
|
14
|
+
@app = app
|
15
|
+
end
|
16
|
+
|
17
|
+
attr_reader :app
|
18
|
+
|
19
|
+
# Start server. Raises Errno::EADDRINUSE if port is in use by another
|
20
|
+
# process. Raises Errno::EACCES if binding to the port requires root
|
21
|
+
# privilege.
|
22
|
+
def start
|
23
|
+
setup_signal_handlers
|
24
|
+
@server = WEBrick::HTTPServer.new(options)
|
25
|
+
@server.mount '/', Rack::Handler::WEBrick, app
|
26
|
+
@server.start
|
27
|
+
end
|
28
|
+
|
29
|
+
# Stop server.
|
30
|
+
def stop
|
31
|
+
@server.shutdown
|
32
|
+
end
|
33
|
+
|
34
|
+
# Options Hash passed to WEBrick::HTTPServer.
|
35
|
+
# rubocop:disable Metrics/AbcSize
|
36
|
+
def options
|
37
|
+
@options ||= {
|
38
|
+
:BindAddress => app.config[:host],
|
39
|
+
:Port => app.config[:port],
|
40
|
+
:StartCallback => proc { app.on_start },
|
41
|
+
:StopCallback => proc { app.on_stop },
|
42
|
+
:OutputBufferSize => 5,
|
43
|
+
:AccessLog => [[logdev, WEBrick::AccessLog::COMMON_LOG_FORMAT]],
|
44
|
+
:Logger => WEBrick::Log.new(logdev)
|
45
|
+
}
|
46
|
+
end
|
47
|
+
# rubocop:enable Metrics/AbcSize
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def setup_signal_handlers
|
52
|
+
[:INT, :TERM].each do |sig|
|
53
|
+
trap sig do
|
54
|
+
stop
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def logdev
|
60
|
+
@logdev ||= app.verbose? ? STDERR : '/dev/null'
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,207 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
require 'neurohmmerapp/config'
|
5
|
+
require 'neurohmmerapp/exceptions'
|
6
|
+
require 'neurohmmerapp/neurohmmer'
|
7
|
+
require 'neurohmmerapp/logger'
|
8
|
+
require 'neurohmmerapp/routes'
|
9
|
+
require 'neurohmmerapp/server'
|
10
|
+
require 'neurohmmerapp/version'
|
11
|
+
|
12
|
+
module NeuroHmmerApp
|
13
|
+
# Use a fixed minimum version of BLAST+
|
14
|
+
MINIMUM_HMMER_VERSION = '3.0.0'
|
15
|
+
|
16
|
+
class << self
|
17
|
+
def environment
|
18
|
+
ENV['RACK_ENV']
|
19
|
+
end
|
20
|
+
|
21
|
+
def verbose?
|
22
|
+
@verbose ||= (environment == 'development')
|
23
|
+
end
|
24
|
+
|
25
|
+
def root
|
26
|
+
File.dirname(File.dirname(__FILE__))
|
27
|
+
end
|
28
|
+
|
29
|
+
def logger
|
30
|
+
@logger ||= Logger.new(STDERR, verbose?)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Setting up the environment before running the app...
|
34
|
+
def init(config = {})
|
35
|
+
@config = Config.new(config)
|
36
|
+
|
37
|
+
init_binaries
|
38
|
+
init_dirs
|
39
|
+
|
40
|
+
load_extension
|
41
|
+
check_num_threads
|
42
|
+
check_max_characters
|
43
|
+
self
|
44
|
+
end
|
45
|
+
|
46
|
+
attr_reader :config, :temp_dir, :public_dir
|
47
|
+
|
48
|
+
# Starting the app manually
|
49
|
+
def run
|
50
|
+
check_host
|
51
|
+
Server.run(self)
|
52
|
+
rescue Errno::EADDRINUSE
|
53
|
+
puts "** Could not bind to port #{config[:port]}."
|
54
|
+
puts " Is NeuroHmmer already accessible at #{server_url}?"
|
55
|
+
puts ' No? Try running NeuroHmmer on another port, like so:'
|
56
|
+
puts
|
57
|
+
puts ' neurohmmerapp -p 4570.'
|
58
|
+
rescue Errno::EACCES
|
59
|
+
puts "** Need root privilege to bind to port #{config[:port]}."
|
60
|
+
puts ' It is not advisable to run NeuroHmmer as root.'
|
61
|
+
puts ' Please use Apache/Nginx to bind to a privileged port.'
|
62
|
+
end
|
63
|
+
|
64
|
+
def on_start
|
65
|
+
puts '** NeuroHmmer is ready.'
|
66
|
+
puts " Go to #{server_url} in your browser and start analysing genes!"
|
67
|
+
puts ' Press CTRL+C to quit.'
|
68
|
+
open_in_browser(server_url)
|
69
|
+
end
|
70
|
+
|
71
|
+
def on_stop
|
72
|
+
puts
|
73
|
+
puts '** Thank you for using NeuroHmmerApp :).'
|
74
|
+
puts ' Please cite: '
|
75
|
+
puts ' Moghul M.I., Elphick M & Wurm Y (in prep).'
|
76
|
+
puts ' NeuroHmmer: identify Neuropeptide Precursors.'
|
77
|
+
end
|
78
|
+
|
79
|
+
# Rack-interface.
|
80
|
+
#
|
81
|
+
# Inject our logger in the env and dispatch request to our controller.
|
82
|
+
def call(env)
|
83
|
+
env['rack.logger'] = logger
|
84
|
+
Routes.call(env)
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
def init_dirs
|
90
|
+
config[:public_dir] = File.expand_path(config[:public_dir])
|
91
|
+
unique_start_id = 'NH_' + "#{Time.now.strftime('%Y%m%d-%H-%M-%S')}"
|
92
|
+
@public_dir = File.join(config[:public_dir], unique_start_id)
|
93
|
+
init_public_dir
|
94
|
+
end
|
95
|
+
|
96
|
+
# Create the Public Dir and copy files from gem root - this public dir
|
97
|
+
# is served by the app is accessible at URL/...
|
98
|
+
def init_public_dir
|
99
|
+
FileUtils.mkdir_p(File.join(@public_dir, 'NeuroHmmer'))
|
100
|
+
root_web_files = File.join(NeuroHmmerApp.root, 'public/web_files')
|
101
|
+
root_gv = File.join(NeuroHmmerApp.root, 'public/NeuroHmmer')
|
102
|
+
FileUtils.cp_r(root_web_files, @public_dir)
|
103
|
+
FileUtils.cp_r(root_gv, @public_dir)
|
104
|
+
end
|
105
|
+
|
106
|
+
def init_binaries
|
107
|
+
config[:bin] = init_bins if config[:bin]
|
108
|
+
assert_blast_installed_and_compatible
|
109
|
+
assert_mafft_installed
|
110
|
+
end
|
111
|
+
|
112
|
+
def load_extension
|
113
|
+
return unless config[:require]
|
114
|
+
config[:require] = File.expand_path config[:require]
|
115
|
+
unless File.exist?(config[:require]) && File.file?(config[:require])
|
116
|
+
fail EXTENSION_FILE_NOT_FOUND, config[:require]
|
117
|
+
end
|
118
|
+
|
119
|
+
logger.debug("Loading extension: #{config[:require]}")
|
120
|
+
require config[:require]
|
121
|
+
end
|
122
|
+
|
123
|
+
def check_num_threads
|
124
|
+
num_threads = Integer(config[:num_threads])
|
125
|
+
fail NUM_THREADS_INCORRECT unless num_threads > 0
|
126
|
+
|
127
|
+
logger.debug "Will use #{num_threads} threads to run BLAST."
|
128
|
+
if num_threads > 256
|
129
|
+
logger.warn "Number of threads set at #{num_threads} is unusually high."
|
130
|
+
end
|
131
|
+
rescue
|
132
|
+
raise NUM_THREADS_INCORRECT
|
133
|
+
end
|
134
|
+
|
135
|
+
def check_max_characters
|
136
|
+
if config[:max_characters] != 'undefined'
|
137
|
+
config[:max_characters] = Integer(config[:max_characters])
|
138
|
+
end
|
139
|
+
rescue
|
140
|
+
raise MAX_CHARACTERS_INCORRECT
|
141
|
+
end
|
142
|
+
|
143
|
+
def init_bins
|
144
|
+
bins = []
|
145
|
+
config[:bin].each do |bin|
|
146
|
+
bins << File.expand_path(bin)
|
147
|
+
unless File.exist?(bin) && File.directory?(bin)
|
148
|
+
fail BIN_DIR_NOT_FOUND, config[:bin]
|
149
|
+
end
|
150
|
+
export_bin_dir(bin)
|
151
|
+
end
|
152
|
+
bins
|
153
|
+
end
|
154
|
+
|
155
|
+
## Checks if dir is in $PATH and if not, it adds the dir to the $PATH.
|
156
|
+
def export_bin_dir(bin_dir)
|
157
|
+
return unless bin_dir
|
158
|
+
return if ENV['PATH'].split(':').include?(bin_dir)
|
159
|
+
ENV['PATH'] = "#{bin_dir}:#{ENV['PATH']}"
|
160
|
+
end
|
161
|
+
|
162
|
+
def assert_blast_installed_and_compatible
|
163
|
+
fail HMMER_NOT_INSTALLED unless command? 'hmmscan'
|
164
|
+
# version = `hmmscan -version`.split[1]
|
165
|
+
# fail HMMER_NOT_COMPATIBLE, version unless version >= MINIMUM_HMMER_VERSION
|
166
|
+
end
|
167
|
+
|
168
|
+
def assert_mafft_installed
|
169
|
+
fail MAFFT_NOT_INSTALLED unless command? 'mafft'
|
170
|
+
end
|
171
|
+
|
172
|
+
# Check and warn user if host is 0.0.0.0 (default).
|
173
|
+
def check_host
|
174
|
+
return unless config[:host] == '0.0.0.0'
|
175
|
+
logger.warn 'Will listen on all interfaces (0.0.0.0).' \
|
176
|
+
' Consider using 127.0.0.1 (--host option).'
|
177
|
+
end
|
178
|
+
|
179
|
+
def server_url
|
180
|
+
host = config[:host]
|
181
|
+
host = 'localhost' if host == '127.0.0.1' || host == '0.0.0.0'
|
182
|
+
"http://#{host}:#{config[:port]}"
|
183
|
+
end
|
184
|
+
|
185
|
+
def open_in_browser(server_url)
|
186
|
+
return if using_ssh? || verbose?
|
187
|
+
if RUBY_PLATFORM =~ /linux/ && xdg?
|
188
|
+
system "xdg-open #{server_url}system"
|
189
|
+
elsif RUBY_PLATFORM =~ /darwin/
|
190
|
+
system "open #{server_url}system"
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
def using_ssh?
|
195
|
+
true if ENV['SSH_CLIENT'] || ENV['SSH_TTY'] || ENV['SSH_CONNECTION']
|
196
|
+
end
|
197
|
+
|
198
|
+
def xdg?
|
199
|
+
true if ENV['DISPLAY'] && command?('xdg-open')
|
200
|
+
end
|
201
|
+
|
202
|
+
# Return `true` if the given command exists and is executable.
|
203
|
+
def command?(command)
|
204
|
+
system("which #{command} > /dev/null 2>&1")
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'neurohmmerapp/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'neurohmmerapp'
|
8
|
+
spec.version = NeuroHmmerApp::VERSION
|
9
|
+
spec.authors = ['Ismail Moghul', 'Yannick Wurm']
|
10
|
+
spec.email = 'y.wurm@qmul.ac.uk'
|
11
|
+
spec.summary = 'A Web App wrapper for NeuroHmmer.'
|
12
|
+
spec.description = 'A Web App wrapper for NeuroHmmer, a program for' \
|
13
|
+
' validating gene predictions.'
|
14
|
+
spec.homepage = 'https://github.com/wurmlab/neurohmmerapp'
|
15
|
+
spec.license = 'AGPL'
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0")
|
18
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
19
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
20
|
+
spec.require_paths = ['lib']
|
21
|
+
|
22
|
+
spec.required_ruby_version = '>= 2.0.0'
|
23
|
+
|
24
|
+
spec.add_development_dependency 'bundler', '~> 1.6'
|
25
|
+
spec.add_development_dependency 'rake', '~>10.3'
|
26
|
+
spec.add_development_dependency('rspec', '~> 2.8', '>= 2.8.0')
|
27
|
+
spec.add_development_dependency 'rack-test', '~> 0.6'
|
28
|
+
spec.add_development_dependency('capybara', '~> 2.4', '>= 2.4.4')
|
29
|
+
spec.add_development_dependency 'w3c_validators', '~>1.1'
|
30
|
+
|
31
|
+
spec.add_dependency 'neurohmmer', '~>0.1'
|
32
|
+
spec.add_dependency 'bio', '~>1.4'
|
33
|
+
spec.add_dependency 'sinatra', '~>1.4'
|
34
|
+
spec.add_dependency 'sinatra-cross_origin', '~> 0.3'
|
35
|
+
spec.add_dependency 'slim', '~>3.0'
|
36
|
+
spec.add_dependency 'slop', '~>3.6'
|
37
|
+
spec.post_install_message = <<INFO
|
38
|
+
|
39
|
+
------------------------------------------------------------------------
|
40
|
+
Thank you for Installing the NeuroHmmer App!
|
41
|
+
|
42
|
+
To launch NeuroHmmerApp execute 'neurohmmerapp' from command line.
|
43
|
+
|
44
|
+
$ neurohmmerapp [options]
|
45
|
+
|
46
|
+
Visit https://github.com/wurmlab/neurohmmerapp for more information.
|
47
|
+
------------------------------------------------------------------------
|
48
|
+
|
49
|
+
INFO
|
50
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<!DOCTYPE html><html><head><title>NeuroHmmer: Identify Neuropeptide Precursors</title><meta content="text/html; charset=utf-8" http-equiv="Content-Type"><link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootswatch/3.3.5/flatly/bootstrap.min.css"><link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
|
2
|
+
<style type="text/css">html{position:relative;min-height:100%;}body{margin:0 0 100px;background-color:#F5F5F5}footer{bottom:0;width:100%;margin:0 auto;position:absolute;height:100px;overflow:hidden;border-top:2px solid #DBDBDB;padding-top:10px;color:#b4bcc2}
|
3
|
+
</style></head>
|
4
|
+
<body>
|
5
|
+
<div class="container text-center">
|
6
|
+
<h1 style="font-size: 78px">NeuroHmmer</h1>
|
7
|
+
<h4 style="margin-bottom:3em">Identify Neuropeptide Precursors</h4>
|
8
|
+
<i class="fa fa-spinner fa-spin" style="font-size: 10em"></i>
|
9
|
+
<h2> Calculating...</h2>
|
10
|
+
<p class="results_link"> This may take some time. Please leave this page open.</p>
|
11
|
+
</div>
|
12
|
+
<footer><div class="container center-block"><p class="text-muted text-center">Please cite: "Moghul MI, Elphick M & Wurm Y <em>(in prep)</em> NeuroHmmer: Identify Neuropeptide Precursors"<br/> Developed at <a href="https://wurmlab.github.io" target="_blank">Wurm Lab</a>, <a href="http://www.sbcs.qmul.ac.uk" target="_blank">QMUL</a> with funding by <a href="http://www.bbsrc.ac.uk/home/home.aspx" target="_blank">BBSRC</a><br/>This page was created by <a href="https://github.com/wurmlab/neurohmmer" target="_blank" >NeuroHmmer</a> v0.01</p></div></footer></body></html>
|