<commit_before>package CoGeX::Dataset;

# Created by DBIx::Class::Schema::Loader v0.03009 @ 2006-12-01 18:13:38

use strict;
use warnings;
use Data::Dumper;

use base 'DBIx::Class';

__PACKAGE__->load_components("PK::Auto", "ResultSetManager", "Core");
__PACKAGE__->table("dataset");
__PACKAGE__->add_columns(
  "dataset_id",
  { data_type => "INT", default_value => undef, is_nullable => 0, size => 10 },
  "data_source_id",
  { data_type => "INT", default_value => 0, is_nullable => 0, size => 10 },
  "organism_id",
  { data_type => "INT", default_value => "", is_nullable => 0, size => 10 },
  "name",
  { data_type => "VARCHAR", default_value => "", is_nullable => 0, size => 50 },
  "description",
  {
    data_type => "VARCHAR",
    default_value => undef,
    is_nullable => 1,
    size => 255,
  },
  "version",
  {
    data_type => "VARCHAR",
    default_value => undef,
    is_nullable => 1,
    size => 50,
  },
  "link",
  {
    data_type => "TEXT",
    default_value => undef,
    is_nullable => 1,
    size => 65535,
  },
);

__PACKAGE__->set_primary_key("dataset_id");

__PACKAGE__->has_many("features" => "CoGeX::Feature", 'dataset_id');

__PACKAGE__->has_many("genomic_sequences" => "CoGeX::GenomicSequence", 'dataset_id');

__PACKAGE__->belongs_to("datasource" => "CoGeX::DataSource", 'data_source_id');

__PACKAGE__->belongs_to("organism" => "CoGeX::Organism", 'organism_id');


sub chromosomes : ResultSet {
    my $self = shift;
    my $r1 = $self->search(undef,{
        prefetch =>['genomic_sequences']
    });
    return $r1 if $r1->count;
    # TODO: should probably just return an array here instead of 
    # full objects...
    return $self->search(undef,{
        prefetch =>[{'features' => 'locations' }]
    });

}

# get_sequence:
# $rs->get_genome_sequence( [chromosome, from, to] )
# $rs->get_genome_sequence() - returns the entire genome sequence *woot*
# $rs->get_genome_sequence(1, 42, 101) - returns chromosome 1 sequence 
#                                        from position 42 up to and
#                                        including position 101

sub get_genomic_sequence {
  my $self = shift;
  my %opts = @_;
  my $start = $opts{start} || $opts{begin};
  my $stop = $opts{stop} || $opts{end};
  my $chr = $opts{chr} || $opts{chromosome};
  
  my $str = "";

  if ( @_ > 1 ) {     
    my($chromosome, $from, $to);
    if (defined $start && defined $stop && defined $chr)
      {
 	$chromosome = $chr;
 	$from = $start;
 	$to = $stop;
      }
    else
      {
 	($chromosome, $from, $to) = @_;
      }
        
    $chromosome = "1" unless defined $chromosome;
    my $last = $self->last_chromosome_position($chromosome);
    $from = 1 if $from < 1;
    $to = $last if $to > $last;
    # make sure two numbers were sent in
    return undef unless ($from =~ /\A\d+\z/ and  $to =~ /\A\d+\z/);
    return undef unless $to > $from;
    my $g1 = $self->genomic_sequences(
                      {
                        'chromosome' => $chromosome,
                        'start'      => { '<=' => $from },
                        'stop'       => { '>=' => $from }
                      })->first();
    my $g2 = $self->genomic_sequences(
                      {
                        'chromosome' => $chromosome ,
                        'start'      => { '<=' => $to },
                        'stop'       => { '>=' => $to }
                      })->first();
    if ( $g2->start == $g1->start )         { # hit is within one row
      $str = $g1->sequence_data;
    } elsif ( $g2->start == $g1->stop + 1 ) { # consecutive rows
      $str = $g1->sequence_data . $g2->sequence_data;
    } elsif ( $g2->start >= $g1->stop + ($g1->stop - $g1->start) ) {
      $str = $g1->sequence_data();            # start with first row
      my $inneriter = $self->genomic_sequences(
                                  {
                                    'chromosome' => $chromosome ,
                                    'start' => { '>=' => $g1->stop + 1 },
                                    'stop ' => { '<'  => $g2->start }
                                  });

        
      while( my $innerseq = $inneriter->next() ) {
        $str .= $innerseq->sequence_data();
      }
      $str .= $g2->sequence_data(); # get last row
    }
    $str = $self->trim_sequence( $str, $g1->start, $g2->stop, $from, $to );

  } elsif ( @_ == 1 ) {    # get a whole chromosome
    my $chromosome = shift;
    my $allseqs = $self->genomic_sequences( { 'chromosome' => $chromosome } );
    while ( my $g = $allseqs->next ) {
      $str .= $g->sequence_data;
    }
  } else {                 # entire sequence
    my $allseqs = $self->genomic_sequences();
    while ( my $g = $allseqs->next ) {
      $str .= $g->sequence_data;
    }
  }
  return $str;
}

