Skip to content

Commit

Permalink
Merge branch 'devel' of github.com:htgt/LIMS2-WebApp into devel
Browse files Browse the repository at this point in the history
  • Loading branch information
tgrego committed Feb 26, 2015
2 parents 3b54779 + cae01be commit d8cb1f9
Show file tree
Hide file tree
Showing 20 changed files with 1,769 additions and 70 deletions.
1 change: 1 addition & 0 deletions ddl/versions/83/up.sql
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ ALTER TABLE designs ADD foreign key (nonsense_design_crispr_id) references crisp

ALTER TABLE crisprs ADD COLUMN nonsense_crispr_original_crispr_id INT;
ALTER TABLE crisprs ADD foreign key (nonsense_crispr_original_crispr_id) references crisprs(id);

1 change: 1 addition & 0 deletions ddl/versions/84/fixtures.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
INSERT INTO schema_versions(version) VALUES (84);
3 changes: 3 additions & 0 deletions ddl/versions/84/up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
alter table crispr_primers drop constraint "crispr_id and primer name must be unique";
alter table crispr_primers drop constraint "crispr_pair_id and primer name must be unique";
alter table crispr_primers drop constraint "crispr_group_id and and primer_name must be unique";
214 changes: 203 additions & 11 deletions lib/LIMS2/Model/Plugin/Primer.pm
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,90 @@ sub retrieve_crispr_primer {
return $crispr_primer;
}

# Retrieve only the crispr primer where the is_rejected flag is not set to true
# There should be only one of these but this is constrained in the model
# rather than the database so it may not always be the case
sub retrieve_current_crispr_primer{
my ( $self, $params ) = @_;

my $validated_params = $self->check_params( $params, $self->pspec_retrieve_crispr_primer );

my %params = slice_def $validated_params,
qw( crispr_id crispr_pair_id crispr_group_id primer_name );

$params{is_rejected} = [0, undef];

my $crispr_primer = $self->retrieve(
CrisprPrimer => \%params,
);

return $crispr_primer;

}

sub pspec_create_primer_common {
return {
primer_seq => { validate => 'dna_seq' },
tm => { validate => 'numeric', optional => 1 },
gc_content => { validate => 'numeric', optional => 1 },
locus => { validate => 'hashref' },
overwrite => { validate => 'boolean', optional => 1, default => 0 },
check_for_rejection => { validate => 'boolean', optional => 1, default => 0 },
};
}

# pspec_create_genotyping_primer already exists in WebApp Common hence slightly odd name here
sub pspec_create_genotyping_primer_lims2{
my $common = pspec_create_primer_common;
return {
%$common,
design_id => { validate => 'integer' },
primer_name => { validate => 'existing_genotyping_primer_type' }
};
}

=head2 create_genotyping_primer
Like create_crispr_primer.. but for genotyping primers which are linked to a design
=cut
sub create_genotyping_primer{
my ($self, $params) = @_;

my $validated_params = $self->check_params( $params, $self->pspec_create_genotyping_primer_lims2 );

my $ready_to_create = $self->_handle_existing_primers('GenotypingPrimer', $validated_params);

my $primer;
if($ready_to_create){
$primer = $self->schema->resultset('GenotypingPrimer')->create({
genotyping_primer_type_id => $validated_params->{primer_name},
seq => $validated_params->{primer_seq},
slice_def(
$validated_params,
qw( design_id tm gc_content )
)
});

$self->log->debug( 'Create primer ' . $primer->id );

my $locus_params = $validated_params->{locus};
$locus_params->{genotyping_primer_id} = $primer->id;
$self->create_genotyping_primer_locus( $locus_params, $primer );
}

return $primer;
}

