<commit_before>
=head1 LICENSE

Copyright [1999-2015] Wellcome Trust Sanger Institute and the EMBL-European Bioinformatics Institute

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

=cut

=pod


=head1 NAME

Bio::EnsEMBL::Utils::IO::GTFSerializer - Transcript to GTF converter

=head1 SYNOPSIS

use Bio::EnsEMBL::Utils::IO::GTFSerializer;

my $serializer = Bio::EnsEMBL::Utils::IO::GTFSerializer->new($output_fh);

=head1 DESCRIPTION

Subclass of Serializer that can turn a transcript into a series of lines 
for the GTF format.

=cut

package Bio::EnsEMBL::Utils::IO::GTFSerializer;

use strict;
use warnings;

use Bio::Tools::CodonTable;
use Bio::EnsEMBL::SeqFeature;
use Bio::EnsEMBL::Utils::Exception;
use Bio::EnsEMBL::Utils::IO::FeatureSerializer;
use Bio::EnsEMBL::Utils::Scalar qw/check_ref/;
use Bio::EnsEMBL::Feature;

use base qw(Bio::EnsEMBL::Utils::IO::FeatureSerializer);

my %strand_conversion = ( '1' => '+', '0' => '.', '-1' => '-' );

sub print_main_header {
  my $self = shift;
  my $dba = shift;
  my $fh = $self->{'filehandle'};
  
  my $mc = $dba->get_MetaContainer();
  my $gc = $dba->get_GenomeContainer();

  # Get the build. name gives us GRCh37.p1 where as default gives us GRCh37
  my $assembly_name = $gc->get_assembly_name();
  print $fh "#!genome-build ${assembly_name}\n" if $assembly_name;

  # Get the build default
  my $version = $gc->get_version();
  print $fh "#!genome-version ${version}\n" if $version;

  # Get the date of the genome build
  my $assembly_date = $gc->get_assembly_date();
  print $fh "#!genome-date ${assembly_date}\n" if $assembly_date;

  # Get accession and only print if it is there
  my $accession = $gc->get_accession();
  if($accession) {
     my $accession_source = $mc->single_value_by_key('assembly.web_accession_source');
     my $string = "#!genome-build-accession ";
     $string .= "$accession_source:" if $accession_source;
     $string .= "$accession"; 

     print $fh "$string\n";
     #my $accession_source = $mc->single_value_by_key('assembly.web_accession_source');
     #print $fh "#!genome-build-accession ${accession_source}:${accession}\n";
  }

  # Genebuild last updated
  my $genebuild_last_date = $gc->get_genebuild_last_geneset_update();
  print $fh "#!genebuild-last-updated ${genebuild_last_date}\n" if $genebuild_last_date;

  return;
}

sub print_Gene {
  my ($self, $gene) = @_;

  #Print Gene summary
  my $slice           = $gene->slice();
  my $idstr           = $slice->seq_region_name;
  my $sliceoffset     = $slice->start - 1;
  my $vegadb          = 0;
  my $fh              = $self->{'filehandle'};
  my $biotype_display = q{};
  if($gene->adaptor()) {
    my $dbname = $gene->adaptor()->dbc()->dbname();
    $vegadb = $dbname =~ /vega/;
  }

  {
    no warnings 'uninitialized';
    $biotype_display = $vegadb ? $gene->status . '_' . $gene->biotype : $gene->biotype;
  }

  print $fh sprintf(qq{%s\t%s\tgene\t%d\t%d\t.\t%s\t.\t}, 
        $idstr, $gene->source, 
        ($gene->start()+$sliceoffset), ($gene->end()+$sliceoffset),
        ($strand_conversion{$gene->strand}));
  $self->_print_attribs($gene, $biotype_display, $gene, $biotype_display, 0, 'gene');
  print $fh "\n";

  # Now print all transcripts
  foreach my $t (@{$gene->get_all_Transcripts()}) {
    $self->print_feature($t, $gene);
  }
  return;
}

sub print_Prediction {
  my ($self, $prediction) = @_;

  #Print prediction transcript summary
  my $slice           = $prediction->slice();
  my $idstr           = $slice->seq_region_name;
  my $sliceoffset     = $slice->start - 1;
  my $vegadb          = 0;
  my $fh              = $self->{'filehandle'};

  my $source = $prediction->analysis->gff_source || 'ensembl';

  print $fh sprintf(qq{%s\t%s\ttranscript\t%d\t%d\t.\t%s\t.\t},
        $idstr, $source,
        ($prediction->start()+$sliceoffset), ($prediction->end()+$sliceoffset),
        ($strand_conversion{$prediction->strand}));
  print $fh "\n";

  # Now print all transcripts
  foreach my $exon (@{$prediction->get_all_Exons()}) {
    print $fh sprintf(qq{%s\t%s\texon\t%d\t%d\t.\t%s\t.\t},
          $idstr, $source,
          ($exon->start()+$sliceoffset), ($exon->end()+$sliceoffset),
          ($strand_conversion{$exon->strand}));
    print $fh "\n";
  }
  return;
}

