<commit_before>package Sanger::CGP::Pindel::InputGen::SamHeader;

use strict;
use English qw( -no_match_vars );
use autodie qw(:all);
use warnings FATAL => 'all';
use Const::Fast qw(const);
use Carp qw( croak );

use Sanger::CGP::Pindel;
our $VERSION = Sanger::CGP::Pindel->VERSION;

use PCAP::Bam::Bas;

const my $DEFAULT_PI => 500;

sub new {
  my ($class, $bam) = @_;
  my $self = {'header_lines' => [],};
  $self->{'bas'} = PCAP::Bam::Bas->new("$bam.bas") if(defined $bam && -e "$bam.bas");
  bless $self, $class;
  return $self;
}

sub add_header_line {
  my ($self, $line) = @_;
  croak "add_header_line requires value for 'line'" unless(defined $line);
  chomp $line;
  croak "add_header_line received blank input" unless(length $line > 0);
  croak "add_header_line appears to have received invalid input $line" if($line !~ m/^\@/);
  return 1 if($line !~ m/^\@RG/);
  push @{$self->{'header_lines'}}, $line;
  return 1;
}

sub rgs_to_offsets_and_sample_name {
  my ($self, $force) = @_;
  if(scalar @{$self->{'header_lines'}} == 0) {
    die "No header information has been provided in the BAM file" unless($force);
    return {'.' => $DEFAULT_PI};
  }

  my %rgs;
  my $sample_name;
  for my $rg( @{$self->{'header_lines'}} ) {
    my ($rg_id) = $rg =~ m/\tID:([^\t]+)/;
    die "Readgroup line has no ID:\n\n$rg\n" unless(defined $rg_id);
    my $median_insert;
    if(exists $self->{'bas'}) {
      $median_insert = $self->{'bas'}->get($rg_id, 'median_insert_size');
      die "BAS file is present but no median_insert_size found for RG:ID $rg_id\n" unless(defined $median_insert);
      $median_insert = int $median_insert;
    }
    else {
      ($median_insert) = $rg =~ m/\tPI:([[:digit:]]+)/;
      if(!defined $median_insert) {
        warn "No PI tag found for RG:ID $rg_id in BAM header.";
        $median_insert = $DEFAULT_PI;
      }
    }
    die "BAM file has multiple RG lines with ID of: $rg_id" if(exists $rgs{$rg_id});
    $rgs{$rg_id} = $median_insert;

    my ($sample_tmp) = $rg =~ m/\SM:([^\t]+)/;
    if(defined $sample_name) {
      die "Different sample names found in RG lines, $sample_name vs. $sample_tmp" if($sample_name ne $sample_tmp);
    }
    else {
      $sample_name = $sample_tmp
    }
  }
  my $rg_str = q{};
  for (keys %rgs) {
    $rg_str .= "$_:$rgs{$_},";<commit_msg>Fixes #3, missing 't' causing first non-space character folowed by 'M:' to be matched, didn't fail when PM didn't preceed SM<commit_after>package Sanger::CGP::Pindel::InputGen::SamHeader;

use strict;
use English qw( -no_match_vars );
use autodie qw(:all);
use warnings FATAL => 'all';
use Const::Fast qw(const);
use Carp qw( croak );

use Sanger::CGP::Pindel;
our $VERSION = Sanger::CGP::Pindel->VERSION;

use PCAP::Bam::Bas;

const my $DEFAULT_PI => 500;

sub new {
  my ($class, $bam) = @_;
  my $self = {'header_lines' => [],};
  $self->{'bas'} = PCAP::Bam::Bas->new("$bam.bas") if(defined $bam && -e "$bam.bas");
  bless $self, $class;
  return $self;
}

sub add_header_line {
  my ($self, $line) = @_;
  croak "add_header_line requires value for 'line'" unless(defined $line);
  chomp $line;
  croak "add_header_line received blank input" unless(length $line > 0);
  croak "add_header_line appears to have received invalid input $line" if($line !~ m/^\@/);
  return 1 if($line !~ m/^\@RG/);
  push @{$self->{'header_lines'}}, $line;
  return 1;
}

sub rgs_to_offsets_and_sample_name {
  my ($self, $force) = @_;
  if(scalar @{$self->{'header_lines'}} == 0) {
    die "No header information has been provided in the BAM file" unless($force);
    return {'.' => $DEFAULT_PI};
  }

  my %rgs;
  my $sample_name;
  for my $rg( @{$self->{'header_lines'}} ) {
    my ($rg_id) = $rg =~ m/\tID:([^\t]+)/;
    die "Readgroup line has no ID:\n\n$rg\n" unless(defined $rg_id);
    my $median_insert;
    if(exists $self->{'bas'}) {
      $median_insert = $self->{'bas'}->get($rg_id, 'median_insert_size');
      die "BAS file is present but no median_insert_size found for RG:ID $rg_id\n" unless(defined $median_insert);
      $median_insert = int $median_insert;
    }
    else {
      ($median_insert) = $rg =~ m/\tPI:([[:digit:]]+)/;
      if(!defined $median_insert) {
        warn "No PI tag found for RG:ID $rg_id in BAM header.";
        $median_insert = $DEFAULT_PI;
      }
    }
    die "BAM file has multiple RG lines with ID of: $rg_id" if(exists $rgs{$rg_id});
    $rgs{$rg_id} = $median_insert;

    my ($sample_tmp) = $rg =~ m/\tSM:([^\t]+)/;
    if(defined $sample_name) {
      die "Different sample names found in RG lines, $sample_name vs. $sample_tmp" if($sample_name ne $sample_tmp);
    }
    else {
      $sample_name = $sample_tmp
    }
  }
  my $rg_str = q{};
  for (keys %rgs) {
    $rg_str .= "$_:$rgs{$_},";
{'fraction_non_alphanumeric': 0.18513058129738838, 'fraction_numerical': 0.0031592249368155014, 'mean_word_length': 3.6106796116504856, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, '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': '6979822', 'n_tokens_mistral': 1866, 'n_tokens_neox': 1804, 'n_words': 471}