modified key
[sgn.git] / lib / CXGN / Project.pm
blob9acf26d343e1890f1095b42a7cebe762eacb06fe
2 =head1 NAME
4 CXGN::Project - helper class for projects
6 =head1 DESCRIPTION
8 CXGN::Project is the root object for information stored in the project table, such as trials, genotyping trials, breeding programs, folders, etc.
10 It should rarely be necessary to be instantiated on its own. Use the CXGN::Trial factory object to generate the appropriate object from a project_id.
12 =head1 SYNOPSYS
14 my $project = CXGN::Project->new( { bcs_schema => $schema, trial_id => $trial_id });
15 $trial->set_description("yield trial with promising varieties");
16 etc.
18 =head1 AUTHOR
20 Lukas Mueller <lam87@cornell.edu>
22 =head1 METHODS
24 =cut
26 package CXGN::Project;
28 use Moose;
30 use Data::Dumper;
31 use Try::Tiny;
32 use Data::Dumper;
33 use CXGN::Trial::Folder;
34 use CXGN::Stock;
35 use CXGN::Trial::TrialLayout;
36 use CXGN::Trial::TrialLayoutDownload;
37 use SGN::Model::Cvterm;
38 use Time::Piece;
39 use Time::Seconds;
40 use CXGN::Calendar;
41 use JSON;
42 use File::Basename qw | basename dirname|;
43 use Scalar::Util qw | looks_like_number |;
44 use CXGN::Genotype::GenotypingProject;
45 use CXGN::Genotype::Protocol;
47 =head2 accessor bcs_schema()
49 accessor for bcs_schema. Needs to be set when calling the constructor.
51 =cut
53 has 'bcs_schema' => (
54 isa => 'Bio::Chado::Schema',
55 is => 'rw',
56 required => 1,
59 has 'metadata_schema' => (
60 isa => 'CXGN::Metadata::Schema',
61 is => 'rw',
64 has 'phenome_schema' => (
65 isa => 'CXGN::Phenome::Schema',
66 is => 'rw',
69 has 'project_id' => (
70 isa => 'Maybe[Int]',
71 is => 'rw',
72 trigger => \&set_trial_id,
73 builder => 'get_trial_id',
76 has 'name' => (
77 isa => 'Str',
78 is => 'rw',
79 trigger => \&set_name,
80 builder => 'get_name',
81 lazy => 1,
84 has 'description' => (
85 isa => 'Maybe[Str]',
86 is => 'rw',
87 trigger => \&set_description,
88 builder => 'get_description',
89 lazy => 1,
92 has 'year' => (
93 isa => 'Maybe[Str]',
94 is => 'rw',
95 trigger => \&get_year,
96 builder => 'set_year',
97 lazy => 1,
100 has 'additional_info' => (
101 is => 'rw',
102 isa => 'Maybe[HashRef]'
106 sub BUILD {
107 my $self = shift;
108 my $args = shift;
110 print STDERR "BUILD CXGN::Project... with ".$args->{trial_id}."\n";
112 if (! $args->{description}) {
113 $args->{description} = "(No description provided)";
116 my $row = $self->bcs_schema()->resultset("Project::Project")->find( { project_id => $args->{trial_id} });
118 # print STDERR "PROJECT ID = $args->{trial_id}\n";
119 if ($row){
120 $self->name( $row->name() );
123 if ($args->{trial_id} && ! $row) {
124 die "The trial ".$args->{trial_id}." does not exist - aborting.";
127 $row = $self->bcs_schema()->resultset("Project::Project")->find( { name => $args->{name } } );
130 if (! $args->{trial_id} && $row) {
131 die "A trial with the name $args->{name} already exists. Please choose another name.";
134 if (! $args->{trial_id} && ! $row) {
135 print STDERR "INSERTING A NEW ROW...\n";
137 my $new_row = $args->{bcs_schema}->resultset("Project::Project")->create( { name => $args->{name}, description => $args->{description} });
138 my $project_id = $new_row->project_id();
139 print STDERR "new project object has project id $project_id\n";
141 $self->set_trial_id($project_id);
144 if ($args->{trial_id} && $row) {
145 # print STDERR "Existing project... populating object.\n";
146 $self->set_trial_id($args->{trial_id});
147 $self->name($args->{name});
148 $self->description($args->{description});
152 =head2 accessors get_trial_id()
154 Desc: get the trial id
156 =cut
158 has 'trial_id' => (isa => 'Int',
159 is => 'rw',
160 reader => 'get_trial_id',
161 writer => 'set_trial_id',
164 =head2 accessors get_layout(), set_layout()
166 Desc: set the layout object for this trial (CXGN::Trial::TrialLayout)
167 (This is populated automatically by the constructor)
169 =cut
171 has 'layout' => (isa => 'CXGN::Trial::TrialLayout::Phenotyping |
172 CXGN::Trial::TrialLayout::Genotyping |
173 CXGN::Trial::TrialLayout::Analysis |
174 CXGN::Trial::TrialLayout::SamplingTrial',
175 is => 'rw',
176 reader => 'get_layout',
177 writer => 'set_layout',
178 predicate => 'has_layout',
179 lazy => 1,
180 default => sub { my $self = shift; $self->_get_layout(); }
183 sub _get_layout {
184 my $self = shift;
185 print STDERR "RETRIEVING LAYOUT...\n";
186 my $layout = CXGN::Trial::TrialLayout->new( { schema => $self->bcs_schema, trial_id => $self->get_trial_id(), experiment_type=>$self->get_cxgn_project_type()->{experiment_type} });
187 $self->set_layout($layout);
190 =head2 accessors get_cxgn_project_type()
192 get the CXGN::Project type e.g. field trial, analysis, genotyping trial, etc
194 =cut
196 sub get_cxgn_project_type {
197 my $self = shift;
199 my $analysis_metadata_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema(), 'analysis_metadata_json', 'project_property')->cvterm_id();
200 my $crossing_trial_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema(), 'crossing_trial', 'project_type')->cvterm_id();
202 my $q = "SELECT projectprop.type_id, projectprop.value FROM project JOIN projectprop USING(project_id)";
203 my $h = $self->bcs_schema->storage->dbh->prepare($q);
204 $h->execute();
206 my $cxgn_project_type = 'field_trial_project';
207 my $plot_data_level = 'plot';
208 my $experiment_type = 'field_layout';
209 while (my ($prop, $propvalue) = $h->fetchrow_array()) {
210 if ($prop) {
211 if ($prop == $crossing_trial_cvterm_id) {
212 $cxgn_project_type = 'crossing_project';
214 if ($prop == $analysis_metadata_cvterm_id) {
215 $cxgn_project_type = 'analysis_project';
216 $plot_data_level = 'analysis_instance';
217 $experiment_type = 'analysis_experiment';
219 if ($propvalue) {
220 if ($propvalue eq "genotyping_plate") {
221 $cxgn_project_type = 'genotyping_plate_project';
222 $experiment_type = 'genotyping_layout';
224 if ($propvalue eq "sampling_trial") {
225 $cxgn_project_type = 'sampling_trial_project';
226 $experiment_type = 'sampling_layout';
228 if ($propvalue eq "treatment") {
229 $cxgn_project_type = 'management_factor_project';
231 if (($propvalue eq "genotype_data_project") || ($propvalue eq "pcr_genotype_data_project")) {
232 $cxgn_project_type = 'genotyping_data_project';
234 if ($propvalue eq "drone_run") {
235 $cxgn_project_type = 'drone_run_project';
237 if ($propvalue eq "drone_run_band") {
238 $cxgn_project_type = 'drone_run_band_project';
243 return {
244 cxgn_project_type => $cxgn_project_type,
245 data_level => $plot_data_level,
246 experiment_type => $experiment_type
250 =head2 accessors get_year(), set_year()
252 getter/setter for the year property. The setter modifies the database.
254 =cut
256 sub get_year {
257 my $self = shift;
259 print STDERR "get_year()...\n";
261 if ($self->year()) { return $self->year(); }
263 my $type_id = $self->get_year_type_id();
265 my $rs = $self->bcs_schema->resultset('Project::Project')->search( { 'me.project_id' => $self->get_trial_id() })->search_related('projectprops', { 'projectprops.type_id' => $type_id } );
267 if ($rs->count() == 0) {
268 return undef;
270 else {
271 return $rs->first()->value();
276 sub set_year {
277 my $self = shift;
278 my $year = shift;
280 if (!$year) {
281 print STDERR "set_year(): No year provided, not setting.\n";
282 return;
285 print STDERR "set_year()... (with parameter $year)\n";
286 my $type_id = $self->get_year_type_id();
288 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find( { project_id => $self->get_trial_id(), type_id => $type_id });
290 if ($row) {
291 print STDERR "Updating year to $year...\n";
292 $row->value($year);
293 $row->update();
295 else {
296 print STDERR "inserting new year ($year)...\n";
297 $row = $self->bcs_schema->resultset('Project::Projectprop')->create(
299 type_id => $type_id,
300 value => $year,
301 project_id => $self->get_trial_id()
302 } );
303 $year = $row->value();
305 return $year;
308 =head2 accessors get_description(), set_description()
310 getter/setter for the description
312 =cut
314 sub get_description {
315 my $self = shift;
317 # print STDERR "Get description for trial id ".$self->get_trial_id()."\n";
318 my $rs = $self->bcs_schema->resultset('Project::Project')->search( { project_id => $self->get_trial_id() });
320 return $rs->first()->description();
325 sub set_description {
326 my $self = shift;
327 my $description = shift;
328 my $dbh = $self->bcs_schema->storage->dbh;
330 my $row = $self->bcs_schema->resultset('Project::Project')->find( { project_id => $self->get_trial_id() });
332 #print STDERR "Setting new description $description for trial ".$self->get_trial_id()."\n";
334 $row->description($description);
336 $row->update();
338 my $logged_in_user_q = "select * from logged_in_user";
339 my $logged_in_user_h = $dbh -> prepare($logged_in_user_q);
340 $logged_in_user_h->execute();
341 my $logged_in_user_arr = $logged_in_user_h->fetchall_arrayref();
342 print STDERR "logged in user Project.pm: ".Dumper($logged_in_user_arr)."\n";
347 =head2 function get_nd_experiment_id()
349 Usage: my $location = $trial->get_nd_experiment_id();
350 Desc: Every trial should have only a single nd_experiment entry of type 'field_layout'. This returns this nd_experiment_id for the trial.
351 Ret: $nd_experiment_id
352 Args:
353 Side Effects:
354 Example:
356 =cut
358 sub get_nd_experiment_id {
359 my $self = shift;
360 my $nd_experiment_field_layout_type_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'field_layout', 'experiment_type')->cvterm_id();
361 my $nd_experiment_genotyping_layout_type_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'genotyping_layout', 'experiment_type')->cvterm_id();
362 my $nd_experiment_rs = $self->bcs_schema->resultset('NaturalDiversity::NdExperiment')->search(
363 { 'me.type_id' => [$nd_experiment_field_layout_type_id, $nd_experiment_genotyping_layout_type_id], 'project.project_id' => $self->get_trial_id },
364 { 'join' => {'nd_experiment_projects'=>'project'}}
366 if ($nd_experiment_rs->count > 1){
367 return {error => "A trial cannot have more than one nd_experiment entry of type field_layout. Please contact us."};
369 if ($nd_experiment_rs == 1){
370 return {success => 1, nd_experiment_id => $nd_experiment_rs->first->nd_experiment_id};
371 } else {
372 return {error => "This trial does not have an nd_experiment entry of type field_layout. Please contact us."}
376 =head2 function get_location()
378 Usage: my $location = $trial->get_location();
379 Desc:
380 Ret: [ location_id, 'location description' ]
381 Args:
382 Side Effects:
383 Example:
385 =cut
387 sub get_location {
388 my $self = shift;
390 if ($self->get_location_type_id()) {
391 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find( { project_id => $self->get_trial_id() , type_id=> $self->get_location_type_id() });
393 if ($row) {
394 my $loc = $self->bcs_schema->resultset('NaturalDiversity::NdGeolocation')->find( { nd_geolocation_id => $row->value() });
396 return [ $row->value(), $loc->description() ];
398 else {
399 return [];
404 =head2 function set_location()
406 Usage: $trial->set_location($location_id);
407 Desc:
408 Ret: nothing
409 Args:
410 Side Effects: database access
411 Example:
413 =cut
415 sub set_location {
416 my $self = shift;
417 my $location_id = shift;
418 my $schema = $self->bcs_schema();
420 if (!looks_like_number($location_id)) {
421 die "Location_id $location_id not an integer!\n";
424 my $project_id = $self->get_trial_id();
425 my $type_id = $self->get_location_type_id();
427 ## Use txn_do with the following coderef so that if any part fails, the entire transaction fails.
428 my $coderef = sub {
430 # update or create location id in projectprop
431 my $row = $schema->resultset('Project::Projectprop')->find({
432 project_id => $project_id,
433 type_id => $type_id,
436 if ($row) {
437 $row->value($location_id);
438 $row->update();
440 else {
441 $row = $schema->resultset('Project::Projectprop')->create({
442 project_id => $project_id,
443 type_id => $type_id,
444 value => $location_id,
448 # update location ids for connected rows in nd_experiment
449 my $nd_experiment_rs = $schema->resultset('NaturalDiversity::NdExperimentProject')->search(
450 { project_id => $project_id }
451 )->search_related('nd_experiment');
453 foreach my $exp ($nd_experiment_rs->all()) {
454 $exp->nd_geolocation_id($location_id);
455 $exp->update();
459 try {
460 $schema->txn_do($coderef);
461 } catch {
462 print STDERR "Transaction error updating location: $_\n";
467 =head2 function get_location_noaa_station_id()
469 Usage: my $noaa_station_id = $trial->get_location_noaa_station_id();
470 Desc:
471 Ret:
472 Args:
473 Side Effects:
474 Example:
476 =cut
478 sub get_location_noaa_station_id {
479 my $self = shift;
480 my $nd_geolocation_id = $self->bcs_schema->resultset('Project::Projectprop')->find( { project_id => $self->get_trial_id() , type_id=> $self->get_location_type_id() })->value();
481 my $noaa_station_id_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'noaa_station_id', 'geolocation_property')->cvterm_id();
483 my $q = "SELECT value FROM nd_geolocationprop WHERE nd_geolocation_id = ? AND type_id = ?;";
484 my $h = $self->bcs_schema->storage->dbh()->prepare($q);
485 $h->execute($nd_geolocation_id, $noaa_station_id_cvterm_id);
486 my ($noaa_station_id) = $h->fetchrow_array();
487 return $noaa_station_id;
490 =head2 function get_location_country_name()
492 Usage: my $country_name = $trial->get_location_country_name();
493 Desc:
494 Ret:
495 Args:
496 Side Effects:
497 Example:
499 =cut
501 sub get_location_country_name {
502 my $self = shift;
504 my $country_name;
506 eval {
507 my $nd_geolocation_id = $self->bcs_schema->resultset('Project::Projectprop')->find( { project_id => $self->get_trial_id() , type_id=> $self->get_location_type_id() })->value();
508 my $country_name_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'country_name', 'geolocation_property')->cvterm_id();
510 if ( $nd_geolocation_id && $country_name_cvterm_id ) {
511 my $q = "SELECT value FROM nd_geolocationprop WHERE nd_geolocation_id = ? AND type_id = ?;";
512 my $h = $self->bcs_schema->storage->dbh()->prepare($q);
514 $h->execute($nd_geolocation_id, $country_name_cvterm_id);
515 ($country_name) = $h->fetchrow_array();
519 return $country_name;
522 =head2 function get_breeding_programs()
524 Usage:
525 Desc: return associated breeding program info
526 Ret: returns a listref to [ id, name, desc ] listrefs
527 Args:
528 Side Effects:
529 Example:
531 =cut
533 sub get_breeding_programs {
534 my $self = shift;
536 my $breeding_program_cvterm_id = $self->get_breeding_program_cvterm_id();
538 my $trial_rs= $self->bcs_schema->resultset('Project::ProjectRelationship')->search( { 'subject_project_id' => $self->get_trial_id() } );
540 my $trial_row = $trial_rs -> first();
541 my $rs;
542 my @projects;
544 if ($trial_row) {
545 $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' } );
547 while (my $row = $rs->next()) {
548 push @projects, [ $row->project_id, $row->name, $row->description ];
551 return \@projects;
554 =head2 function set_field_trials_source_field_trials()
556 Usage:
557 Desc: sets associated source field trials for the current field trial
558 Ret: returns an arrayref [ id, name ] of arrayrefs
559 Args: an arrayref [source_trial_id1, source_trial_id2]
560 Side Effects:
561 Example:
563 =cut
565 sub set_field_trials_source_field_trials {
566 my $self = shift;
567 my $source_field_trial_ids = shift;
568 my $schema = $self->bcs_schema;
569 my $field_trial_from_field_trial_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'field_trial_from_field_trial', 'project_relationship')->cvterm_id();
571 foreach (@$source_field_trial_ids){
572 if ($_){
573 my $trial_rs= $self->bcs_schema->resultset('Project::ProjectRelationship')->create({
574 'subject_project_id' => $self->get_trial_id(),
575 'object_project_id' => $_,
576 'type_id' => $field_trial_from_field_trial_cvterm_id
580 my $projects = $self->get_field_trials_source_field_trials();
581 return $projects;
584 =head2 function get_field_trials_source_field_trials()
586 Usage:
587 Desc: return associated source field trials for the current field trial
588 Ret: returns an arrayref [ id, name ] of arrayrefs
589 Args:
590 Side Effects:
591 Example:
593 =cut
595 sub get_field_trials_source_field_trials {
596 my $self = shift;
597 my $schema = $self->bcs_schema;
598 my $field_trial_from_field_trial_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'field_trial_from_field_trial', 'project_relationship')->cvterm_id();
600 my $trial_rs= $self->bcs_schema->resultset('Project::ProjectRelationship')->search({
601 'me.subject_project_id' => $self->get_trial_id(),
602 'me.type_id' => $field_trial_from_field_trial_cvterm_id
603 }, {
604 join => 'object_project', '+select' => ['object_project.name'], '+as' => ['source_trial_name']
607 my @projects;
608 while (my $r = $trial_rs->next) {
609 push @projects, [ $r->object_project_id, $r->get_column('source_trial_name') ];
611 return \@projects;
614 =head2 function get_field_trials_sourced_from_field_trials()
616 Usage:
617 Desc: return associated source field trials for the current field trial
618 Ret: returns an arrayref [ id, name ] of arrayrefs
619 Args:
620 Side Effects:
621 Example:
623 =cut
625 sub get_field_trials_sourced_from_field_trials {
626 my $self = shift;
627 my $schema = $self->bcs_schema;
628 my $field_trial_from_field_trial_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'field_trial_from_field_trial', 'project_relationship')->cvterm_id();
630 my $trial_rs= $self->bcs_schema->resultset('Project::ProjectRelationship')->search({
631 'me.object_project_id' => $self->get_trial_id(),
632 'me.type_id' => $field_trial_from_field_trial_cvterm_id
633 }, {
634 join => 'subject_project', '+select' => ['subject_project.name'], '+as' => ['trial_name']
637 my @projects;
638 while (my $r = $trial_rs->next) {
639 push @projects, [ $r->subject_project_id, $r->get_column('trial_name') ];
641 return \@projects;
644 =head2 function set_genotyping_trials_from_field_trial()
646 Usage:
647 Desc: sets associated genotyping plates for the current field trial
648 Ret: returns an arrayref [ id, name ] of arrayrefs
649 Args: an arrayref [genotyping_trial_id1, genotyping_trial_id2]
650 Side Effects:
651 Example:
653 =cut
655 sub set_genotyping_trials_from_field_trial {
656 my $self = shift;
657 my $source_field_trial_ids = shift;
658 my $schema = $self->bcs_schema;
659 my $genotyping_trial_from_field_trial_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'genotyping_trial_from_field_trial', 'project_relationship')->cvterm_id();
661 foreach (@$source_field_trial_ids){
662 if ($_){
663 my $trial_rs= $self->bcs_schema->resultset('Project::ProjectRelationship')->create({
664 'subject_project_id' => $self->get_trial_id(),
665 'object_project_id' => $_,
666 'type_id' => $genotyping_trial_from_field_trial_cvterm_id
670 my $projects = $self->get_genotyping_trials_from_field_trial();
671 return $projects;
674 =head2 function get_genotyping_trials_from_field_trial()
676 Usage:
677 Desc: return associated genotyping plates for the current field trial
678 Ret: returns an arrayref [ id, name ] of arrayrefs
679 Args:
680 Side Effects:
681 Example:
683 =cut
685 sub get_genotyping_trials_from_field_trial {
686 my $self = shift;
687 my $schema = $self->bcs_schema;
688 my $genotyping_trial_from_field_trial_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'genotyping_trial_from_field_trial', 'project_relationship')->cvterm_id();
690 my $trial_rs= $self->bcs_schema->resultset('Project::ProjectRelationship')->search({
691 'me.subject_project_id' => $self->get_trial_id(),
692 'me.type_id' => $genotyping_trial_from_field_trial_cvterm_id
693 }, {
694 join => 'object_project', '+select' => ['object_project.name'], '+as' => ['source_trial_name']
697 my @projects;
698 while (my $r = $trial_rs->next) {
699 push @projects, [ $r->object_project_id, $r->get_column('source_trial_name') ];
701 return \@projects;
704 =head2 function set_source_field_trials_for_genotyping_trial()
706 Usage:
707 Desc: sets associated field trials for the current genotyping plate
708 Ret: returns an arrayref [ id, name ] of arrayrefs
709 Args: an arrayref [field_trial_id1, field_trial_id2]
710 Side Effects:
711 Example:
713 =cut
715 sub set_source_field_trials_for_genotyping_trial {
716 my $self = shift;
717 my $source_field_trial_ids = shift;
718 my $schema = $self->bcs_schema;
719 my $genotyping_trial_from_field_trial_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'genotyping_trial_from_field_trial', 'project_relationship')->cvterm_id();
721 foreach (@$source_field_trial_ids){
722 if ($_){
723 my $trial_rs= $self->bcs_schema->resultset('Project::ProjectRelationship')->create({
724 'object_project_id' => $self->get_trial_id(),
725 'subject_project_id' => $_,
726 'type_id' => $genotyping_trial_from_field_trial_cvterm_id
730 my $projects = $self->get_field_trials_source_of_genotyping_trial();
731 return $projects;
734 =head2 function get_field_trials_source_of_genotyping_trial()
736 Usage:
737 Desc: return associated field trials for current genotying trial
738 Ret: returns an arrayref [ id, name ] of arrayrefs
739 Args:
740 Side Effects:
741 Example:
743 =cut
745 sub get_field_trials_source_of_genotyping_trial {
746 my $self = shift;
747 my $schema = $self->bcs_schema;
748 my $genotyping_trial_from_field_trial_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'genotyping_trial_from_field_trial', 'project_relationship')->cvterm_id();
750 my $trial_rs= $self->bcs_schema->resultset('Project::ProjectRelationship')->search({
751 'me.object_project_id' => $self->get_trial_id(),
752 'me.type_id' => $genotyping_trial_from_field_trial_cvterm_id
753 }, {
754 join => 'subject_project', '+select' => ['subject_project.name'], '+as' => ['source_trial_name']
757 my @projects;
758 while (my $r = $trial_rs->next) {
759 push @projects, [ $r->subject_project_id, $r->get_column('source_trial_name') ];
761 return \@projects;
764 =head2 function set_source_field_trials_for_sampling_trial()
766 Usage:
767 Desc: sets associated field trials for the current sampling trial
768 Ret: returns an arrayref [ id, name ] of arrayrefs
769 Args: an arrayref [field_trial_id1, field_trial_id2]
770 Side Effects:
771 Example:
773 =cut
775 sub set_source_field_trials_for_sampling_trial {
776 my $self = shift;
777 my $source_field_trial_ids = shift;
778 my $schema = $self->bcs_schema;
779 my $sampling_trial_from_field_trial_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'sampling_trial_from_field_trial', 'project_relationship')->cvterm_id();
781 foreach (@$source_field_trial_ids){
782 if ($_){
783 my $trial_rs= $self->bcs_schema->resultset('Project::ProjectRelationship')->create({
784 'object_project_id' => $self->get_trial_id(),
785 'subject_project_id' => $_,
786 'type_id' => $sampling_trial_from_field_trial_cvterm_id
790 my $projects = $self->get_field_trials_source_of_sampling_trial();
791 return $projects;
794 =head2 function get_field_trials_source_of_sampling_trial()
796 Usage:
797 Desc: return associated field trials for current sampling trial
798 Ret: returns an arrayref [ id, name ] of arrayrefs
799 Args:
800 Side Effects:
801 Example:
803 =cut
805 sub get_field_trials_source_of_sampling_trial {
806 my $self = shift;
807 my $schema = $self->bcs_schema;
808 my $sampling_trial_from_field_trial_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'sampling_trial_from_field_trial', 'project_relationship')->cvterm_id();
810 my $trial_rs= $self->bcs_schema->resultset('Project::ProjectRelationship')->search({
811 'me.object_project_id' => $self->get_trial_id(),
812 'me.type_id' => $sampling_trial_from_field_trial_cvterm_id
813 }, {
814 join => 'subject_project', '+select' => ['subject_project.name'], '+as' => ['source_trial_name']
817 my @projects;
818 while (my $r = $trial_rs->next) {
819 push @projects, [ $r->subject_project_id, $r->get_column('source_trial_name') ];
821 return \@projects;
824 =head2 function set_crossing_trials_from_field_trial()
826 Usage:
827 Desc: sets associated crossing trials for the current field trial
828 Ret: returns an arrayref [ id, name ] of arrayrefs
829 Args: an arrayref [crossing_trial_id1, crossing_trial_id2]
830 Side Effects:
831 Example:
833 =cut
835 sub set_crossing_trials_from_field_trial {
836 my $self = shift;
837 my $source_field_trial_ids = shift;
838 my $schema = $self->bcs_schema;
839 my $genotyping_trial_from_field_trial_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'crossing_trial_from_field_trial', 'project_relationship')->cvterm_id();
841 foreach (@$source_field_trial_ids){
842 if ($_){
843 my $trial_rs= $self->bcs_schema->resultset('Project::ProjectRelationship')->create({
844 'subject_project_id' => $self->get_trial_id(),
845 'object_project_id' => $_,
846 'type_id' => $genotyping_trial_from_field_trial_cvterm_id
850 my $projects = $self->get_crossing_trials_from_field_trial();
851 return $projects;
854 =head2 function get_crossing_trials_from_field_trial()
856 Usage:
857 Desc: return associated crossing trials for athe current field trial
858 Ret: returns an arrayref [ id, name ] of arrayrefs
859 Args:
860 Side Effects:
861 Example:
863 =cut
865 sub get_crossing_trials_from_field_trial {
866 my $self = shift;
867 my $schema = $self->bcs_schema;
868 my $crossing_trial_from_field_trial_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'crossing_trial_from_field_trial', 'project_relationship')->cvterm_id();
870 my $trial_rs= $self->bcs_schema->resultset('Project::ProjectRelationship')->search({
871 'me.subject_project_id' => $self->get_trial_id(),
872 'me.type_id' => $crossing_trial_from_field_trial_cvterm_id
873 }, {
874 join => 'object_project', '+select' => ['object_project.name'], '+as' => ['source_trial_name']
877 my @projects;
878 while (my $r = $trial_rs->next) {
879 push @projects, [ $r->object_project_id, $r->get_column('source_trial_name') ];
881 return \@projects;
884 =head2 function get_field_trials_source_of_crossing_trial()
886 Usage:
887 Desc: return associated field trials for the current crossing trial
888 Ret: returns an arrayref [ id, name ] of arrayrefs
889 Args:
890 Side Effects:
891 Example:
893 =cut
895 sub get_field_trials_source_of_crossing_trial {
896 my $self = shift;
897 my $schema = $self->bcs_schema;
898 my $crossing_trial_from_field_trial_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'crossing_trial_from_field_trial', 'project_relationship')->cvterm_id();
900 my $trial_rs= $self->bcs_schema->resultset('Project::ProjectRelationship')->search({
901 'me.object_project_id' => $self->get_trial_id(),
902 'me.type_id' => $crossing_trial_from_field_trial_cvterm_id
903 }, {
904 join => 'subject_project', '+select' => ['subject_project.name'], '+as' => ['source_trial_name']
907 my @projects;
908 while (my $r = $trial_rs->next) {
909 push @projects, [ $r->subject_project_id, $r->get_column('source_trial_name') ];
911 return \@projects;
915 =head2 function get_project_type()
917 Usage: [ $project_type_cvterm_id, $project_type_name ] = $t -> get_project_type();
918 Desc:
919 Ret:
920 Args:
921 Side Effects:
922 Example:
924 =cut
926 sub get_project_type {
927 my $self = shift;
929 my @project_type_ids = CXGN::Trial::get_all_project_types($self->bcs_schema());
931 my @ids = map { $_->[0] } @project_type_ids;
932 my $rs = $self->bcs_schema()->resultset('Project::Projectprop')->search(
934 type_id => { -in => [ @ids ] },
935 project_id => $self->get_trial_id()
938 if ($rs->count() > 0) {
939 my $type_id = $rs->first()->type_id();
940 foreach my $pt (@project_type_ids) {
941 if ($type_id == $pt->[0]) {
942 #print STDERR "[get_project_type] ".$pt->[0]." ".$pt->[1]."\n";
943 return $pt;
947 return undef;
952 =head2 function set_project_type()
954 Usage: $t -> set_project_type($type);
955 Desc:
956 Ret:
957 Args:
958 Side Effects:
959 Example:
961 =cut
963 sub set_project_type {
964 my $self = shift;
965 my $type_id = shift;
966 my $type_value = shift;
967 my $project_id = $self->get_trial_id();
968 my @project_type_ids = CXGN::Trial::get_all_project_types($self->bcs_schema());
969 my $type;
971 foreach my $pt (@project_type_ids) {
972 if ($pt->[0] eq $type_id) {
973 $type = $pt->[1];
977 if ($type eq 'misc_trial' && defined $type_value) {
978 $type = $type_value;
981 my @ids = map { $_->[0] } @project_type_ids;
982 my $rs = $self->bcs_schema()->resultset('Project::Projectprop')->search({
983 type_id => { -in => [ @ids ] },
984 project_id => $project_id
986 if (my $row = $rs->next()) {
987 $row->delete();
990 my $row = $self->bcs_schema()->resultset('Project::Projectprop')->create({
991 project_id => $project_id,
992 type_id => $type_id,
993 value => $type,
998 sub set_design_type {
999 my $self = shift;
1000 my $design_type = shift;
1002 my $design_cv_type = $self->bcs_schema->resultset('Cv::Cvterm')->find( { name => 'design' });
1003 if (!$design_cv_type) {
1004 print STDERR "Design CV term not found. Cannot set design type.\n";
1005 return;
1007 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find_or_create(
1009 project_id => $self->get_trial_id(),
1010 type_id => $design_cv_type->cvterm_id(),
1012 $row->value($design_type);
1013 $row->update();
1016 =head2 accessors get_breeding_program(), set_breeding_program()
1018 Usage:
1019 Desc:
1020 Ret:
1021 Args:
1022 Side Effects:
1023 Example:
1025 =cut
1027 sub get_breeding_program {
1029 my $self = shift;
1031 my $rs = $self->bcs_schema()->resultset("Project::ProjectRelationship")->search({
1032 subject_project_id => $self->get_trial_id(),
1033 type_id => $self->get_breeding_program_trial_relationship_cvterm_id(),
1035 if ($rs->count() == 0) {
1036 return undef;
1039 my $bp_rs = $self->bcs_schema()->resultset("Project::Project")->search({
1040 project_id => $rs->first()->object_project_id()
1042 if ($bp_rs->count > 0) {
1043 return $bp_rs->first()->name();
1046 return undef;
1049 sub set_breeding_program {
1050 my $self = shift;
1051 my $breeding_program_id = shift;
1053 if (!looks_like_number($breeding_program_id)) {
1054 die "Breeding_program_id $breeding_program_id is not an integer!\n";
1057 my $trial_id = $self->get_trial_id();
1058 my $type_id = $self->get_breeding_program_trial_relationship_cvterm_id();
1060 eval {
1061 my $row = $self->bcs_schema->resultset("Project::ProjectRelationship")->find ({
1062 subject_project_id => $trial_id,
1063 type_id => $type_id,
1066 if ($row) {
1067 $row->object_project_id($breeding_program_id);
1068 $row->update();
1070 else {
1071 $row = $self->bcs_schema->resultset("Project::ProjectRelationship")->create ({
1072 object_project_id => $breeding_program_id,
1073 subject_project_id => $trial_id,
1074 type_id => $type_id,
1076 $row->insert();
1080 if ($@) {
1081 print STDERR "ERROR: $@\n";
1082 return { error => "An error occurred while setting the trial's breeding program." };
1084 return {};
1088 =head2 accessors get_name(), set_name()
1090 Usage:
1091 Desc: retrieve and store project name from/to database
1092 Ret:
1093 Args:
1094 Side Effects: setter modifies the database
1095 Example:
1097 =cut
1099 sub get_name {
1100 my $self = shift;
1101 my $row = $self->bcs_schema->resultset('Project::Project')->find( { project_id => $self->get_trial_id() });
1103 if ($row) {
1104 return $row->name();
1108 sub set_name {
1109 my $self = shift;
1110 my $name = shift;
1111 my $row = $self->bcs_schema->resultset('Project::Project')->find( { project_id => $self->get_trial_id() });
1112 if ($row) {
1113 $row->name($name);
1114 $row->update();
1118 =head2 accessors get_project_start_date(), set_project_start_date()
1120 Usage: $t->set_project_start_date("2016/09/17");
1121 Desc: sets the projects project_start_date property.
1122 The date format in the setter has to be
1123 YYYY/MM/DD
1124 Ret:
1125 Args:
1126 Side Effects:
1127 Example:
1129 =cut
1131 sub get_project_start_date {
1132 my $self = shift;
1134 my $project_start_date_cvterm_id = $self->get_project_start_date_cvterm_id();
1135 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find({
1136 project_id => $self->get_trial_id(),
1137 type_id => $project_start_date_cvterm_id,
1140 my $calendar_funcs = CXGN::Calendar->new({});
1141 return $row ? $calendar_funcs->display_start_date($row->value()) : undef;
1144 sub set_project_start_date {
1145 my $self = shift;
1146 my $project_start_date = shift;
1148 my $calendar_funcs = CXGN::Calendar->new({});
1149 if (my $project_start_date_event = $calendar_funcs->check_value_format($project_start_date) ) {
1150 my $project_start_date_cvterm_id = $self->get_project_start_date_cvterm_id();
1151 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find_or_create({
1152 project_id => $self->get_trial_id(),
1153 type_id => $project_start_date_cvterm_id,
1156 $row->value($project_start_date_event);
1157 $row->update();
1158 } else {
1159 print STDERR "date format did not pass check while preparing to set project start date: $project_start_date \n";
1163 =head2 accessors get_harvest_date(), set_harvest_date()
1165 Usage: $t->set_harvest_date("2016/09/17");
1166 Desc: sets the projects harvest_date property.
1167 The date format in the setter has to be
1168 YYYY/MM/DD
1169 Ret:
1170 Args:
1171 Side Effects:
1172 Example:
1174 =cut
1176 sub get_harvest_date {
1177 my $self = shift;
1179 my $harvest_date_cvterm_id = $self->get_harvest_date_cvterm_id();
1180 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find(
1182 project_id => $self->get_trial_id(),
1183 type_id => $harvest_date_cvterm_id,
1186 my $calendar_funcs = CXGN::Calendar->new({});
1188 if ($row) {
1189 my $harvest_date = $calendar_funcs->display_start_date($row->value());
1190 return $harvest_date;
1191 } else {
1192 return;
1196 sub set_harvest_date {
1197 my $self = shift;
1198 my $harvest_date = shift;
1200 my $calendar_funcs = CXGN::Calendar->new({});
1202 if (my $harvest_event = $calendar_funcs->check_value_format($harvest_date) ) {
1204 my $harvest_date_cvterm_id = $self->get_harvest_date_cvterm_id();
1206 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find_or_create(
1208 project_id => $self->get_trial_id(),
1209 type_id => $harvest_date_cvterm_id,
1212 $row->value($harvest_event);
1213 $row->update();
1214 } else {
1215 print STDERR "date format did not pass check while preparing to set harvest date: $harvest_date \n";
1219 sub remove_harvest_date {
1220 my $self = shift;
1221 my $harvest_date = shift;
1223 my $calendar_funcs = CXGN::Calendar->new({});
1224 if (my $harvest_event = $calendar_funcs->check_value_format($harvest_date) ) {
1226 my $harvest_date_cvterm_id = $self->get_harvest_date_cvterm_id();
1228 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find_or_create(
1230 project_id => $self->get_trial_id(),
1231 type_id => $harvest_date_cvterm_id,
1232 value => $harvest_event,
1235 if ($row) {
1236 print STDERR "Removing harvest date $harvest_event from trial ".$self->get_trial_id()."\n";
1237 $row->delete();
1239 } else {
1240 print STDERR "date format did not pass check while preparing to delete harvest date: $harvest_date \n";
1245 =head2 accessors get_planting_date(), set_planting_date()
1247 Usage:
1248 Desc:
1249 Ret:
1250 Args:
1251 Side Effects:
1252 Example:
1254 =cut
1256 sub get_planting_date {
1257 my $self = shift;
1259 my $planting_date_cvterm_id = $self->get_planting_date_cvterm_id();
1260 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find(
1262 project_id => $self->get_trial_id(),
1263 type_id => $planting_date_cvterm_id,
1266 my $calendar_funcs = CXGN::Calendar->new({});
1268 if ($row) {
1269 my $planting_date = $calendar_funcs->display_start_date($row->value());
1270 return $planting_date;
1271 } else {
1272 return;
1276 sub set_planting_date {
1277 my $self = shift;
1278 my $planting_date = shift;
1280 my $calendar_funcs = CXGN::Calendar->new({});
1282 if (my $planting_event = $calendar_funcs->check_value_format($planting_date) ) { # It should be a format : "YYYY/MM/DD HH:MM:SS" or "YYYY-MM-DD"
1284 my $planting_date_cvterm_id = $self->get_planting_date_cvterm_id();
1286 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find_or_create(
1288 project_id => $self->get_trial_id(),
1289 type_id => $planting_date_cvterm_id,
1292 $row->value($planting_event);
1293 $row->update();
1294 } else {
1295 print STDERR "date format did not pass check while preparing to set planting date: $planting_date \n";
1299 sub remove_planting_date {
1300 my $self = shift;
1301 my $planting_date = shift;
1303 my $calendar_funcs = CXGN::Calendar->new({});
1304 if (my $planting_event = $calendar_funcs->check_value_format($planting_date) ) {
1306 my $planting_date_cvterm_id = $self->get_planting_date_cvterm_id();
1308 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find_or_create(
1310 project_id => $self->get_trial_id(),
1311 type_id => $planting_date_cvterm_id,
1312 value => $planting_event,
1315 if ($row) {
1316 print STDERR "Removing planting date $planting_event from trial ".$self->get_trial_id()."\n";
1317 $row->delete();
1319 } else {
1320 print STDERR "date format did not pass check while preparing to delete planting date: $planting_date \n";
1324 =head2 accessors get_transplanting_date(), set_transplanting_date()
1326 Usage:
1327 Desc:
1328 Ret:
1329 Args:
1330 Side Effects:
1331 Example:
1333 =cut
1335 sub get_transplanting_date {
1336 my $self = shift;
1337 my $transplanting_date_cvterm_id = $self->get_transplanting_date_cvterm_id();
1338 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find({
1339 project_id => $self->get_trial_id(),
1340 type_id => $transplanting_date_cvterm_id,
1343 my $calendar_funcs = CXGN::Calendar->new({});
1344 if ($row){
1345 my $harvest_date = $calendar_funcs->display_start_date($row->value());
1346 return $harvest_date;
1348 else {
1349 return;
1353 sub set_transplanting_date {
1354 my $self = shift;
1355 my $transplanting_date = shift;
1356 my $calendar_funcs = CXGN::Calendar->new({});
1358 if (my $transplanting_event = $calendar_funcs->check_value_format($transplanting_date)) {
1359 my $transplanting_date_cvterm_id = $self->get_transplanting_date_cvterm_id();
1360 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find_or_create({
1361 project_id => $self->get_trial_id(),
1362 type_id => $transplanting_date_cvterm_id,
1364 $row->value($transplanting_event);
1365 $row->update();
1367 else{
1368 print STDERR "date format did not pass check while preparing to set transplanting date: $transplanting_date \n";
1372 sub remove_transplanting_date {
1373 my $self = shift;
1374 my $transplanting_date = shift;
1375 my $calendar_funcs = CXGN::Calendar->new({});
1376 if (my $transplanting_event = $calendar_funcs->check_value_format($transplanting_date) ) {
1377 my $transplanting_date_cvterm_id = $self->get_transplanting_date_cvterm_id();
1378 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find_or_create({
1379 project_id => $self->get_trial_id(),
1380 type_id => $transplanting_date_cvterm_id,
1381 value => $transplanting_event,
1383 if ($row){
1384 print STDERR "Removing transplanting date $transplanting_event from trial ".$self->get_trial_id()."\n";
1385 $row->delete();
1388 else {
1389 print STDERR "date format did not pass check while preparing to delete transplanting date: $transplanting_date \n";
1394 =head2 accessors get_temperature_averaged_gdd(), set_temperature_averaged_gdd()
1396 Usage:
1397 Desc:
1398 Ret:
1399 Args:
1400 Side Effects:
1401 Example:
1403 =cut
1405 sub get_temperature_averaged_gdd {
1406 my $self = shift;
1408 my $temperature_averaged_gdd_cvterm_id = $self->get_temperature_averaged_gdd_cvterm_id();
1409 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find({
1410 project_id => $self->get_trial_id(),
1411 type_id => $temperature_averaged_gdd_cvterm_id,
1414 if ($row) {
1415 return $row->value;
1416 } else {
1417 return;
1421 sub set_temperature_averaged_gdd {
1422 my $self = shift;
1423 my $temperature_averaged_gdd = shift;
1425 my $temperature_averaged_gdd_cvterm_id = $self->get_temperature_averaged_gdd_cvterm_id();
1426 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find_or_create({
1427 project_id => $self->get_trial_id(),
1428 type_id => $temperature_averaged_gdd_cvterm_id,
1430 $row->value($temperature_averaged_gdd);
1431 $row->update();
1434 sub remove_temperature_averaged_gdd {
1435 my $self = shift;
1436 my $temperature_averaged_gdd = shift;
1438 my $temperature_averaged_gdd_cvterm_id = $self->get_temperature_averaged_gdd_cvterm_id();
1439 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find_or_create({
1440 project_id => $self->get_trial_id(),
1441 type_id => $temperature_averaged_gdd_cvterm_id,
1442 value => $temperature_averaged_gdd,
1444 if ($row) {
1445 print STDERR "Removing $temperature_averaged_gdd from trial ".$self->get_trial_id()."\n";
1446 $row->delete();
1450 sub get_temperature_averaged_gdd_cvterm_id {
1451 my $self = shift;
1452 return SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'drone_run_averaged_temperature_growing_degree_days', 'project_property')->cvterm_id();
1455 =head2 accessors get_precipitation_averaged_sum_gdd(), set_precipitation_averaged_sum_gdd()
1457 Usage:
1458 Desc:
1459 Ret:
1460 Args:
1461 Side Effects:
1462 Example:
1464 =cut
1466 sub get_precipitation_averaged_sum_gdd {
1467 my $self = shift;
1469 my $precipitation_cvterm_id = $self->get_precipitation_averaged_sum_cvterm_id();
1470 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find({
1471 project_id => $self->get_trial_id(),
1472 type_id => $precipitation_cvterm_id,
1475 if ($row) {
1476 return $row->value;
1477 } else {
1478 return;
1482 sub set_precipitation_averaged_sum_gdd {
1483 my $self = shift;
1484 my $precipitation_averaged_sum = shift;
1486 my $precipitation_cvterm_id = $self->get_precipitation_averaged_sum_cvterm_id();
1487 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find_or_create({
1488 project_id => $self->get_trial_id(),
1489 type_id => $precipitation_cvterm_id,
1491 $row->value($precipitation_averaged_sum);
1492 $row->update();
1495 sub remove_precipitation_averaged_sum {
1496 my $self = shift;
1497 my $precipitation = shift;
1499 my $precipitation_cvterm_id = $self->get_precipitation_averaged_sum_cvterm_id();
1500 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find_or_create({
1501 project_id => $self->get_trial_id(),
1502 type_id => $precipitation_cvterm_id,
1503 value => $precipitation,
1505 if ($row) {
1506 print STDERR "Removing $precipitation from trial ".$self->get_trial_id()."\n";
1507 $row->delete();
1511 sub get_precipitation_averaged_sum_cvterm_id {
1512 my $self = shift;
1513 return SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'drone_run_averaged_precipitation_sum', 'project_property')->cvterm_id();
1516 =head2 accessors get_related_time_cvterms_json(), set_related_time_cvterms_json()
1518 Usage:
1519 Desc:
1520 Ret:
1521 Args:
1522 Side Effects:
1523 Example:
1525 =cut
1527 sub get_related_time_cvterms_json {
1528 my $self = shift;
1530 my $cvterm_id = $self->get_related_time_cvterms_json_cvterm_id();
1531 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find({
1532 project_id => $self->get_trial_id(),
1533 type_id => $cvterm_id,
1536 if ($row) {
1537 return $row->value;
1538 } else {
1539 return;
1543 sub set_related_time_cvterms_json {
1544 my $self = shift;
1545 my $related_time_terms_json = shift;
1547 my $cvterm_id = $self->get_related_time_cvterms_json_cvterm_id();
1548 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find_or_create({
1549 project_id => $self->get_trial_id(),
1550 type_id => $cvterm_id,
1552 $row->value($related_time_terms_json);
1553 $row->update();
1556 sub remove_related_time_cvterms_json {
1557 my $self = shift;
1558 my $related_time_terms_json = shift;
1560 my $cvterm_id = $self->get_related_time_cvterms_json_cvterm_id();
1561 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find_or_create({
1562 project_id => $self->get_trial_id(),
1563 type_id => $cvterm_id,
1564 value => $related_time_terms_json,
1566 if ($row) {
1567 print STDERR "Removing $related_time_terms_json from trial ".$self->get_trial_id()."\n";
1568 $row->delete();
1572 sub get_related_time_cvterms_json_cvterm_id {
1573 my $self = shift;
1574 return SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'drone_run_related_time_cvterms_json', 'project_property')->cvterm_id();
1577 =head2 function get_management_factor_date()
1579 Usage: $trial->get_management_factor_date();
1580 Desc: Field management factors are a project and are therefore instantiated with CXGN::Trial. this gets the date projectprop
1581 Ret: Returns string
1582 Args:
1583 Side Effects:
1584 Example:
1586 =cut
1588 sub get_management_factor_date {
1589 my $self = shift;
1591 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find({
1592 project_id => $self->get_trial_id(),
1593 type_id => $self->get_mangement_factor_date_cvterm_id()
1595 my $calendar_funcs = CXGN::Calendar->new({});
1597 if ($row) {
1598 return $calendar_funcs->display_start_date($row->value());
1599 } else {
1600 return;
1604 sub set_management_factor_date {
1605 my $self = shift;
1606 my $management_factor_date = shift;
1608 my $calendar_funcs = CXGN::Calendar->new({});
1610 if (my $management_factor_event = $calendar_funcs->check_value_format($management_factor_date) ) {
1611 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find_or_create({
1612 project_id => $self->get_trial_id(),
1613 type_id => $self->get_mangement_factor_date_cvterm_id()
1616 $row->value($management_factor_event);
1617 $row->update();
1618 } else {
1619 print STDERR "date format did not pass check while preparing to set management factor date: $management_factor_date \n";
1623 sub get_mangement_factor_date_cvterm_id {
1624 my $self = shift;
1625 return SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'management_factor_date', 'project_property')->cvterm_id();
1628 sub get_mangement_factor_type_cvterm_id {
1629 my $self = shift;
1630 return SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'management_factor_type', 'project_property')->cvterm_id();
1633 sub get_management_factor_type {
1634 my $self = shift;
1636 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find({
1637 project_id => $self->get_trial_id(),
1638 type_id => $self->get_mangement_factor_type_cvterm_id()
1641 if ($row) {
1642 return $row->value();
1643 } else {
1644 return;
1648 sub set_management_factor_type {
1649 my $self = shift;
1650 my $management_factor_type = shift;
1652 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find_or_create({
1653 project_id => $self->get_trial_id(),
1654 type_id => $self->get_mangement_factor_type_cvterm_id()
1657 $row->value($management_factor_type);
1658 $row->update();
1661 =head2 accessors get_phenotypes_fully_uploaded(), set_phenotypes_fully_uploaded()
1663 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
1664 Desc:
1665 Ret:
1666 Args:
1667 Side Effects:
1668 Example:
1670 =cut
1672 sub get_phenotypes_fully_uploaded {
1673 my $self = shift;
1674 return $self->_get_projectprop('phenotypes_fully_uploaded');
1677 sub set_phenotypes_fully_uploaded {
1678 my $self = shift;
1679 my $value = shift;
1680 $self->_set_projectprop('phenotypes_fully_uploaded', $value);
1683 =head2 accessors get_raw_data_link(), set_raw_data_link()
1685 Usage: For genotyping plates, a genotyping facility can be set as a projectprop value e.g. 'igd'
1686 Desc:
1687 Ret:
1688 Args:
1689 Side Effects:
1690 Example:
1692 =cut
1694 sub get_raw_data_link {
1695 my $self = shift;
1696 return $self->_get_projectprop('raw_data_link');
1699 sub set_raw_data_link {
1700 my $self = shift;
1701 my $value = shift;
1702 $self->_set_projectprop('raw_data_link', $value);
1706 =head2 accessors get_genotyping_facility(), set_genotyping_facility()
1708 Usage: For genotyping plates, a genotyping facility can be set as a projectprop value e.g. 'igd'
1709 Desc:
1710 Ret:
1711 Args:
1712 Side Effects:
1713 Example:
1715 =cut
1717 sub get_genotyping_facility {
1718 my $self = shift;
1719 return $self->_get_projectprop('genotyping_facility');
1722 sub set_genotyping_facility {
1723 my $self = shift;
1724 my $value = shift;
1725 $self->_set_projectprop('genotyping_facility', $value);
1728 =head2 accessors get_genotyping_facility_submitted(), set_genotyping_facility_submitted()
1730 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'
1731 Desc:
1732 Ret:
1733 Args:
1734 Side Effects:
1735 Example:
1737 =cut
1739 sub get_genotyping_facility_submitted {
1740 my $self = shift;
1741 return $self->_get_projectprop('genotyping_facility_submitted');
1744 sub set_genotyping_facility_submitted {
1745 my $self = shift;
1746 my $value = shift;
1747 $self->_set_projectprop('genotyping_facility_submitted', $value);
1750 =head2 accessors get_genotyping_facility_status(), set_genotyping_facility_status()
1752 Usage: For genotyping plates, if a genotyping plate has been submitted to genotyping facility, the status of that plate can be set here
1753 Desc:
1754 Ret:
1755 Args:
1756 Side Effects:
1757 Example:
1759 =cut
1761 sub get_genotyping_facility_status {
1762 my $self = shift;
1763 return $self->_get_projectprop('genotyping_facility_status');
1766 sub set_genotyping_facility_status {
1767 my $self = shift;
1768 my $value = shift;
1769 $self->_set_projectprop('genotyping_facility_status', $value);
1772 =head2 accessors get_genotyping_vendor_order_id(), set_genotyping_vendor_order_id()
1774 Usage: For genotyping plates, if a genotyping plate has been submitted to genotyping facility, the order id of that plate can be set here
1775 Desc:
1776 Ret:
1777 Args:
1778 Side Effects:
1779 Example:
1781 =cut
1783 sub get_genotyping_vendor_order_id {
1784 my $self = shift;
1785 return $self->_get_projectprop('genotyping_vendor_order_id');
1788 sub set_genotyping_vendor_order_id {
1789 my $self = shift;
1790 my $value = shift;
1791 $self->_set_projectprop('genotyping_vendor_order_id', $value);
1794 =head2 accessors get_genotyping_vendor_submission_id(), set_genotyping_vendor_submission_id()
1796 Usage: For genotyping plates, if a genotyping plate has been submitted to genotyping facility, the order id of that plate can be set here
1797 Desc:
1798 Ret:
1799 Args:
1800 Side Effects:
1801 Example:
1803 =cut
1805 sub get_genotyping_vendor_submission_id {
1806 my $self = shift;
1807 return $self->_get_projectprop('genotyping_vendor_submission_id');
1810 sub set_genotyping_vendor_submission_id {
1811 my $self = shift;
1812 my $value = shift;
1813 $self->_set_projectprop('genotyping_vendor_submission_id', $value);
1816 =head2 accessors get_genotyping_plate_format(), set_genotyping_plate_format()
1818 Usage: For genotyping plates, this records if it is 96 wells or 384 or other
1819 Desc:
1820 Ret:
1821 Args:
1822 Side Effects:
1823 Example:
1825 =cut
1827 sub get_genotyping_plate_format {
1828 my $self = shift;
1829 return $self->_get_projectprop('genotyping_plate_format');
1832 sub set_genotyping_plate_format {
1833 my $self = shift;
1834 my $value = shift;
1835 $self->_set_projectprop('genotyping_plate_format', $value);
1838 =head2 accessors get_genotyping_plate_sample_type(), set_genotyping_plate_sample_type()
1840 Usage: For genotyping plates, this records sample type of plate e.g. DNA
1841 Desc:
1842 Ret:
1843 Args:
1844 Side Effects:
1845 Example:
1847 =cut
1849 sub get_genotyping_plate_sample_type {
1850 my $self = shift;
1851 return $self->_get_projectprop('genotyping_plate_sample_type');
1854 sub set_genotyping_plate_sample_type {
1855 my $self = shift;
1856 my $value = shift;
1857 $self->_set_projectprop('genotyping_plate_sample_type', $value);
1860 =head2 accessors get_field_trial_is_planned_to_be_genotyped(), set_field_trial_is_planned_to_be_genotyped()
1862 Usage: For field trials, this records whether the trial will be genotyped
1863 Desc:
1864 Ret:
1865 Args:
1866 Side Effects:
1867 Example:
1869 =cut
1871 sub get_field_trial_is_planned_to_be_genotyped {
1872 my $self = shift;
1873 return $self->_get_projectprop('field_trial_is_planned_to_be_genotyped');
1876 sub set_field_trial_is_planned_to_be_genotyped {
1877 my $self = shift;
1878 my $value = shift;
1879 $self->_set_projectprop('field_trial_is_planned_to_be_genotyped', $value);
1882 =head2 accessors get_field_trial_is_planned_to_cross(), set_field_trial_is_planned_to_cross()
1884 Usage: For field trials, this records whether the trial will be involved in crosses
1885 Desc:
1886 Ret:
1887 Args:
1888 Side Effects:
1889 Example:
1891 =cut
1893 sub get_field_trial_is_planned_to_cross {
1894 my $self = shift;
1895 return $self->_get_projectprop('field_trial_is_planned_to_cross');
1898 sub set_field_trial_is_planned_to_cross {
1899 my $self = shift;
1900 my $value = shift;
1901 $self->_set_projectprop('field_trial_is_planned_to_cross', $value);
1904 =head2 accessors get_plot_width(), set_plot_width()
1906 Usage: For field trials, this records plot width in meters
1907 Desc:
1908 Ret:
1909 Args:
1910 Side Effects:
1911 Example:
1913 =cut
1915 sub get_plot_width {
1916 my $self = shift;
1917 return $self->_get_projectprop('plot_width');
1920 sub set_plot_width {
1921 my $self = shift;
1922 my $value = shift;
1923 $self->_set_projectprop('plot_width', $value);
1926 =head2 accessors get_plot_length(), set_plot_length()
1928 Usage: For field trials, this records plot length in meters
1929 Desc:
1930 Ret:
1931 Args:
1932 Side Effects:
1933 Example:
1935 =cut
1937 sub get_plot_length {
1938 my $self = shift;
1939 return $self->_get_projectprop('plot_length');
1942 sub set_plot_length {
1943 my $self = shift;
1944 my $value = shift;
1945 $self->_set_projectprop('plot_length', $value);
1948 =head2 accessors get_field_size(), set_field_size()
1950 Usage: For field trials, this recordsfield size in hectares
1951 Desc:
1952 Ret:
1953 Args:
1954 Side Effects:
1955 Example:
1957 =cut
1959 sub get_field_size {
1960 my $self = shift;
1961 return $self->_get_projectprop('field_size');
1964 sub set_field_size {
1965 my $self = shift;
1966 my $value = shift;
1967 $self->_set_projectprop('field_size', $value);
1970 =head2 accessors get_additional_info(), set_additional_info()
1972 Usage: For field trials, this stores brapi additional information
1973 Desc:
1974 Ret:
1975 Args:
1976 Side Effects:
1977 Example:
1979 =cut
1981 sub get_additional_info {
1982 my $self = shift;
1983 my $additional_info = $self->_get_projectprop('project_additional_info');
1984 return $additional_info ? decode_json($additional_info) : undef;
1987 sub set_additional_info {
1988 my $self = shift;
1989 my $value = shift;
1990 $self->_set_projectprop('project_additional_info', encode_json($value));
1993 =head2 accessors get_entry_numbers(), set_entry_numbers()
1995 Usage: For field trials, this records a map of stock ids to entry numbers
1996 Desc: The value of this projectprop is stored as a JSON object, where the
1997 key is the stock id and the value is the stock entry number
1998 Ret:
1999 Args:
2000 Side Effects:
2001 Example:
2003 =cut
2005 sub get_entry_numbers {
2006 my $self = shift;
2007 my $value = $self->_get_projectprop('project_entry_number_map');
2008 return $value ? decode_json($value) : undef;
2011 sub set_entry_numbers {
2012 my $self = shift;
2013 my $value = shift;
2014 $self->_set_projectprop('project_entry_number_map', encode_json($value));
2017 sub _get_projectprop {
2018 my $self = shift;
2019 my $term = shift;
2020 my $cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, $term, 'project_property')->cvterm_id;
2021 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find({
2022 project_id => $self->get_trial_id(),
2023 type_id => $cvterm_id,
2026 if ($row) {
2027 return $row->value;
2028 } else {
2029 return;
2033 sub _set_projectprop {
2034 my $self = shift;
2035 my $term = shift;
2036 my $value = shift;
2037 my $cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, $term, 'project_property')->cvterm_id;
2038 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find_or_create({
2039 project_id => $self->get_trial_id(),
2040 type_id => $cvterm_id,
2042 $row->value($value);
2043 $row->update();
2046 sub get_owner_link {
2047 my $self = shift;
2048 my $owners = $self->_get_trial_owners();
2049 my @sp_person_ids = keys % { $owners } ;
2050 my $q = "SELECT first_name, last_name FROM sgn_people.sp_person WHERE sp_person_id=?;";
2051 my $link;
2052 foreach my $sp_person_id (@sp_person_ids) {
2053 my $h = $self->bcs_schema()->storage->dbh()->prepare($q);
2054 $h->execute($sp_person_id);
2055 my ( $first_name, $last_name ) = $h->fetchrow_array();
2056 my $create_date = ${ $owners }{$sp_person_id};
2058 $link .= '<a href="/solpeople/personal-info.pl?sp_person_id='.$sp_person_id. '">' . $first_name . " " . $last_name . "</a> ". $create_date . "<br />";
2060 return $link;
2063 sub _get_trial_owners {
2064 my $self = shift;
2065 my $schema = $self->bcs_schema();
2066 my $owner_q = "SELECT sp_person_id, date(create_date) FROM phenome.project_owner WHERE project_id = ? ";
2067 my $owner_h = $schema->storage->dbh()->prepare($owner_q);
2068 $owner_h ->execute($self->get_trial_id());
2070 my %owners;
2071 while (my ($sp_person_id, $create_date) = $owner_h->fetchrow_array()) {
2072 $owners{$sp_person_id} = $create_date;
2074 return \%owners;
2077 sub set_trial_owner {
2078 my $self = shift;
2079 my $sp_person_id = shift;
2080 my $schema = $self->bcs_schema();
2081 my $trial_id = $self->get_trial_id();
2082 my $q = "INSERT INTO phenome.project_owner (project_id, sp_person_id, create_date) VALUES (?,?,now())";
2083 my $h = $schema->storage->dbh()->prepare($q);
2084 $h->execute($trial_id,$sp_person_id);
2087 =head2 function delete_phenotype_data()
2089 Usage:
2090 Desc:
2091 Ret:
2092 Args:
2093 Side Effects:
2094 Example:
2096 =cut
2098 # note: you may need to delete the metadata before deleting the phenotype data (see function).
2099 # this function has a test!
2101 sub delete_phenotype_data {
2102 my $self = shift;
2103 my $basepath = shift;
2104 my $dbhost = shift;
2105 my $dbname = shift;
2106 my $dbuser = shift;
2107 my $dbpass = shift;
2108 my $temp_file_nd_experiment_id = shift;
2110 my $trial_id = $self->get_trial_id();
2111 my $nd_experiment_type_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'phenotyping_experiment', 'experiment_type')->cvterm_id();
2113 my $q_search = "
2114 SELECT phenotype_id, nd_experiment_id, file_id
2115 FROM phenotype
2116 JOIN nd_experiment_phenotype using(phenotype_id)
2117 JOIN nd_experiment using(nd_experiment_id)
2118 JOIN nd_experiment_stock using(nd_experiment_id)
2119 JOIN nd_experiment_project using(nd_experiment_id)
2120 LEFT JOIN phenome.nd_experiment_md_files using(nd_experiment_id)
2121 JOIN stock using(stock_id)
2122 WHERE project_id = $trial_id
2123 AND nd_experiment.type_id = $nd_experiment_type_id;
2125 my $h = $self->bcs_schema->storage->dbh()->prepare($q_search);
2126 $h->execute();
2128 my %phenotype_ids_and_nd_experiment_ids_to_delete;
2129 while (my ($phenotype_id, $nd_experiment_id, $file_id) = $h->fetchrow_array()) {
2130 push @{$phenotype_ids_and_nd_experiment_ids_to_delete{phenotype_ids}}, $phenotype_id;
2131 push @{$phenotype_ids_and_nd_experiment_ids_to_delete{nd_experiment_ids}}, $nd_experiment_id;
2133 return delete_phenotype_values_and_nd_experiment_md_values($dbhost, $dbname, $dbuser, $dbpass, $temp_file_nd_experiment_id, $basepath, $self->bcs_schema, \%phenotype_ids_and_nd_experiment_ids_to_delete);
2136 #Class function
2137 sub delete_phenotype_values_and_nd_experiment_md_values {
2138 my $dbhost = shift;
2139 my $dbname = shift;
2140 my $dbuser = shift;
2141 my $dbpass = shift;
2142 my $temp_file_nd_experiment_id = shift;
2143 my $basepath = shift;
2144 my $schema = shift;
2145 my $phenotype_ids_and_nd_experiment_ids_to_delete = shift;
2147 my $coderef = sub {
2148 my $phenotype_id_sql = join (",", @{$phenotype_ids_and_nd_experiment_ids_to_delete->{phenotype_ids}});
2149 my $q_pheno_delete = "DELETE FROM phenotype WHERE phenotype_id IN ($phenotype_id_sql);";
2150 my $h2 = $schema->storage->dbh()->prepare($q_pheno_delete);
2151 $h2->execute();
2153 print STDERR "DELETED ".scalar(@{$phenotype_ids_and_nd_experiment_ids_to_delete->{phenotype_ids}})." Phenotype Values\n";
2155 my $nd_experiment_id_sql = join (",", @{$phenotype_ids_and_nd_experiment_ids_to_delete->{nd_experiment_ids}});
2157 # check if the nd_experiment has no other associated phenotypes, since phenotypstore actually attaches many phenotypes to one nd_experiment
2159 my $checkq = "SELECT nd_experiment_id FROM nd_experiment left join nd_experiment_phenotype using(nd_experiment_id) where nd_experiment_id in ($nd_experiment_id_sql) and phenotype_id IS NULL";
2160 my $check_h = $schema->storage->dbh()->prepare($checkq);
2161 $check_h ->execute();
2163 my @nd_experiment_ids;
2164 while (my ($nd_experiment_id) = $check_h->fetchrow_array()) {
2165 push @nd_experiment_ids, $nd_experiment_id;
2168 if (scalar(@nd_experiment_ids)>0) {
2169 $nd_experiment_id_sql = join(",", @nd_experiment_ids);
2171 my $q_nd_exp_files_delete = "DELETE FROM phenome.nd_experiment_md_files WHERE nd_experiment_id IN ($nd_experiment_id_sql);";
2172 my $h3 = $schema->storage->dbh()->prepare($q_nd_exp_files_delete);
2173 $h3->execute();
2175 my $q_nd_json = "DELETE FROM phenome.nd_experiment_md_json WHERE nd_experiment_id IN ($nd_experiment_id_sql)";
2176 my $h_nd_json = $schema->storage->dbh()->prepare($q_nd_json);
2177 $h_nd_json->execute();
2179 my $q_nd_exp_files_images_delete = "DELETE FROM phenome.nd_experiment_md_images WHERE nd_experiment_id IN ($nd_experiment_id_sql);";
2180 my $h4 = $schema->storage->dbh()->prepare($q_nd_exp_files_images_delete);
2181 $h4->execute();
2183 open (my $fh, ">", $temp_file_nd_experiment_id ) || print STDERR ("\nWARNING: the file $temp_file_nd_experiment_id could not be found\n" );
2184 foreach (@nd_experiment_ids) {
2185 print $fh "$_\n";
2187 close($fh);
2189 my $async_delete = CXGN::Tools::Run->new();
2190 $async_delete->run_async("perl $basepath/bin/delete_nd_experiment_entries.pl -H $dbhost -D $dbname -U $dbuser -P $dbpass -i $temp_file_nd_experiment_id");
2192 print STDERR "DELETED ".scalar(@{$phenotype_ids_and_nd_experiment_ids_to_delete->{phenotype_ids}})." Phenotype Values and nd_experiment_md_file_links (and ".scalar(@nd_experiment_ids)." nd_experiment entries may still be in deletion in asynchronous process.)\n";
2196 my $error;
2197 try {
2198 $schema->txn_do($coderef);
2199 } catch {
2200 print STDERR "ERROR: $_\n";
2201 $error = $_;
2203 return $error;
2206 =head2 function delete_field_layout()
2208 Usage:
2209 Desc:
2210 Ret:
2211 Args:
2212 Side Effects:
2213 Example:
2215 =cut
2218 # this function has a test!
2220 sub delete_field_layout {
2221 my $self = shift;
2223 my $trial_id = $self->get_trial_id();
2225 if (scalar(@{$self->get_genotyping_trials_from_field_trial}) > 0) {
2226 return 'This field trial has been linked to genotyping trials already, and cannot be easily deleted.';
2228 if (scalar(@{$self->get_field_trials_source_of_genotyping_trial}) > 0) {
2229 return 'This genotyping trial has been linked to field trials already, and cannot be easily deleted.';
2231 if (scalar(@{$self->get_crossing_trials_from_field_trial}) >0) {
2232 return 'This field trial has been linked to crossing trials already, and cannot be easily deleted.';
2234 if (scalar(@{$self->get_field_trials_source_of_crossing_trial}) >0) {
2235 return 'This crossing trial has been linked to field trials already, and cannot be easily deleted.';
2238 # Note: metadata entries need to be deleted separately using delete_metadata()
2240 my $error = '';
2241 eval {
2242 $self->bcs_schema()->txn_do(
2243 sub {
2244 #print STDERR "DELETING FIELD LAYOUT FOR TRIAL $trial_id...\n";
2245 $self->_delete_field_layout_experiment();
2246 #print STDERR "DELETE MANAGEMENT FACTORS FOR TRIAL $trial_id...\n";
2247 $self->_delete_management_factors_experiments();
2251 if ($@) {
2252 print STDERR "ERROR $@\n";
2253 return "An error occurred: $@\n";
2256 return '';
2259 =head2 function get_phenotype_metadata()
2261 Usage: $trial->get_phenotype_metadata();
2262 Desc: retrieves metadata.md_file entries for this trial. These entries are created during StorePhenotypes
2263 Ret:
2264 Args:
2265 Side Effects:
2266 Example:
2268 =cut
2270 sub get_phenotype_metadata {
2271 my $self = shift;
2272 my $trial_id = $self->get_trial_id();
2273 my @file_array;
2274 my %file_info;
2275 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";
2276 my $h = $self->bcs_schema->storage()->dbh()->prepare($q);
2277 $h->execute($trial_id);
2279 while (my ($file_id, $create_date, $person_id, $username, $basename, $dirname, $filetype) = $h->fetchrow_array()) {
2280 $file_info{$file_id} = [$file_id, $create_date, $person_id, $username, $basename, $dirname, $filetype];
2282 foreach (keys %file_info){
2283 push @file_array, $file_info{$_};
2285 return \@file_array;
2288 =head2 function delete_phenotype_metadata()
2290 Usage: $trial->delete_phenotype_metadata($metadata_schema, $phenome_schema);
2291 Desc: obsoletes the metadata entries for this trial.
2292 Ret:
2293 Args:
2294 Side Effects:
2295 Example:
2297 =cut
2299 sub delete_phenotype_metadata {
2300 my $self = shift;
2301 my $metadata_schema = shift;
2302 my $phenome_schema = shift;
2304 if (!$metadata_schema || !$phenome_schema) { die "Need metadata schema parameter\n"; }
2306 my $trial_id = $self->get_trial_id();
2308 #print STDERR "Deleting metadata for trial $trial_id...\n";
2310 # first, deal with entries in the md_metadata table, which may reference nd_experiment (through linking table)
2312 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=?";
2313 my $h = $self->bcs_schema->storage()->dbh()->prepare($q);
2314 $h->execute($trial_id);
2316 while (my ($md_id) = $h->fetchrow_array()) {
2317 #print STDERR "Associated metadata id: $md_id\n";
2318 my $mdmd_row = $metadata_schema->resultset("MdMetadata")->find( { metadata_id => $md_id } );
2319 if ($mdmd_row) {
2320 #print STDERR "Obsoleting $md_id...\n";
2322 $mdmd_row -> update( { obsolete => 1 });
2326 #print STDERR "Deleting the entries in the linking table...\n";
2328 # delete the entries from the linking table...
2329 $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=?";
2330 $h = $self->bcs_schema->storage()->dbh()->prepare($q);
2331 $h->execute($trial_id);
2333 while (my ($file_id) = $h->fetchrow_array()) {
2334 print STDERR "trying to delete association for file with id $file_id...\n";
2335 my $ndemdf_rs = $phenome_schema->resultset("NdExperimentMdFiles")->search( { file_id=>$file_id });
2336 print STDERR "Deleting md_files linking table entries...\n";
2337 foreach my $row ($ndemdf_rs->all()) {
2338 print STDERR "DELETING !!!!\n";
2339 $row->delete();
2346 =head2 function delete_metadata()
2348 Usage: $trial->delete_metadata();
2349 Desc: obsoletes the metadata entries for this trial.
2350 Ret:
2351 Args:
2352 Side Effects:
2353 Example:
2355 =cut
2357 sub delete_metadata {
2358 my $self = shift;
2359 my $metadata_schema = $self->metadata_schema;
2360 my $phenome_schema = $self->phenome_schema;
2362 if (!$metadata_schema || !$phenome_schema) { die "Need metadata schema parameter\n"; }
2364 my $trial_id = $self->get_trial_id();
2366 if (scalar(@{$self->get_genotyping_trials_from_field_trial}) > 0) {
2367 return 'This field trial has been linked to genotyping trials already, and cannot be easily deleted.';
2369 if (scalar(@{$self->get_field_trials_source_of_genotyping_trial}) > 0) {
2370 return 'This genotyping trial has been linked to field trials already, and cannot be easily deleted.';
2372 if (scalar(@{$self->get_crossing_trials_from_field_trial}) >0) {
2373 return 'This field trial has been linked to crossing trials already, and cannot be easily deleted.';
2375 if (scalar(@{$self->get_field_trials_source_of_crossing_trial}) >0) {
2376 return 'This crossing trial has been linked to field trials already, and cannot be easily deleted.';
2379 #print STDERR "Deleting metadata for trial $trial_id...\n";
2381 # first, deal with entries in the md_metadata table, which may reference nd_experiment (through linking table)
2383 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=?";
2384 my $h = $self->bcs_schema->storage()->dbh()->prepare($q);
2385 $h->execute($trial_id);
2387 while (my ($md_id) = $h->fetchrow_array()) {
2388 #print STDERR "Associated metadata id: $md_id\n";
2389 my $mdmd_row = $metadata_schema->resultset("MdMetadata")->find( { metadata_id => $md_id } );
2390 if ($mdmd_row) {
2391 #print STDERR "Obsoleting $md_id...\n";
2393 $mdmd_row -> update( { obsolete => 1 });
2397 #print STDERR "Deleting the entries in the linking table...\n";
2399 # delete the entries from the linking table... (left joins are due to sometimes missing md_file entries)
2400 $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=?";
2401 $h = $self->bcs_schema->storage()->dbh()->prepare($q);
2402 $h->execute($trial_id);
2404 while (my ($file_id) = $h->fetchrow_array()) {
2405 print STDERR "trying to delete association for file with id $file_id...\n";
2406 my $ndemdf_rs = $phenome_schema->resultset("NdExperimentMdFiles")->search( { file_id=>$file_id });
2407 print STDERR "Deleting md_files linking table entries...\n";
2408 foreach my $row ($ndemdf_rs->all()) {
2409 print STDERR "DELETING !!!!\n";
2410 $row->delete();
2416 sub _delete_field_layout_experiment {
2417 my $self = shift;
2419 my $trial_id = $self->get_trial_id();
2421 print STDERR "_delete_field_layout_experiment...\n";
2423 # check if there are still associated phenotypes...
2425 if ($self->phenotype_count() > 0) {
2426 print STDERR "Attempt to delete field layout that still has associated phenotype data.\n";
2427 die "cannot delete because of associated phenotypes\n";
2428 return { error => "Trial still has associated phenotyping experiment, cannot delete." };
2431 my $field_layout_type_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'field_layout', 'experiment_type')->cvterm_id();
2432 my $genotyping_layout_type_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'genotyping_layout', 'experiment_type')->cvterm_id();
2433 my $analysis_experiment_type_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'analysis_experiment', 'experiment_type')->cvterm_id();
2435 my $layout_design = $self->get_layout->get_design;
2436 my @all_stock_ids;
2437 while( my($plot_num, $design_info) = each %$layout_design){
2438 my $plot_id = $design_info->{plot_id}; #this includes the "tissue_sample" in "genotyping_layout"
2439 my @plant_ids = $design_info->{plant_ids} ? @{$design_info->{plant_ids}} : ();
2440 my @subplot_ids = $design_info->{subplot_ids} ? @{$design_info->{subplot_ids}} : ();
2441 my @tissue_sample_ids = $design_info->{tissue_sample_ids} ? @{$design_info->{tissue_sample_ids}} : ();
2442 push @all_stock_ids, $plot_id;
2443 push @all_stock_ids, @plant_ids;
2444 push @all_stock_ids, @tissue_sample_ids;
2445 push @all_stock_ids, @subplot_ids;
2448 my $phenome_schema = CXGN::Phenome::Schema->connect( sub {
2449 $self->bcs_schema->storage->dbh()
2452 on_connect_do => ['SET search_path TO public,phenome;']
2454 foreach my $s (@all_stock_ids) {
2455 my $stock_owner_rs = $phenome_schema->resultset('StockOwner')->search({stock_id=>$s});
2456 while (my $stock_row = $stock_owner_rs->next) {
2457 $stock_row->delete();
2459 my $stock_delete_rs = $self->bcs_schema->resultset('Stock::Stock')->search({stock_id=>$s});
2460 while (my $r = $stock_delete_rs->next){
2461 $r->delete();
2466 my $has_plants = $self->has_plant_entries();
2467 my $has_subplots = $self->has_subplot_entries();
2468 my $has_tissues = $self->has_tissue_sample_entries();
2470 if ($has_plants) {
2471 my $has_plants_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'project_has_plant_entries', 'project_property' )->cvterm_id();
2472 my $has_plants_prop = $self->bcs_schema->resultset("Project::Projectprop")->find({ type_id => $has_plants_cvterm_id, project_id => $trial_id });
2473 $has_plants_prop->delete();
2475 if ($has_subplots) {
2476 my $has_subplots_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'project_has_subplot_entries', 'project_property' )->cvterm_id();
2477 my $has_subplots_prop = $self->bcs_schema->resultset("Project::Projectprop")->find({ type_id => $has_subplots_cvterm_id, project_id => $trial_id });
2478 $has_subplots_prop->delete();
2480 if ($has_tissues) {
2481 my $has_tissues_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'project_has_tissue_sample_entries', 'project_property' )->cvterm_id();
2482 my $has_tissues_prop = $self->bcs_schema->resultset("Project::Projectprop")->find({ type_id => $has_tissues_cvterm_id, project_id => $trial_id });
2483 $has_tissues_prop->delete();
2486 my $trial_layout_json_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'trial_layout_json', 'project_property')->cvterm_id();
2487 my $has_cached_layout_prop = $self->bcs_schema->resultset("Project::Projectprop")->find({ type_id => $trial_layout_json_cvterm_id, project_id => $trial_id });
2488 if ($has_cached_layout_prop){
2489 $has_cached_layout_prop->delete();
2492 my $nde_rs = $self->bcs_schema()->resultset("NaturalDiversity::NdExperiment")->search({ 'me.type_id'=>[$field_layout_type_id, $genotyping_layout_type_id, $analysis_experiment_type_id], 'project.project_id'=>$trial_id }, {'join'=>{'nd_experiment_projects'=>'project'}});
2493 if ($nde_rs->count != 1){
2494 die "Project $trial_id does not have exactly one ndexperiment of type field_layout or genotyping_layout!"
2496 while( my $r = $nde_rs->next){
2497 $r->delete();
2500 #return { success => $plots_deleted };
2501 return { success => 1 };
2504 sub _delete_management_factors_experiments {
2505 my $self = shift;
2506 my $management_factor_type_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'treatment_experiment', 'experiment_type')->cvterm_id();
2507 my $management_factors = $self->get_treatments;
2508 foreach (@$management_factors){
2509 my $m = CXGN::Trial->new({
2510 bcs_schema => $self->bcs_schema,
2511 metadata_schema => $self->metadata_schema,
2512 phenome_schema => $self->phenome_schema,
2513 trial_id => $_->[0]
2515 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'}});
2516 if ($nde_rs->count != 1){
2517 die "Management factor ".$m->get_name." does not have exactly one ndexperiment of type treatment_experiment!"
2519 while( my $r = $nde_rs->next){
2520 $r->delete();
2522 $m->delete_project_entry;
2524 return { success => 1 };
2527 =head2 function delete_project_entry()
2529 Usage:
2530 Desc:
2531 Ret:
2532 Args:
2533 Side Effects:
2534 Example:
2536 =cut
2538 sub delete_project_entry {
2539 my $self = shift;
2541 if ($self->phenotype_count() > 0) {
2542 print STDERR "Cannot delete trial with associated phenotypes.\n";
2543 return;
2546 if (scalar(@{$self->get_genotyping_trials_from_field_trial}) > 0) {
2547 return 'This field trial has been linked to genotyping trials already, and cannot be easily deleted.';
2549 if (scalar(@{$self->get_field_trials_source_of_genotyping_trial}) > 0) {
2550 return 'This genotyping trial has been linked to field trials already, and cannot be easily deleted.';
2552 if (scalar(@{$self->get_crossing_trials_from_field_trial}) >0) {
2553 return 'This field trial has been linked to crossing trials already, and cannot be easily deleted.';
2555 if (scalar(@{$self->get_field_trials_source_of_crossing_trial}) >0) {
2556 return 'This crossing trial has been linked to field trials already, and cannot be easily deleted.';
2559 my $project_owner_schema = CXGN::Phenome::Schema->connect( sub {
2560 $self->bcs_schema->storage->dbh()
2563 on_connect_do => ['SET search_path TO public,phenome;']
2565 my $project_owner_row = $project_owner_schema->resultset('ProjectOwner')->find( { project_id=> $self->get_trial_id() });
2566 if ($project_owner_row) { $project_owner_row->delete(); }
2567 eval {
2568 my $row = $self->bcs_schema->resultset("Project::Project")->find( { project_id=> $self->get_trial_id() });
2569 $row->delete();
2570 print STDERR "deleted project ".$self->get_trial_id."\n";
2572 if ($@) {
2573 print STDERR "An error occurred during deletion: $@\n";
2574 return $@;
2578 =head2 function phenotype_count()
2580 Usage:
2581 Desc: The number of phenotype measurements associated with this trial
2582 Ret:
2583 Args:
2584 Side Effects:
2585 Example:
2587 =cut
2590 sub phenotype_count {
2591 my $self = shift;
2592 my $phenotyping_experiment_type_id = $self->bcs_schema->resultset("Cv::Cvterm")->find( { name => 'phenotyping_experiment' })->cvterm_id();
2594 my $q = "SELECT count(phenotype_id)
2595 FROM phenotype
2596 JOIN nd_experiment_phenotype using(phenotype_id)
2597 JOIN nd_experiment_project using(nd_experiment_id)
2598 JOIN nd_experiment using(nd_experiment_id)
2599 JOIN project using(project_id)
2600 WHERE nd_experiment.type_id = $phenotyping_experiment_type_id
2601 AND project_id = ?;";
2602 my $h = $self->bcs_schema->storage->dbh()->prepare($q);
2603 $h->execute($self->get_trial_id());
2604 my ($count) = $h->fetchrow_array();
2605 return $count;
2609 =head2 function total_phenotypes()
2611 Usage:
2612 Desc: returns the total number of phenotype measurements
2613 associated with the trial
2614 Ret:
2615 Args:
2616 Side Effects:
2617 Example:
2619 =cut
2621 sub total_phenotypes {
2622 my $self = shift;
2624 my $pt_rs = $self->bcs_schema()->resultset("Phenotype::Phenotype")->search( { });
2625 return $pt_rs->count();
2628 =head2 function add_additional_uploaded_file()
2630 Usage: $trial->add_additional_uploaded_file();
2631 Desc: adds metadata.md_file entry for additional_files_uploaded to trial
2632 Ret:
2633 Args:
2634 Side Effects:
2635 Example:
2637 =cut
2639 sub add_additional_uploaded_file {
2640 my $self = shift;
2641 my $user_id = shift;
2642 my $archived_filename_with_path = shift;
2643 my $md5checksum = shift;
2644 my $result = $self->get_nd_experiment_id();
2645 if ($result->{error}){
2646 return {error => $result->{error} };
2648 my $nd_experiment_id = $result->{nd_experiment_id};
2650 my $md_row = $self->metadata_schema->resultset("MdMetadata")->create({create_person_id => $user_id});
2651 $md_row->insert();
2652 my $file_row = $self->metadata_schema->resultset("MdFiles")
2653 ->create({
2654 basename => basename($archived_filename_with_path),
2655 dirname => dirname($archived_filename_with_path),
2656 filetype => 'trial_additional_file_upload',
2657 md5checksum => $md5checksum,
2658 metadata_id => $md_row->metadata_id(),
2660 my $file_id = $file_row->file_id();
2661 my $experiment_file = $self->phenome_schema->resultset("NdExperimentMdFiles")
2662 ->create({
2663 nd_experiment_id => $nd_experiment_id,
2664 file_id => $file_id,
2667 return {success => 1, file_id=>$file_id};
2670 =head2 function get_additional_uploaded_files()
2672 Usage: $trial->get_additional_uploaded_files();
2673 Desc: retrieves metadata.md_file entries for additional_files_uploaded to trial. these entries are created from add_additional_uploaded_file
2674 Ret:
2675 Args:
2676 Side Effects:
2677 Example:
2679 =cut
2681 sub get_additional_uploaded_files {
2682 my $self = shift;
2683 my $trial_id = $self->get_trial_id();
2684 my @file_array;
2685 my %file_info;
2686 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";
2687 my $h = $self->bcs_schema->storage()->dbh()->prepare($q);
2688 $h->execute($trial_id);
2690 while (my ($file_id, $create_date, $person_id, $username, $basename, $dirname, $filetype) = $h->fetchrow_array()) {
2691 $file_info{$file_id} = [$file_id, $create_date, $person_id, $username, $basename, $dirname, $filetype];
2693 foreach (keys %file_info){
2694 push @file_array, $file_info{$_};
2696 return \@file_array;
2701 =head2 obsolete_additional_uploaded_file
2703 Usage:
2704 Desc:
2705 Ret:
2706 Args:
2707 Side Effects:
2708 Example:
2710 =cut
2712 sub obsolete_additional_uploaded_file {
2713 my $self = shift;
2714 my $file_id = shift;
2715 my $user_id = shift;
2716 my $role = shift;
2718 my @errors;
2719 # check ownership of that image
2720 my $q = "SELECT metadata.md_metadata.create_person_id, metadata.md_metadata.metadata_id, metadata.md_files.file_id FROM metadata.md_metadata join metadata.md_files using(metadata_id) where md_metadata.obsolete=0 and md_files.file_id=? and md_metadata.create_person_id=?";
2722 my $dbh = $self->bcs_schema->storage()->dbh();
2723 my $h = $dbh->prepare($q);
2725 $h->execute($file_id, $user_id);
2727 if (my ($create_person_id, $metadata_id, $file_id) = $h->fetchrow_array()) {
2728 if ($create_person_id == $user_id || $role eq "curator") {
2729 my $uq = "UPDATE metadata.md_metadata SET obsolete=1 where metadata_id = ?";
2730 my $uh = $dbh->prepare($uq);
2731 $uh->execute($metadata_id);
2733 else {
2734 push @errors, "Only the owner of the uploaded file, or a curator, can delete this file.";
2738 else {
2739 push @errors, "No such file currently exists.";
2742 if (@errors >0) {
2743 return { errors => \@errors };
2746 return { success => 1 };
2754 =head2 function get_phenotypes_for_trait($trait_id)
2756 Usage:
2757 Desc: returns the measurements for the given trait in this trial as an array of values, e.g. [2.1, 2, 50]
2758 Ret:
2759 Args:
2760 Side Effects:
2761 Example:
2763 =cut
2765 sub get_phenotypes_for_trait {
2766 my $self = shift;
2767 my $trait_id = shift;
2768 my $stock_type = shift;
2769 my @data;
2770 my $dbh = $self->bcs_schema->storage()->dbh();
2771 #my $schema = $self->bcs_schema();
2773 my $h;
2774 my $join_string = '';
2775 my $where_string = '';
2776 if ($stock_type) {
2777 my $stock_type_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, $stock_type, 'stock_type')->cvterm_id();
2778 $join_string = 'JOIN nd_experiment_stock USING(nd_experiment_id) JOIN stock USING(stock_id)';
2779 $where_string = "stock.type_id=$stock_type_id and";
2781 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;";
2782 $h = $dbh->prepare($q);
2784 my $numeric_regex = '^-?[0-9]+([,.][0-9]+)?$';
2785 $h->execute($self->get_trial_id(), $trait_id, $numeric_regex );
2786 while (my ($value) = $h->fetchrow_array()) {
2787 push @data, $value + 0;
2789 return @data;
2792 =head2 function get_stock_phenotypes_for_traits(\@trait_id, 'all', ['plot_of','plant_of'], 'accession', 'subject')
2794 Usage:
2795 Desc: returns all observations for the given traits in this trial
2796 Ret: arrayref of [[ $stock_id, $stock_name, $trait_id, $trait_name, $phenotype_id, $pheno_uniquename, $uploader_id, $value, $rel_stock_id, $rel_stock_name ], [], ...]
2797 Args: trait_ids : arrayref of cvterm_ids
2798 stock_type: the stock type that the phenotype is associated to. 'plot', or 'plant', or 'all'
2799 stock_relationships: for fetching stock_relationships of the phenotyped stock. arrayref of relationships. e.g. ['plot_of', 'plant_of'].
2800 relationship_stock_type: the associated stock_type from the stock_relationship. 'plot', or 'plant'
2801 subject_or_object: whether the stock_relationship join should be done from the subject or object side. 'subject', or 'object'
2802 Side Effects:
2803 Example:
2805 =cut
2807 sub get_stock_phenotypes_for_traits {
2808 my $self = shift;
2809 my $trait_ids = shift;
2810 my $stock_type = shift; #plot, plant, all
2811 my $stock_relationships = shift; #arrayref. plot_of, plant_of
2812 my $relationship_stock_type = shift; #plot, plant
2813 my $subject_or_object = shift;
2814 my @data;
2815 #$self->bcs_schema->storage->debug(1);
2816 my $dbh = $self->bcs_schema->storage()->dbh();
2817 my $where_clause = "WHERE project_id=? and b.cvterm_id = ? and phenotype.value~? ";
2818 my $phenotyping_experiment_cvterm = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'phenotyping_experiment', 'experiment_type')->cvterm_id();
2820 if (scalar(@$trait_ids)>0){
2821 my $sql_trait_ids = join ("," , @$trait_ids);
2822 $where_clause .= "and a.cvterm_id IN ($sql_trait_ids) ";
2825 my $relationship_join = '';
2826 if ($subject_or_object eq 'object') {
2827 $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) ';
2828 } elsif ($subject_or_object eq 'subject') {
2829 $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) ';
2831 if ($stock_type ne 'all') {
2832 my $stock_type_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema(), $stock_type, 'stock_type')->cvterm_id();
2833 $where_clause .= "and stock.type_id=$stock_type_cvterm_id ";
2835 my @stock_rel_or;
2836 foreach (@$stock_relationships) {
2837 my $stock_relationship_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema(), $_, 'stock_relationship')->cvterm_id();
2838 push @stock_rel_or, "stock_relationship.type_id=$stock_relationship_cvterm_id";
2840 my $stock_rel_or_sql = join (" OR " , @stock_rel_or);
2841 if ($stock_rel_or_sql) {
2842 $where_clause .= "and ($stock_rel_or_sql) ";
2844 my $rel_stock_type_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema(), $relationship_stock_type, 'stock_type')->cvterm_id();
2845 $where_clause .= "and rel_stock.type_id=$rel_stock_type_cvterm_id ";
2847 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
2848 FROM cvterm as a
2849 JOIN dbxref ON (a.dbxref_id = dbxref.dbxref_id)
2850 JOIN db USING(db_id)
2851 JOIN phenotype ON (a.cvterm_id=cvalue_id)
2852 JOIN nd_experiment_phenotype USING(phenotype_id)
2853 JOIN nd_experiment_project USING(nd_experiment_id)
2854 JOIN nd_experiment_stock USING(nd_experiment_id)
2855 JOIN cvterm as b ON (b.cvterm_id=nd_experiment_stock.type_id)
2856 JOIN stock USING(stock_id)
2857 JOIN cvterm as stock_type ON (stock_type.cvterm_id=stock.type_id)
2858 $relationship_join
2859 $where_clause
2860 ORDER BY stock.stock_id;";
2862 print STDERR "QUERY = $q\n";
2863 my $h = $dbh->prepare($q);
2865 my $numeric_regex = '^-?[0-9]+([,.][0-9]+)?$';
2866 $h->execute($self->get_trial_id(), $phenotyping_experiment_cvterm, $numeric_regex );
2867 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()) {
2868 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];
2870 return \@data;
2873 =head2 function get_traits_assayed()
2875 Usage:
2876 Desc: returns the cvterm_id and name for traits assayed
2877 Ret:
2878 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.
2879 Side Effects:
2880 Example:
2882 =cut
2884 sub get_traits_assayed {
2885 my $self = shift;
2886 my $stock_type = shift;
2887 my $trait_format = shift;
2888 my $contains_composable_cv_type = shift;
2889 my $schema = $self->bcs_schema;
2890 my $dbh = $self->bcs_schema->storage()->dbh();
2892 my @traits_assayed;
2894 my $cvtermprop_join = '';
2895 my $cvtermprop_where = '';
2896 if ($trait_format){
2897 my $trait_format_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema(), 'trait_format', 'trait_property')->cvterm_id();
2898 $cvtermprop_join = ' JOIN cvtermprop ON (cvtermprop.cvterm_id = cvterm.cvterm_id) ';
2899 $cvtermprop_where = " AND cvtermprop.type_id = $trait_format_cvterm_id AND cvtermprop.value = '$trait_format' ";
2902 my $contains_relationship_rs = $schema->resultset("Cv::Cvterm")->search({ name => 'contains' });
2903 if ($contains_relationship_rs->count == 0) {
2904 die "The cvterm 'contains' was not found! Please add this cvterm! Generally this term is added when loading an ontology into the database.\n";
2906 elsif ($contains_relationship_rs->count > 1) {
2907 die "The cvterm 'contains' was found more than once! Please consolidate this cvterm by updating cvterm_relationship entries and then deleting the left over cvterm entry! Generally this term is added when loading an ontology into the database.\n";
2909 my $contains_relationship_cvterm_id = $contains_relationship_rs->first->cvterm_id;
2910 my $variable_relationship_rs = $schema->resultset("Cv::Cvterm")->search({ name => 'VARIABLE_OF' });
2911 if ($variable_relationship_rs->count == 0) {
2912 die "The cvterm 'VARIABLE_OF' was not found! Please add this cvterm! Generally this term is added when loading an ontology into the database.\n";
2914 elsif ($variable_relationship_rs->count > 1) {
2915 die "The cvterm 'VARIABLE_OF' was found more than once! Please consolidate this cvterm by updating cvterm_relationship entries and then deleting the left over cvterm entry! Generally this term is added when loading an ontology into the database.\n";
2918 my $composable_cv_type_cvterm_id = $contains_composable_cv_type ? SGN::Model::Cvterm->get_cvterm_row($schema, $contains_composable_cv_type, 'composable_cvtypes')->cvterm_id : '';
2920 my $q;
2921 if ($stock_type) {
2922 my $stock_type_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema(), $stock_type, 'stock_type')->cvterm_id();
2923 $q = "SELECT (((cvterm.name::text || '|'::text) || db.name::text) || ':'::text) || dbxref.accession::text AS trait, cvterm.cvterm_id, imaging_project.project_id, imaging_project.name, count(phenotype.value)
2924 FROM cvterm
2925 $cvtermprop_join
2926 JOIN dbxref ON (cvterm.dbxref_id = dbxref.dbxref_id)
2927 JOIN db ON (dbxref.db_id = db.db_id)
2928 JOIN phenotype ON (cvterm.cvterm_id=phenotype.cvalue_id)
2929 JOIN nd_experiment_phenotype USING(phenotype_id)
2930 JOIN nd_experiment_project USING(nd_experiment_id)
2931 JOIN nd_experiment_stock USING(nd_experiment_id)
2932 LEFT JOIN phenome.nd_experiment_md_images AS nd_experiment_md_images USING(nd_experiment_id)
2933 LEFT JOIN phenome.project_md_image AS project_md_image ON (nd_experiment_md_images.image_id=project_md_image.image_id)
2934 LEFT JOIN project AS imaging_project ON (project_md_image.project_id=imaging_project.project_id)
2935 JOIN stock on (stock.stock_id = nd_experiment_stock.stock_id)
2936 WHERE stock.type_id=$stock_type_cvterm_id and nd_experiment_project.project_id=? $cvtermprop_where
2937 GROUP BY trait, cvterm.cvterm_id, imaging_project.project_id, imaging_project.name
2938 ORDER BY trait;";
2939 } else {
2940 $q = "SELECT (((cvterm.name::text || '|'::text) || db.name::text) || ':'::text) || dbxref.accession::text AS trait, cvterm.cvterm_id, imaging_project.project_id, imaging_project.name, count(phenotype.value)
2941 FROM cvterm
2942 $cvtermprop_join
2943 JOIN dbxref ON (cvterm.dbxref_id = dbxref.dbxref_id)
2944 JOIN db ON (dbxref.db_id = db.db_id)
2945 JOIN phenotype ON (cvterm.cvterm_id=phenotype.cvalue_id)
2946 JOIN nd_experiment_phenotype USING(phenotype_id)
2947 JOIN nd_experiment_project USING(nd_experiment_id)
2948 LEFT JOIN phenome.nd_experiment_md_images AS nd_experiment_md_images USING(nd_experiment_id)
2949 LEFT JOIN phenome.project_md_image AS project_md_image ON (nd_experiment_md_images.image_id=project_md_image.image_id)
2950 LEFT JOIN project AS imaging_project ON (project_md_image.project_id=imaging_project.project_id)
2951 WHERE nd_experiment_project.project_id=? $cvtermprop_where
2952 GROUP BY trait, cvterm.cvterm_id, imaging_project.project_id, imaging_project.name
2953 ORDER BY trait;";
2956 my $component_q = "SELECT COALESCE(
2957 json_agg(json_build_object('cvterm_id', component_cvterm.cvterm_id, 'name', component_cvterm.name, 'definition', component_cvterm.definition, 'cv_name', cv.name, 'cv_type', cv_type.name, 'cv_type_cvterm_id', cv_type.cvterm_id))
2958 FILTER (WHERE component_cvterm.cvterm_id IS NOT NULL), '[]'
2959 ) AS components
2960 FROM cvterm
2961 LEFT JOIN cvterm_relationship on (cvterm.cvterm_id = cvterm_relationship.object_id AND cvterm_relationship.type_id = $contains_relationship_cvterm_id)
2962 LEFT JOIN cvterm AS component_cvterm on (cvterm_relationship.subject_id = component_cvterm.cvterm_id)
2963 LEFT JOIN cv on (component_cvterm.cv_id = cv.cv_id)
2964 LEFT JOIN cvprop on (cv.cv_id = cvprop.cv_id)
2965 LEFT JOIN cvterm AS cv_type on (cv_type.cvterm_id = cvprop.type_id)
2966 WHERE cvterm.cvterm_id=? ;";
2968 print STDERR Dumper $q;
2970 my $traits_assayed_h = $dbh->prepare($q);
2971 my $component_h = $dbh->prepare($component_q);
2973 $traits_assayed_h->execute($self->get_trial_id());
2974 while (my ($trait_name, $trait_id, $imaging_project_id, $imaging_project_name, $count) = $traits_assayed_h->fetchrow_array()) {
2975 $component_h->execute($trait_id);
2976 my ($component_terms) = $component_h->fetchrow_array();
2977 $component_terms = decode_json $component_terms;
2978 if ($contains_composable_cv_type) {
2979 my $has_composable_cv_type = 0;
2980 foreach (@$component_terms) {
2981 if ($_->{cv_type_cvterm_id} && $_->{cv_type_cvterm_id} == $composable_cv_type_cvterm_id) {
2982 $has_composable_cv_type = 1;
2985 if ($has_composable_cv_type == 1) {
2986 push @traits_assayed, [$trait_id, $trait_name, $component_terms, $count, $imaging_project_id, $imaging_project_name];
2989 else {
2990 push @traits_assayed, [$trait_id, $trait_name, $component_terms, $count, $imaging_project_id, $imaging_project_name];
2993 return \@traits_assayed;
2996 =head2 function get_trait_components_assayed()
2998 Usage:
2999 Desc: returns the cvterm_id and name for trait components assayed
3000 Ret:
3001 Args:
3002 Side Effects:
3003 Example:
3005 =cut
3007 sub get_trait_components_assayed {
3008 my $self = shift;
3009 my $stock_type = shift;
3010 my $composable_cvterm_format = shift;
3011 my $dbh = $self->bcs_schema->storage()->dbh();
3012 my $traits_assayed = $self->get_traits_assayed($stock_type);
3014 my %unique_components;
3015 my @trait_components_assayed;
3016 foreach (@$traits_assayed){
3017 my $trait_components = SGN::Model::Cvterm->get_components_from_trait($self->bcs_schema, $_->[0]);
3018 foreach (@$trait_components){
3019 if (!exists($unique_components{$_})){
3020 my $component_cvterm = SGN::Model::Cvterm::get_trait_from_cvterm_id($self->bcs_schema, $_, $composable_cvterm_format);
3021 push @trait_components_assayed, [$_, $component_cvterm];
3022 $unique_components{$_}++;
3026 return \@trait_components_assayed;
3029 =head2 function get_experiment_count()
3031 Usage:
3032 Desc: return the total number of experiments associated
3033 with the trial.
3034 Ret:
3035 Args:
3036 Side Effects:
3037 Example:
3039 =cut
3041 sub get_experiment_count {
3042 my $self = shift;
3044 my $rs = $self->bcs_schema->resultset('NaturalDiversity::NdExperimentProject')->search( { project_id => $self->get_trial_id() });
3045 return $rs->count();
3048 sub get_location_type_id {
3049 my $self = shift;
3050 my $rs = $self->bcs_schema->resultset('Cv::Cvterm')->search( { name => 'project location' });
3052 if ($rs->count() > 0) {
3053 return $rs->first()->cvterm_id();
3058 sub get_year_type_id {
3059 my $self = shift;
3061 my $rs = $self->bcs_schema->resultset('Cv::Cvterm')->search( { name => 'project year' });
3063 return $rs->first()->cvterm_id();
3066 sub get_breeding_program_trial_relationship_cvterm_id {
3067 my $self = shift;
3069 my $breeding_program_trial_relationship_cvterm_id;
3070 my $breeding_program_trial_relationship_cvterm = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'breeding_program_trial_relationship', 'project_relationship');
3071 if ($breeding_program_trial_relationship_cvterm) {
3072 $breeding_program_trial_relationship_cvterm_id = $breeding_program_trial_relationship_cvterm->cvterm_id();
3075 return $breeding_program_trial_relationship_cvterm_id;
3078 sub get_breeding_program_cvterm_id {
3079 my $self = shift;
3081 my $breeding_program_cvterm_id;
3082 my $breeding_program_cvterm = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'breeding_program', 'project_property');
3083 if ($breeding_program_cvterm) {
3084 $breeding_program_cvterm_id = $breeding_program_cvterm->cvterm_id();
3087 return $breeding_program_cvterm_id;
3090 sub get_folder {
3091 my $self = shift;
3093 my $f = CXGN::Trial::Folder->new( { bcs_schema => $self->bcs_schema(), folder_id => $self->get_trial_id() });
3095 my $parent_folder_data = $f->project_parent();
3097 if ($parent_folder_data) {
3098 return $parent_folder_data;
3100 else {
3101 return;
3105 sub get_harvest_date_cvterm_id {
3106 my $self = shift;
3108 my $harvest_date_cvterm_id;
3109 my $harvest_date_cvterm = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'project_harvest_date', 'project_property');
3110 if ($harvest_date_cvterm) {
3111 $harvest_date_cvterm_id = $harvest_date_cvterm->cvterm_id();
3114 return $harvest_date_cvterm_id;
3118 sub get_project_start_date_cvterm_id {
3119 my $self = shift;
3121 my $start_date_cvterm_id;
3122 my $start_date_cvterm = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'project_start_date', 'project_property');
3123 if ($start_date_cvterm) {
3124 $start_date_cvterm_id = $start_date_cvterm->cvterm_id();
3127 return $start_date_cvterm_id;
3130 =head2 function create_plant_entities()
3132 Usage: $trial->create_plant_entities($plants_per_plot);
3133 Desc: Some trials require plant-level data. This function will
3134 add an additional layer of plant entities for each plot.
3135 Ret:
3136 Args: the number of plants per plot to add.
3137 Side Effects:
3138 Example:
3140 =cut
3142 sub create_plant_entities {
3143 my $self = shift;
3144 my $plants_per_plot = shift || 30;
3145 my $inherits_plot_treatments = shift;
3146 my $plant_owner = shift;
3147 my $plant_owner_username = shift;
3149 my $create_plant_entities_txn = sub {
3150 my $chado_schema = $self->bcs_schema();
3151 my $layout = CXGN::Trial::TrialLayout->new( { schema => $chado_schema, trial_id => $self->get_trial_id(), experiment_type=>'field_layout' });
3152 my $design = $layout->get_design();
3154 my $accession_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'accession', 'stock_type')->cvterm_id();
3155 my $cross_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'cross', 'stock_type')->cvterm_id();
3156 my $family_name_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'family_name', 'stock_type')->cvterm_id();
3157 my $plant_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plant', 'stock_type')->cvterm_id();
3158 my $plot_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plot', 'stock_type')->cvterm_id();
3159 my $plot_relationship_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plot_of', 'stock_relationship')->cvterm_id();
3160 my $plant_relationship_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plant_of', 'stock_relationship')->cvterm_id();
3161 my $plant_index_number_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plant_index_number', 'stock_property')->cvterm_id();
3162 my $block_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'block', 'stock_property')->cvterm_id();
3163 my $plot_number_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plot number', 'stock_property')->cvterm_id();
3164 my $replicate_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'replicate', 'stock_property')->cvterm_id();
3165 my $has_plants_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'project_has_plant_entries', 'project_property')->cvterm_id();
3166 my $field_layout_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'field_layout', 'experiment_type')->cvterm_id();
3167 my $treatment_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'treatment_experiment', 'experiment_type')->cvterm_id();
3168 #my $plants_per_plot_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plants_per_plot', 'project_property')->cvterm_id();
3170 my $treatments;
3171 my %treatment_experiments;
3172 my %treatment_plots;
3173 if ($inherits_plot_treatments){
3174 $treatments = $self->get_treatments();
3175 foreach (@$treatments){
3177 my $rs = $chado_schema->resultset("Project::Projectprop")->find_or_create({
3178 type_id => $has_plants_cvterm,
3179 value => $plants_per_plot,
3180 project_id => $_->[0],
3183 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', { 'nd_experiment.type_id' => $treatment_cvterm })->single();
3184 $treatment_experiments{$_->[0]} = $treatment_nd_experiment->nd_experiment_id();
3186 my $treatment_trial = CXGN::Project->new({ bcs_schema => $chado_schema, trial_id => $_->[0]});
3187 my $plots = $treatment_trial->get_plots();
3188 foreach my $plot (@$plots){
3189 $treatment_plots{$_->[0]}->{$plot->[0]} = 1;
3194 my $rs = $chado_schema->resultset("Project::Projectprop")->find_or_create({
3195 type_id => $has_plants_cvterm,
3196 value => $plants_per_plot,
3197 project_id => $self->get_trial_id(),
3200 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', { 'nd_experiment.type_id' => $field_layout_cvterm })->single();
3202 foreach my $plot (keys %$design) {
3203 #print STDERR " ... creating plants for plot $plot...\n";
3204 my $plot_row = $chado_schema->resultset("Stock::Stock")->find( { uniquename => $design->{$plot}->{plot_name}, type_id=>$plot_cvterm });
3206 if (! $plot_row) {
3207 print STDERR "The plot $plot is not found in the database\n";
3208 return "The plot $plot is not yet in the database. Cannot create plant entries.";
3211 my $parent_plot = $plot_row->stock_id();
3212 my $parent_plot_name = $plot_row->uniquename();
3213 my $parent_plot_organism = $plot_row->organism_id();
3215 foreach my $plant_index_number (1..$plants_per_plot) {
3216 my $plant_name = $parent_plot_name."_plant_$plant_index_number";
3217 #print STDERR "... ... creating plant $plant_name...\n";
3219 $self->_save_plant_entry($chado_schema, $accession_cvterm, $cross_cvterm, $family_name_cvterm, $parent_plot_organism, $parent_plot_name,
3220 $parent_plot, $plant_name, $plant_cvterm, $plant_index_number, $plant_index_number_cvterm, $block_cvterm, $plot_number_cvterm,
3221 $replicate_cvterm, $plant_relationship_cvterm, $field_layout_experiment, $field_layout_cvterm, $inherits_plot_treatments, $treatments,
3222 $plot_relationship_cvterm, \%treatment_plots, \%treatment_experiments, $treatment_cvterm, $plant_owner, $plant_owner_username);
3226 $layout->generate_and_cache_layout();
3229 eval {
3230 $self->bcs_schema()->txn_do($create_plant_entities_txn);
3232 if ($@) {
3233 print STDERR "An error occurred creating the plant entities. $@\n";
3234 return 0;
3237 print STDERR "Plant entities created.\n";
3238 return 1;
3241 =head2 function save_plant_entries()
3243 Usage: $trial->save_plant_entries(\%data, $plants_per_plot, $inherits_plot_treatments);
3244 Desc: Some trials require plant-level data. It is possible to upload
3245 plant_names to save.
3246 Ret:
3247 Args: Requires $plants_per_plot and \%data which is a hashref of the data parsed from the
3248 uploaded file.
3249 example: { 'myplotname1' => { 'plot_stock_id'=>123, 'plant_names'=>['plot1_plant1', 'plot1_plant2'] }, ... }
3250 Side Effects:
3251 Example:
3253 =cut
3255 sub save_plant_entries {
3256 my $self = shift;
3257 my $parsed_data = shift;
3258 my $plants_per_plot = shift;
3259 my $inherits_plot_treatments = shift;
3261 my $create_plant_entities_txn = sub {
3262 my $chado_schema = $self->bcs_schema();
3263 my $layout = CXGN::Trial::TrialLayout->new( { schema => $chado_schema, trial_id => $self->get_trial_id(), experiment_type=>'field_layout' });
3264 my $design = $layout->get_design();
3266 my $accession_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'accession', 'stock_type')->cvterm_id();
3267 my $cross_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'cross', 'stock_type')->cvterm_id();
3268 my $family_name_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'family_name', 'stock_type')->cvterm_id();
3269 my $plant_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plant', 'stock_type')->cvterm_id();
3270 my $plot_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plot', 'stock_type')->cvterm_id();
3271 my $plot_relationship_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plot_of', 'stock_relationship')->cvterm_id();
3272 my $plant_relationship_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plant_of', 'stock_relationship')->cvterm_id();
3273 my $plant_index_number_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plant_index_number', 'stock_property')->cvterm_id();
3274 my $block_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'block', 'stock_property')->cvterm_id();
3275 my $plot_number_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plot number', 'stock_property')->cvterm_id();
3276 my $replicate_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'replicate', 'stock_property')->cvterm_id();
3277 my $has_plants_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'project_has_plant_entries', 'project_property')->cvterm_id();
3278 my $field_layout_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'field_layout', 'experiment_type')->cvterm_id();
3279 my $treatment_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'treatment_experiment', 'experiment_type')->cvterm_id();
3280 #my $plants_per_plot_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plants_per_plot', 'project_property')->cvterm_id();
3282 my $treatments;
3283 my %treatment_experiments;
3284 my %treatment_plots;
3285 if ($inherits_plot_treatments){
3286 $treatments = $self->get_treatments();
3287 foreach (@$treatments){
3289 my $rs = $chado_schema->resultset("Project::Projectprop")->find_or_create({
3290 type_id => $has_plants_cvterm,
3291 value => $plants_per_plot,
3292 project_id => $_->[0],
3295 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();
3296 $treatment_experiments{$_->[0]} = $treatment_nd_experiment->nd_experiment_id();
3298 my $treatment_trial = CXGN::Trial->new({ bcs_schema => $chado_schema, trial_id => $_->[0]});
3299 my $plots = $treatment_trial->get_plots();
3300 foreach my $plot (@$plots){
3301 $treatment_plots{$_->[0]}->{$plot->[0]} = 1;
3306 my $rs = $chado_schema->resultset("Project::Projectprop")->find_or_create({
3307 type_id => $has_plants_cvterm,
3308 value => $plants_per_plot,
3309 project_id => $self->get_trial_id(),
3313 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', { 'nd_experiment.type_id' => $field_layout_cvterm })->single();
3315 while( my ($key, $val) = each %$parsed_data){
3316 my $plot_stock_id = $key;
3317 my $plot_name = $val->{plot_name};
3318 print STDERR " ... creating plants for plot $plot_name...\n";
3319 my $plot_row = $chado_schema->resultset("Stock::Stock")->find( { stock_id=>$plot_stock_id });
3321 if (!$plot_row) {
3322 print STDERR "The plot $plot_name is not found in the database\n";
3323 return "The plot $plot_name is not yet in the database. Cannot create plant entries.";
3326 my $parent_plot = $plot_row->stock_id();
3327 my $parent_plot_name = $plot_row->uniquename();
3328 my $parent_plot_organism = $plot_row->organism_id();
3330 my $plant_index_number = 1;
3331 my $plant_names = $val->{plant_names};
3332 my $plant_index_numbers = $val->{plant_index_numbers};
3333 my $increment = 0;
3334 foreach my $plant_name (@$plant_names) {
3335 my $given_plant_index_number = $plant_index_numbers->[$increment];
3336 my $plant_index_number_save = $given_plant_index_number ? $given_plant_index_number : $plant_index_number;
3338 $self->_save_plant_entry($chado_schema, $accession_cvterm, $cross_cvterm, $family_name_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);
3339 $plant_index_number++;
3340 $increment++;
3344 $layout->generate_and_cache_layout();
3347 eval {
3348 $self->bcs_schema()->txn_do($create_plant_entities_txn);
3350 if ($@) {
3351 print STDERR "An error occurred creating the plant entities. $@\n";
3352 return 0;
3355 print STDERR "Plant entities created.\n";
3356 return 1;
3359 =head2 function create_plant_subplot_entities()
3361 Usage: $trial->create_plant_subplot_entities($plants_per_subplot);
3362 Desc: Some trials require plant-level data. This function will
3363 add an additional layer of plant entities for each subplot.
3364 Ret:
3365 Args: the number of plants per subplot to add.
3366 Side Effects:
3367 Example:
3369 =cut
3371 sub create_plant_subplot_entities {
3372 my $self = shift;
3373 my $plants_per_subplot = shift || 10;
3374 my $inherits_plot_treatments = shift;
3375 my $plant_owner = shift;
3376 my $plant_owner_username = shift;
3378 my $create_plant_entities_txn = sub {
3379 my $chado_schema = $self->bcs_schema();
3380 my $layout = CXGN::Trial::TrialLayout->new( { schema => $chado_schema, trial_id => $self->get_trial_id(), experiment_type=>'field_layout' });
3381 my $design = $layout->get_design();
3383 my $accession_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'accession', 'stock_type')->cvterm_id();
3384 my $cross_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'cross', 'stock_type')->cvterm_id();
3385 my $family_name_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'family_name', 'stock_type')->cvterm_id();
3386 my $plant_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plant', 'stock_type')->cvterm_id();
3387 my $plot_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plot', 'stock_type')->cvterm_id();
3388 my $subplot_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'subplot', 'stock_type')->cvterm_id();
3389 my $plot_relationship_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plot_of', 'stock_relationship')->cvterm_id();
3390 my $plant_relationship_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plant_of', 'stock_relationship')->cvterm_id();
3391 my $plant_subplot_relationship_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plant_of_subplot', 'stock_relationship')->cvterm_id();
3392 my $plant_index_number_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plant_index_number', 'stock_property')->cvterm_id();
3393 my $block_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'block', 'stock_property')->cvterm_id();
3394 my $plot_number_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plot number', 'stock_property')->cvterm_id();
3395 my $replicate_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'replicate', 'stock_property')->cvterm_id();
3396 my $has_subplots_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'project_has_subplot_entries', 'project_property')->cvterm_id();
3397 my $has_plants_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'project_has_plant_entries', 'project_property')->cvterm_id();
3398 my $field_layout_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'field_layout', 'experiment_type')->cvterm_id();
3399 my $treatment_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'treatment_experiment', 'experiment_type')->cvterm_id();
3400 #my $plants_per_plot_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plants_per_plot', 'project_property')->cvterm_id();
3402 # Calculate the number of plants per plot (subplots_per_plot * plants_per_subplot)
3403 my $subplots_per_plot_row = $chado_schema->resultset("Project::Projectprop")->find({
3404 type_id => $has_subplots_cvterm,
3405 project_id => $self->get_trial_id()
3407 my $subplots_per_plot = $subplots_per_plot_row->value();
3408 my $plants_per_plot = $subplots_per_plot * $plants_per_subplot;
3410 my $treatments;
3411 my %treatment_experiments;
3412 my %treatment_plots;
3413 if ($inherits_plot_treatments){
3414 $treatments = $self->get_treatments();
3415 foreach (@$treatments){
3417 my $rs = $chado_schema->resultset("Project::Projectprop")->find_or_create({
3418 type_id => $has_plants_cvterm,
3419 value => $plants_per_plot,
3420 project_id => $_->[0],
3423 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', { 'nd_experiment.type_id' => $treatment_cvterm })->single();
3424 $treatment_experiments{$_->[0]} = $treatment_nd_experiment->nd_experiment_id();
3426 my $treatment_trial = CXGN::Project->new({ bcs_schema => $chado_schema, trial_id => $_->[0]});
3427 my $plots = $treatment_trial->get_plots();
3428 foreach my $plot (@$plots){
3429 $treatment_plots{$_->[0]}->{$plot->[0]} = 1;
3434 my $rs = $chado_schema->resultset("Project::Projectprop")->find_or_create({
3435 type_id => $has_plants_cvterm,
3436 value => $plants_per_plot,
3437 project_id => $self->get_trial_id(),
3440 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', { 'nd_experiment.type_id' => $field_layout_cvterm })->single();
3442 foreach my $plot (keys %$design) {
3443 print STDERR " ... creating plants for plot $plot...\n";
3445 my $plot_row = $chado_schema->resultset("Stock::Stock")->find( { uniquename => $design->{$plot}->{plot_name}, type_id=>$plot_cvterm });
3446 if (! $plot_row) {
3447 print STDERR "The plot $plot is not found in the database\n";
3448 return "The plot $plot is not yet in the database. Cannot create plant entries.";
3451 my $parent_plot = $plot_row->stock_id();
3452 my $parent_plot_name = $plot_row->uniquename();
3453 my $parent_plot_organism = $plot_row->organism_id();
3455 my $subplots = $design->{$plot}->{subplot_names};
3456 foreach my $subplot (@$subplots) {
3457 print STDERR " ... ... creating plants for subplot $subplot...\n";
3459 my $subplot_row = $chado_schema->resultset("Stock::Stock")->find({ uniquename => $subplot, type_id => $subplot_cvterm });
3460 if ( !$subplot_row ) {
3461 print STDERR "The subplot $subplot is not found in the database\n";
3462 return "The subplot $subplot is not yet in the database. Cannot create plant entries.";
3465 my $parent_subplot = $subplot_row->stock_id();
3467 foreach my $plant_index_number (1..$plants_per_subplot) {
3468 my $plant_name = $subplot."_plant_$plant_index_number";
3469 print STDERR "... ... ... creating plant $plant_name...\n";
3471 $self->_save_plant_entry($chado_schema, $accession_cvterm, $cross_cvterm, $family_name_cvterm, $parent_plot_organism, $parent_plot_name,
3472 $parent_plot, $plant_name, $plant_cvterm, $plant_index_number, $plant_index_number_cvterm, $block_cvterm, $plot_number_cvterm,
3473 $replicate_cvterm, $plant_relationship_cvterm, $field_layout_experiment, $field_layout_cvterm, $inherits_plot_treatments, $treatments,
3474 $plot_relationship_cvterm, \%treatment_plots, \%treatment_experiments, $treatment_cvterm, $plant_owner, $plant_owner_username,
3475 $parent_subplot, $plant_subplot_relationship_cvterm);
3480 $layout->generate_and_cache_layout();
3483 eval {
3484 $self->bcs_schema()->txn_do($create_plant_entities_txn);
3486 if ($@) {
3487 print STDERR "An error occurred creating the plant entities. $@\n";
3488 return 0;
3491 print STDERR "Plant entities created.\n";
3492 return 1;
3496 =head2 function save_plant_subplot_entries()
3498 Usage: $trial->save_plant_subplot_entries(\%data, $plants_per_subplot, $inherits_plot_treatments);
3499 Desc: Some trials require plant-level data. It is possible to upload
3500 plant_names to save.
3501 Ret:
3502 Args: Requires $plants_per_subplot and \%data which is a hashref of the data parsed from the
3503 uploaded file.
3504 example: { 'mysubplotname1' => { 'subplot_stock_id'=>123, 'plant_names'=>['plot1_subplot1_plant1', 'plot1_subplot1_plant2'] }, ... }
3505 Side Effects:
3506 Example:
3508 =cut
3510 sub save_plant_subplot_entries {
3511 my $self = shift;
3512 my $parsed_data = shift;
3513 my $plants_per_subplot = shift;
3514 my $inherits_plot_treatments = shift;
3515 my $plant_owner = shift;
3516 my $plant_owner_username = shift;
3518 my $create_plant_entities_txn = sub {
3519 my $chado_schema = $self->bcs_schema();
3520 my $layout = CXGN::Trial::TrialLayout->new( { schema => $chado_schema, trial_id => $self->get_trial_id(), experiment_type=>'field_layout' });
3521 my $design = $layout->get_design();
3523 my $accession_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'accession', 'stock_type')->cvterm_id();
3524 my $cross_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'cross', 'stock_type')->cvterm_id();
3525 my $family_name_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'family_name', 'stock_type')->cvterm_id();
3526 my $plant_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plant', 'stock_type')->cvterm_id();
3527 my $plot_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plot', 'stock_type')->cvterm_id();
3528 my $subplot_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'subplot', 'stock_type')->cvterm_id();
3529 my $plot_relationship_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plot_of', 'stock_relationship')->cvterm_id();
3530 my $plant_relationship_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plant_of', 'stock_relationship')->cvterm_id();
3531 my $subplot_relationship_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'subplot_of', 'stock_relationship')->cvterm_id();
3532 my $plant_subplot_relationship_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plant_of_subplot', 'stock_relationship')->cvterm_id();
3533 my $plant_index_number_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plant_index_number', 'stock_property')->cvterm_id();
3534 my $block_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'block', 'stock_property')->cvterm_id();
3535 my $plot_number_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plot number', 'stock_property')->cvterm_id();
3536 my $replicate_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'replicate', 'stock_property')->cvterm_id();
3537 my $has_subplots_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'project_has_subplot_entries', 'project_property')->cvterm_id();
3538 my $has_plants_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'project_has_plant_entries', 'project_property')->cvterm_id();
3539 my $field_layout_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'field_layout', 'experiment_type')->cvterm_id();
3540 my $treatment_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'treatment_experiment', 'experiment_type')->cvterm_id();
3542 # Calculate the number of plants per plot (subplots_per_plot * plants_per_subplot)
3543 my $subplots_per_plot_row = $chado_schema->resultset("Project::Projectprop")->find({
3544 type_id => $has_subplots_cvterm,
3545 project_id => $self->get_trial_id()
3547 my $subplots_per_plot = $subplots_per_plot_row->value();
3548 my $plants_per_plot = $subplots_per_plot * $plants_per_subplot;
3550 my $treatments;
3551 my %treatment_experiments;
3552 my %treatment_plots;
3553 if ($inherits_plot_treatments){
3554 $treatments = $self->get_treatments();
3555 foreach (@$treatments){
3557 my $rs = $chado_schema->resultset("Project::Projectprop")->find_or_create({
3558 type_id => $has_plants_cvterm,
3559 value => $plants_per_plot,
3560 project_id => $_->[0],
3563 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', { 'nd_experiment.type_id' => $treatment_cvterm })->single();
3564 $treatment_experiments{$_->[0]} = $treatment_nd_experiment->nd_experiment_id();
3566 my $treatment_trial = CXGN::Trial->new({ bcs_schema => $chado_schema, trial_id => $_->[0]});
3567 my $plots = $treatment_trial->get_plots();
3568 foreach my $plot (@$plots){
3569 $treatment_plots{$_->[0]}->{$plot->[0]} = 1;
3574 my $rs = $chado_schema->resultset("Project::Projectprop")->find_or_create({
3575 type_id => $has_plants_cvterm,
3576 value => $plants_per_plot,
3577 project_id => $self->get_trial_id(),
3581 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', { 'nd_experiment.type_id' => $field_layout_cvterm })->single();
3583 while( my ($key, $val) = each %$parsed_data){
3584 my $subplot_stock_id = $key;
3585 my $subplot_name = $val->{subplot_name};
3586 print STDERR " ... creating plants for subplot $subplot_name...\n";
3588 my $subplot_row = $chado_schema->resultset("Stock::Stock")->find( { stock_id=>$subplot_stock_id });
3589 if (!$subplot_row) {
3590 print STDERR "The subplot $subplot_name is not found in the database\n";
3591 return "The subplot $subplot_name is not yet in the database. Cannot create plant entries.";
3594 my $plot_relationship_row = $chado_schema->resultset("Stock::StockRelationship")->find({
3595 object_id => $subplot_stock_id,
3596 type_id => $subplot_relationship_cvterm
3598 if (!$plot_relationship_row) {
3599 print STDERR "The subplot $subplot_name does not have a defined plot relationship in the database\n";
3600 return "The subplot $subplot_name does not have a defined plot relationship in the database. Cannot create plant entries.";
3602 my $plot_row = $chado_schema->resultset("Stock::Stock")->find({ stock_id => $plot_relationship_row->subject_id() });
3603 if (!$plot_row) {
3604 print STDERR "The parent plot of subplot $subplot_name is not found in the database\n";
3605 return "The parent plot of subplot $subplot_name is not yet in the database. Cannot create plant entries.";
3608 my $parent_plot = $plot_row->stock_id();
3609 my $parent_plot_name = $plot_row->uniquename();
3610 my $parent_plot_organism = $plot_row->organism_id();
3612 my $plant_index_number = 1;
3613 my $plant_names = $val->{plant_names};
3614 my $plant_index_numbers = $val->{plant_index_numbers};
3615 my $increment = 0;
3616 foreach my $plant_name (@$plant_names) {
3617 my $given_plant_index_number = $plant_index_numbers->[$increment];
3618 my $plant_index_number_save = $given_plant_index_number ? $given_plant_index_number : $plant_index_number;
3620 $self->_save_plant_entry($chado_schema, $accession_cvterm, $cross_cvterm, $family_name_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, $plant_owner, $plant_owner_username,
3621 $subplot_stock_id, $plant_subplot_relationship_cvterm);
3622 $plant_index_number++;
3623 $increment++;
3627 $layout->generate_and_cache_layout();
3630 eval {
3631 $self->bcs_schema()->txn_do($create_plant_entities_txn);
3633 if ($@) {
3634 print STDERR "An error occurred creating the plant entities. $@\n";
3635 return 0;
3638 print STDERR "Plant entities created.\n";
3639 return 1;
3642 sub _save_plant_entry {
3643 my $self = shift;
3644 my $chado_schema = shift;
3645 my $accession_cvterm = shift;
3646 my $cross_cvterm = shift;
3647 my $family_name_cvterm = shift;
3648 my $parent_plot_organism = shift;
3649 my $parent_plot_name = shift;
3650 my $parent_plot = shift;
3651 my $plant_name = shift;
3652 my $plant_cvterm = shift;
3653 my $plant_index_number = shift;
3654 my $plant_index_number_cvterm = shift;
3655 my $block_cvterm = shift;
3656 my $plot_number_cvterm = shift;
3657 my $replicate_cvterm = shift;
3658 my $plant_relationship_cvterm = shift;
3659 my $field_layout_experiment = shift;
3660 my $field_layout_cvterm = shift;
3661 my $inherits_plot_treatments = shift;
3662 my $treatments = shift;
3663 my $plot_relationship_cvterm = shift;
3664 my $treatment_plots_ref = shift;
3665 my $treatment_experiments_ref = shift;
3666 my $treatment_cvterm = shift;
3667 my $plant_owner = shift;
3668 my $plant_owner_username = shift;
3669 my $parent_subplot = shift;
3670 my $plant_subplot_relationship_cvterm = shift;
3671 my %treatment_plots = %$treatment_plots_ref;
3672 my %treatment_experiments = %$treatment_experiments_ref;
3674 my $plant = $chado_schema->resultset("Stock::Stock")->create({
3675 organism_id => $parent_plot_organism,
3676 name => $plant_name,
3677 uniquename => $plant_name,
3678 type_id => $plant_cvterm,
3681 if ($plant_owner){
3682 my $stock = CXGN::Stock->new({schema=>$chado_schema,stock_id=>$plant->stock_id()});
3683 $stock->associate_owner($plant_owner,$plant_owner,$plant_owner_username, "");
3686 my $plantprop = $chado_schema->resultset("Stock::Stockprop")->create( {
3687 stock_id => $plant->stock_id(),
3688 type_id => $plant_index_number_cvterm,
3689 value => $plant_index_number,
3692 #The plant inherits the properties of the plot.
3693 my $plot_props = $chado_schema->resultset("Stock::Stockprop")->search({ stock_id => $parent_plot, type_id => [$block_cvterm, $plot_number_cvterm, $replicate_cvterm] });
3694 while (my $prop = $plot_props->next() ) {
3695 #print STDERR $plant->uniquename()." ".$prop->type_id()."\n";
3696 $plantprop = $chado_schema->resultset("Stock::Stockprop")->create( {
3697 stock_id => $plant->stock_id(),
3698 type_id => $prop->type_id(),
3699 value => $prop->value(),
3703 #the plant has a relationship to the plot
3704 my $stock_relationship = $self->bcs_schema()->resultset("Stock::StockRelationship")->create({
3705 subject_id => $parent_plot,
3706 object_id => $plant->stock_id(),
3707 type_id => $plant_relationship_cvterm,
3710 #the plant has a relationship to the subplot
3711 if ( $parent_subplot ) {
3712 $self->bcs_schema()->resultset("Stock::StockRelationship")->create({
3713 subject_id => $plant->stock_id(),
3714 object_id => $parent_subplot,
3715 type_id => $plant_subplot_relationship_cvterm
3719 #the plant has a relationship to the accession
3720 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, $cross_cvterm, $family_name_cvterm] }, {'join'=>'object'});
3721 if ($plot_accession_rs->count != 1){
3722 die "There is not 1 stock_relationship of type plot_of between the plot $parent_plot and an accession, a cross or a family_name.";
3724 $stock_relationship = $self->bcs_schema()->resultset("Stock::StockRelationship")->create({
3725 subject_id => $plant->stock_id(),
3726 object_id => $plot_accession_rs->first->object_id,
3727 type_id => $plant_relationship_cvterm,
3730 #link plant to project through nd_experiment. also add nd_genolocation_id of plot to nd_experiment for the plant
3731 my $plant_nd_experiment_stock = $chado_schema->resultset("NaturalDiversity::NdExperimentStock")->create({
3732 nd_experiment_id => $field_layout_experiment->nd_experiment_id(),
3733 type_id => $field_layout_cvterm,
3734 stock_id => $plant->stock_id(),
3737 if ($inherits_plot_treatments){
3738 if($treatments){
3739 foreach (@$treatments){
3740 my $plots = $treatment_plots{$_->[0]};
3741 if (exists($plots->{$parent_plot})){
3742 my $plant_nd_experiment_stock = $chado_schema->resultset("NaturalDiversity::NdExperimentStock")->create({
3743 nd_experiment_id => $treatment_experiments{$_->[0]},
3744 type_id => $treatment_cvterm,
3745 stock_id => $plant->stock_id(),
3753 =head2 function has_plant_entries()
3755 Usage: $trial->has_plant_entries();
3756 Desc: Some trials require plant-level data. This function will determine if a trial has plants associated with it.
3757 Ret: Returns 1 if trial has plants, 0 if the trial does not.
3758 Args:
3759 Side Effects:
3760 Example:
3762 =cut
3764 sub has_plant_entries {
3765 my $self = shift;
3766 my $chado_schema = $self->bcs_schema();
3767 my $has_plants_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'project_has_plant_entries', 'project_property' );
3769 my $rs = $chado_schema->resultset("Project::Projectprop")->find({
3770 type_id => $has_plants_cvterm->cvterm_id(),
3771 project_id => $self->get_trial_id(),
3774 if ($rs) {
3775 return 1;
3776 } else {
3777 return 0;
3782 =head2 function create_tissue_samples()
3784 Usage: $trial->create_tissue_samples(\@tissue_names, $inherits_plot_treatments);
3785 Desc: Some trials require tissue_sample-level data. This function will
3786 add an additional layer of tissue samples for each plant.
3787 Ret:
3788 Args: an arrayref of tissue names to add to sample name e.g. ['leaf','root']
3789 Side Effects:
3790 Example:
3792 =cut
3794 sub create_tissue_samples {
3795 my $self = shift;
3796 my $tissue_names = shift;
3797 my $inherits_plot_treatments = shift;
3798 my $use_tissue_numbers = shift;
3799 my $tissue_sample_owner = shift;
3800 my $username = shift;
3803 my $create_tissue_sample_entries_txn = sub {
3804 my $chado_schema = $self->bcs_schema();
3805 my $layout = CXGN::Trial::TrialLayout->new( { schema => $chado_schema, trial_id => $self->get_trial_id(), experiment_type=>'field_layout' });
3806 my $design = $layout->get_design();
3808 my $accession_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'accession', 'stock_type')->cvterm_id();
3809 my $cross_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'cross', 'stock_type')->cvterm_id();
3810 my $family_name_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'family_name', 'stock_type')->cvterm_id();
3811 my $plant_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plant', 'stock_type')->cvterm_id();
3812 my $subplot_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'subplot', 'stock_type')->cvterm_id();
3813 my $plot_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plot', 'stock_type')->cvterm_id();
3814 my $tissue_sample_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'tissue_sample', 'stock_type')->cvterm_id();
3815 my $plot_relationship_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plot_of', 'stock_relationship')->cvterm_id();
3816 my $plant_relationship_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plant_of', 'stock_relationship')->cvterm_id();
3817 my $tissue_relationship_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'tissue_sample_of', 'stock_relationship')->cvterm_id();
3818 my $plant_index_number_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plant_index_number', 'stock_property')->cvterm_id();
3819 my $tissue_index_number_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'tissue_sample_index_number', 'stock_property')->cvterm_id();
3820 my $has_tissues_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'project_has_tissue_sample_entries', 'project_property')->cvterm_id();
3821 my $block_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'block', 'stock_property')->cvterm_id();
3822 my $plot_number_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plot number', 'stock_property')->cvterm_id();
3823 my $tissue_type_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'tissue_type', 'stock_property')->cvterm_id();
3824 my $replicate_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'replicate', 'stock_property')->cvterm_id();
3825 my $field_layout_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'field_layout', 'experiment_type')->cvterm_id();
3826 my $treatment_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'treatment_experiment', 'experiment_type')->cvterm_id();
3828 my $rs_previous_tissue = $chado_schema->resultset("Project::Projectprop")->search({
3829 type_id => $has_tissues_cvterm,
3830 project_id => $self->get_trial_id(),
3832 my $previous_tissue_number = 0;
3833 if ($rs_previous_tissue->count > 0) {
3834 $previous_tissue_number = $rs_previous_tissue->first->value;
3836 my $new_tissue_number = $previous_tissue_number + ($use_tissue_numbers ? scalar(@$tissue_names) : 0);
3838 my $treatments;
3839 my %treatment_experiments;
3840 my %treatment_plots;
3841 my %treatment_subplots;
3842 if ($inherits_plot_treatments){
3843 $treatments = $self->get_treatments();
3844 foreach (@$treatments){
3846 my $rs = $chado_schema->resultset('Project::Projectprop')->update_or_create({
3847 type_id => $has_tissues_cvterm,
3848 project_id => $_->[0],
3849 rank => 0,
3850 value => $new_tissue_number
3853 key=>'projectprop_c1'
3856 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', { 'nd_experiment.type_id' => $treatment_cvterm })->single();
3857 $treatment_experiments{$_->[0]} = $treatment_nd_experiment->nd_experiment_id();
3859 my $treatment_trial = CXGN::Trial->new({ bcs_schema => $chado_schema, trial_id => $_->[0]});
3860 my $plots = $treatment_trial->get_plots();
3861 foreach my $plot (@$plots){
3862 $treatment_plots{$_->[0]}->{$plot->[0]} = 1;
3864 my $subplots = $treatment_trial->get_subplots();
3865 foreach my $subplot (@$subplots){
3866 $treatment_subplots{$_->[0]}->{$subplot->[0]} = 1;
3871 my $rs = $chado_schema->resultset('Project::Projectprop')->update_or_create({
3872 type_id => $has_tissues_cvterm,
3873 project_id => $self->get_trial_id(),
3874 rank => 0,
3875 value => $new_tissue_number
3878 key=>'projectprop_c1'
3881 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', { 'nd_experiment.type_id' => $field_layout_cvterm })->single();
3883 foreach my $plot (keys %$design) {
3884 my $plant_names = $design->{$plot}->{plant_names};
3885 my $subplot_names = $design->{$plot}->{subplot_names};
3886 my $subplots_plant_names = $design->{$plot}->{subplots_plant_names};
3887 my %plant_tissue_hash;
3888 foreach my $plant_name (@$plant_names){
3889 my $parent_plot_id = $design->{$plot}->{plot_id};
3890 my $parent_plot_name = $design->{$plot}->{plot_name};
3891 my $plant_row = $chado_schema->resultset("Stock::Stock")->find( { uniquename => $plant_name, type_id=>$plant_cvterm });
3893 if (! $plant_row) {
3894 print STDERR "The plant $plant_name is not found in the database\n";
3895 return "The plant $plant_name is not yet in the database. Cannot create tissue entries.";
3898 my $parent_plant = $plant_row->stock_id();
3899 my $parent_plant_name = $plant_row->uniquename();
3900 my $parent_plant_organism = $plant_row->organism_id();
3902 my $tissue_index_number = $previous_tissue_number + 1;
3903 foreach my $tissue_name (@$tissue_names){
3904 my $tissue_sample_name;
3905 if ($use_tissue_numbers) {
3906 $tissue_sample_name = $parent_plant_name."_".$tissue_name.$tissue_index_number;
3907 } else {
3908 $tissue_sample_name = $parent_plant_name."_".$tissue_name;
3910 print STDERR "... ... creating tissue $tissue_sample_name...\n";
3912 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, $cross_cvterm, $family_name_cvterm]}, {'join'=>'object'});
3913 if ($plant_accession_rs->count != 1){
3914 die "There is not 1 stock_relationship of type plant_of between the plant $parent_plant and an accession, a cross or a family_name.";
3917 my @tissue_stock_props;
3918 my @tissue_subjects;
3919 my @tissue_objects;
3920 my @tissue_nd_experiment_stocks;
3921 push @tissue_stock_props, { type_id => $tissue_type_cvterm, value => $tissue_name };
3922 push @tissue_stock_props, { type_id => $tissue_index_number_cvterm, value => $tissue_index_number };
3923 push @tissue_subjects, { type_id => $tissue_relationship_cvterm, object_id => $parent_plant };
3924 push @tissue_subjects, { type_id => $tissue_relationship_cvterm, object_id => $parent_plot_id };
3925 push @tissue_subjects, { type_id => $tissue_relationship_cvterm, object_id => $plant_accession_rs->first->object_id };
3926 push @tissue_nd_experiment_stocks, { nd_experiment_id => $field_layout_experiment->nd_experiment_id(), type_id => $field_layout_cvterm };
3928 if ($inherits_plot_treatments){
3929 if($treatments){
3930 foreach (@$treatments){
3931 my $plots = $treatment_plots{$_->[0]};
3932 if (exists($plots->{$parent_plot_id})){
3933 push @tissue_nd_experiment_stocks, { nd_experiment_id => $treatment_experiments{$_->[0]}, type_id => $treatment_cvterm };
3939 my $tissue = $chado_schema->resultset("Stock::Stock")->create({
3940 organism_id => $parent_plant_organism,
3941 name => $tissue_sample_name,
3942 uniquename => $tissue_sample_name,
3943 type_id => $tissue_sample_cvterm,
3944 stockprops => \@tissue_stock_props,
3945 stock_relationship_subjects => \@tissue_subjects,
3946 stock_relationship_objects => \@tissue_objects,
3947 nd_experiment_stocks => \@tissue_nd_experiment_stocks,
3950 if ($tissue_sample_owner) {
3951 my $stock = CXGN::Stock->new({schema=>$chado_schema,stock_id=>$tissue->stock_id()});
3952 $stock->associate_owner($tissue_sample_owner,$tissue_sample_owner,$username, "");
3955 $tissue_index_number++;
3957 push @{$plant_tissue_hash{$plant_name}}, $tissue->stock_id;
3962 foreach my $subplot_name (%$subplots_plant_names){
3963 my $subplot_row = $chado_schema->resultset("Stock::Stock")->find({ uniquename => $subplot_name, type_id=>$subplot_cvterm });
3964 foreach my $plant (@{$subplots_plant_names->{$subplot_name}}){
3965 foreach my $t (@{$plant_tissue_hash{$plant}}){
3966 #the tissue has a relationship to the subplot
3967 my $stock_relationship = $self->bcs_schema()->resultset("Stock::StockRelationship")->create({
3968 object_id => $subplot_row->stock_id(),
3969 subject_id => $t,
3970 type_id => $tissue_relationship_cvterm,
3973 if ($inherits_plot_treatments){
3974 if($treatments){
3975 foreach (@$treatments){
3976 my $subplots = $treatment_subplots{$_->[0]};
3977 if (exists($subplots->{$subplot_row->stock_id})){
3978 my $plant_nd_experiment_stock = $chado_schema->resultset("NaturalDiversity::NdExperimentStock")->create({
3979 nd_experiment_id => $treatment_experiments{$_->[0]},
3980 type_id => $treatment_cvterm,
3981 stock_id => $t,
3992 foreach (@$treatments) {
3993 my $layout = CXGN::Trial::TrialLayout->new( { schema => $chado_schema, trial_id => $_->[0], experiment_type=>'field_layout' });
3994 $layout->generate_and_cache_layout();
3996 $layout->generate_and_cache_layout();
3999 eval {
4000 $self->bcs_schema()->txn_do($create_tissue_sample_entries_txn);
4002 if ($@) {
4003 print STDERR "An error occurred creating the tissue sample entities. $@\n";
4004 return 0;
4007 print STDERR "Tissue sample entities created.\n";
4008 return 1;
4011 =head2 function has_col_and_row_numbers()
4013 Usage: $trial->has_col_and_row_numbers();
4014 Desc: Some trials require tissue_samples from plants. This function will determine if a trial has row and column numbers for fieldMap spreadsheet download.
4015 Ret: Returns 1 if trial has row and column numbers, 0 if the trial does not.
4016 Args:
4017 Side Effects:
4018 Example:
4020 =cut
4022 sub has_col_and_row_numbers {
4023 my $self = shift;
4024 my $chado_schema = $self->bcs_schema();
4025 my $design;
4026 try {
4027 my $layout = CXGN::Trial::TrialLayout->new( { schema => $chado_schema, trial_id => $self->get_trial_id(), experiment_type=>'field_layout' });
4028 $design = $layout->get_design();
4031 my (@row_numbers, @col_numbers);
4032 foreach my $plot (keys %$design) {
4033 my $row_number = $design->{$plot}->{row_number};
4034 my $col_number = $design->{$plot}->{col_number};
4035 if ($row_number){
4036 push @row_numbers, $row_number;
4038 if ($col_number){
4039 push @col_numbers, $col_number;
4043 if (scalar(@row_numbers) ne '0' && scalar(@col_numbers) ne '0'){
4044 return 1;
4045 } else {
4046 return 0;
4051 =head2 function has_tissue_sample_entries()
4053 Usage: $trial->has_tissue_sample_entries();
4054 Desc: Some trials require tissue_samples from plants. This function will determine if a trial has tissue_samples associated with it.
4055 Ret: Returns 1 if trial has tissue_samples, 0 if the trial does not.
4056 Args:
4057 Side Effects:
4058 Example:
4060 =cut
4062 sub has_tissue_sample_entries {
4063 my $self = shift;
4064 my $chado_schema = $self->bcs_schema();
4065 my $has_tissues_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'project_has_tissue_sample_entries', 'project_property' );
4067 my $rs = $chado_schema->resultset("Project::Projectprop")->find({
4068 type_id => $has_tissues_cvterm->cvterm_id(),
4069 project_id => $self->get_trial_id(),
4072 if ($rs) {
4073 return 1;
4074 } else {
4075 return 0;
4081 =head2 function create_subplot_entities()
4083 Usage: $trial->create_subplot_entities($subplots_per_plot, $inherits_plot_treatments, $subplot_owner, $subplot_owner_username);
4084 Desc: Some trials require subplot-level data. This function will
4085 add an additional layer of subplot entities for each plot.
4086 Ret:
4087 Args: the number of subplots per plot to add.
4088 flag to inherit plot treatments for the subplots
4089 the user id of the subplot owner
4090 the username of the subplot owner
4091 Side Effects:
4092 Example:
4094 =cut
4096 sub create_subplot_entities {
4097 my $self = shift;
4098 my $subplots_per_plot = shift;
4099 my $inherits_plot_treatments = shift;
4100 my $subplot_owner = shift;
4101 my $subplot_owner_username = shift;
4103 my $create_subplot_entities_txn = sub {
4104 my $chado_schema = $self->bcs_schema();
4105 my $layout = CXGN::Trial::TrialLayout->new( { schema => $chado_schema, trial_id => $self->get_trial_id(), experiment_type=>'field_layout' });
4106 my $design = $layout->get_design();
4108 my $accession_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'accession', 'stock_type')->cvterm_id();
4109 my $cross_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'cross', 'stock_type')->cvterm_id();
4110 my $family_name_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'family_name', 'stock_type')->cvterm_id();
4111 my $subplot_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'subplot', 'stock_type')->cvterm_id();
4112 my $plot_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plot', 'stock_type')->cvterm_id();
4113 my $plot_relationship_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plot_of', 'stock_relationship')->cvterm_id();
4114 my $subplot_relationship_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'subplot_of', 'stock_relationship')->cvterm_id();
4115 my $subplot_index_number_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'subplot_index_number', 'stock_property')->cvterm_id();
4116 my $block_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'block', 'stock_property')->cvterm_id();
4117 my $plot_number_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plot number', 'stock_property')->cvterm_id();
4118 my $replicate_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'replicate', 'stock_property')->cvterm_id();
4119 my $has_subplots_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'project_has_subplot_entries', 'project_property')->cvterm_id();
4120 my $field_layout_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'field_layout', 'experiment_type')->cvterm_id();
4121 my $treatment_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'treatment_experiment', 'experiment_type')->cvterm_id();
4122 #my $subplots_per_plot_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'subplots_per_plot', 'project_property')->cvterm_id();
4124 my $treatments;
4125 my %treatment_experiments;
4126 my %treatment_plots;
4127 if ($inherits_plot_treatments){
4128 $treatments = $self->get_treatments();
4129 foreach (@$treatments){
4131 my $rs = $chado_schema->resultset("Project::Projectprop")->find_or_create({
4132 type_id => $has_subplots_cvterm,
4133 value => $subplots_per_plot,
4134 project_id => $_->[0],
4137 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', { 'nd_experiment.type_id' => $treatment_cvterm })->single();
4138 $treatment_experiments{$_->[0]} = $treatment_nd_experiment->nd_experiment_id();
4140 my $treatment_trial = CXGN::Project->new({ bcs_schema => $chado_schema, trial_id => $_->[0]});
4141 my $plots = $treatment_trial->get_plots();
4142 foreach my $plot (@$plots){
4143 $treatment_plots{$_->[0]}->{$plot->[0]} = 1;
4148 my $rs = $chado_schema->resultset("Project::Projectprop")->find_or_create({
4149 type_id => $has_subplots_cvterm,
4150 value => $subplots_per_plot,
4151 project_id => $self->get_trial_id(),
4154 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', { 'nd_experiment.type_id' => $field_layout_cvterm })->single();
4156 foreach my $plot (keys %$design) {
4157 print STDERR " ... creating subplots for plot $plot...\n";
4158 my $plot_row = $chado_schema->resultset("Stock::Stock")->find( { uniquename => $design->{$plot}->{plot_name}, type_id=>$plot_cvterm });
4160 if (! $plot_row) {
4161 print STDERR "The plot $plot is not found in the database\n";
4162 return "The plot $plot is not yet in the database. Cannot create subplot entries.";
4165 my $parent_plot = $plot_row->stock_id();
4166 my $parent_plot_name = $plot_row->uniquename();
4167 my $parent_plot_organism = $plot_row->organism_id();
4169 foreach my $subplot_index_number (1..$subplots_per_plot) {
4170 my $subplot_name = $parent_plot_name."_subplot_$subplot_index_number";
4171 #print STDERR "... ... creating subplot $subplot_name...\n";
4173 $self->_save_subplot_entry($chado_schema, $accession_cvterm, $cross_cvterm, $family_name_cvterm, $parent_plot_organism, $parent_plot_name,
4174 $parent_plot, $subplot_name, $subplot_cvterm, $subplot_index_number, $subplot_index_number_cvterm, $block_cvterm, $plot_number_cvterm,
4175 $replicate_cvterm, $subplot_relationship_cvterm, $field_layout_experiment, $field_layout_cvterm, $inherits_plot_treatments, $treatments,
4176 $plot_relationship_cvterm, \%treatment_plots, \%treatment_experiments, $treatment_cvterm, $subplot_owner, $subplot_owner_username);
4180 $layout->generate_and_cache_layout();
4183 eval {
4184 $self->bcs_schema()->txn_do($create_subplot_entities_txn);
4186 if ($@) {
4187 print STDERR "An error occurred creating the subplot entities. $@\n";
4188 return 0;
4191 print STDERR "Subplot entities created.\n";
4192 return 1;
4196 =head2 function save_subplot_entries()
4198 Usage: $trial->save_subplot_entries(\%data, $subplots_per_plot, $inherits_plot_treatments);
4199 Desc: Some trials require subplot-level data. It is possible to upload
4200 subplot_names to save.
4201 Ret:
4202 Args: Requires $subplots_per_plot and \%data which is a hashref of the data parsed from the
4203 uploaded file.
4204 example: { 'myplotname1' => { 'plot_stock_id'=>123, 'subplot_names'=>['plot1_subplot1', 'plot1_subplot2'] }, ... }
4205 Side Effects:
4206 Example:
4208 =cut
4210 sub save_subplot_entries {
4211 my $self = shift;
4212 my $parsed_data = shift;
4213 my $subplots_per_plot = shift;
4214 my $inherits_plot_treatments = shift;
4216 my $create_subplot_entities_txn = sub {
4217 my $chado_schema = $self->bcs_schema();
4218 my $layout = CXGN::Trial::TrialLayout->new( { schema => $chado_schema, trial_id => $self->get_trial_id(), experiment_type=>'field_layout' });
4219 my $design = $layout->get_design();
4221 my $accession_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'accession', 'stock_type')->cvterm_id();
4222 my $cross_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'cross', 'stock_type')->cvterm_id();
4223 my $family_name_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'family_name', 'stock_type')->cvterm_id();
4224 my $subplot_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'subplot', 'stock_type')->cvterm_id();
4225 my $plot_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plot', 'stock_type')->cvterm_id();
4226 my $plot_relationship_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plot_of', 'stock_relationship')->cvterm_id();
4227 my $subplot_relationship_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'subplot_of', 'stock_relationship')->cvterm_id();
4228 my $subplot_index_number_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'subplot_index_number', 'stock_property')->cvterm_id();
4229 my $block_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'block', 'stock_property')->cvterm_id();
4230 my $plot_number_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plot number', 'stock_property')->cvterm_id();
4231 my $replicate_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'replicate', 'stock_property')->cvterm_id();
4232 my $has_subplots_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'project_has_subplot_entries', 'project_property')->cvterm_id();
4233 my $field_layout_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'field_layout', 'experiment_type')->cvterm_id();
4234 my $treatment_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'treatment_experiment', 'experiment_type')->cvterm_id();
4235 #my $subplots_per_plot_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'subplots_per_plot', 'project_property')->cvterm_id();
4237 my $treatments;
4238 my %treatment_experiments;
4239 my %treatment_plots;
4240 if ($inherits_plot_treatments){
4241 $treatments = $self->get_treatments();
4242 foreach (@$treatments){
4244 my $rs = $chado_schema->resultset("Project::Projectprop")->find_or_create({
4245 type_id => $has_subplots_cvterm,
4246 value => $subplots_per_plot,
4247 project_id => $_->[0],
4250 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', { 'nd_experiment.type_id' => $treatment_cvterm })->single();
4251 $treatment_experiments{$_->[0]} = $treatment_nd_experiment->nd_experiment_id();
4253 my $treatment_trial = CXGN::Trial->new({ bcs_schema => $chado_schema, trial_id => $_->[0]});
4254 my $plots = $treatment_trial->get_plots();
4255 foreach my $plot (@$plots){
4256 $treatment_plots{$_->[0]}->{$plot->[0]} = 1;
4261 my $rs = $chado_schema->resultset("Project::Projectprop")->find_or_create({
4262 type_id => $has_subplots_cvterm,
4263 value => $subplots_per_plot,
4264 project_id => $self->get_trial_id(),
4268 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', { 'nd_experiment.type_id' => $field_layout_cvterm })->single();
4270 while( my ($key, $val) = each %$parsed_data){
4271 my $plot_stock_id = $key;
4272 my $plot_name = $val->{plot_name};
4273 print STDERR " ... creating subplots for plot $plot_name...\n";
4274 my $plot_row = $chado_schema->resultset("Stock::Stock")->find( { stock_id=>$plot_stock_id });
4276 if (!$plot_row) {
4277 print STDERR "The plot $plot_name is not found in the database\n";
4278 return "The plot $plot_name is not yet in the database. Cannot create subplot entries.";
4281 my $parent_plot = $plot_row->stock_id();
4282 my $parent_plot_name = $plot_row->uniquename();
4283 my $parent_plot_organism = $plot_row->organism_id();
4285 my $subplot_index_number = 1;
4286 my $subplot_names = $val->{subplot_names};
4287 my $subplot_index_numbers = $val->{subplot_index_numbers};
4288 my $increment = 0;
4289 foreach my $subplot_name (@$subplot_names) {
4290 my $given_subplot_index_number = $subplot_index_numbers->[$increment];
4291 my $subplot_index_number_save = $given_subplot_index_number ? $given_subplot_index_number : $subplot_index_number;
4293 $self->_save_subplot_entry($chado_schema, $accession_cvterm, $cross_cvterm, $family_name_cvterm, $parent_plot_organism, $parent_plot_name, $parent_plot, $subplot_name, $subplot_cvterm, $subplot_index_number_save, $subplot_index_number_cvterm, $block_cvterm, $plot_number_cvterm, $replicate_cvterm, $subplot_relationship_cvterm, $field_layout_experiment, $field_layout_cvterm, $inherits_plot_treatments, $treatments, $plot_relationship_cvterm, \%treatment_plots, \%treatment_experiments, $treatment_cvterm);
4294 $subplot_index_number++;
4295 $increment++;
4299 $layout->generate_and_cache_layout();
4302 eval {
4303 $self->bcs_schema()->txn_do($create_subplot_entities_txn);
4305 if ($@) {
4306 print STDERR "An error occurred creating the subplot entities. $@\n";
4307 return 0;
4310 print STDERR "Subplot entities created.\n";
4311 return 1;
4314 sub _save_subplot_entry {
4315 my $self = shift;
4316 my $chado_schema = shift;
4317 my $accession_cvterm = shift;
4318 my $cross_cvterm = shift;
4319 my $family_name_cvterm = shift;
4320 my $parent_plot_organism = shift;
4321 my $parent_plot_name = shift;
4322 my $parent_plot = shift;
4323 my $subplot_name = shift;
4324 my $subplot_cvterm = shift;
4325 my $subplot_index_number = shift;
4326 my $subplot_index_number_cvterm = shift;
4327 my $block_cvterm = shift;
4328 my $plot_number_cvterm = shift;
4329 my $replicate_cvterm = shift;
4330 my $subplot_relationship_cvterm = shift;
4331 my $field_layout_experiment = shift;
4332 my $field_layout_cvterm = shift;
4333 my $inherits_plot_treatments = shift;
4334 my $treatments = shift;
4335 my $plot_relationship_cvterm = shift;
4336 my $treatment_plots_ref = shift;
4337 my $treatment_experiments_ref = shift;
4338 my $treatment_cvterm = shift;
4339 my $subplot_owner = shift;
4340 my $subplot_owner_username = shift;
4341 my %treatment_plots = %$treatment_plots_ref;
4342 my %treatment_experiments = %$treatment_experiments_ref;
4344 my $subplot = $chado_schema->resultset("Stock::Stock")->create({
4345 organism_id => $parent_plot_organism,
4346 name => $subplot_name,
4347 uniquename => $subplot_name,
4348 type_id => $subplot_cvterm,
4351 if ($subplot_owner){
4352 my $stock = CXGN::Stock->new({schema=>$chado_schema,stock_id=>$subplot->stock_id()});
4353 $stock->associate_owner($subplot_owner,$subplot_owner,$subplot_owner_username, "");
4356 my $subplotprop = $chado_schema->resultset("Stock::Stockprop")->create( {
4357 stock_id => $subplot->stock_id(),
4358 type_id => $subplot_index_number_cvterm,
4359 value => $subplot_index_number,
4362 #The subplot inherits the properties of the plot.
4363 my $plot_props = $chado_schema->resultset("Stock::Stockprop")->search({ stock_id => $parent_plot, type_id => [$block_cvterm, $plot_number_cvterm, $replicate_cvterm] });
4364 while (my $prop = $plot_props->next() ) {
4365 #print STDERR $subplot->uniquename()." ".$prop->type_id()."\n";
4366 $subplotprop = $chado_schema->resultset("Stock::Stockprop")->create( {
4367 stock_id => $subplot->stock_id(),
4368 type_id => $prop->type_id(),
4369 value => $prop->value(),
4373 #the subplot has a relationship to the plot
4374 my $stock_relationship = $self->bcs_schema()->resultset("Stock::StockRelationship")->create({
4375 subject_id => $parent_plot,
4376 object_id => $subplot->stock_id(),
4377 type_id => $subplot_relationship_cvterm,
4380 #the subplot has a relationship to the accession
4381 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, $cross_cvterm, $family_name_cvterm] }, {'join'=>'object'});
4382 if ($plot_accession_rs->count != 1){
4383 die "There is not 1 stock_relationship of type plot_of between the plot $parent_plot and an accession, a cross or a family_name.";
4385 $stock_relationship = $self->bcs_schema()->resultset("Stock::StockRelationship")->create({
4386 subject_id => $subplot->stock_id(),
4387 object_id => $plot_accession_rs->first->object_id,
4388 type_id => $subplot_relationship_cvterm,
4391 #link subplot to project through nd_experiment. also add nd_genolocation_id of plot to nd_experiment for the subplot
4392 my $subplot_nd_experiment_stock = $chado_schema->resultset("NaturalDiversity::NdExperimentStock")->create({
4393 nd_experiment_id => $field_layout_experiment->nd_experiment_id(),
4394 type_id => $field_layout_cvterm,
4395 stock_id => $subplot->stock_id(),
4398 if ($inherits_plot_treatments){
4399 if($treatments){
4400 foreach (@$treatments){
4401 my $plots = $treatment_plots{$_->[0]};
4402 if (exists($plots->{$parent_plot})){
4403 my $subplot_nd_experiment_stock = $chado_schema->resultset("NaturalDiversity::NdExperimentStock")->create({
4404 nd_experiment_id => $treatment_experiments{$_->[0]},
4405 type_id => $treatment_cvterm,
4406 stock_id => $subplot->stock_id(),
4414 =head2 function has_subplot_entries()
4416 Usage: $trial->has_subplot_entries();
4417 Desc: Some trials require subplot-level data (splitplot designs). This function will determine if a trial has subplots associated with it.
4418 Ret: Returns 1 if trial has subplots, 0 if the trial does not.
4419 Args:
4420 Side Effects:
4421 Example:
4423 =cut
4425 sub has_subplot_entries {
4426 my $self = shift;
4427 my $chado_schema = $self->bcs_schema();
4428 my $has_subplots_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'project_has_subplot_entries', 'project_property' );
4430 my $rs = $chado_schema->resultset("Project::Projectprop")->find({
4431 type_id => $has_subplots_cvterm->cvterm_id(),
4432 project_id => $self->get_trial_id(),
4435 if ($rs) {
4436 return 1;
4437 } else {
4438 return 0;
4443 sub get_planting_date_cvterm_id {
4444 my $self = shift;
4445 my $planting_date = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'project_planting_date', 'project_property');
4447 return $planting_date->cvterm_id();
4451 sub get_transplanting_date_cvterm_id {
4452 my $self = shift;
4453 my $transplanting_date = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'project_transplanting_date', 'project_property');
4455 return $transplanting_date->cvterm_id();
4459 =head2 accessors set_design_type(), get_design_type()
4461 Usage: $trial->set_design_type("RCBD");
4462 Desc:
4463 Ret:
4464 Args:
4465 Side Effects:
4466 Example:
4468 =cut
4470 sub get_design_type {
4471 my $self = shift;
4472 my $design_prop;
4473 my $design_type;
4475 my $project = $self->bcs_schema->resultset("Project::Project")->find( { project_id => $self->get_trial_id() });
4477 $design_prop = $project->projectprops->find(
4478 { 'type.name' => 'design' },
4479 { join => 'type'}
4480 ); #there should be only one design prop.
4481 if (!$design_prop) {
4482 return;
4484 $design_type = $design_prop->value;
4485 if (!$design_type) {
4486 return;
4488 return $design_type;
4493 sub duplicate {
4496 =head2 get_accessions
4498 Usage: my $accessions = $t->get_accessions();
4499 Desc: retrieves the accessions or family names or cross unique ids used in this trial.
4500 Ret: an arrayref of { accession_name => acc_name, stock_id => stock_id, stock_type => stock_type }
4501 Args: none
4502 Side Effects:
4503 Example:
4505 =cut
4507 sub get_accessions {
4508 my $self = shift;
4509 my @accessions;
4511 my $accession_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'accession', 'stock_type' )->cvterm_id();
4512 my $cross_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'cross', 'stock_type' )->cvterm_id();
4513 my $family_name_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'family_name', 'stock_type' )->cvterm_id();
4514 my $field_trial_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, "field_layout", "experiment_type")->cvterm_id();
4515 my $plot_of_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, "plot_of", "stock_relationship")->cvterm_id();
4516 my $plant_of_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, "plant_of", "stock_relationship")->cvterm_id();
4517 my $subplot_of_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, "subplot_of", "stock_relationship")->cvterm_id();
4518 my $tissue_sample_of_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, "tissue_sample_of", "stock_relationship")->cvterm_id();
4520 my $q = "SELECT DISTINCT(accession.stock_id), accession.uniquename, cvterm.name
4521 FROM stock as accession
4522 JOIN cvterm on (accession.type_id = cvterm.cvterm_id)
4523 JOIN stock_relationship on (accession.stock_id = stock_relationship.object_id)
4524 JOIN stock as plot on (plot.stock_id = stock_relationship.subject_id)
4525 JOIN nd_experiment_stock on (plot.stock_id=nd_experiment_stock.stock_id)
4526 JOIN nd_experiment using(nd_experiment_id)
4527 JOIN nd_experiment_project using(nd_experiment_id)
4528 JOIN project using(project_id)
4529 WHERE accession.type_id IN (?, ?, ?)
4530 AND stock_relationship.type_id IN (?, ?, ?, ?)
4531 AND project.project_id = ?
4532 ORDER BY accession.stock_id;";
4534 my $h = $self->bcs_schema->storage->dbh()->prepare($q);
4535 $h->execute($accession_cvterm_id, $cross_cvterm_id, $family_name_cvterm_id,$plot_of_cvterm_id, $tissue_sample_of_cvterm_id, $plant_of_cvterm_id, $subplot_of_cvterm_id,$self->get_trial_id());
4536 while (my ($stock_id, $uniquename, $stock_type) = $h->fetchrow_array()) {
4537 push @accessions, {accession_name=>$uniquename, stock_id=>$stock_id, stock_type=>$stock_type};
4539 return \@accessions;
4542 =head2 get_trial_stock_count
4544 Usage: my $stock_count = $t->get_trial_stock_count();
4545 Desc: retrieves the count of accessions or family names or cross unique ids used in this trial.
4546 Ret: a scalar of the total count
4547 Args: none
4548 Side Effects:
4549 Example:
4551 =cut
4553 sub get_trial_stock_count {
4554 my $self = shift;
4556 my $accessions = $self->get_accessions();
4557 my $stock_count = scalar(@{$accessions});
4559 return $stock_count;
4562 =head2 get_tissue_sources
4564 Usage: my $tissue_sources = $t->get_tissue_sources();
4565 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
4566 Ret: an arrayref of { uniquename => acc_name, type=>'plant', stock_id => stock_id }
4567 Args: none
4568 Side Effects:
4569 Example:
4571 =cut
4573 sub get_tissue_sources {
4574 my $self = shift;
4575 my @tissue_samples;
4576 my $tissue_sample_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'tissue_sample', 'stock_type' )->cvterm_id();
4577 my $tissue_sample_of_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, "tissue_sample_of", "stock_relationship")->cvterm_id();
4578 my $q = "SELECT DISTINCT(stock.stock_id), stock.uniquename, cvterm.name
4579 FROM stock
4580 JOIN cvterm on (stock.type_id = cvterm.cvterm_id)
4581 JOIN stock_relationship on (stock.stock_id = stock_relationship.object_id)
4582 JOIN stock as tissue_sample on (tissue_sample.stock_id = stock_relationship.subject_id)
4583 JOIN nd_experiment_stock on (tissue_sample.stock_id=nd_experiment_stock.stock_id)
4584 JOIN nd_experiment using(nd_experiment_id)
4585 JOIN nd_experiment_project using(nd_experiment_id)
4586 JOIN project using(project_id)
4587 WHERE tissue_sample.type_id = $tissue_sample_cvterm_id
4588 AND stock_relationship.type_id = $tissue_sample_of_cvterm_id
4589 AND project.project_id = ?
4590 GROUP BY (stock.stock_id, cvterm.name)
4591 ORDER BY (stock.stock_id);";
4593 my $h = $self->bcs_schema->storage->dbh()->prepare($q);
4594 $h->execute($self->get_trial_id());
4595 while (my ($stock_id, $uniquename, $type) = $h->fetchrow_array()) {
4596 push @tissue_samples, {uniquename=>$uniquename, type=>$type, stock_id=>$stock_id };
4598 return \@tissue_samples;
4601 =head2 get_plants
4603 Usage: $plants = $t->get_plants();
4604 Desc: retrieves that plants that are part of the design for this trial.
4605 Ret: an array ref containing [ plant_name, plant_stock_id ]
4606 Args:
4607 Side Effects:
4608 Example:
4610 =cut
4612 sub get_plants {
4613 my $self = shift;
4614 my @plants;
4616 my $trial_layout_download = CXGN::Trial::TrialLayoutDownload->new({
4617 schema => $self->bcs_schema,
4618 trial_id => $self->get_trial_id(),
4619 data_level => 'plants',
4620 selected_columns => {"plant_name"=>1,"plant_id"=>1},
4622 my $output = $trial_layout_download->get_layout_output()->{output};
4624 if (defined $output){
4625 my $header = shift @$output;
4626 foreach (@$output) {
4627 push @plants, [$_->[1], $_->[0]];
4629 } else {
4630 @plants = @{$self->get_observation_units_direct('plant')};
4632 return \@plants;
4635 =head2 get_plants_per_accession
4637 Usage: $plants = $t->get_plants_per_accession();
4638 Desc: retrieves that plants that are part of the design for this trial grouping them by accession.
4639 Ret: a hash ref containing { $accession_stock_id1 => [ [ plant_name1, plant_stock_id1 ], [ plant_name2, plant_stock_id2 ] ], ... }
4640 Args:
4641 Side Effects:
4642 Example:
4644 =cut
4646 sub get_plants_per_accession {
4647 my $self = shift;
4648 my %return;
4650 my $plant_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'plant', 'stock_type' )->cvterm_id();
4651 my $accession_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'accession', 'stock_type' )->cvterm_id();
4652 my $family_name_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'family_name', 'stock_type' )->cvterm_id();
4653 my $cross_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'cross', 'stock_type' )->cvterm_id();
4654 my @trial_stock_type_ids;
4655 push @trial_stock_type_ids, $accession_cvterm_id, $family_name_cvterm_id, $cross_cvterm_id;
4656 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'=>{ in => [@trial_stock_type_ids] }}, {join=>{'stock_relationship_subjects'=>'object'}, '+select'=>['stock_relationship_subjects.object_id'], '+as'=>['accession_stock_id']});
4658 my %unique_plants;
4659 while(my $rs = $trial_plant_rs->next()) {
4660 $unique_plants{$rs->uniquename} = [$rs->stock_id, $rs->get_column('accession_stock_id')];
4662 while (my ($key, $value) = each %unique_plants) {
4663 push @{$return{$value->[1]}}, [$value->[0], $key];
4665 #print STDERR Dumper \%return;
4666 return \%return;
4669 =head2 get_seedlots
4671 Usage: my $seedlots = $trial->get_seedlots();
4672 Desc: returns a list of seedlots that are defined for the trial.
4673 Ret: an array ref of elements that contain
4674 [ seedlot_name, seedlot_stock_id ]
4675 Args: none
4676 Side Effects: db access
4677 Example:
4679 =cut
4681 sub get_seedlots {
4682 my $self = shift;
4683 my @seedlots;
4685 my $seedlot_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'seedlot', 'stock_type' )->cvterm_id();
4686 my $seed_transaction_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, "seed transaction", "stock_relationship")->cvterm_id();
4688 my $q = "SELECT DISTINCT(accession.stock_id), accession.uniquename
4689 FROM stock as accession
4690 JOIN stock_relationship on (accession.stock_id = stock_relationship.object_id)
4691 JOIN stock as plot on (plot.stock_id = stock_relationship.subject_id)
4692 JOIN nd_experiment_stock on (plot.stock_id=nd_experiment_stock.stock_id)
4693 JOIN nd_experiment using(nd_experiment_id)
4694 JOIN nd_experiment_project using(nd_experiment_id)
4695 JOIN project using(project_id)
4696 WHERE accession.type_id = $seedlot_cvterm_id
4697 AND stock_relationship.type_id IN ($seed_transaction_cvterm_id)
4698 AND project.project_id = ?
4699 GROUP BY accession.stock_id
4700 ORDER BY accession.stock_id;";
4702 #Removed nd_experiment.type_id IN ($field_trial_cvterm_id, $genotyping_trial_cvterm_id) AND
4704 my $h = $self->bcs_schema->storage->dbh()->prepare($q);
4705 $h->execute($self->get_trial_id());
4706 while (my ($stock_id, $uniquename) = $h->fetchrow_array()) {
4707 push @seedlots, [$stock_id, $uniquename];
4710 return \@seedlots;
4713 =head2 get_plots
4715 Usage: my $plots = $trial->get_plots();
4716 Desc: returns a list of plots that are defined for the trial.
4717 Ret: an array ref of elements that contain
4718 [ plot_name, plot_stock_id ]
4719 Args: none
4720 Side Effects: db access
4721 Example:
4723 =cut
4725 sub get_plots {
4726 my $self = shift;
4727 my @plots;
4729 my $trial_layout_download = CXGN::Trial::TrialLayoutDownload->new({
4730 schema => $self->bcs_schema,
4731 trial_id => $self->get_trial_id(),
4732 data_level => 'plots',
4733 selected_columns => {"plot_name"=>1,"plot_id"=>1},
4735 my $output = $trial_layout_download->get_layout_output()->{output};
4737 if (defined $output){
4738 my $header = shift @$output;
4739 foreach (@$output) {
4740 push @plots, [$_->[1], $_->[0]];
4742 } else {
4743 @plots = @{$self->get_observation_units_direct('plot')};
4745 return \@plots;
4748 sub get_observation_units_direct {
4749 my $self = shift;
4750 my $stock_type = shift;
4751 # my $nd_experiment_types = shift || ['field_layout','treatment_experiment','genotyping_layout'];
4752 my $schema = $self->bcs_schema;
4753 my @obs;
4754 my $obs_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, $stock_type, "stock_type")->cvterm_id();
4755 # my @nd_experiment_type_ids;
4756 # foreach (@$nd_experiment_types) {
4757 # push @nd_experiment_type_ids, SGN::Model::Cvterm->get_cvterm_row($schema, $_, "experiment_type")->cvterm_id();
4759 my $q = "SELECT stock.uniquename, stock.stock_id FROM stock JOIN nd_experiment_stock USING(stock_id) JOIN nd_experiment_project USING(nd_experiment_id) WHERE project_id=? AND stock.type_id=? ORDER BY stock.uniquename ASC;";
4760 my $h = $schema->storage->dbh()->prepare($q);
4761 $h->execute($self->get_trial_id(), $obs_cvterm_id);
4762 while (my ($uniquename, $stock_id) = $h->fetchrow_array()) {
4763 push @obs, [$stock_id, $uniquename];
4765 return \@obs;
4768 =head2 get_plots_per_accession
4770 Usage: $plots = $t->get_plots_per_accession();
4771 Desc: retrieves that plots that are part of the design for this trial grouping them by accession.
4772 Ret: a hash ref containing { $accession_stock_id1 => [ [ plot_name1, plot_stock_id1 ], [ plot_name2, plot_stock_id2 ] ], ... }
4773 Args:
4774 Side Effects:
4775 Example:
4777 =cut
4779 sub get_plots_per_accession {
4780 my $self = shift;
4781 my %return;
4783 # note: this function also retrieves stocks of type tissue_sample (for genotyping plates).
4784 my $plot_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'plot', 'stock_type' )->cvterm_id();
4785 my $accession_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'accession', 'stock_type' )->cvterm_id();
4786 my $cross_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'cross', 'stock_type' )->cvterm_id();
4787 my $family_name_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'family_name', 'stock_type' )->cvterm_id();
4788 my $tissue_sample_cvterm = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'tissue_sample', 'stock_type');
4789 my $tissue_sample_cvterm_id = $tissue_sample_cvterm ? $tissue_sample_cvterm->cvterm_id() : '';
4791 my @type_ids;
4792 push @type_ids, $plot_cvterm_id if $plot_cvterm_id;
4793 push @type_ids, $tissue_sample_cvterm_id if $tissue_sample_cvterm_id;
4795 print STDERR "TYPE IDS: ".join(", ", @type_ids);
4797 my @trial_stock_type_ids;
4798 push @trial_stock_type_ids, $accession_cvterm_id, $cross_cvterm_id, $family_name_cvterm_id;
4800 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'=> { in => [@trial_stock_type_ids] }}, {join=>{'stock_relationship_subjects'=>'object'}, '+select'=>['stock_relationship_subjects.object_id'], '+as'=>['accession_stock_id']});
4802 my %unique_plots;
4803 while(my $rs = $trial_plot_rs->next()) {
4804 $unique_plots{$rs->uniquename} = [$rs->stock_id, $rs->get_column('accession_stock_id')];
4806 while (my ($key, $value) = each %unique_plots) {
4807 push @{$return{$value->[1]}}, [$value->[0], $key];
4809 #print STDERR Dumper \%return;
4810 return \%return;
4813 =head2 get_subplots
4815 Usage: my $subplots = $trial->get_subplots();
4816 Desc: returns a list of subplots that are defined for the trial.
4817 Ret: an array ref of elements that contain
4818 [ subplot_name, subplot_stock_id ]
4819 Args: none
4820 Side Effects: db access
4821 Example:
4823 =cut
4825 sub get_subplots {
4826 my $self = shift;
4827 my @subplots;
4829 my $trial_layout_download = CXGN::Trial::TrialLayoutDownload->new({
4830 schema => $self->bcs_schema,
4831 trial_id => $self->get_trial_id(),
4832 data_level => 'subplots',
4833 selected_columns => {"subplot_name"=>1,"subplot_id"=>1},
4835 my $output = $trial_layout_download->get_layout_output()->{output};
4837 if (defined $output){
4838 my $header = shift @$output;
4839 foreach (@$output) {
4840 push @subplots, [$_->[1], $_->[0]];
4842 } else {
4843 @subplots = @{$self->get_observation_units_direct('subplot')};
4845 print STDERR Dumper \@subplots;
4846 return \@subplots;
4849 =head2 get_tissue_samples
4851 Usage: $tissues = $t->get_tissue_samples();
4852 Desc: retrieves the tissue samples that are linked to plants for this trial.
4853 Ret: an array ref containing [ tissue_sample_name, tissue_sample_stock_id ]
4854 Args:
4855 Side Effects:
4856 Example:
4858 =cut
4860 sub get_tissue_samples {
4861 my $self = shift;
4862 my @tissues;
4864 my $trial_layout_download = CXGN::Trial::TrialLayoutDownload->new({
4865 schema => $self->bcs_schema,
4866 trial_id => $self->get_trial_id(),
4867 data_level => 'field_trial_tissue_samples',
4868 selected_columns => {"tissue_sample_name"=>1,"tissue_sample_id"=>1},
4870 my $output = $trial_layout_download->get_layout_output()->{output};
4871 if (defined $output){
4872 my $header = shift @$output;
4873 foreach (@$output) {
4874 push @tissues, [$_->[1], $_->[0]];
4876 } else {
4877 @tissues = @{$self->get_observation_units_direct('tissue_sample')};
4879 return \@tissues;
4882 =head2 get_controls
4884 Usage: my $controls = $t->get_controls();
4885 Desc: Returns the accessions that were used as controls in the design
4886 Ret: an arrayref containing
4887 { accession_name => control_name, stock_id => control_stock_id }
4888 Args: none
4889 Side Effects:
4890 Example:
4892 =cut
4894 sub get_controls {
4895 my $self = shift;
4896 my @controls;
4898 my $accession_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'accession', 'stock_type' )->cvterm_id();
4899 my $field_trial_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, "field_layout", "experiment_type")->cvterm_id();
4900 my $genotyping_trial_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, "genotyping_layout", "experiment_type")->cvterm_id();
4901 my $plot_of_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, "plot_of", "stock_relationship")->cvterm_id();
4902 my $plant_of_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, "plant_of", "stock_relationship")->cvterm_id();
4903 my $tissue_sample_of_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, "tissue_sample_of", "stock_relationship")->cvterm_id();
4904 my $control_type_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, "is a control", 'stock_property')->cvterm_id();
4906 my $q = "SELECT DISTINCT(accession.stock_id), accession.uniquename
4907 FROM stock as accession
4908 JOIN stock_relationship on (accession.stock_id = stock_relationship.object_id)
4909 JOIN stock as plot on (plot.stock_id = stock_relationship.subject_id)
4910 JOIN stockprop as control on (plot.stock_id=control.stock_id)
4911 JOIN nd_experiment_stock on (plot.stock_id=nd_experiment_stock.stock_id)
4912 JOIN nd_experiment using(nd_experiment_id)
4913 JOIN nd_experiment_project using(nd_experiment_id)
4914 JOIN project using(project_id)
4915 WHERE accession.type_id = $accession_cvterm_id
4916 AND stock_relationship.type_id IN ($plot_of_cvterm_id, $tissue_sample_of_cvterm_id, $plant_of_cvterm_id)
4917 AND project.project_id = ?
4918 AND control.type_id = $control_type_id
4919 GROUP BY accession.stock_id
4920 ORDER BY accession.stock_id;";
4922 #removed nd_experiment.type_id IN ($field_trial_cvterm_id, $genotyping_trial_cvterm_id) AND
4924 my $h = $self->bcs_schema->storage->dbh()->prepare($q);
4925 $h->execute($self->get_trial_id());
4926 while (my ($stock_id, $uniquename) = $h->fetchrow_array()) {
4927 push @controls, {accession_name=> $uniquename, stock_id=>$stock_id } ;
4930 return \@controls;
4933 =head2 get_controls_by_plot
4935 Usage: my $controls = $t->get_controls_by_plot(\@plot_ids);
4936 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
4937 Ret: an arrayref containing
4938 { accession_name => control_name, stock_id => control_stock_id }
4939 Args: none
4940 Side Effects:
4941 Example:
4943 =cut
4945 sub get_controls_by_plot {
4946 my $self = shift;
4947 my $plot_ids = shift;
4948 my @ids = @$plot_ids;
4949 my @controls;
4951 my $accession_type_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'accession', 'stock_type')->cvterm_id();
4952 my $accession_rs = $self->bcs_schema->resultset('Stock::Stock')->search(
4953 { 'me.type_id'=>$accession_type_id, 'subject.stock_id' => { 'in' => \@ids} , 'type.name' => 'is a control' },
4954 { join => { stock_relationship_objects => { subject => { stockprops => 'type' }}}, group_by => 'me.stock_id',},
4957 while(my $accession = $accession_rs->next()) {
4958 push @controls, { accession_name => $accession->uniquename, stock_id => $accession->stock_id };
4961 return \@controls;
4964 =head2 get_treatments
4966 Usage: $plants = $t->get_treatments();
4967 Desc: retrieves the treatments that are part of this trial
4968 Ret: an array ref containing from project table [ treatment_name, treatment_id ]
4969 Args:
4970 Side Effects:
4971 Example:
4973 =cut
4975 sub get_treatments {
4976 my $self = shift;
4977 my @plants;
4978 my $treatment_rel_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, "trial_treatment_relationship", "project_relationship")->cvterm_id();
4980 my $treatment_rs = $self->bcs_schema->resultset("Project::ProjectRelationship")->search({ 'me.type_id'=>$treatment_rel_cvterm_id, object_project_id=>$self->get_trial_id()})->search_related('subject_project');
4982 my @treatments;
4983 while(my $rs = $treatment_rs->next()) {
4984 push @treatments, [$rs->project_id, $rs->name];
4986 return \@treatments;
4989 =head2 get_trial_contacts
4991 Usage: my $contacts = $t->get_trial_contacts();
4992 Desc: Returns an arrayref of hashrefs that contain all sp_person info fpr sp_person_ids saved as projectprops to this trial
4993 Ret: an arrayref containing
4994 { sp_person_id => 1, salutation => 'Mr.', first_name => 'joe', last_name => 'doe', email => 'j@d.com' }
4995 Args: none
4996 Side Effects:
4997 Example:
4999 =cut
5001 sub get_trial_contacts {
5002 my $self = shift;
5003 my @contacts;
5005 my $sp_person_id_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema,'sp_person_id','local')->cvterm_id;
5006 my $prop_rs = $self->bcs_schema->resultset('Project::Projectprop')->search(
5007 { 'project_id' => $self->get_trial_id, 'type_id'=>$sp_person_id_cvterm_id }
5010 while(my $prop = $prop_rs->next()) {
5011 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=?;";
5012 my $h = $self->bcs_schema()->storage->dbh()->prepare($q);
5013 $h->execute($prop->value);
5014 while (my ($sp_person_id, $username, $salutation, $first_name, $last_name, $email, $user_type, $phone, $organization) = $h->fetchrow_array()){
5015 push @contacts, {
5016 sp_person_id => $sp_person_id,
5017 salutation => $salutation,
5018 first_name => $first_name,
5019 last_name => $last_name,
5020 username => $username,
5021 email => $email,
5022 type => $user_type,
5023 phone_number => $phone,
5024 organization => $organization
5029 return \@contacts;
5033 =head2 function get_data_agreement()
5035 Usage: $trial->get_data_agreement();
5036 Desc: return data agreement saved for trial.
5037 Ret:
5038 Args:
5039 Side Effects:
5040 Example:
5042 =cut
5044 sub get_data_agreement {
5045 my $self = shift;
5046 my $chado_schema = $self->bcs_schema();
5047 my $cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'data_agreement', 'project_property' );
5049 my $rs = $chado_schema->resultset("Project::Projectprop")->find({
5050 type_id => $cvterm->cvterm_id(),
5051 project_id => $self->get_trial_id(),
5054 if ($rs) {
5055 return $rs->value();
5056 } else {
5057 return;
5062 =head2 suppress_plot_phenotype
5064 Usage: my $suppress_return_error = $trial->suppress_plot_phenotype($trait_id, $plot_name, $plot_pheno_value, $phenotype_id);
5065 if ($suppress_return_error) {
5066 $c->stash->{rest} = { error => $suppress_return_error };
5067 return;
5070 Desc: Suppresses plot phenotype
5071 Ret:
5072 Args:
5073 Side Effects:
5074 Example:
5076 =cut
5078 sub suppress_plot_phenotype {
5079 my $self = shift;
5080 my $trait_id = shift;
5081 my $plot_name = shift;
5082 my $phenotype_value = shift;
5083 my $phenotype_id = shift;
5084 my $username = shift;
5085 my $timestamp = shift;
5086 my $schema = $self->bcs_schema;
5087 my $trial_id = $self->get_trial_id();
5088 my $plot_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'plot', 'stock_type')->cvterm_id();
5089 my $phenotype_outlier_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'phenotype_outlier', 'phenotype_property')->cvterm_id();
5090 my $error;
5091 my $json_string = { value => 1, username=>$username, timestamp=>$timestamp };
5093 my $prop_rs = $self->bcs_schema->resultset('Phenotype::Phenotypeprop')->search(
5094 { 'phenotype_id' => $phenotype_id, 'type_id'=>$phenotype_outlier_type_id }
5097 if ($prop_rs->count == 0) {
5098 my $suppress_plot_pheno = $schema->resultset("Phenotype::Phenotypeprop")->create({
5099 phenotype_id => $phenotype_id,
5100 type_id => $phenotype_outlier_type_id,
5101 value => encode_json $json_string,
5104 else {
5105 $error = "This plot phenotype has already been suppressed.";
5108 return $error;
5112 =head2 delete_assayed_trait
5114 Usage: my $delete_trait_return_error = $trial->delete_assayed_trait($c->config->{basepath}, $c->config->{dbhost}, $c->config->{dbname}, $c->config->{dbuser}, $c->config->{dbpass}, $phenotypes_ids, [] );
5115 if ($delete_trait_return_error) {
5116 $c->stash->{rest} = { error => $delete_trait_return_error };
5117 return;
5120 Desc: Delete Assayed Traits
5121 Ret:
5122 Args:
5123 Side Effects:
5124 Example:
5126 =cut
5128 sub delete_assayed_trait {
5129 my $self = shift;
5130 my $basepath = shift;
5131 my $dbhost = shift;
5132 my $dbname = shift;
5133 my $dbuser = shift;
5134 my $dbpass = shift;
5135 my $temp_file_nd_experiment_id = shift;
5136 my $pheno_ids = shift;
5137 my $trait_ids = shift;
5139 my $trial_id = $self->get_trial_id();
5140 my $schema = $self->bcs_schema;
5141 my $phenome_schema = $self->phenome_schema;
5142 my ($error, @nd_expt_ids);
5143 my $nd_experiment_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'phenotyping_experiment', 'experiment_type')->cvterm_id();
5144 my $search_params = { 'nd_experiment.type_id' => $nd_experiment_type_id, 'nd_experiment_projects.project_id' => $trial_id };
5145 if (scalar(@$trait_ids) > 0){
5146 $search_params->{'me.observable_id'} = { '-in' => $trait_ids };
5148 if (scalar(@$pheno_ids) > 0){
5149 $search_params->{'me.phenotype_id'} = { '-in' => $pheno_ids };
5151 #$schema->storage->debug(1);
5152 if (scalar(@$pheno_ids) > 0 || scalar(@$trait_ids) > 0 ){
5153 my %phenotype_ids_and_nd_experiment_ids_to_delete;
5154 my $delete_pheno_id_rs = $schema->resultset("Phenotype::Phenotype")->search(
5155 $search_params,
5157 join => { 'nd_experiment_phenotypes' => {'nd_experiment' => 'nd_experiment_projects'} },
5158 '+select' => ['nd_experiment.nd_experiment_id'],
5159 '+as' => ['nd_expt_id'],
5161 while ( my $res = $delete_pheno_id_rs->next()){
5162 push @{$phenotype_ids_and_nd_experiment_ids_to_delete{nd_experiment_ids}}, $res->get_column('nd_expt_id');
5163 push @{$phenotype_ids_and_nd_experiment_ids_to_delete{phenotype_ids}}, $res->phenotype_id;
5165 return delete_phenotype_values_and_nd_experiment_md_values($dbhost, $dbname, $dbuser, $dbpass, $temp_file_nd_experiment_id, $basepath, $schema, \%phenotype_ids_and_nd_experiment_ids_to_delete);
5167 else {
5168 $error = "List of trait or phenotype ids was not provided for deletion.";
5170 return $error;
5173 =head2 function delete_empty_crossing_experiment()
5175 Usage:
5176 Desc:
5177 Ret:
5178 Args:
5179 Side Effects:
5180 Example:
5182 =cut
5184 sub delete_empty_crossing_experiment {
5185 my $self = shift;
5187 if ($self->cross_count() > 0) {
5188 return 'Cannot delete crossing experiment with associated crosses.';
5191 my $project_owner_schema = CXGN::Phenome::Schema->connect( sub {$self->bcs_schema->storage->dbh()},{on_connect_do => ['SET search_path TO public,phenome;']});
5192 my $project_owner_row = $project_owner_schema->resultset('ProjectOwner')->find( { project_id=> $self->get_trial_id() });
5193 if ($project_owner_row) {
5194 $project_owner_row->delete();
5197 eval {
5198 my $row = $self->bcs_schema->resultset("Project::Project")->find( { project_id=> $self->get_trial_id() });
5199 $row->delete();
5200 print STDERR "deleted project ".$self->get_trial_id."\n";
5202 if ($@) {
5203 print STDERR "An error occurred during deletion: $@\n";
5204 return $@;
5208 =head2 function cross_count()
5210 Usage:
5211 Desc: The number of crosses associated with this crossing experiment
5212 Ret:
5213 Args:
5214 Side Effects:
5215 Example:
5217 =cut
5219 sub cross_count {
5220 my $self = shift;
5221 my $schema = $self->bcs_schema;
5222 my $crossing_experiment_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, "cross_experiment", "experiment_type")->cvterm_id();
5224 my $q = "SELECT count(nd_experiment_project.nd_experiment_id)
5225 FROM nd_experiment_project
5226 JOIN nd_experiment on (nd_experiment_project.nd_experiment_id = nd_experiment.nd_experiment_id)
5227 WHERE nd_experiment.type_id = $crossing_experiment_type_id
5228 AND nd_experiment_project.project_id = ?";
5229 my $h = $self->bcs_schema->storage->dbh()->prepare($q);
5230 $h->execute($self->get_trial_id());
5231 my ($count) = $h->fetchrow_array();
5232 return $count;
5237 =head2 delete_genotyping_plate_and_field_trial_linkage
5239 Usage:
5240 Desc:
5241 Ret:
5242 Args:
5243 Side Effects:
5244 Example:
5246 =cut
5248 sub delete_genotyping_plate_from_field_trial_linkage {
5249 my $self = shift;
5250 my $field_trial_id = shift;
5251 my $role = shift;
5252 my $plate_id = $self->get_trial_id();
5254 my @errors;
5256 #Make sure to have the right access to delete
5257 if ($role ne "curator") {
5258 push @errors, "Only a curator can delete this linkage.";
5259 return { errors => \@errors };
5262 my $genotyping_trial_from_field_trial_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($self->bcs_schema, 'genotyping_trial_from_field_trial', 'project_relationship')->cvterm_id();
5263 # check ownership of that image
5264 my $q = "SELECT project_relationship.project_relationship_id from project join project_relationship on(project_id= subject_project_id) join project as genotypeproject on (genotypeproject.project_id= project_relationship.object_project_id) where genotypeproject.project_id=? and project.project_id=? and project_relationship.type_id=?;";
5266 my $dbh = $self->bcs_schema->storage()->dbh();
5267 my $h = $dbh->prepare($q);
5269 $h->execute($plate_id, $field_trial_id,$genotyping_trial_from_field_trial_cvterm_id);
5271 if ($h->rows() == 1){
5272 if (my ($project_relationship_id) = $h->fetchrow_array()) {
5273 my $uq = "DELETE from project_relationship where project_relationship_id = ? and type_id = ? ";
5274 my $uh = $dbh->prepare($uq);
5275 $uh->execute($project_relationship_id,$genotyping_trial_from_field_trial_cvterm_id);
5277 else {
5278 push @errors, "An error occurred during deletion.";
5280 } else {
5281 push @errors, "Project relationship does not exists or has more than 1 occurrence.";
5284 if (@errors >0) {
5285 return { errors => \@errors };
5288 return { success => 1 };
5294 =head2 function delete_empty_genotyping_project()
5296 Usage:
5297 Desc:
5298 Ret:
5299 Args:
5300 Side Effects:
5301 Example:
5303 =cut
5305 sub delete_empty_genotyping_project {
5306 my $self = shift;
5308 if ($self->genotyping_plate_count() > 0) {
5309 return 'Cannot delete genotyping project with associated genotyping plates.';
5312 if ($self->genotyping_protocol_count() > 0) {
5313 return 'Cannot delete genotyping project with associated genotyping protocol.';
5316 my $project_owner_schema = CXGN::Phenome::Schema->connect( sub {$self->bcs_schema->storage->dbh()},{on_connect_do => ['SET search_path TO public,phenome;']});
5317 my $project_owner_row = $project_owner_schema->resultset('ProjectOwner')->find( { project_id=> $self->get_trial_id() });
5318 if ($project_owner_row) {
5319 $project_owner_row->delete();
5322 eval {
5323 my $row = $self->bcs_schema->resultset("Project::Project")->find( { project_id=> $self->get_trial_id() });
5324 $row->delete();
5325 print STDERR "deleted project ".$self->get_trial_id."\n";
5327 if ($@) {
5328 print STDERR "An error occurred during deletion: $@\n";
5329 return $@;
5334 =head2 function genotyping_plate_count()
5336 Usage:
5337 Desc: The number of genotyping plates associated with this genotyping project
5338 Ret:
5339 Args:
5340 Side Effects:
5341 Example:
5343 =cut
5345 sub genotyping_plate_count {
5346 my $self = shift;
5347 my $schema = $self->bcs_schema;
5348 my $genotyping_project_id = $self->get_trial_id();
5350 my $plate_info = CXGN::Genotype::GenotypingProject->new({
5351 bcs_schema => $schema,
5352 project_id => $genotyping_project_id
5354 my ($data, $plate_count) = $plate_info->get_plate_info();
5356 return $plate_count;
5360 =head2 function genotyping_protocol_count()
5362 Usage:
5363 Desc: The number of genotyping protocols associated with this genotyping project
5364 Ret:
5365 Args:
5366 Side Effects:
5367 Example:
5369 =cut
5371 sub genotyping_protocol_count {
5372 my $self = shift;
5373 my $schema = $self->bcs_schema;
5374 my $genotyping_project_id = $self->get_trial_id();
5375 my @project_list = ($genotyping_project_id);
5376 my $protocol_search_result = CXGN::Genotype::Protocol::list($schema, undef, undef, undef, undef, undef ,\@project_list);
5378 my $protocol_count;
5379 if ($protocol_search_result) {
5380 $protocol_count = scalar(@$protocol_search_result);
5383 return $protocol_count;
5392 ##__PACKAGE__->meta->make_immutable;