<commit_before>=head1 LICENSE

  Copyright (c) 1999-2012 The European Bioinformatics Institute and
  Genome Research Limited.  All rights reserved.

  This software is distributed under a modified Apache license.
  For license details, please see

   http://www.ensembl.org/info/about/code_licence.html

=head1 CONTACT

  Please email comments or questions to the public Ensembl
  developers list at <<EMAIL>>.

  Questions may also be sent to the Ensembl help desk at
  <<EMAIL>>.

=head1 NAME

Bio::EnsEMBL::Compara::RunnableDB::ProteinTrees::MCoffee

=head1 DESCRIPTION

This RunnableDB implements Bio::EnsEMBL::Compara::RunnableDB::ProteinTrees::MSA
by calling MCoffee. It needs the following parameters:
 - mcoffee_exe

=head1 AUTHORSHIP

Ensembl Team. Individual contributions can be found in the CVS log.

=head1 MAINTAINER

$Author$

=head VERSION

$Revision$

=head1 APPENDIX

The rest of the documentation details each of the object methods.
Internal methods are usually preceded with an underscore (_)

=cut

package Bio::EnsEMBL::Compara::RunnableDB::ProteinTrees::MCoffee;

use strict;

use IO::File;

use Bio::EnsEMBL::Compara::AlignedMemberSet;

use base ('Bio::EnsEMBL::Compara::RunnableDB::ProteinTrees::MSA');


sub param_defaults {
    my $self = shift;
    return {
        %{$self->SUPER::param_defaults},
        'method'                => 'fmcoffee',              # the style of MCoffee to be run for this alignment
        'options'               => '',
        'cutoff'                => 2,                       # for filtering
    };
}


#
# Redefined methods from the base class (MSA)
########################################################

sub parse_and_store_alignment_into_proteintree {
    my $self = shift;

    my $aln_ok = $self->SUPER::parse_and_store_alignment_into_proteintree();
    return 0 unless $aln_ok;

    my $mcoffee_scores = $self->param('mcoffee_scores');
    return 0 unless defined $mcoffee_scores;

    #
    # Read in the scores file manually.
    #
    my %score_hash;
    my $FH = IO::File->new();
    unless ($FH->open($mcoffee_scores)) {
        $self->warning("Could not open alignment scores file [$mcoffee_scores]");
        return 0;
    }
    <$FH>; #skip header
    my $i=0;
    while(<$FH>) {
        $i++;
        next if ($i < 7); # skip first 7 lines.
            next if($_ =~ /^\s+/);  #skip lines that start with space
            if ($_ =~ /:/) {
                my ($id,$overall_score) = split(/:/,$_);
                $id =~ s/^\s+|\s+$//g;
                $overall_score =~ s/^\s+|\s+$//g;
                print "___".$id."___".$overall_score."___\n";
                next;
            }
        chomp;
        my ($id, $align) = split;
        $score_hash{$id} ||= '';
        $score_hash{$id} .= $align;
    }
    $FH->close;

    #
    # Align cigar_lines to members and store
    #
    my $aln_score = Bio::Ensembl::Compara::AlignedMemberSet->deep_copy($self->param('protein_tree'));
    $aln_score->aln_method('mcoffee_score');
    foreach my $member (@{$aln_score->get_all_Members}) {
        my $score_string = $score_hash{$member->sequence_id} || '';
        $score_string =~ s/[^\d-]/9/g;   # Convert non-digits and non-dashes into 9s. This is necessary because t_coffee leaves some leftover letters
        printf("Updating the score of %s : %s\n",$member->stable_id,$score_string) if ($self->debug);
        $member->cigar_line($score_string);
    }
    $self->compara_dba->get_AlignedMemberAdaptor->store($aln_score);
    $self->param('protein_tree')->store_tag('mcoffee_scores', $aln_score->gene_align_id);
    return 1;
}



#
# Abstract methods from the base class (MSA) 
##############################################

