-
Notifications
You must be signed in to change notification settings - Fork 13
/
tripal_blast.module
executable file
·270 lines (233 loc) · 8.6 KB
/
tripal_blast.module
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
<?php
/**
* @file
* .module file of Tripal BLAST.
*/
use Drupal\Core\Url;
use \Drupal\Core\Link;
use Drupal\Core\Render\Markup;
/**
* Implements hook_theme().
* Used by Tripal BLAST UI page.
*
* @see templates in /templates
*/
function tripal_blast_theme($existing, $type, $theme, $path) {
// Links rendered as a markup for the template file.
// Query type + programs route.
$blast_programs = [
'blastn' => ['nucleotide', 'nucleotide'],
'blastx' => ['nucleotide', 'protein'],
'tblastn' => ['protein', 'nucleotide'],
'blastp' => ['protein', 'protein']
];
$route_ui = 'tripal_blast.blast_program';
$links_ui = [];
foreach($blast_programs as $name => $param) {
list($query, $db) = $param;
$links_ui[ 'link_' . $name ] = Link::createFromRoute(
t($name),
$route_ui,
['query' => $query, 'db' => $db]
);
}
$context_links = [
// MISC/ADMIN.
'link_config' => '#',
'link_jobs' => '#',
'link_nodeadd' => '#',
'link_dbadd' => '#',
'link_dbfields' => '#',
];
// Recent jobs table: Note this is not BLAST program specific.
$recent_jobs = \Drupal::service('tripal_blast.job_service')
->jobsCreateTable();
// Pass rendered links as variables and make available in the template file.
$variables = [
// Tripal BLAST UI page.
'theme-tripal-blast-ui' => [
'variables' => [
'context_links' => $links_ui,
'recent_jobs' => $recent_jobs
],
'template' => 'template-tripal-blast-ui',
],
// Tripal BLAST Configuration page.
// Tripal BLAST Help page.
'theme-tripal-blast-help' => [
'variables' => ['context_links' => $context_links],
'template' => 'template-tripal-blast-help',
],
// Tripal BLAST messages.
'theme-tripal-blast-message' => [
'variables' => ['data' => []],
'template' => 'template-tripal-blast-message'
],
// Tripal BLAST Report Pending.
'theme-tripal-blast-report-pending' => [
'variables' => ['data' => []],
'template' => 'template-tripal-blast-report-pending'
],
// Tripal BLAST Show Report.
'theme-tripal-blast-show-report' => [
'variables' => ['report' => []],
'template' => 'template-tripal-blast-show-report'
]
];
return $variables;
}
/**
* Run BLAST (should be called from the command-line)
*
* @param $program
* Which BLAST program to run (ie: 'blastn', 'tblastn', tblastx', 'blastp','blastx')
* @param $query
* The full path and filename of the query FASTA file
* @param $database
* The full path and filename prefix (excluding .nhr, .nin, .nsq, etc.)
* @param $output_filestub
* The filename (not including path) to give the results. Should not include file type suffix
* @param $options
* An array of additional option where the key is the name of the option used by
* BLAST (ie: 'num_alignments') and the value is relates to this particular
* BLAST job (ie: 250)
*/
function run_BLAST_tripal_job($program, $query, $database, $output_filestub, $options, $job_id = NULL) {
$output_file = $output_filestub . '.asn';
$output_file_xml = $output_filestub . '.xml';
$output_file_tsv = $output_filestub . '.tsv';
$output_file_html = $output_filestub . '.html';
$output_file_gff = $output_filestub . '.gff';
print "\nExecuting $program\n\n";
print "Query: $query\n";
print "Database: $database\n";
print "Results File: $output_file\n";
print "Options:\n";
// Allow administrators to use an absolute path for these commands.
// Defaults to using $PATH.
$blast_path = \Drupal::config('tripal_blast.settings')
->get('tripal_blast_config_general.path');
$blast_threads = \Drupal::config('tripal_blast.settings')
->get('tripal_blast_config_general.threads');
// Strip the extension off the BLAST target
$suffix = ['.ndb', '.nhr', '.nin', '.not', '.nsq', '.ntf', '.nto',
'.pdb', '.phr', '.pin', '.pot', '.psq', '.ptf', '.pto'];
$database = str_replace($suffix, '', $database);
// Check that the database exists before trying to execute the job.
if (!(file_exists($database . '.nsq') OR file_exists($database . '.psq'))) {
tripal_report_error(
'blast_ui',
TRIPAL_ERROR,
"Unable to find the BLAST database (ie: @db). Please ensure you have supplied the absolute path not including the file format endings.",
['@db' => $database],
['print' => TRUE]
);
return FALSE;
}
// The BLAST executeable.
$program = $blast_path . $program;
if (!file_exists($program)) {
tripal_report_error(
'blast_ui',
TRIPAL_ERROR,
"Unable to find the BLAST executable (ie: /usr/bin/blastn). This can be changed in the admin settings; you supplied: @command",
['@command' => $program],
['print' => TRUE]
);
return FALSE;
}
// The blast db formatter executable.
$blast_formatter_command = $blast_path . 'blast_formatter';
if (!file_exists($blast_formatter_command)) {
tripal_report_error(
'blast_ui',
TRIPAL_ERROR,
"Unable to find the BLAST Formatter executable (ie: /usr/bin/blast_formatter). This can be changed in the admin settings; you supplied: @command",
['@command' => $blast_formatter_command],
['print' => TRUE]
);
return FALSE;
}
// Note: all variables are escaped (adds single quotes around their values) for security reasons.
$blast_cmd = escapeshellarg($program) . ' -query ' . escapeshellarg($query) . ' -db ' . escapeshellarg($database) . ' -out ' . escapeshellarg($output_file) . ' -outfmt=11';
if (!empty($options)) {
foreach ($options as $opt => $val) {
$val = trim($val);
if (!empty($val)) {
print "\t$opt: $val\n";
// We want to escape all the option values since they were supplied via
// user input. These values should also have been checked in the
// advanced form _validate functions but this adds an extra layer of
// protection.
$blast_cmd .= ' -' . escapeshellarg($opt) . ' ' . escapeshellarg($val);
}
}
}
// Setting the value of threads by admin page
$blast_cmd .= ' -num_threads ' . escapeshellarg($blast_threads);
print "\nExecuting the following BLAST command:\n" . $blast_cmd . "\n";
system($blast_cmd);
if (!file_exists($output_file)) {
tripal_report_error(
'blast_ui',
TRIPAL_ERROR,
"BLAST did not complete successfully as is implied by the lack of output file (%file). The command run was @command",
['%file' => $output_file, '@command' => $blast_cmd],
['print' => TRUE]
);
return FALSE;
}
print "\nGenerating additional download formats...\n";
print "\tXML\n";
$format_cmd = escapeshellarg($blast_formatter_command) . ' -archive ' . escapeshellarg($output_file) . ' -outfmt 5 -out ' . escapeshellarg($output_file_xml);
print "\t\tExecuting $format_cmd\n\n";
system($format_cmd);
if (!file_exists($output_file_xml)) {
tripal_report_error(
'blast_ui',
TRIPAL_ERROR,
"Unable to convert BLAST ASN.1 archive to XML (%archive => %file).",
['%archive' => $output_file, '%file' => $output_file_xml],
['print' => TRUE]
);
}
print "\tTab-delimited\n";
$format_cmd = escapeshellarg($blast_formatter_command) . ' -archive ' . escapeshellarg($output_file) . ' -outfmt 7 -out ' . escapeshellarg($output_file_tsv);
print "\t\tExecuting $format_cmd\n\n";
system($format_cmd);
if (!file_exists($output_file_tsv)) {
tripal_report_error(
'blast_ui',
TRIPAL_WARNING,
"Unable to convert BLAST ASN.1 archive to Tabular Output (%archive => %file).",
['%archive' => $output_file, '%file' => $output_file_tsv],
['print' => TRUE]
);
}
print "\tGFF\n";
$job_service = \Drupal::service('tripal_blast.job_service');
$job_service->jobsConvertTSVtoGFF3($output_file_tsv,$output_file_gff);
if (!file_exists($output_file_gff)) {
tripal_report_error(
'blast_ui',
TRIPAL_WARNING,
"Unable to convert BLAST Tabular Output to GFF Output (%archive => %file).",
['%archive' => $output_file, '%file' => $output_file_gff],
['print' => TRUE]
);
}
print "\tHTML (includes alignments)\n";
$format_cmd = escapeshellarg($blast_formatter_command) . ' -archive ' . escapeshellarg($output_file) . ' -outfmt 0 -out ' . escapeshellarg($output_file_html) . ' -html';
print "\t\tExecuting $format_cmd\n\n";
system($format_cmd);
if (!file_exists($output_file_tsv)) {
tripal_report_error(
'blast_ui',
TRIPAL_WARNING,
"Unable to convert BLAST ASN.1 archive to HTML Output (%archive => %file).",
['%archive' => $output_file, '%file' => $output_file_html],
['print' => TRUE]
);
}
print "\nDone!\n";
}