=head2 print_feature

    Arg [1]    : Bio::EnsEMBL::Transcript
    Example    : $serializer->print_feature($transcript)
    Description: Generate all the GTF features required for this transcript
    Returntype : none

=cut

sub print_feature {
  my $self       = shift;
  my $transcript = shift;
  my $gene = shift;

  throw( sprintf "Feature is of type %s. Cannot write non transcripts to GTF", ref($transcript) ) 
    unless check_ref( $transcript, "Bio::EnsEMBL::Transcript" );

  # filehandle is inherited
  my $fh = $self->{'filehandle'};

  my $slice       = $transcript->slice();
  my $sliceoffset = $slice->start - 1;
  my $idstr       = $slice->seq_region_name;

  # Create start codon features. Multiple due to outcomes of projection, but they will 
  # overlap the first exon
  my @startcodons = $self->_make_start_codon_features($transcript);

  # Stop codons (multiple "features" from projection), are NOT included in the CDS in GTF, so the
  # CDS coordinates get adjusted in the process of creating the stop.
  my @endcodons   = $self->_make_stop_codon_features($transcript);

  # We then verify the positions really are proper stops and starts, by looking for annotation
  # and checking the bases constitute a stop. These flags are then used to decide whether to
  # actually print the features created by the two calls above.
  my ( $hasstart, $hasend ) = $self->_check_start_and_stop($transcript);

  my $vegadb = 0;
  if($transcript->adaptor()) {
    my $dbname = $transcript->adaptor()->dbc()->dbname();
    $vegadb = $dbname =~ /vega/;
  }
  $gene   ||= $transcript->get_Gene();<commit_msg>ENSCORESW-1318: ignore seqedits for gtf<commit_after>
=head1 LICENSE

Copyright [1999-2015] Wellcome Trust Sanger Institute and the EMBL-European Bioinformatics Institute

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

=cut

=pod


=head1 NAME

Bio::EnsEMBL::Utils::IO::GTFSerializer - Transcript to GTF converter

=head1 SYNOPSIS

use Bio::EnsEMBL::Utils::IO::GTFSerializer;

my $serializer = Bio::EnsEMBL::Utils::IO::GTFSerializer->new($output_fh);

=head1 DESCRIPTION

Subclass of Serializer that can turn a transcript into a series of lines 
for the GTF format.

=cut

package Bio::EnsEMBL::Utils::IO::GTFSerializer;

use strict;
use warnings;

use Bio::Tools::CodonTable;
use Bio::EnsEMBL::SeqFeature;
use Bio::EnsEMBL::Utils::Exception;
use Bio::EnsEMBL::Utils::IO::FeatureSerializer;
use Bio::EnsEMBL::Utils::Scalar qw/check_ref/;
use Bio::EnsEMBL::Feature;

use base qw(Bio::EnsEMBL::Utils::IO::FeatureSerializer);

my %strand_conversion = ( '1' => '+', '0' => '.', '-1' => '-' );

sub print_main_header {
  my $self = shift;
  my $dba = shift;
  my $fh = $self->{'filehandle'};
  
  my $mc = $dba->get_MetaContainer();
  my $gc = $dba->get_GenomeContainer();

  # Get the build. name gives us GRCh37.p1 where as default gives us GRCh37
  my $assembly_name = $gc->get_assembly_name();
  print $fh "#!genome-build ${assembly_name}\n" if $assembly_name;

  # Get the build default
  my $version = $gc->get_version();
  print $fh "#!genome-version ${version}\n" if $version;

  # Get the date of the genome build
  my $assembly_date = $gc->get_assembly_date();
  print $fh "#!genome-date ${assembly_date}\n" if $assembly_date;

  # Get accession and only print if it is there
  my $accession = $gc->get_accession();
  if($accession) {
     my $accession_source = $mc->single_value_by_key('assembly.web_accession_source');
     my $string = "#!genome-build-accession ";
     $string .= "$accession_source:" if $accession_source;
     $string .= "$accession"; 

     print $fh "$string\n";
     #my $accession_source = $mc->single_value_by_key('assembly.web_accession_source');
     #print $fh "#!genome-build-accession ${accession_source}:${accession}\n";
  }

  # Genebuild last updated
  my $genebuild_last_date = $gc->get_genebuild_last_geneset_update();
  print $fh "#!genebuild-last-updated ${genebuild_last_date}\n" if $genebuild_last_date;

  return;
}

sub print_Gene {
  my ($self, $gene) = @_;

  #Print Gene summary
  my $slice           = $gene->slice();
  my $idstr           = $slice->seq_region_name;
  my $sliceoffset     = $slice->start - 1;
  my $vegadb          = 0;
  my $fh              = $self->{'filehandle'};
  my $biotype_display = q{};
  if($gene->adaptor()) {
    my $dbname = $gene->adaptor()->dbc()->dbname();
    $vegadb = $dbname =~ /vega/;
  }

  {
    no warnings 'uninitialized';
    $biotype_display = $vegadb ? $gene->status . '_' . $gene->biotype : $gene->biotype;
  }

  print $fh sprintf(qq{%s\t%s\tgene\t%d\t%d\t.\t%s\t.\t}, 
        $idstr, $gene->source, 
        ($gene->start()+$sliceoffset), ($gene->end()+$sliceoffset),
        ($strand_conversion{$gene->strand}));
  $self->_print_attribs($gene, $biotype_display, $gene, $biotype_display, 0, 'gene');
  print $fh "\n";

  # Now print all transcripts
  foreach my $t (@{$gene->get_all_Transcripts()}) {
    $self->print_feature($t, $gene);
  }
  return;
}

sub print_Prediction {
  my ($self, $prediction) = @_;

  #Print prediction transcript summary
  my $slice           = $prediction->slice();
  my $idstr           = $slice->seq_region_name;
  my $sliceoffset     = $slice->start - 1;
  my $vegadb          = 0;
  my $fh              = $self->{'filehandle'};

  my $source = $prediction->analysis->gff_source || 'ensembl';

  print $fh sprintf(qq{%s\t%s\ttranscript\t%d\t%d\t.\t%s\t.\t},
        $idstr, $source,
        ($prediction->start()+$sliceoffset), ($prediction->end()+$sliceoffset),
        ($strand_conversion{$prediction->strand}));
  print $fh "\n";

  # Now print all transcripts
  foreach my $exon (@{$prediction->get_all_Exons()}) {
    print $fh sprintf(qq{%s\t%s\texon\t%d\t%d\t.\t%s\t.\t},
          $idstr, $source,
          ($exon->start()+$sliceoffset), ($exon->end()+$sliceoffset),
          ($strand_conversion{$exon->strand}));
    print $fh "\n";
  }
  return;
}

=head2 print_feature

    Arg [1]    : Bio::EnsEMBL::Transcript
    Example    : $serializer->print_feature($transcript)
    Description: Generate all the GTF features required for this transcript
    Returntype : none

=cut

sub print_feature {
  my $self       = shift;
  my $transcript = shift;
  my $gene = shift;

  throw( sprintf "Feature is of type %s. Cannot write non transcripts to GTF", ref($transcript) ) 
    unless check_ref( $transcript, "Bio::EnsEMBL::Transcript" );

  # filehandle is inherited
  my $fh = $self->{'filehandle'};

  my $slice       = $transcript->slice();
  my $sliceoffset = $slice->start - 1;
  my $idstr       = $slice->seq_region_name;

  ## Seq edits are needed for sequence, not coordinates
  $transcript->edits_enabled(0);

  # Create start codon features. Multiple due to outcomes of projection, but they will 
  # overlap the first exon
  my @startcodons = $self->_make_start_codon_features($transcript);

  # Stop codons (multiple "features" from projection), are NOT included in the CDS in GTF, so the
  # CDS coordinates get adjusted in the process of creating the stop.
  my @endcodons   = $self->_make_stop_codon_features($transcript);

  # We then verify the positions really are proper stops and starts, by looking for annotation
  # and checking the bases constitute a stop. These flags are then used to decide whether to
  # actually print the features created by the two calls above.
  my ( $hasstart, $hasend ) = $self->_check_start_and_stop($transcript);

  my $vegadb = 0;
  if($transcript->adaptor()) {
    my $dbname = $transcript->adaptor()->dbc()->dbname();
    $vegadb = $dbname =~ /vega/;
  }
  $gene   ||= $transcript->get_Gene();
{'fraction_non_alphanumeric': 0.14861912934935248, 'fraction_numerical': 0.005539085660789515, 'mean_word_length': 3.7583518930957682, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 120, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6123102', 'n_tokens_mistral': 4603, 'n_tokens_neox': 4257, 'n_words': 1160}