sub get_msa_command_line {
    my $self = shift;
    my $input_fasta = $self->param('input_fasta');

    my $tempdir = $self->worker_temp_directory;
<commit_msg>bugfix + memory leak<commit_after>=head1 LICENSE

  Copyright (c) 1999-2012 The European Bioinformatics Institute and
  Genome Research Limited.  All rights reserved.

  This software is distributed under a modified Apache license.
  For license details, please see

   http://www.ensembl.org/info/about/code_licence.html

=head1 CONTACT

  Please email comments or questions to the public Ensembl
  developers list at <<EMAIL>>.

  Questions may also be sent to the Ensembl help desk at
  <<EMAIL>>.

=head1 NAME

Bio::EnsEMBL::Compara::RunnableDB::ProteinTrees::MCoffee

=head1 DESCRIPTION

This RunnableDB implements Bio::EnsEMBL::Compara::RunnableDB::ProteinTrees::MSA
by calling MCoffee. It needs the following parameters:
 - mcoffee_exe

=head1 AUTHORSHIP

Ensembl Team. Individual contributions can be found in the CVS log.

=head1 MAINTAINER

$Author$

=head VERSION

$Revision$

=head1 APPENDIX

The rest of the documentation details each of the object methods.
Internal methods are usually preceded with an underscore (_)

=cut

package Bio::EnsEMBL::Compara::RunnableDB::ProteinTrees::MCoffee;

use strict;

use IO::File;

use Bio::EnsEMBL::Compara::AlignedMemberSet;

use base ('Bio::EnsEMBL::Compara::RunnableDB::ProteinTrees::MSA');


sub param_defaults {
    my $self = shift;
    return {
        %{$self->SUPER::param_defaults},
        'method'                => 'fmcoffee',              # the style of MCoffee to be run for this alignment
        'options'               => '',
        'cutoff'                => 2,                       # for filtering
    };
}


#
# Redefined methods from the base class (MSA)
########################################################

sub parse_and_store_alignment_into_proteintree {
    my $self = shift;

    my $aln_ok = $self->SUPER::parse_and_store_alignment_into_proteintree();
    return 0 unless $aln_ok;

    my $mcoffee_scores = $self->param('mcoffee_scores');
    return 0 unless defined $mcoffee_scores;

    #
    # Read in the scores file manually.
    #
    my %score_hash;
    my $FH = IO::File->new();
    unless ($FH->open($mcoffee_scores)) {
        $self->warning("Could not open alignment scores file [$mcoffee_scores]");
        return 0;
    }
    <$FH>; #skip header
    my $i=0;
    while(<$FH>) {
        $i++;
        next if ($i < 7); # skip first 7 lines.
            next if($_ =~ /^\s+/);  #skip lines that start with space
            if ($_ =~ /:/) {
                my ($id,$overall_score) = split(/:/,$_);
                $id =~ s/^\s+|\s+$//g;
                $overall_score =~ s/^\s+|\s+$//g;
                print "___".$id."___".$overall_score."___\n";
                next;
            }
        chomp;
        my ($id, $align) = split;
        $score_hash{$id} ||= '';
        $score_hash{$id} .= $align;
    }
    $FH->close;

    #
    # Align cigar_lines to members and store
    #
    my $aln_score = $self->param('protein_tree')->deep_copy;
    $aln_score->aln_method('mcoffee_score');
    foreach my $member (@{$aln_score->get_all_Members}) {
        my $score_string = $score_hash{$member->sequence_id} || '';
        $score_string =~ s/[^\d-]/9/g;   # Convert non-digits and non-dashes into 9s. This is necessary because t_coffee leaves some leftover letters
        printf("Updating the score of %s : %s\n",$member->stable_id,$score_string) if ($self->debug);
        $member->cigar_line($score_string);
    }
    $self->compara_dba->get_AlignedMemberAdaptor->store($aln_score);
    $self->param('protein_tree')->store_tag('mcoffee_scores', $aln_score->gene_align_id);
    $aln_score->root->release_tree;
    $aln_score->clear;
    return 1;
}



#
# Abstract methods from the base class (MSA) 
##############################################

sub get_msa_command_line {
    my $self = shift;
    my $input_fasta = $self->param('input_fasta');

    my $tempdir = $self->worker_temp_directory;

{'fraction_non_alphanumeric': 0.1558759171064487, 'fraction_numerical': 0.0064358347277641914, 'mean_word_length': 2.978494623655914, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 70, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4152709', 'n_tokens_mistral': 2687, 'n_tokens_neox': 2460, 'n_words': 626}