fix to years pheno download
[sgn.git] / lib / CXGN / Trial / TrialCreate.pm
blob465b5efb6359bbd2f3327319c46e05df8cc0cfda
1 package CXGN::Trial::TrialCreate;
3 =head1 NAME
5 CXGN::Trial::TrialCreate - Module to create a trial based on a specified design.
8 =head1 USAGE
10 my $trial_create = CXGN::Trial::TrialCreate->new({schema => $schema} );
13 =head1 DESCRIPTION
16 =head1 AUTHORS
18 Jeremy D. Edwards (jde22@cornell.edu)
20 =cut
23 use Moose;
24 use MooseX::FollowPBP;
25 use Moose::Util::TypeConstraints;
26 use Try::Tiny;
27 use CXGN::Stock::StockLookup;
28 use CXGN::Location::LocationLookup;
29 use CXGN::BreedersToolbox::Projects;
30 use CXGN::People::Person;
31 use CXGN::Trial;
32 use SGN::Model::Cvterm;
33 use Data::Dumper;
35 has 'chado_schema' => (
36 is => 'rw',
37 isa => 'DBIx::Class::Schema',
38 predicate => 'has_chado_schema',
39 required => 1,
41 has 'phenome_schema' => (
42 is => 'rw',
43 isa => 'DBIx::Class::Schema',
44 predicate => 'has_phenome_schema',
45 required => 1,
47 has 'metadata_schema' => (
48 is => 'rw',
49 isa => 'DBIx::Class::Schema',
50 predicate => 'has_metadata_schema',
51 required => 0,
54 has 'dbh' => (is => 'rw',predicate => 'has_dbh', required => 1,);
55 has 'user_name' => (isa => 'Str', is => 'rw', predicate => 'has_user_name', required => 1,);
56 #has 'location' => (isa =>'Str', is => 'rw', predicate => 'has_location', required => 1,);
57 has 'program' => (isa =>'Str', is => 'rw', predicate => 'has_program', required => 1,);
58 has 'trial_year' => (isa => 'Str', is => 'rw', predicate => 'has_trial_year', required => 1,);
59 has 'trial_description' => (isa => 'Str', is => 'rw', predicate => 'has_trial_description', required => 1,);
60 has 'trial_location' => (isa => 'Str', is => 'rw', predicate => 'has_trial_location', required => 1,);
61 has 'design_type' => (isa => 'Str', is => 'rw', predicate => 'has_design_type', required => 1);
62 has 'design' => (isa => 'HashRef[HashRef[Str|ArrayRef]]|Undef', is => 'rw', predicate => 'has_design', required => 1);
63 #has 'breeding_program_id' => (isa => 'Int', is => 'rw', predicate => 'has_breeding_program_id', required => 1);
64 has 'trial_name' => (isa => 'Str', is => 'rw', predicate => 'has_trial_name', required => 0,);
65 has 'greenhouse_num_plants' => (isa => 'ArrayRef[Int]|Undef', is => 'rw', predicate => 'has_greenhouse_num_plants', required => 0,);
66 has 'is_genotyping' => (isa => 'Bool', is => 'rw', required => 0, default => 0, );
67 has 'genotyping_user_id' => (isa => 'Str', is => 'rw');
69 has 'genotyping_project_name' => (isa => 'Str', is => 'rw');
71 # sub get_trial_name {
72 # my $self = shift;
73 # my $trial_name;
74 # if ($self->has_trial_year() && $self->has_trial_location()) {
75 # $trial_name = "Trial ".$self->get_trial_location()." ".$self->get_trial_year();
76 # }
77 # return $trial_name;
78 # }
80 sub trial_name_already_exists {
81 my $self = shift;
82 my $trial_name = $self->get_trial_name();
83 my $schema = $self->get_chado_schema();
84 if($schema->resultset('Project::Project')->find({name => $trial_name})){
85 return 1;
87 else {
88 return;
92 sub get_breeding_program_id {
93 my $self = shift;
94 my $project_lookup = CXGN::BreedersToolbox::Projects->new(schema => $self->get_chado_schema);
95 my $breeding_program_ref = $project_lookup->get_breeding_program_by_name($self->get_program());
96 if (!$breeding_program_ref ) {
97 print STDERR "UNDEF breeding program " . $self->get_program . "\n\n";
98 return ;
100 my $breeding_program_id = $breeding_program_ref->project_id();
101 print STDERR "get_breeding_program _id returning $breeding_program_id";
102 return $breeding_program_id;
106 sub save_trial {
107 #print STDERR "Check 4.1: ".localtime();
108 print STDERR "**trying to save trial \n\n";
109 my $self = shift;
110 my $chado_schema = $self->get_chado_schema();
112 my %design;
113 if ($self->get_design) {
114 %design = %{$self->get_design()};
117 if ($self->trial_name_already_exists()) {
118 print STDERR "Can't create trial: Trial name already exists\n";
119 die "trial name already exists" ;
122 if (!$self->get_breeding_program_id()) {
123 print STDERR "Can't create trial: Breeding program does not exist\n";
124 die "No breeding program id";
125 #return ( error => "no breeding program id" );
128 #print STDERR "Check 4.2: ".localtime();
130 #lookup user by name
131 my $user_name = $self->get_user_name();
132 my $dbh = $self->get_dbh();
133 my $owner_sp_person_id;
134 $owner_sp_person_id = CXGN::People::Person->get_person_by_username($dbh, $user_name); #add person id as an option.
135 if (!$owner_sp_person_id) {
136 print STDERR "Can't create trial: User/owner not found\n";
137 die "no owner $user_name" ;
140 #print STDERR "Check 4.3: ".localtime();
142 my $geolocation;
143 my $geolocation_lookup = CXGN::Location::LocationLookup->new(schema => $chado_schema);
144 $geolocation_lookup->set_location_name($self->get_trial_location());
145 $geolocation = $geolocation_lookup->get_geolocation();
146 if (!$geolocation) {
147 print STDERR "Can't create trial: Location not found\n";
148 die "no geolocation" ;
151 #print STDERR "Check 4.4: ".localtime();
153 my $field_layout_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'field_layout', 'experiment_type');
154 my $accession_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'accession', 'stock_type');
155 my $plot_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plot', 'stock_type');
156 my $plant_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plant', 'stock_type');
157 my $plot_of = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plot_of', 'stock_relationship');
158 my $plant_of = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plant_of', 'stock_relationship');
159 my $sample_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'tissue_sample', 'stock_type');
160 my $sample_of = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'tissue_sample_of', 'stock_relationship');
161 my $genotyping_layout_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'genotyping_layout', 'experiment_type');
162 my $plant_index_number_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'plant_index_number', 'stock_property')->cvterm_id();
164 my $project = $chado_schema->resultset('Project::Project')
165 ->create({
166 name => $self->get_trial_name(),
167 description => $self->get_trial_description(),
170 my $field_layout_experiment = $chado_schema->resultset('NaturalDiversity::NdExperiment')
171 ->create({
172 nd_geolocation_id => $geolocation->nd_geolocation_id(),
173 type_id => $field_layout_cvterm->cvterm_id(),
176 my $genotyping_layout_experiment = $chado_schema->resultset('NaturalDiversity::NdExperiment')
177 ->create({
178 nd_geolocation_id => $geolocation->nd_geolocation_id(),
179 type_id => $genotyping_layout_cvterm->cvterm_id(),
182 #print STDERR "Check 4.5: ".localtime();
184 #modify cvterms used to create the trial when it is a genotyping trial
185 if ($self->get_is_genotyping()){
186 $field_layout_cvterm = $genotyping_layout_cvterm;
187 $field_layout_experiment = $genotyping_layout_experiment;
188 $plot_cvterm = $sample_cvterm;
189 $plot_of = $sample_of;
191 #print STDERR "Storing user_id and project_name provided by the IGD spreadksheet for later recovery in the spreadsheet download... ".(join ",", ($self->get_genotyping_user_id(), $self->get_genotyping_project_name()))."\n";
193 $genotyping_layout_experiment->create_nd_experimentprops(
195 'genotyping_user_id' => $self->get_genotyping_user_id(),
196 'genotyping_project_name' => $self->get_genotyping_project_name(),
198 { autocreate => 1});
201 #print STDERR "Check 4.6: ".localtime();
203 my $t = CXGN::Trial->new( { bcs_schema => $chado_schema, trial_id => $project->project_id() } );
204 $t->set_location($geolocation->nd_geolocation_id()); # set location also as a project prop
206 my $design_type = $self->get_design_type();
207 if ($design_type eq 'greenhouse') {
208 my $has_plants_cvterm = SGN::Model::Cvterm->get_cvterm_row($chado_schema, 'project_has_plant_entries', 'project_property')->cvterm_id();
209 my $rs = $chado_schema->resultset("Project::Projectprop")->find_or_create({
210 type_id => $has_plants_cvterm,
211 value => 'varies',
212 project_id => $project->project_id(),
216 #link to the project
217 $field_layout_experiment->find_or_create_related('nd_experiment_projects',{project_id => $project->project_id()});
219 #print STDERR "Check 4.7: ".localtime();
221 $project->create_projectprops( { 'project year' => $self->get_trial_year(),'design' => $self->get_design_type()}, {autocreate=>1});
223 my $rs = $chado_schema->resultset('Stock::Stock')->search(
224 { 'me.is_obsolete' => { '!=' => 't' }, 'me.type_id' => $accession_cvterm->cvterm_id },
225 { join => [ 'stock_relationship_objects', 'nd_experiment_stocks' ],
226 '+select'=> ['me.stock_id', 'me.uniquename', 'me.organism_id', 'stock_relationship_objects.type_id', 'stock_relationship_objects.subject_id', 'nd_experiment_stocks.nd_experiment_id', 'nd_experiment_stocks.type_id'],
227 '+as'=> ['stock_id', 'uniquename', 'organism_id', 'stock_relationship_type_id', 'stock_relationship_subject_id', 'stock_experiment_id', 'stock_experiment_type_id']
231 my %stock_data;
232 my %stock_relationship_data;
233 my %stock_experiment_data;
234 while (my $s = $rs->next()) {
235 $stock_data{$s->get_column('uniquename')} = [$s->get_column('stock_id'), $s->get_column('organism_id') ];
236 if ($s->get_column('stock_relationship_type_id') && $s->get_column('stock_relationship_subject_id') ) {
237 $stock_relationship_data{$s->get_column('stock_id'), $s->get_column('stock_relationship_type_id'), $s->get_column('stock_relationship_subject_id') } = 1;
239 if ($s->get_column('stock_experiment_id') && $s->get_column('stock_experiment_type_id') ) {
240 $stock_experiment_data{$s->get_column('stock_id'), $s->get_column('stock_experiment_id'), $s->get_column('stock_experiment_type_id')} = 1;
244 my $stock_id_checked;
245 my $organism_id_checked;
247 #print STDERR Dumper \%design;
248 foreach my $key (sort { $a cmp $b} keys %design) {
250 #print STDERR "Check 01: ".localtime();
252 my $plot_name;
253 if ($design{$key}->{plot_name}) {
254 $plot_name = $design{$key}->{plot_name};
256 my $plot_number;
257 if ($design{$key}->{plot_number}) {
258 $plot_number = $design{$key}->{plot_number};
260 my $plant_names;
261 if ($design{$key}->{plant_names}) {
262 $plant_names = $design{$key}->{plant_names};
264 my $stock_name;
265 if ($design{$key}->{stock_name}) {
266 $stock_name = $design{$key}->{stock_name};
268 my $block_number;
269 if ($design{$key}->{block_number}) { #set block number to 1 if no blocks are specified
270 $block_number = $design{$key}->{block_number};
271 } else {
272 $block_number = 1;
274 my $rep_number;
275 if ($design{$key}->{rep_number}) { #set rep number to 1 if no reps are specified
276 $rep_number = $design{$key}->{rep_number};
277 } else {
278 $rep_number = 1;
280 my $well;
281 if ($design{$key}->{well}) {
282 $well = $design{$key}->{well};
284 my $plate;
285 if ($design{$key}->{plate}) {
286 $plate = $design{$key}->{plate};
288 my $is_a_control;
289 if ($design{$key}->{is_a_control}) {
290 $is_a_control = $design{$key}->{is_a_control};
292 my $row_number;
293 if ($design{$key}->{row_number}) {
294 $row_number = $design{$key}->{row_number};
296 my $col_number;
297 if ($design{$key}->{col_number}) {
298 $col_number = $design{$key}->{col_number};
303 #check if stock_name exists in database by checking if stock_name is key in %stock_data. if it is not, then check if it exists as a synonym in the database.
304 if ($stock_data{$stock_name}) {
305 $stock_id_checked = $stock_data{$stock_name}[0];
306 $organism_id_checked = $stock_data{$stock_name}[1];
307 } else {
308 my $parent_stock;
309 my $stock_lookup = CXGN::Stock::StockLookup->new(schema => $chado_schema);
310 $stock_lookup->set_stock_name($stock_name);
311 $parent_stock = $stock_lookup->get_stock();
313 if (!$parent_stock) {
314 die ("Error while saving trial layout: no stocks found matching $stock_name");
317 $stock_id_checked = $parent_stock->stock_id();
318 $organism_id_checked = $parent_stock->organism_id();
321 #print STDERR "Check 02: ".localtime();
323 #create the plot, if plot given
324 my $plot;
325 if ($plot_name) {
326 $plot = $chado_schema->resultset("Stock::Stock")
327 ->find_or_create({
328 organism_id => $organism_id_checked,
329 name => $plot_name,
330 uniquename => $plot_name,
331 type_id => $plot_cvterm->cvterm_id,
333 if ($rep_number) {
334 $plot->create_stockprops({'replicate' => $rep_number}, {autocreate => 1} );
336 if ($block_number) {
337 $plot->create_stockprops({'block' => $block_number}, {autocreate => 1} );
339 if ($plot_number) {
340 $plot->create_stockprops({'plot number' => $plot_number}, {autocreate => 1});
342 else {
343 $plot->create_stockprops({'plot number' => $key}, {autocreate => 1});
346 if ($is_a_control) {
347 $plot->create_stockprops({'is a control' => $is_a_control}, {autocreate => 1} );
349 if ($design{$key}->{'range_number'}) {
350 $plot->create_stockprops({'range' => $key}, {autocreate => 1});
352 if ($well) {
353 $plot->create_stockprops({'well' => $well}, {autocreate => 1});
355 if ($plate) {
356 $plot->create_stockprops({'plate' => $plate}, {autocreate => 1});
358 if ($row_number) {
359 $plot->create_stockprops({'row_number' => $row_number}, {autocreate => 1} );
361 if ($col_number) {
362 $plot->create_stockprops({'col_number' => $col_number}, {autocreate => 1} );
365 # print STDERR "Check 03: ".localtime();
367 #create the stock_relationship of the accession with the plot, if it does not exist already
368 if (!$stock_relationship_data{$stock_id_checked, $plot_of->cvterm_id(), $plot->stock_id()} ) {
369 my $parent_stock = $chado_schema->resultset("Stock::StockRelationship")->create({
370 object_id => $stock_id_checked,
371 type_id => $plot_of->cvterm_id(),
372 subject_id => $plot->stock_id()
376 #link the experiment to the plot, if it is not already
377 if (!$stock_experiment_data{$plot->stock_id(), $field_layout_experiment->nd_experiment_id(), $field_layout_cvterm->cvterm_id()} ) {
378 my $stock_experiment_link = $chado_schema->resultset("NaturalDiversity::NdExperimentStock")->create({
379 nd_experiment_id => $field_layout_experiment->nd_experiment_id(),
380 type_id => $field_layout_cvterm->cvterm_id(),
381 stock_id => $plot->stock_id(),
386 #Create plant entry if given. Currently this is for the greenhouse trial creation.
387 #print STDERR "Check 04: ".localtime();
388 if ($plant_names) {
389 foreach my $plant_name (@$plant_names) {
390 my $plant = $chado_schema->resultset("Stock::Stock")
391 ->find_or_create({
392 organism_id => $organism_id_checked,
393 name => $plant_name,
394 uniquename => $plant_name,
395 type_id => $plant_cvterm->cvterm_id,
398 my $plantprop = $chado_schema->resultset("Stock::Stockprop")->find_or_create( {
399 stock_id => $plant->stock_id(),
400 type_id => $plant_index_number_cvterm,
401 value => 1,
404 $plant->create_stockprops({'plot number' => $plot_number}, {autocreate => 1});
405 $plant->create_stockprops({'replicate' => $rep_number}, {autocreate => 1} );
406 $plant->create_stockprops({'block' => $block_number}, {autocreate => 1} );
408 #the plant has a relationship to the plot
409 if (!$stock_relationship_data{$plant->stock_id(), $plant_of->cvterm_id(), $plot->stock_id()} ) {
410 my $stock_relationship = $chado_schema->resultset("Stock::StockRelationship")->create({
411 subject_id => $plot->stock_id,
412 object_id => $plant->stock_id(),
413 type_id => $plant_of->cvterm_id(),
417 #create the stock_relationship of the accession with the plant, if it does not exist already
418 if (!$stock_relationship_data{$stock_id_checked, $plant_of->cvterm_id(), $plant->stock_id()} ) {
419 my $parent_stock = $chado_schema->resultset("Stock::StockRelationship")->create({
420 object_id => $stock_id_checked,
421 type_id => $plant_of->cvterm_id(),
422 subject_id => $plant->stock_id()
426 #link the experiment to the plant, if it is not already
427 if (!$stock_experiment_data{$plant->stock_id(), $field_layout_experiment->nd_experiment_id(), $field_layout_cvterm->cvterm_id()} ) {
428 my $stock_experiment_link = $chado_schema->resultset("NaturalDiversity::NdExperimentStock")->create({
429 nd_experiment_id => $field_layout_experiment->nd_experiment_id(),
430 type_id => $field_layout_cvterm->cvterm_id(),
431 stock_id => $plant->stock_id(),
438 #print STDERR "Check 4.8: ".localtime();
440 $t->set_breeding_program($self->get_breeding_program_id);
442 #print STDERR "Check 4.9: ".localtime();
444 return ( trial_id => $project->project_id );
452 #######
454 #######