Skip to content
This repository
Browse code

The beginnings of the allele request factory

  • Loading branch information...
commit 8dec4d28b69d0c5909e04c6ecafd039fc8703e8b 1 parent d97bf86
authored July 30, 2012
8  ddl/templates/versions/8/fixtures.sql
@@ -9,19 +9,21 @@ VALUES ('Core', 'Homozygous - Core'),
9 9
        ('Cre BAC', 'EUCOMMTools-Cre BAC'),
10 10
        ('Human','Homozygous - Human');
11 11
 
12  
-INSERT INTO mutation_type(mutation_type)
  12
+INSERT INTO mutation_types(mutation_type)
13 13
 VALUES ('conditional'),
14 14
        ('deletion'),
15 15
        ('insertion');
16 16
 
17  
-INSERT INTO targeting_type(targeting_type)
  17
+INSERT INTO targeting_types(targeting_type)
18 18
 VALUES ('single_targeting'),
19 19
        ('double_targeting'),
20 20
        ('modified_bac_insertion');
21 21
 
22  
-INSERT INTO final_cassette_function(final_cassette_function)
  22
+INSERT INTO cassette_functions(final_cassette_function)
23 23
 VALUES ('knockout_first'),
24 24
        ('reporter_only'),
25 25
        ('conditional_only'),
26 26
        ('cre_expressor'),
27 27
        ('promoterless_cre_expressor');
  28
+
  29
