annotate COG/bac-genomics-scripts/ecoli_mlst/ecoli_mlst.pl @ 10:d103c41b6931 draft

Uploaded
author dereeper
date Thu, 30 May 2024 16:35:22 +0000
parents e42d30da7a74
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
1 #!/usr/bin/perl
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
2
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
3 #######
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
4 # POD #
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
5 #######
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
6
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
7 =pod
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
8
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
9 =head1 NAME
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
10
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
11 ecoli_mlst.pl 25-10-2011
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
12
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
13 =head1 SYNOPSIS
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
14
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
15 C<perl ecoli_mlst.pl -a fas -g fasta>
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
16
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
17 =head1 DESCRIPTION
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
18
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
19 The script searches for multilocus sequence type (MLST) alleles in
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
20 I<E. coli> genomes according to Mark Achtman's scheme with seven
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
21 house-keeping genes (I<adk>, I<fumC>, I<gyrB>, I<icd>, I<mdh>,
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
22 I<purA>, and I<recA>) [Wirth et al., 2006]. I<NUCmer> from the
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
23 L<I<MUMmer package>|http://mummer.sourceforge.net/> is used to
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
24 compare the given allele sequences to bacterial genomes via
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
25 nucleotide alignments.
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
26
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
27 Download the allele files (adk.fas ...) and the sequence type file
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
28 ('publicSTs.txt') from this website:
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
29 http://mlst.warwick.ac.uk/mlst/dbs/Ecoli
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
30
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
31 To run C<ecoli_mlst.pl> include all I<E. coli> genome files (file
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
32 extension e.g. 'fasta'), all allele sequence files (file extension
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
33 'fas') and 'publicSTs.txt' in the current working directory. The
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
34 allele profiles are parsed from the created *.coord files and written
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
35 to a result file, plus additional information from the file
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
36 'publicSTs.txt'. Also, the corresponding allele sequences (obtained
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
37 from the allele input files) are concatenated for each I<E. coli>
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
38 genome into a result multi-fasta file. Option B<-c> can be used to
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
39 initiate an alignment for this multi-fasta file with
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
40 L<I<ClustalW>|http://www.clustal.org/clustal2/> (standard alignment
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
41 parameters; has to be in the C<$PATH> or change variable
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
42 C<$clustal_call>). The alignment fasta output file can be used
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
43 directly for L<I<RAxML>|http://sco.h-its.org/exelixis/web/software/raxml/index.html>. CAREFUL the Phylip alignment format from
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
44 I<ClustalW> allows only 10 characters per strain ID.
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
45
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
46 C<ecoli_mlst.pl> works with complete and draft genomes. However,
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
47 several genomes cannot be included in a single input file!
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
48
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
49 Obviously, only for those genomes whose allele sequences have been
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
50 deposited in Achtman's allele database results can be obtained. If an
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
51 allele is not found in a genome it is marked by a '?' in the result
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
52 profile file and a place holder 'XXX' in the result fasta file. For
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
53 these cases a manual I<NUCmer> or I<BLASTN> might be useful to fill the
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
54 gaps and L<C<run_sub_seq.pl>|/run_sub_seq> to get the corresponding
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
55 'new' allele sequences.
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
56
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
57 Non-NCBI fasta headers for the genome files have to have a unique ID
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
58 directly following the '>' (e.g. 'Sakai', '55989' ...).
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
59
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
60 =head1 OPTIONS
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
61
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
62 =head2 Mandatory options
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
63
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
64 =over 22
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
65
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
66 =item B<-a>=I<str>, B<-alleles>=I<str>
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
67
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
68 File extension of the MLST allele fasta files, e.g. 'fas' (<=> B<-g>).
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
69
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
70 =item B<-g>=I<str>, B<-genomes>=I<str>
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
71
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
72 File extension of the I<E. coli> genome fasta files, e.g. 'fasta' (<=> B<-a>).
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
73
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
74 =back
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
75
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
76 =head2 Optional options
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
77
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
78 =over
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
79
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
80 =item B<-h>, B<-help>
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
81
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
82 Help (perldoc POD)
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
83
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
84 =item B<-c>, B<-clustalw>
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
85
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
86 Call L<I<ClustalW>|http://www.clustal.org/clustal2/> for alignment
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
87
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
88 =back
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
89
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
90 =head1 OUTPUT
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
91
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
92 =over 17
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
93
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
94 =item F<ecoli_mlst_profile.txt>
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
95
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
96 Tab-separated allele profiles for the I<E. coli> genomes, plus additional info from 'publicSTs.txt'
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
97
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
98 =item F<ecoli_mlst_seq.fasta>
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
99
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
100 Multi-fasta file of all concatenated allele sequences for each genome
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
101
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
102 =item F<*.coord>
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
103
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
104 Text files that contain the coordinates of the I<NUCmer> hits for each genome and allele
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
105
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
106 =item (F<errors.txt>)
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
107
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
108 Error file, summarizing number of not found alleles or unclear I<NUCmer> hits
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
109
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
110 =item (F<ecoli_mlst_seq_aln.fasta>)
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
111
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
112 Optional, L<I<ClustalW>|http://www.clustal.org/clustal2/> alignment in Phylip format
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
113
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
114 =item (F<ecoli_mlst_seq_aln.dnd>)
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
115
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
116 Optional, I<ClustalW> alignment guide tree
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
117
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
118 =back
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
119
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
120 =head1 EXAMPLE
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
121
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
122 =over
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
123
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
124 =item C<perl ecoli_mlst.pl -a fas -g fasta -c>
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
125
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
126 =back
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
127
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
128 =head1 VERSION
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
129
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
130 0.3 update: 30-01-2013
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
131
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
132 =head1 AUTHOR
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
133
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
134 Andreas Leimbach aleimba[at]gmx[dot]de
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
135
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
136 =head1 LICENSE
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
137
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
138 This program is free software: you can redistribute it and/or modify
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
139 it under the terms of the GNU General Public License as published by
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
140 the Free Software Foundation; either version 3 (GPLv3) of the License,
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
141 or (at your option) any later version.
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
142
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
143 This program is distributed in the hope that it will be useful, but
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
144 WITHOUT ANY WARRANTY; without even the implied warranty of
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
145 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
146 General Public License for more details.
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
147
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
148 You should have received a copy of the GNU General Public License
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
149 along with this program. If not, see L<http://www.gnu.org/licenses/>.
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
150
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
151 =cut
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
152
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
153
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
154 ########
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
155 # MAIN #
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
156 ########
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
157
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
158 use strict;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
159 use warnings;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
160 use Getopt::Long; # module to get options from the command line
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
161
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
162
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
163 ### Get the options with Getopt::Long, works also abbreviated and with two "--": -g, --g, -genomes ...
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
164 my $usage = "perldoc $0";
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
165 die system($usage) unless @ARGV;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
166 my $allele_ext = ''; # file extension of allele fasta files (<=> $genome_ext)
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
167 my $genome_ext = ''; # file extension of E. coli genome fasta files (<=> allele_ext)
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
168 my $clustalw = ''; # optionally, call ClustalW for alignment
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
169 my $help = ''; # run perldoc on the POD
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
170 GetOptions ('alleles=s' => \$allele_ext, 'genomes=s' => \$genome_ext, 'clustalw' => \$clustalw, 'help' => \$help);
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
171
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
172
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
173 ### Run perldoc on POD if no arguments or help
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
174 if (!$genome_ext || !$allele_ext) {
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
175 die system($usage);
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
176 } elsif ($help) {
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
177 die system($usage);
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
178 }
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
179
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
180
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
181 ### Check if result files already exist, overwrite or exit script after user question
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
182 my $ecoli_allele_seq = 'ecoli_mlst_seq.fasta'; # multi-fasta result file with concatenated allele seqs for each E. coli genome (sequences are from the MLST allele files)
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
183 my $clustal_aln = 'ecoli_mlst_seq_aln.fasta'; # fasta alignment file from optional clustalW alignment
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
184 if (-e $ecoli_allele_seq) {
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
185 print "A previous analysis exists, overwrite the old result files [y|n]? ";
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
186 my $stdin = <STDIN>;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
187 chomp $stdin;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
188 if ($stdin =~ /n/i) {
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
189 die "Script abborted!\n\n";
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
190 } elsif ($stdin =~ /y/i) {
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
191 if (-e $clustal_aln) { # get rid of the optional clustalW alignment fasta-file before program run
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
192 unlink $clustal_aln;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
193 }
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
194 }
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
195 }
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
196
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
197
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
198 ### The MLST alleles from the Achtman scheme
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
199 my @alleles = ('adk', 'fumC', 'gyrB', 'icd', 'mdh', 'purA', 'recA');
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
200
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
201
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
202 ### Read directory and look for corresponding files
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
203 my $dirname = ".";
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
204 my @genome_files; # array to save all the fasta genome files
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
205 my %allele_files; # hash to save all the multi-fasta allele files
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
206 opendir(DIR, $dirname) or die "Can't opendir $dirname: $!\n";
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
207 while (defined(my $file = readdir(DIR))) { # go through each file in the directory
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
208 if ($file eq 'ecoli_mlst_seq.fasta') { # don't use the result file from a previous analysis, the allele multi fasta file 'ecoli_mlst_multi.fasta' (see below)!
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
209 next;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
210 } elsif ($file =~ /^(\S+)\.$genome_ext$/ && (-s $file < 9000000)) { # don't use files > 10 MB, E. coli fasta file shouldn't be too big (normally around 5 MB), otherwise probably wrong fasta file in folder
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
211 push (@genome_files, $file);
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
212 }
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
213 foreach my $allele (@alleles) {
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
214 if ($file =~ /^$allele\S*\.$allele_ext$/i) {
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
215 $allele_files{$allele} = $file;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
216 }
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
217 }
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
218 }
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
219 closedir(DIR);
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
220 die "No E. coli genome fasta-files were found!\n" unless scalar @genome_files; # empty array in scalar context returns 0
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
221 die "No allele fasta-files were found!\n" unless scalar %allele_files; # empty hash in scalar context returns 0
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
222
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
223
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
224 ### Look for multi-fasta genome files and concatenate them to a single-fasta entry (e.g. draft genomes). Subsequently concatenate all E. coli genome sequence files to one multi-fasta/-genome file for the subsequent nucmer run. Additionally parse and associate the E. coli accession#s/unique IDs and descriptions (strain names ...) from the genomes
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
225 my $genome_file = 'ecoli_multi.fasta'; # multi-genome/-fasta file for the nucmer run, used as a temp file, will be deleted at the end of the script
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
226 open(GENOMES, ">$genome_file") or die "Failed to create file '$genome_file': $!\n";
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
227 my $genome_number = 0; # used to control if lines in *.coords files correspond to the overall genome count
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
228 my %genome_desc; # hash to associate accession#/unique ID with genome descriptions
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
229 foreach my $file (@genome_files) {
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
230 $genome_number++;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
231 open(MULTI, "<$file") or die "Failed to open E. coli genome file '$file': $!\n";
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
232 my @multi = <MULTI>; # read the whole genome file (potential multi-fasta file)
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
233 my @IDs = grep(/^>/, @multi); # get ID lines in fasta file
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
234 if (scalar @IDs > 1) { # multi-fasta files
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
235 my $new_id; # new ID line for the multi-fasta file
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
236 foreach (@IDs) { # discard plasmid ID lines in complete genomes for new file (name with chromosome ID line)
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
237 if (!/plasmid/) {
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
238 chomp;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
239 $new_id = $_;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
240 last; # jump out of the loop if a non-plasmid ID found
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
241 }
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
242 }
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
243 if (!defined($new_id)) {
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
244 die "The file '$file' only contains plasmids, program exits!\n";
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
245 }
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
246 my ($acc, $desc) = acc_desc($new_id); # subroutine to fill hash %genome_desc with acc#/unique ID and genome description
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
247 print GENOMES ">$acc $desc; artificial genome\n"; # print the now shortened ID-line for the new single-fasta entry in the result multi-genome file
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
248 foreach (@multi) { # print the rest of the new single-fasta file
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
249 if (/^>/) { # skip ID lines of the old multi-fasta file
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
250 next;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
251 }
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
252 print GENOMES;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
253 }
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
254 } elsif (scalar @IDs == 1) { # non-multi-fasta files
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
255 my ($acc, $desc) = acc_desc($IDs[0]);
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
256 print GENOMES ">$acc $desc\n"; # print the new shortened ID-line
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
257 foreach (@multi) {
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
258 if (/^>/) { # skip ID line, since new one already printed
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
259 next;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
260 }
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
261 print GENOMES;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
262 }
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
263 } else { # wrong fasta files
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
264 die "File '$file' does not include a fasta ID line, program exits!\n";
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
265 }
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
266 print GENOMES "\n";
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
267 close MULTI;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
268 }
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
269 close GENOMES;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
270 my @delete; # files to be deleted after program run
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
271 if (-e $genome_file) {
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
272 push (@delete, $genome_file);
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
273 } else {
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
274 die "The multi-fasta E. coli genome file \'$genome_file\' could not be created for the NUCmer run: $!\n";
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
275 }
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
276
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
277
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
278 ### Parse file 'publicSTs.txt' to get additional info for each sequence type
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
279 my $st_file = 'publicSTs.txt';
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
280 open(ST, "<$st_file") or die "Failed to open sequence type file '$st_file': $!\n";
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
281 my %seq_type; # hash to save ST info to each allele profile
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
282 my $header = <ST>; # get rid of file header
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
283 while (<ST>) {
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
284 chomp;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
285 my @st = split (/\t/, $_);
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
286 my $profile = "$st[3] $st[4] $st[5] $st[6] $st[7] $st[8] $st[9]"; # allele profile
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
287 my $info = "$st[0]\t$st[1]\t$st[2]\t$st[10]\t$st[11]"; # associated info to allele profile
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
288 # $st[0] = ST, 1 = ST_COMPLEX, 2 = ANCESTRAL_GROUP, 3-9 = adk-recA alleles, 10 = SOURCE, 11 = REFSTRAIN
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
289 $seq_type{$profile} = $info;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
290 }
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
291 close ST;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
292
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
293
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
294 ### Run nucmer with allele sequences as REFERENCES and the created 'ecoli_multi.fasta' file as QUERY
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
295 my @created_files; # used to print out files that are created at the end of the script
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
296 my %coord_files;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
297 foreach (keys %allele_files) {
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
298 system ("nucmer --prefix $_-all_ecoli $allele_files{$_} $genome_file"); # system call; seperate args not possible, probably because nucmer not a system command?!
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
299 system ("show-coords -lT $_-all_ecoli.delta > $_-all_ecoli.coords"); # '-l' include seq length in output, '-T' tab-separated output
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
300 if (-e "$_-all_ecoli.coords") {
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
301 $coord_files{$_} = "$_-all_ecoli.coords";
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
302 push (@delete, "$_-all_ecoli.delta");
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
303 push (@created_files, "\t\t\t$_-all_ecoli.coords\n");
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
304 } else {
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
305 die "Coord file '$_-all_ecoli.coords' could not be created: $!\n";
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
306 }
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
307 }
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
308
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
309
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
310 ### Parse *.coords nucmer result files for MLST alleles and corresponding accession#s
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
311 my @summary_err; # array to store error summary for error file
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
312 my @detail_err; # array to store the more detailed errors for error file
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
313 my $error = 0; # switches to '1' if an error is detected
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
314 my %strain_allele; # declare hash, that's subsequently used as 'hash in hash' in sub parse_coords to associate MLST alleles and accession#s
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
315 foreach (sort keys %coord_files) {
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
316 parse_coord($coord_files{$_}, $_); # subroutine to fill %strain_allele
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
317 }
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
318
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
319
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
320 ### Print the corresponding allele sequences and allele profile (plus additional info) for each E. coli genome
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
321 open(SEQ, ">$ecoli_allele_seq") or die "Failed to create file '$ecoli_allele_seq': $!\n";
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
322 my $ecoli_allele_profile = 'ecoli_mlst_profile.txt'; # tab-separated result file for the allele profile of each E. coli genome plus additional info from file 'publicSTs.txt' from the Achtman MLST DB
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
323 open(PROFILE, ">$ecoli_allele_profile") or die "Failed to create file '$ecoli_allele_profile': $!\n";
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
324 print PROFILE "Strain"; # header for profile file
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
325 foreach (sort @alleles) {
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
326 print PROFILE "\t$_";
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
327 }
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
328 print PROFILE "\tST\tST_COMPLEX\tANCESTRAL_GROUP\tSOURCE\tREFSTRAIN\n"; # info from file 'publicSTs.txt'
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
329 foreach my $acc (sort {lc $genome_desc{$a} cmp lc $genome_desc{$b}} keys %genome_desc) { # call hash %genome_desc by keys (acc#s), but sort by values (genome desc.s) of the hash case-insensitively (all in lowercase, because Perl sorts lowercase after uppercase!)
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
330 print SEQ ">$genome_desc{$acc} $acc\n"; # print fasta ID line for 'ecoli_mlst_seq.fasta'
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
331 print PROFILE "$genome_desc{$acc}"; # print genome desc for strain in first column for 'ecoli_mlst_profile.txt'
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
332 my $profile = ''; # allele profile to extract info from %seq_type
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
333 foreach my $allele (sort keys %strain_allele) {
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
334 if (defined $strain_allele{$allele}->{$acc}) {
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
335 open(ALLELE, "<$allele_files{$allele}") or die "Failed to open allele file $allele_files{$allele}: $!\n";
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
336 while (my $line = <ALLELE>) { # search for corresponding allele in multi-fasta allele file
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
337 chomp $line;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
338 if ($line =~ /^>$strain_allele{$allele}->{$acc}$/i) {
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
339 $line = <ALLELE>; # don't need the ID line but the following seq lines
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
340 while ($line !~ /^>/) { # print sequence in result file until another '>' is found
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
341 chomp $line;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
342 print SEQ "$line";
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
343 $line = <ALLELE>;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
344 }
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
345 }
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
346 }
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
347 close ALLELE;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
348 $strain_allele{$allele}->{$acc} =~ s/^(\D+)(\d+)$/$2/; # only keep allele number
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
349 print PROFILE "\t$strain_allele{$allele}->{$acc}";
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
350 $profile .= "$strain_allele{$allele}->{$acc} "; # concat allele numbers in $profile to extract info from %seq_type
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
351 } else {
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
352 print SEQ "XXX"; # place holder if allele of genome not determined
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
353 print PROFILE "\t?"; # place holder as well
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
354 unshift (@detail_err, "$genome_desc{$acc} didn't give a hit with $allele, marked by \'XXX\' in allele sequences and \'?\' in allele profile!\n");
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
355 next;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
356 }
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
357 }
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
358 print SEQ "\n\n"; # blank line in front of each ID line
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
359 chop $profile; # get rid of the last space, so it can be used as the key in %seq_type
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
360 if (defined $seq_type{$profile}) { # print ST and additional info from file 'publicST.txt' in 'ecoli_mlst_profile.txt'
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
361 print PROFILE "\t$seq_type{$profile}\n";
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
362 } else {
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
363 print PROFILE "\t?\t?\t?\t?\t?\n";
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
364 }
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
365 }
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
366 close SEQ;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
367 close PROFILE;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
368 if (-e $ecoli_allele_seq && $ecoli_allele_profile) { # push new created files in array for print out
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
369 push (@created_files, "\n\tResult files:\n\t\t\t$ecoli_allele_seq\t-> Allele sequences!\n", "\t\t\t$ecoli_allele_profile\t-> Allele profile plus info from 'publicSTs.txt'!\n");
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
370 } else {
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
371 die "The result files $ecoli_allele_seq and $ecoli_allele_profile could not be created: $!\n";
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
372 }
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
373
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
374
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
375 ### Print errors in error file,
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
376 if ($error == 1) { # error(s) occurred
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
377 my $err_file = 'errors.txt';
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
378 open(ERR, ">$err_file") or die "Failed to create file '$err_file': $!\n";
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
379 print ERR "Error summary:\n";
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
380 print ERR @summary_err; # filled in sub 'parse_coords'
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
381 print ERR "\nDetailed error output:\n";
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
382 print ERR @detail_err;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
383 push (@created_files, "\t\t\t$err_file\t\t-> Error file!\n");
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
384 close ERR;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
385 }
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
386
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
387
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
388 ### Delete unneeded files, temp file 'ecoli_multi.fasta' (see above) and the *.delta files from the NUCmer run
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
389 foreach my $goners (@delete) {
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
390 unlink $goners or warn "Could not remove file '$goners': $!";
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
391 }
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
392
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
393
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
394 ### Print newly created files
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
395 print "\n###########################################################################\n";
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
396 print "The following files were created:\n";
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
397 print "\tCoordinates of MLST alleles in each genome:\n";
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
398 print @created_files;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
399 print "\n###########################################################################\n";
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
400
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
401
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
402 ### Align with ClustalW if option '-c' is given
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
403 if ($clustalw) {
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
404 print "\nStarting ClustalW alignment with file $ecoli_allele_seq ...";
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
405 my $out = $ecoli_allele_seq;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
406 $out =~ s/\.fasta$//;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
407 my $clustal_call = "clustalw -infile=$ecoli_allele_seq -outfile=$clustal_aln -align -type=DNA -output=phylip -tree -newtree=$out\_aln.dnd -outputtree=phylip";
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
408 system ($clustal_call);
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
409 }
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
410
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
411 exit;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
412
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
413
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
414 ###############
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
415 # Subroutines #
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
416 ###############
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
417
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
418 ### Subroutine to associate the acc# to the genome description in hash %genome_desc (see above)
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
419 sub acc_desc {
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
420 my $ID = shift;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
421 chomp $ID;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
422 if ($ID =~ /^>gi\|\d+\|(emb|gb|dbj|ref)\|(\w+\d+\.\d)\|\s(.+)$/) { # NCBI fasta header
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
423 # e.g.: >gi|387605479|ref|NC_017626.1| Escherichia coli 042, complete genome
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
424 # $1 = DB (embl, genbank, ddbj, refseq), $2 = acc#, $3 = genome description
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
425 my $desc = shorten_desc($3); # subroutine to shorten the genome description
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
426 $genome_desc{$2} = $desc; # associate accession# with genome description
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
427 return ($2, $desc);
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
428 } elsif ($ID =~ /^>(\S+)\s*(\S*)\s*(.*)$/) { # headers after EMBOSS's union of multi-fasta files, and other headers with a unique ID after '>'
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
429 # e.g.: >NC_011748.1 NC_011748.1 Escherichia coli 55989 chromosome, complete genome
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
430 # $1 = acc#, $2 = genome desc for drafts|duplicated acc# for complete genomes, $3 = genome desc for complete genomes
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
431 my $desc = $2 . ' ' . $3;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
432 if ($1 eq $2) { # complete genomes have acc# double after EMBOSS's union (see above)
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
433 $desc = $3;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
434 }
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
435 $desc = shorten_desc($desc);
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
436 $genome_desc{$1} = $desc;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
437 return ($1, $desc);
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
438 }
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
439 return 0;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
440 }
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
441
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
442
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
443 ### Subroutine to parse *.coord nucmer result files for MLST alleles and corresponding accession#s
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
444 sub parse_coord {
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
445 my ($coord_file, $allele) = @_;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
446 my $lines = 0; # lines of respective *.coords file (without header); control if hit is missing or insensitive hits are present in comparison to $genome_number for the error file
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
447 my $discarded = 0; # number of discarded hits/lines in coord file for error file
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
448 open (COORD, "$coord_file") or die "Failed to open file '$coord_file': $!\n";
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
449 while (<COORD>) {
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
450 chomp;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
451 if ( /\d+\t\d+\t\d+\t\d+\t(\d+)\t(\d+)\t(\d+\.\d+)\t(\d+)\t\d+\t(\D+\d+)\t(\w*\d+\.\d)$/ ) {
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
452 # since the ID lines of the fastas were shortened in temp file 'ecoli_multi.fasta', the acc#s should be the last element of each line in the coords file
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
453 # $1 = length of ref alignment, $2 = length of query alignment, $3 = identity percentage,
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
454 # $4 = length of ref seq, $5 = allele-nr. (e.g. ADK15), $6 = accession-nr.
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
455 $lines++; # after 'if' to skip headers
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
456 if ($1 != $4) { # write error to @detail_err for error file
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
457 push (@detail_err, "$genome_desc{$6}, $5: Reference (allele) alignment doesn't have a correct length, therefore allele is not included in output!\n");
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
458 $discarded++;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
459 next;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
460 } elsif ($2 != $4) {
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
461 push (@detail_err, "$genome_desc{$6}, $5: Query (genome) alignment doesn't have a correct length, therefore allele is not included in output!\n");
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
462 $discarded++;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
463 next;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
464 } elsif ($3 != '100.00') {
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
465 push (@detail_err, "$genome_desc{$6}, $5: Identity is not 100\%, therefore is not included in output!\n");
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
466 $discarded++;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
467 next;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
468 }
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
469 $strain_allele{$allele}{$6} = $5; # associate allele# with acc# and store as hash in hash in %strain_allele
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
470 }
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
471 }
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
472 close COORD;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
473 # error identifications for later print out in error.txt
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
474 if ($discarded == 0) {
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
475 if ($lines < $genome_number) {
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
476 $error = 1; # switch $error from 0 to 1 to indicate error was found
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
477 push (@summary_err, $genome_number - $lines, " $allele allele(s) missing!\n");
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
478 }
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
479 } elsif ($discarded > 0) {
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
480 $error = 1;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
481 if (($lines - $discarded) == $genome_number) {
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
482 push (@summary_err, "Total number of specific assigned $allele alleles is correct, but $discarded non-specific hit(s) discarded!\n");
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
483 } elsif (($lines - $discarded) < $genome_number) {
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
484 push (@summary_err, $genome_number - ($lines - $discarded), " $allele allele(s) missing and $discarded non-specific hit(s)!\n");
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
485 }
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
486 }
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
487 return 1;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
488 }
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
489
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
490
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
491 ### Shorten the genome descriptions of the ID headers
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
492 sub shorten_desc {
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
493 my $desc = shift;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
494 $desc =~ s/Escherichia coli/Ecoli/;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
495 $desc =~ s/\'//g;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
496 $desc =~ s/( DNA, complete genome| chromosome, complete genome|, complete genome| chromosome, complete sequence| complete genome|, complete sequence|, strain (\S+)|, whole genome shotgun sequence)$//;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
497 $desc =~ s/\s/_/g;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
498 return $desc;
e42d30da7a74 Uploaded
dereeper
parents:
diff changeset
499 }