4 CXGN::Project - helper class for projects
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.
14 my $project = CXGN::Project->new( { bcs_schema => $schema, trial_id => $trial_id });
15 $trial->set_description("yield trial with promising varieties");
20 Lukas Mueller <lam87@cornell.edu>
26 package CXGN
::Project
;
33 use CXGN
::Trial
::Folder
;
34 use CXGN
::Trial
::TrialLayout
;
35 use CXGN
::Trial
::TrialLayoutDownload
;
36 use SGN
::Model
::Cvterm
;
41 use File
::Basename qw
| basename dirname
|;
43 =head2 accessor bcs_schema()
45 accessor for bcs_schema. Needs to be set when calling the constructor.
50 isa
=> 'Bio::Chado::Schema',
55 has
'metadata_schema' => (
56 isa
=> 'CXGN::Metadata::Schema',
60 has
'phenome_schema' => (
61 isa
=> 'CXGN::Phenome::Schema',
68 trigger
=> \
&set_trial_id
,
69 builder
=> 'get_trial_id',
75 trigger
=> \
&set_name
,
76 builder
=> 'get_name',
80 has
'description' => (
83 trigger
=> \
&set_description
,
84 builder
=> 'get_description',
91 trigger
=> \
&get_year
,
92 builder
=> 'set_year',
100 print STDERR
"BUILD CXGN::Project... with ".$args->{trial_id
}."\n";
102 if (! $args->{description
}) {
103 $args->{description
} = "(No description provided)";
106 my $row = $self->bcs_schema()->resultset("Project::Project")->find( { project_id
=> $args->{trial_id
} });
108 print STDERR
"PROJECT ID = $args->{trial_id}\n";
110 $self->name( $row->name() );
113 if ($args->{trial_id
} && ! $row) {
114 die "The trial ".$args->{trial_id
}." does not exist - aborting.";
117 $row = $self->bcs_schema()->resultset("Project::Project")->find( { name
=> $args->{name
} } );
120 if (! $args->{trial_id
} && $row) {
121 die "A trial with the name $args->{name} already exists. Please choose another name.";
124 if (! $args->{trial_id
} && ! $row) {
125 print STDERR
"INSERTING A NEW ROW...\n";
127 my $new_row = $args->{bcs_schema
}->resultset("Project::Project")->create( { name
=> $args->{name
}, description
=> $args->{description
} });
128 my $project_id = $new_row->project_id();
129 print STDERR
"new project object has project id $project_id\n";
131 $self->set_trial_id($project_id);
134 if ($args->{trial_id
} && $row) {
135 print STDERR
"Existing project... populating object.\n";
136 $self->set_trial_id($args->{trial_id
});
137 $self->name($args->{name
});
138 $self->description($args->{description
});
142 =head2 accessors get_trial_id()
144 Desc: get the trial id
148 has
'trial_id' => (isa
=> 'Int',
150 reader
=> 'get_trial_id',
151 writer
=> 'set_trial_id',
154 =head2 accessors get_layout(), set_layout()
156 Desc: set the layout object for this trial (CXGN::Trial::TrialLayout)
157 (This is populated automatically by the constructor)
161 has
'layout' => (isa
=> 'CXGN::Trial::TrialLayout::Phenotyping |
162 CXGN::Trial::TrialLayout::Genotyping |
163 CXGN::Trial::TrialLayout::Analysis',
165 reader
=> 'get_layout',
166 writer
=> 'set_layout',
167 predicate
=> 'has_layout',
169 default => sub { my $self = shift; $self->_get_layout(); }
174 print STDERR
"RETRIEVING LAYOUT...\n";
175 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
} });
176 $self->set_layout($layout);
179 =head2 accessors get_cxgn_project_type()
181 get the CXGN::Project type e.g. field trial, analysis, genotyping trial, etc
185 sub get_cxgn_project_type
{
188 my $analysis_metadata_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema(), 'analysis_metadata_json', 'project_property')->cvterm_id();
189 my $crossing_trial_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema(), 'crossing_trial', 'project_type')->cvterm_id();
191 my $q = "SELECT projectprop.type_id, projectprop.value FROM project JOIN projectprop USING(project_id)";
192 my $h = $self->bcs_schema->storage->dbh->prepare($q);
195 my $cxgn_project_type = 'field_trial_project';
196 my $plot_data_level = 'plot';
197 my $experiment_type = 'field_layout';
198 while (my ($prop, $propvalue) = $h->fetchrow_array()) {
200 if ($prop == $crossing_trial_cvterm_id) {
201 $cxgn_project_type = 'crossing_project';
203 if ($prop == $analysis_metadata_cvterm_id) {
204 $cxgn_project_type = 'analysis_project';
205 $plot_data_level = 'analysis_instance';
206 $experiment_type = 'analysis_experiment';
209 if ($propvalue eq "genotyping_plate") {
210 $cxgn_project_type = 'genotyping_plate_project';
211 $experiment_type = 'genotyping_layout';
213 if ($propvalue eq "treatment") {
214 $cxgn_project_type = 'management_factor_project';
216 if ($propvalue eq "genotype_data_project") {
217 $cxgn_project_type = 'genotyping_data_project';
219 if ($propvalue eq "drone_run") {
220 $cxgn_project_type = 'drone_run_project';
222 if ($propvalue eq "drone_run_band") {
223 $cxgn_project_type = 'drone_run_band_project';
229 cxgn_project_type
=> $cxgn_project_type,
230 data_level
=> $plot_data_level,
231 experiment_type
=> $experiment_type
235 =head2 accessors get_year(), set_year()
237 getter/setter for the year property. The setter modifies the database.
244 print STDERR
"get_year()...\n";
246 if ($self->year()) { return $self->year(); }
248 my $type_id = $self->get_year_type_id();
250 my $rs = $self->bcs_schema->resultset('Project::Project')->search( { 'me.project_id' => $self->get_trial_id() })->search_related('projectprops', { type_id
=> $type_id } );
252 if ($rs->count() == 0) {
256 return $rs->first()->value();
266 print STDERR
"set_year(): No year provided, not setting.\n";
270 print STDERR
"set_year()... (with parameter $year)\n";
271 my $type_id = $self->get_year_type_id();
273 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find( { project_id
=> $self->get_trial_id(), type_id
=> $type_id });
276 print STDERR
"Updating year to $year...\n";
281 print STDERR
"inserting new year ($year)...\n";
282 $row = $self->bcs_schema->resultset('Project::Projectprop')->create(
286 project_id
=> $self->get_trial_id()
288 $year = $row->value();
293 =head2 accessors get_description(), set_description()
295 getter/setter for the description
299 sub get_description
{
302 print STDERR
"Get description for trial id ".$self->get_trial_id()."\n";
303 my $rs = $self->bcs_schema->resultset('Project::Project')->search( { project_id
=> $self->get_trial_id() });
305 return $rs->first()->description();
310 sub set_description
{
312 my $description = shift;
314 my $row = $self->bcs_schema->resultset('Project::Project')->find( { project_id
=> $self->get_trial_id() });
316 #print STDERR "Setting new description $description for trial ".$self->get_trial_id()."\n";
318 $row->description($description);
325 =head2 function get_nd_experiment_id()
327 Usage: my $location = $trial->get_nd_experiment_id();
328 Desc: Every trial should have only a single nd_experiment entry of type 'field_layout'. This returns this nd_experiment_id for the trial.
329 Ret: $nd_experiment_id
336 sub get_nd_experiment_id
{
338 my $nd_experiment_field_layout_type_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'field_layout', 'experiment_type')->cvterm_id();
339 my $nd_experiment_genotyping_layout_type_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'genotyping_layout', 'experiment_type')->cvterm_id();
340 my $nd_experiment_rs = $self->bcs_schema->resultset('NaturalDiversity::NdExperiment')->search(
341 { 'me.type_id' => [$nd_experiment_field_layout_type_id, $nd_experiment_genotyping_layout_type_id], 'project.project_id' => $self->get_trial_id },
342 { 'join' => {'nd_experiment_projects'=>'project'}}
344 if ($nd_experiment_rs->count > 1){
345 return {error
=> "A trial cannot have more than one nd_experiment entry of type field_layout. Please contact us."};
347 if ($nd_experiment_rs == 1){
348 return {success
=> 1, nd_experiment_id
=> $nd_experiment_rs->first->nd_experiment_id};
350 return {error
=> "This trial does not have an nd_experiment entry of type field_layout. Please contact us."}
354 =head2 function get_location()
356 Usage: my $location = $trial->get_location();
358 Ret: [ location_id, 'location description' ]
368 if ($self->get_location_type_id()) {
369 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find( { project_id
=> $self->get_trial_id() , type_id
=> $self->get_location_type_id() });
372 my $loc = $self->bcs_schema->resultset('NaturalDiversity::NdGeolocation')->find( { nd_geolocation_id
=> $row->value() });
374 return [ $row->value(), $loc->description() ];
382 =head2 function set_location()
384 Usage: $trial->set_location($location_id);
388 Side Effects: database access
395 my $location_id = shift;
396 my $project_id = $self->get_trial_id();
397 my $type_id = $self->get_location_type_id();
399 my $row = $self->bcs_schema()->resultset('Project::Projectprop')->find({
400 project_id
=> $project_id,
405 $row->value($location_id);
409 $row = $self->bcs_schema()->resultset('Project::Projectprop')->create({
410 project_id
=> $project_id,
412 value
=> $location_id,
417 =head2 function get_location_noaa_station_id()
419 Usage: my $noaa_station_id = $trial->get_location_noaa_station_id();
428 sub get_location_noaa_station_id
{
430 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();
431 my $noaa_station_id_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'noaa_station_id', 'geolocation_property')->cvterm_id();
433 my $q = "SELECT value FROM nd_geolocationprop WHERE nd_geolocation_id = ? AND type_id = ?;";
434 my $h = $self->bcs_schema->storage->dbh()->prepare($q);
435 $h->execute($nd_geolocation_id, $noaa_station_id_cvterm_id);
436 my ($noaa_station_id) = $h->fetchrow_array();
437 return $noaa_station_id;
440 =head2 function get_breeding_programs()
443 Desc: return associated breeding program info
444 Ret: returns a listref to [ id, name, desc ] listrefs
451 sub get_breeding_programs
{
454 my $breeding_program_cvterm_id = $self->get_breeding_program_cvterm_id();
456 my $trial_rs= $self->bcs_schema->resultset('Project::ProjectRelationship')->search( { 'subject_project_id' => $self->get_trial_id() } );
458 my $trial_row = $trial_rs -> first
();
463 $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' } );
465 while (my $row = $rs->next()) {
466 push @projects, [ $row->project_id, $row->name, $row->description ];
472 =head2 function set_field_trials_source_field_trials()
475 Desc: sets associated source field trials for the current field trial
476 Ret: returns an arrayref [ id, name ] of arrayrefs
477 Args: an arrayref [source_trial_id1, source_trial_id2]
483 sub set_field_trials_source_field_trials
{
485 my $source_field_trial_ids = shift;
486 my $schema = $self->bcs_schema;
487 my $field_trial_from_field_trial_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'field_trial_from_field_trial', 'project_relationship')->cvterm_id();
489 foreach (@
$source_field_trial_ids){
491 my $trial_rs= $self->bcs_schema->resultset('Project::ProjectRelationship')->create({
492 'subject_project_id' => $self->get_trial_id(),
493 'object_project_id' => $_,
494 'type_id' => $field_trial_from_field_trial_cvterm_id
498 my $projects = $self->get_field_trials_source_field_trials();
502 =head2 function get_field_trials_source_field_trials()
505 Desc: return associated source field trials for the current field trial
506 Ret: returns an arrayref [ id, name ] of arrayrefs
513 sub get_field_trials_source_field_trials
{
515 my $schema = $self->bcs_schema;
516 my $field_trial_from_field_trial_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'field_trial_from_field_trial', 'project_relationship')->cvterm_id();
518 my $trial_rs= $self->bcs_schema->resultset('Project::ProjectRelationship')->search({
519 'me.subject_project_id' => $self->get_trial_id(),
520 'me.type_id' => $field_trial_from_field_trial_cvterm_id
522 join => 'object_project', '+select' => ['object_project.name'], '+as' => ['source_trial_name']
526 while (my $r = $trial_rs->next) {
527 push @projects, [ $r->object_project_id, $r->get_column('source_trial_name') ];
532 =head2 function get_field_trials_sourced_from_field_trials()
535 Desc: return associated source field trials for the current field trial
536 Ret: returns an arrayref [ id, name ] of arrayrefs
543 sub get_field_trials_sourced_from_field_trials
{
545 my $schema = $self->bcs_schema;
546 my $field_trial_from_field_trial_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'field_trial_from_field_trial', 'project_relationship')->cvterm_id();
548 my $trial_rs= $self->bcs_schema->resultset('Project::ProjectRelationship')->search({
549 'me.object_project_id' => $self->get_trial_id(),
550 'me.type_id' => $field_trial_from_field_trial_cvterm_id
552 join => 'subject_project', '+select' => ['subject_project.name'], '+as' => ['trial_name']
556 while (my $r = $trial_rs->next) {
557 push @projects, [ $r->subject_project_id, $r->get_column('trial_name') ];
562 =head2 function set_genotyping_trials_from_field_trial()
565 Desc: sets associated genotyping plates for the current field trial
566 Ret: returns an arrayref [ id, name ] of arrayrefs
567 Args: an arrayref [genotyping_trial_id1, genotyping_trial_id2]
573 sub set_genotyping_trials_from_field_trial
{
575 my $source_field_trial_ids = shift;
576 my $schema = $self->bcs_schema;
577 my $genotyping_trial_from_field_trial_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'genotyping_trial_from_field_trial', 'project_relationship')->cvterm_id();
579 foreach (@
$source_field_trial_ids){
581 my $trial_rs= $self->bcs_schema->resultset('Project::ProjectRelationship')->create({
582 'subject_project_id' => $self->get_trial_id(),
583 'object_project_id' => $_,
584 'type_id' => $genotyping_trial_from_field_trial_cvterm_id
588 my $projects = $self->get_genotyping_trials_from_field_trial();
592 =head2 function get_genotyping_trials_from_field_trial()
595 Desc: return associated genotyping plates for the current field trial
596 Ret: returns an arrayref [ id, name ] of arrayrefs
603 sub get_genotyping_trials_from_field_trial
{
605 my $schema = $self->bcs_schema;
606 my $genotyping_trial_from_field_trial_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'genotyping_trial_from_field_trial', 'project_relationship')->cvterm_id();
608 my $trial_rs= $self->bcs_schema->resultset('Project::ProjectRelationship')->search({
609 'me.subject_project_id' => $self->get_trial_id(),
610 'me.type_id' => $genotyping_trial_from_field_trial_cvterm_id
612 join => 'object_project', '+select' => ['object_project.name'], '+as' => ['source_trial_name']
616 while (my $r = $trial_rs->next) {
617 push @projects, [ $r->object_project_id, $r->get_column('source_trial_name') ];
622 =head2 function set_source_field_trials_for_genotyping_trial()
625 Desc: sets associated field trials for the current genotyping plate
626 Ret: returns an arrayref [ id, name ] of arrayrefs
627 Args: an arrayref [field_trial_id1, field_trial_id2]
633 sub set_source_field_trials_for_genotyping_trial
{
635 my $source_field_trial_ids = shift;
636 my $schema = $self->bcs_schema;
637 my $genotyping_trial_from_field_trial_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'genotyping_trial_from_field_trial', 'project_relationship')->cvterm_id();
639 foreach (@
$source_field_trial_ids){
641 my $trial_rs= $self->bcs_schema->resultset('Project::ProjectRelationship')->create({
642 'object_project_id' => $self->get_trial_id(),
643 'subject_project_id' => $_,
644 'type_id' => $genotyping_trial_from_field_trial_cvterm_id
648 my $projects = $self->get_field_trials_source_of_genotyping_trial();
652 =head2 function get_field_trials_source_of_genotyping_trial()
655 Desc: return associated field trials for current genotying trial
656 Ret: returns an arrayref [ id, name ] of arrayrefs
663 sub get_field_trials_source_of_genotyping_trial
{
665 my $schema = $self->bcs_schema;
666 my $genotyping_trial_from_field_trial_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'genotyping_trial_from_field_trial', 'project_relationship')->cvterm_id();
668 my $trial_rs= $self->bcs_schema->resultset('Project::ProjectRelationship')->search({
669 'me.object_project_id' => $self->get_trial_id(),
670 'me.type_id' => $genotyping_trial_from_field_trial_cvterm_id
672 join => 'subject_project', '+select' => ['subject_project.name'], '+as' => ['source_trial_name']
676 while (my $r = $trial_rs->next) {
677 push @projects, [ $r->subject_project_id, $r->get_column('source_trial_name') ];
683 =head2 function set_crossing_trials_from_field_trial()
686 Desc: sets associated crossing trials for the current field trial
687 Ret: returns an arrayref [ id, name ] of arrayrefs
688 Args: an arrayref [crossing_trial_id1, crossing_trial_id2]
694 sub set_crossing_trials_from_field_trial
{
696 my $source_field_trial_ids = shift;
697 my $schema = $self->bcs_schema;
698 my $genotyping_trial_from_field_trial_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'crossing_trial_from_field_trial', 'project_relationship')->cvterm_id();
700 foreach (@
$source_field_trial_ids){
702 my $trial_rs= $self->bcs_schema->resultset('Project::ProjectRelationship')->create({
703 'subject_project_id' => $self->get_trial_id(),
704 'object_project_id' => $_,
705 'type_id' => $genotyping_trial_from_field_trial_cvterm_id
709 my $projects = $self->get_crossing_trials_from_field_trial();
713 =head2 function get_crossing_trials_from_field_trial()
716 Desc: return associated crossing trials for athe current field trial
717 Ret: returns an arrayref [ id, name ] of arrayrefs
724 sub get_crossing_trials_from_field_trial
{
726 my $schema = $self->bcs_schema;
727 my $crossing_trial_from_field_trial_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'crossing_trial_from_field_trial', 'project_relationship')->cvterm_id();
729 my $trial_rs= $self->bcs_schema->resultset('Project::ProjectRelationship')->search({
730 'me.subject_project_id' => $self->get_trial_id(),
731 'me.type_id' => $crossing_trial_from_field_trial_cvterm_id
733 join => 'object_project', '+select' => ['object_project.name'], '+as' => ['source_trial_name']
737 while (my $r = $trial_rs->next) {
738 push @projects, [ $r->object_project_id, $r->get_column('source_trial_name') ];
743 =head2 function get_field_trials_source_of_crossing_trial()
746 Desc: return associated field trials for the current crossing trial
747 Ret: returns an arrayref [ id, name ] of arrayrefs
754 sub get_field_trials_source_of_crossing_trial
{
756 my $schema = $self->bcs_schema;
757 my $crossing_trial_from_field_trial_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'crossing_trial_from_field_trial', 'project_relationship')->cvterm_id();
759 my $trial_rs= $self->bcs_schema->resultset('Project::ProjectRelationship')->search({
760 'me.object_project_id' => $self->get_trial_id(),
761 'me.type_id' => $crossing_trial_from_field_trial_cvterm_id
763 join => 'subject_project', '+select' => ['subject_project.name'], '+as' => ['source_trial_name']
767 while (my $r = $trial_rs->next) {
768 push @projects, [ $r->subject_project_id, $r->get_column('source_trial_name') ];
774 =head2 function get_project_type()
776 Usage: [ $project_type_cvterm_id, $project_type_name ] = $t -> get_project_type();
785 sub get_project_type
{
788 my @project_type_ids = CXGN
::Trial
::get_all_project_types
($self->bcs_schema());
790 my @ids = map { $_->[0] } @project_type_ids;
791 my $rs = $self->bcs_schema()->resultset('Project::Projectprop')->search(
793 type_id
=> { -in => [ @ids ] },
794 project_id
=> $self->get_trial_id()
797 if ($rs->count() > 0) {
798 my $type_id = $rs->first()->type_id();
799 foreach my $pt (@project_type_ids) {
800 if ($type_id == $pt->[0]) {
801 #print STDERR "[get_project_type] ".$pt->[0]." ".$pt->[1]."\n";
811 =head2 function set_project_type()
813 Usage: $t -> set_project_type($type);
822 sub set_project_type
{
825 my $project_id = $self->get_trial_id();
826 my @project_type_ids = CXGN
::Trial
::get_all_project_types
($self->bcs_schema());
829 foreach my $pt (@project_type_ids) {
830 if ($pt->[0] eq $type_id) {
835 my @ids = map { $_->[0] } @project_type_ids;
836 my $rs = $self->bcs_schema()->resultset('Project::Projectprop')->search({
837 type_id
=> { -in => [ @ids ] },
838 project_id
=> $project_id
840 if (my $row = $rs->next()) {
844 my $row = $self->bcs_schema()->resultset('Project::Projectprop')->create({
845 project_id
=> $project_id,
852 sub set_design_type
{
854 my $design_type = shift;
856 my $design_cv_type = $self->bcs_schema->resultset('Cv::Cvterm')->find( { name
=> 'design' });
857 if (!$design_cv_type) {
858 print STDERR
"Design CV term not found. Cannot set design type.\n";
861 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find_or_create(
863 project_id
=> $self->get_trial_id(),
864 type_id
=> $design_cv_type->cvterm_id(),
866 $row->value($design_type);
870 =head2 accessors get_breeding_program(), set_breeding_program()
881 sub get_breeding_program
{
885 my $rs = $self->bcs_schema()->resultset("Project::ProjectRelationship")->search({
886 subject_project_id
=> $self->get_trial_id(),
887 type_id
=> $self->get_breeding_program_trial_relationship_cvterm_id(),
889 if ($rs->count() == 0) {
893 my $bp_rs = $self->bcs_schema()->resultset("Project::Project")->search({
894 project_id
=> $rs->first()->object_project_id()
896 if ($bp_rs->count > 0) {
897 return $bp_rs->first()->name();
903 sub set_breeding_program
{
905 my $breeding_program_id = shift;
906 my $trial_id = $self->get_trial_id();
907 my $type_id = $self->get_breeding_program_trial_relationship_cvterm_id();
910 my $row = $self->bcs_schema->resultset("Project::ProjectRelationship")->find ({
911 subject_project_id
=> $trial_id,
916 $row->object_project_id($breeding_program_id);
920 $row = $self->bcs_schema->resultset("Project::ProjectRelationship")->create ({
921 object_project_id
=> $breeding_program_id,
922 subject_project_id
=> $trial_id,
930 print STDERR
"ERROR: $@\n";
931 return { error
=> "An error occurred while setting the trial's breeding program." };
937 =head2 accessors get_name(), set_name()
940 Desc: retrieve and store project name from/to database
943 Side Effects: setter modifies the database
950 my $row = $self->bcs_schema->resultset('Project::Project')->find( { project_id
=> $self->get_trial_id() });
960 my $row = $self->bcs_schema->resultset('Project::Project')->find( { project_id
=> $self->get_trial_id() });
967 =head2 accessors get_project_start_date(), set_project_start_date()
969 Usage: $t->set_project_start_date("2016/09/17");
970 Desc: sets the projects project_start_date property.
971 The date format in the setter has to be
980 sub get_project_start_date
{
983 my $project_start_date_cvterm_id = $self->get_project_start_date_cvterm_id();
984 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find({
985 project_id
=> $self->get_trial_id(),
986 type_id
=> $project_start_date_cvterm_id,
989 my $calendar_funcs = CXGN
::Calendar
->new({});
990 return $row ?
$calendar_funcs->display_start_date($row->value()) : undef;
993 sub set_project_start_date
{
995 my $project_start_date = shift;
997 my $calendar_funcs = CXGN
::Calendar
->new({});
998 if (my $project_start_date_event = $calendar_funcs->check_value_format($project_start_date) ) {
999 my $project_start_date_cvterm_id = $self->get_project_start_date_cvterm_id();
1000 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find_or_create({
1001 project_id
=> $self->get_trial_id(),
1002 type_id
=> $project_start_date_cvterm_id,
1005 $row->value($project_start_date_event);
1008 print STDERR
"date format did not pass check while preparing to set project start date: $project_start_date \n";
1012 =head2 accessors get_harvest_date(), set_harvest_date()
1014 Usage: $t->set_harvest_date("2016/09/17");
1015 Desc: sets the projects harvest_date property.
1016 The date format in the setter has to be
1025 sub get_harvest_date
{
1028 my $harvest_date_cvterm_id = $self->get_harvest_date_cvterm_id();
1029 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find(
1031 project_id
=> $self->get_trial_id(),
1032 type_id
=> $harvest_date_cvterm_id,
1035 my $calendar_funcs = CXGN
::Calendar
->new({});
1038 my $harvest_date = $calendar_funcs->display_start_date($row->value());
1039 return $harvest_date;
1045 sub set_harvest_date
{
1047 my $harvest_date = shift;
1049 my $calendar_funcs = CXGN
::Calendar
->new({});
1051 if (my $harvest_event = $calendar_funcs->check_value_format($harvest_date) ) {
1053 my $harvest_date_cvterm_id = $self->get_harvest_date_cvterm_id();
1055 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find_or_create(
1057 project_id
=> $self->get_trial_id(),
1058 type_id
=> $harvest_date_cvterm_id,
1061 $row->value($harvest_event);
1064 print STDERR
"date format did not pass check while preparing to set harvest date: $harvest_date \n";
1068 sub remove_harvest_date
{
1070 my $harvest_date = shift;
1072 my $calendar_funcs = CXGN
::Calendar
->new({});
1073 if (my $harvest_event = $calendar_funcs->check_value_format($harvest_date) ) {
1075 my $harvest_date_cvterm_id = $self->get_harvest_date_cvterm_id();
1077 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find_or_create(
1079 project_id
=> $self->get_trial_id(),
1080 type_id
=> $harvest_date_cvterm_id,
1081 value
=> $harvest_event,
1085 print STDERR
"Removing harvest date $harvest_event from trial ".$self->get_trial_id()."\n";
1089 print STDERR
"date format did not pass check while preparing to delete harvest date: $harvest_date \n";
1094 =head2 accessors get_planting_date(), set_planting_date()
1105 sub get_planting_date
{
1108 my $planting_date_cvterm_id = $self->get_planting_date_cvterm_id();
1109 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find(
1111 project_id
=> $self->get_trial_id(),
1112 type_id
=> $planting_date_cvterm_id,
1115 my $calendar_funcs = CXGN
::Calendar
->new({});
1118 my $harvest_date = $calendar_funcs->display_start_date($row->value());
1119 return $harvest_date;
1125 sub set_planting_date
{
1127 my $planting_date = shift;
1129 my $calendar_funcs = CXGN
::Calendar
->new({});
1131 if (my $planting_event = $calendar_funcs->check_value_format($planting_date) ) {
1133 my $planting_date_cvterm_id = $self->get_planting_date_cvterm_id();
1135 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find_or_create(
1137 project_id
=> $self->get_trial_id(),
1138 type_id
=> $planting_date_cvterm_id,
1141 $row->value($planting_event);
1144 print STDERR
"date format did not pass check while preparing to set planting date: $planting_date \n";
1148 sub remove_planting_date
{
1150 my $planting_date = shift;
1152 my $calendar_funcs = CXGN
::Calendar
->new({});
1153 if (my $planting_event = $calendar_funcs->check_value_format($planting_date) ) {
1155 my $planting_date_cvterm_id = $self->get_planting_date_cvterm_id();
1157 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find_or_create(
1159 project_id
=> $self->get_trial_id(),
1160 type_id
=> $planting_date_cvterm_id,
1161 value
=> $planting_event,
1165 print STDERR
"Removing planting date $planting_event from trial ".$self->get_trial_id()."\n";
1169 print STDERR
"date format did not pass check while preparing to delete planting date: $planting_date \n";
1174 =head2 accessors get_temperature_averaged_gdd(), set_temperature_averaged_gdd()
1185 sub get_temperature_averaged_gdd
{
1188 my $temperature_averaged_gdd_cvterm_id = $self->get_temperature_averaged_gdd_cvterm_id();
1189 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find({
1190 project_id
=> $self->get_trial_id(),
1191 type_id
=> $temperature_averaged_gdd_cvterm_id,
1201 sub set_temperature_averaged_gdd
{
1203 my $temperature_averaged_gdd = shift;
1205 my $temperature_averaged_gdd_cvterm_id = $self->get_temperature_averaged_gdd_cvterm_id();
1206 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find_or_create({
1207 project_id
=> $self->get_trial_id(),
1208 type_id
=> $temperature_averaged_gdd_cvterm_id,
1210 $row->value($temperature_averaged_gdd);
1214 sub remove_temperature_averaged_gdd
{
1216 my $temperature_averaged_gdd = shift;
1218 my $temperature_averaged_gdd_cvterm_id = $self->get_temperature_averaged_gdd_cvterm_id();
1219 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find_or_create({
1220 project_id
=> $self->get_trial_id(),
1221 type_id
=> $temperature_averaged_gdd_cvterm_id,
1222 value
=> $temperature_averaged_gdd,
1225 print STDERR
"Removing $temperature_averaged_gdd from trial ".$self->get_trial_id()."\n";
1230 sub get_temperature_averaged_gdd_cvterm_id
{
1232 return SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'drone_run_averaged_temperature_growing_degree_days', 'project_property')->cvterm_id();
1235 =head2 accessors get_related_time_cvterms_json(), set_related_time_cvterms_json()
1246 sub get_related_time_cvterms_json
{
1249 my $cvterm_id = $self->get_related_time_cvterms_json_cvterm_id();
1250 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find({
1251 project_id
=> $self->get_trial_id(),
1252 type_id
=> $cvterm_id,
1262 sub set_related_time_cvterms_json
{
1264 my $related_time_terms_json = shift;
1266 my $cvterm_id = $self->get_related_time_cvterms_json_cvterm_id();
1267 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find_or_create({
1268 project_id
=> $self->get_trial_id(),
1269 type_id
=> $cvterm_id,
1271 $row->value($related_time_terms_json);
1275 sub remove_related_time_cvterms_json
{
1277 my $related_time_terms_json = shift;
1279 my $cvterm_id = $self->get_related_time_cvterms_json_cvterm_id();
1280 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find_or_create({
1281 project_id
=> $self->get_trial_id(),
1282 type_id
=> $cvterm_id,
1283 value
=> $related_time_terms_json,
1286 print STDERR
"Removing $related_time_terms_json from trial ".$self->get_trial_id()."\n";
1291 sub get_related_time_cvterms_json_cvterm_id
{
1293 return SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'drone_run_related_time_cvterms_json', 'project_property')->cvterm_id();
1296 =head2 function get_management_factor_date()
1298 Usage: $trial->get_management_factor_date();
1299 Desc: Field management factors are a project and are therefore instantiated with CXGN::Trial. this gets the date projectprop
1307 sub get_management_factor_date
{
1310 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find({
1311 project_id
=> $self->get_trial_id(),
1312 type_id
=> $self->get_mangement_factor_date_cvterm_id()
1314 my $calendar_funcs = CXGN
::Calendar
->new({});
1317 return $calendar_funcs->display_start_date($row->value());
1323 sub set_management_factor_date
{
1325 my $management_factor_date = shift;
1327 my $calendar_funcs = CXGN
::Calendar
->new({});
1329 if (my $management_factor_event = $calendar_funcs->check_value_format($management_factor_date) ) {
1330 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find_or_create({
1331 project_id
=> $self->get_trial_id(),
1332 type_id
=> $self->get_mangement_factor_date_cvterm_id()
1335 $row->value($management_factor_event);
1338 print STDERR
"date format did not pass check while preparing to set management factor date: $management_factor_date \n";
1342 sub get_mangement_factor_date_cvterm_id
{
1344 return SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'management_factor_date', 'project_property')->cvterm_id();
1347 sub get_mangement_factor_type_cvterm_id
{
1349 return SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'management_factor_type', 'project_property')->cvterm_id();
1352 sub get_management_factor_type
{
1355 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find({
1356 project_id
=> $self->get_trial_id(),
1357 type_id
=> $self->get_mangement_factor_type_cvterm_id()
1361 return $row->value();
1367 =head2 accessors get_phenotypes_fully_uploaded(), set_phenotypes_fully_uploaded()
1369 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
1378 sub get_phenotypes_fully_uploaded
{
1380 return $self->_get_projectprop('phenotypes_fully_uploaded');
1383 sub set_phenotypes_fully_uploaded
{
1386 $self->_set_projectprop('phenotypes_fully_uploaded', $value);
1389 =head2 accessors get_raw_data_link(), set_raw_data_link()
1391 Usage: For genotyping plates, a genotyping facility can be set as a projectprop value e.g. 'igd'
1400 sub get_raw_data_link
{
1402 return $self->_get_projectprop('raw_data_link');
1405 sub set_raw_data_link
{
1408 $self->_set_projectprop('raw_data_link', $value);
1412 =head2 accessors get_genotyping_facility(), set_genotyping_facility()
1414 Usage: For genotyping plates, a genotyping facility can be set as a projectprop value e.g. 'igd'
1423 sub get_genotyping_facility
{
1425 return $self->_get_projectprop('genotyping_facility');
1428 sub set_genotyping_facility
{
1431 $self->_set_projectprop('genotyping_facility', $value);
1434 =head2 accessors get_genotyping_facility_submitted(), set_genotyping_facility_submitted()
1436 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'
1445 sub get_genotyping_facility_submitted
{
1447 return $self->_get_projectprop('genotyping_facility_submitted');
1450 sub set_genotyping_facility_submitted
{
1453 $self->_set_projectprop('genotyping_facility_submitted', $value);
1456 =head2 accessors get_genotyping_facility_status(), set_genotyping_facility_status()
1458 Usage: For genotyping plates, if a genotyping plate has been submitted to genotyping facility, the status of that plate can be set here
1467 sub get_genotyping_facility_status
{
1469 return $self->_get_projectprop('genotyping_facility_status');
1472 sub set_genotyping_facility_status
{
1475 $self->_set_projectprop('genotyping_facility_status', $value);
1478 =head2 accessors get_genotyping_plate_format(), set_genotyping_plate_format()
1480 Usage: For genotyping plates, this records if it is 96 wells or 384 or other
1489 sub get_genotyping_plate_format
{
1491 return $self->_get_projectprop('genotyping_plate_format');
1494 sub set_genotyping_plate_format
{
1497 $self->_set_projectprop('genotyping_plate_format', $value);
1500 =head2 accessors get_genotyping_plate_sample_type(), set_genotyping_plate_sample_type()
1502 Usage: For genotyping plates, this records sample type of plate e.g. DNA
1511 sub get_genotyping_plate_sample_type
{
1513 return $self->_get_projectprop('genotyping_plate_sample_type');
1516 sub set_genotyping_plate_sample_type
{
1519 $self->_set_projectprop('genotyping_plate_sample_type', $value);
1522 =head2 accessors get_field_trial_is_planned_to_be_genotyped(), set_field_trial_is_planned_to_be_genotyped()
1524 Usage: For field trials, this records whether the trial will be genotyped
1533 sub get_field_trial_is_planned_to_be_genotyped
{
1535 return $self->_get_projectprop('field_trial_is_planned_to_be_genotyped');
1538 sub set_field_trial_is_planned_to_be_genotyped
{
1541 $self->_set_projectprop('field_trial_is_planned_to_be_genotyped', $value);
1544 =head2 accessors get_field_trial_is_planned_to_cross(), set_field_trial_is_planned_to_cross()
1546 Usage: For field trials, this records whether the trial will be involved in crosses
1555 sub get_field_trial_is_planned_to_cross
{
1557 return $self->_get_projectprop('field_trial_is_planned_to_cross');
1560 sub set_field_trial_is_planned_to_cross
{
1563 $self->_set_projectprop('field_trial_is_planned_to_cross', $value);
1566 =head2 accessors get_plot_width(), set_plot_width()
1568 Usage: For field trials, this records plot width in meters
1577 sub get_plot_width
{
1579 return $self->_get_projectprop('plot_width');
1582 sub set_plot_width
{
1585 $self->_set_projectprop('plot_width', $value);
1588 =head2 accessors get_plot_length(), set_plot_length()
1590 Usage: For field trials, this records plot length in meters
1599 sub get_plot_length
{
1601 return $self->_get_projectprop('plot_length');
1604 sub set_plot_length
{
1607 $self->_set_projectprop('plot_length', $value);
1610 =head2 accessors get_field_size(), set_field_size()
1612 Usage: For field trials, this recordsfield size in hectares
1621 sub get_field_size
{
1623 return $self->_get_projectprop('field_size');
1626 sub set_field_size
{
1629 $self->_set_projectprop('field_size', $value);
1633 sub _get_projectprop
{
1636 my $cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, $term, 'project_property')->cvterm_id;
1637 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find({
1638 project_id
=> $self->get_trial_id(),
1639 type_id
=> $cvterm_id,
1649 sub _set_projectprop
{
1653 my $cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, $term, 'project_property')->cvterm_id;
1654 my $row = $self->bcs_schema->resultset('Project::Projectprop')->find_or_create({
1655 project_id
=> $self->get_trial_id(),
1656 type_id
=> $cvterm_id,
1658 $row->value($value);
1662 =head2 function delete_phenotype_data()
1673 # note: you may need to delete the metadata before deleting the phenotype data (see function).
1674 # this function has a test!
1676 sub delete_phenotype_data
{
1678 my $basepath = shift;
1683 my $temp_file_nd_experiment_id = shift;
1685 my $trial_id = $self->get_trial_id();
1686 my $nd_experiment_type_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'phenotyping_experiment', 'experiment_type')->cvterm_id();
1689 SELECT phenotype_id, nd_experiment_id, file_id
1691 JOIN nd_experiment_phenotype using(phenotype_id)
1692 JOIN nd_experiment using(nd_experiment_id)
1693 JOIN nd_experiment_stock using(nd_experiment_id)
1694 JOIN nd_experiment_project using(nd_experiment_id)
1695 LEFT JOIN phenome.nd_experiment_md_files using(nd_experiment_id)
1696 JOIN stock using(stock_id)
1697 WHERE project_id = $trial_id
1698 AND nd_experiment.type_id = $nd_experiment_type_id;
1700 my $h = $self->bcs_schema->storage->dbh()->prepare($q_search);
1703 my %phenotype_ids_and_nd_experiment_ids_to_delete;
1704 while (my ($phenotype_id, $nd_experiment_id, $file_id) = $h->fetchrow_array()) {
1705 push @
{$phenotype_ids_and_nd_experiment_ids_to_delete{phenotype_ids
}}, $phenotype_id;
1706 push @
{$phenotype_ids_and_nd_experiment_ids_to_delete{nd_experiment_ids
}}, $nd_experiment_id;
1708 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);
1712 sub delete_phenotype_values_and_nd_experiment_md_values
{
1717 my $temp_file_nd_experiment_id = shift;
1718 my $basepath = shift;
1720 my $phenotype_ids_and_nd_experiment_ids_to_delete = shift;
1723 my $phenotype_id_sql = join (",", @
{$phenotype_ids_and_nd_experiment_ids_to_delete->{phenotype_ids
}});
1724 my $q_pheno_delete = "DELETE FROM phenotype WHERE phenotype_id IN ($phenotype_id_sql);";
1725 my $h2 = $schema->storage->dbh()->prepare($q_pheno_delete);
1727 my $nd_experiment_id_sql = join (",", @
{$phenotype_ids_and_nd_experiment_ids_to_delete->{nd_experiment_ids
}});
1728 my $q_nd_exp_files_delete = "DELETE FROM phenome.nd_experiment_md_files WHERE nd_experiment_id IN ($nd_experiment_id_sql);";
1729 my $h3 = $schema->storage->dbh()->prepare($q_nd_exp_files_delete);
1731 my $q_nd_exp_files_images_delete = "DELETE FROM phenome.nd_experiment_md_images WHERE nd_experiment_id IN ($nd_experiment_id_sql);";
1732 my $h4 = $schema->storage->dbh()->prepare($q_nd_exp_files_images_delete);
1735 open (my $fh, ">", $temp_file_nd_experiment_id ) || die ("\nERROR: the file $temp_file_nd_experiment_id could not be found\n" );
1736 foreach (@
{$phenotype_ids_and_nd_experiment_ids_to_delete->{nd_experiment_ids
}}) {
1741 my $async_delete = CXGN
::Tools
::Run
->new();
1742 $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");
1744 print STDERR
"DELETED ".scalar(@
{$phenotype_ids_and_nd_experiment_ids_to_delete->{phenotype_ids
}})." Phenotype Values and nd_experiment_md_file_links (nd_experiment entries may still be in deletion in asynchronous process.)\n";
1749 $schema->txn_do($coderef);
1751 print STDERR
"ERROR: $_\n";
1757 =head2 function delete_field_layout()
1769 # this function has a test!
1771 sub delete_field_layout
{
1774 my $trial_id = $self->get_trial_id();
1776 if (scalar(@
{$self->get_genotyping_trials_from_field_trial}) > 0) {
1777 return 'This field trial has been linked to genotyping trials already, and cannot be easily deleted.';
1779 if (scalar(@
{$self->get_field_trials_source_of_genotyping_trial}) > 0) {
1780 return 'This genotyping trial has been linked to field trials already, and cannot be easily deleted.';
1782 if (scalar(@
{$self->get_crossing_trials_from_field_trial}) >0) {
1783 return 'This field trial has been linked to crossing trials already, and cannot be easily deleted.';
1785 if (scalar(@
{$self->get_field_trials_source_of_crossing_trial}) >0) {
1786 return 'This crossing trial has been linked to field trials already, and cannot be easily deleted.';
1789 # Note: metadata entries need to be deleted separately using delete_metadata()
1793 $self->bcs_schema()->txn_do(
1795 #print STDERR "DELETING FIELD LAYOUT FOR TRIAL $trial_id...\n";
1796 $self->_delete_field_layout_experiment();
1797 #print STDERR "DELETE MANAGEMENT FACTORS FOR TRIAL $trial_id...\n";
1798 $self->_delete_management_factors_experiments();
1803 print STDERR
"ERROR $@\n";
1804 return "An error occurred: $@\n";
1810 =head2 function get_phenotype_metadata()
1812 Usage: $trial->get_phenotype_metadata();
1813 Desc: retrieves metadata.md_file entries for this trial. These entries are created during StorePhenotypes
1821 sub get_phenotype_metadata
{
1823 my $trial_id = $self->get_trial_id();
1826 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";
1827 my $h = $self->bcs_schema->storage()->dbh()->prepare($q);
1828 $h->execute($trial_id);
1830 while (my ($file_id, $create_date, $person_id, $username, $basename, $dirname, $filetype) = $h->fetchrow_array()) {
1831 $file_info{$file_id} = [$file_id, $create_date, $person_id, $username, $basename, $dirname, $filetype];
1833 foreach (keys %file_info){
1834 push @file_array, $file_info{$_};
1836 return \
@file_array;
1839 =head2 function delete_phenotype_metadata()
1841 Usage: $trial->delete_phenotype_metadata($metadata_schema, $phenome_schema);
1842 Desc: obsoletes the metadata entries for this trial.
1850 sub delete_phenotype_metadata
{
1852 my $metadata_schema = shift;
1853 my $phenome_schema = shift;
1855 if (!$metadata_schema || !$phenome_schema) { die "Need metadata schema parameter\n"; }
1857 my $trial_id = $self->get_trial_id();
1859 #print STDERR "Deleting metadata for trial $trial_id...\n";
1861 # first, deal with entries in the md_metadata table, which may reference nd_experiment (through linking table)
1863 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=?";
1864 my $h = $self->bcs_schema->storage()->dbh()->prepare($q);
1865 $h->execute($trial_id);
1867 while (my ($md_id) = $h->fetchrow_array()) {
1868 #print STDERR "Associated metadata id: $md_id\n";
1869 my $mdmd_row = $metadata_schema->resultset("MdMetadata")->find( { metadata_id
=> $md_id } );
1871 #print STDERR "Obsoleting $md_id...\n";
1873 $mdmd_row -> update
( { obsolete
=> 1 });
1877 #print STDERR "Deleting the entries in the linking table...\n";
1879 # delete the entries from the linking table...
1880 $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=?";
1881 $h = $self->bcs_schema->storage()->dbh()->prepare($q);
1882 $h->execute($trial_id);
1884 while (my ($file_id) = $h->fetchrow_array()) {
1885 print STDERR
"trying to delete association for file with id $file_id...\n";
1886 my $ndemdf_rs = $phenome_schema->resultset("NdExperimentMdFiles")->search( { file_id
=>$file_id });
1887 print STDERR
"Deleting md_files linking table entries...\n";
1888 foreach my $row ($ndemdf_rs->all()) {
1889 print STDERR
"DELETING !!!!\n";
1897 =head2 function delete_metadata()
1899 Usage: $trial->delete_metadata();
1900 Desc: obsoletes the metadata entries for this trial.
1908 sub delete_metadata
{
1910 my $metadata_schema = $self->metadata_schema;
1911 my $phenome_schema = $self->phenome_schema;
1913 if (!$metadata_schema || !$phenome_schema) { die "Need metadata schema parameter\n"; }
1915 my $trial_id = $self->get_trial_id();
1917 if (scalar(@
{$self->get_genotyping_trials_from_field_trial}) > 0) {
1918 return 'This field trial has been linked to genotyping trials already, and cannot be easily deleted.';
1920 if (scalar(@
{$self->get_field_trials_source_of_genotyping_trial}) > 0) {
1921 return 'This genotyping trial has been linked to field trials already, and cannot be easily deleted.';
1923 if (scalar(@
{$self->get_crossing_trials_from_field_trial}) >0) {
1924 return 'This field trial has been linked to crossing trials already, and cannot be easily deleted.';
1926 if (scalar(@
{$self->get_field_trials_source_of_crossing_trial}) >0) {
1927 return 'This crossing trial has been linked to field trials already, and cannot be easily deleted.';
1930 #print STDERR "Deleting metadata for trial $trial_id...\n";
1932 # first, deal with entries in the md_metadata table, which may reference nd_experiment (through linking table)
1934 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=?";
1935 my $h = $self->bcs_schema->storage()->dbh()->prepare($q);
1936 $h->execute($trial_id);
1938 while (my ($md_id) = $h->fetchrow_array()) {
1939 #print STDERR "Associated metadata id: $md_id\n";
1940 my $mdmd_row = $metadata_schema->resultset("MdMetadata")->find( { metadata_id
=> $md_id } );
1942 #print STDERR "Obsoleting $md_id...\n";
1944 $mdmd_row -> update
( { obsolete
=> 1 });
1948 #print STDERR "Deleting the entries in the linking table...\n";
1950 # delete the entries from the linking table... (left joins are due to sometimes missing md_file entries)
1951 $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=?";
1952 $h = $self->bcs_schema->storage()->dbh()->prepare($q);
1953 $h->execute($trial_id);
1955 while (my ($file_id) = $h->fetchrow_array()) {
1956 print STDERR
"trying to delete association for file with id $file_id...\n";
1957 my $ndemdf_rs = $phenome_schema->resultset("NdExperimentMdFiles")->search( { file_id
=>$file_id });
1958 print STDERR
"Deleting md_files linking table entries...\n";
1959 foreach my $row ($ndemdf_rs->all()) {
1960 print STDERR
"DELETING !!!!\n";
1967 sub _delete_field_layout_experiment
{
1970 my $trial_id = $self->get_trial_id();
1972 print STDERR
"_delete_field_layout_experiment...\n";
1974 # check if there are still associated phenotypes...
1976 if ($self->phenotype_count() > 0) {
1977 print STDERR
"Attempt to delete field layout that still has associated phenotype data.\n";
1978 die "cannot delete because of associated phenotypes\n";
1979 return { error
=> "Trial still has associated phenotyping experiment, cannot delete." };
1982 my $field_layout_type_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'field_layout', 'experiment_type')->cvterm_id();
1983 my $genotyping_layout_type_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'genotyping_layout', 'experiment_type')->cvterm_id();
1985 my $layout_design = $self->get_layout->get_design;
1987 while( my($plot_num, $design_info) = each %$layout_design){
1988 my $plot_id = $design_info->{plot_id
}; #this includes the "tissue_sample" in "genotyping_layout"
1989 my @plant_ids = $design_info->{plant_ids
} ? @
{$design_info->{plant_ids
}} : ();
1990 my @subplot_ids = $design_info->{subplot_ids
} ? @
{$design_info->{subplot_ids
}} : ();
1991 my @tissue_sample_ids = $design_info->{tissue_sample_ids
} ? @
{$design_info->{tissue_sample_ids
}} : ();
1992 push @all_stock_ids, $plot_id;
1993 push @all_stock_ids, @plant_ids;
1994 push @all_stock_ids, @subplot_ids;
1995 push @all_stock_ids, @tissue_sample_ids;
1998 #print STDERR Dumper \@all_stock_ids;
1999 my $stock_delete_rs = $self->bcs_schema->resultset('Stock::Stock')->search({stock_id
=>{'-in'=>\
@all_stock_ids}});
2000 while (my $r = $stock_delete_rs->next){
2004 my $has_plants = $self->has_plant_entries();
2005 my $has_subplots = $self->has_subplot_entries();
2006 my $has_tissues = $self->has_tissue_sample_entries();
2009 my $has_plants_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'project_has_plant_entries', 'project_property' )->cvterm_id();
2010 my $has_plants_prop = $self->bcs_schema->resultset("Project::Projectprop")->find({ type_id
=> $has_plants_cvterm_id, project_id
=> $trial_id });
2011 $has_plants_prop->delete();
2013 if ($has_subplots) {
2014 my $has_subplots_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'project_has_subplot_entries', 'project_property' )->cvterm_id();
2015 my $has_subplots_prop = $self->bcs_schema->resultset("Project::Projectprop")->find({ type_id
=> $has_subplots_cvterm_id, project_id
=> $trial_id });
2016 $has_subplots_prop->delete();
2019 my $has_tissues_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'project_has_tissue_sample_entries', 'project_property' )->cvterm_id();
2020 my $has_tissues_prop = $self->bcs_schema->resultset("Project::Projectprop")->find({ type_id
=> $has_tissues_cvterm_id, project_id
=> $trial_id });
2021 $has_tissues_prop->delete();
2024 my $trial_layout_json_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'trial_layout_json', 'project_property')->cvterm_id();
2025 my $has_cached_layout_prop = $self->bcs_schema->resultset("Project::Projectprop")->find({ type_id
=> $trial_layout_json_cvterm_id, project_id
=> $trial_id });
2026 if ($has_cached_layout_prop){
2027 $has_cached_layout_prop->delete();
2030 my $nde_rs = $self->bcs_schema()->resultset("NaturalDiversity::NdExperiment")->search({ 'me.type_id'=>[$field_layout_type_id, $genotyping_layout_type_id], 'project.project_id'=>$trial_id }, {'join'=>{'nd_experiment_projects'=>'project'}});
2031 if ($nde_rs->count != 1){
2032 die "Project $trial_id does not have exactly one ndexperiment of type field_layout or genotyping_layout!"
2034 while( my $r = $nde_rs->next){
2038 #return { success => $plots_deleted };
2039 return { success
=> 1 };
2042 sub _delete_management_factors_experiments
{
2044 my $management_factor_type_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'treatment_experiment', 'experiment_type')->cvterm_id();
2045 my $management_factors = $self->get_treatments;
2046 foreach (@
$management_factors){
2047 my $m = CXGN
::Trial
->new({
2048 bcs_schema
=> $self->bcs_schema,
2049 metadata_schema
=> $self->metadata_schema,
2050 phenome_schema
=> $self->phenome_schema,
2053 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'}});
2054 if ($nde_rs->count != 1){
2055 die "Management factor ".$m->get_name." does not have exactly one ndexperiment of type treatment_experiment!"
2057 while( my $r = $nde_rs->next){
2060 $m->delete_project_entry;
2062 return { success
=> 1 };
2065 =head2 function delete_project_entry()
2076 sub delete_project_entry
{
2079 if ($self->phenotype_count() > 0) {
2080 print STDERR
"Cannot delete trial with associated phenotypes.\n";
2084 if (scalar(@
{$self->get_genotyping_trials_from_field_trial}) > 0) {
2085 return 'This field trial has been linked to genotyping trials already, and cannot be easily deleted.';
2087 if (scalar(@
{$self->get_field_trials_source_of_genotyping_trial}) > 0) {
2088 return 'This genotyping trial has been linked to field trials already, and cannot be easily deleted.';
2090 if (scalar(@
{$self->get_crossing_trials_from_field_trial}) >0) {
2091 return 'This field trial has been linked to crossing trials already, and cannot be easily deleted.';
2093 if (scalar(@
{$self->get_field_trials_source_of_crossing_trial}) >0) {
2094 return 'This crossing trial has been linked to field trials already, and cannot be easily deleted.';
2098 my $row = $self->bcs_schema->resultset("Project::Project")->find( { project_id
=> $self->get_trial_id() });
2100 print STDERR
"deleted project ".$self->get_trial_id."\n";
2103 print STDERR
"An error occurred during deletion: $@\n";
2108 =head2 function phenotype_count()
2111 Desc: The number of phenotype measurements associated with this trial
2120 sub phenotype_count
{
2122 my $phenotyping_experiment_type_id = $self->bcs_schema->resultset("Cv::Cvterm")->find( { name
=> 'phenotyping_experiment' })->cvterm_id();
2124 my $q = "SELECT count(phenotype_id)
2126 JOIN nd_experiment_phenotype using(phenotype_id)
2127 JOIN nd_experiment_project using(nd_experiment_id)
2128 JOIN nd_experiment using(nd_experiment_id)
2129 JOIN project using(project_id)
2130 WHERE nd_experiment.type_id = $phenotyping_experiment_type_id
2131 AND project_id = ?;";
2132 my $h = $self->bcs_schema->storage->dbh()->prepare($q);
2133 $h->execute($self->get_trial_id());
2134 my ($count) = $h->fetchrow_array();
2139 =head2 function total_phenotypes()
2142 Desc: returns the total number of phenotype measurements
2143 associated with the trial
2151 sub total_phenotypes
{
2154 my $pt_rs = $self->bcs_schema()->resultset("Phenotype::Phenotype")->search( { });
2155 return $pt_rs->count();
2158 =head2 function add_additional_uploaded_file()
2160 Usage: $trial->add_additional_uploaded_file();
2161 Desc: adds metadata.md_file entry for additional_files_uploaded to trial
2169 sub add_additional_uploaded_file
{
2171 my $user_id = shift;
2172 my $archived_filename_with_path = shift;
2173 my $md5checksum = shift;
2174 my $result = $self->get_nd_experiment_id();
2175 if ($result->{error
}){
2176 return {error
=> $result->{error
} };
2178 my $nd_experiment_id = $result->{nd_experiment_id
};
2180 my $md_row = $self->metadata_schema->resultset("MdMetadata")->create({create_person_id
=> $user_id});
2182 my $file_row = $self->metadata_schema->resultset("MdFiles")
2184 basename
=> basename
($archived_filename_with_path),
2185 dirname
=> dirname
($archived_filename_with_path),
2186 filetype
=> 'trial_additional_file_upload',
2187 md5checksum
=> $md5checksum,
2188 metadata_id
=> $md_row->metadata_id(),
2190 my $file_id = $file_row->file_id();
2191 my $experiment_file = $self->phenome_schema->resultset("NdExperimentMdFiles")
2193 nd_experiment_id
=> $nd_experiment_id,
2194 file_id
=> $file_id,
2197 return {success
=> 1, file_id
=>$file_id};
2200 =head2 function get_additional_uploaded_files()
2202 Usage: $trial->get_additional_uploaded_files();
2203 Desc: retrieves metadata.md_file entries for additional_files_uploaded to trial. these entries are created from add_additional_uploaded_file
2211 sub get_additional_uploaded_files
{
2213 my $trial_id = $self->get_trial_id();
2216 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";
2217 my $h = $self->bcs_schema->storage()->dbh()->prepare($q);
2218 $h->execute($trial_id);
2220 while (my ($file_id, $create_date, $person_id, $username, $basename, $dirname, $filetype) = $h->fetchrow_array()) {
2221 $file_info{$file_id} = [$file_id, $create_date, $person_id, $username, $basename, $dirname, $filetype];
2223 foreach (keys %file_info){
2224 push @file_array, $file_info{$_};
2226 return \
@file_array;
2229 =head2 function get_phenotypes_for_trait($trait_id)
2232 Desc: returns the measurements for the given trait in this trial as an array of values, e.g. [2.1, 2, 50]
2240 sub get_phenotypes_for_trait
{
2242 my $trait_id = shift;
2243 my $stock_type = shift;
2245 my $dbh = $self->bcs_schema->storage()->dbh();
2246 #my $schema = $self->bcs_schema();
2249 my $join_string = '';
2250 my $where_string = '';
2252 my $stock_type_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, $stock_type, 'stock_type')->cvterm_id();
2253 $join_string = 'JOIN nd_experiment_stock USING(nd_experiment_id) JOIN stock USING(stock_id)';
2254 $where_string = "stock.type_id=$stock_type_id and";
2256 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;";
2257 $h = $dbh->prepare($q);
2259 my $numeric_regex = '^-?[0-9]+([,.][0-9]+)?$';
2260 $h->execute($self->get_trial_id(), $trait_id, $numeric_regex );
2261 while (my ($value) = $h->fetchrow_array()) {
2262 push @data, $value + 0;
2267 =head2 function get_stock_phenotypes_for_traits(\@trait_id, 'all', ['plot_of','plant_of'], 'accession', 'subject')
2270 Desc: returns all observations for the given traits in this trial
2271 Ret: arrayref of [[ $stock_id, $stock_name, $trait_id, $trait_name, $phenotype_id, $pheno_uniquename, $uploader_id, $value, $rel_stock_id, $rel_stock_name ], [], ...]
2272 Args: trait_ids : arrayref of cvterm_ids
2273 stock_type: the stock type that the phenotype is associated to. 'plot', or 'plant', or 'all'
2274 stock_relationships: for fetching stock_relationships of the phenotyped stock. arrayref of relationships. e.g. ['plot_of', 'plant_of'].
2275 relationship_stock_type: the associated stock_type from the stock_relationship. 'plot', or 'plant'
2276 subject_or_object: whether the stock_relationship join should be done from the subject or object side. 'subject', or 'object'
2282 sub get_stock_phenotypes_for_traits
{
2284 my $trait_ids = shift;
2285 my $stock_type = shift; #plot, plant, all
2286 my $stock_relationships = shift; #arrayref. plot_of, plant_of
2287 my $relationship_stock_type = shift; #plot, plant
2288 my $subject_or_object = shift;
2290 #$self->bcs_schema->storage->debug(1);
2291 my $dbh = $self->bcs_schema->storage()->dbh();
2292 my $where_clause = "WHERE project_id=? and b.cvterm_id = ? and phenotype.value~? ";
2293 my $phenotyping_experiment_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'phenotyping_experiment', 'experiment_type')->cvterm_id();
2295 if (scalar(@
$trait_ids)>0){
2296 my $sql_trait_ids = join ("," , @
$trait_ids);
2297 $where_clause .= "and a.cvterm_id IN ($sql_trait_ids) ";
2300 my $relationship_join = '';
2301 if ($subject_or_object eq 'object') {
2302 $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) ';
2303 } elsif ($subject_or_object eq 'subject') {
2304 $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) ';
2306 if ($stock_type ne 'all') {
2307 my $stock_type_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema(), $stock_type, 'stock_type')->cvterm_id();
2308 $where_clause .= "and stock.type_id=$stock_type_cvterm_id ";
2311 foreach (@
$stock_relationships) {
2312 my $stock_relationship_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema(), $_, 'stock_relationship')->cvterm_id();
2313 push @stock_rel_or, "stock_relationship.type_id=$stock_relationship_cvterm_id";
2315 my $stock_rel_or_sql = join (" OR " , @stock_rel_or);
2316 if ($stock_rel_or_sql) {
2317 $where_clause .= "and ($stock_rel_or_sql) ";
2319 my $rel_stock_type_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema(), $relationship_stock_type, 'stock_type')->cvterm_id();
2320 $where_clause .= "and rel_stock.type_id=$rel_stock_type_cvterm_id ";
2322 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
2324 JOIN dbxref ON (a.dbxref_id = dbxref.dbxref_id)
2325 JOIN db USING(db_id)
2326 JOIN phenotype ON (a.cvterm_id=cvalue_id)
2327 JOIN nd_experiment_phenotype USING(phenotype_id)
2328 JOIN nd_experiment_project USING(nd_experiment_id)
2329 JOIN nd_experiment_stock USING(nd_experiment_id)
2330 JOIN cvterm as b ON (b.cvterm_id=nd_experiment_stock.type_id)
2331 JOIN stock USING(stock_id)
2332 JOIN cvterm as stock_type ON (stock_type.cvterm_id=stock.type_id)
2335 ORDER BY stock.stock_id;";
2337 print STDERR
"QUERY = $q\n";
2338 my $h = $dbh->prepare($q);
2340 my $numeric_regex = '^-?[0-9]+([,.][0-9]+)?$';
2341 $h->execute($self->get_trial_id(), $phenotyping_experiment_cvterm, $numeric_regex );
2342 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()) {
2343 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];
2348 =head2 function get_traits_assayed()
2351 Desc: returns the cvterm_id and name for traits assayed
2353 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.
2359 sub get_traits_assayed
{
2361 my $stock_type = shift;
2362 my $trait_format = shift;
2363 my $contains_composable_cv_type = shift;
2364 my $schema = $self->bcs_schema;
2365 my $dbh = $self->bcs_schema->storage()->dbh();
2369 my $cvtermprop_join = '';
2370 my $cvtermprop_where = '';
2372 my $trait_format_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema(), 'trait_format', 'trait_property')->cvterm_id();
2373 $cvtermprop_join = ' JOIN cvtermprop ON (cvtermprop.cvterm_id = cvterm.cvterm_id) ';
2374 $cvtermprop_where = " AND cvtermprop.type_id = $trait_format_cvterm_id AND cvtermprop.value = '$trait_format' ";
2377 my $contains_relationship_rs = $schema->resultset("Cv::Cvterm")->search({ name
=> 'contains' });
2378 if ($contains_relationship_rs->count == 0) {
2379 die "The cvterm 'contains' was not found! Please add this cvterm! Generally this term is added when loading an ontology into the database.\n";
2381 elsif ($contains_relationship_rs->count > 1) {
2382 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";
2384 my $contains_relationship_cvterm_id = $contains_relationship_rs->first->cvterm_id;
2385 my $variable_relationship_rs = $schema->resultset("Cv::Cvterm")->search({ name
=> 'VARIABLE_OF' });
2386 if ($variable_relationship_rs->count == 0) {
2387 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";
2389 elsif ($variable_relationship_rs->count > 1) {
2390 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";
2393 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 : '';
2397 my $stock_type_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema(), $stock_type, 'stock_type')->cvterm_id();
2398 $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)
2401 JOIN dbxref ON (cvterm.dbxref_id = dbxref.dbxref_id)
2402 JOIN db ON (dbxref.db_id = db.db_id)
2403 JOIN phenotype ON (cvterm.cvterm_id=phenotype.cvalue_id)
2404 JOIN nd_experiment_phenotype USING(phenotype_id)
2405 JOIN nd_experiment_project USING(nd_experiment_id)
2406 JOIN nd_experiment_stock USING(nd_experiment_id)
2407 LEFT JOIN phenome.nd_experiment_md_images AS nd_experiment_md_images USING(nd_experiment_id)
2408 LEFT JOIN phenome.project_md_image AS project_md_image ON (nd_experiment_md_images.image_id=project_md_image.image_id)
2409 LEFT JOIN project AS imaging_project ON (project_md_image.project_id=imaging_project.project_id)
2410 JOIN stock on (stock.stock_id = nd_experiment_stock.stock_id)
2411 WHERE stock.type_id=$stock_type_cvterm_id and nd_experiment_project.project_id=? $cvtermprop_where
2412 GROUP BY trait, cvterm.cvterm_id, imaging_project.project_id, imaging_project.name
2415 $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)
2418 JOIN dbxref ON (cvterm.dbxref_id = dbxref.dbxref_id)
2419 JOIN db ON (dbxref.db_id = db.db_id)
2420 JOIN phenotype ON (cvterm.cvterm_id=phenotype.cvalue_id)
2421 JOIN nd_experiment_phenotype USING(phenotype_id)
2422 JOIN nd_experiment_project USING(nd_experiment_id)
2423 LEFT JOIN phenome.nd_experiment_md_images AS nd_experiment_md_images USING(nd_experiment_id)
2424 LEFT JOIN phenome.project_md_image AS project_md_image ON (nd_experiment_md_images.image_id=project_md_image.image_id)
2425 LEFT JOIN project AS imaging_project ON (project_md_image.project_id=imaging_project.project_id)
2426 WHERE nd_experiment_project.project_id=? $cvtermprop_where
2427 GROUP BY trait, cvterm.cvterm_id, imaging_project.project_id, imaging_project.name
2431 my $component_q = "SELECT COALESCE(
2432 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))
2433 FILTER (WHERE component_cvterm.cvterm_id IS NOT NULL), '[]'
2436 LEFT JOIN cvterm_relationship on (cvterm.cvterm_id = cvterm_relationship.object_id AND cvterm_relationship.type_id = $contains_relationship_cvterm_id)
2437 LEFT JOIN cvterm AS component_cvterm on (cvterm_relationship.subject_id = component_cvterm.cvterm_id)
2438 LEFT JOIN cv on (component_cvterm.cv_id = cv.cv_id)
2439 LEFT JOIN cvprop on (cv.cv_id = cvprop.cv_id)
2440 LEFT JOIN cvterm AS cv_type on (cv_type.cvterm_id = cvprop.type_id)
2441 WHERE cvterm.cvterm_id=? ;";
2443 print STDERR Dumper
$q;
2445 my $traits_assayed_h = $dbh->prepare($q);
2446 my $component_h = $dbh->prepare($component_q);
2448 $traits_assayed_h->execute($self->get_trial_id());
2449 while (my ($trait_name, $trait_id, $imaging_project_id, $imaging_project_name, $count) = $traits_assayed_h->fetchrow_array()) {
2450 $component_h->execute($trait_id);
2451 my ($component_terms) = $component_h->fetchrow_array();
2452 $component_terms = decode_json
$component_terms;
2453 if ($contains_composable_cv_type) {
2454 my $has_composable_cv_type = 0;
2455 foreach (@
$component_terms) {
2456 if ($_->{cv_type_cvterm_id
} && $_->{cv_type_cvterm_id
} == $composable_cv_type_cvterm_id) {
2457 $has_composable_cv_type = 1;
2460 if ($has_composable_cv_type == 1) {
2461 push @traits_assayed, [$trait_id, $trait_name, $component_terms, $count, $imaging_project_id, $imaging_project_name];
2465 push @traits_assayed, [$trait_id, $trait_name, $component_terms, $count, $imaging_project_id, $imaging_project_name];
2468 return \
@traits_assayed;
2471 =head2 function get_trait_components_assayed()
2474 Desc: returns the cvterm_id and name for trait components assayed
2482 sub get_trait_components_assayed
{
2484 my $stock_type = shift;
2485 my $composable_cvterm_format = shift;
2486 my $dbh = $self->bcs_schema->storage()->dbh();
2487 my $traits_assayed = $self->get_traits_assayed($stock_type);
2489 my %unique_components;
2490 my @trait_components_assayed;
2491 foreach (@
$traits_assayed){
2492 my $trait_components = SGN
::Model
::Cvterm
->get_components_from_trait($self->bcs_schema, $_->[0]);
2493 foreach (@
$trait_components){
2494 if (!exists($unique_components{$_})){
2495 my $component_cvterm = SGN
::Model
::Cvterm
::get_trait_from_cvterm_id
($self->bcs_schema, $_, $composable_cvterm_format);
2496 push @trait_components_assayed, [$_, $component_cvterm];
2497 $unique_components{$_}++;
2501 return \
@trait_components_assayed;
2504 =head2 function get_experiment_count()
2507 Desc: return the total number of experiments associated
2516 sub get_experiment_count
{
2519 my $rs = $self->bcs_schema->resultset('NaturalDiversity::NdExperimentProject')->search( { project_id
=> $self->get_trial_id() });
2520 return $rs->count();
2523 sub get_location_type_id
{
2525 my $rs = $self->bcs_schema->resultset('Cv::Cvterm')->search( { name
=> 'project location' });
2527 if ($rs->count() > 0) {
2528 return $rs->first()->cvterm_id();
2533 sub get_year_type_id
{
2536 my $rs = $self->bcs_schema->resultset('Cv::Cvterm')->search( { name
=> 'project year' });
2538 return $rs->first()->cvterm_id();
2541 sub get_breeding_program_trial_relationship_cvterm_id
{
2544 my $breeding_program_trial_relationship_cvterm_id;
2545 my $breeding_program_trial_relationship_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'breeding_program_trial_relationship', 'project_relationship');
2546 if ($breeding_program_trial_relationship_cvterm) {
2547 $breeding_program_trial_relationship_cvterm_id = $breeding_program_trial_relationship_cvterm->cvterm_id();
2550 return $breeding_program_trial_relationship_cvterm_id;
2553 sub get_breeding_program_cvterm_id
{
2556 my $breeding_program_cvterm_id;
2557 my $breeding_program_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'breeding_program', 'project_property');
2558 if ($breeding_program_cvterm) {
2559 $breeding_program_cvterm_id = $breeding_program_cvterm->cvterm_id();
2562 return $breeding_program_cvterm_id;
2568 my $f = CXGN
::Trial
::Folder
->new( { bcs_schema
=> $self->bcs_schema(), folder_id
=> $self->get_trial_id() });
2570 my $parent_folder_data = $f->project_parent();
2572 if ($parent_folder_data) {
2573 return $parent_folder_data;
2580 sub get_harvest_date_cvterm_id
{
2583 my $harvest_date_cvterm_id;
2584 my $harvest_date_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'project_harvest_date', 'project_property');
2585 if ($harvest_date_cvterm) {
2586 $harvest_date_cvterm_id = $harvest_date_cvterm->cvterm_id();
2589 return $harvest_date_cvterm_id;
2593 sub get_project_start_date_cvterm_id
{
2596 my $start_date_cvterm_id;
2597 my $start_date_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'project_start_date', 'project_property');
2598 if ($start_date_cvterm) {
2599 $start_date_cvterm_id = $start_date_cvterm->cvterm_id();
2602 return $start_date_cvterm_id;
2605 =head2 function create_plant_entities()
2607 Usage: $trial->create_plant_entries($plants_per_plot);
2608 Desc: Some trials require plant-level data. This function will
2609 add an additional layer of plant entries for each plot.
2611 Args: the number of plants per plot to add.
2617 sub create_plant_entities
{
2619 my $plants_per_plot = shift || 30;
2620 my $inherits_plot_treatments = shift;
2622 my $create_plant_entities_txn = sub {
2623 my $chado_schema = $self->bcs_schema();
2624 my $layout = CXGN
::Trial
::TrialLayout
->new( { schema
=> $chado_schema, trial_id
=> $self->get_trial_id(), experiment_type
=>'field_layout' });
2625 my $design = $layout->get_design();
2627 my $accession_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'accession', 'stock_type')->cvterm_id();
2628 my $cross_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'cross', 'stock_type')->cvterm_id();
2629 my $family_name_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'family_name', 'stock_type')->cvterm_id();
2630 my $plant_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'plant', 'stock_type')->cvterm_id();
2631 my $plot_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'plot', 'stock_type')->cvterm_id();
2632 my $plot_relationship_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'plot_of', 'stock_relationship')->cvterm_id();
2633 my $plant_relationship_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'plant_of', 'stock_relationship')->cvterm_id();
2634 my $plant_index_number_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'plant_index_number', 'stock_property')->cvterm_id();
2635 my $block_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'block', 'stock_property')->cvterm_id();
2636 my $plot_number_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'plot number', 'stock_property')->cvterm_id();
2637 my $replicate_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'replicate', 'stock_property')->cvterm_id();
2638 my $has_plants_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'project_has_plant_entries', 'project_property')->cvterm_id();
2639 my $field_layout_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'field_layout', 'experiment_type')->cvterm_id();
2640 my $treatment_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'treatment_experiment', 'experiment_type')->cvterm_id();
2641 #my $plants_per_plot_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plants_per_plot', 'project_property')->cvterm_id();
2644 my %treatment_experiments;
2645 my %treatment_plots;
2646 if ($inherits_plot_treatments){
2647 $treatments = $self->get_treatments();
2648 foreach (@
$treatments){
2650 my $rs = $chado_schema->resultset("Project::Projectprop")->find_or_create({
2651 type_id
=> $has_plants_cvterm,
2652 value
=> $plants_per_plot,
2653 project_id
=> $_->[0],
2656 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();
2657 $treatment_experiments{$_->[0]} = $treatment_nd_experiment->nd_experiment_id();
2659 my $treatment_trial = CXGN
::Project
->new({ bcs_schema
=> $chado_schema, trial_id
=> $_->[0]});
2660 my $plots = $treatment_trial->get_plots();
2661 foreach my $plot (@
$plots){
2662 $treatment_plots{$_->[0]}->{$plot->[0]} = 1;
2667 my $rs = $chado_schema->resultset("Project::Projectprop")->find_or_create({
2668 type_id
=> $has_plants_cvterm,
2669 value
=> $plants_per_plot,
2670 project_id
=> $self->get_trial_id(),
2673 my $field_layout_experiment = $chado_schema->resultset("Project::Project")->search( { 'me.project_id' => $self->get_trial_id() }, {select=>['nd_experiment.nd_experiment_id']})->search_related('nd_experiment_projects')->search_related('nd_experiment', { type_id
=> $field_layout_cvterm })->single();
2675 foreach my $plot (keys %$design) {
2676 print STDERR
" ... creating plants for plot $plot...\n";
2677 my $plot_row = $chado_schema->resultset("Stock::Stock")->find( { uniquename
=> $design->{$plot}->{plot_name
}, type_id
=>$plot_cvterm });
2680 print STDERR
"The plot $plot is not found in the database\n";
2681 return "The plot $plot is not yet in the database. Cannot create plant entries.";
2684 my $parent_plot = $plot_row->stock_id();
2685 my $parent_plot_name = $plot_row->uniquename();
2686 my $parent_plot_organism = $plot_row->organism_id();
2688 foreach my $plant_index_number (1..$plants_per_plot) {
2689 my $plant_name = $parent_plot_name."_plant_$plant_index_number";
2690 #print STDERR "... ... creating plant $plant_name...\n";
2692 $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, $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);
2696 $layout->generate_and_cache_layout();
2700 $self->bcs_schema()->txn_do($create_plant_entities_txn);
2703 print STDERR
"An error occurred creating the plant entities. $@\n";
2707 print STDERR
"Plant entities created.\n";
2711 =head2 function save_plant_entries()
2713 Usage: $trial->save_plant_entries(\%data, $plants_per_plot, $inherits_plot_treatments);
2714 Desc: Some trials require plant-level data. It is possible to upload
2715 plant_names to save.
2717 Args: Requires $plants_per_plot and \%data which is a hashref of the data parsed from the
2719 example: { 'myplotname1' => { 'plot_stock_id'=>123, 'plant_names'=>['plot1_plant1', 'plot1_plant2'] }, ... }
2725 sub save_plant_entries
{
2727 my $parsed_data = shift;
2728 my $plants_per_plot = shift;
2729 my $inherits_plot_treatments = shift;
2731 my $create_plant_entities_txn = sub {
2732 my $chado_schema = $self->bcs_schema();
2733 my $layout = CXGN
::Trial
::TrialLayout
->new( { schema
=> $chado_schema, trial_id
=> $self->get_trial_id(), experiment_type
=>'field_layout' });
2734 my $design = $layout->get_design();
2736 my $accession_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'accession', 'stock_type')->cvterm_id();
2737 my $cross_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'cross', 'stock_type')->cvterm_id();
2738 my $family_name_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'family_name', 'stock_type')->cvterm_id();
2739 my $plant_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'plant', 'stock_type')->cvterm_id();
2740 my $plot_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'plot', 'stock_type')->cvterm_id();
2741 my $plot_relationship_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'plot_of', 'stock_relationship')->cvterm_id();
2742 my $plant_relationship_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'plant_of', 'stock_relationship')->cvterm_id();
2743 my $plant_index_number_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'plant_index_number', 'stock_property')->cvterm_id();
2744 my $block_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'block', 'stock_property')->cvterm_id();
2745 my $plot_number_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'plot number', 'stock_property')->cvterm_id();
2746 my $replicate_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'replicate', 'stock_property')->cvterm_id();
2747 my $has_plants_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'project_has_plant_entries', 'project_property')->cvterm_id();
2748 my $field_layout_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'field_layout', 'experiment_type')->cvterm_id();
2749 my $treatment_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'treatment_experiment', 'experiment_type')->cvterm_id();
2750 #my $plants_per_plot_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plants_per_plot', 'project_property')->cvterm_id();
2753 my %treatment_experiments;
2754 my %treatment_plots;
2755 if ($inherits_plot_treatments){
2756 $treatments = $self->get_treatments();
2757 foreach (@
$treatments){
2759 my $rs = $chado_schema->resultset("Project::Projectprop")->find_or_create({
2760 type_id
=> $has_plants_cvterm,
2761 value
=> $plants_per_plot,
2762 project_id
=> $_->[0],
2765 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();
2766 $treatment_experiments{$_->[0]} = $treatment_nd_experiment->nd_experiment_id();
2768 my $treatment_trial = CXGN
::Trial
->new({ bcs_schema
=> $chado_schema, trial_id
=> $_->[0]});
2769 my $plots = $treatment_trial->get_plots();
2770 foreach my $plot (@
$plots){
2771 $treatment_plots{$_->[0]}->{$plot->[0]} = 1;
2776 my $rs = $chado_schema->resultset("Project::Projectprop")->find_or_create({
2777 type_id
=> $has_plants_cvterm,
2778 value
=> $plants_per_plot,
2779 project_id
=> $self->get_trial_id(),
2783 my $field_layout_experiment = $chado_schema->resultset("Project::Project")->search( { 'me.project_id' => $self->get_trial_id() }, {select=>['nd_experiment.nd_experiment_id']})->search_related('nd_experiment_projects')->search_related('nd_experiment', { type_id
=> $field_layout_cvterm })->single();
2785 while( my ($key, $val) = each %$parsed_data){
2786 my $plot_stock_id = $key;
2787 my $plot_name = $val->{plot_name
};
2788 print STDERR
" ... creating plants for plot $plot_name...\n";
2789 my $plot_row = $chado_schema->resultset("Stock::Stock")->find( { stock_id
=>$plot_stock_id });
2792 print STDERR
"The plot $plot_name is not found in the database\n";
2793 return "The plot $plot_name is not yet in the database. Cannot create plant entries.";
2796 my $parent_plot = $plot_row->stock_id();
2797 my $parent_plot_name = $plot_row->uniquename();
2798 my $parent_plot_organism = $plot_row->organism_id();
2800 my $plant_index_number = 1;
2801 my $plant_names = $val->{plant_names
};
2802 my $plant_index_numbers = $val->{plant_index_numbers
};
2804 foreach my $plant_name (@
$plant_names) {
2805 my $given_plant_index_number = $plant_index_numbers->[$increment];
2806 my $plant_index_number_save = $given_plant_index_number ?
$given_plant_index_number : $plant_index_number;
2808 $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);
2809 $plant_index_number++;
2814 $layout->generate_and_cache_layout();
2818 $self->bcs_schema()->txn_do($create_plant_entities_txn);
2821 print STDERR
"An error occurred creating the plant entities. $@\n";
2825 print STDERR
"Plant entities created.\n";
2829 sub _save_plant_entry
{
2831 my $chado_schema = shift;
2832 my $accession_cvterm = shift;
2833 my $cross_cvterm = shift;
2834 my $family_name_cvterm = shift;
2835 my $parent_plot_organism = shift;
2836 my $parent_plot_name = shift;
2837 my $parent_plot = shift;
2838 my $plant_name = shift;
2839 my $plant_cvterm = shift;
2840 my $plant_index_number = shift;
2841 my $plant_index_number_cvterm = shift;
2842 my $block_cvterm = shift;
2843 my $plot_number_cvterm = shift;
2844 my $replicate_cvterm = shift;
2845 my $plant_relationship_cvterm = shift;
2846 my $field_layout_experiment = shift;
2847 my $field_layout_cvterm = shift;
2848 my $inherits_plot_treatments = shift;
2849 my $treatments = shift;
2850 my $plot_relationship_cvterm = shift;
2851 my $treatment_plots_ref = shift;
2852 my $treatment_experiments_ref = shift;
2853 my $treatment_cvterm = shift;
2854 my %treatment_plots = %$treatment_plots_ref;
2855 my %treatment_experiments = %$treatment_experiments_ref;
2857 my $plant = $chado_schema->resultset("Stock::Stock")->create({
2858 organism_id
=> $parent_plot_organism,
2859 name
=> $plant_name,
2860 uniquename
=> $plant_name,
2861 type_id
=> $plant_cvterm,
2864 my $plantprop = $chado_schema->resultset("Stock::Stockprop")->create( {
2865 stock_id
=> $plant->stock_id(),
2866 type_id
=> $plant_index_number_cvterm,
2867 value
=> $plant_index_number,
2870 #The plant inherits the properties of the plot.
2871 my $plot_props = $chado_schema->resultset("Stock::Stockprop")->search({ stock_id
=> $parent_plot, type_id
=> [$block_cvterm, $plot_number_cvterm, $replicate_cvterm] });
2872 while (my $prop = $plot_props->next() ) {
2873 #print STDERR $plant->uniquename()." ".$prop->type_id()."\n";
2874 $plantprop = $chado_schema->resultset("Stock::Stockprop")->create( {
2875 stock_id
=> $plant->stock_id(),
2876 type_id
=> $prop->type_id(),
2877 value
=> $prop->value(),
2881 #the plant has a relationship to the plot
2882 my $stock_relationship = $self->bcs_schema()->resultset("Stock::StockRelationship")->create({
2883 subject_id
=> $parent_plot,
2884 object_id
=> $plant->stock_id(),
2885 type_id
=> $plant_relationship_cvterm,
2888 #the plant has a relationship to the accession
2889 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'});
2890 if ($plot_accession_rs->count != 1){
2891 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.";
2893 $stock_relationship = $self->bcs_schema()->resultset("Stock::StockRelationship")->create({
2894 subject_id
=> $plant->stock_id(),
2895 object_id
=> $plot_accession_rs->first->object_id,
2896 type_id
=> $plant_relationship_cvterm,
2899 #link plant to project through nd_experiment. also add nd_genolocation_id of plot to nd_experiment for the plant
2900 my $plant_nd_experiment_stock = $chado_schema->resultset("NaturalDiversity::NdExperimentStock")->create({
2901 nd_experiment_id
=> $field_layout_experiment->nd_experiment_id(),
2902 type_id
=> $field_layout_cvterm,
2903 stock_id
=> $plant->stock_id(),
2906 if ($inherits_plot_treatments){
2908 foreach (@
$treatments){
2909 my $plots = $treatment_plots{$_->[0]};
2910 if (exists($plots->{$parent_plot})){
2911 my $plant_nd_experiment_stock = $chado_schema->resultset("NaturalDiversity::NdExperimentStock")->create({
2912 nd_experiment_id
=> $treatment_experiments{$_->[0]},
2913 type_id
=> $treatment_cvterm,
2914 stock_id
=> $plant->stock_id(),
2922 =head2 function has_plant_entries()
2924 Usage: $trial->has_plant_entries();
2925 Desc: Some trials require plant-level data. This function will determine if a trial has plants associated with it.
2926 Ret: Returns 1 if trial has plants, 0 if the trial does not.
2933 sub has_plant_entries
{
2935 my $chado_schema = $self->bcs_schema();
2936 my $has_plants_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'project_has_plant_entries', 'project_property' );
2938 my $rs = $chado_schema->resultset("Project::Projectprop")->find({
2939 type_id
=> $has_plants_cvterm->cvterm_id(),
2940 project_id
=> $self->get_trial_id(),
2951 =head2 function create_tissue_samples()
2953 Usage: $trial->create_tissue_samples(\@tissue_names, $inherits_plot_treatments);
2954 Desc: Some trials require tissue_sample-level data. This function will
2955 add an additional layer of tissue samples for each plant.
2957 Args: an arrayref of tissue names to add to sample name e.g. ['leaf','root']
2963 sub create_tissue_samples
{
2965 my $tissue_names = shift;
2966 my $inherits_plot_treatments = shift;
2968 my $create_tissue_sample_entries_txn = sub {
2969 my $chado_schema = $self->bcs_schema();
2970 my $layout = CXGN
::Trial
::TrialLayout
->new( { schema
=> $chado_schema, trial_id
=> $self->get_trial_id(), experiment_type
=>'field_layout' });
2971 my $design = $layout->get_design();
2973 my $accession_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'accession', 'stock_type')->cvterm_id();
2974 my $cross_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'cross', 'stock_type')->cvterm_id();
2975 my $family_name_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'family_name', 'stock_type')->cvterm_id();
2976 my $plant_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'plant', 'stock_type')->cvterm_id();
2977 my $subplot_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'subplot', 'stock_type')->cvterm_id();
2978 my $plot_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'plot', 'stock_type')->cvterm_id();
2979 my $tissue_sample_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'tissue_sample', 'stock_type')->cvterm_id();
2980 my $plot_relationship_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'plot_of', 'stock_relationship')->cvterm_id();
2981 my $plant_relationship_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'plant_of', 'stock_relationship')->cvterm_id();
2982 my $tissue_relationship_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'tissue_sample_of', 'stock_relationship')->cvterm_id();
2983 my $plant_index_number_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'plant_index_number', 'stock_property')->cvterm_id();
2984 my $tissue_index_number_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'tissue_sample_index_number', 'stock_property')->cvterm_id();
2985 my $has_tissues_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'project_has_tissue_sample_entries', 'project_property')->cvterm_id();
2986 my $block_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'block', 'stock_property')->cvterm_id();
2987 my $plot_number_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'plot number', 'stock_property')->cvterm_id();
2988 my $replicate_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'replicate', 'stock_property')->cvterm_id();
2989 my $field_layout_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'field_layout', 'experiment_type')->cvterm_id();
2990 my $treatment_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'treatment_experiment', 'experiment_type')->cvterm_id();
2993 my %treatment_experiments;
2994 my %treatment_plots;
2995 my %treatment_subplots;
2996 if ($inherits_plot_treatments){
2997 $treatments = $self->get_treatments();
2998 foreach (@
$treatments){
3000 my $rs = $chado_schema->resultset("Project::Projectprop")->find_or_create({
3001 type_id
=> $has_tissues_cvterm,
3002 value
=> scalar(@
$tissue_names),
3003 project_id
=> $_->[0],
3006 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();
3007 $treatment_experiments{$_->[0]} = $treatment_nd_experiment->nd_experiment_id();
3009 my $treatment_trial = CXGN
::Trial
->new({ bcs_schema
=> $chado_schema, trial_id
=> $_->[0]});
3010 my $plots = $treatment_trial->get_plots();
3011 foreach my $plot (@
$plots){
3012 $treatment_plots{$_->[0]}->{$plot->[0]} = 1;
3014 my $subplots = $treatment_trial->get_subplots();
3015 foreach my $subplot (@
$subplots){
3016 $treatment_subplots{$_->[0]}->{$subplot->[0]} = 1;
3021 my $rs = $chado_schema->resultset("Project::Projectprop")->find_or_create({
3022 type_id
=> $has_tissues_cvterm,
3023 value
=> scalar(@
$tissue_names),
3024 project_id
=> $self->get_trial_id(),
3027 my $field_layout_experiment = $chado_schema->resultset("Project::Project")->search( { 'me.project_id' => $self->get_trial_id() }, {select=>['nd_experiment.nd_experiment_id']})->search_related('nd_experiment_projects')->search_related('nd_experiment', { type_id
=> $field_layout_cvterm })->single();
3029 foreach my $plot (keys %$design) {
3030 my $plant_names = $design->{$plot}->{plant_names
};
3031 my $subplot_names = $design->{$plot}->{subplot_names
};
3032 my $subplots_plant_names = $design->{$plot}->{subplots_plant_names
};
3033 my %plant_tissue_hash;
3034 foreach my $plant_name (@
$plant_names){
3035 my $parent_plot_id = $design->{$plot}->{plot_id
};
3036 my $parent_plot_name = $design->{$plot}->{plot_name
};
3037 my $plant_row = $chado_schema->resultset("Stock::Stock")->find( { uniquename
=> $plant_name, type_id
=>$plant_cvterm });
3040 print STDERR
"The plant $plant_name is not found in the database\n";
3041 return "The plant $plant_name is not yet in the database. Cannot create tissue entries.";
3044 my $parent_plant = $plant_row->stock_id();
3045 my $parent_plant_name = $plant_row->uniquename();
3046 my $parent_plant_organism = $plant_row->organism_id();
3048 my $tissue_index_number = 1;
3049 foreach my $tissue_name (@
$tissue_names){
3050 my $tissue_name = $parent_plant_name."_".$tissue_name.$tissue_index_number;
3051 print STDERR
"... ... creating tissue $tissue_name...\n";
3053 my $tissue = $chado_schema->resultset("Stock::Stock")->create({
3054 organism_id
=> $parent_plant_organism,
3055 name
=> $tissue_name,
3056 uniquename
=> $tissue_name,
3057 type_id
=> $tissue_sample_cvterm,
3060 my $tissueprop = $chado_schema->resultset("Stock::Stockprop")->create( {
3061 stock_id
=> $tissue->stock_id(),
3062 type_id
=> $tissue_index_number_cvterm,
3063 value
=> $tissue_index_number,
3065 $tissue_index_number++;
3067 #the tissue has a relationship to the plant
3068 my $stock_relationship = $self->bcs_schema()->resultset("Stock::StockRelationship")->create({
3069 object_id
=> $parent_plant,
3070 subject_id
=> $tissue->stock_id(),
3071 type_id
=> $tissue_relationship_cvterm,
3074 #the tissue has a relationship to the plot
3075 $stock_relationship = $self->bcs_schema()->resultset("Stock::StockRelationship")->create({
3076 object_id
=> $parent_plot_id,
3077 subject_id
=> $tissue->stock_id(),
3078 type_id
=> $tissue_relationship_cvterm,
3081 #the tissue has a relationship to the accession
3082 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'});
3083 if ($plant_accession_rs->count != 1){
3084 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.";
3086 $stock_relationship = $self->bcs_schema()->resultset("Stock::StockRelationship")->create({
3087 object_id
=> $plant_accession_rs->first->object_id,
3088 subject_id
=> $tissue->stock_id(),
3089 type_id
=> $tissue_relationship_cvterm,
3092 #link tissue to project through nd_experiment.
3093 my $plant_nd_experiment_stock = $chado_schema->resultset("NaturalDiversity::NdExperimentStock")->create({
3094 nd_experiment_id
=> $field_layout_experiment->nd_experiment_id(),
3095 type_id
=> $field_layout_cvterm,
3096 stock_id
=> $tissue->stock_id(),
3099 if ($inherits_plot_treatments){
3101 foreach (@
$treatments){
3102 my $plots = $treatment_plots{$_->[0]};
3103 if (exists($plots->{$parent_plot_id})){
3104 my $plant_nd_experiment_stock = $chado_schema->resultset("NaturalDiversity::NdExperimentStock")->create({
3105 nd_experiment_id
=> $treatment_experiments{$_->[0]},
3106 type_id
=> $treatment_cvterm,
3107 stock_id
=> $tissue->stock_id(),
3114 push @
{$plant_tissue_hash{$plant_name}}, $tissue->stock_id;
3119 foreach my $subplot_name (%$subplots_plant_names){
3120 my $subplot_row = $chado_schema->resultset("Stock::Stock")->find({ uniquename
=> $subplot_name, type_id
=>$subplot_cvterm });
3121 foreach my $plant (@
{$subplots_plant_names->{$subplot_name}}){
3122 foreach my $t (@
{$plant_tissue_hash{$plant}}){
3123 #the tissue has a relationship to the subplot
3124 my $stock_relationship = $self->bcs_schema()->resultset("Stock::StockRelationship")->create({
3125 object_id
=> $subplot_row->stock_id(),
3127 type_id
=> $tissue_relationship_cvterm,
3130 if ($inherits_plot_treatments){
3132 foreach (@
$treatments){
3133 my $subplots = $treatment_subplots{$_->[0]};
3134 if (exists($subplots->{$subplot_row->stock_id})){
3135 my $plant_nd_experiment_stock = $chado_schema->resultset("NaturalDiversity::NdExperimentStock")->create({
3136 nd_experiment_id
=> $treatment_experiments{$_->[0]},
3137 type_id
=> $treatment_cvterm,
3149 $layout->generate_and_cache_layout();
3153 $self->bcs_schema()->txn_do($create_tissue_sample_entries_txn);
3156 print STDERR
"An error occurred creating the tissue sample entities. $@\n";
3160 print STDERR
"Tissue sample entities created.\n";
3164 =head2 function has_col_and_row_numbers()
3166 Usage: $trial->has_col_and_row_numbers();
3167 Desc: Some trials require tissue_samples from plants. This function will determine if a trial has row and column numbers for fieldMap spreadsheet download.
3168 Ret: Returns 1 if trial has row and column numbers, 0 if the trial does not.
3175 sub has_col_and_row_numbers
{
3177 my $chado_schema = $self->bcs_schema();
3180 my $layout = CXGN
::Trial
::TrialLayout
->new( { schema
=> $chado_schema, trial_id
=> $self->get_trial_id(), experiment_type
=>'field_layout' });
3181 $design = $layout->get_design();
3184 my (@row_numbers, @col_numbers);
3185 foreach my $plot (keys %$design) {
3186 my $row_number = $design->{$plot}->{row_number
};
3187 my $col_number = $design->{$plot}->{col_number
};
3189 push @row_numbers, $row_number;
3192 push @col_numbers, $col_number;
3196 if (scalar(@row_numbers) ne '0' && scalar(@col_numbers) ne '0'){
3204 =head2 function has_tissue_sample_entries()
3206 Usage: $trial->has_tissue_sample_entries();
3207 Desc: Some trials require tissue_samples from plants. This function will determine if a trial has tissue_samples associated with it.
3208 Ret: Returns 1 if trial has tissue_samples, 0 if the trial does not.
3215 sub has_tissue_sample_entries
{
3217 my $chado_schema = $self->bcs_schema();
3218 my $has_tissues_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'project_has_tissue_sample_entries', 'project_property' );
3220 my $rs = $chado_schema->resultset("Project::Projectprop")->find({
3221 type_id
=> $has_tissues_cvterm->cvterm_id(),
3222 project_id
=> $self->get_trial_id(),
3234 =head2 function has_subplot_entries()
3236 Usage: $trial->has_subplot_entries();
3237 Desc: Some trials require subplot-level data (splitplot designs). This function will determine if a trial has subplots associated with it.
3238 Ret: Returns 1 if trial has subplots, 0 if the trial does not.
3245 sub has_subplot_entries
{
3247 my $chado_schema = $self->bcs_schema();
3248 my $has_subplots_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'project_has_subplot_entries', 'project_property' );
3250 my $rs = $chado_schema->resultset("Project::Projectprop")->find({
3251 type_id
=> $has_subplots_cvterm->cvterm_id(),
3252 project_id
=> $self->get_trial_id(),
3263 sub get_planting_date_cvterm_id
{
3265 my $planting_date = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'project_planting_date', 'project_property');
3267 return $planting_date->cvterm_id();
3271 =head2 accessors set_design_type(), get_design_type()
3273 Usage: $trial->set_design_type("RCBD");
3282 sub get_design_type
{
3287 my $project = $self->bcs_schema->resultset("Project::Project")->find( { project_id
=> $self->get_trial_id() });
3289 $design_prop = $project->projectprops->find(
3290 { 'type.name' => 'design' },
3292 ); #there should be only one design prop.
3293 if (!$design_prop) {
3296 $design_type = $design_prop->value;
3297 if (!$design_type) {
3300 return $design_type;
3308 =head2 get_accessions
3310 Usage: my $accessions = $t->get_accessions();
3311 Desc: retrieves the accessions or family names or cross unique ids used in this trial.
3312 Ret: an arrayref of { accession_name => acc_name, stock_id => stock_id, stock_type => stock_type }
3319 sub get_accessions
{
3323 my $accession_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'accession', 'stock_type' )->cvterm_id();
3324 my $cross_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'cross', 'stock_type' )->cvterm_id();
3325 my $family_name_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'family_name', 'stock_type' )->cvterm_id();
3326 my $field_trial_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, "field_layout", "experiment_type")->cvterm_id();
3327 my $plot_of_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, "plot_of", "stock_relationship")->cvterm_id();
3328 my $plant_of_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, "plant_of", "stock_relationship")->cvterm_id();
3329 my $subplot_of_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, "subplot_of", "stock_relationship")->cvterm_id();
3330 my $tissue_sample_of_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, "tissue_sample_of", "stock_relationship")->cvterm_id();
3332 my $q = "SELECT DISTINCT(accession.stock_id), accession.uniquename, cvterm.name
3333 FROM stock as accession
3334 JOIN cvterm on (accession.type_id = cvterm.cvterm_id)
3335 JOIN stock_relationship on (accession.stock_id = stock_relationship.object_id)
3336 JOIN stock as plot on (plot.stock_id = stock_relationship.subject_id)
3337 JOIN nd_experiment_stock on (plot.stock_id=nd_experiment_stock.stock_id)
3338 JOIN nd_experiment using(nd_experiment_id)
3339 JOIN nd_experiment_project using(nd_experiment_id)
3340 JOIN project using(project_id)
3341 WHERE accession.type_id IN (?, ?, ?)
3342 AND stock_relationship.type_id IN (?, ?, ?, ?)
3343 AND project.project_id = ?
3344 ORDER BY accession.stock_id;";
3346 my $h = $self->bcs_schema->storage->dbh()->prepare($q);
3347 $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());
3348 while (my ($stock_id, $uniquename, $stock_type) = $h->fetchrow_array()) {
3349 push @accessions, {accession_name
=>$uniquename, stock_id
=>$stock_id, stock_type
=>$stock_type};
3351 return \
@accessions;
3354 =head2 get_tissue_sources
3356 Usage: my $tissue_sources = $t->get_tissue_sources();
3357 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
3358 Ret: an arrayref of { uniquename => acc_name, type=>'plant', stock_id => stock_id }
3365 sub get_tissue_sources
{
3368 my $tissue_sample_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'tissue_sample', 'stock_type' )->cvterm_id();
3369 my $tissue_sample_of_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, "tissue_sample_of", "stock_relationship")->cvterm_id();
3370 my $q = "SELECT DISTINCT(stock.stock_id), stock.uniquename, cvterm.name
3372 JOIN cvterm on (stock.type_id = cvterm.cvterm_id)
3373 JOIN stock_relationship on (stock.stock_id = stock_relationship.object_id)
3374 JOIN stock as tissue_sample on (tissue_sample.stock_id = stock_relationship.subject_id)
3375 JOIN nd_experiment_stock on (tissue_sample.stock_id=nd_experiment_stock.stock_id)
3376 JOIN nd_experiment using(nd_experiment_id)
3377 JOIN nd_experiment_project using(nd_experiment_id)
3378 JOIN project using(project_id)
3379 WHERE tissue_sample.type_id = $tissue_sample_cvterm_id
3380 AND stock_relationship.type_id = $tissue_sample_of_cvterm_id
3381 AND project.project_id = ?
3382 GROUP BY (stock.stock_id, cvterm.name)
3383 ORDER BY (stock.stock_id);";
3385 my $h = $self->bcs_schema->storage->dbh()->prepare($q);
3386 $h->execute($self->get_trial_id());
3387 while (my ($stock_id, $uniquename, $type) = $h->fetchrow_array()) {
3388 push @tissue_samples, {uniquename
=>$uniquename, type
=>$type, stock_id
=>$stock_id };
3390 return \
@tissue_samples;
3395 Usage: $plants = $t->get_plants();
3396 Desc: retrieves that plants that are part of the design for this trial.
3397 Ret: an array ref containing [ plant_name, plant_stock_id ]
3408 my $trial_layout_download = CXGN
::Trial
::TrialLayoutDownload
->new({
3409 schema
=> $self->bcs_schema,
3410 trial_id
=> $self->get_trial_id(),
3411 data_level
=> 'plants',
3412 selected_columns
=> {"plant_name"=>1,"plant_id"=>1},
3414 my $output = $trial_layout_download->get_layout_output()->{output
};
3416 if (defined $output){
3417 my $header = shift @
$output;
3418 foreach (@
$output) {
3419 push @plants, [$_->[1], $_->[0]];
3422 @plants = @
{$self->get_observation_units_direct('plant')};
3427 =head2 get_plants_per_accession
3429 Usage: $plants = $t->get_plants_per_accession();
3430 Desc: retrieves that plants that are part of the design for this trial grouping them by accession.
3431 Ret: a hash ref containing { $accession_stock_id1 => [ [ plant_name1, plant_stock_id1 ], [ plant_name2, plant_stock_id2 ] ], ... }
3438 sub get_plants_per_accession
{
3442 my $plant_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'plant', 'stock_type' )->cvterm_id();
3443 my $accession_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'accession', 'stock_type' )->cvterm_id();
3444 my $family_name_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'family_name', 'stock_type' )->cvterm_id();
3445 my $cross_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'cross', 'stock_type' )->cvterm_id();
3446 my @trial_stock_type_ids;
3447 push @trial_stock_type_ids, $accession_cvterm_id, $family_name_cvterm_id, $cross_cvterm_id;
3448 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']});
3451 while(my $rs = $trial_plant_rs->next()) {
3452 $unique_plants{$rs->uniquename} = [$rs->stock_id, $rs->get_column('accession_stock_id')];
3454 while (my ($key, $value) = each %unique_plants) {
3455 push @
{$return{$value->[1]}}, [$value->[0], $key];
3457 #print STDERR Dumper \%return;
3463 Usage: my $seedlots = $trial->get_seedlots();
3464 Desc: returns a list of seedlots that are defined for the trial.
3465 Ret: an array ref of elements that contain
3466 [ seedlot_name, seedlot_stock_id ]
3468 Side Effects: db access
3477 my $seedlot_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'seedlot', 'stock_type' )->cvterm_id();
3478 my $seed_transaction_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, "seed transaction", "stock_relationship")->cvterm_id();
3480 my $q = "SELECT DISTINCT(accession.stock_id), accession.uniquename
3481 FROM stock as accession
3482 JOIN stock_relationship on (accession.stock_id = stock_relationship.object_id)
3483 JOIN stock as plot on (plot.stock_id = stock_relationship.subject_id)
3484 JOIN nd_experiment_stock on (plot.stock_id=nd_experiment_stock.stock_id)
3485 JOIN nd_experiment using(nd_experiment_id)
3486 JOIN nd_experiment_project using(nd_experiment_id)
3487 JOIN project using(project_id)
3488 WHERE accession.type_id = $seedlot_cvterm_id
3489 AND stock_relationship.type_id IN ($seed_transaction_cvterm_id)
3490 AND project.project_id = ?
3491 GROUP BY accession.stock_id
3492 ORDER BY accession.stock_id;";
3494 #Removed nd_experiment.type_id IN ($field_trial_cvterm_id, $genotyping_trial_cvterm_id) AND
3496 my $h = $self->bcs_schema->storage->dbh()->prepare($q);
3497 $h->execute($self->get_trial_id());
3498 while (my ($stock_id, $uniquename) = $h->fetchrow_array()) {
3499 push @seedlots, [$stock_id, $uniquename];
3507 Usage: my $plots = $trial->get_plots();
3508 Desc: returns a list of plots that are defined for the trial.
3509 Ret: an array ref of elements that contain
3510 [ plot_name, plot_stock_id ]
3512 Side Effects: db access
3521 my $trial_layout_download = CXGN
::Trial
::TrialLayoutDownload
->new({
3522 schema
=> $self->bcs_schema,
3523 trial_id
=> $self->get_trial_id(),
3524 data_level
=> 'plots',
3525 selected_columns
=> {"plot_name"=>1,"plot_id"=>1},
3527 my $output = $trial_layout_download->get_layout_output()->{output
};
3529 if (defined $output){
3530 my $header = shift @
$output;
3531 foreach (@
$output) {
3532 push @plots, [$_->[1], $_->[0]];
3535 @plots = @
{$self->get_observation_units_direct('plot')};
3540 sub get_observation_units_direct
{
3542 my $stock_type = shift;
3543 # my $nd_experiment_types = shift || ['field_layout','treatment_experiment','genotyping_layout'];
3544 my $schema = $self->bcs_schema;
3546 my $obs_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($schema, $stock_type, "stock_type")->cvterm_id();
3547 # my @nd_experiment_type_ids;
3548 # foreach (@$nd_experiment_types) {
3549 # push @nd_experiment_type_ids, SGN::Model::Cvterm->get_cvterm_row($schema, $_, "experiment_type")->cvterm_id();
3551 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;";
3552 my $h = $schema->storage->dbh()->prepare($q);
3553 $h->execute($self->get_trial_id(), $obs_cvterm_id);
3554 while (my ($uniquename, $stock_id) = $h->fetchrow_array()) {
3555 push @obs, [$stock_id, $uniquename];
3560 =head2 get_plots_per_accession
3562 Usage: $plots = $t->get_plots_per_accession();
3563 Desc: retrieves that plots that are part of the design for this trial grouping them by accession.
3564 Ret: a hash ref containing { $accession_stock_id1 => [ [ plot_name1, plot_stock_id1 ], [ plot_name2, plot_stock_id2 ] ], ... }
3571 sub get_plots_per_accession
{
3575 # note: this function also retrieves stocks of type tissue_sample (for genotyping plates).
3576 my $plot_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'plot', 'stock_type' )->cvterm_id();
3577 my $accession_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'accession', 'stock_type' )->cvterm_id();
3578 my $cross_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'cross', 'stock_type' )->cvterm_id();
3579 my $family_name_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'family_name', 'stock_type' )->cvterm_id();
3580 my $tissue_sample_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'tissue_sample', 'stock_type');
3581 my $tissue_sample_cvterm_id = $tissue_sample_cvterm ?
$tissue_sample_cvterm->cvterm_id() : '';
3584 push @type_ids, $plot_cvterm_id if $plot_cvterm_id;
3585 push @type_ids, $tissue_sample_cvterm_id if $tissue_sample_cvterm_id;
3587 print STDERR
"TYPE IDS: ".join(", ", @type_ids);
3589 my @trial_stock_type_ids;
3590 push @trial_stock_type_ids, $accession_cvterm_id, $cross_cvterm_id, $family_name_cvterm_id;
3592 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']});
3595 while(my $rs = $trial_plot_rs->next()) {
3596 $unique_plots{$rs->uniquename} = [$rs->stock_id, $rs->get_column('accession_stock_id')];
3598 while (my ($key, $value) = each %unique_plots) {
3599 push @
{$return{$value->[1]}}, [$value->[0], $key];
3601 #print STDERR Dumper \%return;
3607 Usage: my $subplots = $trial->get_subplots();
3608 Desc: returns a list of subplots that are defined for the trial.
3609 Ret: an array ref of elements that contain
3610 [ subplot_name, subplot_stock_id ]
3612 Side Effects: db access
3621 my $trial_layout_download = CXGN
::Trial
::TrialLayoutDownload
->new({
3622 schema
=> $self->bcs_schema,
3623 trial_id
=> $self->get_trial_id(),
3624 data_level
=> 'subplots',
3625 selected_columns
=> {"subplot_name"=>1,"subplot_id"=>1},
3627 my $output = $trial_layout_download->get_layout_output()->{output
};
3629 if (defined $output){
3630 my $header = shift @
$output;
3631 foreach (@
$output) {
3632 push @subplots, [$_->[1], $_->[0]];
3635 @subplots = @
{$self->get_observation_units_direct('subplot')};
3637 print STDERR Dumper \
@subplots;
3641 =head2 get_tissue_samples
3643 Usage: $tissues = $t->get_tissue_samples();
3644 Desc: retrieves the tissue samples that are linked to plants for this trial.
3645 Ret: an array ref containing [ tissue_sample_name, tissue_sample_stock_id ]
3652 sub get_tissue_samples
{
3656 my $trial_layout_download = CXGN
::Trial
::TrialLayoutDownload
->new({
3657 schema
=> $self->bcs_schema,
3658 trial_id
=> $self->get_trial_id(),
3659 data_level
=> 'field_trial_tissue_samples',
3660 selected_columns
=> {"tissue_sample_name"=>1,"tissue_sample_id"=>1},
3662 my $output = $trial_layout_download->get_layout_output()->{output
};
3663 if (defined $output){
3664 my $header = shift @
$output;
3665 foreach (@
$output) {
3666 push @tissues, [$_->[1], $_->[0]];
3669 @tissues = @
{$self->get_observation_units_direct('tissue_sample')};
3676 Usage: my $controls = $t->get_controls();
3677 Desc: Returns the accessions that were used as controls in the design
3678 Ret: an arrayref containing
3679 { accession_name => control_name, stock_id => control_stock_id }
3690 my $accession_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'accession', 'stock_type' )->cvterm_id();
3691 my $field_trial_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, "field_layout", "experiment_type")->cvterm_id();
3692 my $genotyping_trial_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, "genotyping_layout", "experiment_type")->cvterm_id();
3693 my $plot_of_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, "plot_of", "stock_relationship")->cvterm_id();
3694 my $plant_of_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, "plant_of", "stock_relationship")->cvterm_id();
3695 my $tissue_sample_of_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, "tissue_sample_of", "stock_relationship")->cvterm_id();
3696 my $control_type_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, "is a control", 'stock_property')->cvterm_id();
3698 my $q = "SELECT DISTINCT(accession.stock_id), accession.uniquename
3699 FROM stock as accession
3700 JOIN stock_relationship on (accession.stock_id = stock_relationship.object_id)
3701 JOIN stock as plot on (plot.stock_id = stock_relationship.subject_id)
3702 JOIN stockprop as control on (plot.stock_id=control.stock_id)
3703 JOIN nd_experiment_stock on (plot.stock_id=nd_experiment_stock.stock_id)
3704 JOIN nd_experiment using(nd_experiment_id)
3705 JOIN nd_experiment_project using(nd_experiment_id)
3706 JOIN project using(project_id)
3707 WHERE accession.type_id = $accession_cvterm_id
3708 AND stock_relationship.type_id IN ($plot_of_cvterm_id, $tissue_sample_of_cvterm_id, $plant_of_cvterm_id)
3709 AND project.project_id = ?
3710 AND control.type_id = $control_type_id
3711 GROUP BY accession.stock_id
3712 ORDER BY accession.stock_id;";
3714 #removed nd_experiment.type_id IN ($field_trial_cvterm_id, $genotyping_trial_cvterm_id) AND
3716 my $h = $self->bcs_schema->storage->dbh()->prepare($q);
3717 $h->execute($self->get_trial_id());
3718 while (my ($stock_id, $uniquename) = $h->fetchrow_array()) {
3719 push @controls, {accession_name
=> $uniquename, stock_id
=>$stock_id } ;
3725 =head2 get_controls_by_plot
3727 Usage: my $controls = $t->get_controls_by_plot(\@plot_ids);
3728 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
3729 Ret: an arrayref containing
3730 { accession_name => control_name, stock_id => control_stock_id }
3737 sub get_controls_by_plot
{
3739 my $plot_ids = shift;
3740 my @ids = @
$plot_ids;
3743 my $accession_rs = $self->bcs_schema->resultset('Stock::Stock')->search(
3744 { 'subject.stock_id' => { 'in' => \
@ids} , 'type.name' => 'is a control' },
3745 { join => { stock_relationship_objects
=> { subject
=> { stockprops
=> 'type' }}}, group_by
=> 'me.stock_id',},
3748 while(my $accession = $accession_rs->next()) {
3749 push @controls, { accession_name
=> $accession->uniquename, stock_id
=> $accession->stock_id };
3755 =head2 get_treatments
3757 Usage: $plants = $t->get_treatments();
3758 Desc: retrieves the treatments that are part of this trial
3759 Ret: an array ref containing from project table [ treatment_name, treatment_id ]
3766 sub get_treatments
{
3769 my $treatment_rel_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, "trial_treatment_relationship", "project_relationship")->cvterm_id();
3771 my $treatment_rs = $self->bcs_schema->resultset("Project::ProjectRelationship")->search({type_id
=>$treatment_rel_cvterm_id, object_project_id
=>$self->get_trial_id()})->search_related('subject_project');
3774 while(my $rs = $treatment_rs->next()) {
3775 push @treatments, [$rs->project_id, $rs->name];
3777 return \
@treatments;
3780 =head2 get_trial_contacts
3782 Usage: my $contacts = $t->get_trial_contacts();
3783 Desc: Returns an arrayref of hashrefs that contain all sp_person info fpr sp_person_ids saved as projectprops to this trial
3784 Ret: an arrayref containing
3785 { sp_person_id => 1, salutation => 'Mr.', first_name => 'joe', last_name => 'doe', email => 'j@d.com' }
3792 sub get_trial_contacts
{
3796 my $sp_person_id_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema,'sp_person_id','local')->cvterm_id;
3797 my $prop_rs = $self->bcs_schema->resultset('Project::Projectprop')->search(
3798 { 'project_id' => $self->get_trial_id, 'type_id'=>$sp_person_id_cvterm_id }
3801 while(my $prop = $prop_rs->next()) {
3802 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=?;";
3803 my $h = $self->bcs_schema()->storage->dbh()->prepare($q);
3804 $h->execute($prop->value);
3805 while (my ($sp_person_id, $username, $salutation, $first_name, $last_name, $email, $user_type, $phone, $organization) = $h->fetchrow_array()){
3807 sp_person_id
=> $sp_person_id,
3808 salutation
=> $salutation,
3809 first_name
=> $first_name,
3810 last_name
=> $last_name,
3811 username
=> $username,
3814 phone_number
=> $phone,
3815 organization
=> $organization
3824 =head2 function get_data_agreement()
3826 Usage: $trial->get_data_agreement();
3827 Desc: return data agreement saved for trial.
3835 sub get_data_agreement
{
3837 my $chado_schema = $self->bcs_schema();
3838 my $cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'data_agreement', 'project_property' );
3840 my $rs = $chado_schema->resultset("Project::Projectprop")->find({
3841 type_id
=> $cvterm->cvterm_id(),
3842 project_id
=> $self->get_trial_id(),
3846 return $rs->value();
3853 =head2 suppress_plot_phenotype
3855 Usage: my $suppress_return_error = $trial->suppress_plot_phenotype($trait_id, $plot_name, $plot_pheno_value, $phenotype_id);
3856 if ($suppress_return_error) {
3857 $c->stash->{rest} = { error => $suppress_return_error };
3861 Desc: Suppresses plot phenotype
3869 sub suppress_plot_phenotype
{
3871 my $trait_id = shift;
3872 my $plot_name = shift;
3873 my $phenotype_value = shift;
3874 my $phenotype_id = shift;
3875 my $username = shift;
3876 my $timestamp = shift;
3877 my $schema = $self->bcs_schema;
3878 my $trial_id = $self->get_trial_id();
3879 my $plot_type_id = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'plot', 'stock_type')->cvterm_id();
3880 my $phenotype_outlier_type_id = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'phenotype_outlier', 'phenotype_property')->cvterm_id();
3882 my $json_string = { value
=> 1, username
=>$username, timestamp
=>$timestamp };
3884 my $prop_rs = $self->bcs_schema->resultset('Phenotype::Phenotypeprop')->search(
3885 { 'phenotype_id' => $phenotype_id, 'type_id'=>$phenotype_outlier_type_id }
3888 if ($prop_rs->count == 0) {
3889 my $suppress_plot_pheno = $schema->resultset("Phenotype::Phenotypeprop")->create({
3890 phenotype_id
=> $phenotype_id,
3891 type_id
=> $phenotype_outlier_type_id,
3892 value
=> encode_json
$json_string,
3896 $error = "This plot phenotype has already been suppressed.";
3903 =head2 delete_assayed_trait
3905 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, [] );
3906 if ($delete_trait_return_error) {
3907 $c->stash->{rest} = { error => $delete_trait_return_error };
3911 Desc: Delete Assayed Traits
3919 sub delete_assayed_trait
{
3921 my $basepath = shift;
3926 my $temp_file_nd_experiment_id = shift;
3927 my $pheno_ids = shift;
3928 my $trait_ids = shift;
3930 my $trial_id = $self->get_trial_id();
3931 my $schema = $self->bcs_schema;
3932 my $phenome_schema = $self->phenome_schema;
3933 my ($error, @nd_expt_ids);
3934 my $nd_experiment_type_id = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'phenotyping_experiment', 'experiment_type')->cvterm_id();
3935 my $search_params = { 'nd_experiment.type_id' => $nd_experiment_type_id, 'nd_experiment_projects.project_id' => $trial_id };
3936 if (scalar(@
$trait_ids) > 0){
3937 $search_params->{'me.observable_id'} = { '-in' => $trait_ids };
3939 if (scalar(@
$pheno_ids) > 0){
3940 $search_params->{'me.phenotype_id'} = { '-in' => $pheno_ids };
3942 #$schema->storage->debug(1);
3943 if (scalar(@
$pheno_ids) > 0 || scalar(@
$trait_ids) > 0 ){
3944 my %phenotype_ids_and_nd_experiment_ids_to_delete;
3945 my $delete_pheno_id_rs = $schema->resultset("Phenotype::Phenotype")->search(
3948 join => { 'nd_experiment_phenotypes' => {'nd_experiment' => 'nd_experiment_projects'} },
3949 '+select' => ['nd_experiment.nd_experiment_id'],
3950 '+as' => ['nd_expt_id'],
3952 while ( my $res = $delete_pheno_id_rs->next()){
3953 push @
{$phenotype_ids_and_nd_experiment_ids_to_delete{nd_experiment_ids
}}, $res->get_column('nd_expt_id');
3954 push @
{$phenotype_ids_and_nd_experiment_ids_to_delete{phenotype_ids
}}, $res->phenotype_id;
3956 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);
3959 $error = "List of trait or phenotype ids was not provided for deletion.";
3964 =head2 function delete_empty_crossing_experiment()
3975 sub delete_empty_crossing_experiment
{
3978 if ($self->cross_count() > 0) {
3979 return 'Cannot delete crossing experiment with associated crosses.';
3983 my $row = $self->bcs_schema->resultset("Project::Project")->find( { project_id
=> $self->get_trial_id() });
3985 print STDERR
"deleted project ".$self->get_trial_id."\n";
3988 print STDERR
"An error occurred during deletion: $@\n";
3993 =head2 function cross_count()
3996 Desc: The number of crosses associated with this crossing experiment
4006 my $schema = $self->bcs_schema;
4007 my $crossing_experiment_type_id = SGN
::Model
::Cvterm
->get_cvterm_row($schema, "cross_experiment", "experiment_type")->cvterm_id();
4009 my $q = "SELECT count(nd_experiment_project.nd_experiment_id)
4010 FROM nd_experiment_project
4011 JOIN nd_experiment on (nd_experiment_project.nd_experiment_id = nd_experiment.nd_experiment_id)
4012 WHERE nd_experiment.type_id = $crossing_experiment_type_id
4013 AND nd_experiment_project.project_id = ?";
4014 my $h = $self->bcs_schema->storage->dbh()->prepare($q);
4015 $h->execute($self->get_trial_id());
4016 my ($count) = $h->fetchrow_array();
4022 ##__PACKAGE__->meta->make_immutable;