quorum 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +82 -74
- data/HISTORY.md +9 -0
- data/README.rdoc +101 -23
- data/app/assets/javascripts/quorum/jobs.js +45 -3
- data/app/controllers/quorum/jobs_controller.rb +47 -2
- data/app/models/quorum/job.rb +52 -9
- data/app/views/quorum/jobs/new.html.erb +7 -6
- data/app/views/quorum/jobs/show.html.erb +7 -118
- data/app/views/quorum/jobs/templates/_blast_detailed_report_template.html.erb +53 -0
- data/app/views/quorum/jobs/templates/_blast_template.html.erb +68 -0
- data/config/routes.rb +2 -0
- data/db/migrate/20120109232446_add_hit_display_id_to_blast_reports.rb +8 -0
- data/lib/generators/quorum/images_generator.rb +18 -0
- data/lib/generators/quorum/install_generator.rb +41 -13
- data/lib/generators/templates/README +1 -1
- data/lib/generators/templates/blast.rb +18 -7
- data/lib/generators/templates/blast_db.rb +106 -0
- data/lib/generators/templates/fetch +115 -0
- data/lib/generators/templates/quorum_initializer.rb +1 -1
- data/lib/generators/templates/quorum_settings.yml +4 -4
- data/lib/quorum/helpers.rb +71 -1
- data/lib/quorum/version.rb +1 -1
- data/lib/quorum.rb +15 -5
- data/lib/workers/quorum.rb +12 -2
- data/quorum.gemspec +4 -2
- data/spec/data/seqs_not_fa.txt +16 -16
- data/spec/dummy/config/initializers/quorum_initializer.rb +1 -1
- data/spec/dummy/config/initializers/resque.rb +4 -1
- data/spec/dummy/config/quorum_settings.yml +4 -4
- data/spec/dummy/db/schema.rb +8 -1
- data/spec/dummy/quorum/bin/fetch +115 -0
- data/spec/dummy/quorum/blastdb/test.nin +0 -0
- data/spec/dummy/quorum/blastdb/test.pin +0 -0
- data/spec/dummy/quorum/lib/fetch_tools/blast_db.rb +106 -0
- data/spec/dummy/quorum/lib/search_tools/blast.rb +18 -7
- data/spec/models/job_spec.rb +3 -4
- data/spec/quorum_installed_spec.rb +5 -0
- data/spec/requests/jobs_spec.rb +14 -1
- data/spec/spec_helper.rb +32 -1
- data/spec/support/streams.rb +16 -0
- data/spec/templates/blast_db_spec.rb +63 -0
- data/spec/templates/blast_spec.rb +108 -2
- metadata +64 -37
- /data/app/assets/images/quorum/{knight_rider.gif → loading.gif} +0 -0
- /data/app/views/quorum/jobs/{_blastn_form.html.erb → form/_blastn_form.html.erb} +0 -0
- /data/app/views/quorum/jobs/{_blastp_form.html.erb → form/_blastp_form.html.erb} +0 -0
- /data/app/views/quorum/jobs/{_blastx_form.html.erb → form/_blastx_form.html.erb} +0 -0
- /data/app/views/quorum/jobs/{_tblastn_form.html.erb → form/_tblastn_form.html.erb} +0 -0
data/app/models/quorum/job.rb
CHANGED
@@ -33,6 +33,34 @@ module Quorum
|
|
33
33
|
|
34
34
|
validate :filter_input_sequences, :algorithm_selected
|
35
35
|
|
36
|
+
#
|
37
|
+
# Fetch Blast hit_id, hit_display_id, queue Resque worker and
|
38
|
+
# return worker's meta_id.
|
39
|
+
#
|
40
|
+
def fetch_quorum_blast_sequence(algo, algo_id)
|
41
|
+
job = "#{algo}_job".to_sym
|
42
|
+
report = "#{algo}_job_reports".to_sym
|
43
|
+
|
44
|
+
blast_dbs = self.method(job).call.blast_dbs
|
45
|
+
|
46
|
+
job_report = self.method(report).call.where(
|
47
|
+
"quorum_#{algo}_job_reports.id = ?", algo_id
|
48
|
+
).first
|
49
|
+
|
50
|
+
hit_id = job_report.hit_id
|
51
|
+
hit_display_id = job_report.hit_display_id
|
52
|
+
|
53
|
+
cmd = create_blast_fetch_command(blast_dbs, hit_id, hit_display_id, algo)
|
54
|
+
|
55
|
+
data = Workers::System.enqueue(
|
56
|
+
cmd, Quorum.blast_remote,
|
57
|
+
Quorum.blast_ssh_host, Quorum.blast_ssh_user,
|
58
|
+
Quorum.blast_ssh_options, true
|
59
|
+
)
|
60
|
+
|
61
|
+
Workers::System.get_meta(data.meta_id)
|
62
|
+
end
|
63
|
+
|
36
64
|
private
|
37
65
|
|
38
66
|
#
|
@@ -114,22 +142,22 @@ module Quorum
|
|
114
142
|
def queue_workers
|
115
143
|
jobs = []
|
116
144
|
if self.blastn_job && self.blastn_job.queue
|
117
|
-
jobs <<
|
145
|
+
jobs << create_search_command("blastn")
|
118
146
|
end
|
119
147
|
if self.blastx_job && self.blastx_job.queue
|
120
|
-
jobs <<
|
148
|
+
jobs << create_search_command("blastx")
|
121
149
|
end
|
122
150
|
if self.tblastn_job && self.tblastn_job.queue
|
123
|
-
jobs <<
|
151
|
+
jobs << create_search_command("tblastn")
|
124
152
|
end
|
125
153
|
if self.blastp_job && self.blastp_job.queue
|
126
|
-
jobs <<
|
154
|
+
jobs << create_search_command("blastp")
|
127
155
|
end
|
128
156
|
|
129
157
|
unless jobs.blank?
|
130
158
|
jobs.each do |j|
|
131
|
-
|
132
|
-
|
159
|
+
Workers::System.enqueue(
|
160
|
+
j, Quorum.blast_remote,
|
133
161
|
Quorum.blast_ssh_host, Quorum.blast_ssh_user,
|
134
162
|
Quorum.blast_ssh_options
|
135
163
|
)
|
@@ -138,14 +166,29 @@ module Quorum
|
|
138
166
|
end
|
139
167
|
|
140
168
|
#
|
141
|
-
# Create
|
169
|
+
# Create fetch command based on config/quorum_settings.yml
|
170
|
+
#
|
171
|
+
def create_blast_fetch_command(db_names, hit_id, hit_display_id, algo)
|
172
|
+
# System command
|
173
|
+
cmd = ""
|
174
|
+
|
175
|
+
fetch = File.join(Quorum.blast_bin, "fetch")
|
176
|
+
cmd << "#{fetch} -f blastdbcmd -l #{Quorum.blast_log_dir} " <<
|
177
|
+
"-m #{Quorum.blast_tmp_dir} -d #{Quorum.blast_db} " <<
|
178
|
+
"-n '#{db_names}' -b '#{hit_id}' -s '#{hit_display_id}' " <<
|
179
|
+
"-a #{algo}"
|
180
|
+
end
|
181
|
+
|
182
|
+
#
|
183
|
+
# Create search command based on config/quorum_settings.yml
|
142
184
|
#
|
143
|
-
def
|
185
|
+
def create_search_command(algorithm)
|
144
186
|
# System command
|
145
187
|
cmd = ""
|
146
188
|
|
147
189
|
if Quorum::BLAST_ALGORITHMS.include?(algorithm)
|
148
|
-
|
190
|
+
search = File.join(Quorum.blast_bin, "search")
|
191
|
+
cmd << "#{search} -l #{Quorum.blast_log_dir} " <<
|
149
192
|
"-m #{Quorum.blast_tmp_dir} -b #{Quorum.blast_db} " <<
|
150
193
|
"-t #{Quorum.blast_threads} "
|
151
194
|
else
|
@@ -4,29 +4,30 @@
|
|
4
4
|
<%= render "shared/error_messages", :target => @job %>
|
5
5
|
<div>
|
6
6
|
<%= f.text_area :sequence,
|
7
|
-
:title => "Paste nucleic and amino acid FASTA sequence(s) here
|
7
|
+
:title => "Paste nucleic and amino acid FASTA sequence(s) here " <<
|
8
|
+
"or upload a file below.",
|
8
9
|
:class => "auto-hint" %>
|
9
10
|
</div>
|
10
11
|
<div>
|
11
12
|
<%= f.file_field :sequence_file %>
|
12
13
|
</div>
|
13
14
|
<!-- Search Algorithms -->
|
14
|
-
<!-- Comment out an
|
15
|
+
<!-- Comment out an algorithm below to remove it from the form. -->
|
15
16
|
|
16
17
|
<!-- blastn -->
|
17
|
-
<%= render :partial => "blastn_form", :locals => {
|
18
|
+
<%= render :partial => "quorum/jobs/form/blastn_form", :locals => {
|
18
19
|
:f => f, :blast_dbs => @blast_dbs } %>
|
19
20
|
|
20
21
|
<!-- blastx -->
|
21
|
-
<%= render :partial => "blastx_form", :locals => {
|
22
|
+
<%= render :partial => "quorum/jobs/form/blastx_form", :locals => {
|
22
23
|
:f => f, :blast_dbs => @blast_dbs } %>
|
23
24
|
|
24
25
|
<!-- tblastn -->
|
25
|
-
<%= render :partial => "tblastn_form", :locals => {
|
26
|
+
<%= render :partial => "quorum/jobs/form/tblastn_form", :locals => {
|
26
27
|
:f => f, :blast_dbs => @blast_dbs } %>
|
27
28
|
|
28
29
|
<!-- blastp -->
|
29
|
-
<%= render :partial => "blastp_form", :locals => {
|
30
|
+
<%= render :partial => "quorum/jobs/form/blastp_form", :locals => {
|
30
31
|
:f => f, :blast_dbs => @blast_dbs } %>
|
31
32
|
|
32
33
|
<!-- End Search Algorithms -->
|
@@ -16,28 +16,28 @@
|
|
16
16
|
<div id="tabs-1">
|
17
17
|
<h2>Blastn</h2>
|
18
18
|
<div id="blastn-results">
|
19
|
-
Searching... <%= image_tag "quorum/
|
19
|
+
Searching... <%= image_tag "quorum/loading.gif" %>
|
20
20
|
</div>
|
21
21
|
</div>
|
22
22
|
|
23
23
|
<div id="tabs-2">
|
24
24
|
<h2>Blastx</h2>
|
25
25
|
<div id="blastx-results">
|
26
|
-
Searching... <%= image_tag "quorum/
|
26
|
+
Searching... <%= image_tag "quorum/loading.gif" %>
|
27
27
|
</div>
|
28
28
|
</div>
|
29
29
|
|
30
30
|
<div id="tabs-3">
|
31
31
|
<h2>Tblastn</h2>
|
32
32
|
<div id="tblastn-results">
|
33
|
-
Searching... <%= image_tag "quorum/
|
33
|
+
Searching... <%= image_tag "quorum/loading.gif" %>
|
34
34
|
</div>
|
35
35
|
</div>
|
36
36
|
|
37
37
|
<div id="tabs-4">
|
38
38
|
<h2>Blastp</h2>
|
39
39
|
<div id="blastp-results">
|
40
|
-
Searching... <%= image_tag "quorum/
|
40
|
+
Searching... <%= image_tag "quorum/loading.gif" %>
|
41
41
|
</div>
|
42
42
|
</div>
|
43
43
|
</div>
|
@@ -54,120 +54,9 @@
|
|
54
54
|
</p>
|
55
55
|
</div>
|
56
56
|
|
57
|
-
<!--
|
58
|
-
|
59
|
-
|
60
|
-
<p><strong>Your search returned 0 hits.</strong></p>
|
61
|
-
{{ } else { }}
|
62
|
-
<table class="results">
|
63
|
-
<tr>
|
64
|
-
<th>Query Accession</th>
|
65
|
-
<th>Query Length</th>
|
66
|
-
<th>Hit Length</th>
|
67
|
-
<th>Qstrand / Hstrand</th>
|
68
|
-
<th>Hit Accession</th>
|
69
|
-
<th>Hit Description</th>
|
70
|
-
<th>Alignment Length</th>
|
71
|
-
<th>
|
72
|
-
<a class="bit-score"
|
73
|
-
onclick="openWindow(
|
74
|
-
'http://www.ncbi.nlm.nih.gov/books/NBK21106/def-item/app8/',
|
75
|
-
'Bit Score',
|
76
|
-
800,
|
77
|
-
300
|
78
|
-
)">
|
79
|
-
Bit Score
|
80
|
-
</a>
|
81
|
-
</th>
|
82
|
-
<th>
|
83
|
-
<a class="e-value"
|
84
|
-
onclick="openWindow(
|
85
|
-
'http://www.ncbi.nlm.nih.gov/books/NBK21106/def-item/app42/',
|
86
|
-
'E-value',
|
87
|
-
800,
|
88
|
-
300
|
89
|
-
)">
|
90
|
-
E-value
|
91
|
-
</a>
|
92
|
-
</th>
|
93
|
-
</tr>
|
94
|
-
{{ var i = 1; var style = "" }}
|
95
|
-
{{ _.each(data, function(v) { }}
|
96
|
-
{{ i % 2 == 0 ? style = "even" : style = "odd" }}
|
97
|
-
{{ var qstrand = v.query_frame }}
|
98
|
-
{{ var hstrand = v.hit_frame }}
|
99
|
-
<tr class="{{= style }}">
|
100
|
-
<td>{{= v.query }}</td>
|
101
|
-
<td class="right">{{= v.query_len }}</td>
|
102
|
-
<td class="right">{{= v.hit_len }}</td>
|
103
|
-
<td>{{= formatStrand(qstrand, hstrand) }}</td>
|
104
|
-
<td>{{= v.hit_id }}</td>
|
105
|
-
<td>{{= v.hit_def.trunc(20) }}</td>
|
106
|
-
<td class="right">{{= v.align_len }}</td>
|
107
|
-
<td class="right">{{= v.bit_score }}</td>
|
108
|
-
<td class="right">
|
109
|
-
<a class="detailed_report"
|
110
|
-
onclick="viewDetailedReport(
|
111
|
-
<%= @jobs.id %>,
|
112
|
-
{{= v.id }},
|
113
|
-
'{{= v.query }}',
|
114
|
-
'{{= algo }}')">
|
115
|
-
{{= v.evalue }}
|
116
|
-
</a>
|
117
|
-
</td>
|
118
|
-
</tr>
|
119
|
-
{{ i++ }}
|
120
|
-
{{ }); }}
|
121
|
-
</table>
|
122
|
-
{{ } }}
|
123
|
-
</script>
|
124
|
-
|
125
|
-
<!-- Detailed Report Template -->
|
126
|
-
<script type="text/template" id="detailed_report_template">
|
127
|
-
<h3>Query Accession {{= query }}</h3>
|
128
|
-
{{ _.each(data, function(v) { }}
|
129
|
-
{{ var id = v.id }}
|
130
|
-
{{ var qseq = v.qseq }}
|
131
|
-
{{ var midline = v.midline }}
|
132
|
-
{{ var hseq = v.hseq }}
|
133
|
-
{{ var q_from = v.query_from }}
|
134
|
-
{{ var q_to = v.query_to }}
|
135
|
-
{{ var h_from = v.hit_from }}
|
136
|
-
{{ var h_to = v.hit_to }}
|
137
|
-
{{ var qstrand = v.query_frame }}
|
138
|
-
{{ var hstrand = v.hit_frame }}
|
139
|
-
{{ var hsp_group = v.hsp_group }}
|
140
|
-
<div id="{{= id }}">
|
141
|
-
<p class="small">{{= displayHspLinks(id, hsp_group, data) }}</p>
|
142
|
-
<p class="small">Hit Accession: {{= v.hit_id }}</p>
|
143
|
-
<p class="small">Hit Description: {{= v.hit_def }}</p>
|
144
|
-
<table class="report_details">
|
145
|
-
<tr>
|
146
|
-
<td>E-value: {{= v.evalue }}</td>
|
147
|
-
<td>Bit Score: {{= v.bit_score }}</td>
|
148
|
-
<td></td>
|
149
|
-
</tr>
|
150
|
-
<tr>
|
151
|
-
<td>Alignment Length: {{= v.align_len }}</td>
|
152
|
-
<td>Qstrand / Hstrand: {{= formatStrand(qstrand, hstrand) }}</td>
|
153
|
-
<td></td>
|
154
|
-
</tr>
|
155
|
-
<tr>
|
156
|
-
<td>Query Length: {{= v.query_len }}</td>
|
157
|
-
<td>Query From: {{= v.query_from }}</td>
|
158
|
-
<td>Query To: {{= v.query_to }}</td>
|
159
|
-
</tr>
|
160
|
-
<tr>
|
161
|
-
<td>Hit Length: {{= v.hit_len }}</td>
|
162
|
-
<td>Hit From: {{= v.hit_from }}</td>
|
163
|
-
<td>Hit To: {{= v.hit_to }}</td>
|
164
|
-
</tr>
|
165
|
-
</table>
|
166
|
-
{{= formatSequenceReport(qseq, midline, hseq, q_from, q_to, h_from, h_to, algo) }}
|
167
|
-
</div>
|
168
|
-
<hr />
|
169
|
-
{{ }); }}
|
170
|
-
</script>
|
57
|
+
<!-- Templates -->
|
58
|
+
<%= render :partial => "quorum/jobs/templates/blast_template" %>
|
59
|
+
<%= render :partial => "quorum/jobs/templates/blast_detailed_report_template" %>
|
171
60
|
|
172
61
|
<script type="text/javascript">
|
173
62
|
$(function() {
|
@@ -0,0 +1,53 @@
|
|
1
|
+
<!-- Detailed Report Template -->
|
2
|
+
<script type="text/template" id="detailed_report_template">
|
3
|
+
<h3>Query Accession {{= query }}</h3>
|
4
|
+
{{ _.each(data, function(v) { }}
|
5
|
+
{{ var id = v.id }}
|
6
|
+
{{ var qseq = v.qseq }}
|
7
|
+
{{ var midline = v.midline }}
|
8
|
+
{{ var hseq = v.hseq }}
|
9
|
+
{{ var q_from = v.query_from }}
|
10
|
+
{{ var q_to = v.query_to }}
|
11
|
+
{{ var h_from = v.hit_from }}
|
12
|
+
{{ var h_to = v.hit_to }}
|
13
|
+
{{ var qstrand = v.query_frame }}
|
14
|
+
{{ var hstrand = v.hit_frame }}
|
15
|
+
{{ var hsp_group = v.hsp_group }}
|
16
|
+
<div id="{{= id }}">
|
17
|
+
<p class="small">{{= displayHspLinks(id, hsp_group, data) }}</p>
|
18
|
+
<p class="small">Hit Accession: {{= v.hit_display_id }}</p>
|
19
|
+
<p class="small">Hit Description: {{= v.hit_def }}</p>
|
20
|
+
<table class="report_details">
|
21
|
+
<tr>
|
22
|
+
<td>E-value: {{= v.evalue }}</td>
|
23
|
+
<td>Bit Score: {{= v.bit_score }}</td>
|
24
|
+
<td></td>
|
25
|
+
</tr>
|
26
|
+
<tr>
|
27
|
+
<td>Alignment Length: {{= v.align_len }}</td>
|
28
|
+
<td>Qstrand / Hstrand: {{= formatStrand(qstrand, hstrand) }}</td>
|
29
|
+
<td></td>
|
30
|
+
</tr>
|
31
|
+
<tr>
|
32
|
+
<td>Query Length: {{= v.query_len }}</td>
|
33
|
+
<td>Query From: {{= v.query_from }}</td>
|
34
|
+
<td>Query To: {{= v.query_to }}</td>
|
35
|
+
</tr>
|
36
|
+
<tr>
|
37
|
+
<td>Hit Length: {{= v.hit_len }}</td>
|
38
|
+
<td>Hit From: {{= v.hit_from }}</td>
|
39
|
+
<td>Hit To: {{= v.hit_to }}</td>
|
40
|
+
</tr>
|
41
|
+
</table>
|
42
|
+
<p class="small">
|
43
|
+
<a id="download_sequence_{{= id }}"
|
44
|
+
onclick="downloadSequence(<%= @jobs.id %>, {{= id }}, '{{= algo }}', this)">
|
45
|
+
Download Sequence
|
46
|
+
</a>
|
47
|
+
</p>
|
48
|
+
{{= formatSequenceReport(qseq, midline, hseq, q_from, q_to, h_from, h_to, algo) }}
|
49
|
+
</div>
|
50
|
+
<hr />
|
51
|
+
{{ }); }}
|
52
|
+
</script>
|
53
|
+
|
@@ -0,0 +1,68 @@
|
|
1
|
+
<!-- Blast Results Template -->
|
2
|
+
<script type="text/template" id="blast_template">
|
3
|
+
{{ if (data[0].results === false) { }}
|
4
|
+
<p><strong>Your search returned 0 hits.</strong></p>
|
5
|
+
{{ } else { }}
|
6
|
+
<table class="results">
|
7
|
+
<tr>
|
8
|
+
<th>Query Accession</th>
|
9
|
+
<th>Query Length</th>
|
10
|
+
<th>Hit Length</th>
|
11
|
+
<th>Qstrand / Hstrand</th>
|
12
|
+
<th>Hit Accession</th>
|
13
|
+
<th>Hit Description</th>
|
14
|
+
<th>Alignment Length</th>
|
15
|
+
<th>
|
16
|
+
<a class="bit-score"
|
17
|
+
onclick="openWindow(
|
18
|
+
'http://www.ncbi.nlm.nih.gov/books/NBK21106/def-item/app8/',
|
19
|
+
'Bit Score',
|
20
|
+
800,
|
21
|
+
300
|
22
|
+
)">
|
23
|
+
Bit Score
|
24
|
+
</a>
|
25
|
+
</th>
|
26
|
+
<th>
|
27
|
+
<a class="e-value"
|
28
|
+
onclick="openWindow(
|
29
|
+
'http://www.ncbi.nlm.nih.gov/books/NBK21106/def-item/app42/',
|
30
|
+
'E-value',
|
31
|
+
800,
|
32
|
+
300
|
33
|
+
)">
|
34
|
+
E-value
|
35
|
+
</a>
|
36
|
+
</th>
|
37
|
+
</tr>
|
38
|
+
{{ var i = 1; var style = "" }}
|
39
|
+
{{ _.each(data, function(v) { }}
|
40
|
+
{{ i % 2 == 0 ? style = "even" : style = "odd" }}
|
41
|
+
{{ var qstrand = v.query_frame }}
|
42
|
+
{{ var hstrand = v.hit_frame }}
|
43
|
+
<tr class="{{= style }}">
|
44
|
+
<td>{{= v.query }}</td>
|
45
|
+
<td class="right">{{= v.query_len }}</td>
|
46
|
+
<td class="right">{{= v.hit_len }}</td>
|
47
|
+
<td>{{= formatStrand(qstrand, hstrand) }}</td>
|
48
|
+
<td>{{= v.hit_display_id }}</td>
|
49
|
+
<td>{{= v.hit_def.trunc(20) }}</td>
|
50
|
+
<td class="right">{{= v.align_len }}</td>
|
51
|
+
<td class="right">{{= v.bit_score }}</td>
|
52
|
+
<td class="right">
|
53
|
+
<a class="detailed_report"
|
54
|
+
onclick="viewDetailedReport(
|
55
|
+
<%= @jobs.id %>,
|
56
|
+
{{= v.id }},
|
57
|
+
'{{= v.query }}',
|
58
|
+
'{{= algo }}')">
|
59
|
+
{{= v.evalue }}
|
60
|
+
</a>
|
61
|
+
</td>
|
62
|
+
</tr>
|
63
|
+
{{ i++ }}
|
64
|
+
{{ }); }}
|
65
|
+
</table>
|
66
|
+
{{ } }}
|
67
|
+
</script>
|
68
|
+
|
data/config/routes.rb
CHANGED
@@ -0,0 +1,8 @@
|
|
1
|
+
class AddHitDisplayIdToBlastReports < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
add_column :quorum_blastn_job_reports, :hit_display_id, :string
|
4
|
+
add_column :quorum_blastx_job_reports, :hit_display_id, :string
|
5
|
+
add_column :quorum_tblastn_job_reports, :hit_display_id, :string
|
6
|
+
add_column :quorum_blastp_job_reports, :hit_display_id, :string
|
7
|
+
end
|
8
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Quorum
|
2
|
+
module Generators
|
3
|
+
class ImagesGenerator < Rails::Generators::Base
|
4
|
+
source_root File.expand_path("../../../../app/assets/images", __FILE__)
|
5
|
+
desc "Copy quorum images to your application."
|
6
|
+
|
7
|
+
IMAGE_DIRECTORIES = [
|
8
|
+
"quorum"
|
9
|
+
]
|
10
|
+
|
11
|
+
def copy_images
|
12
|
+
IMAGE_DIRECTORIES.each do |d|
|
13
|
+
directory d.to_s, "app/assets/images/#{d.to_s}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -1,21 +1,26 @@
|
|
1
1
|
module Quorum
|
2
2
|
module Generators
|
3
3
|
class InstallGenerator < Rails::Generators::Base
|
4
|
+
|
5
|
+
include Quorum::Helpers::Colors
|
6
|
+
|
4
7
|
source_root File.expand_path("../../templates", __FILE__)
|
5
8
|
|
6
|
-
desc "Creates Quorum initializer, settings and " <<
|
7
|
-
"
|
9
|
+
desc "Creates Quorum initializer, settings and search " <<
|
10
|
+
"/ fetch tool files."
|
8
11
|
|
9
12
|
DEPENDENCIES = ["makeblastdb", "seqret"]
|
10
13
|
|
11
|
-
def
|
14
|
+
def copy_quorum
|
12
15
|
template "quorum_initializer.rb",
|
13
16
|
"config/initializers/quorum_initializer.rb"
|
14
17
|
template "quorum_settings.yml", "config/quorum_settings.yml"
|
15
18
|
template "search", "quorum/bin/search"
|
19
|
+
template "fetch", "quorum/bin/fetch"
|
16
20
|
template "trollop.rb", "quorum/lib/trollop.rb"
|
17
21
|
template "logger.rb", "quorum/lib/logger.rb"
|
18
22
|
template "blast.rb", "quorum/lib/search_tools/blast.rb"
|
23
|
+
template "blast_db.rb", "quorum/lib/fetch_tools/blast_db.rb"
|
19
24
|
end
|
20
25
|
|
21
26
|
def copy_locale
|
@@ -23,8 +28,9 @@ module Quorum
|
|
23
28
|
end
|
24
29
|
|
25
30
|
def change_file_permissions
|
26
|
-
|
27
|
-
|
31
|
+
Dir.glob(File.join("quorum", "bin", "*")).each do |f|
|
32
|
+
File.new(f, "r").chmod(0755)
|
33
|
+
end
|
28
34
|
end
|
29
35
|
|
30
36
|
def create_quorum_tmp_dir
|
@@ -35,12 +41,30 @@ module Quorum
|
|
35
41
|
Dir.mkdir("quorum/log") unless File.directory?("quorum/log")
|
36
42
|
end
|
37
43
|
|
44
|
+
def set_mount_engines
|
45
|
+
@quorum = %Q(mount Quorum::Engine => "/quorum")
|
46
|
+
@resque = %Q(mount Resque::Server.new, :at => "/quorum/resque")
|
47
|
+
end
|
48
|
+
|
49
|
+
def read_routes_file
|
50
|
+
@routes = File.open(File.join("config", "routes.rb"), "r")
|
51
|
+
@routes = @routes.read
|
52
|
+
end
|
53
|
+
|
54
|
+
def mount_engine_exists?
|
55
|
+
@routes.include?(@quorum)
|
56
|
+
end
|
57
|
+
|
38
58
|
def add_mount_engine
|
39
|
-
route
|
59
|
+
route @quorum unless mount_engine_exists?
|
60
|
+
end
|
61
|
+
|
62
|
+
def resque_mount_engine_exists?
|
63
|
+
@routes.include?(@resque)
|
40
64
|
end
|
41
65
|
|
42
66
|
def add_resque_mount_engine
|
43
|
-
route
|
67
|
+
route @resque unless resque_mount_engine_exists?
|
44
68
|
end
|
45
69
|
|
46
70
|
def check_dependencies
|
@@ -49,14 +73,18 @@ module Quorum
|
|
49
73
|
messages = []
|
50
74
|
DEPENDENCIES.each do |b|
|
51
75
|
system("which #{b} > /dev/null 2>&1")
|
52
|
-
if $?.exitstatus > 0
|
53
|
-
messages << "Please add `#{b}` to your PATH."
|
54
|
-
end
|
76
|
+
messages << b if $?.exitstatus > 0
|
55
77
|
end
|
56
78
|
unless messages.empty?
|
57
|
-
puts
|
58
|
-
|
59
|
-
|
79
|
+
puts bold(
|
80
|
+
red("*** Warning: Quorum system dependencies not found ***")
|
81
|
+
)
|
82
|
+
puts bold(
|
83
|
+
red("Please add the below to your PATH.")
|
84
|
+
)
|
85
|
+
messages.each { |m| puts bold(red(m)) }
|
86
|
+
else
|
87
|
+
puts "All good! Yay!!"
|
60
88
|
end
|
61
89
|
end
|
62
90
|
|
@@ -11,6 +11,8 @@ module Quorum
|
|
11
11
|
class Blast
|
12
12
|
|
13
13
|
class QuorumJob < ActiveRecord::Base
|
14
|
+
set_table_name "quorum_jobs"
|
15
|
+
|
14
16
|
has_one :quorum_blastn_job,
|
15
17
|
:foreign_key => "job_id"
|
16
18
|
has_many :quorum_blastn_job_reports,
|
@@ -33,38 +35,46 @@ module Quorum
|
|
33
35
|
end
|
34
36
|
|
35
37
|
class QuorumBlastnJob < ActiveRecord::Base
|
38
|
+
set_table_name "quorum_blastn_jobs"
|
36
39
|
belongs_to :quorum_job
|
37
40
|
has_many :quorum_blastn_job_reports
|
38
41
|
end
|
39
42
|
|
40
43
|
class QuorumBlastnJobReport < ActiveRecord::Base
|
44
|
+
set_table_name "quorum_blastn_job_reports"
|
41
45
|
belongs_to :quorum_blastn_job
|
42
46
|
end
|
43
47
|
|
44
48
|
class QuorumBlastxJob < ActiveRecord::Base
|
49
|
+
set_table_name "quorum_blastx_jobs"
|
45
50
|
belongs_to :quorum_job
|
46
51
|
has_many :quorum_blastx_job_reports
|
47
52
|
end
|
48
53
|
|
49
54
|
class QuorumBlastxJobReport < ActiveRecord::Base
|
55
|
+
set_table_name "quorum_blastx_job_reports"
|
50
56
|
belongs_to :quorum_blastx_job
|
51
57
|
end
|
52
58
|
|
53
59
|
class QuorumTblastnJob < ActiveRecord::Base
|
60
|
+
set_table_name "quorum_tblastn_jobs"
|
54
61
|
belongs_to :quorum_job
|
55
62
|
has_many :quorum_tblastn_job_reports
|
56
63
|
end
|
57
64
|
|
58
65
|
class QuorumTblastnJobReport < ActiveRecord::Base
|
66
|
+
set_table_name "quorum_tblastn_job_reports"
|
59
67
|
belongs_to :quorum_tblastn_job
|
60
68
|
end
|
61
69
|
|
62
70
|
class QuorumBlastpJob < ActiveRecord::Base
|
71
|
+
set_table_name "quorum_blastp_jobs"
|
63
72
|
belongs_to :quorum_job
|
64
73
|
has_many :quorum_blastp_job_reports
|
65
74
|
end
|
66
75
|
|
67
76
|
class QuorumBlastpJobReport < ActiveRecord::Base
|
77
|
+
set_table_name "quorum_blastp_job_reports"
|
68
78
|
belongs_to :quorum_blastp_job
|
69
79
|
end
|
70
80
|
|
@@ -235,26 +245,26 @@ module Quorum
|
|
235
245
|
end
|
236
246
|
|
237
247
|
#
|
238
|
-
# Format Blast report
|
248
|
+
# Format Blast report hit_display_id and hit_def.
|
239
249
|
#
|
240
250
|
# For added flexibility, Quorum doesn't parse seqids or deflines.
|
241
251
|
# Instead, format_hit splits the hit_def on whitespace and
|
242
|
-
# reports
|
252
|
+
# reports hit_display_id as the first element and hit_def as the second.
|
243
253
|
#
|
244
254
|
def format_hit(str)
|
245
|
-
|
255
|
+
hit_display_id = ""
|
246
256
|
hit_def = ""
|
247
257
|
|
248
258
|
hit = str.split(" ", 2)
|
249
259
|
if hit.length < 2
|
250
|
-
|
260
|
+
hit_display_id = hit.first
|
251
261
|
hit_def = "None"
|
252
262
|
else
|
253
|
-
|
263
|
+
hit_display_id = hit.first
|
254
264
|
hit_def = hit.last
|
255
265
|
end
|
256
266
|
|
257
|
-
return
|
267
|
+
return hit_display_id, hit_def
|
258
268
|
end
|
259
269
|
|
260
270
|
#
|
@@ -275,8 +285,9 @@ module Quorum
|
|
275
285
|
@data[:query_len] = iteration.query_len
|
276
286
|
|
277
287
|
iteration.each do |hit|
|
278
|
-
@data[:
|
288
|
+
@data[:hit_display_id], @data[:hit_def] = format_hit(hit.hit_def)
|
279
289
|
|
290
|
+
@data[:hit_id] = hit.hit_id
|
280
291
|
@data[:hit_accession] = hit.accession
|
281
292
|
@data[:hit_len] = hit.len
|
282
293
|
|