My solution:
# split a large MSA into smaller chunks
use Bio::Perl;
use Bio::AlignIO;
use Data::Dumper;
use List::Util qw[min max];
use strict;
use warnings;
exit(main(@ARGV));
sub main{
my($lcbFile,$format)=@_;
my @aln=splitLcb($lcbFile,$format);
# write the split alignment
for(my $i=0;$i<@aln;$i++){
my $outFile="$lcbFile.part$i";
print "Writing $outFile\n";
my $out=Bio::AlignIO->new(-format=>"fasta",-file=>">$outFile");
$out->write_aln($aln[$i]);
}
return 0;
}
# only looks at a single MSA in the input file (does not accept more than one aln in an aln file)
sub splitLcb{
my($lcb,$format)=@_;
# look for a set of xx nt that are homologous and split in the middle.
my $minHomologousNucleotides=499;
my @slicedAln; # result
my $in=Bio::AlignIO->new(-file=>$lcb,-format=>$format);
my $aln=$in->next_aln;
# walk along the LCB to find a region of 100% identity
my $alnLength=$aln->length;
my $matchLine=$aln->match_line;
# use the match line to find regions of homology
SEARCH_FOR_HOMOLOGY: for(my $col=$minHomologousNucleotides*2;$col<$alnLength;$col++){
if(is_col_identical($matchLine,$col)){
# now see if the next xx nts are identical too
my $length=min($alnLength,$col+$minHomologousNucleotides-1);
for($col=$col;$col<$length;$col++){
if(!is_col_identical($matchLine,$col)){
next SEARCH_FOR_HOMOLOGY;
}
}
my $homologyStart=($col-$minHomologousNucleotides+1);
my $homologyStop=$col-1;
print "Region of homology is $homologyStart - $homologyStop, and the minHomologousNucleotides=$minHomologousNucleotides, alignmentLength=$alnLength\n";
# slice the alignment into two chunks
$homologyStart++;$homologyStop++; # base-1 coordinates
my $sliceCoordinate=int ($minHomologousNucleotides/2+$homologyStart);
$slicedAln[0]=$aln->slice(1,$sliceCoordinate);
$slicedAln[1]=$aln->slice($sliceCoordinate+1,$alnLength);
last SEARCH_FOR_HOMOLOGY;
}
}
return (@slicedAln);
}
sub is_col_identical{
my($matchLine,$col)=@_;
my $t=substr($matchLine,$col,1);
if($t eq '*'){
return 1;
}
return 0;
}
How large is your sequence?
How large is your sequence? It will be nice to know the round figure so people here can know your challenges.
I guess you should split on syntenic regions. How large is very large?
Have you tried to use Exonerate instead of MUSCLE or Clustal?
One of my large alignments is 86636 nucleotides, 1.4 megabytes. Another one is 861 kilobytes.
I have not tried Exonerate yet but guessing from "exon" it is not exactly what I want.
Exonerate is a general purpose aligner aimed at genome projects. You can even use it for gene models. By the way, the sizes of your aligments are small. MUSCLE should work . . .
Well, not so small . . .
I guess you should split on syntenic regions. How large is very large?