sub get_genome_sequence
  {
    return shift->get_genomic_sequence(@_);
  }
#         .         .         .         .
#1234567890123456789012345678901234567890
#                                       CCACAACCAGCTGACTAGGTA
#ACGACGCAGCTATGGCCTCCCCGCCCACCAGGCCGCCAGCCACAACCAGC
#         CTATGGCCTC
sub trim_sequence {
  my $self = shift;
  my( $seq, $seqstart, $seqend, $newstart, $newend ) = @_;
  my $start = $newstart-$seqstart;
  my $stop = length($seq)-($seqend-$newend);
  $seq = substr($seq, $start, $stop);
  return($seq);
}


################################################## subroutine header start ##

=head2 last_chromsome_position

 Usage     : my $last = $genome_seq_obj->last_chromosome_position($chr);
 Purpose   : gets the last genomic sequence position for a dataset given a chromosome
 Returns   : an integer that refers to the last position in the genomic sequence refered
             to by a dataset given a chromosome
 Argument  : string => chromsome for which the last position is sought<commit_msg>updated get_genomic_sequence query to use a single query<commit_after>package CoGeX::Dataset;

# Created by DBIx::Class::Schema::Loader v0.03009 @ 2006-12-01 18:13:38

use strict;
use warnings;
use Data::Dumper;

use base 'DBIx::Class';

__PACKAGE__->load_components("PK::Auto", "ResultSetManager", "Core");
__PACKAGE__->table("dataset");
__PACKAGE__->add_columns(
  "dataset_id",
  { data_type => "INT", default_value => undef, is_nullable => 0, size => 10 },
  "data_source_id",
  { data_type => "INT", default_value => 0, is_nullable => 0, size => 10 },
  "organism_id",
  { data_type => "INT", default_value => "", is_nullable => 0, size => 10 },
  "name",
  { data_type => "VARCHAR", default_value => "", is_nullable => 0, size => 50 },
  "description",
  {
    data_type => "VARCHAR",
    default_value => undef,
    is_nullable => 1,
    size => 255,
  },
  "version",
  {
    data_type => "VARCHAR",
    default_value => undef,
    is_nullable => 1,
    size => 50,
  },
  "link",
  {
    data_type => "TEXT",
    default_value => undef,
    is_nullable => 1,
    size => 65535,
  },
);

__PACKAGE__->set_primary_key("dataset_id");

__PACKAGE__->has_many("features" => "CoGeX::Feature", 'dataset_id');

__PACKAGE__->has_many("genomic_sequences" => "CoGeX::GenomicSequence", 'dataset_id');

__PACKAGE__->belongs_to("datasource" => "CoGeX::DataSource", 'data_source_id');

__PACKAGE__->belongs_to("organism" => "CoGeX::Organism", 'organism_id');


sub chromosomes : ResultSet {
    my $self = shift;
    my $r1 = $self->search(undef,{
        prefetch =>['genomic_sequences']
    });
    return $r1 if $r1->count;
    # TODO: should probably just return an array here instead of 
    # full objects...
    return $self->search(undef,{
        prefetch =>[{'features' => 'locations' }]
    });

}

# get_sequence:
# $rs->get_genome_sequence( [chromosome, from, to] )
# $rs->get_genome_sequence() - returns the entire genome sequence *woot*
# $rs->get_genome_sequence(1, 42, 101) - returns chromosome 1 sequence 
#                                        from position 42 up to and
#                                        including position 101

