minor fixes
[sgn.git] / lib / CXGN / Trial / TrialCreate.pm
blob9cf950936f9f26db63579dd4f302e12fd2156440
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]]|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 my $number = 1;
249 foreach my $key (sort { $a cmp $b} keys %design) {
251 #print STDERR "Check 01: ".localtime();
253 my $plot_name;
254 if ($design{$key}->{plot_name}) {
255 $plot_name = $design{$key}->{plot_name};
257 my $plot_number;
258 if ($design{$key}->{plot_number}) {
259 $plot_number = $design{$key}->{plot_number};
261 my $plant_name;
262 if ($design{$key}->{plant_name}) {
263 $plant_name = $design{$key}->{plant_name};
265 my $stock_name;
266 if ($design{$key}->{stock_name}) {
267 $stock_name = $design{$key}->{stock_name};
269 my $block_number;
270 if ($design{$key}->{block_number}) { #set block number to 1 if no blocks are specified
271 $block_number = $design{$key}->{block_number};
272 } else {
273 $block_number = 1;
275 my $rep_number;
276 if ($design{$key}->{rep_number}) { #set rep number to 1 if no reps are specified
277 $rep_number = $design{$key}->{rep_number};
278 } else {
279 $rep_number = 1;
281 my $well;
282 if ($design{$key}->{well}) {
283 $well = $design{$key}->{well};
285 my $plate;
286 if ($design{$key}->{plate}) {
287 $plate = $design{$key}->{plate};
289 my $is_a_control;
290 if ($design{$key}->{is_a_control}) {
291 $is_a_control = $design{$key}->{is_a_control};
294 #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.
295 if ($stock_data{$stock_name}) {
296 $stock_id_checked = $stock_data{$stock_name}[0];
297 $organism_id_checked = $stock_data{$stock_name}[1];
298 } else {
299 my $parent_stock;
300 my $stock_lookup = CXGN::Stock::StockLookup->new(schema => $chado_schema);
301 $stock_lookup->set_stock_name($stock_name);
302 $parent_stock = $stock_lookup->get_stock();
304 if (!$parent_stock) {
305 die ("Error while saving trial layout: no stocks found matching $stock_name");
308 $stock_id_checked = $parent_stock->stock_id();
309 $organism_id_checked = $parent_stock->organism_id();
312 #print STDERR "Check 02: ".localtime();
314 #create the plot, if plot given
315 if ($plot_name) {
316 my $plot = $chado_schema->resultset("Stock::Stock")
317 ->find_or_create({
318 organism_id => $organism_id_checked,
319 name => $plot_name,
320 uniquename => $plot_name,
321 type_id => $plot_cvterm->cvterm_id,
323 if ($rep_number) {
324 $plot->create_stockprops({'replicate' => $rep_number}, {autocreate => 1} );
326 if ($block_number) {
327 $plot->create_stockprops({'block' => $block_number}, {autocreate => 1} );
329 if ($plot_number) {
330 $plot->create_stockprops({'plot number' => $plot_number}, {autocreate => 1});
332 else {
333 $plot->create_stockprops({'plot number' => $key}, {autocreate => 1});
336 if ($is_a_control) {
337 $plot->create_stockprops({'is a control' => $is_a_control}, {autocreate => 1} );
339 if ($design{$key}->{'range_number'}) {
340 $plot->create_stockprops({'range' => $key}, {autocreate => 1});
342 if ($well) {
343 $plot->create_stockprops({'well' => $well}, {autocreate => 1});
345 if ($plate) {
346 $plot->create_stockprops({'plate' => $plate}, {autocreate => 1});
349 # print STDERR "Check 03: ".localtime();
351 #create the stock_relationship of the accession with the plot, if it does not exist already
352 if (!$stock_relationship_data{$stock_id_checked, $plot_of->cvterm_id(), $plot->stock_id()} ) {
353 my $parent_stock = $chado_schema->resultset("Stock::StockRelationship")->create({
354 object_id => $stock_id_checked,
355 type_id => $plot_of->cvterm_id(),
356 subject_id => $plot->stock_id()
360 #link the experiment to the plot, if it is not already
361 if (!$stock_experiment_data{$plot->stock_id(), $field_layout_experiment->nd_experiment_id(), $field_layout_cvterm->cvterm_id()} ) {
362 my $stock_experiment_link = $chado_schema->resultset("NaturalDiversity::NdExperimentStock")->create({
363 nd_experiment_id => $field_layout_experiment->nd_experiment_id(),
364 type_id => $field_layout_cvterm->cvterm_id(),
365 stock_id => $plot->stock_id(),
370 #Create plant entry if given. Currently this is for the greenhouse trial creation.
371 #print STDERR "Check 04: ".localtime();
372 if ($plant_name) {
373 my $plant = $chado_schema->resultset("Stock::Stock")
374 ->find_or_create({
375 organism_id => $organism_id_checked,
376 name => $plant_name,
377 uniquename => $plant_name,
378 type_id => $plant_cvterm->cvterm_id,
381 my $plantprop = $chado_schema->resultset("Stock::Stockprop")->find_or_create( {
382 stock_id => $plant->stock_id(),
383 type_id => $plant_index_number_cvterm,
384 value => 1,
387 $plant->create_stockprops({'plot number' => $number}, {autocreate => 1});
388 $plant->create_stockprops({'replicate' => 1}, {autocreate => 1} );
389 $plant->create_stockprops({'block' => 1}, {autocreate => 1} );
390 $number ++;
392 #create the stock_relationship of the accession with the plant, if it does not exist already
393 if (!$stock_relationship_data{$stock_id_checked, $plot_of->cvterm_id(), $plant->stock_id()} ) {
394 my $parent_stock = $chado_schema->resultset("Stock::StockRelationship")->create({
395 object_id => $stock_id_checked,
396 type_id => $plant_of->cvterm_id(),
397 subject_id => $plant->stock_id()
401 #link the experiment to the plant, if it is not already
402 if (!$stock_experiment_data{$plant->stock_id(), $field_layout_experiment->nd_experiment_id(), $field_layout_cvterm->cvterm_id()} ) {
403 my $stock_experiment_link = $chado_schema->resultset("NaturalDiversity::NdExperimentStock")->create({
404 nd_experiment_id => $field_layout_experiment->nd_experiment_id(),
405 type_id => $field_layout_cvterm->cvterm_id(),
406 stock_id => $plant->stock_id(),
412 #print STDERR "Check 4.8: ".localtime();
414 $t->set_breeding_program($self->get_breeding_program_id);
416 #print STDERR "Check 4.9: ".localtime();
418 return ( trial_id => $project->project_id );
426 #######
428 #######