package LIMS::Local::GalliumData; # for use with gallium_data.pl (supercedes GalliumTrial for use with # gallium_data_roche.pl & gallium_data_quintiles.pl) use Moo; use LIMS::Local::MooX::Types qw(HashReference); has data => ( is => 'ro', isa => HashReference, required => 1 ); use Data::Dumper; use LIMS::Local::Utils; my $trim = sub { LIMS::Local::Utils::trim(@_) }; #=============================================================================== use Regexp::Common qw(pattern); # Regexp::Common patterns: pattern # biopsy type name => [ qw(biopsy type) ], create => 'Type of biopsy\:\s*(\b\w+\b(\s\b\w+\b?)+)'; # matches 1 or more words pattern # % lymphoma involvement name => [ qw(lymphoma involvement) ], create => 'Marrow involvement\:\s*(\d+?)%'; # capture digits before % pattern # discrepant diagnosis name => [ qw(discrepant diagnosis) ], create => 'Discrepant diagnosis\:\s*(\b\w+\b)'; # capture word pattern # discrepant localisation name => [ qw(discrepant localisation) ], create => 'Discrepant localisation\:\s*(\b\w+\b)'; # capture word pattern # trial eligibility name => [ qw(trial eligible) ], create => 'Eligible for trial\:\s*(\b\w+\b)'; # capture word pattern # lymphoma grade name => [ qw(lymphoma grade) ], # "Lymphoma grade: xn" OR "grade xn" : create => '\b(?:Lymphoma )?grade(?:[\s\:]+)?(\d\w?)\b'; # 1,2,3[ab] pattern # dna volume name => [ qw(dna volume) ], create => 'DNA volume\:(.*)ul'; # DNA volume\:(.*)ul pattern # dna concentration name => [ qw(dna concentration) ], create => 'DNA concentration\:(.*)ng'; pattern # dna purity name => [ qw(dna purity) ], create => 'DNA purity OD260\/280\:\s*(\d*\.\d+)'; pattern # dna sections name => [ qw(dna sections) ], create => 'DNA sections\:(.*)micron'; pattern # rna volume name => [ qw(rna volume) ], create => 'RNA volume\:(.*)ul'; # DNA volume\:(.*)ul pattern # rna concentration name => [ qw(rna concentration) ], create => 'RNA concentration\:(.*)ng'; pattern # rna purity name => [ qw(rna purity) ], create => 'RNA purity OD260\/280\:\s?(\d*\.\d+)'; pattern # rna sections name => [ qw(rna sections) ], create => 'RNA sections\:(.*)micron'; pattern # tma status name => [ qw(tma status) ], create => 'TMA taken\:\s*(\b\w+\b( \b\w+\b)?)'; # matches 1 or 2 words pattern # tma position name => [ qw(tma position) ], # 1st number = block, then 2 core positions: create => 'Position on TMA\:\s*(\d{1,2}\w\d\w\d)'; # [A1 - J5, eg 2A1B2] pattern # tma cores name => [ qw(tma cores) ], create => 'No. of TMA cores\:\s*(\d)'; # single digit pattern # IgH-ASO assay name => [ qw(igh_aso assay) ], create => 'IgH-ASO assay\:\s*(\b\w+\b( \b\w+\b)?)'; # matches 1 or 2 words pattern # IgH-ASO result name => [ qw(igh_aso result) ], create => 'IgH-ASO result\:\s*(not evaluable|(mono|oligo|poly)clonal)'; pattern # IgH-ASO bp length name => [ qw(igh_aso bp_length) ], create => 'IgH-ASO bp length\:\s*(\d+)'; pattern # IgH-ASO comment name => [ qw(igh_aso comment) ], create => 'IgH-ASO comment\:\s*(.*)'; #=============================================================================== sub get_lab_role { my $self = shift; my $source = $self->data->{source}; my $result = $source =~ /^Kiel/i # query now exclusively source = Quintiles ? 'Adjudicator' : 'First Time Reviewer'; return $result; } # extract block ref + number of slides & blocks from external_ref: sub get_external_reference { my $self = shift; my $exref = $self->data->{external_reference} or return 0; # just capture 1st item of block_ref eg (125-16696) x20uss my ($block_ref) = split /\sx(:?\d+)[spu]/, $exref; # warn $block_ref; my ($unstained_slides) = $exref =~ /x(\d+)uss/; # warn $unstained_slides my ($stained_slides) = $exref =~ /x(\d+)ss/; # warn $stained_slides my ($blocks) = $exref =~ /x(\d+)p/; # warn $blocks; my $slides = do { no warnings 'uninitialized'; $unstained_slides + $stained_slides; }; # warn Dumper [$block_ref, $slides, $blocks]; my %h = ( block_id => &$trim($block_ref), slides => $slides || 0, blocks => $blocks || 0, ); return \%h; } sub get_dna_results { my $self = shift; my %h = (); if ( my $result = $self->data->{molecular_summary} ) { if ( $result =~ $RE{dna}{volume}{-keep} ) { # warn $1; $h{dna_volume} = &$trim($1); } if ( $result =~ $RE{dna}{concentration}{-keep} ) { # warn $1; $h{dna_concentration} = &$trim($1); } if ( $result =~ $RE{dna}{purity}{-keep} ) { # warn $1; $h{dna_purity} = $1; } if ( $result =~ $RE{dna}{sections}{-keep} ) { # warn $1 $h{dna_sections} = &$trim($1); } } # warn Dumper \%h; return \%h; } sub get_rna_results { my $self = shift; my %h = (); if ( my $result = $self->data->{molecular_summary} ) { if ( $result =~ $RE{rna}{volume}{-keep} ) { # warn $1; $h{rna_volume} = &$trim($1); } if ( $result =~ $RE{rna}{concentration}{-keep} ) { # warn $1; $h{rna_concentration} = &$trim($1); } if ( $result =~ $RE{rna}{purity}{-keep} ) { # warn $1; $h{rna_purity} = $1; } if ( $result =~ $RE{rna}{sections}{-keep} ) { # warn $1 $h{rna_sections} = &$trim($1); } } # warn Dumper \%h; return \%h; } sub get_tma_results { my $self = shift; my %h = (); if ( my $result = $self->data->{immunohistochemistry_summary} ) { if ( $result =~ $RE{tma}{status}{-keep} ) { # warn $1; $h{tma_status} = &$trim($1); } if ( $result =~ $RE{tma}{position}{-keep} ) { # warn $1; my ($block, $core_positions) = $1 =~ /(\d{1,2})(\w\d\w\d)/; # eg 2A2A4 $h{tma_position} = $core_positions; $h{tma_block} = $block; # block number } if ( $result =~ $RE{tma}{cores}{-keep} ) { # warn $1; $h{tma_cores} = &$trim($1); } } # warn Dumper \%h; return \%h; } sub get_igh_pcr { my $self = shift; my %h = (); if ( my $result = $self->data->{molecular_summary} ) { if ( $result =~ $RE{igh_aso}{assay}{-keep} ) { # warn $1; $h{igh_pcr_assay} = &$trim($1); } if ( $result =~ $RE{igh_aso}{result}{-keep}{-i} ) { # warn $1; $h{igh_pcr_result} = lc &$trim($1); } if ( $result =~ $RE{igh_aso}{bp_length}{-keep} ) { # warn $1; $h{igh_pcr_bp_length} = $1; } if ( $result =~ $RE{igh_aso}{comment}{-keep} ) { # warn $1; $h{igh_pcr_comment} = &$trim($1); } } # warn Dumper \%h; return \%h; } sub get_fish_break_apart_result { my $self = shift; my $col = shift; my $val = $self->data->{$col} || return 0; my $result = $val =~ /rearranged/ ? 'Positive' : $val eq 'failed' ? 'Not Evaluable' : 'Negative'; return $result; } sub get_fish_fusion_assay_result { my $self = shift; my $col = shift; my $val = $self->data->{$col} || return 0; my $result = $val =~ /translocation/ ? 'Positive' : $val eq 'failed' ? 'Not Evaluable' : 'Negative'; return $result; } sub get_biopsy_type { # FINE NEEDLE ASPIRATION / CORE BIOPSY / SURGICAL EXCISION / OTHER my $self = shift; if ( $self->data->{comment} =~ $RE{biopsy}{type}{-keep} ) { return $1; } return 0; } sub get_lymphoma_grade { my $self = shift; my $comment = $self->data->{comment}; my $icdo3 = $self->data->{icdo3} || return 0; if ( $icdo3 =~ /^9698/ ) { # Follicular lymphoma; large cell - automatically 3B return '3b'; } # extract grade - only if FL: elsif ( $icdo3 =~ /^9690/ && $comment =~ $RE{lymphoma}{grade}{-keep} ) { return $1; } return 0; } sub get_trial_elegibility { # [YES/NO/PENDING] my $self = shift; if ( $self->data->{comment} =~ $RE{trial}{eligible}{-keep} ) { return $1; } else { # diagnosis FL - common, SMZL or EMZL: no warnings 'uninitialized'; return $self->get_icdo3 =~ /^96(89|90|99)/ ? 'YES' : 'NO'; } } sub get_diagnosis { my $self = shift; return $self->data->{diagnosis}; # required to be authorised so will exist } sub get_icdo3 { my $self = shift; return $self->data->{icdo3} || 0; } sub get_lymphoma_involvement { my $self = shift; if ( $self->data->{comment} =~ $RE{lymphoma}{involvement}{-keep} ) { return $1; # numerical } return undef; # don't return 0 - valid result !! } sub get_test_results { my ($self, $markers) = @_; # list of IHC markers my %h = (); for my $t(@$markers) { my $result = $self->data->{$t}; $h{$t} = $result if defined $result; # can be zero }; # warn Dumper \%h; return \%h; } sub is_discrepant_diagnosis { my $self = shift; if ( $self->data->{comment} =~ $RE{discrepant}{diagnosis}{-keep} ) { return $1; } return 0; } sub is_discrepant_localisation { my $self = shift; if ( $self->data->{comment} =~ $RE{discrepant}{localisation}{-keep} ) { return $1; } return 0; } 1;