Permalink
Browse files

The beginnings of the allele request factory

  • Loading branch information...
1 parent d97bf86 commit 8dec4d28b69d0c5909e04c6ecafd039fc8703e8b Ray Miller committed Jul 30, 2012
View
8 ddl/templates/versions/8/fixtures.sql
@@ -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
View
33 ddl/templates/versions/8/up.sql
@@ -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 %]";
View
89 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__
+
View
69 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__
View
54 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__
+
+
View
59 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.