Skip to content

Commit

Permalink
The beginnings of the allele request factory
Browse files Browse the repository at this point in the history
  • Loading branch information
Ray Miller committed Jul 30, 2012
1 parent d97bf86 commit 8dec4d2
Show file tree
Hide file tree
Showing 6 changed files with 298 additions and 14 deletions.
8 changes: 5 additions & 3 deletions ddl/templates/versions/8/fixtures.sql
Expand Up @@ -9,19 +9,21 @@ VALUES ('Core', 'Homozygous - Core'),
('Cre BAC', 'EUCOMMTools-Cre BAC'),
('Human','Homozygous - Human');

INSERT INTO mutation_type(mutation_type)
INSERT INTO mutation_types(mutation_type)
VALUES ('conditional'),
('deletion'),
('insertion');

INSERT INTO targeting_type(targeting_type)
INSERT INTO targeting_types(targeting_type)
VALUES ('single_targeting'),
('double_targeting'),
('modified_bac_insertion');

INSERT INTO final_cassette_function(final_cassette_function)
INSERT INTO cassette_functions(final_cassette_function)
VALUES ('knockout_first'),
('reporter_only'),
('conditional_only'),
('cre_expressor'),
('promoterless_cre_expressor');

[% FOR cassette IN
33 changes: 22 additions & 11 deletions ddl/templates/versions/8/up.sql
Expand Up @@ -9,23 +9,34 @@ CREATE TABLE sponsors (
GRANT SELECT ON sponsors TO "[% ro_role %]";
GRANT SELECT, INSERT, UPDATE, DELETE ON sponsors TO "[% rw_role %]";

CREATE TABLE mutation_type (
-- XXX at the very least, need unique key on mutation_type, targeting_type, cassette_function
-- Should we dispense with the SERIAL id column on these tables?

CREATE TABLE mutation_types (
id SERIAL PRIMARY KEY,
mutation_type TEXT NOT NULL
);
GRANT SELECT ON mutation_type TO "[% ro_role %]";
GRANT SELECT, INSERT, UPDATE, DELETE ON mutation_type TO "[% rw_role %]";
GRANT SELECT ON mutation_types TO "[% ro_role %]";
GRANT SELECT, INSERT, UPDATE, DELETE ON mutation_types TO "[% rw_role %]";

CREATE TABLE targeting_type (
CREATE TABLE targeting_types (
id SERIAL PRIMARY KEY,
targeting_type TEXT NOT NULL
);
GRANT SELECT ON targeting_type TO "[% ro_role %]";
GRANT SELECT, INSERT, UPDATE, DELETE ON targeting_type TO "[% rw_role %]";
GRANT SELECT ON targeting_types TO "[% ro_role %]";
GRANT SELECT, INSERT, UPDATE, DELETE ON targeting_types TO "[% rw_role %]";

CREATE TABLE cassette_functions (
id SERIAL PRIMARY KEY,
cassette_function TEXT NOT NULL
);
GRANT SELECT ON cassette_functions TO "[% ro_role %]";
GRANT SELECT, INSERT, UPDATE, DELETE ON cassette_functions TO "[% rw_role %]";

CREATE TABLE final_cassette_function (
id SERIAL PRIMARY KEY,
final_cassette_function TEXT NOT NULL
CREATE TABLE cassette_cassette_functions (
cassette_id INTEGER NOT NULL REFERENCES cassettes(id),
function_id INTEGER NOT NULL REFERENCES cassette_functions(id),
PRIMARY KEY(cassette_id,function_id)
);
GRANT SELECT ON final_cassette_function TO "[% ro_role %]";
GRANT SELECT, INSERT, UPDATE, DELETE ON final_cassette_function TO "[% rw_role %]";
GRANT SELECT ON cassette_cassette_functions TO "[% ro_role %]";
GRANT SELECT, INSERT, UPDATE, DELETE ON cassette_cassette_functions TO "[% rw_role %]";
89 changes: 89 additions & 0 deletions lib/LIMS2/AlleleRequest.pm
@@ -0,0 +1,89 @@
package LIMS2::AlleleRequest;

use strict;
use warnings FATAL => 'all';

use Moose;
use MooseX::ClassAttribute;
use List::MoreUtils qw( any );
use namespace::autoclean;

class_has handled_targeting_types => (
is => 'ro',
isa => 'ArrayRef[Str]',
default => sub { [] }
);

sub handles {
my ( $class, $targeting_type ) = @_;

return any { $_ eq $targeting_type } @{ $class->handled_targeting_types };
}

has model => (
is => 'ro',
isa => 'LIMS2::Model',
required => 1
);

has [ qw( species gene_id ) ] => (
is => 'ro',
isa => 'Str',
required => 1
);

sub _build_designs {
my ( $self, $mutation_type ) = @_;

return $self->model->list_assigned_designs_for_gene(
{
species => $self->species,
gene_id => $self->gene_id,
type => $self->design_types_for( $mutation_type )
}
);
}

## no critic(RequireFinalReturn)
sub design_types_for {
my ( $self, $mutation_type ) = @_;

if ( $mutation_type eq 'ko first' ) {
return [ 'conditional', 'artificial-intron', 'intron-replacement' ];
}

$self->model->throw( Implementation => "Unrecognized mutation type: $mutation_type" );
}
## use critic

sub design_wells {
my ( $self, $design ) = @_;
return map { $_->output_wells } $design->process_designs_rs->search_related( process => { type_id => 'create_di' } );
}



# Input:
#
# gene_id: Snf8 ( MGI:1343161 )
# targeting type: double targeting
# first allele Mutation type: ko first
# first allele cassette function: ko first
# second allele mutation type: conditional
# second allele cassette function: reporter only (conditional + cre)

# Output:
#
# Designs
# Design wells
# Final vector wells for 1st allele
# Final vector wells for 2nd allele
# First EP
# Second EP

__PACKAGE__->meta->make_immutable;

1;

__END__
69 changes: 69 additions & 0 deletions lib/LIMS2/AlleleRequest/DoubleTargeted.pm
@@ -0,0 +1,69 @@
package LIMS2::AlleleRequest::DoubleTargeted;

use strict;
use warnings FATAL => 'all';

use Moose;
use MooseX::ClassAttribute;
use namespace::autoclean;

extends qw( LIMS2::AlleleRequest );

class_has '+handled_targeting_types' => (
default => sub { [ 'double_targeted' ] }
);

has [ qw( first_allele_mutation_type first_allele_cassette_function second_allele_mutation_type second_allele_cassette_function ) ] => (
is => 'ro',
isa => 'Str',
required => 1
);

has [ qw( first_allele_designs second_allele_designs ) ] => (
is => 'ro',
isa => 'ArrayRef[LIMS2::Model::Schema::Result::Design]',
init_arg => undef,
lazy_build => 1
);

sub _build_first_allele_designs {
my $self = shift;
return $self->_build_designs( $self->first_allele_mutation_type );
}

sub _build_second_allele_designs {
my $self = shift;
return $self->_build_designs( $self->second_allele_mutation_type );
}

has [
qw( first_allele_design_wells second_allele_design_wells
first_allele_final_vector_wells second_allele_final_vector_wells
)
] => (
is => 'ro',
isa => 'ArrayRef[LIMS2::Model::Schema::Result::Well]',
init_arg => undef,
lazy_build => 1
);

sub _build_first_allele_design_wells {
my $self = shift;
[ map { $self->design_wells($_) } @{$self->first_allele_designs} ];
}

sub _build_second_allele_design_wells {
my $self = shift;
[ map { $self->design_wells($_) } @{$self->second_allele_designs} ];
}

sub _build_first_allele_final_vector_wells {
my $self = shift;

}

__PACKAGE__->meta->make_immutable;

1;

__END__
54 changes: 54 additions & 0 deletions lib/LIMS2/AlleleRequestFactory.pm
@@ -0,0 +1,54 @@
package LIMS2::AlleleRequestFactory;

use strict;
use warnings FATAL => 'all';

use Moose;
use Module::Pluggable::Object;
use LIMS2::Exception::Implementation;
use namespace::autoclean;

has model => (
is => 'ro',
isa => 'LIMS2::Model',
required => 1
);

has species => (
is => 'ro',
isa => 'Str',
required => 1
);

sub plugins {
my $self = shift;
return Module::Pluggable::Object->new( search_path => 'LIMS2::AlleleRequest', require => 1 )->plugins;
}

## no critic(RequireFinalReturn)
sub allele_request {
my ( $self, %params ) = @_;

my $targeting_type = delete $params{targeting_type}
or LIMS2::Exception::Implementation->throw( "allele_request() requires targeting_type" );

$params{model} ||= $self->model;
$params{species} ||= $self->species;

for my $plugin ( $self->plugins ) {
if ( $plugin->handles( $targeting_type ) ) {
return $plugin->new( \%params );
}
}

LIMS2::Exception::Implementation->throw( "Allele request targeting type '$targeting_type' not recognized" );
}
## use critic

__PACKAGE__->meta->make_immutable;

1;

__END__
59 changes: 59 additions & 0 deletions t/60-allele-request.t
@@ -0,0 +1,59 @@
#!/usr/bin/env perl

use strict;
use warnings FATAL => 'all';

#use LIMS2::Test;
use Test::Most;
use LIMS2::AlleleRequestFactory;

# XXX Naughty hack, we should really use LIMS2::Test
{
require LIMS2::Model;

my $model;

sub model {
return $model ||= LIMS2::Model->new( { user => 'tasks' } );
}
}

ok my $arf = LIMS2::AlleleRequestFactory->new( model => model(), species => 'Mouse' ),
'create allele request factory';

isa_ok $arf, 'LIMS2::AlleleRequestFactory';

throws_ok { $arf->allele_request() }
qr/\Qallele_request() requires targeting_type\E/, 'allele_request requires targeting_type';

ok my $ar = $arf->allele_request(
gene_id => 'MGI:1343161',
targeting_type => 'double_targeted',
first_allele_mutation_type => 'ko first',
first_allele_cassette_function => 'ko first',
second_allele_mutation_type => 'ko first',
second_allele_cassette_function => 'reporter only'
), 'constructor succeeds';

my $first_allele_designs;
lives_ok { $first_allele_designs = $ar->first_allele_designs } 'first_allele_designs succeeds';
cmp_bag [ map { $_->id } @{$first_allele_designs} ], [ 76 ], 'first_allele_designs returns expected result';

my $second_allele_designs;
lives_ok { $second_allele_designs = $ar->second_allele_designs } 'second_allele_designs succeeds';
cmp_bag [ map { $_->id } @{$second_allele_designs} ], [ 76 ], 'second_allele_designs returns expected result';

my $first_allele_design_wells;
lives_ok { $first_allele_design_wells = $ar->first_allele_design_wells } 'first_allele_design_wells succeeds';
cmp_bag [ map { $_->as_string } @{$first_allele_design_wells} ], [ '4_C04', '34_C04' ], 'first_allele_design_wells returns the expected result';

my $second_allele_design_wells;
lives_ok { $second_allele_design_wells = $ar->second_allele_design_wells } 'second_allele_design_wells succeeds';
cmp_bag [ map { $_->as_string } @{$second_allele_design_wells} ], [ '4_C04', '34_C04' ], 'second_allele_design_wells returns the expected result';






done_testing();

0 comments on commit 8dec4d2

Please sign in to comment.