<commit_before>package Bio::EnsEMBL::GlyphSet_generic;

use strict;
use warnings;
no warnings 'uninitialized';
use base qw(Bio::EnsEMBL::GlyphSet);

use Data::Dumper;

sub features {
  return {
    'f_count'    => 0,
    'g_count'    => 0,
    'merge'      => 0, ## Merge all logic names into one track! note different from other systems!!
    'groups'     => {},
    'f_styles'   => {},
    'g_styles'   => {},
    'errors'     => [],
    'ss_errors'  => [],
    'urls'       => [],
    'ori'        => {},
    'max_height' => 0
  };
} 

use Bio::EnsEMBL::Feature;

sub _draw_features {
  my( $self, $ori, $features, $render_flags ) = @_;

  $self->_init_bump();

  my $strand = $self->strand;
  my %can_hash;
  my $ppbp    = $self->{ppbp} = $self->scalex;
  $self->{bppp} = 1 / $ppbp; 
  my $seq_len = $self->{'seq_len'} = $self->{'container'}->length;
#  my $h       = $self->{'h'}       = $features->{'max_height'} || 8; ## We may need to hack this to make it specific to orientation later! needs hacking in _das.pm

  $self->{'h'} = 0;
  my $colour = $ori ? 'blue' : 'green';

  foreach my $lname   ( sort keys %{$features->{'groups'}} ) {
    foreach my $gkey  ( sort keys %{$features->{'groups'}{$lname}} ) {
      my $group = $features->{'groups'}{$lname}{$gkey}{$ori};
      next unless $group;                                          ## No features from this group on this strand!
      next if $group->{'end'} < 1 || $group->{'start'} > $seq_len; ## All features in group exist outside region!

## Now loop through all features and get the extents of features - we will need this later for bumping! and joining!

      my $g_s = $features->{'g_styles'}{$lname}{$gkey};             ## Get the group style...
      my $to_join = lc( $g_s->{'symbol'} ) ne 'hidden';

      foreach my $style_key ( keys %{$group->{'features'}} ) {
        my $f_s  = $features->{'f_styles'}{$lname}{$style_key};
        my $to_bump = $f_s->{'style'}{'bump'} eq 'yes';             ## Bump if style bump is set!
        my $fn_c = "composite_extent_".$f_s->{'style'}{'symbol'};
        my $fn_g = "extent_".$f_s->{'style'}{'symbol'};
        $can_hash{$fn_c} ||= $self->can($fn_c);
        $can_hash{$fn_g} ||= $self->can($fn_g) || '-';
        $fn_g = 'extent_box' if $can_hash{$fn_g} eq '-'; ## default to drawing a box!!
        if( $can_hash{$fn_c} ) { ## This is one of the histogram style displays and the render fn has been defined!
          $self->$fn_c( $group, $f_s->{style} );
        } else {
          foreach my $f ( @{$group->{'features'}{$style_key}} ) { # Compute the extent of each glyph - and add to extent of group if not bumped!
## Only pass the glyph if we are going to put this glyph in a composite
            $self->$fn_g( $to_join && !$to_bump ? $group : undef, $f, $f_s->{style} );
          }
        }
        $group->{height} = $g_s->{style}{height} if $g_s->{style}{height} > $group->{height} && $group->{extent_start};
        $self->{h} = $g_s->{style}{height} if $g_s->{style}{height} > $self->{h} && $group->{extent_start};
      }
    }
  }
  $self->{h} ||= 12;
## All groups and features now have two additional values...
## -> extent_start and extent_end so we know where to draw the boxes....

  foreach my $lname   ( sort keys %{$features->{'groups'}} ) {
    foreach my $gkey  ( sort keys %{$features->{'groups'}{$lname}} ) {
      my $group = $features->{'groups'}{$lname}{$gkey}{$ori};
      next unless $group; ### May not have group on this strand!!
## We now have a feature....
## Now let us grab all the features in the group as we need to work out the width of the "group"
## which may be wider than the feature if
##   (a) we have labels (width of label if wider than feature)
##   (b) have fixed width glyphs at points
##   (c) have histogram data - has nos to left of graph..

## Start with looking for special "aggregator glyphs"
#       foreach my $style_key ( keys %{ $group->{'features'} } ) {
      my $g_s = $features->{'g_styles'}{$lname}{$gkey};             ## Get the group style...
      my @boxes;
      my $to_join = lc( $g_s->{'symbol'} ) ne 'hidden';
      my $composite_flag   = 0;
      my $score_based_flag = 0;
      $group->{height} ||= $self->{h};
      foreach ( keys %{$group->{'features'}} ) {
        $score_based_flag = 1        if $features->{'f_styles'}{$lname}{$_}{'use_score'};               ## Composite if it is a graph!
        $composite_flag ||= $to_join if $features->{'f_styles'}{$lname}{$_}{'style'}{'bump'} ne 'yes'; ## Composite if the features are to be bumped && linked!
      }
      my($s,$e) = ($group->{extent_start}, $group->{extent_end});
      my $composite;
      if( $composite_flag || $score_based_flag ) {
        my $row = $self->bump_row( $group->{'start'}*$ppbp, $group->{'end'}*$ppbp );
        $group->{'y'} = - $strand * $row * ($self->{h}+2);
        $composite =  $self->Space({ ## Just draw a composite at the moment!
          'absolutey' => 1,
          'x'         => $s-1,
          'width'     => $e-$s+1,
          'y'         => $group->{y},
          'height'    => $self->{h},
          'colour'    => 'darkkhaki',
          'bordercolour' => 'green',
          'title'     => $group->{label}.' : '.$group->{id}
        }); ## Create a composite for the group and bump it!
      }

      foreach my $style_key (
        map  { $_->[2]                                    }
        sort { $a->[0] <=> $b->[0] || $a->[1] <=> $b->[1] }
        map  {[
          $features->{'f_styles'}{$lname}{$_}{'style'}{'zindex'}||0, ## Render in z-index order!
          $features->{'f_styles'}{$lname}{$_}{'use_score'}      ||0, ## Render non-"group features" first!
          $_                                                 ## What we want the key!!
        ]}
        keys %{$group->{'features'}}
      ) {
## Grab the style for the group of features!
        my $f_s     = $features->{'f_styles'}{$lname}{$style_key};
        $f_s->{style}{height}||=$self->{h};
        my $to_bump = lc($f_s->{'style'}{'bump'}) eq 'yes';
       
        my $fn_c = "composite_".lc($f_s->{'style'}{'symbol'});
        my $fn_g = "glyph_".lc($f_s->{'style'}{'symbol'});
        $can_hash{$fn_c} ||= $self->can($fn_c);
        $can_hash{$fn_g} ||= $self->can($fn_g) || '-' ; ## Default to drawing a box!!
        $fn_g = 'glyph_box' if $can_hash{$fn_g} eq '-';
        if( $can_hash{$fn_c} ) { ## This is one of the histogram style displays and the render fn has been defined!
          $self->$fn_c( $group, $group->{'features'}{$style_key}, $f_s->{style} );
        } else {
          if( $to_bump || !$to_join ) { ## We are bumping this feature so do not group it!
            foreach my $f ( ## Draw the features in order!
              sort { $a->start <=> $b->start }
              @{$group->{'features'}{$style_key}}
            ) { ## Draw in order!!
              ## Create glyph and bump it!!
              next unless defined $f->{'extent_start'};
              $f->{'y'} = 0;
              if( $to_bump ) {
                my $row = $self->bump_row( $f->{'extent_start'}*$ppbp, $f->{'extent_end'}*$ppbp );
                $f->{'y'} = - $strand * $row * ($self->{h}+2);
                ## reposition!
              }
              $self->push( $self->Space({
                'x'     => $f->{extent_start}-1,
                'width' => $f->{extent_end}-$f->{extent_start}+1,
                'y'     => $f->{'y'},
                'height' => $self->{'h'},
                'absolutey' => 1
              }));
              $self->$fn_g( undef, $f, $f_s->{'style'});
            }
         } else {
            ## We are grouping these features!!
            foreach my $f ( ## Draw the features in order!
              sort { $a->start <=> $b->start }
              @{$group->{'features'}{$style_key}}
            ) { ## Draw in order!!
              next unless $f->{extent_start};
              $self->$fn_g( $group, $f, $f_s->{'style'});<commit_msg>simple glyphs now have titles<commit_after>package Bio::EnsEMBL::GlyphSet_generic;

use strict;
use warnings;
no warnings 'uninitialized';
use base qw(Bio::EnsEMBL::GlyphSet);

use Data::Dumper;

sub features {
  return {
    'f_count'    => 0,
    'g_count'    => 0,
    'merge'      => 0, ## Merge all logic names into one track! note different from other systems!!
    'groups'     => {},
    'f_styles'   => {},
    'g_styles'   => {},
    'errors'     => [],
    'ss_errors'  => [],
    'urls'       => [],
    'ori'        => {},
    'max_height' => 0
  };
} 

use Bio::EnsEMBL::Feature;

sub _draw_features {
  my( $self, $ori, $features, $render_flags ) = @_;

  $self->_init_bump();

  my $strand = $self->strand;
  my %can_hash;
  my $ppbp    = $self->{ppbp} = $self->scalex;
  $self->{bppp} = 1 / $ppbp; 
  my $seq_len = $self->{'seq_len'} = $self->{'container'}->length;
#  my $h       = $self->{'h'}       = $features->{'max_height'} || 8; ## We may need to hack this to make it specific to orientation later! needs hacking in _das.pm

  $self->{'h'} = 0;
  my $colour = $ori ? 'blue' : 'green';

  foreach my $lname   ( sort keys %{$features->{'groups'}} ) {
    foreach my $gkey  ( sort keys %{$features->{'groups'}{$lname}} ) {
      my $group = $features->{'groups'}{$lname}{$gkey}{$ori};
      next unless $group;                                          ## No features from this group on this strand!
      next if $group->{'end'} < 1 || $group->{'start'} > $seq_len; ## All features in group exist outside region!

## Now loop through all features and get the extents of features - we will need this later for bumping! and joining!

      my $g_s = $features->{'g_styles'}{$lname}{$gkey};             ## Get the group style...
      my $to_join = lc( $g_s->{'symbol'} ) ne 'hidden';

      foreach my $style_key ( keys %{$group->{'features'}} ) {
        my $f_s  = $features->{'f_styles'}{$lname}{$style_key};
        my $to_bump = $f_s->{'style'}{'bump'} eq 'yes';             ## Bump if style bump is set!
        my $fn_c = "composite_extent_".$f_s->{'style'}{'symbol'};
        my $fn_g = "extent_".$f_s->{'style'}{'symbol'};
        $can_hash{$fn_c} ||= $self->can($fn_c);
        $can_hash{$fn_g} ||= $self->can($fn_g) || '-';
        $fn_g = 'extent_box' if $can_hash{$fn_g} eq '-'; ## default to drawing a box!!
        if( $can_hash{$fn_c} ) { ## This is one of the histogram style displays and the render fn has been defined!
          $self->$fn_c( $group, $f_s->{style} );
        } else {
          foreach my $f ( @{$group->{'features'}{$style_key}} ) { # Compute the extent of each glyph - and add to extent of group if not bumped!
## Only pass the glyph if we are going to put this glyph in a composite
            $self->$fn_g( $to_join && !$to_bump ? $group : undef, $f, $f_s->{style} );
          }
        }
        $group->{height} = $g_s->{style}{height} if $g_s->{style}{height} > $group->{height} && $group->{extent_start};
        $self->{h} = $g_s->{style}{height} if $g_s->{style}{height} > $self->{h} && $group->{extent_start};
      }
    }
  }
  $self->{h} ||= 12;
## All groups and features now have two additional values...
## -> extent_start and extent_end so we know where to draw the boxes....

  foreach my $lname   ( sort keys %{$features->{'groups'}} ) {
    foreach my $gkey  ( sort keys %{$features->{'groups'}{$lname}} ) {
      my $group = $features->{'groups'}{$lname}{$gkey}{$ori};
      next unless $group; ### May not have group on this strand!!
## We now have a feature....
## Now let us grab all the features in the group as we need to work out the width of the "group"
## which may be wider than the feature if
##   (a) we have labels (width of label if wider than feature)
##   (b) have fixed width glyphs at points
##   (c) have histogram data - has nos to left of graph..

## Start with looking for special "aggregator glyphs"
#       foreach my $style_key ( keys %{ $group->{'features'} } ) {
      my $g_s = $features->{'g_styles'}{$lname}{$gkey};             ## Get the group style...
      my @boxes;
      my $to_join = lc( $g_s->{'symbol'} ) ne 'hidden';
      my $composite_flag   = 0;
      my $score_based_flag = 0;
      $group->{height} ||= $self->{h};
      foreach ( keys %{$group->{'features'}} ) {
        $score_based_flag = 1        if $features->{'f_styles'}{$lname}{$_}{'use_score'};               ## Composite if it is a graph!
        $composite_flag ||= $to_join if $features->{'f_styles'}{$lname}{$_}{'style'}{'bump'} ne 'yes'; ## Composite if the features are to be bumped && linked!
      }
      my($s,$e) = ($group->{extent_start}, $group->{extent_end});
      my $composite;
      if( $composite_flag || $score_based_flag ) {
        my $row = $self->bump_row( $group->{'start'}*$ppbp, $group->{'end'}*$ppbp );
        $group->{'y'} = - $strand * $row * ($self->{h}+2);
        $composite =  $self->Space({ ## Just draw a composite at the moment!
          'absolutey' => 1,
          'x'         => $s-1,
          'width'     => $e-$s+1,
          'y'         => $group->{y},
          'height'    => $self->{h},
          'colour'    => 'darkkhaki',
          'bordercolour' => 'green',
          'title'     => $group->{label}.' : '.$group->{id}
        }); ## Create a composite for the group and bump it!
      }

      foreach my $style_key (
        map  { $_->[2]                                    }
        sort { $a->[0] <=> $b->[0] || $a->[1] <=> $b->[1] }
        map  {[
          $features->{'f_styles'}{$lname}{$_}{'style'}{'zindex'}||0, ## Render in z-index order!
          $features->{'f_styles'}{$lname}{$_}{'use_score'}      ||0, ## Render non-"group features" first!
          $_                                                 ## What we want the key!!
        ]}
        keys %{$group->{'features'}}
      ) {
## Grab the style for the group of features!
        my $f_s     = $features->{'f_styles'}{$lname}{$style_key};
        $f_s->{style}{height}||=$self->{h};
        my $to_bump = lc($f_s->{'style'}{'bump'}) eq 'yes';
       
        my $fn_c = "composite_".lc($f_s->{'style'}{'symbol'});
        my $fn_g = "glyph_".lc($f_s->{'style'}{'symbol'});
        $can_hash{$fn_c} ||= $self->can($fn_c);
        $can_hash{$fn_g} ||= $self->can($fn_g) || '-' ; ## Default to drawing a box!!
        $fn_g = 'glyph_box' if $can_hash{$fn_g} eq '-';
        if( $can_hash{$fn_c} ) { ## This is one of the histogram style displays and the render fn has been defined!
          $self->$fn_c( $group, $group->{'features'}{$style_key}, $f_s->{style} );
        } else {
          if( $to_bump || !$to_join ) { ## We are bumping this feature so do not group it!
            foreach my $f ( ## Draw the features in order!
              sort { $a->start <=> $b->start }
              @{$group->{'features'}{$style_key}}
            ) { ## Draw in order!!
              ## Create glyph and bump it!!
              next unless defined $f->{'extent_start'};
              $f->{'y'} = 0;
              if( $to_bump ) {
                my $row = $self->bump_row( $f->{'extent_start'}*$ppbp, $f->{'extent_end'}*$ppbp );
                $f->{'y'} = - $strand * $row * ($self->{h}+2);
                ## reposition!
              }
              $self->push( $self->Space({
                'x'     => $f->{extent_start}-1,
                'width' => $f->{extent_end}-$f->{extent_start}+1,
                'y'     => $f->{'y'},
                'height' => $self->{'h'},
                'absolutey' => 1,
                'title' => $f->display_label.' : '.$f->display_id
              }));
              $self->$fn_g( undef, $f, $f_s->{'style'});
            }
         } else {
            ## We are grouping these features!!
            foreach my $f ( ## Draw the features in order!
              sort { $a->start <=> $b->start }
              @{$group->{'features'}{$style_key}}
            ) { ## Draw in order!!
              next unless $f->{extent_start};
              $self->$fn_g( $group, $f, $f_s->{'style'});
{'fraction_non_alphanumeric': 0.20176592147285366, 'fraction_numerical': 0.0036320370718266643, 'mean_word_length': 2.197837404885863, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 286, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4905840', 'n_tokens_mistral': 5576, 'n_tokens_neox': 5445, 'n_words': 1388}