sub pspec_create_crispr_primer {
my $common = pspec_create_primer_common;
return {
%$common,
crispr_id => { validate => 'integer', optional => 1 },
crispr_pair_id => { validate => 'integer', optional => 1 },
crispr_group_id => { validate => 'integer', optional => 1 },
primer_name => { validate => 'existing_crispr_primer_type' },
primer_seq => { validate => 'dna_seq' },
tm => { validate => 'numeric', optional => 1 },
gc_content => { validate => 'numeric', optional => 1 },
locus => { validate => 'hashref' },

REQUIRE_SOME => { single_pair_or_group_crispr_id =>
[ 1, qw( crispr_id crispr_pair_id crispr_group_id ) ] },
};
Expand All @@ -54,27 +128,105 @@ sub pspec_create_crispr_primer {
Create a crispr primer record, along with its locus.
First check to see crispr does not already have primer of same type.
To overwrite the existing primer use overwrite = 1
To check if this primer seq has previously been rejected before creating it
use check_for_rejection = 1
You should run this in a txn_do
=cut
sub create_crispr_primer {
my ( $self, $params ) = @_;

my $validated_params = $self->check_params( $params, $self->pspec_create_crispr_primer );

my $crispr_primer = $self->schema->resultset('CrisprPrimer')->create(
{ slice_def(
my $ready_to_create = $self->_handle_existing_primers('CrisprPrimer', $validated_params);

my $crispr_primer;
if($ready_to_create){
$crispr_primer = $self->schema->resultset('CrisprPrimer')->create({
slice_def(
$validated_params,
qw( crispr_id crispr_pair_id crispr_group_id
primer_seq primer_name tm gc_content
)
)
}
});

$self->log->debug( 'Create crispr primer ' . $crispr_primer->id );

my $locus_params = $validated_params->{locus};
$locus_params->{crispr_oligo_id} = $crispr_primer->id;
$self->create_crispr_primer_locus( $locus_params, $crispr_primer );
}

return $crispr_primer;
}

# Decide how to handle existing CrisprPrimers or GenotypingPrimers using common logic
# and overwrite/check_for_rejection flag parameters
sub _handle_existing_primers{
my ($self, $resultset, $validated_params) = @_;
my $ready_to_create = 0;

my %search_params = slice_def( $validated_params,
qw( crispr_id crispr_pair_id crispr_group_id design_id primer_name)
);
$self->log->debug( 'Create crispr primer ' . $crispr_primer->id );

my $locus_params = $validated_params->{locus};
$locus_params->{crispr_oligo_id} = $crispr_primer->id;
$self->create_crispr_primer_locus( $locus_params, $crispr_primer );
# Bit of a hack because primer_name in CrisprPrimer == genotyping_primer_type_id in GenotypingPrimer
if($resultset eq 'GenotypingPrimer'){
$search_params{genotyping_primer_type_id} = $search_params{primer_name};
delete $search_params{primer_name};
}

my @existing_primers = $self->schema->resultset($resultset)->search(\%search_params)->all;
my %rejected_seqs;
my @current_primers;
foreach my $existing (@existing_primers){
if($existing->is_rejected){
my $seq = uc($existing->primer_seq);
$rejected_seqs{$seq} = 1;
}
else{
push @current_primers, $existing;
}
}

if(@current_primers){
$self->log->debug("Existing $resultset found");
unless($validated_params->{overwrite}){
$self->throw( Validation => 'Primer '.$validated_params->{primer_name}.' already exists' );
}

if($validated_params->{check_for_rejection}){
$self->_check_for_rejection($validated_params->{primer_seq}, \%rejected_seqs);
}

# If method has not died yet it is time to remove existing and create new primer
foreach my $existing (@current_primers){
$self->log->debug('Deleting existing primer '.$existing->id);
$existing->delete;
}
$ready_to_create = 1;
}
else{
if($validated_params->{check_for_rejection}){
$self->_check_for_rejection($validated_params->{primer_seq}, \%rejected_seqs);
}

# If method has not died we can go ahead and create the primer
$ready_to_create = 1;
}
return $ready_to_create;
}

sub _check_for_rejection{
my ($self, $seq, $rejected_seqs) = @_;
$seq = uc($seq);
$self->log->debug('Checking if new primer seq has previously been rejected');
if($rejected_seqs->{$seq}){
$self->throw( Validation => "Primer with sequence $seq has previously been rejected" );
}
return;
}

Expand Down Expand Up @@ -119,6 +271,46 @@ sub create_crispr_primer_locus {
return $crispr_primer_locus;
}

sub pspec_create_genotyping_primer_locus {
return {
assembly => { validate => 'existing_assembly' },
chr_name => { validate => 'existing_chromosome' },
chr_start => { validate => 'integer' },
chr_end => { validate => 'integer' },
chr_strand => { validate => 'strand' },
genotyping_primer_id => { validate => 'integer' },
};
}

=head2 create_genotyping_primer_locus
Create locus record for a genotyping primer, for a given assembly
=cut
sub create_genotyping_primer_locus {
my ( $self, $params, $primer ) = @_;

my $validated_params = $self->check_params( $params, $self->pspec_create_genotyping_primer_locus );
$self->trace( "Create genotyping primer locus", $validated_params );

$primer ||= $self->schema->resultset( 'GenotypingPrimer' )->find(
{
id => $validated_params->{genotyping_primer_id},
}
);

my $primer_locus = $primer->create_related(
genotyping_primer_loci => {
assembly_id => $validated_params->{assembly},
chr_id => $self->_chr_id_for( @{$validated_params}{ 'assembly', 'chr_name' } ),
chr_start => $validated_params->{chr_start},
chr_end => $validated_params->{chr_end},
chr_strand => $validated_params->{chr_strand}
}
);

return $primer_locus;
}
1;

__END__
19 changes: 19 additions & 0 deletions lib/LIMS2/Model/Schema/Result/Crispr.pm
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,15 @@ sub current_locus {
return $loci;
}

sub gene_id {
my $self = shift;
my $crispr_design = $self->crispr_designs->first
or return;
my $genes = $crispr_design->design->genes
or return;
return $genes->first->gene_id;
}

sub start {
return shift->current_locus->chr_start;
}
Expand All @@ -427,6 +436,16 @@ sub chr_name {
return shift->current_locus->chr->name;
}

sub default_assembly{
return shift->species->default_assembly;
}

# The name of the foreign key column to use when
# linking e.g. a crispr_primer to a crispr
sub id_column_name{
return 'crispr_id';
}

sub target_slice {
my ( $self, $ensembl_util ) = @_;

Expand Down
4 changes: 2 additions & 2 deletions lib/LIMS2/Model/Schema/Result/CrisprEsQcWell.pm
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ sub get_crispr_primers {

#return a resultset of all the relevant crispr primers
return $self->result_source->schema->resultset('CrisprPrimer')->search(
{ $field => $analysis_data->{crispr_id} },
{ $field => $analysis_data->{crispr_id}, is_rejected => [0, undef] },
{ order_by => { -asc => 'me.primer_name' } }
);
}
Expand Down Expand Up @@ -415,7 +415,7 @@ sub format_alignment_strings {

return { forward => 'No Read', reverse => 'No Read' } if $json->{no_reads};
return { forward => 'No valid crispr pair', reverse => 'No valid crispr pair' } if $json->{no_crispr};
if ( $json->{forward_no_alignment} && $json->{forward_no_alignment} ) {
if ( $json->{forward_no_alignment} && $json->{reverse_no_alignment} ) {
if ( !$self->fwd_read ) {
return { forward => 'No Read', no_reverse_alignment => 1 };
}
Expand Down
17 changes: 17 additions & 0 deletions lib/LIMS2/Model/Schema/Result/CrisprGroup.pm
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,23 @@ sub species {
return shift->right_most_crispr->species_id;
}

# Added species_id method to CrisprPair and CrisprGroup to fetch
# the species_id (name string) so it is equivalent to Crispr->species_id
# (Crispr->species returns the Species object)
sub species_id {
return shift->right_most_crispr->species_id;
}

sub default_assembly{
return shift->right_most_crispr->default_assembly;
}

# The name of the foreign key column to use when
# linking e.g. a crispr_primer to a crispr_group
sub id_column_name{
return 'crispr_group_id';
}

sub target_slice {
my ( $self, $ensembl_util ) = @_;

Expand Down
23 changes: 23 additions & 0 deletions lib/LIMS2/Model/Schema/Result/CrisprPair.pm
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,19 @@ sub target_slice {
return $slice;
}

sub gene_id {
my $self = shift;
my $crispr_designs = $self->crispr_designs
or return;
my $genes = $crispr_designs->first->design->genes
or return;
return $genes->first->gene_id;
}

sub species_id {
return shift->right_crispr->species_id;
}

sub start {
return shift->left_crispr_locus->chr_start;
}
Expand All @@ -246,6 +259,16 @@ sub chr_name {
return shift->right_crispr_locus->chr->name;
}

sub default_assembly {
return shift->left_crispr->default_assembly;
}

# The name of the foreign key column to use when
# linking e.g. a crispr_primer to a crispr_pair
sub id_column_name{
return 'crispr_pair_id';
}

sub is_pair { return 1; }

sub is_group { return; }
Expand Down
Loading

0 comments on commit d8cb1f9

Please sign in to comment.