1 package CXGN
::Trial
::TrialLayout
;
5 CXGN::Trial::TrialLayout - Module to get layout information about a trial (i.e. a project with a "design" projectprop)
9 my $trial_layout = CXGN::Trial::TrialLayout->new({schema => $schema, trial_id => $trial_id} );
17 Jeremy D. Edwards (jde22@cornell.edu)
23 use MooseX
::FollowPBP
;
24 use Moose
::Util
::TypeConstraints
;
26 use CXGN
::Stock
::StockLookup
;
27 use CXGN
::Location
::LocationLookup
;
29 use SGN
::Model
::Cvterm
;
33 isa
=> 'DBIx::Class::Schema',
37 has
'trial_id' => (isa
=> 'Int', is
=> 'rw', predicate
=> 'has_trial_id', trigger
=> \
&_lookup_trial_id
, required
=> 1);
40 isa
=> 'Bio::Chado::Schema::Result::Project::Project',
41 reader
=> 'get_project',
42 writer
=> '_set_project',
43 predicate
=> 'has_project',
45 has
'design_type' => (isa
=> 'Str', is
=> 'ro', predicate
=> 'has_design_type', reader
=> 'get_design_type', writer
=> '_set_design_type');
46 has
'trial_year' => (isa
=> 'Str', is
=> 'ro', predicate
=> 'has_trial_year', reader
=> 'get_trial_year', writer
=> '_set_trial_year');
47 has
'trial_name' => (isa
=> 'Str', is
=> 'ro', predicate
=> 'has_trial_name', reader
=> 'get_trial_name', writer
=> '_set_trial_name');
48 has
'trial_description' => (isa
=> 'Str', is
=> 'ro', predicate
=> 'has_trial_description', reader
=> 'get_trial_description', writer
=> '_set_trial_description');
49 has
'trial_location' => (isa
=> 'Str', is
=> 'ro', predicate
=> 'has_trial_location', reader
=> 'get_trial_location', writer
=> '_set_trial_location');
50 has
'plot_dimensions' => (isa
=> 'ArrayRef', is
=> 'ro', predicate
=> 'has_plot_dimensions', reader
=> 'get_plot_dimensions', writer
=> '_set_plot_dimensions');
51 has
'design' => (isa
=> 'HashRef', is
=> 'ro', predicate
=> 'has_design', reader
=> 'get_design', writer
=> '_set_design');
52 has
'plot_names' => (isa
=> 'ArrayRef', is
=> 'ro', predicate
=> 'has_plot_names', reader
=> 'get_plot_names', writer
=> '_set_plot_names', default => sub { [] } );
53 has
'block_numbers' => (isa
=> 'ArrayRef', is
=> 'ro', predicate
=> 'has_block_numbers', reader
=> 'get_block_numbers', writer
=> '_set_block_numbers');
54 has
'replicate_numbers' => (isa
=> 'ArrayRef', is
=> 'ro', predicate
=> 'has_replicate_numbers', reader
=> 'get_replicate_numbers', writer
=> '_set_replicate_numbers');
55 has
'accession_names' => (isa
=> 'ArrayRef', is
=> 'ro', predicate
=> 'has_accession_names', reader
=> 'get_accession_names', writer
=> '_set_accession_names');
56 has
'control_names' => (isa
=> 'ArrayRef', is
=> 'ro', predicate
=> 'has_control_names', reader
=> 'get_control_names', writer
=> '_set_control_names');
57 has
'row_numbers' => (isa
=> 'ArrayRef', is
=> 'rw', predicate
=> 'has_row_numbers', reader
=> 'get_row_numbers', writer
=> '_set_row_numbers');
58 has
'col_numbers' => (isa
=> 'ArrayRef', is
=> 'rw', predicate
=> 'has_col_numbers', reader
=> 'get_col_numbers', writer
=> '_set_col_numbers');
61 sub _lookup_trial_id
{
62 #print STDERR "Check 2.1: ".localtime()."\n";
64 $self->_set_project_from_id();
65 if (!$self->has_project()) {
66 print STDERR
"Trial id not found\n";
69 my $accession_names_ref;
70 my $control_names_ref;
71 my $design_type_from_project;
73 #print STDERR "Check 2.2: ".localtime()."\n";
74 if (!$self->_get_trial_year_from_project()) {return;}
76 $self->_set_trial_year($self->_get_trial_year_from_project());
77 $self->_set_trial_name($self->get_project->name());
78 $self->_set_trial_description($self->get_project->description());
79 #print STDERR "Check 2.3: ".localtime()."\n";
81 $design_type_from_project = $self->_get_design_type_from_project();
82 if (! $design_type_from_project) {
83 print STDERR
"Trial has no design type... not creating layout object.\n";
86 if (!$self->_get_location_from_field_layout_experiment()) {
87 print STDERR
"Trial has not location... not creating layout object.\n";
91 #print STDERR "Check 2.3.1: ".localtime()."\n";
92 if (!$self->_get_location_from_field_layout_experiment()) {return;}
93 $self->_set_trial_location($self->_get_location_from_field_layout_experiment());
94 #print STDERR "Check 2.3.2: ".localtime()."\n";
95 if (!$self->has_trial_location) {return;}
97 $self->_set_plot_dimensions($self->_get_plot_dimensions_from_trial());
98 #print STDERR "Check 2.3.3: ".localtime()."\n";
99 $self->_set_design_type($self->_get_design_type_from_project());
100 #print STDERR "Check 2.3.4: ".localtime()."\n";
101 $self->_set_design($self->_get_design_from_trial());
102 #print STDERR "Check 2.4: ".localtime()."\n";
103 $self->_set_plot_names($self->_get_plot_info_fields_from_trial("plot_name") || []);
104 $self->_set_block_numbers($self->_get_plot_info_fields_from_trial("block_number") || []);
105 $self->_set_replicate_numbers($self->_get_plot_info_fields_from_trial("rep_number") || []);
106 $self->_set_row_numbers($self->_get_plot_info_fields_from_trial("row_number") || [] );
107 $self->_set_col_numbers($self->_get_plot_info_fields_from_trial("col_number") || [] );
108 #$self->_set_is_a_control($self->_get_plot_info_fields_from_trial("is_a_control"));
109 ($accession_names_ref, $control_names_ref) = $self->_get_trial_accession_names_and_control_names();
110 if ($accession_names_ref) {
111 $self->_set_accession_names($accession_names_ref);
113 if ($control_names_ref) {
114 $self->_set_control_names($control_names_ref);
116 #print STDERR "Check 2.5: ".localtime()."\n";
120 sub _get_control_plot_names_from_trial
{
122 my %design = %{$self->get_design()};
124 foreach my $key (sort { $a <=> $b} keys %design) {
125 my %design_info = %{$design{$key}};
127 $is_a_control = $design_info{"is_a_control"};
129 push(@control_names, $design_info{"plot_name"});
132 if (! scalar(@control_names) >= 1){
135 return \
@control_names;
139 sub _get_plot_info_fields_from_trial
{
141 my $field_name = shift;
142 my %design = %{$self->get_design()};
144 my %unique_field_values;
145 foreach my $key (sort { $a cmp $b} keys %design) {
146 my %design_info = %{$design{$key}};
147 if (exists($design_info{$field_name})) {
148 if (! exists($unique_field_values{$design_info{$field_name}})) {
149 #print STDERR "pushing $design_info{$field_name}...\n";
150 push(@field_values, $design_info{$field_name});
152 $unique_field_values{$design_info{$field_name}} = 1;
156 if (! scalar(@field_values) >= 1){
159 return \
@field_values;
163 sub _get_design_from_trial
{
164 #print STDERR "Check 2.3.4.1: ".localtime()."\n";
166 my $schema = $self->get_schema();
171 $plots_ref = $self->_get_plots();
173 print STDERR
"_get_design_from_trial: not plots provided... returning.\n";
176 #print STDERR "Check 2.3.4.2: ".localtime()."\n";
177 my $project = $self->get_project();
179 my $genotyping_user_id_row = $project
180 ->search_related("nd_experiment_projects")
181 ->search_related("nd_experiment")
182 ->search_related("nd_experimentprops")
183 ->find({ 'type.name' => 'genotyping_user_id' }, {join => 'type' });
185 my $genotyping_project_name_row = $project
186 ->search_related("nd_experiment_projects")
187 ->search_related("nd_experiment")
188 ->search_related("nd_experimentprops")
189 ->find({ 'type.name' => 'genotyping_project_name' }, {join => 'type' });
190 #print STDERR "Check 2.3.4.3: ".localtime()."\n";
192 my $plot_of_cv = $schema->resultset("Cv::Cvterm")->find({name
=> 'plot_of'});
193 my $tissue_sample_of_cv = $schema->resultset("Cv::Cvterm")->find({ name
=>'tissue_sample_of' });
194 my $plant_rel_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($self->get_schema, 'plant_of', 'stock_relationship' );
196 @plots = @
{$plots_ref};
197 foreach my $plot (@plots) {
198 #print STDERR "_get_design_from_trial. Working on plot ".$plot->uniquename()."\n";
201 if ($genotyping_user_id_row) {
202 $design_info{genotyping_user_id
} = $genotyping_user_id_row->get_column("value") || "unknown";
203 #print STDERR "RETRIEVED: genotyping_user_id: $design{genotyping_user_id}\n";
205 if ($genotyping_project_name_row) {
206 $design_info{genotyping_project_name
} = $genotyping_project_name_row->get_column("value") || "unknown";
207 #print STDERR "RETRIEVED: genotyping_project_name: $design{genotyping_project_name}\n";
209 my $plot_name = $plot->uniquename;
210 my $plot_number_prop = $plot->stockprops->find( { 'type.name' => 'plot number' }, { join => 'type'} );
211 my $block_number_prop = $plot->stockprops->find( { 'type.name' => 'block' }, { join => 'type'} );
212 my $replicate_number_prop = $plot->stockprops->find( { 'type.name' => 'replicate' }, { join => 'type'} );
213 my $range_number_prop = $plot->stockprops->find( { 'type.name' => 'range' }, { join => 'type'} );
214 my $is_a_control_prop = $plot->stockprops->find( { 'type.name' => 'is a control' }, { join => 'type'} );
215 my $row_number_prop = $plot->stockprops->find( { 'type.name' => 'row_number' }, { join => 'type'} );
216 my $col_number_prop = $plot->stockprops->find( { 'type.name' => 'col_number' }, { join => 'type'} );
217 my $accession = $plot->search_related('stock_relationship_subjects')->find({ 'type_id' => { -in => [ $plot_of_cv->cvterm_id(), $tissue_sample_of_cv->cvterm_id() ] } })->object;
218 my $plants = $plot->search_related('stock_relationship_subjects', { 'me.type_id' => $plant_rel_cvterm->cvterm_id() })->search_related('object');
220 my $accession_name = $accession->uniquename;
221 my $accession_id = $accession->stock_id;
223 $design_info{"plot_name"}=$plot_name;
224 $design_info{"plot_id"}=$plot->stock_id;
226 if ($plot_number_prop) {
227 $design_info{"plot_number"}=$plot_number_prop->value();
230 die "no plot number stockprop found for plot $plot_name";
233 if ($block_number_prop) {
234 $design_info{"block_number"}=$block_number_prop->value();
236 if ($row_number_prop) {
237 $design_info{"row_number"}=$row_number_prop->value();
239 if ($col_number_prop) {
240 $design_info{"col_number"}=$col_number_prop->value();
242 if ($replicate_number_prop) {
243 $design_info{"rep_number"}=$replicate_number_prop->value();
245 if ($range_number_prop) {
246 $design_info{"range_number"}=$replicate_number_prop->value();
248 if ($is_a_control_prop) {
249 $design_info{"is_a_control"}=$is_a_control_prop->value();
251 if ($accession_name) {
252 $design_info{"accession_name"}=$accession_name;
255 $design_info{"accession_id"}=$accession_id;
260 while (my $p = $plants->next()) {
261 my $plant_name = $p->uniquename();
262 my $plant_id = $p->stock_id();
263 push @plant_names, $plant_name;
264 push @plant_ids, $plant_id;
266 $design_info{"plant_names"}=\
@plant_names;
267 $design_info{"plant_ids"}=\
@plant_ids;
269 $design{$plot_number_prop->value}=\
%design_info;
271 #print STDERR "Check 2.3.4.4: ".localtime()."\n";
276 sub _get_field_layout_experiment_from_project
{
279 my $field_layout_experiment;
280 $project = $self->get_project();
284 $field_layout_experiment = $project
285 ->search_related("nd_experiment_projects")
286 ->search_related("nd_experiment")
287 ->find({ 'type.name' => ['field_layout', 'genotyping_layout']}, {join => 'type' });
288 return $field_layout_experiment;
292 sub _get_location_from_field_layout_experiment
{
294 my $field_layout_experiment;
296 $field_layout_experiment = $self -> _get_field_layout_experiment_from_project
();
297 if (!$field_layout_experiment) {
298 print STDERR
"No field layout detected for this trial.\n";
301 $location_name = $field_layout_experiment -> nd_geolocation
-> description
();
302 #print STDERR "Location: $location_name\n";
303 return $location_name;
306 sub _get_plot_dimensions_from_trial
{
308 if (!$self->has_trial_id()) {
311 my $project = $self->get_project();
315 my $schema = $self->get_schema();
317 my $plot_width_cvterm_id = $schema->resultset("Cv::Cvterm")->find({name
=> 'plot_width'});
318 my $plot_width_type_id = '';
319 if ($plot_width_cvterm_id) {
320 $plot_width_type_id = $plot_width_cvterm_id->cvterm_id;
322 my $plot_width_row = $schema->resultset('Project::Projectprop')->find({project_id
=> $self->get_trial_id(), type_id
=> $plot_width_type_id});
323 if ($plot_width_row) {
324 $plot_width = $plot_width_row->value();
328 my $plot_length = '';
329 my $plot_length_cvterm_id = $schema->resultset("Cv::Cvterm")->find({name
=> 'plot_length'});
330 my $plot_length_type_id = '';
331 if ($plot_length_cvterm_id) {
332 $plot_length_type_id = $plot_length_cvterm_id->cvterm_id;
334 my $plot_length_row = $schema->resultset('Project::Projectprop')->find({project_id
=> $self->get_trial_id(), type_id
=> $plot_length_type_id});
335 if ($plot_length_row) {
336 $plot_length = $plot_length_row->value();
340 my $plants_per_plot = '';
341 my $plants_per_plot_cvterm_id = $schema->resultset("Cv::Cvterm")->find({name
=> 'plot_length'});
342 my $plants_per_plot_type_id = '';
343 if ($plants_per_plot_cvterm_id) {
344 $plants_per_plot_type_id = $plants_per_plot_cvterm_id->cvterm_id;
346 my $plants_per_plot_row = $schema->resultset('Project::Projectprop')->find({project_id
=> $self->get_trial_id(), type_id
=> $plants_per_plot_type_id});
347 if ($plants_per_plot_row) {
348 $plants_per_plot = $plants_per_plot_row->value();
351 return [$plot_length, $plot_width, $plants_per_plot];
354 sub _set_project_from_id
{
356 my $schema = $self->get_schema();
358 if (!$self->has_trial_id()) {
361 $project = $schema->resultset('Project::Project')->find({project_id
=> $self->get_trial_id()});
365 $self->_set_project($project);
368 sub _get_design_type_from_project
{
374 if (!$self->has_trial_id()) {
377 $project = $self->get_project();
381 $design_prop = $project->projectprops->find(
382 { 'type.name' => 'design' },
384 ); #there should be only one design prop.
388 $design_type = $design_prop->value;
395 sub _get_trial_year_from_project
{
401 if (!$self->has_trial_id()) {
404 $project = $self->get_project();
408 $year_prop = $project->projectprops->find(
409 { 'type.name' => 'project year' },
411 ); #there should be only one project year prop.
415 $year = $year_prop->value;
422 my $field_layout_experiment;
424 $project = $self->get_project();
428 $field_layout_experiment = $self->_get_field_layout_experiment_from_project();
429 if (!$field_layout_experiment) {
430 print STDERR
"No field layout experiment found!\n";
433 my $plot_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->get_schema(), "plot", "stock_type")->cvterm_id();
434 my $tissue_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->get_schema(), "tissue_sample", "stock_type")->cvterm_id();
435 @plots = $field_layout_experiment->nd_experiment_stocks->search_related('stock', {'stock.type_id' => [$plot_cvterm_id, $tissue_cvterm_id] });
438 #print STDERR "PLOT LIST: \n";
439 #print STDERR join "\n", map { $_->name() } @plots;
445 sub get_plant_names
{
450 my $schema = $args->{bcs_schema
};
451 my $plots = $args->{plot_rs
};
452 my $plant_rel_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'plant_of', 'stock_relationship' );
454 my $plot_id = $_->stock_id();
455 #print STDERR $plot_id;
456 my $stock_relationships =$schema->resultset("Stock::StockRelationship")->search({
457 subject_id
=> $plot_id,
458 #object_id => $plant->stock_id(),
459 'me.type_id' => $plant_rel_cvterm->cvterm_id(),
460 })->search_related('object');
461 if (!$stock_relationships) {
462 print STDERR
"Plot ".$_->name()." does not have plants associated with it.\n";
465 while (my $plant = $stock_relationships->next()){
466 push @plants, $plant->name();
469 #print STDERR Dumper \@plants;
474 sub oldget_plot_names
{
480 $plots_ref = $self->_get_plots();
484 @plots = @
{$plots_ref};
485 foreach $plot (@plots) {
486 push(@plot_names,$plot->uniquename);
487 # print "plot: ".$plot->uniquename."\n";
489 if (!scalar(@plot_names) >= 1) {
501 $plots_ref = $self->_get_plots();
505 @plots = @
{$plots_ref};
506 foreach $plot (@plots) {
507 push(@plot_names,$plot->stock_id);
509 if (!scalar(@plot_names) >= 1) {
515 sub _get_trial_accession_names_and_control_names
{
518 $schema = $self->get_schema();
524 my %unique_accessions;
528 $plots_ref = $self->_get_plots();
532 @plots = @
{$plots_ref};
533 $plot_of_cv = $schema->resultset("Cv::Cvterm")->find({name
=> 'plot_of'});
534 $sample_of_cv = $schema->resultset("Cv::Cvterm")->find({name
=> 'tissue_sample_of'});
535 foreach $plot (@plots) {
536 my $accession = $plot->search_related('stock_relationship_subjects')->find({ 'type_id' => [$plot_of_cv->cvterm_id(),$sample_of_cv->cvterm_id() ]})->object;
537 my $is_a_control_prop = $plot->stockprops->find( { 'type.name' => 'is a control' }, { join => 'type'} );
539 if ($is_a_control_prop) {
540 $is_a_control = $is_a_control_prop->value();
543 $unique_controls{$accession->uniquename}=$accession->stock_id;
546 $unique_accessions{$accession->uniquename}=$accession->stock_id;
549 foreach my $accession_name (sort { lc($a) cmp lc($b)} keys %unique_accessions) {
550 push(@accession_names, {accession_name
=>$accession_name, stock_id
=>$unique_accessions{$accession_name} } );
551 #print STDERR "Accession: $accession_name \n";
553 if (!scalar(@accession_names) >= 1) {
556 foreach my $control_name (sort { lc($a) cmp lc($b)} keys %unique_controls) {
557 push(@control_names, {accession_name
=>$control_name, stock_id
=>$unique_controls{$control_name} } );
558 #print STDERR "Control: $control_name \n";
560 return (\
@accession_names, \
@control_names);
564 # sub _get_genotyping_experiment_metadata {
567 # my $project = $self->get_project();
571 # my $metadata = $project
572 # ->search_related("nd_experiment_projects")
573 # ->search_related("nd_experiment")
574 # ->search_related("nd_experimentprop")
575 # ->search({ 'type.name' => ['genotyping_user_id', 'genotyping_project_name']}, {join => 'type' });
576 # return $metadata_rs;