+[% FOR cassette IN        
33  ddl/templates/versions/8/up.sql
@@ -9,23 +9,34 @@ CREATE TABLE sponsors (
9 9
 GRANT SELECT ON sponsors TO "[% ro_role %]";
10 10
 GRANT SELECT, INSERT, UPDATE, DELETE ON sponsors TO "[% rw_role %]";
11 11
 
12  
-CREATE TABLE mutation_type (
  12
+-- XXX at the very least, need unique key on mutation_type, targeting_type, cassette_function
  13
+-- Should we dispense with the SERIAL id column on these tables?
  14
+
  15
+CREATE TABLE mutation_types (
13 16
        id            SERIAL PRIMARY KEY,
14 17
        mutation_type TEXT NOT NULL
15 18
 );
16  
-GRANT SELECT ON mutation_type TO "[% ro_role %]";
17  
-GRANT SELECT, INSERT, UPDATE, DELETE ON mutation_type TO "[% rw_role %]";       
  19
+GRANT SELECT ON mutation_types TO "[% ro_role %]";
  20
+GRANT SELECT, INSERT, UPDATE, DELETE ON mutation_types TO "[% rw_role %]";       
18 21
 
19  
-CREATE TABLE targeting_type (
  22
+CREATE TABLE targeting_types (
20 23
        id             SERIAL PRIMARY KEY,
21 24
        targeting_type TEXT NOT NULL
22 25
 );
23  
-GRANT SELECT ON targeting_type TO "[% ro_role %]";
24  
-GRANT SELECT, INSERT, UPDATE, DELETE ON targeting_type TO "[% rw_role %]";
  26
+GRANT SELECT ON targeting_types TO "[% ro_role %]";
  27
+GRANT SELECT, INSERT, UPDATE, DELETE ON targeting_types TO "[% rw_role %]";
  28
+
  29
+CREATE TABLE cassette_functions (
  30
+       id                SERIAL PRIMARY KEY,
  31
+       cassette_function TEXT NOT NULL
  32
+);
  33
+GRANT SELECT ON cassette_functions TO "[% ro_role %]";
  34
+GRANT SELECT, INSERT, UPDATE, DELETE ON cassette_functions TO "[% rw_role %]";
25 35
 
26  
-CREATE TABLE final_cassette_function (
27  
-       id                      SERIAL PRIMARY KEY,
28  
-       final_cassette_function TEXT NOT NULL
  36
+CREATE TABLE cassette_cassette_functions (
  37
+       cassette_id INTEGER NOT NULL REFERENCES cassettes(id),
  38
+       function_id INTEGER NOT NULL REFERENCES cassette_functions(id),
  39
+       PRIMARY KEY(cassette_id,function_id)
29 40
 );
30  
-GRANT SELECT ON final_cassette_function TO "[% ro_role %]";
31  
-GRANT SELECT, INSERT, UPDATE, DELETE ON final_cassette_function TO "[% rw_role %]";
  41
+GRANT SELECT ON cassette_cassette_functions TO "[% ro_role %]";
  42
+GRANT SELECT, INSERT, UPDATE, DELETE ON cassette_cassette_functions TO "[% rw_role %]";
89  lib/LIMS2/AlleleRequest.pm
... ...
@@ -0,0 +1,89 @@
  1
+package LIMS2::AlleleRequest;
  2
+
  3
+use strict;
  4
+use warnings FATAL => 'all';
  5
+
  6
+use Moose;
  7
+use MooseX::ClassAttribute;
  8
+use List::MoreUtils qw( any );
  9
+use namespace::autoclean;
  10
+
  11
+class_has handled_targeting_types => (
  12
+    is      => 'ro',
  13
+    isa     => 'ArrayRef[Str]',
  14
+    default => sub { [] }
  15
+);
  16
+
  17
+sub handles {
  18
+    my ( $class, $targeting_type ) = @_;
  19
+
  20
+    return any { $_ eq $targeting_type } @{ $class->handled_targeting_types };
  21
+}
  22
+
  23
+has model => (
  24
+    is       => 'ro',
  25
+    isa      => 'LIMS2::Model',
  26
+    required => 1
  27
+);
  28
+
  29
+has [ qw( species gene_id ) ] => ( 
  30
+    is => 'ro',
  31
+    isa => 'Str',
  32
+    required => 1
  33
+);
  34
+
  35
+sub _build_designs {
  36
+    my ( $self, $mutation_type ) = @_;
  37
+
  38
+    return $self->model->list_assigned_designs_for_gene(
  39
+        {
  40
+            species => $self->species,
  41
+            gene_id => $self->gene_id,
  42
+            type    => $self->design_types_for( $mutation_type )
  43
+        }
  44
+    );
  45
+}
  46
+
  47
+## no critic(RequireFinalReturn)
  48
+sub design_types_for {
  49
+    my ( $self, $mutation_type ) = @_;
  50
+
  51
+    if ( $mutation_type eq 'ko first' ) {
  52
+        return [ 'conditional', 'artificial-intron', 'intron-replacement' ];
  53
+    }
  54
+
  55
+    $self->model->throw( Implementation => "Unrecognized mutation type: $mutation_type" );    
  56
+}
  57
+## use critic
  58
+
  59
+sub design_wells {
  60
+    my ( $self, $design ) = @_;
  61
+    return map { $_->output_wells } $design->process_designs_rs->search_related( process => { type_id => 'create_di' } );
  62
+}
  63
+
  64
+    
  65
+
  66
+# Input:
  67
+#
  68
+# gene_id: Snf8 ( MGI:1343161 )
  69
+# targeting type: double targeting
  70
+# first allele Mutation type: ko first
  71
+# first allele cassette function: ko first
  72
+# second allele mutation type: conditional
  73
+# second allele cassette function: reporter only (conditional + cre)
  74
+
  75
+# Output:
  76
+#
  77
+# Designs
  78
+# Design wells
  79
+# Final vector wells for 1st allele
  80
+# Final vector wells for 2nd allele
  81
+# First EP
  82
+# Second EP
  83
+
  84
+__PACKAGE__->meta->make_immutable;
  85
+
  86
+1;
  87
+
  88
+__END__
  89
+
69  lib/LIMS2/AlleleRequest/DoubleTargeted.pm
... ...
@@ -0,0 +1,69 @@
  1
+package LIMS2::AlleleRequest::DoubleTargeted;
  2
+
  3
+use strict;
  4
+use warnings FATAL => 'all';
  5
+
  6
+use Moose;
  7
+use MooseX::ClassAttribute;
  8
+use namespace::autoclean;
  9
+
  10
+extends qw( LIMS2::AlleleRequest );
  11
+
  12
+class_has '+handled_targeting_types' => (
  13
+    default => sub { [ 'double_targeted' ] }
  14
+);
  15
+
  16
+has [ qw( first_allele_mutation_type first_allele_cassette_function second_allele_mutation_type second_allele_cassette_function ) ] => (
  17
+    is => 'ro',
  18
+    isa => 'Str',
  19
+    required => 1
  20
+);
  21
+
  22
+has [ qw( first_allele_designs second_allele_designs ) ] => (
  23
+    is         => 'ro',
  24
+    isa        => 'ArrayRef[LIMS2::Model::Schema::Result::Design]',
  25
+    init_arg   => undef,
  26
+    lazy_build => 1
  27
+);
  28
+
  29
+sub _build_first_allele_designs {
  30
+    my $self = shift;
  31
+    return $self->_build_designs( $self->first_allele_mutation_type );
  32
+}
  33
+
  34
+sub _build_second_allele_designs {
  35
+    my $self = shift;
  36
+    return $self->_build_designs( $self->second_allele_mutation_type );
  37
+}
  38
+
  39
+has [
  40
+    qw( first_allele_design_wells second_allele_design_wells
  41
+        first_allele_final_vector_wells second_allele_final_vector_wells
  42
+  )
  43
+] => (
  44
+    is         => 'ro',
  45
+    isa        => 'ArrayRef[LIMS2::Model::Schema::Result::Well]',
  46
+    init_arg   => undef,
  47
+    lazy_build => 1
  48
+);
  49
+
  50
+sub _build_first_allele_design_wells {
  51
+    my $self = shift;
  52
+    [ map { $self->design_wells($_) } @{$self->first_allele_designs} ];
  53
+}
  54
+
  55
+sub _build_second_allele_design_wells {
  56
+    my $self = shift;
  57
+    [ map { $self->design_wells($_) } @{$self->second_allele_designs} ];
  58
+}
  59
+
  60
+sub _build_first_allele_final_vector_wells {
  61
+    my $self = shift;
  62
+    
  63
+}
  64
+
  65
+__PACKAGE__->meta->make_immutable;
  66
+
  67
+1;
  68
+
  69
+__END__
54  lib/LIMS2/AlleleRequestFactory.pm
... ...
@@ -0,0 +1,54 @@
  1
+package LIMS2::AlleleRequestFactory;
  2
+
  3
+use strict;
  4
+use warnings FATAL => 'all';
  5
+
  6
+use Moose;
  7
+use Module::Pluggable::Object;
  8
+use LIMS2::Exception::Implementation;
  9
+use namespace::autoclean;
  10
+
  11
+has model => (
  12
+    is       => 'ro',
  13
+    isa      => 'LIMS2::Model',
  14
+    required => 1
  15
+);
  16
+
  17
+has species => ( 
  18
+    is       => 'ro',
  19
+    isa      => 'Str',
  20
+    required => 1
  21
+);
  22
+
  23
+sub plugins {
  24
+    my $self = shift;
  25
+    return Module::Pluggable::Object->new( search_path => 'LIMS2::AlleleRequest', require => 1 )->plugins;
  26
+}
  27
+
  28
+## no critic(RequireFinalReturn)
  29
+sub allele_request {
  30
+    my ( $self, %params ) = @_;
  31
+
  32
+    my $targeting_type = delete $params{targeting_type}
  33
+        or LIMS2::Exception::Implementation->throw( "allele_request() requires targeting_type" );
  34
+
  35
+    $params{model}   ||= $self->model;
  36
+    $params{species} ||= $self->species;
  37
+
  38
+    for my $plugin ( $self->plugins ) {
  39
+        if ( $plugin->handles( $targeting_type ) ) {
  40
+            return $plugin->new( \%params );
  41
+        }
  42
+    }
  43
+
  44
+    LIMS2::Exception::Implementation->throw( "Allele request targeting type '$targeting_type' not recognized" );
  45
+}
  46
+## use critic
  47
+
  48
+__PACKAGE__->meta->make_immutable;
  49
+
  50
+1;
  51
+
  52
+__END__
  53
+
  54
+
59  t/60-allele-request.t
... ...
@@ -0,0 +1,59 @@
  1
+#!/usr/bin/env perl
  2
+
  3
+use strict;
  4
+use warnings FATAL => 'all';
  5
+
  6
+#use LIMS2::Test;
  7
+use Test::Most;
  8
+use LIMS2::AlleleRequestFactory;
  9
+
  10
+# XXX Naughty hack, we should really use LIMS2::Test
  11
+{
  12
+    require LIMS2::Model;
  13
+
  14
+    my $model;
  15
+    
  16
+    sub model {
  17
+        return $model ||= LIMS2::Model->new( { user => 'tasks' } );
  18
+    }
  19
+}
  20
+
  21
+ok my $arf = LIMS2::AlleleRequestFactory->new( model => model(), species => 'Mouse' ),
  22
+    'create allele request factory';
  23
+
  24
+isa_ok $arf, 'LIMS2::AlleleRequestFactory';
  25
+
  26
+throws_ok { $arf->allele_request() }
  27
+    qr/\Qallele_request() requires targeting_type\E/, 'allele_request requires targeting_type';
  28
+
  29
+ok my $ar = $arf->allele_request(
  30
+    gene_id                         => 'MGI:1343161',
  31
+    targeting_type                  => 'double_targeted',
  32
+    first_allele_mutation_type      => 'ko first',
  33
+    first_allele_cassette_function  => 'ko first',
  34
+    second_allele_mutation_type     => 'ko first',
  35
+    second_allele_cassette_function => 'reporter only'
  36
+), 'constructor succeeds';
  37
+
  38
+my $first_allele_designs;
  39
+lives_ok { $first_allele_designs = $ar->first_allele_designs } 'first_allele_designs succeeds';
  40
+cmp_bag [ map { $_->id } @{$first_allele_designs} ], [ 76 ], 'first_allele_designs returns expected result';
  41
+
  42
+my $second_allele_designs;
  43
+lives_ok { $second_allele_designs = $ar->second_allele_designs } 'second_allele_designs succeeds';
  44
+cmp_bag [ map { $_->id } @{$second_allele_designs} ], [ 76 ], 'second_allele_designs returns expected result';
  45
+
  46
+my $first_allele_design_wells;
  47
+lives_ok { $first_allele_design_wells = $ar->first_allele_design_wells } 'first_allele_design_wells succeeds';
  48
+cmp_bag [ map { $_->as_string } @{$first_allele_design_wells} ], [ '4_C04', '34_C04' ], 'first_allele_design_wells returns the expected result';
  49
+
  50
+my $second_allele_design_wells;
  51
+lives_ok { $second_allele_design_wells = $ar->second_allele_design_wells } 'second_allele_design_wells succeeds';
  52
+cmp_bag [ map { $_->as_string } @{$second_allele_design_wells} ], [ '4_C04', '34_C04' ], 'second_allele_design_wells returns the expected result';
  53
+
  54
+    
  55
+
  56
+
  57
+
  58
+
  59
+done_testing();

0 notes on commit 8dec4d2

Please sign in to comment.
Something went wrong with that request. Please try again.