sub get_genomic_sequence {
  my $self = shift;
  my %opts = @_;
  my $start = $opts{start} || $opts{begin};
  my $stop = $opts{stop} || $opts{end};
  my $chr = $opts{chr} || $opts{chromosome};
  my $str = "";

  if ( @_ > 1 ) {     
    my($chromosome, $from, $to);
    if (defined $start && defined $stop && defined $chr)
      {
 	$chromosome = $chr;
 	$from = $start;
 	$to = $stop;
      }
    else
      {
 	($chromosome, $from, $to) = @_;
      }
        
    $chromosome = "1" unless defined $chromosome;
    my $last = $self->last_chromosome_position($chromosome);
    $from = 1 if $from < 1;
    $to = $last if $to > $last;
    # make sure two numbers were sent in
    return undef unless ($from =~ /\A\d+\z/ and  $to =~ /\A\d+\z/);
    return undef unless $to > $from;
    my @seqs = $self->genomic_sequences(
					      {chromosome=>$chromosome,
					       -and=>[
						      -or=>[
							    -and=>[
								   start => {'<='=>$to},
								   stop  => {'>='=>$to},
								  ],
							     -and=>[
								    start => {'<='=>$from},
								    stop  => {'>='=>$from},
								   ],
							    -and=>[
								   start => {'>'=>$from},
								   stop  => {'<'=>$to},
								  ],
							   ],
						     ],
					      },
					      {-order_by=>"start"}
					     )->all;
    $str = join ("", map{$_->sequence_data} @seqs);  
    $str = $self->trim_sequence( $str, $seqs[0]->start, $seqs[-1]->stop, $from, $to );
    
  } elsif ( @_ == 1 ) {    # get a whole chromosome
    my $chromosome = shift;
    my $allseqs = $self->genomic_sequences( { 'chromosome' => $chromosome } );
    while ( my $g = $allseqs->next ) {
      $str .= $g->sequence_data;
    }
  } else {                 # entire sequence
    my $allseqs = $self->genomic_sequences();
    while ( my $g = $allseqs->next ) {
      $str .= $g->sequence_data;
    }
  }
  return $str;
}
sub get_genomic_sequence_old {
  my $self = shift;
  my %opts = @_;
  my $start = $opts{start} || $opts{begin};
  my $stop = $opts{stop} || $opts{end};
  my $chr = $opts{chr} || $opts{chromosome};
  
  my $str = "";

  if ( @_ > 1 ) {     
    my($chromosome, $from, $to);
    if (defined $start && defined $stop && defined $chr)
      {
 	$chromosome = $chr;
 	$from = $start;
 	$to = $stop;
      }
    else
      {
 	($chromosome, $from, $to) = @_;
      }
        
    $chromosome = "1" unless defined $chromosome;
    my $last = $self->last_chromosome_position($chromosome);
    $from = 1 if $from < 1;
    $to = $last if $to > $last;
    # make sure two numbers were sent in
    return undef unless ($from =~ /\A\d+\z/ and  $to =~ /\A\d+\z/);
    return undef unless $to > $from;
    my $g1 = $self->genomic_sequences(
                      {
                        'chromosome' => $chromosome,
                        'start'      => { '<=' => $from },
                        'stop'       => { '>=' => $from }
                      })->first();
    my $g2 = $self->genomic_sequences(
                      {
                        'chromosome' => $chromosome ,
                        'start'      => { '<=' => $to },
                        'stop'       => { '>=' => $to }
                      })->first();
    if ( $g2->start == $g1->start )         { # hit is within one row
      $str = $g1->sequence_data;
    } elsif ( $g2->start == $g1->stop + 1 ) { # consecutive rows
      $str = $g1->sequence_data . $g2->sequence_data;
    } elsif ( $g2->start >= $g1->stop + ($g1->stop - $g1->start) ) {
      $str = $g1->sequence_data();            # start with first row
      my $inneriter = $self->genomic_sequences(
                                  {
                                    'chromosome' => $chromosome ,
                                    'start' => { '>=' => $g1->stop + 1 },
                                    'stop ' => { '<'  => $g2->start }
                                  });

        
      while( my $innerseq = $inneriter->next() ) {
        $str .= $innerseq->sequence_data();
      }
      $str .= $g2->sequence_data(); # get last row
    }
    $str = $self->trim_sequence( $str, $g1->start, $g2->stop, $from, $to );
  } elsif ( @_ == 1 ) {    # get a whole chromosome
    my $chromosome = shift;
    my $allseqs = $self->genomic_sequences( { 'chromosome' => $chromosome } );
    while ( my $g = $allseqs->next ) {
      $str .= $g->sequence_data;
    }
  } else {                 # entire sequence
    my $allseqs = $self->genomic_sequences();
    while ( my $g = $allseqs->next ) {
      $str .= $g->sequence_data;
    }
  }
  return $str;
}

sub get_genome_sequence
  {
    return shift->get_genomic_sequence(@_);
  }
#         .         .         .         .
#1234567890123456789012345678901234567890
#                                       CCACAACCAGCTGACTAGGTA
#ACGACGCAGCTATGGCCTCCCCGCCCACCAGGCCGCCAGCCACAACCAGC
#         CTATGGCCTC
sub trim_sequence {
  my $self = shift;
  my( $seq, $seqstart, $seqend, $newstart, $newend ) = @_;
  my $start = $newstart-$seqstart;
  my $stop = length($seq)-($seqend-$newend)-1;
  $seq = substr($seq, $start, $stop);
  return($seq);
}


################################################## subroutine header start ##

=head2 last_chromsome_position

 Usage     : my $last = $genome_seq_obj->last_chromosome_position($chr);
 Purpose   : gets the last genomic sequence position for a dataset given a chromosome
 Returns   : an integer that refers to the last position in the genomic sequence refered
             to by a dataset given a chromosome
 Argument  : string => chromsome for which the last position is sought
{'fraction_non_alphanumeric': 0.17303420701910263, 'fraction_numerical': 0.019546868058640605, 'mean_word_length': 2.1244506130002314, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 256, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 18, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7375362', 'n_tokens_mistral': 4985, 'n_tokens_neox': 4438, 'n_words': 1019}