ignore emacs backup files also in db/run_all_patches.pl
[sgn.git] / lib / CXGN / Trial.pm
blob3be485f76d272fa59aa2199b786673768d445b10
2 =head1 NAME
4 CXGN::Trial - helper class for trials
6 =head1 SYNOPSYS
8 my $trial = CXGN::Trial->new( { bcs_schema => $schema, trial_id => $trial_id });
9 $trial->set_description("yield trial with promising varieties");
10 etc.
12 =head1 AUTHOR
14 Lukas Mueller <lam87@cornell.edu>
16 =head1 METHODS
18 =cut
20 package CXGN::Trial;
22 use Moose;
23 use Data::Dumper;
24 use Try::Tiny;
25 use Data::Dumper;
26 use CXGN::Trial::Folder;
27 use CXGN::Trial::TrialLayout;
28 use CXGN::Trial::TrialLayoutDownload;
29 use SGN::Model::Cvterm;
30 use Time::Piece;
31 use Time::Seconds;
32 use CXGN::Calendar;
33 use JSON;
34 use File::Basename qw | basename dirname|;
36 =head2 accessor bcs_schema()
38 accessor for bcs_schema. Needs to be set when calling the constructor.
40 =cut
42 has 'bcs_schema' => (
43 isa => 'Bio::Chado::Schema',
44 is => 'rw',
45 required => 1,
48 has 'metadata_schema' => (
49 isa => 'CXGN::Metadata::Schema',
50 is => 'rw',
53 has 'phenome_schema' => (
54 isa => 'CXGN::Phenome::Schema',
55 is => 'rw',
60 sub BUILD {
61 my $self = shift;
63 my $row = $self->bcs_schema->resultset("Project::Project")->find( { project_id => $self->get_trial_id() });
65 if ($row){
66 #print STDERR "Found row for ".$self->get_trial_id()." ".$row->name()."\n";
69 if (!$row) {
70 die "The trial ".$self->get_trial_id()." does not exist";
74 =head2 accessors get_trial_id()
76 Desc: get the trial id
78 =cut
80 has 'trial_id' => (isa => 'Int',
81 is => 'rw',
82 reader => 'get_trial_id',
83 writer => 'set_trial_id',
86 =head2 accessors get_layout(), set_layout()
88 Desc: set the layout object for this trial (CXGN::Trial::TrialLayout)
89 (This is populated automatically by the constructor)
91 =cut
93 has 'layout' => (isa => 'CXGN::Trial::TrialLayout',
94 is => 'rw',
95 reader => 'get_layout',
96 writer => 'set_layout',
97 predicate => 'has_layout',
98 lazy => 1,
99 default => sub { my $self = shift; $self->_get_layout(); }
102 sub _get_layout {
103 my $self = shift;
104 print STDERR "RETRIEVING LAYOUT...\n";
105 my $layout = CXGN::Trial::TrialLayout->new( { schema => $self->bcs_schema, trial_id => $self->get_trial_id(), experiment_type=>'field_layout' });
106 $self->set_layout($layout);
110 =head2 accessors get_year(), set_year()
112 getter/setter for the year property. The setter modifies the database.
114 =cut
116 sub get_year {
117 my $self = shift;
119 my $type_id = $self->get_year_type_id();
121 my $rs = $self->bcs_schema->resultset('Project::Project')->search( { 'me.project_id' => $self->get_trial_id() })->search_related('projectprops', { type_id => $type_id } );
123 if ($rs->count() == 0) {
124 return undef;
126 else {
127 return $rs->first()->value();
131 sub set_year {
132 my $self = shift;
133 my $year = shift;
135 my $type_id = $self->get_year_type_id();
137 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find( { project_id => $self->get_trial_id(), type_id => $type_id });
139 if ($row) {
140 $row->value($year);
141 $row->update();
143 else {
144 $row = $self->bcs_schema->resultset('Project::Projectprop')->create(
146 type_id => $type_id,
147 value => $year,
148 project_id => $self->get_trial_id()
149 } );
153 =head2 accessors get_description(), set_description()
155 getter/setter for the description
157 =cut
159 sub get_description {
160 my $self = shift;
162 my $rs = $self->bcs_schema->resultset('Project::Project')->search( { project_id => $self->get_trial_id() });
164 return $rs->first()->description();
169 sub set_description {
170 my $self = shift;
171 my $description = shift;
173 my $row = $self->bcs_schema->resultset('Project::Project')->find( { project_id => $self->get_trial_id() });
175 #print STDERR "Setting new description $description for trial ".$self->get_trial_id()."\n";
177 $row->description($description);
179 $row->update();
184 =head2 function get_nd_experiment_id()
186 Usage: my $location = $trial->get_nd_experiment_id();
187 Desc: Every trial should have only a single nd_experiment entry of type 'field_layout'. This returns this nd_experiment_id for the trial.
188 Ret: $nd_experiment_id
189 Args:
190 Side Effects:
191 Example:
193 =cut
195 sub get_nd_experiment_id {
196 my $self = shift;
197 my $nd_experiment_type_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'field_layout', 'experiment_type')->cvterm_id();
198 my $nd_experiment_rs = $self->bcs_schema->resultset('NaturalDiversity::NdExperiment')->search(
199 { 'me.type_id' => $nd_experiment_type_id, 'project.project_id' => $self->get_trial_id },
200 { 'join' => {'nd_experiment_projects'=>'project'}}
202 if ($nd_experiment_rs->count > 1){
203 return {error => "A trial cannot have more than one nd_experiment entry of type field_layout. Please contact us."};
205 if ($nd_experiment_rs == 1){
206 return {success => 1, nd_experiment_id => $nd_experiment_rs->first->nd_experiment_id};
207 } else {
208 return {error => "This trial does not have an nd_experiment entry of type field_layout. Please contact us."}
212 =head2 function get_location()
214 Usage: my $location = $trial->get_location();
215 Desc:
216 Ret: [ location_id, 'location description' ]
217 Args:
218 Side Effects:
219 Example:
221 =cut
223 sub get_location {
224 my $self = shift;
226 if ($self->get_location_type_id()) {
227 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find( { project_id => $self->get_trial_id() , type_id=> $self->get_location_type_id() });
229 if ($row) {
230 my $loc = $self->bcs_schema->resultset('NaturalDiversity::NdGeolocation')->find( { nd_geolocation_id => $row->value() });
232 return [ $row->value(), $loc->description() ];
234 else {
235 return [];
240 =head2 function set_location()
242 Usage: $trial->set_location($location_id);
243 Desc:
244 Ret: nothing
245 Args:
246 Side Effects: database access
247 Example:
249 =cut
251 sub set_location {
252 my $self = shift;
253 my $location_id = shift;
254 my $project_id = $self->get_trial_id();
255 my $type_id = $self->get_location_type_id();
257 my $row = $self->bcs_schema()->resultset('Project::Projectprop')->find({
258 project_id => $project_id,
259 type_id => $type_id,
262 if ($row) {
263 $row->value($location_id);
264 $row->update();
266 else {
267 $row = $self->bcs_schema()->resultset('Project::Projectprop')->create({
268 project_id => $project_id,
269 type_id => $type_id,
270 value => $location_id,
275 # CLASS METHOD!
277 =head2 class method get_all_locations()
279 Usage: my $locations = CXGN::Trial::get_all_locations($schema)
280 Desc:
281 Ret:
282 Args:
283 Side Effects:
284 Example:
286 =cut
288 sub get_all_locations {
289 my $schema = shift;
290 my $location_id = shift;
291 my @locations;
293 my %search_params;
294 if ($location_id){
295 $search_params{'nd_geolocation_id'} = $location_id;
298 my $loc = $schema->resultset('NaturalDiversity::NdGeolocation')->search( \%search_params, {order_by => { -asc => 'nd_geolocation_id' }} );
299 while (my $s = $loc->next()) {
300 my $loc_props = $schema->resultset('NaturalDiversity::NdGeolocationprop')->search( { nd_geolocation_id => $s->nd_geolocation_id() }, {join=>'type', '+select'=>['me.value', 'type.name'], '+as'=>['value', 'cvterm_name'] } );
302 my %attr;
303 $attr{'geodetic datum'} = $s->geodetic_datum();
305 my $country = '';
306 my $country_code = '';
307 my $location_type = '';
308 my $abbreviation = '';
309 my $address = '';
311 while (my $sp = $loc_props->next()) {
312 if ($sp->get_column('cvterm_name') eq 'country_name') {
313 $country = $sp->get_column('value');
314 } elsif ($sp->get_column('cvterm_name') eq 'country_code') {
315 $country_code = $sp->get_column('value');
316 } elsif ($sp->get_column('cvterm_name') eq 'location_type') {
317 $location_type = $sp->get_column('value');
318 } elsif ($sp->get_column('cvterm_name') eq 'abbreviation') {
319 $abbreviation = $sp->get_column('value');
320 } elsif ($sp->get_column('cvterm_name') eq 'geolocation address') {
321 $address = $sp->get_column('value');
322 } else {
323 $attr{$sp->get_column('cvterm_name')} = $sp->get_column('value') ;
327 push @locations, [$s->nd_geolocation_id(), $s->description(), $s->latitude(), $s->longitude(), $s->altitude(), $country, $country_code, \%attr, $location_type, $abbreviation, $address],
330 return \@locations;
334 =head2 function get_breeding_programs()
336 Usage:
337 Desc: return associated breeding program info
338 Ret: returns a listref to [ id, name, desc ] listrefs
339 Args:
340 Side Effects:
341 Example:
343 =cut
345 sub get_breeding_programs {
346 my $self = shift;
348 my $breeding_program_cvterm_id = $self->get_breeding_program_cvterm_id();
350 my $trial_rs= $self->bcs_schema->resultset('Project::ProjectRelationship')->search( { 'subject_project_id' => $self->get_trial_id() } );
352 my $trial_row = $trial_rs -> first();
353 my $rs;
354 my @projects;
356 if ($trial_row) {
357 $rs = $self->bcs_schema->resultset('Project::Project')->search( { 'me.project_id' => $trial_row->object_project_id(), 'projectprops.type_id'=>$breeding_program_cvterm_id }, { join => 'projectprops' } );
359 while (my $row = $rs->next()) {
360 push @projects, [ $row->project_id, $row->name, $row->description ];
363 return \@projects;
366 =head2 function set_field_trials_source_field_trials()
368 Usage:
369 Desc: sets associated source field trials for the current field trial
370 Ret: returns an arrayref [ id, name ] of arrayrefs
371 Args: an arrayref [source_trial_id1, source_trial_id2]
372 Side Effects:
373 Example:
375 =cut
377 sub set_field_trials_source_field_trials {
378 my $self = shift;
379 my $source_field_trial_ids = shift;
380 my $schema = $self->bcs_schema;
381 my $field_trial_from_field_trial_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'field_trial_from_field_trial', 'project_relationship')->cvterm_id();
383 foreach (@$source_field_trial_ids){
384 if ($_){
385 my $trial_rs= $self->bcs_schema->resultset('Project::ProjectRelationship')->create({
386 'subject_project_id' => $self->get_trial_id(),
387 'object_project_id' => $_,
388 'type_id' => $field_trial_from_field_trial_cvterm_id
392 my $projects = $self->get_field_trials_source_field_trials();
393 return $projects;
396 =head2 function get_field_trials_source_field_trials()
398 Usage:
399 Desc: return associated source field trials for the current field trial
400 Ret: returns an arrayref [ id, name ] of arrayrefs
401 Args:
402 Side Effects:
403 Example:
405 =cut
407 sub get_field_trials_source_field_trials {
408 my $self = shift;
409 my $schema = $self->bcs_schema;
410 my $field_trial_from_field_trial_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'field_trial_from_field_trial', 'project_relationship')->cvterm_id();
412 my $trial_rs= $self->bcs_schema->resultset('Project::ProjectRelationship')->search({
413 'me.subject_project_id' => $self->get_trial_id(),
414 'me.type_id' => $field_trial_from_field_trial_cvterm_id
415 }, {
416 join => 'object_project', '+select' => ['object_project.name'], '+as' => ['source_trial_name']
419 my @projects;
420 while (my $r = $trial_rs->next) {
421 push @projects, [ $r->object_project_id, $r->get_column('source_trial_name') ];
423 return \@projects;
426 =head2 function get_field_trials_sourced_from_field_trials()
428 Usage:
429 Desc: return associated source field trials for the current field trial
430 Ret: returns an arrayref [ id, name ] of arrayrefs
431 Args:
432 Side Effects:
433 Example:
435 =cut
437 sub get_field_trials_sourced_from_field_trials {
438 my $self = shift;
439 my $schema = $self->bcs_schema;
440 my $field_trial_from_field_trial_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'field_trial_from_field_trial', 'project_relationship')->cvterm_id();
442 my $trial_rs= $self->bcs_schema->resultset('Project::ProjectRelationship')->search({
443 'me.object_project_id' => $self->get_trial_id(),
444 'me.type_id' => $field_trial_from_field_trial_cvterm_id
445 }, {
446 join => 'subject_project', '+select' => ['subject_project.name'], '+as' => ['trial_name']
449 my @projects;
450 while (my $r = $trial_rs->next) {
451 push @projects, [ $r->subject_project_id, $r->get_column('trial_name') ];
453 return \@projects;
456 =head2 function set_genotyping_trials_from_field_trial()
458 Usage:
459 Desc: sets associated genotyping plates for the current field trial
460 Ret: returns an arrayref [ id, name ] of arrayrefs
461 Args: an arrayref [genotyping_trial_id1, genotyping_trial_id2]
462 Side Effects:
463 Example:
465 =cut
467 sub set_genotyping_trials_from_field_trial {
468 my $self = shift;
469 my $source_field_trial_ids = shift;
470 my $schema = $self->bcs_schema;
471 my $genotyping_trial_from_field_trial_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'genotyping_trial_from_field_trial', 'project_relationship')->cvterm_id();
473 foreach (@$source_field_trial_ids){
474 if ($_){
475 my $trial_rs= $self->bcs_schema->resultset('Project::ProjectRelationship')->create({
476 'subject_project_id' => $self->get_trial_id(),
477 'object_project_id' => $_,
478 'type_id' => $genotyping_trial_from_field_trial_cvterm_id
482 my $projects = $self->get_genotyping_trials_from_field_trial();
483 return $projects;
486 =head2 function get_genotyping_trials_from_field_trial()
488 Usage:
489 Desc: return associated genotyping plates for the current field trial
490 Ret: returns an arrayref [ id, name ] of arrayrefs
491 Args:
492 Side Effects:
493 Example:
495 =cut
497 sub get_genotyping_trials_from_field_trial {
498 my $self = shift;
499 my $schema = $self->bcs_schema;
500 my $genotyping_trial_from_field_trial_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'genotyping_trial_from_field_trial', 'project_relationship')->cvterm_id();
502 my $trial_rs= $self->bcs_schema->resultset('Project::ProjectRelationship')->search({
503 'me.subject_project_id' => $self->get_trial_id(),
504 'me.type_id' => $genotyping_trial_from_field_trial_cvterm_id
505 }, {
506 join => 'object_project', '+select' => ['object_project.name'], '+as' => ['source_trial_name']
509 my @projects;
510 while (my $r = $trial_rs->next) {
511 push @projects, [ $r->object_project_id, $r->get_column('source_trial_name') ];
513 return \@projects;
516 =head2 function set_source_field_trials_for_genotyping_trial()
518 Usage:
519 Desc: sets associated field trials for the current genotyping plate
520 Ret: returns an arrayref [ id, name ] of arrayrefs
521 Args: an arrayref [field_trial_id1, field_trial_id2]
522 Side Effects:
523 Example:
525 =cut
527 sub set_source_field_trials_for_genotyping_trial {
528 my $self = shift;
529 my $source_field_trial_ids = shift;
530 my $schema = $self->bcs_schema;
531 my $genotyping_trial_from_field_trial_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'genotyping_trial_from_field_trial', 'project_relationship')->cvterm_id();
533 foreach (@$source_field_trial_ids){
534 if ($_){
535 my $trial_rs= $self->bcs_schema->resultset('Project::ProjectRelationship')->create({
536 'object_project_id' => $self->get_trial_id(),
537 'subject_project_id' => $_,
538 'type_id' => $genotyping_trial_from_field_trial_cvterm_id
542 my $projects = $self->get_field_trials_source_of_genotyping_trial();
543 return $projects;
546 =head2 function get_field_trials_source_of_genotyping_trial()
548 Usage:
549 Desc: return associated field trials for current genotying trial
550 Ret: returns an arrayref [ id, name ] of arrayrefs
551 Args:
552 Side Effects:
553 Example:
555 =cut
557 sub get_field_trials_source_of_genotyping_trial {
558 my $self = shift;
559 my $schema = $self->bcs_schema;
560 my $genotyping_trial_from_field_trial_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'genotyping_trial_from_field_trial', 'project_relationship')->cvterm_id();
562 my $trial_rs= $self->bcs_schema->resultset('Project::ProjectRelationship')->search({
563 'me.object_project_id' => $self->get_trial_id(),
564 'me.type_id' => $genotyping_trial_from_field_trial_cvterm_id
565 }, {
566 join => 'subject_project', '+select' => ['subject_project.name'], '+as' => ['source_trial_name']
569 my @projects;
570 while (my $r = $trial_rs->next) {
571 push @projects, [ $r->subject_project_id, $r->get_column('source_trial_name') ];
573 return \@projects;
577 =head2 function set_crossing_trials_from_field_trial()
579 Usage:
580 Desc: sets associated crossing trials for the current field trial
581 Ret: returns an arrayref [ id, name ] of arrayrefs
582 Args: an arrayref [crossing_trial_id1, crossing_trial_id2]
583 Side Effects:
584 Example:
586 =cut
588 sub set_crossing_trials_from_field_trial {
589 my $self = shift;
590 my $source_field_trial_ids = shift;
591 my $schema = $self->bcs_schema;
592 my $genotyping_trial_from_field_trial_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'crossing_trial_from_field_trial', 'project_relationship')->cvterm_id();
594 foreach (@$source_field_trial_ids){
595 if ($_){
596 my $trial_rs= $self->bcs_schema->resultset('Project::ProjectRelationship')->create({
597 'subject_project_id' => $self->get_trial_id(),
598 'object_project_id' => $_,
599 'type_id' => $genotyping_trial_from_field_trial_cvterm_id
603 my $projects = $self->get_crossing_trials_from_field_trial();
604 return $projects;
607 =head2 function get_crossing_trials_from_field_trial()
609 Usage:
610 Desc: return associated crossing trials for athe current field trial
611 Ret: returns an arrayref [ id, name ] of arrayrefs
612 Args:
613 Side Effects:
614 Example:
616 =cut
618 sub get_crossing_trials_from_field_trial {
619 my $self = shift;
620 my $schema = $self->bcs_schema;
621 my $genotyping_trial_from_field_trial_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'crossing_trial_from_field_trial', 'project_relationship')->cvterm_id();
623 my $trial_rs= $self->bcs_schema->resultset('Project::ProjectRelationship')->search({
624 'me.subject_project_id' => $self->get_trial_id(),
625 'me.type_id' => $genotyping_trial_from_field_trial_cvterm_id
626 }, {
627 join => 'object_project', '+select' => ['object_project.name'], '+as' => ['source_trial_name']
630 my @projects;
631 while (my $r = $trial_rs->next) {
632 push @projects, [ $r->object_project_id, $r->get_column('source_trial_name') ];
634 return \@projects;
637 =head2 function get_field_trials_source_of_crossing_trial()
639 Usage:
640 Desc: return associated crossing trials for athe current field trial
641 Ret: returns an arrayref [ id, name ] of arrayrefs
642 Args:
643 Side Effects:
644 Example:
646 =cut
648 sub get_field_trials_source_of_crossing_trial {
649 my $self = shift;
650 my $schema = $self->bcs_schema;
651 my $genotyping_trial_from_field_trial_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'crossing_trial_from_field_trial', 'project_relationship')->cvterm_id();
653 my $trial_rs= $self->bcs_schema->resultset('Project::ProjectRelationship')->search({
654 'me.object_project_id' => $self->get_trial_id(),
655 'me.type_id' => $genotyping_trial_from_field_trial_cvterm_id
656 }, {
657 join => 'subject_project', '+select' => ['subject_project.name'], '+as' => ['source_trial_name']
660 my @projects;
661 while (my $r = $trial_rs->next) {
662 push @projects, [ $r->subject_project_id, $r->get_column('source_trial_name') ];
664 return \@projects;
668 =head2 function get_project_type()
670 Usage: [ $project_type_cvterm_id, $project_type_name ] = $t -> get_project_type();
671 Desc:
672 Ret:
673 Args:
674 Side Effects:
675 Example:
677 =cut
679 sub get_project_type {
680 my $self = shift;
682 my @project_type_ids = CXGN::Trial::get_all_project_types($self->bcs_schema());
684 my @ids = map { $_->[0] } @project_type_ids;
685 my $rs = $self->bcs_schema()->resultset('Project::Projectprop')->search(
687 type_id => { -in => [ @ids ] },
688 project_id => $self->get_trial_id()
691 if ($rs->count() > 0) {
692 my $type_id = $rs->first()->type_id();
693 foreach my $pt (@project_type_ids) {
694 if ($type_id == $pt->[0]) {
695 #print STDERR "[get_project_type] ".$pt->[0]." ".$pt->[1]."\n";
696 return $pt;
700 return undef;
705 =head2 function set_project_type()
707 Usage: $t -> set_project_type($type);
708 Desc:
709 Ret:
710 Args:
711 Side Effects:
712 Example:
714 =cut
716 sub set_project_type {
717 my $self = shift;
718 my $type_id = shift;
719 my $project_id = $self->get_trial_id();
720 my @project_type_ids = CXGN::Trial::get_all_project_types($self->bcs_schema());
721 my $type;
723 foreach my $pt (@project_type_ids) {
724 if ($pt->[0] eq $type_id) {
725 $type = $pt->[1];
729 my @ids = map { $_->[0] } @project_type_ids;
730 my $rs = $self->bcs_schema()->resultset('Project::Projectprop')->search({
731 type_id => { -in => [ @ids ] },
732 project_id => $project_id
734 if (my $row = $rs->next()) {
735 $row->delete();
738 my $row = $self->bcs_schema()->resultset('Project::Projectprop')->create({
739 project_id => $project_id,
740 type_id => $type_id,
741 value => $type,
746 sub set_design_type {
747 my $self = shift;
748 my $design_type = shift;
750 my $design_cv_type = $self->bcs_schema->resultset('Cv::Cvterm')->find( { name => 'design' });
751 if (!$design_cv_type) {
752 print STDERR "Design CV term not found. Cannot set design type.\n";
753 return;
755 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find_or_create(
757 project_id => $self->get_trial_id(),
758 type_id => $design_cv_type->cvterm_id(),
760 $row->value($design_type);
761 $row->update();
764 =head2 accessors get_breeding_program(), set_breeding_program()
766 Usage:
767 Desc:
768 Ret:
769 Args:
770 Side Effects:
771 Example:
773 =cut
775 sub get_breeding_program {
777 my $self = shift;
779 my $rs = $self->bcs_schema()->resultset("Project::ProjectRelationship")->search({
780 subject_project_id => $self->get_trial_id(),
781 type_id => $self->get_breeding_program_trial_relationship_cvterm_id(),
783 if ($rs->count() == 0) {
784 return undef;
787 my $bp_rs = $self->bcs_schema()->resultset("Project::Project")->search({
788 project_id => $rs->first()->object_project_id()
790 if ($bp_rs->count > 0) {
791 return $bp_rs->first()->name();
794 return undef;
797 sub set_breeding_program {
798 my $self = shift;
799 my $breeding_program_id = shift;
800 my $trial_id = $self->get_trial_id();
801 my $type_id = $self->get_breeding_program_trial_relationship_cvterm_id();
803 eval {
804 my $row = $self->bcs_schema->resultset("Project::ProjectRelationship")->find ({
805 subject_project_id => $trial_id,
806 type_id => $type_id,
809 if ($row) {
810 $row->object_project_id($breeding_program_id);
811 $row->update();
813 else {
814 $row = $self->bcs_schema->resultset("Project::ProjectRelationship")->create ({
815 object_project_id => $breeding_program_id,
816 subject_project_id => $trial_id,
817 type_id => $type_id,
819 $row->insert();
823 if ($@) {
824 print STDERR "ERROR: $@\n";
825 return { error => "An error occurred while setting the trial's breeding program." };
827 return {};
830 # CLASS METHOD!
832 =head2 class method get_all_project_types()
834 Usage: my @cvterm_ids = CXGN::Trial::get_all_project_types($schema)
835 Desc:
836 Ret:
837 Args:
838 Side Effects:
839 Example:
841 =cut
843 sub get_all_project_types {
844 ##my $class = shift;
845 my $schema = shift;
846 my $project_type_cv_id = $schema->resultset('Cv::Cv')->find( { name => 'project_type' } )->cv_id();
847 my $rs = $schema->resultset('Cv::Cvterm')->search( { cv_id=> $project_type_cv_id }, {order_by=>'me.cvterm_id'} );
848 my @cvterm_ids;
849 if ($rs->count() > 0) {
850 @cvterm_ids = map { [ $_->cvterm_id(), $_->name(), $_->definition ] } ($rs->all());
852 return @cvterm_ids;
855 =head2 accessors get_name(), set_name()
857 Usage:
858 Desc: retrieve and store project name from/to database
859 Ret:
860 Args:
861 Side Effects: setter modifies the database
862 Example:
864 =cut
866 sub get_name {
867 my $self = shift;
868 my $row = $self->bcs_schema->resultset('Project::Project')->find( { project_id => $self->get_trial_id() });
870 if ($row) {
871 return $row->name();
875 sub set_name {
876 my $self = shift;
877 my $name = shift;
878 my $row = $self->bcs_schema->resultset('Project::Project')->find( { project_id => $self->get_trial_id() });
879 if ($row) {
880 $row->name($name);
881 $row->update();
885 =head2 accessors get_harvest_date(), set_harvest_date()
887 Usage: $t->set_harvest_date("2016/09/17");
888 Desc: sets the projects harvest_date property.
889 The date format in the setter has to be
890 YYYY/MM/DD
891 Ret:
892 Args:
893 Side Effects:
894 Example:
896 =cut
898 sub get_harvest_date {
899 my $self = shift;
901 my $harvest_date_cvterm_id = $self->get_harvest_date_cvterm_id();
902 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find(
904 project_id => $self->get_trial_id(),
905 type_id => $harvest_date_cvterm_id,
908 my $calendar_funcs = CXGN::Calendar->new({});
910 if ($row) {
911 my $harvest_date = $calendar_funcs->display_start_date($row->value());
912 return $harvest_date;
913 } else {
914 return;
918 sub set_harvest_date {
919 my $self = shift;
920 my $harvest_date = shift;
922 my $calendar_funcs = CXGN::Calendar->new({});
924 if (my $harvest_event = $calendar_funcs->check_value_format($harvest_date) ) {
926 my $harvest_date_cvterm_id = $self->get_harvest_date_cvterm_id();
928 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find_or_create(
930 project_id => $self->get_trial_id(),
931 type_id => $harvest_date_cvterm_id,
934 $row->value($harvest_event);
935 $row->update();
936 } else {
937 print STDERR "date format did not pass check while preparing to set harvest date: $harvest_date \n";
941 sub remove_harvest_date {
942 my $self = shift;
943 my $harvest_date = shift;
945 my $calendar_funcs = CXGN::Calendar->new({});
946 if (my $harvest_event = $calendar_funcs->check_value_format($harvest_date) ) {
948 my $harvest_date_cvterm_id = $self->get_harvest_date_cvterm_id();
950 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find_or_create(
952 project_id => $self->get_trial_id(),
953 type_id => $harvest_date_cvterm_id,
954 value => $harvest_event,
957 if ($row) {
958 print STDERR "Removing harvest date $harvest_event from trial ".$self->get_trial_id()."\n";
959 $row->delete();
961 } else {
962 print STDERR "date format did not pass check while preparing to delete harvest date: $harvest_date \n";
967 =head2 accessors get_planting_date(), set_planting_date()
969 Usage:
970 Desc:
971 Ret:
972 Args:
973 Side Effects:
974 Example:
976 =cut
978 sub get_planting_date {
979 my $self = shift;
981 my $planting_date_cvterm_id = $self->get_planting_date_cvterm_id();
982 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find(
984 project_id => $self->get_trial_id(),
985 type_id => $planting_date_cvterm_id,
988 my $calendar_funcs = CXGN::Calendar->new({});
990 if ($row) {
991 my $harvest_date = $calendar_funcs->display_start_date($row->value());
992 return $harvest_date;
993 } else {
994 return;
998 sub set_planting_date {
999 my $self = shift;
1000 my $planting_date = shift;
1002 my $calendar_funcs = CXGN::Calendar->new({});
1004 if (my $planting_event = $calendar_funcs->check_value_format($planting_date) ) {
1006 my $planting_date_cvterm_id = $self->get_planting_date_cvterm_id();
1008 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find_or_create(
1010 project_id => $self->get_trial_id(),
1011 type_id => $planting_date_cvterm_id,
1014 $row->value($planting_event);
1015 $row->update();
1016 } else {
1017 print STDERR "date format did not pass check while preparing to set planting date: $planting_date \n";
1021 sub remove_planting_date {
1022 my $self = shift;
1023 my $planting_date = shift;
1025 my $calendar_funcs = CXGN::Calendar->new({});
1026 if (my $planting_event = $calendar_funcs->check_value_format($planting_date) ) {
1028 my $planting_date_cvterm_id = $self->get_planting_date_cvterm_id();
1030 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find_or_create(
1032 project_id => $self->get_trial_id(),
1033 type_id => $planting_date_cvterm_id,
1034 value => $planting_event,
1037 if ($row) {
1038 print STDERR "Removing planting date $planting_event from trial ".$self->get_trial_id()."\n";
1039 $row->delete();
1041 } else {
1042 print STDERR "date format did not pass check while preparing to delete planting date: $planting_date \n";
1046 =head2 accessors get_phenotypes_fully_uploaded(), set_phenotypes_fully_uploaded()
1048 Usage: When a trial's phenotypes have been fully upload, the user can set a projectprop called 'phenotypes_fully_uploaded' with a value of 1
1049 Desc:
1050 Ret:
1051 Args:
1052 Side Effects:
1053 Example:
1055 =cut
1057 sub get_phenotypes_fully_uploaded {
1058 my $self = shift;
1059 return $self->_get_projectprop('phenotypes_fully_uploaded');
1062 sub set_phenotypes_fully_uploaded {
1063 my $self = shift;
1064 my $value = shift;
1065 $self->_set_projectprop('phenotypes_fully_uploaded', $value);
1069 =head2 accessors get_genotyping_facility(), set_genotyping_facility()
1071 Usage: For genotyping plates, a genotyping facility can be set as a projectprop value e.g. 'igd'
1072 Desc:
1073 Ret:
1074 Args:
1075 Side Effects:
1076 Example:
1078 =cut
1080 sub get_genotyping_facility {
1081 my $self = shift;
1082 return $self->_get_projectprop('genotyping_facility');
1085 sub set_genotyping_facility {
1086 my $self = shift;
1087 my $value = shift;
1088 $self->_set_projectprop('genotyping_facility', $value);
1091 =head2 accessors get_genotyping_facility_submitted(), set_genotyping_facility_submitted()
1093 Usage: For genotyping plates, if a genotyping plate has been submitted to genotyping facility and the plate is stored in out system, this stockprop can be set to 'yes'
1094 Desc:
1095 Ret:
1096 Args:
1097 Side Effects:
1098 Example:
1100 =cut
1102 sub get_genotyping_facility_submitted {
1103 my $self = shift;
1104 return $self->_get_projectprop('genotyping_facility_submitted');
1107 sub set_genotyping_facility_submitted {
1108 my $self = shift;
1109 my $value = shift;
1110 $self->_set_projectprop('genotyping_facility_submitted', $value);
1113 =head2 accessors get_genotyping_facility_status(), set_genotyping_facility_status()
1115 Usage: For genotyping plates, if a genotyping plate has been submitted to genotyping facility, the status of that plate can be set here
1116 Desc:
1117 Ret:
1118 Args:
1119 Side Effects:
1120 Example:
1122 =cut
1124 sub get_genotyping_facility_status {
1125 my $self = shift;
1126 return $self->_get_projectprop('genotyping_facility_status');
1129 sub set_genotyping_facility_status {
1130 my $self = shift;
1131 my $value = shift;
1132 $self->_set_projectprop('genotyping_facility_status', $value);
1135 =head2 accessors get_genotyping_plate_format(), set_genotyping_plate_format()
1137 Usage: For genotyping plates, this records if it is 96 wells or 384 or other
1138 Desc:
1139 Ret:
1140 Args:
1141 Side Effects:
1142 Example:
1144 =cut
1146 sub get_genotyping_plate_format {
1147 my $self = shift;
1148 return $self->_get_projectprop('genotyping_plate_format');
1151 sub set_genotyping_plate_format {
1152 my $self = shift;
1153 my $value = shift;
1154 $self->_set_projectprop('genotyping_plate_format', $value);
1157 =head2 accessors get_genotyping_plate_sample_type(), set_genotyping_plate_sample_type()
1159 Usage: For genotyping plates, this records sample type of plate e.g. DNA
1160 Desc:
1161 Ret:
1162 Args:
1163 Side Effects:
1164 Example:
1166 =cut
1168 sub get_genotyping_plate_sample_type {
1169 my $self = shift;
1170 return $self->_get_projectprop('genotyping_plate_sample_type');
1173 sub set_genotyping_plate_sample_type {
1174 my $self = shift;
1175 my $value = shift;
1176 $self->_set_projectprop('genotyping_plate_sample_type', $value);
1179 =head2 accessors get_field_trial_is_planned_to_be_genotyped(), set_field_trial_is_planned_to_be_genotyped()
1181 Usage: For field trials, this records whether the trial will be genotyped
1182 Desc:
1183 Ret:
1184 Args:
1185 Side Effects:
1186 Example:
1188 =cut
1190 sub get_field_trial_is_planned_to_be_genotyped {
1191 my $self = shift;
1192 return $self->_get_projectprop('field_trial_is_planned_to_be_genotyped');
1195 sub set_field_trial_is_planned_to_be_genotyped {
1196 my $self = shift;
1197 my $value = shift;
1198 $self->_set_projectprop('field_trial_is_planned_to_be_genotyped', $value);
1201 =head2 accessors get_field_trial_is_planned_to_cross(), set_field_trial_is_planned_to_cross()
1203 Usage: For field trials, this records whether the trial will be involved in crosses
1204 Desc:
1205 Ret:
1206 Args:
1207 Side Effects:
1208 Example:
1210 =cut
1212 sub get_field_trial_is_planned_to_cross {
1213 my $self = shift;
1214 return $self->_get_projectprop('field_trial_is_planned_to_cross');
1217 sub set_field_trial_is_planned_to_cross {
1218 my $self = shift;
1219 my $value = shift;
1220 $self->_set_projectprop('field_trial_is_planned_to_cross', $value);
1223 =head2 accessors get_plot_width(), set_plot_width()
1225 Usage: For field trials, this records plot width in meters
1226 Desc:
1227 Ret:
1228 Args:
1229 Side Effects:
1230 Example:
1232 =cut
1234 sub get_plot_width {
1235 my $self = shift;
1236 return $self->_get_projectprop('plot_width');
1239 sub set_plot_width {
1240 my $self = shift;
1241 my $value = shift;
1242 $self->_set_projectprop('plot_width', $value);
1245 =head2 accessors get_plot_length(), set_plot_length()
1247 Usage: For field trials, this records plot length in meters
1248 Desc:
1249 Ret:
1250 Args:
1251 Side Effects:
1252 Example:
1254 =cut
1256 sub get_plot_length {
1257 my $self = shift;
1258 return $self->_get_projectprop('plot_length');
1261 sub set_plot_length {
1262 my $self = shift;
1263 my $value = shift;
1264 $self->_set_projectprop('plot_length', $value);
1267 =head2 accessors get_field_size(), set_field_size()
1269 Usage: For field trials, this recordsfield size in hectares
1270 Desc:
1271 Ret:
1272 Args:
1273 Side Effects:
1274 Example:
1276 =cut
1278 sub get_field_size {
1279 my $self = shift;
1280 return $self->_get_projectprop('field_size');
1283 sub set_field_size {
1284 my $self = shift;
1285 my $value = shift;
1286 $self->_set_projectprop('field_size', $value);
1290 sub _get_projectprop {
1291 my $self = shift;
1292 my $term = shift;
1293 my $cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, $term, 'project_property')->cvterm_id;
1294 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find({
1295 project_id => $self->get_trial_id(),
1296 type_id => $cvterm_id,
1299 if ($row) {
1300 return $row->value;
1301 } else {
1302 return;
1306 sub _set_projectprop {
1307 my $self = shift;
1308 my $term = shift;
1309 my $value = shift;
1310 my $cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, $term, 'project_property')->cvterm_id;
1311 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find_or_create({
1312 project_id => $self->get_trial_id(),
1313 type_id => $cvterm_id,
1315 $row->value($value);
1316 $row->update();
1319 =head2 function delete_phenotype_data()
1321 Usage:
1322 Desc:
1323 Ret:
1324 Args:
1325 Side Effects:
1326 Example:
1328 =cut
1330 # note: you may need to delete the metadata before deleting the phenotype data (see function).
1331 # this function has a test!
1333 sub delete_phenotype_data {
1334 my $self = shift;
1336 my $trial_id = $self->get_trial_id();
1338 eval {
1339 $self->bcs_schema->txn_do(
1340 sub {
1341 #print STDERR "\n\nDELETING PHENOTYPES...\n\n";
1343 # delete phenotype data associated with trial
1345 #my $trial = $self->bcs_schema()->resultset("Project::Project")->search( { project_id => $trial_id });
1347 my $q = "SELECT nd_experiment_id FROM nd_experiment_project JOIN nd_experiment_phenotype USING(nd_experiment_id) WHERE project_id =?";
1349 my $h = $self->bcs_schema()->storage()->dbh()->prepare($q);
1351 $h->execute($trial_id);
1352 my @nd_experiment_ids = ();
1353 while (my ($id) = $h->fetchrow_array()) {
1354 push @nd_experiment_ids, $id;
1356 print STDERR "GOING TO REMOVE ".scalar(@nd_experiment_ids)." EXPERIMENTS...\n";
1357 $self->_delete_phenotype_experiments(@nd_experiment_ids);
1363 if ($@) {
1364 print STDERR "ERROR DELETING PHENOTYPE DATA $@\n";
1365 return "Error deleting phenotype data for trial $trial_id. $@\n";
1367 return '';
1372 =head2 function delete_field_layout()
1374 Usage:
1375 Desc:
1376 Ret:
1377 Args:
1378 Side Effects:
1379 Example:
1381 =cut
1384 # this function has a test!
1386 sub delete_field_layout {
1387 my $self = shift;
1389 my $trial_id = $self->get_trial_id();
1391 # Note: metadata entries need to be deleted separately using delete_metadata()
1393 my $error = '';
1394 eval {
1395 $self->bcs_schema()->txn_do(
1396 sub {
1397 #print STDERR "DELETING FIELD LAYOUT FOR TRIAL $trial_id...\n";
1398 $self->_delete_field_layout_experiment();
1399 #print STDERR "DELETE MANAGEMENT FACTORS FOR TRIAL $trial_id...\n";
1400 $self->_delete_management_factors_experiments();
1404 if ($@) {
1405 print STDERR "ERROR $@\n";
1406 return "An error occurred: $@\n";
1409 return '';
1412 =head2 function get_phenotype_metadata()
1414 Usage: $trial->get_phenotype_metadata();
1415 Desc: retrieves metadata.md_file entries for this trial. These entries are created during StorePhenotypes
1416 Ret:
1417 Args:
1418 Side Effects:
1419 Example:
1421 =cut
1423 sub get_phenotype_metadata {
1424 my $self = shift;
1425 my $trial_id = $self->get_trial_id();
1426 my @file_array;
1427 my %file_info;
1428 my $q = "SELECT file_id, m.create_date, p.sp_person_id, p.username, basename, dirname, filetype FROM nd_experiment_project JOIN nd_experiment_phenotype USING(nd_experiment_id) JOIN phenome.nd_experiment_md_files ON (nd_experiment_phenotype.nd_experiment_id=nd_experiment_md_files.nd_experiment_id) LEFT JOIN metadata.md_files using(file_id) LEFT JOIN metadata.md_metadata as m using(metadata_id) LEFT JOIN sgn_people.sp_person as p ON (p.sp_person_id=m.create_person_id) WHERE project_id=? and m.obsolete = 0 and NOT (metadata.md_files.filetype='generated from plot from plant phenotypes') and NOT (metadata.md_files.filetype='direct phenotyping') ORDER BY file_id ASC";
1429 my $h = $self->bcs_schema->storage()->dbh()->prepare($q);
1430 $h->execute($trial_id);
1432 while (my ($file_id, $create_date, $person_id, $username, $basename, $dirname, $filetype) = $h->fetchrow_array()) {
1433 $file_info{$file_id} = [$file_id, $create_date, $person_id, $username, $basename, $dirname, $filetype];
1435 foreach (keys %file_info){
1436 push @file_array, $file_info{$_};
1438 return \@file_array;
1441 =head2 function delete_phenotype_metadata()
1443 Usage: $trial->delete_phenotype_metadata($metadata_schema, $phenome_schema);
1444 Desc: obsoletes the metadata entries for this trial.
1445 Ret:
1446 Args:
1447 Side Effects:
1448 Example:
1450 =cut
1452 sub delete_phenotype_metadata {
1453 my $self = shift;
1454 my $metadata_schema = shift;
1455 my $phenome_schema = shift;
1457 if (!$metadata_schema || !$phenome_schema) { die "Need metadata schema parameter\n"; }
1459 my $trial_id = $self->get_trial_id();
1461 #print STDERR "Deleting metadata for trial $trial_id...\n";
1463 # first, deal with entries in the md_metadata table, which may reference nd_experiment (through linking table)
1465 my $q = "SELECT distinct(metadata_id) FROM nd_experiment_project JOIN nd_experiment_phenotype USING(nd_experiment_id) LEFT JOIN phenome.nd_experiment_md_files ON (nd_experiment_phenotype.nd_experiment_id=nd_experiment_md_files.nd_experiment_id) LEFT JOIN metadata.md_files using(file_id) LEFT JOIN metadata.md_metadata using(metadata_id) WHERE project_id=?";
1466 my $h = $self->bcs_schema->storage()->dbh()->prepare($q);
1467 $h->execute($trial_id);
1469 while (my ($md_id) = $h->fetchrow_array()) {
1470 #print STDERR "Associated metadata id: $md_id\n";
1471 my $mdmd_row = $metadata_schema->resultset("MdMetadata")->find( { metadata_id => $md_id } );
1472 if ($mdmd_row) {
1473 #print STDERR "Obsoleting $md_id...\n";
1475 $mdmd_row -> update( { obsolete => 1 });
1479 #print STDERR "Deleting the entries in the linking table...\n";
1481 # delete the entries from the linking table...
1482 $q = "SELECT distinct(file_id) FROM nd_experiment_project JOIN nd_experiment_phenotype USING(nd_experiment_id) JOIN phenome.nd_experiment_md_files ON (nd_experiment_phenotype.nd_experiment_id=nd_experiment_md_files.nd_experiment_id) LEFT JOIN metadata.md_files using(file_id) LEFT JOIN metadata.md_metadata using(metadata_id) WHERE project_id=?";
1483 $h = $self->bcs_schema->storage()->dbh()->prepare($q);
1484 $h->execute($trial_id);
1486 while (my ($file_id) = $h->fetchrow_array()) {
1487 print STDERR "trying to delete association for file with id $file_id...\n";
1488 my $ndemdf_rs = $phenome_schema->resultset("NdExperimentMdFiles")->search( { file_id=>$file_id });
1489 print STDERR "Deleting md_files linking table entries...\n";
1490 foreach my $row ($ndemdf_rs->all()) {
1491 print STDERR "DELETING !!!!\n";
1492 $row->delete();
1499 =head2 function delete_metadata()
1501 Usage: $trial->delete_metadata();
1502 Desc: obsoletes the metadata entries for this trial.
1503 Ret:
1504 Args:
1505 Side Effects:
1506 Example:
1508 =cut
1510 sub delete_metadata {
1511 my $self = shift;
1512 my $metadata_schema = $self->metadata_schema;
1513 my $phenome_schema = $self->phenome_schema;
1515 if (!$metadata_schema || !$phenome_schema) { die "Need metadata schema parameter\n"; }
1517 my $trial_id = $self->get_trial_id();
1519 #print STDERR "Deleting metadata for trial $trial_id...\n";
1521 # first, deal with entries in the md_metadata table, which may reference nd_experiment (through linking table)
1523 my $q = "SELECT distinct(metadata_id) FROM nd_experiment_project JOIN phenome.nd_experiment_md_files using(nd_experiment_id) LEFT JOIN metadata.md_files using(file_id) LEFT JOIN metadata.md_metadata using(metadata_id) WHERE project_id=?";
1524 my $h = $self->bcs_schema->storage()->dbh()->prepare($q);
1525 $h->execute($trial_id);
1527 while (my ($md_id) = $h->fetchrow_array()) {
1528 #print STDERR "Associated metadata id: $md_id\n";
1529 my $mdmd_row = $metadata_schema->resultset("MdMetadata")->find( { metadata_id => $md_id } );
1530 if ($mdmd_row) {
1531 #print STDERR "Obsoleting $md_id...\n";
1533 $mdmd_row -> update( { obsolete => 1 });
1537 #print STDERR "Deleting the entries in the linking table...\n";
1539 # delete the entries from the linking table... (left joins are due to sometimes missing md_file entries)
1540 $q = "SELECT distinct(file_id) FROM nd_experiment_project LEFT JOIN phenome.nd_experiment_md_files using(nd_experiment_id) LEFT JOIN metadata.md_files using(file_id) LEFT JOIN metadata.md_metadata using(metadata_id) WHERE project_id=?";
1541 $h = $self->bcs_schema->storage()->dbh()->prepare($q);
1542 $h->execute($trial_id);
1544 while (my ($file_id) = $h->fetchrow_array()) {
1545 print STDERR "trying to delete association for file with id $file_id...\n";
1546 my $ndemdf_rs = $phenome_schema->resultset("NdExperimentMdFiles")->search( { file_id=>$file_id });
1547 print STDERR "Deleting md_files linking table entries...\n";
1548 foreach my $row ($ndemdf_rs->all()) {
1549 print STDERR "DELETING !!!!\n";
1550 $row->delete();
1556 sub _delete_phenotype_experiments {
1557 my $self = shift;
1558 my @nd_experiment_ids = @_;
1560 # retrieve the associated phenotype ids (they won't be deleted by the cascade)
1562 my $phenotypes_deleted = 0;
1563 my $nd_experiments_deleted = 0;
1565 foreach my $nde_id (@nd_experiment_ids) {
1566 my $nd_exp_phenotype_rs = $self->bcs_schema()->resultset("NaturalDiversity::NdExperimentPhenotype")->search( { nd_experiment_id => $nde_id }, { join => 'phenotype' });
1567 if ($nd_exp_phenotype_rs->count() > 0) {
1568 print STDERR "Deleting experiments ... \n";
1569 while (my $pep = $nd_exp_phenotype_rs->next()) {
1570 my $phenotype_rs = $self->bcs_schema()->resultset("Phenotype::Phenotype")->search( { phenotype_id => $pep->phenotype_id() } );
1571 print STDERR "DELETING ".$phenotype_rs->count(). " phenotypes\n";
1572 $phenotype_rs->delete_all();
1573 $phenotypes_deleted++;
1576 print STDERR "Deleting linking table entries...\n";
1577 $nd_exp_phenotype_rs->delete_all();
1581 # delete the experiments
1583 #print STDERR "Deleting experiments...\n";
1584 foreach my $nde_id (@nd_experiment_ids) {
1585 my $delete_rs = $self->bcs_schema()->resultset("NaturalDiversity::NdExperiment")->search({ nd_experiment_id => $nde_id });
1587 $nd_experiments_deleted++;
1589 $delete_rs->delete_all();
1591 return { phenotypes_deleted => $phenotypes_deleted,
1592 nd_experiments_deleted => $nd_experiments_deleted
1596 sub _delete_field_layout_experiment {
1597 my $self = shift;
1599 my $trial_id = $self->get_trial_id();
1601 print STDERR "_delete_field_layout_experiment...\n";
1603 # check if there are still associated phenotypes...
1605 if ($self->phenotype_count() > 0) {
1606 print STDERR "Attempt to delete field layout that still has associated phenotype data.\n";
1607 die "cannot delete because of associated phenotypes\n";
1608 return { error => "Trial still has associated phenotyping experiment, cannot delete." };
1611 my $field_layout_type_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'field_layout', 'experiment_type')->cvterm_id();
1612 my $genotyping_layout_type_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'genotyping_layout', 'experiment_type')->cvterm_id();
1614 my $layout_design = $self->get_layout->get_design;
1615 my @all_stock_ids;
1616 while( my($plot_num, $design_info) = each %$layout_design){
1617 my $plot_id = $design_info->{plot_id}; #this includes the "tissue_sample" in "genotyping_layout"
1618 my @plant_ids = $design_info->{plant_ids} ? @{$design_info->{plant_ids}} : ();
1619 my @subplot_ids = $design_info->{subplot_ids} ? @{$design_info->{subplot_ids}} : ();
1620 my @tissue_sample_ids = $design_info->{tissue_sample_ids} ? @{$design_info->{tissue_sample_ids}} : ();
1621 push @all_stock_ids, $plot_id;
1622 push @all_stock_ids, @plant_ids;
1623 push @all_stock_ids, @subplot_ids;
1624 push @all_stock_ids, @tissue_sample_ids;
1627 #print STDERR Dumper \@all_stock_ids;
1628 my $stock_delete_rs = $self->bcs_schema->resultset('Stock::Stock')->search({stock_id=>{'-in'=>\@all_stock_ids}});
1629 $stock_delete_rs->delete();
1631 my $has_plants = $self->has_plant_entries();
1632 my $has_subplots = $self->has_subplot_entries();
1633 my $has_tissues = $self->has_tissue_sample_entries();
1635 if ($has_plants) {
1636 my $has_plants_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'project_has_plant_entries', 'project_property' )->cvterm_id();
1637 my $has_plants_prop = $self->bcs_schema->resultset("Project::Projectprop")->find({ type_id => $has_plants_cvterm_id, project_id => $trial_id });
1638 $has_plants_prop->delete();
1640 if ($has_subplots) {
1641 my $has_subplots_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'project_has_subplot_entries', 'project_property' )->cvterm_id();
1642 my $has_subplots_prop = $self->bcs_schema->resultset("Project::Projectprop")->find({ type_id => $has_subplots_cvterm_id, project_id => $trial_id });
1643 $has_subplots_prop->delete();
1645 if ($has_tissues) {
1646 my $has_tissues_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'project_has_tissue_sample_entries', 'project_property' )->cvterm_id();
1647 my $has_tissues_prop = $self->bcs_schema->resultset("Project::Projectprop")->find({ type_id => $has_tissues_cvterm_id, project_id => $trial_id });
1648 $has_tissues_prop->delete();
1651 my $trial_layout_json_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'trial_layout_json', 'project_property')->cvterm_id();
1652 my $has_cached_layout_prop = $self->bcs_schema->resultset("Project::Projectprop")->find({ type_id => $trial_layout_json_cvterm_id, project_id => $trial_id });
1653 if ($has_cached_layout_prop){
1654 $has_cached_layout_prop->delete();
1657 my $nde_rs = $self->bcs_schema()->resultset("NaturalDiversity::NdExperiment")->search({ 'me.type_id'=>[$field_layout_type_id, $genotyping_layout_type_id], 'project.project_id'=>$trial_id }, {'join'=>{'nd_experiment_projects'=>'project'}});
1658 if ($nde_rs->count != 1){
1659 die "Trial $trial_id does not have exactly one ndexperiment of type field_layout or genotyping_layout!"
1661 while( my $r = $nde_rs->next){
1662 $r->delete();
1665 #return { success => $plots_deleted };
1666 return { success => 1 };
1669 sub _delete_management_factors_experiments {
1670 my $self = shift;
1671 my $management_factor_type_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'treatment_experiment', 'experiment_type')->cvterm_id();
1672 my $management_factors = $self->get_treatments;
1673 foreach (@$management_factors){
1674 my $m = CXGN::Trial->new({
1675 bcs_schema => $self->bcs_schema,
1676 metadata_schema => $self->metadata_schema,
1677 phenome_schema => $self->phenome_schema,
1678 trial_id => $_->[0]
1680 my $nde_rs = $self->bcs_schema()->resultset("NaturalDiversity::NdExperiment")->search({ 'me.type_id'=>$management_factor_type_id, 'project.project_id'=>$m->get_trial_id }, {'join'=>{'nd_experiment_projects'=>'project'}});
1681 if ($nde_rs->count != 1){
1682 die "Management factor ".$m->get_name." does not have exactly one ndexperiment of type treatment_experiment!"
1684 while( my $r = $nde_rs->next){
1685 $r->delete();
1687 $m->delete_project_entry;
1689 return { success => 1 };
1692 =head2 function delete_project_entry()
1694 Usage:
1695 Desc:
1696 Ret:
1697 Args:
1698 Side Effects:
1699 Example:
1701 =cut
1703 sub delete_project_entry {
1704 my $self = shift;
1706 if ($self->phenotype_count() > 0) {
1707 print STDERR "Cannot delete trial with associated phenotypes.\n";
1708 return;
1710 if (my $count = $self->get_experiment_count() > 0) {
1711 print STDERR "Cannot delete trial with associated experiments ($count)\n";
1712 return "Cannot delete entry because of associated experiments";
1715 eval {
1716 my $row = $self->bcs_schema->resultset("Project::Project")->find( { project_id=> $self->get_trial_id() });
1717 $row->delete();
1718 print STDERR "deleted project ".$self->get_trial_id."\n";
1720 if ($@) {
1721 print STDERR "An error occurred during deletion: $@\n";
1722 return $@;
1726 =head2 function phenotype_count()
1728 Usage:
1729 Desc: The number of phenotype measurements associated with this trial
1730 Ret:
1731 Args:
1732 Side Effects:
1733 Example:
1735 =cut
1738 sub phenotype_count {
1739 my $self = shift;
1741 my $phenotyping_experiment_type_id = $self->bcs_schema->resultset("Cv::Cvterm")->find( { name => 'phenotyping_experiment' })->cvterm_id();
1743 my $phenotype_experiment_rs = $self->bcs_schema()->resultset("NaturalDiversity::NdExperimentProject")->search(
1745 project_id => $self->get_trial_id(), 'nd_experiment.type_id' => $phenotyping_experiment_type_id},
1747 join => 'nd_experiment'
1751 return $phenotype_experiment_rs->count();
1755 =head2 function total_phenotypes()
1757 Usage:
1758 Desc: returns the total number of phenotype measurements
1759 associated with the trial
1760 Ret:
1761 Args:
1762 Side Effects:
1763 Example:
1765 =cut
1767 sub total_phenotypes {
1768 my $self = shift;
1770 my $pt_rs = $self->bcs_schema()->resultset("Phenotype::Phenotype")->search( { });
1771 return $pt_rs->count();
1774 =head2 function add_additional_uploaded_file()
1776 Usage: $trial->add_additional_uploaded_file();
1777 Desc: adds metadata.md_file entry for additional_files_uploaded to trial
1778 Ret:
1779 Args:
1780 Side Effects:
1781 Example:
1783 =cut
1785 sub add_additional_uploaded_file {
1786 my $self = shift;
1787 my $user_id = shift;
1788 my $archived_filename_with_path = shift;
1789 my $md5checksum = shift;
1790 my $result = $self->get_nd_experiment_id();
1791 if ($result->{error}){
1792 return {error => $result->{error} };
1794 my $nd_experiment_id = $result->{nd_experiment_id};
1796 my $md_row = $self->metadata_schema->resultset("MdMetadata")->create({create_person_id => $user_id});
1797 $md_row->insert();
1798 my $file_row = $self->metadata_schema->resultset("MdFiles")
1799 ->create({
1800 basename => basename($archived_filename_with_path),
1801 dirname => dirname($archived_filename_with_path),
1802 filetype => 'trial_additional_file_upload',
1803 md5checksum => $md5checksum,
1804 metadata_id => $md_row->metadata_id(),
1806 my $file_id = $file_row->file_id();
1807 my $experiment_file = $self->phenome_schema->resultset("NdExperimentMdFiles")
1808 ->create({
1809 nd_experiment_id => $nd_experiment_id,
1810 file_id => $file_id,
1813 return {success => 1, file_id=>$file_id};
1816 =head2 function get_additional_uploaded_files()
1818 Usage: $trial->get_additional_uploaded_files();
1819 Desc: retrieves metadata.md_file entries for additional_files_uploaded to trial. these entries are created from add_additional_uploaded_file
1820 Ret:
1821 Args:
1822 Side Effects:
1823 Example:
1825 =cut
1827 sub get_additional_uploaded_files {
1828 my $self = shift;
1829 my $trial_id = $self->get_trial_id();
1830 my @file_array;
1831 my %file_info;
1832 my $q = "SELECT file_id, m.create_date, p.sp_person_id, p.username, basename, dirname, filetype FROM project JOIN nd_experiment_project USING(project_id) JOIN phenome.nd_experiment_md_files ON (nd_experiment_project.nd_experiment_id=nd_experiment_md_files.nd_experiment_id) LEFT JOIN metadata.md_files using(file_id) LEFT JOIN metadata.md_metadata as m using(metadata_id) LEFT JOIN sgn_people.sp_person as p ON (p.sp_person_id=m.create_person_id) WHERE project_id=? and m.obsolete = 0 and metadata.md_files.filetype='trial_additional_file_upload' ORDER BY file_id ASC";
1833 my $h = $self->bcs_schema->storage()->dbh()->prepare($q);
1834 $h->execute($trial_id);
1836 while (my ($file_id, $create_date, $person_id, $username, $basename, $dirname, $filetype) = $h->fetchrow_array()) {
1837 $file_info{$file_id} = [$file_id, $create_date, $person_id, $username, $basename, $dirname, $filetype];
1839 foreach (keys %file_info){
1840 push @file_array, $file_info{$_};
1842 return \@file_array;
1845 =head2 function get_phenotypes_for_trait($trait_id)
1847 Usage:
1848 Desc: returns the measurements for the given trait in this trial as an array of values, e.g. [2.1, 2, 50]
1849 Ret:
1850 Args:
1851 Side Effects:
1852 Example:
1854 =cut
1856 sub get_phenotypes_for_trait {
1857 my $self = shift;
1858 my $trait_id = shift;
1859 my $stock_type = shift;
1860 my @data;
1861 my $dbh = $self->bcs_schema->storage()->dbh();
1862 #my $schema = $self->bcs_schema();
1864 my $h;
1865 my $join_string = '';
1866 my $where_string = '';
1867 if ($stock_type) {
1868 my $stock_type_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, $stock_type, 'stock_type')->cvterm_id();
1869 $join_string = 'JOIN nd_experiment_stock USING(nd_experiment_id) JOIN stock USING(stock_id)';
1870 $where_string = "stock.type_id=$stock_type_id and";
1872 my $q = "SELECT phenotype.value::real FROM cvterm JOIN phenotype ON (cvterm_id=cvalue_id) JOIN nd_experiment_phenotype USING(phenotype_id) JOIN nd_experiment_project USING(nd_experiment_id) $join_string WHERE $where_string project_id=? and cvterm.cvterm_id = ? and phenotype.value~? ORDER BY phenotype_id ASC;";
1873 $h = $dbh->prepare($q);
1875 my $numeric_regex = '^[0-9]+([,.][0-9]+)?$';
1876 $h->execute($self->get_trial_id(), $trait_id, $numeric_regex );
1877 while (my ($value) = $h->fetchrow_array()) {
1878 push @data, $value + 0;
1880 return @data;
1883 =head2 function get_stock_phenotypes_for_traits(\@trait_id, 'all', ['plot_of','plant_of'], 'accession', 'subject')
1885 Usage:
1886 Desc: returns all observations for the given traits in this trial
1887 Ret: arrayref of [[ $stock_id, $stock_name, $trait_id, $trait_name, $phenotype_id, $pheno_uniquename, $uploader_id, $value, $rel_stock_id, $rel_stock_name ], [], ...]
1888 Args: trait_ids : arrayref of cvterm_ids
1889 stock_type: the stock type that the phenotype is associated to. 'plot', or 'plant', or 'all'
1890 stock_relationships: for fetching stock_relationships of the phenotyped stock. arrayref of relationships. e.g. ['plot_of', 'plant_of'].
1891 relationship_stock_type: the associated stock_type from the stock_relationship. 'plot', or 'plant'
1892 subject_or_object: whether the stock_relationship join should be done from the subject or object side. 'subject', or 'object'
1893 Side Effects:
1894 Example:
1896 =cut
1898 sub get_stock_phenotypes_for_traits {
1899 my $self = shift;
1900 my $trait_ids = shift;
1901 my $stock_type = shift; #plot, plant, all
1902 my $stock_relationships = shift; #arrayref. plot_of, plant_of
1903 my $relationship_stock_type = shift; #plot, plant
1904 my $subject_or_object = shift;
1905 my @data;
1906 #$self->bcs_schema->storage->debug(1);
1907 my $dbh = $self->bcs_schema->storage()->dbh();
1908 my $where_clause = "WHERE project_id=? and b.cvterm_id = ? and phenotype.value~? ";
1909 my $phenotyping_experiment_cvterm = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'phenotyping_experiment', 'experiment_type')->cvterm_id();
1911 if (scalar(@$trait_ids)>0){
1912 my $sql_trait_ids = join ("," , @$trait_ids);
1913 $where_clause .= "and a.cvterm_id IN ($sql_trait_ids) ";
1916 my $relationship_join = '';
1917 if ($subject_or_object eq 'object') {
1918 $relationship_join = 'JOIN stock_relationship on (stock.stock_id=stock_relationship.object_id) JOIN stock as rel_stock on (stock_relationship.subject_id=rel_stock.stock_id) ';
1919 } elsif ($subject_or_object eq 'subject') {
1920 $relationship_join = 'JOIN stock_relationship on (stock.stock_id=stock_relationship.subject_id) JOIN stock as rel_stock on (stock_relationship.object_id=rel_stock.stock_id) ';
1922 if ($stock_type ne 'all') {
1923 my $stock_type_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema(), $stock_type, 'stock_type')->cvterm_id();
1924 $where_clause .= "and stock.type_id=$stock_type_cvterm_id ";
1926 my @stock_rel_or;
1927 foreach (@$stock_relationships) {
1928 my $stock_relationship_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema(), $_, 'stock_relationship')->cvterm_id();
1929 push @stock_rel_or, "stock_relationship.type_id=$stock_relationship_cvterm_id";
1931 my $stock_rel_or_sql = join (" OR " , @stock_rel_or);
1932 if ($stock_rel_or_sql) {
1933 $where_clause .= "and ($stock_rel_or_sql) ";
1935 my $rel_stock_type_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema(), $relationship_stock_type, 'stock_type')->cvterm_id();
1936 $where_clause .= "and rel_stock.type_id=$rel_stock_type_cvterm_id ";
1938 my $q = "SELECT stock.stock_id, stock.uniquename, a.cvterm_id, a.name || '|' || db.name || ':' || dbxref.accession, phenotype.phenotype_id, phenotype.uniquename, phenotype.sp_person_id, phenotype.value::real, rel_stock.stock_id, rel_stock.uniquename, stock_type.name
1939 FROM cvterm as a
1940 JOIN dbxref ON (a.dbxref_id = dbxref.dbxref_id)
1941 JOIN db USING(db_id)
1942 JOIN phenotype ON (a.cvterm_id=cvalue_id)
1943 JOIN nd_experiment_phenotype USING(phenotype_id)
1944 JOIN nd_experiment_project USING(nd_experiment_id)
1945 JOIN nd_experiment_stock USING(nd_experiment_id)
1946 JOIN cvterm as b ON (b.cvterm_id=nd_experiment_stock.type_id)
1947 JOIN stock USING(stock_id)
1948 JOIN cvterm as stock_type ON (stock_type.cvterm_id=stock.type_id)
1949 $relationship_join
1950 $where_clause
1951 ORDER BY stock.stock_id;";
1952 my $h = $dbh->prepare($q);
1954 my $numeric_regex = '^[0-9]+([,.][0-9]+)?$';
1955 $h->execute($self->get_trial_id(), $phenotyping_experiment_cvterm, $numeric_regex );
1956 while (my ($stock_id, $stock_name, $trait_id, $trait_name, $phenotype_id, $pheno_uniquename, $uploader_id, $value, $rel_stock_id, $rel_stock_name, $stock_type) = $h->fetchrow_array()) {
1957 push @data, [$stock_id, $stock_name, $trait_id, $trait_name, $phenotype_id, $pheno_uniquename, $uploader_id, $value + 0, $rel_stock_id, $rel_stock_name, $stock_type];
1959 return \@data;
1962 =head2 function get_traits_assayed()
1964 Usage:
1965 Desc: returns the cvterm_id and name for traits assayed
1966 Ret:
1967 Args: stock_type can be the cvterm name for a specific stock type like 'plot'. not providing stock_type will return all traits assayed in the trial. trait_format can be for only returning numeric, categorical, etc traits. not providing trait_format will return all trait types.
1968 Side Effects:
1969 Example:
1971 =cut
1973 sub get_traits_assayed {
1974 my $self = shift;
1975 my $stock_type = shift;
1976 my $trait_format = shift;
1977 my $dbh = $self->bcs_schema->storage()->dbh();
1979 my @traits_assayed;
1981 my $cvtermprop_join = '';
1982 my $cvtermprop_where = '';
1983 if ($trait_format){
1984 my $trait_format_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema(), 'trait_format', 'trait_property')->cvterm_id();
1985 $cvtermprop_join = ' JOIN cvtermprop ON (cvtermprop.cvterm_id = cvterm.cvterm_id) ';
1986 $cvtermprop_where = " AND cvtermprop.type_id = $trait_format_cvterm_id AND cvtermprop.value = '$trait_format' ";
1989 my $q;
1990 if ($stock_type) {
1991 my $stock_type_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema(), $stock_type, 'stock_type')->cvterm_id();
1992 $q = "SELECT (((cvterm.name::text || '|'::text) || db.name::text) || ':'::text) || dbxref.accession::text AS trait, cvterm.cvterm_id, count(phenotype.value) FROM cvterm $cvtermprop_join JOIN dbxref ON (cvterm.dbxref_id = dbxref.dbxref_id) JOIN db ON (dbxref.db_id = db.db_id) JOIN phenotype ON (cvterm.cvterm_id=phenotype.cvalue_id) JOIN nd_experiment_phenotype USING(phenotype_id) JOIN nd_experiment_project USING(nd_experiment_id) JOIN nd_experiment_stock USING(nd_experiment_id) JOIN stock on (stock.stock_id = nd_experiment_stock.stock_id) WHERE stock.type_id=$stock_type_cvterm_id and project_id=? $cvtermprop_where GROUP BY trait, cvterm.cvterm_id ORDER BY trait;";
1993 } else {
1994 $q = "SELECT (((cvterm.name::text || '|'::text) || db.name::text) || ':'::text) || dbxref.accession::text AS trait, cvterm.cvterm_id, count(phenotype.value) FROM cvterm $cvtermprop_join JOIN dbxref ON (cvterm.dbxref_id = dbxref.dbxref_id) JOIN db ON (dbxref.db_id = db.db_id) JOIN phenotype ON (cvterm.cvterm_id=phenotype.cvalue_id) JOIN nd_experiment_phenotype USING(phenotype_id) JOIN nd_experiment_project USING(nd_experiment_id) WHERE project_id=? $cvtermprop_where GROUP BY trait, cvterm.cvterm_id ORDER BY trait;";
1997 my $traits_assayed_q = $dbh->prepare($q);
1999 $traits_assayed_q->execute($self->get_trial_id());
2000 while (my ($trait_name, $trait_id, $count) = $traits_assayed_q->fetchrow_array()) {
2001 push @traits_assayed, [$trait_id, $trait_name];
2003 return \@traits_assayed;
2006 =head2 function get_trait_components_assayed()
2008 Usage:
2009 Desc: returns the cvterm_id and name for trait components assayed
2010 Ret:
2011 Args:
2012 Side Effects:
2013 Example:
2015 =cut
2017 sub get_trait_components_assayed {
2018 my $self = shift;
2019 my $stock_type = shift;
2020 my $composable_cvterm_format = shift;
2021 my $dbh = $self->bcs_schema->storage()->dbh();
2022 my $traits_assayed = $self->get_traits_assayed($stock_type);
2024 my %unique_components;
2025 my @trait_components_assayed;
2026 foreach (@$traits_assayed){
2027 my $trait_components = SGN::Model::Cvterm->get_components_from_trait($self->bcs_schema, $_->[0]);
2028 foreach (@$trait_components){
2029 if (!exists($unique_components{$_})){
2030 my $component_cvterm = SGN::Model::Cvterm::get_trait_from_cvterm_id($self->bcs_schema, $_, $composable_cvterm_format);
2031 push @trait_components_assayed, [$_, $component_cvterm];
2032 $unique_components{$_}++;
2036 return \@trait_components_assayed;
2039 =head2 function get_experiment_count()
2041 Usage:
2042 Desc: return the total number of experiments associated
2043 with the trial.
2044 Ret:
2045 Args:
2046 Side Effects:
2047 Example:
2049 =cut
2051 sub get_experiment_count {
2052 my $self = shift;
2054 my $rs = $self->bcs_schema->resultset('NaturalDiversity::NdExperimentProject')->search( { project_id => $self->get_trial_id() });
2055 return $rs->count();
2058 sub get_location_type_id {
2059 my $self = shift;
2060 my $rs = $self->bcs_schema->resultset('Cv::Cvterm')->search( { name => 'project location' });
2062 if ($rs->count() > 0) {
2063 return $rs->first()->cvterm_id();
2068 sub get_year_type_id {
2069 my $self = shift;
2071 my $rs = $self->bcs_schema->resultset('Cv::Cvterm')->search( { name => 'project year' });
2073 return $rs->first()->cvterm_id();
2076 sub get_breeding_program_trial_relationship_cvterm_id {
2077 my $self = shift;
2079 my $breeding_program_trial_relationship_cvterm_id;
2080 my $breeding_program_trial_relationship_cvterm = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'breeding_program_trial_relationship', 'project_relationship');
2081 if ($breeding_program_trial_relationship_cvterm) {
2082 $breeding_program_trial_relationship_cvterm_id = $breeding_program_trial_relationship_cvterm->cvterm_id();
2085 return $breeding_program_trial_relationship_cvterm_id;
2088 sub get_breeding_program_cvterm_id {
2089 my $self = shift;
2091 my $breeding_program_cvterm_id;
2092 my $breeding_program_cvterm = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'breeding_program', 'project_property');
2093 if ($breeding_program_cvterm) {
2094 $breeding_program_cvterm_id = $breeding_program_cvterm->cvterm_id();
2097 return $breeding_program_cvterm_id;
2100 sub get_folder {
2101 my $self = shift;
2103 my $f = CXGN::Trial::Folder->new( { bcs_schema => $self->bcs_schema(), folder_id => $self->get_trial_id() });
2105 my $parent_folder_data = $f->project_parent();
2107 if ($parent_folder_data) {
2108 return $parent_folder_data;
2110 else {
2111 return;
2115 sub get_harvest_date_cvterm_id {
2116 my $self = shift;
2118 my $harvest_date_cvterm_id;
2119 my $harvest_date_cvterm = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'project_harvest_date', 'project_property');
2120 if ($harvest_date_cvterm) {
2121 $harvest_date_cvterm_id = $harvest_date_cvterm->cvterm_id();
2124 return $harvest_date_cvterm_id;
2128 =head2 function create_plant_entities()
2130 Usage: $trial->create_plant_entries($plants_per_plot);
2131 Desc: Some trials require plant-level data. This function will
2132 add an additional layer of plant entries for each plot.
2133 Ret:
2134 Args: the number of plants per plot to add.
2135 Side Effects:
2136 Example:
2138 =cut
2140 sub create_plant_entities {
2141 my $self = shift;
2142 my $plants_per_plot = shift || 30;
2143 my $inherits_plot_treatments = shift;
2145 my $create_plant_entities_txn = sub {
2146 my $chado_schema = $self->bcs_schema();
2147 my $layout = CXGN::Trial::TrialLayout->new( { schema => $chado_schema, trial_id => $self->get_trial_id(), experiment_type=>'field_layout' });
2148 my $design = $layout->get_design();
2150 my $accession_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'accession', 'stock_type')->cvterm_id();
2151 my $plant_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plant', 'stock_type')->cvterm_id();
2152 my $plot_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plot', 'stock_type')->cvterm_id();
2153 my $plot_relationship_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plot_of', 'stock_relationship')->cvterm_id();
2154 my $plant_relationship_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plant_of', 'stock_relationship')->cvterm_id();
2155 my $plant_index_number_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plant_index_number', 'stock_property')->cvterm_id();
2156 my $block_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'block', 'stock_property')->cvterm_id();
2157 my $plot_number_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plot number', 'stock_property')->cvterm_id();
2158 my $replicate_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'replicate', 'stock_property')->cvterm_id();
2159 my $has_plants_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'project_has_plant_entries', 'project_property')->cvterm_id();
2160 my $field_layout_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'field_layout', 'experiment_type')->cvterm_id();
2161 my $treatment_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'treatment_experiment', 'experiment_type')->cvterm_id();
2162 #my $plants_per_plot_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plants_per_plot', 'project_property')->cvterm_id();
2164 my $treatments;
2165 my %treatment_experiments;
2166 my %treatment_plots;
2167 if ($inherits_plot_treatments){
2168 $treatments = $self->get_treatments();
2169 foreach (@$treatments){
2171 my $rs = $chado_schema->resultset("Project::Projectprop")->find_or_create({
2172 type_id => $has_plants_cvterm,
2173 value => $plants_per_plot,
2174 project_id => $_->[0],
2177 my $treatment_nd_experiment = $chado_schema->resultset("Project::Project")->search( { 'me.project_id' => $_->[0] }, {select=>['nd_experiment.nd_experiment_id']})->search_related('nd_experiment_projects')->search_related('nd_experiment', { type_id => $treatment_cvterm })->single();
2178 $treatment_experiments{$_->[0]} = $treatment_nd_experiment->nd_experiment_id();
2180 my $treatment_trial = CXGN::Trial->new({ bcs_schema => $chado_schema, trial_id => $_->[0]});
2181 my $plots = $treatment_trial->get_plots();
2182 foreach my $plot (@$plots){
2183 $treatment_plots{$_->[0]}->{$plot->[0]} = 1;
2188 my $rs = $chado_schema->resultset("Project::Projectprop")->find_or_create({
2189 type_id => $has_plants_cvterm,
2190 value => $plants_per_plot,
2191 project_id => $self->get_trial_id(),
2194 my $field_layout_experiment = $chado_schema->resultset("Project::Project")->search( { 'me.project_id' => $self->get_trial_id() }, {select=>['nd_experiment.nd_experiment_id']})->search_related('nd_experiment_projects')->search_related('nd_experiment', { type_id => $field_layout_cvterm })->single();
2196 foreach my $plot (keys %$design) {
2197 print STDERR " ... creating plants for plot $plot...\n";
2198 my $plot_row = $chado_schema->resultset("Stock::Stock")->find( { uniquename => $design->{$plot}->{plot_name}, type_id=>$plot_cvterm });
2200 if (! $plot_row) {
2201 print STDERR "The plot $plot is not found in the database\n";
2202 return "The plot $plot is not yet in the database. Cannot create plant entries.";
2205 my $parent_plot = $plot_row->stock_id();
2206 my $parent_plot_name = $plot_row->uniquename();
2207 my $parent_plot_organism = $plot_row->organism_id();
2209 foreach my $plant_index_number (1..$plants_per_plot) {
2210 my $plant_name = $parent_plot_name."_plant_$plant_index_number";
2211 #print STDERR "... ... creating plant $plant_name...\n";
2213 $self->_save_plant_entry($chado_schema, $accession_cvterm, $parent_plot_organism, $parent_plot_name, $parent_plot, $plant_name, $plant_cvterm, $plant_index_number, $plant_index_number_cvterm, $block_cvterm, $plot_number_cvterm, $replicate_cvterm, $plant_relationship_cvterm, $field_layout_experiment, $field_layout_cvterm, $inherits_plot_treatments, $treatments, $plot_relationship_cvterm, \%treatment_plots, \%treatment_experiments, $treatment_cvterm);
2217 $layout->generate_and_cache_layout();
2220 eval {
2221 $self->bcs_schema()->txn_do($create_plant_entities_txn);
2223 if ($@) {
2224 print STDERR "An error occurred creating the plant entities. $@\n";
2225 return 0;
2228 print STDERR "Plant entities created.\n";
2229 return 1;
2232 =head2 function save_plant_entries()
2234 Usage: $trial->save_plant_entries(\%data, $plants_per_plot, $inherits_plot_treatments);
2235 Desc: Some trials require plant-level data. It is possible to upload
2236 plant_names to save.
2237 Ret:
2238 Args: Requires $plants_per_plot and \%data which is a hashref of the data parsed from the
2239 uploaded file.
2240 example: { 'myplotname1' => { 'plot_stock_id'=>123, 'plant_names'=>['plot1_plant1', 'plot1_plant2'] }, ... }
2241 Side Effects:
2242 Example:
2244 =cut
2246 sub save_plant_entries {
2247 my $self = shift;
2248 my $parsed_data = shift;
2249 my $plants_per_plot = shift;
2250 my $inherits_plot_treatments = shift;
2252 my $create_plant_entities_txn = sub {
2253 my $chado_schema = $self->bcs_schema();
2254 my $layout = CXGN::Trial::TrialLayout->new( { schema => $chado_schema, trial_id => $self->get_trial_id(), experiment_type=>'field_layout' });
2255 my $design = $layout->get_design();
2257 my $accession_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'accession', 'stock_type')->cvterm_id();
2258 my $plant_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plant', 'stock_type')->cvterm_id();
2259 my $plot_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plot', 'stock_type')->cvterm_id();
2260 my $plot_relationship_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plot_of', 'stock_relationship')->cvterm_id();
2261 my $plant_relationship_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plant_of', 'stock_relationship')->cvterm_id();
2262 my $plant_index_number_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plant_index_number', 'stock_property')->cvterm_id();
2263 my $block_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'block', 'stock_property')->cvterm_id();
2264 my $plot_number_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plot number', 'stock_property')->cvterm_id();
2265 my $replicate_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'replicate', 'stock_property')->cvterm_id();
2266 my $has_plants_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'project_has_plant_entries', 'project_property')->cvterm_id();
2267 my $field_layout_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'field_layout', 'experiment_type')->cvterm_id();
2268 my $treatment_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'treatment_experiment', 'experiment_type')->cvterm_id();
2269 #my $plants_per_plot_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plants_per_plot', 'project_property')->cvterm_id();
2271 my $treatments;
2272 my %treatment_experiments;
2273 my %treatment_plots;
2274 if ($inherits_plot_treatments){
2275 $treatments = $self->get_treatments();
2276 foreach (@$treatments){
2278 my $rs = $chado_schema->resultset("Project::Projectprop")->find_or_create({
2279 type_id => $has_plants_cvterm,
2280 value => $plants_per_plot,
2281 project_id => $_->[0],
2284 my $treatment_nd_experiment = $chado_schema->resultset("Project::Project")->search( { 'me.project_id' => $_->[0] }, {select=>['nd_experiment.nd_experiment_id']})->search_related('nd_experiment_projects')->search_related('nd_experiment', { type_id => $treatment_cvterm })->single();
2285 $treatment_experiments{$_->[0]} = $treatment_nd_experiment->nd_experiment_id();
2287 my $treatment_trial = CXGN::Trial->new({ bcs_schema => $chado_schema, trial_id => $_->[0]});
2288 my $plots = $treatment_trial->get_plots();
2289 foreach my $plot (@$plots){
2290 $treatment_plots{$_->[0]}->{$plot->[0]} = 1;
2295 my $rs = $chado_schema->resultset("Project::Projectprop")->find_or_create({
2296 type_id => $has_plants_cvterm,
2297 value => $plants_per_plot,
2298 project_id => $self->get_trial_id(),
2302 my $field_layout_experiment = $chado_schema->resultset("Project::Project")->search( { 'me.project_id' => $self->get_trial_id() }, {select=>['nd_experiment.nd_experiment_id']})->search_related('nd_experiment_projects')->search_related('nd_experiment', { type_id => $field_layout_cvterm })->single();
2304 while( my ($key, $val) = each %$parsed_data){
2305 my $plot_stock_id = $key;
2306 my $plot_name = $val->{plot_name};
2307 print STDERR " ... creating plants for plot $plot_name...\n";
2308 my $plot_row = $chado_schema->resultset("Stock::Stock")->find( { stock_id=>$plot_stock_id });
2310 if (!$plot_row) {
2311 print STDERR "The plot $plot_name is not found in the database\n";
2312 return "The plot $plot_name is not yet in the database. Cannot create plant entries.";
2315 my $parent_plot = $plot_row->stock_id();
2316 my $parent_plot_name = $plot_row->uniquename();
2317 my $parent_plot_organism = $plot_row->organism_id();
2319 my $plant_index_number = 1;
2320 my $plant_names = $val->{plant_names};
2321 my $plant_index_numbers = $val->{plant_index_numbers};
2322 my $increment = 0;
2323 foreach my $plant_name (@$plant_names) {
2324 my $given_plant_index_number = $plant_index_numbers->[$increment];
2325 my $plant_index_number_save = $given_plant_index_number ? $given_plant_index_number : $plant_index_number;
2327 $self->_save_plant_entry($chado_schema, $accession_cvterm, $parent_plot_organism, $parent_plot_name, $parent_plot, $plant_name, $plant_cvterm, $plant_index_number_save, $plant_index_number_cvterm, $block_cvterm, $plot_number_cvterm, $replicate_cvterm, $plant_relationship_cvterm, $field_layout_experiment, $field_layout_cvterm, $inherits_plot_treatments, $treatments, $plot_relationship_cvterm, \%treatment_plots, \%treatment_experiments, $treatment_cvterm);
2328 $plant_index_number++;
2329 $increment++;
2333 $layout->generate_and_cache_layout();
2336 eval {
2337 $self->bcs_schema()->txn_do($create_plant_entities_txn);
2339 if ($@) {
2340 print STDERR "An error occurred creating the plant entities. $@\n";
2341 return 0;
2344 print STDERR "Plant entities created.\n";
2345 return 1;
2348 sub _save_plant_entry {
2349 my $self = shift;
2350 my $chado_schema = shift;
2351 my $accession_cvterm = shift;
2352 my $parent_plot_organism = shift;
2353 my $parent_plot_name = shift;
2354 my $parent_plot = shift;
2355 my $plant_name = shift;
2356 my $plant_cvterm = shift;
2357 my $plant_index_number = shift;
2358 my $plant_index_number_cvterm = shift;
2359 my $block_cvterm = shift;
2360 my $plot_number_cvterm = shift;
2361 my $replicate_cvterm = shift;
2362 my $plant_relationship_cvterm = shift;
2363 my $field_layout_experiment = shift;
2364 my $field_layout_cvterm = shift;
2365 my $inherits_plot_treatments = shift;
2366 my $treatments = shift;
2367 my $plot_relationship_cvterm = shift;
2368 my $treatment_plots_ref = shift;
2369 my $treatment_experiments_ref = shift;
2370 my $treatment_cvterm = shift;
2371 my %treatment_plots = %$treatment_plots_ref;
2372 my %treatment_experiments = %$treatment_experiments_ref;
2374 my $plant = $chado_schema->resultset("Stock::Stock")->create({
2375 organism_id => $parent_plot_organism,
2376 name => $plant_name,
2377 uniquename => $plant_name,
2378 type_id => $plant_cvterm,
2381 my $plantprop = $chado_schema->resultset("Stock::Stockprop")->create( {
2382 stock_id => $plant->stock_id(),
2383 type_id => $plant_index_number_cvterm,
2384 value => $plant_index_number,
2387 #The plant inherits the properties of the plot.
2388 my $plot_props = $chado_schema->resultset("Stock::Stockprop")->search({ stock_id => $parent_plot, type_id => [$block_cvterm, $plot_number_cvterm, $replicate_cvterm] });
2389 while (my $prop = $plot_props->next() ) {
2390 #print STDERR $plant->uniquename()." ".$prop->type_id()."\n";
2391 $plantprop = $chado_schema->resultset("Stock::Stockprop")->create( {
2392 stock_id => $plant->stock_id(),
2393 type_id => $prop->type_id(),
2394 value => $prop->value(),
2398 #the plant has a relationship to the plot
2399 my $stock_relationship = $self->bcs_schema()->resultset("Stock::StockRelationship")->create({
2400 subject_id => $parent_plot,
2401 object_id => $plant->stock_id(),
2402 type_id => $plant_relationship_cvterm,
2405 #the plant has a relationship to the accession
2406 my $plot_accession_rs = $self->bcs_schema()->resultset("Stock::StockRelationship")->search({'me.subject_id'=>$parent_plot, 'me.type_id'=>$plot_relationship_cvterm, 'object.type_id'=>$accession_cvterm }, {'join'=>'object'});
2407 if ($plot_accession_rs->count != 1){
2408 die "There is not 1 stock_relationship of type plot_of between the plot $parent_plot and an accession.";
2410 $stock_relationship = $self->bcs_schema()->resultset("Stock::StockRelationship")->create({
2411 subject_id => $plant->stock_id(),
2412 object_id => $plot_accession_rs->first->object_id,
2413 type_id => $plant_relationship_cvterm,
2416 #link plant to project through nd_experiment. also add nd_genolocation_id of plot to nd_experiment for the plant
2417 my $plant_nd_experiment_stock = $chado_schema->resultset("NaturalDiversity::NdExperimentStock")->create({
2418 nd_experiment_id => $field_layout_experiment->nd_experiment_id(),
2419 type_id => $field_layout_cvterm,
2420 stock_id => $plant->stock_id(),
2423 if ($inherits_plot_treatments){
2424 if($treatments){
2425 foreach (@$treatments){
2426 my $plots = $treatment_plots{$_->[0]};
2427 if (exists($plots->{$parent_plot})){
2428 my $plant_nd_experiment_stock = $chado_schema->resultset("NaturalDiversity::NdExperimentStock")->create({
2429 nd_experiment_id => $treatment_experiments{$_->[0]},
2430 type_id => $treatment_cvterm,
2431 stock_id => $plant->stock_id(),
2439 =head2 function has_plant_entries()
2441 Usage: $trial->has_plant_entries();
2442 Desc: Some trials require plant-level data. This function will determine if a trial has plants associated with it.
2443 Ret: Returns 1 if trial has plants, 0 if the trial does not.
2444 Args:
2445 Side Effects:
2446 Example:
2448 =cut
2450 sub has_plant_entries {
2451 my $self = shift;
2452 my $chado_schema = $self->bcs_schema();
2453 my $has_plants_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'project_has_plant_entries', 'project_property' );
2455 my $rs = $chado_schema->resultset("Project::Projectprop")->find({
2456 type_id => $has_plants_cvterm->cvterm_id(),
2457 project_id => $self->get_trial_id(),
2460 if ($rs) {
2461 return 1;
2462 } else {
2463 return 0;
2468 =head2 function create_tissue_samples()
2470 Usage: $trial->create_tissue_samples(\@tissue_names, $inherits_plot_treatments);
2471 Desc: Some trials require tissue_sample-level data. This function will
2472 add an additional layer of tissue samples for each plant.
2473 Ret:
2474 Args: an arrayref of tissue names to add to sample name e.g. ['leaf','root']
2475 Side Effects:
2476 Example:
2478 =cut
2480 sub create_tissue_samples {
2481 my $self = shift;
2482 my $tissue_names = shift;
2483 my $inherits_plot_treatments = shift;
2485 my $create_tissue_sample_entries_txn = sub {
2486 my $chado_schema = $self->bcs_schema();
2487 my $layout = CXGN::Trial::TrialLayout->new( { schema => $chado_schema, trial_id => $self->get_trial_id(), experiment_type=>'field_layout' });
2488 my $design = $layout->get_design();
2490 my $accession_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'accession', 'stock_type')->cvterm_id();
2491 my $plant_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plant', 'stock_type')->cvterm_id();
2492 my $subplot_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'subplot', 'stock_type')->cvterm_id();
2493 my $plot_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plot', 'stock_type')->cvterm_id();
2494 my $tissue_sample_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'tissue_sample', 'stock_type')->cvterm_id();
2495 my $plot_relationship_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plot_of', 'stock_relationship')->cvterm_id();
2496 my $plant_relationship_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plant_of', 'stock_relationship')->cvterm_id();
2497 my $tissue_relationship_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'tissue_sample_of', 'stock_relationship')->cvterm_id();
2498 my $plant_index_number_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plant_index_number', 'stock_property')->cvterm_id();
2499 my $tissue_index_number_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'tissue_sample_index_number', 'stock_property')->cvterm_id();
2500 my $has_tissues_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'project_has_tissue_sample_entries', 'project_property')->cvterm_id();
2501 my $block_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'block', 'stock_property')->cvterm_id();
2502 my $plot_number_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plot number', 'stock_property')->cvterm_id();
2503 my $replicate_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'replicate', 'stock_property')->cvterm_id();
2504 my $field_layout_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'field_layout', 'experiment_type')->cvterm_id();
2505 my $treatment_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'treatment_experiment', 'experiment_type')->cvterm_id();
2507 my $treatments;
2508 my %treatment_experiments;
2509 my %treatment_plots;
2510 my %treatment_subplots;
2511 if ($inherits_plot_treatments){
2512 $treatments = $self->get_treatments();
2513 foreach (@$treatments){
2515 my $rs = $chado_schema->resultset("Project::Projectprop")->find_or_create({
2516 type_id => $has_tissues_cvterm,
2517 value => scalar(@$tissue_names),
2518 project_id => $_->[0],
2521 my $treatment_nd_experiment = $chado_schema->resultset("Project::Project")->search( { 'me.project_id' => $_->[0] }, {select=>['nd_experiment.nd_experiment_id']})->search_related('nd_experiment_projects')->search_related('nd_experiment', { type_id => $treatment_cvterm })->single();
2522 $treatment_experiments{$_->[0]} = $treatment_nd_experiment->nd_experiment_id();
2524 my $treatment_trial = CXGN::Trial->new({ bcs_schema => $chado_schema, trial_id => $_->[0]});
2525 my $plots = $treatment_trial->get_plots();
2526 foreach my $plot (@$plots){
2527 $treatment_plots{$_->[0]}->{$plot->[0]} = 1;
2529 my $subplots = $treatment_trial->get_subplots();
2530 foreach my $subplot (@$subplots){
2531 $treatment_subplots{$_->[0]}->{$subplot->[0]} = 1;
2536 my $rs = $chado_schema->resultset("Project::Projectprop")->find_or_create({
2537 type_id => $has_tissues_cvterm,
2538 value => scalar(@$tissue_names),
2539 project_id => $self->get_trial_id(),
2542 my $field_layout_experiment = $chado_schema->resultset("Project::Project")->search( { 'me.project_id' => $self->get_trial_id() }, {select=>['nd_experiment.nd_experiment_id']})->search_related('nd_experiment_projects')->search_related('nd_experiment', { type_id => $field_layout_cvterm })->single();
2544 foreach my $plot (keys %$design) {
2545 my $plant_names = $design->{$plot}->{plant_names};
2546 my $subplot_names = $design->{$plot}->{subplot_names};
2547 my $subplots_plant_names = $design->{$plot}->{subplots_plant_names};
2548 my %plant_tissue_hash;
2549 foreach my $plant_name (@$plant_names){
2550 my $parent_plot_id = $design->{$plot}->{plot_id};
2551 my $parent_plot_name = $design->{$plot}->{plot_name};
2552 my $plant_row = $chado_schema->resultset("Stock::Stock")->find( { uniquename => $plant_name, type_id=>$plant_cvterm });
2554 if (! $plant_row) {
2555 print STDERR "The plant $plant_name is not found in the database\n";
2556 return "The plant $plant_name is not yet in the database. Cannot create tissue entries.";
2559 my $parent_plant = $plant_row->stock_id();
2560 my $parent_plant_name = $plant_row->uniquename();
2561 my $parent_plant_organism = $plant_row->organism_id();
2563 my $tissue_index_number = 1;
2564 foreach my $tissue_name (@$tissue_names){
2565 my $tissue_name = $parent_plant_name."_".$tissue_name.$tissue_index_number;
2566 print STDERR "... ... creating tissue $tissue_name...\n";
2568 my $tissue = $chado_schema->resultset("Stock::Stock")->create({
2569 organism_id => $parent_plant_organism,
2570 name => $tissue_name,
2571 uniquename => $tissue_name,
2572 type_id => $tissue_sample_cvterm,
2575 my $tissueprop = $chado_schema->resultset("Stock::Stockprop")->create( {
2576 stock_id => $tissue->stock_id(),
2577 type_id => $tissue_index_number_cvterm,
2578 value => $tissue_index_number,
2580 $tissue_index_number++;
2582 #the tissue has a relationship to the plant
2583 my $stock_relationship = $self->bcs_schema()->resultset("Stock::StockRelationship")->create({
2584 object_id => $parent_plant,
2585 subject_id => $tissue->stock_id(),
2586 type_id => $tissue_relationship_cvterm,
2589 #the tissue has a relationship to the plot
2590 $stock_relationship = $self->bcs_schema()->resultset("Stock::StockRelationship")->create({
2591 object_id => $parent_plot_id,
2592 subject_id => $tissue->stock_id(),
2593 type_id => $tissue_relationship_cvterm,
2596 #the tissue has a relationship to the accession
2597 my $plant_accession_rs = $self->bcs_schema()->resultset("Stock::StockRelationship")->search({'me.subject_id'=>$parent_plant, 'me.type_id'=>$plant_relationship_cvterm, 'object.type_id'=>$accession_cvterm }, {'join'=>'object'});
2598 if ($plant_accession_rs->count != 1){
2599 die "There is not 1 stock_relationship of type plant_of between the plant $parent_plant and an accession.";
2601 $stock_relationship = $self->bcs_schema()->resultset("Stock::StockRelationship")->create({
2602 object_id => $plant_accession_rs->first->object_id,
2603 subject_id => $tissue->stock_id(),
2604 type_id => $tissue_relationship_cvterm,
2607 #link tissue to project through nd_experiment.
2608 my $plant_nd_experiment_stock = $chado_schema->resultset("NaturalDiversity::NdExperimentStock")->create({
2609 nd_experiment_id => $field_layout_experiment->nd_experiment_id(),
2610 type_id => $field_layout_cvterm,
2611 stock_id => $tissue->stock_id(),
2614 if ($inherits_plot_treatments){
2615 if($treatments){
2616 foreach (@$treatments){
2617 my $plots = $treatment_plots{$_->[0]};
2618 if (exists($plots->{$parent_plot_id})){
2619 my $plant_nd_experiment_stock = $chado_schema->resultset("NaturalDiversity::NdExperimentStock")->create({
2620 nd_experiment_id => $treatment_experiments{$_->[0]},
2621 type_id => $treatment_cvterm,
2622 stock_id => $tissue->stock_id(),
2629 push @{$plant_tissue_hash{$plant_name}}, $tissue->stock_id;
2634 foreach my $subplot_name (%$subplots_plant_names){
2635 my $subplot_row = $chado_schema->resultset("Stock::Stock")->find({ uniquename => $subplot_name, type_id=>$subplot_cvterm });
2636 foreach my $plant (@{$subplots_plant_names->{$subplot_name}}){
2637 foreach my $t (@{$plant_tissue_hash{$plant}}){
2638 #the tissue has a relationship to the subplot
2639 my $stock_relationship = $self->bcs_schema()->resultset("Stock::StockRelationship")->create({
2640 object_id => $subplot_row->stock_id(),
2641 subject_id => $t,
2642 type_id => $tissue_relationship_cvterm,
2645 if ($inherits_plot_treatments){
2646 if($treatments){
2647 foreach (@$treatments){
2648 my $subplots = $treatment_subplots{$_->[0]};
2649 if (exists($subplots->{$subplot_row->stock_id})){
2650 my $plant_nd_experiment_stock = $chado_schema->resultset("NaturalDiversity::NdExperimentStock")->create({
2651 nd_experiment_id => $treatment_experiments{$_->[0]},
2652 type_id => $treatment_cvterm,
2653 stock_id => $t,
2664 $layout->generate_and_cache_layout();
2667 eval {
2668 $self->bcs_schema()->txn_do($create_tissue_sample_entries_txn);
2670 if ($@) {
2671 print STDERR "An error occurred creating the tissue sample entities. $@\n";
2672 return 0;
2675 print STDERR "Tissue sample entities created.\n";
2676 return 1;
2679 =head2 function has_col_and_row_numbers()
2681 Usage: $trial->has_col_and_row_numbers();
2682 Desc: Some trials require tissue_samples from plants. This function will determine if a trial has row and column numbers for fieldMap spreadsheet download.
2683 Ret: Returns 1 if trial has row and column numbers, 0 if the trial does not.
2684 Args:
2685 Side Effects:
2686 Example:
2688 =cut
2690 sub has_col_and_row_numbers {
2691 my $self = shift;
2692 my $chado_schema = $self->bcs_schema();
2693 my $design;
2694 try {
2695 my $layout = CXGN::Trial::TrialLayout->new( { schema => $chado_schema, trial_id => $self->get_trial_id(), experiment_type=>'field_layout' });
2696 $design = $layout->get_design();
2699 my (@row_numbers, @col_numbers);
2700 foreach my $plot (keys %$design) {
2701 my $row_number = $design->{$plot}->{row_number};
2702 my $col_number = $design->{$plot}->{col_number};
2703 if ($row_number){
2704 push @row_numbers, $row_number;
2706 if ($col_number){
2707 push @col_numbers, $col_number;
2711 if (scalar(@row_numbers) ne '0' && scalar(@col_numbers) ne '0'){
2712 return 1;
2713 } else {
2714 return 0;
2719 =head2 function has_tissue_sample_entries()
2721 Usage: $trial->has_tissue_sample_entries();
2722 Desc: Some trials require tissue_samples from plants. This function will determine if a trial has tissue_samples associated with it.
2723 Ret: Returns 1 if trial has tissue_samples, 0 if the trial does not.
2724 Args:
2725 Side Effects:
2726 Example:
2728 =cut
2730 sub has_tissue_sample_entries {
2731 my $self = shift;
2732 my $chado_schema = $self->bcs_schema();
2733 my $has_tissues_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'project_has_tissue_sample_entries', 'project_property' );
2735 my $rs = $chado_schema->resultset("Project::Projectprop")->find({
2736 type_id => $has_tissues_cvterm->cvterm_id(),
2737 project_id => $self->get_trial_id(),
2740 if ($rs) {
2741 return 1;
2742 } else {
2743 return 0;
2749 =head2 function has_subplot_entries()
2751 Usage: $trial->has_subplot_entries();
2752 Desc: Some trials require subplot-level data (splitplot designs). This function will determine if a trial has subplots associated with it.
2753 Ret: Returns 1 if trial has subplots, 0 if the trial does not.
2754 Args:
2755 Side Effects:
2756 Example:
2758 =cut
2760 sub has_subplot_entries {
2761 my $self = shift;
2762 my $chado_schema = $self->bcs_schema();
2763 my $has_subplots_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'project_has_subplot_entries', 'project_property' );
2765 my $rs = $chado_schema->resultset("Project::Projectprop")->find({
2766 type_id => $has_subplots_cvterm->cvterm_id(),
2767 project_id => $self->get_trial_id(),
2770 if ($rs) {
2771 return 1;
2772 } else {
2773 return 0;
2778 sub get_planting_date_cvterm_id {
2779 my $self = shift;
2780 my $planting_date = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'project_planting_date', 'project_property');
2782 return $planting_date->cvterm_id();
2786 =head2 accessors set_design_type(), get_design_type()
2788 Usage: $trial->set_design_type("RCBD");
2789 Desc:
2790 Ret:
2791 Args:
2792 Side Effects:
2793 Example:
2795 =cut
2797 sub get_design_type {
2798 my $self = shift;
2799 my $design_prop;
2800 my $design_type;
2802 my $project = $self->bcs_schema->resultset("Project::Project")->find( { project_id => $self->get_trial_id() });
2804 $design_prop = $project->projectprops->find(
2805 { 'type.name' => 'design' },
2806 { join => 'type'}
2807 ); #there should be only one design prop.
2808 if (!$design_prop) {
2809 return;
2811 $design_type = $design_prop->value;
2812 if (!$design_type) {
2813 return;
2815 return $design_type;
2820 sub duplicate {
2823 =head2 get_accessions
2825 Usage: my $accessions = $t->get_accessions();
2826 Desc: retrieves the accessions used in this trial.
2827 Ret: an arrayref of { accession_name => acc_name, stock_id => stock_id }
2828 Args: none
2829 Side Effects:
2830 Example:
2832 =cut
2834 sub get_accessions {
2835 my $self = shift;
2836 my @accessions;
2838 my $accession_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'accession', 'stock_type' )->cvterm_id();
2839 my $field_trial_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, "field_layout", "experiment_type")->cvterm_id();
2840 my $plot_of_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, "plot_of", "stock_relationship")->cvterm_id();
2841 my $plant_of_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, "plant_of", "stock_relationship")->cvterm_id();
2842 my $subplot_of_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, "subplot_of", "stock_relationship")->cvterm_id();
2843 my $tissue_sample_of_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, "tissue_sample_of", "stock_relationship")->cvterm_id();
2845 my $q = "SELECT DISTINCT(accession.stock_id), accession.uniquename
2846 FROM stock as accession
2847 JOIN stock_relationship on (accession.stock_id = stock_relationship.object_id)
2848 JOIN stock as plot on (plot.stock_id = stock_relationship.subject_id)
2849 JOIN nd_experiment_stock on (plot.stock_id=nd_experiment_stock.stock_id)
2850 JOIN nd_experiment using(nd_experiment_id)
2851 JOIN nd_experiment_project using(nd_experiment_id)
2852 JOIN project using(project_id)
2853 WHERE accession.type_id = $accession_cvterm_id
2854 AND stock_relationship.type_id IN ($plot_of_cvterm_id, $tissue_sample_of_cvterm_id, $plant_of_cvterm_id, $subplot_of_cvterm_id)
2855 AND project.project_id = ?
2856 GROUP BY accession.stock_id
2857 ORDER BY accession.stock_id;";
2859 my $h = $self->bcs_schema->storage->dbh()->prepare($q);
2860 $h->execute($self->get_trial_id());
2861 while (my ($stock_id, $uniquename) = $h->fetchrow_array()) {
2862 push @accessions, {accession_name=>$uniquename, stock_id=>$stock_id };
2865 return \@accessions;
2868 =head2 get_tissue_sources
2870 Usage: my $tissue_sources = $t->get_tissue_sources();
2871 Desc: retrieves the sources for the tisue_samples in a trial. in field_layout trials this can only be plants. In genotyping_layout trials the source of a tissue_sample can be tissue_samples, plants, plots, or accessions
2872 Ret: an arrayref of { uniquename => acc_name, type=>'plant', stock_id => stock_id }
2873 Args: none
2874 Side Effects:
2875 Example:
2877 =cut
2879 sub get_tissue_sources {
2880 my $self = shift;
2881 my @tissue_samples;
2882 my $tissue_sample_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'tissue_sample', 'stock_type' )->cvterm_id();
2883 my $tissue_sample_of_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, "tissue_sample_of", "stock_relationship")->cvterm_id();
2884 my $q = "SELECT DISTINCT(stock.stock_id), stock.uniquename, cvterm.name
2885 FROM stock
2886 JOIN cvterm on (stock.type_id = cvterm.cvterm_id)
2887 JOIN stock_relationship on (stock.stock_id = stock_relationship.object_id)
2888 JOIN stock as tissue_sample on (tissue_sample.stock_id = stock_relationship.subject_id)
2889 JOIN nd_experiment_stock on (tissue_sample.stock_id=nd_experiment_stock.stock_id)
2890 JOIN nd_experiment using(nd_experiment_id)
2891 JOIN nd_experiment_project using(nd_experiment_id)
2892 JOIN project using(project_id)
2893 WHERE tissue_sample.type_id = $tissue_sample_cvterm_id
2894 AND stock_relationship.type_id = $tissue_sample_of_cvterm_id
2895 AND project.project_id = ?
2896 GROUP BY (stock.stock_id, cvterm.name)
2897 ORDER BY (stock.stock_id);";
2899 my $h = $self->bcs_schema->storage->dbh()->prepare($q);
2900 $h->execute($self->get_trial_id());
2901 while (my ($stock_id, $uniquename, $type) = $h->fetchrow_array()) {
2902 push @tissue_samples, {uniquename=>$uniquename, type=>$type, stock_id=>$stock_id };
2904 return \@tissue_samples;
2907 =head2 get_plants
2909 Usage: $plants = $t->get_plants();
2910 Desc: retrieves that plants that are part of the design for this trial.
2911 Ret: an array ref containing [ plant_name, plant_stock_id ]
2912 Args:
2913 Side Effects:
2914 Example:
2916 =cut
2918 sub get_plants {
2919 my $self = shift;
2920 my @plants;
2922 my $trial_layout_download = CXGN::Trial::TrialLayoutDownload->new({
2923 schema => $self->bcs_schema,
2924 trial_id => $self->get_trial_id(),
2925 data_level => 'plants',
2926 selected_columns => {"plant_name"=>1,"plant_id"=>1},
2928 my $output = $trial_layout_download->get_layout_output()->{output};
2929 my $header = shift @$output;
2930 foreach (@$output) {
2931 push @plants, [$_->[1], $_->[0]];
2933 return \@plants;
2936 =head2 get_plants_per_accession
2938 Usage: $plants = $t->get_plants_per_accession();
2939 Desc: retrieves that plants that are part of the design for this trial grouping them by accession.
2940 Ret: a hash ref containing { $accession_stock_id1 => [ [ plant_name1, plant_stock_id1 ], [ plant_name2, plant_stock_id2 ] ], ... }
2941 Args:
2942 Side Effects:
2943 Example:
2945 =cut
2947 sub get_plants_per_accession {
2948 my $self = shift;
2949 my %return;
2951 my $plant_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'plant', 'stock_type' )->cvterm_id();
2952 my $accession_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'accession', 'stock_type' )->cvterm_id();
2954 my $trial_plant_rs = $self->bcs_schema->resultset("Project::Project")->find({ project_id => $self->get_trial_id(), })->search_related("nd_experiment_projects")->search_related("nd_experiment")->search_related("nd_experiment_stocks")->search_related("stock", {'stock.type_id'=>$plant_cvterm_id, 'object.type_id'=>$accession_cvterm_id}, {join=>{'stock_relationship_subjects'=>'object'}, '+select'=>['stock_relationship_subjects.object_id'], '+as'=>['accession_stock_id']});
2956 my %unique_plants;
2957 while(my $rs = $trial_plant_rs->next()) {
2958 $unique_plants{$rs->uniquename} = [$rs->stock_id, $rs->get_column('accession_stock_id')];
2960 while (my ($key, $value) = each %unique_plants) {
2961 push @{$return{$value->[1]}}, [$value->[0], $key];
2963 #print STDERR Dumper \%return;
2964 return \%return;
2967 =head2 get_seedlots
2969 Usage: my $seedlots = $trial->get_seedlots();
2970 Desc: returns a list of seedlots that are defined for the trial.
2971 Ret: an array ref of elements that contain
2972 [ seedlot_name, seedlot_stock_id ]
2973 Args: none
2974 Side Effects: db access
2975 Example:
2977 =cut
2979 sub get_seedlots {
2980 my $self = shift;
2981 my @seedlots;
2983 my $seedlot_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'seedlot', 'stock_type' )->cvterm_id();
2984 my $seed_transaction_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, "seed transaction", "stock_relationship")->cvterm_id();
2986 my $q = "SELECT DISTINCT(accession.stock_id), accession.uniquename
2987 FROM stock as accession
2988 JOIN stock_relationship on (accession.stock_id = stock_relationship.object_id)
2989 JOIN stock as plot on (plot.stock_id = stock_relationship.subject_id)
2990 JOIN nd_experiment_stock on (plot.stock_id=nd_experiment_stock.stock_id)
2991 JOIN nd_experiment using(nd_experiment_id)
2992 JOIN nd_experiment_project using(nd_experiment_id)
2993 JOIN project using(project_id)
2994 WHERE accession.type_id = $seedlot_cvterm_id
2995 AND stock_relationship.type_id IN ($seed_transaction_cvterm_id)
2996 AND project.project_id = ?
2997 GROUP BY accession.stock_id
2998 ORDER BY accession.stock_id;";
3000 #Removed nd_experiment.type_id IN ($field_trial_cvterm_id, $genotyping_trial_cvterm_id) AND
3002 my $h = $self->bcs_schema->storage->dbh()->prepare($q);
3003 $h->execute($self->get_trial_id());
3004 while (my ($stock_id, $uniquename) = $h->fetchrow_array()) {
3005 push @seedlots, [$stock_id, $uniquename];
3008 return \@seedlots;
3011 =head2 get_plots
3013 Usage: my $plots = $trial->get_plots();
3014 Desc: returns a list of plots that are defined for the trial.
3015 Ret: an array ref of elements that contain
3016 [ plot_name, plot_stock_id ]
3017 Args: none
3018 Side Effects: db access
3019 Example:
3021 =cut
3023 sub get_plots {
3024 my $self = shift;
3025 my @plots;
3027 my $trial_layout_download = CXGN::Trial::TrialLayoutDownload->new({
3028 schema => $self->bcs_schema,
3029 trial_id => $self->get_trial_id(),
3030 data_level => 'plots',
3031 selected_columns => {"plot_name"=>1,"plot_id"=>1},
3033 my $output = $trial_layout_download->get_layout_output()->{output};
3034 my $header = shift @$output;
3035 foreach (@$output) {
3036 push @plots, [$_->[1], $_->[0]];
3038 return \@plots;
3041 =head2 get_plots_per_accession
3043 Usage: $plots = $t->get_plots_per_accession();
3044 Desc: retrieves that plots that are part of the design for this trial grouping them by accession.
3045 Ret: a hash ref containing { $accession_stock_id1 => [ [ plot_name1, plot_stock_id1 ], [ plot_name2, plot_stock_id2 ] ], ... }
3046 Args:
3047 Side Effects:
3048 Example:
3050 =cut
3052 sub get_plots_per_accession {
3053 my $self = shift;
3054 my %return;
3056 # note: this function also retrieves stocks of type tissue_sample (for genotyping plates).
3057 my $plot_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'plot', 'stock_type' )->cvterm_id();
3058 my $accession_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'accession', 'stock_type' )->cvterm_id();
3059 my $tissue_sample_cvterm = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'tissue_sample', 'stock_type');
3060 my $tissue_sample_cvterm_id = $tissue_sample_cvterm ? $tissue_sample_cvterm->cvterm_id() : '';
3062 my @type_ids;
3063 push @type_ids, $plot_cvterm_id if $plot_cvterm_id;
3064 push @type_ids, $tissue_sample_cvterm_id if $tissue_sample_cvterm_id;
3066 print STDERR "TYPE IDS: ".join(", ", @type_ids);
3067 my $trial_plot_rs = $self->bcs_schema->resultset("Project::Project")->find({ project_id => $self->get_trial_id(), })->search_related("nd_experiment_projects")->search_related("nd_experiment")->search_related("nd_experiment_stocks")->search_related("stock", {'stock.type_id'=> { in => [@type_ids] }, 'object.type_id'=>$accession_cvterm_id }, {join=>{'stock_relationship_subjects'=>'object'}, '+select'=>['stock_relationship_subjects.object_id'], '+as'=>['accession_stock_id']});
3069 my %unique_plots;
3070 while(my $rs = $trial_plot_rs->next()) {
3071 $unique_plots{$rs->uniquename} = [$rs->stock_id, $rs->get_column('accession_stock_id')];
3073 while (my ($key, $value) = each %unique_plots) {
3074 push @{$return{$value->[1]}}, [$value->[0], $key];
3076 #print STDERR Dumper \%return;
3077 return \%return;
3080 =head2 get_subplots
3082 Usage: my $subplots = $trial->get_subplots();
3083 Desc: returns a list of subplots that are defined for the trial.
3084 Ret: an array ref of elements that contain
3085 [ subplot_name, subplot_stock_id ]
3086 Args: none
3087 Side Effects: db access
3088 Example:
3090 =cut
3092 sub get_subplots {
3093 my $self = shift;
3094 my @subplots;
3096 my $trial_layout_download = CXGN::Trial::TrialLayoutDownload->new({
3097 schema => $self->bcs_schema,
3098 trial_id => $self->get_trial_id(),
3099 data_level => 'subplots',
3100 selected_columns => {"subplot_name"=>1,"subplot_id"=>1},
3102 my $output = $trial_layout_download->get_layout_output()->{output};
3103 my $header = shift @$output;
3104 foreach (@$output) {
3105 push @subplots, [$_->[1], $_->[0]];
3107 return \@subplots;
3110 =head2 get_tissue_samples
3112 Usage: $tissues = $t->get_tissue_samples();
3113 Desc: retrieves the tissue samples that are linked to plants for this trial.
3114 Ret: an array ref containing [ tissue_sample_name, tissue_sample_stock_id ]
3115 Args:
3116 Side Effects:
3117 Example:
3119 =cut
3121 sub get_tissue_samples {
3122 my $self = shift;
3123 my @tissues;
3125 my $trial_layout_download = CXGN::Trial::TrialLayoutDownload->new({
3126 schema => $self->bcs_schema,
3127 trial_id => $self->get_trial_id(),
3128 data_level => 'field_trial_tissue_samples',
3129 selected_columns => {"tissue_sample_name"=>1,"tissue_sample_id"=>1},
3131 my $output = $trial_layout_download->get_layout_output()->{output};
3132 my $header = shift @$output;
3133 foreach (@$output) {
3134 push @tissues, [$_->[1], $_->[0]];
3136 return \@tissues;
3139 =head2 get_controls
3141 Usage: my $controls = $t->get_controls();
3142 Desc: Returns the accessions that were used as controls in the design
3143 Ret: an arrayref containing
3144 { accession_name => control_name, stock_id => control_stock_id }
3145 Args: none
3146 Side Effects:
3147 Example:
3149 =cut
3151 sub get_controls {
3152 my $self = shift;
3153 my @controls;
3155 my $accession_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'accession', 'stock_type' )->cvterm_id();
3156 my $field_trial_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, "field_layout", "experiment_type")->cvterm_id();
3157 my $genotyping_trial_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, "genotyping_layout", "experiment_type")->cvterm_id();
3158 my $plot_of_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, "plot_of", "stock_relationship")->cvterm_id();
3159 my $plant_of_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, "plant_of", "stock_relationship")->cvterm_id();
3160 my $tissue_sample_of_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, "tissue_sample_of", "stock_relationship")->cvterm_id();
3161 my $control_type_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, "is a control", 'stock_property')->cvterm_id();
3163 my $q = "SELECT DISTINCT(accession.stock_id), accession.uniquename
3164 FROM stock as accession
3165 JOIN stock_relationship on (accession.stock_id = stock_relationship.object_id)
3166 JOIN stock as plot on (plot.stock_id = stock_relationship.subject_id)
3167 JOIN stockprop as control on (plot.stock_id=control.stock_id)
3168 JOIN nd_experiment_stock on (plot.stock_id=nd_experiment_stock.stock_id)
3169 JOIN nd_experiment using(nd_experiment_id)
3170 JOIN nd_experiment_project using(nd_experiment_id)
3171 JOIN project using(project_id)
3172 WHERE accession.type_id = $accession_cvterm_id
3173 AND stock_relationship.type_id IN ($plot_of_cvterm_id, $tissue_sample_of_cvterm_id, $plant_of_cvterm_id)
3174 AND project.project_id = ?
3175 AND control.type_id = $control_type_id
3176 GROUP BY accession.stock_id
3177 ORDER BY accession.stock_id;";
3179 #removed nd_experiment.type_id IN ($field_trial_cvterm_id, $genotyping_trial_cvterm_id) AND
3181 my $h = $self->bcs_schema->storage->dbh()->prepare($q);
3182 $h->execute($self->get_trial_id());
3183 while (my ($stock_id, $uniquename) = $h->fetchrow_array()) {
3184 push @controls, {accession_name=> $uniquename, stock_id=>$stock_id } ;
3187 return \@controls;
3190 =head2 get_controls_by_plot
3192 Usage: my $controls = $t->get_controls_by_plot(\@plot_ids);
3193 Desc: Returns the accessions that were used as controls in a trial from a list of trial plot ids. Improves on speed of get_controls by avoiding a join through nd_experiment_stock
3194 Ret: an arrayref containing
3195 { accession_name => control_name, stock_id => control_stock_id }
3196 Args: none
3197 Side Effects:
3198 Example:
3200 =cut
3202 sub get_controls_by_plot {
3203 my $self = shift;
3204 my $plot_ids = shift;
3205 my @ids = @$plot_ids;
3206 my @controls;
3208 my $accession_rs = $self->bcs_schema->resultset('Stock::Stock')->search(
3209 { 'subject.stock_id' => { 'in' => \@ids} , 'type.name' => 'is a control' },
3210 { join => { stock_relationship_objects => { subject => { stockprops => 'type' }}}, group_by => 'me.stock_id',},
3213 while(my $accession = $accession_rs->next()) {
3214 push @controls, { accession_name => $accession->uniquename, stock_id => $accession->stock_id };
3217 return \@controls;
3220 =head2 get_treatments
3222 Usage: $plants = $t->get_treatments();
3223 Desc: retrieves the treatments that are part of this trial
3224 Ret: an array ref containing from project table [ treatment_name, treatment_id ]
3225 Args:
3226 Side Effects:
3227 Example:
3229 =cut
3231 sub get_treatments {
3232 my $self = shift;
3233 my @plants;
3234 my $treatment_rel_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, "trial_treatment_relationship", "project_relationship")->cvterm_id();
3236 my $treatment_rs = $self->bcs_schema->resultset("Project::ProjectRelationship")->search({type_id=>$treatment_rel_cvterm_id, object_project_id=>$self->get_trial_id()})->search_related('subject_project');
3238 my @treatments;
3239 while(my $rs = $treatment_rs->next()) {
3240 push @treatments, [$rs->project_id, $rs->name];
3242 return \@treatments;
3245 =head2 get_trial_contacts
3247 Usage: my $contacts = $t->get_trial_contacts();
3248 Desc: Returns an arrayref of hashrefs that contain all sp_person info fpr sp_person_ids saved as projectprops to this trial
3249 Ret: an arrayref containing
3250 { sp_person_id => 1, salutation => 'Mr.', first_name => 'joe', last_name => 'doe', email => 'j@d.com' }
3251 Args: none
3252 Side Effects:
3253 Example:
3255 =cut
3257 sub get_trial_contacts {
3258 my $self = shift;
3259 my @contacts;
3261 my $sp_person_id_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema,'sp_person_id','local')->cvterm_id;
3262 my $prop_rs = $self->bcs_schema->resultset('Project::Projectprop')->search(
3263 { 'project_id' => $self->get_trial_id, 'type_id'=>$sp_person_id_cvterm_id }
3266 while(my $prop = $prop_rs->next()) {
3267 my $q = "SELECT sp_person_id, username, salutation, first_name, last_name, contact_email, user_type, phone_number, organization FROM sgn_people.sp_person WHERE sp_person_id=?;";
3268 my $h = $self->bcs_schema()->storage->dbh()->prepare($q);
3269 $h->execute($prop->value);
3270 while (my ($sp_person_id, $username, $salutation, $first_name, $last_name, $email, $user_type, $phone, $organization) = $h->fetchrow_array()){
3271 push @contacts, {
3272 sp_person_id => $sp_person_id,
3273 salutation => $salutation,
3274 first_name => $first_name,
3275 last_name => $last_name,
3276 username => $username,
3277 email => $email,
3278 type => $user_type,
3279 phone_number => $phone,
3280 organization => $organization
3285 return \@contacts;
3289 =head2 function get_data_agreement()
3291 Usage: $trial->get_data_agreement();
3292 Desc: return data agreement saved for trial.
3293 Ret:
3294 Args:
3295 Side Effects:
3296 Example:
3298 =cut
3300 sub get_data_agreement {
3301 my $self = shift;
3302 my $chado_schema = $self->bcs_schema();
3303 my $cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'data_agreement', 'project_property' );
3305 my $rs = $chado_schema->resultset("Project::Projectprop")->find({
3306 type_id => $cvterm->cvterm_id(),
3307 project_id => $self->get_trial_id(),
3310 if ($rs) {
3311 return $rs->value();
3312 } else {
3313 return;
3318 =head2 suppress_plot_phenotype
3320 Usage: my $suppress_return_error = $trial->suppress_plot_phenotype($trait_id, $plot_name, $plot_pheno_value, $phenotype_id);
3321 if ($suppress_return_error) {
3322 $c->stash->{rest} = { error => $suppress_return_error };
3323 return;
3326 Desc: Suppresses plot phenotype
3327 Ret:
3328 Args:
3329 Side Effects:
3330 Example:
3332 =cut
3334 sub suppress_plot_phenotype {
3335 my $self = shift;
3336 my $trait_id = shift;
3337 my $plot_name = shift;
3338 my $phenotype_value = shift;
3339 my $phenotype_id = shift;
3340 my $username = shift;
3341 my $timestamp = shift;
3342 my $schema = $self->bcs_schema;
3343 my $trial_id = $self->get_trial_id();
3344 my $plot_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'plot', 'stock_type')->cvterm_id();
3345 my $phenotype_outlier_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'phenotype_outlier', 'phenotype_property')->cvterm_id();
3346 my $error;
3347 my $json_string = { value => 1, username=>$username, timestamp=>$timestamp };
3349 my $prop_rs = $self->bcs_schema->resultset('Phenotype::Phenotypeprop')->search(
3350 { 'phenotype_id' => $phenotype_id, 'type_id'=>$phenotype_outlier_type_id }
3353 if ($prop_rs->count == 0) {
3354 my $suppress_plot_pheno = $schema->resultset("Phenotype::Phenotypeprop")->create({
3355 phenotype_id => $phenotype_id,
3356 type_id => $phenotype_outlier_type_id,
3357 value => encode_json $json_string,
3360 else {
3361 $error = "This plot phenotype has already been suppressed.";
3364 return $error;
3368 =head2 delete_assayed_trait
3370 Usage: my $delete_trait_return_error = $trial->delete_assayed_trait($phenotypes_ids, [] );
3371 if ($delete_trait_return_error) {
3372 $c->stash->{rest} = { error => $delete_trait_return_error };
3373 return;
3376 Desc: Delete Assayed Traits
3377 Ret:
3378 Args:
3379 Side Effects:
3380 Example:
3382 =cut
3384 sub delete_assayed_trait {
3385 my $self = shift;
3386 my $pheno_ids = shift;
3387 my $trait_ids = shift;
3388 my $trial_id = $self->get_trial_id();
3389 my $schema = $self->bcs_schema;
3390 my $phenome_schema = $self->phenome_schema;
3391 my ($error, @nd_expt_ids);
3392 my $nd_experiment_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'phenotyping_experiment', 'experiment_type')->cvterm_id();
3394 my $search_params = { 'nd_experiment.type_id' => $nd_experiment_type_id, 'nd_experiment_projects.project_id' => $trial_id };
3395 if (scalar(@$trait_ids) > 0){
3396 $search_params->{'me.observable_id'} = { '-in' => $trait_ids };
3398 if (scalar(@$pheno_ids) > 0){
3399 $search_params->{'me.phenotype_id'} = { '-in' => $pheno_ids };
3401 #$schema->storage->debug(1);
3402 if (scalar(@$pheno_ids) > 0 || scalar(@$trait_ids) > 0 ){
3403 my $delete_pheno_id_rs = $schema->resultset("Phenotype::Phenotype")->search(
3404 $search_params,
3406 join => { 'nd_experiment_phenotypes' => {'nd_experiment' => 'nd_experiment_projects'} },
3407 '+select' => ['nd_experiment.nd_experiment_id'],
3408 '+as' => ['nd_expt_id'],
3410 while ( my $res = $delete_pheno_id_rs->next()){
3411 #print STDERR $res->phenotype_id." : ".$res->observable_id."\n";
3412 my $nd_expt_id = $res->get_column('nd_expt_id');
3413 push @nd_expt_ids, $nd_expt_id;
3414 $res->delete;
3416 #print STDERR Dumper(\@nd_expt_ids);
3417 my $delete_nd_expt_md_files_id_rs = $phenome_schema->resultset("NdExperimentMdFiles")->search({
3418 nd_experiment_id => { '-in' => \@nd_expt_ids },
3420 while (my $res = $delete_nd_expt_md_files_id_rs->next()){
3421 $res->delete;
3424 my $delete_nd_expt_id_rs = $schema->resultset("NaturalDiversity::NdExperiment")->search({
3425 nd_experiment_id => { '-in' => \@nd_expt_ids },
3427 while (my $res = $delete_nd_expt_id_rs->next()){
3428 $res->delete;
3431 else {
3432 $error = "List of trait or phenotype ids was not provided for deletion.";
3435 return $error;