1 package SGN
::Controller
::AJAX
::TrialMetadata
;
6 use Bio
::Chado
::Schema
;
7 use List
::Util qw
| any
|;
10 use List
::MoreUtils
qw(uniq);
11 use CXGN
::Trial
::FieldMap
;
13 use CXGN
::Phenotypes
::PhenotypeMatrix
;
16 use CXGN
::Phenotypes
::TrialPhenotype
;
19 use CXGN
::Stock
::Seedlot
;
20 use CXGN
::Stock
::Seedlot
::Transaction
;
21 use File
::Basename qw
| basename dirname
|;
22 use List
::MoreUtils
':all';
24 use CXGN
::BreederSearch
;
25 use CXGN
::Page
::FormattingHelpers qw
/ html_optional_show /;
28 BEGIN { extends
'Catalyst::Controller::REST' }
31 default => 'application/json',
33 map => { 'application/json' => 'JSON', 'text/html' => 'JSON' },
38 isa
=> 'DBIx::Class::Schema',
43 sub trial
: Chained
('/') PathPart
('ajax/breeders/trial') CaptureArgs
(1) {
48 my $bcs_schema = $c->dbic_schema("Bio::Chado::Schema");
49 my $metadata_schema = $c->dbic_schema('CXGN::Metadata::Schema');
50 my $phenome_schema = $c->dbic_schema('CXGN::Phenome::Schema');
52 $c->stash->{trial_id
} = $trial_id;
53 $c->stash->{schema
} = $bcs_schema;
54 $c->stash->{trial
} = CXGN
::Trial
->new({
55 bcs_schema
=> $bcs_schema,
56 metadata_schema
=> $metadata_schema,
57 phenome_schema
=> $phenome_schema,
61 if (!$c->stash->{trial
}) {
62 $c->stash->{rest
} = { error
=> "The specified trial with id $trial_id does not exist" };
67 my %param = ( schema
=> $bcs_schema, trial_id
=> $trial_id );
68 if ($c->stash->{trial
}->get_design_type() eq 'genotyping_plate'){
69 $param{experiment_type
} = 'genotyping_layout';
71 $param{experiment_type
} = 'field_layout';
73 $c->stash->{trial_layout
} = CXGN
::Trial
::TrialLayout
->new(\
%param);
76 print STDERR
"Trial Layout for $trial_id does not exist. @_\n";
81 =head2 delete_trial_by_file
90 sub delete_trial_data
: Local
() ActionClass
('REST');
92 sub delete_trial_data_GET
: Chained
('trial') PathPart
('delete') Args
(1) {
97 if ($self->privileges_denied($c)) {
98 $c->stash->{rest
} = { error
=> "You have insufficient access privileges to delete trial data." };
104 if ($datatype eq 'phenotypes') {
105 $error = $c->stash->{trial
}->delete_phenotype_metadata($c->dbic_schema("CXGN::Metadata::Schema"), $c->dbic_schema("CXGN::Phenome::Schema"));
106 $error .= $c->stash->{trial
}->delete_phenotype_data();
109 elsif ($datatype eq 'layout') {
110 $error = $c->stash->{trial
}->delete_metadata();
111 $error = $c->stash->{trial
}->delete_field_layout();
113 my $dbh = $c->dbc->dbh();
114 my $bs = CXGN
::BreederSearch
->new( { dbh
=>$dbh, dbname
=>$c->config->{dbname
}, } );
115 my $refresh = $bs->refresh_matviews($c->config->{dbhost
}, $c->config->{dbname
}, $c->config->{dbuser
}, $c->config->{dbpass
}, 'stockprop');
117 elsif ($datatype eq 'entry') {
118 $error = $c->stash->{trial
}->delete_project_entry();
121 $c->stash->{rest
} = { error
=> "unknown delete action for $datatype" };
125 $c->stash->{rest
} = { error
=> $error };
128 $c->stash->{rest
} = { message
=> "Successfully deleted trial data.", success
=> 1 };
131 sub trial_phenotypes_fully_uploaded
: Chained
('trial') PathPart
('phenotypes_fully_uploaded') Args
(0) ActionClass
('REST') {};
133 sub trial_phenotypes_fully_uploaded_GET
{
136 my $trial = $c->stash->{trial
};
137 $c->stash->{rest
} = { phenotypes_fully_uploaded
=> $trial->get_phenotypes_fully_uploaded() };
140 sub trial_phenotypes_fully_uploaded_POST
{
143 my $value = $c->req->param("phenotypes_fully_uploaded");
144 my $trial = $c->stash->{trial
};
146 $trial->set_phenotypes_fully_uploaded($value);
149 $c->stash->{rest
} = { error
=> "An error occurred setting phenotypes_fully_uploaded: $@" };
152 $c->stash->{rest
} = { success
=> 1 };
156 sub trial_details
: Chained
('trial') PathPart
('details') Args
(0) ActionClass
('REST') {};
158 sub trial_details_GET
{
162 my $trial = $c->stash->{trial
};
164 $c->stash->{rest
} = { details
=> $trial->get_details() };
168 sub trial_details_POST
{
172 my @categories = $c->req->param("categories[]");
175 foreach my $category (@categories) {
176 $details->{$category} = $c->req->param("details[$category]");
180 $c->stash->{rest
} = { error
=> "No values were edited, so no changes could be made for this trial's details." };
184 print STDERR
"Here are the deets: " . Dumper
($details) . "\n";
188 print STDERR
" curator status = ".$c->user()->check_roles('curator')." and submitter status = ".$c->user()->check_roles('submitter')."\n";
189 if (!($c->user()->check_roles('curator') || $c->user()->check_roles('submitter'))) {
190 $c->stash->{rest
} = { error
=> 'You do not have the required privileges to edit trial details, trial details can only be edited by accounts with submitter or curator privileges' };
194 my $trial_id = $c->stash->{trial_id
};
195 my $trial = $c->stash->{trial
};
196 my $program_object = CXGN
::BreedersToolbox
::Projects
->new( { schema
=> $c->stash->{schema
} });
197 my $program_ref = $program_object->get_breeding_programs_by_trial($trial_id);
199 my $program_array = @
$program_ref[0];
200 my $breeding_program_name = @
$program_array[1];
201 my @user_roles = $c->user->roles();
203 map { $has_roles{$_} = 1; } @user_roles;
205 print STDERR
"my user roles = @user_roles and trial breeding program = $breeding_program_name \n";
207 if (!exists($has_roles{$breeding_program_name})) {
208 $c->stash->{rest
} = { error
=> "You need to be associated with breeding program $breeding_program_name to change the details of this trial." };
212 # set each new detail that is defined
214 if ($details->{name
}) { $trial->set_name($details->{name
}); }
215 if ($details->{breeding_program
}) { $trial->set_breeding_program($details->{breeding_program
}); }
216 if ($details->{location
}) { $trial->set_location($details->{location
}); }
217 if ($details->{year
}) { $trial->set_year($details->{year
}); }
218 if ($details->{type
}) { $trial->set_project_type($details->{type
}); }
219 if ($details->{planting_date
}) {
220 if ($details->{planting_date
} eq 'remove') { $trial->remove_planting_date($trial->get_planting_date()); }
221 else { $trial->set_planting_date($details->{planting_date
}); }
223 if ($details->{harvest_date
}) {
224 if ($details->{harvest_date
} eq 'remove') { $trial->remove_harvest_date($trial->get_harvest_date()); }
225 else { $trial->set_harvest_date($details->{harvest_date
}); }
227 if ($details->{description
}) { $trial->set_description($details->{description
}); }
231 $c->stash->{rest
} = { error
=> "An error occurred setting the new trial details: $@" };
234 $c->stash->{rest
} = { success
=> 1 };
238 sub traits_assayed
: Chained
('trial') PathPart
('traits_assayed') Args
(0) {
241 my $stock_type = $c->req->param('stock_type');
243 my @traits_assayed = $c->stash->{trial
}->get_traits_assayed($stock_type);
244 $c->stash->{rest
} = { traits_assayed
=> \
@traits_assayed };
247 sub trait_phenotypes
: Chained
('trial') PathPart
('trait_phenotypes') Args
(0) {
250 #get userinfo from db
251 my $schema = $c->dbic_schema("Bio::Chado::Schema");
252 my $user = $c->user();
254 $c->stash->{rest
} = {
255 status
=> "not logged in"
259 my $display = $c->req->param('display');
260 my $trait = $c->req->param('trait');
261 my $phenotypes_search = CXGN
::Phenotypes
::PhenotypeMatrix
->new(
262 bcs_schema
=> $schema,
263 search_type
=> "Native",
264 data_level
=> $display,
265 trait_list
=> [$trait],
266 trial_list
=> [$c->stash->{trial_id
}]
268 my @data = $phenotypes_search->get_phenotype_matrix();
269 $c->stash->{rest
} = {
275 sub phenotype_summary
: Chained
('trial') PathPart
('phenotypes') Args
(0) {
279 my $schema = $c->stash->{schema
};
280 my $round = Math
::Round
::Var
->new(0.01);
281 my $dbh = $c->dbc->dbh();
282 my $trial_id = $c->stash->{trial_id
};
283 my $display = $c->req->param('display');
284 my $select_clause_additional = '';
285 my $group_by_additional = '';
286 my $order_by_additional = '';
289 my $total_complete_number;
290 if ($display eq 'plots') {
291 $stock_type_id = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'plot', 'stock_type')->cvterm_id();
292 $rel_type_id = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'plot_of', 'stock_relationship')->cvterm_id();
293 my $plots = $c->stash->{trial
}->get_plots();
294 $total_complete_number = scalar (@
$plots);
296 if ($display eq 'plants') {
297 $stock_type_id = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'plant', 'stock_type')->cvterm_id();
298 $rel_type_id = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'plant_of', 'stock_relationship')->cvterm_id();
299 my $plants = $c->stash->{trial
}->get_plants();
300 $total_complete_number = scalar (@
$plants);
302 if ($display eq 'subplots') {
303 $stock_type_id = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'subplot', 'stock_type')->cvterm_id();
304 $rel_type_id = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'subplot_of', 'stock_relationship')->cvterm_id();
305 my $subplots = $c->stash->{trial
}->get_subplots();
306 $total_complete_number = scalar (@
$subplots);
308 my $stocks_per_accession;
309 if ($display eq 'plots_accession') {
310 $stock_type_id = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'plot', 'stock_type')->cvterm_id();
311 $rel_type_id = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'plot_of', 'stock_relationship')->cvterm_id();
312 $select_clause_additional = ', accession.uniquename, accession.stock_id';
313 $group_by_additional = ', accession.stock_id, accession.uniquename';
314 $stocks_per_accession = $c->stash->{trial
}->get_plots_per_accession();
315 $order_by_additional = ' ,accession.uniquename DESC';
317 if ($display eq 'plants_accession') {
318 $stock_type_id = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'plant', 'stock_type')->cvterm_id();
319 $rel_type_id = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'plant_of', 'stock_relationship')->cvterm_id();
320 $select_clause_additional = ', accession.uniquename, accession.stock_id';
321 $group_by_additional = ', accession.stock_id, accession.uniquename';
322 $stocks_per_accession = $c->stash->{trial
}->get_plants_per_accession();
323 $order_by_additional = ' ,accession.uniquename DESC';
325 my $accesion_type_id = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'accession', 'stock_type')->cvterm_id();
327 my $h = $dbh->prepare("SELECT (((cvterm.name::text || '|'::text) || db.name::text) || ':'::text) || dbxref.accession::text AS trait,
329 count(phenotype.value),
330 to_char(avg(phenotype.value::real), 'FM999990.990'),
331 to_char(max(phenotype.value::real), 'FM999990.990'),
332 to_char(min(phenotype.value::real), 'FM999990.990'),
333 to_char(stddev(phenotype.value::real), 'FM999990.990')
334 $select_clause_additional
336 JOIN phenotype ON (cvterm_id=cvalue_id)
337 JOIN nd_experiment_phenotype USING(phenotype_id)
338 JOIN nd_experiment_project USING(nd_experiment_id)
339 JOIN nd_experiment_stock USING(nd_experiment_id)
340 JOIN stock as plot USING(stock_id)
341 JOIN stock_relationship on (plot.stock_id = stock_relationship.subject_id)
342 JOIN stock as accession on (accession.stock_id = stock_relationship.object_id)
343 JOIN dbxref ON cvterm.dbxref_id = dbxref.dbxref_id JOIN db ON dbxref.db_id = db.db_id
345 AND phenotype.value~?
346 AND stock_relationship.type_id=?
348 AND accession.type_id=?
349 GROUP BY (((cvterm.name::text || '|'::text) || db.name::text) || ':'::text) || dbxref.accession::text, cvterm.cvterm_id $group_by_additional
350 ORDER BY cvterm.name ASC
351 $order_by_additional;");
353 my $numeric_regex = '^[0-9]+([,.][0-9]+)?$';
354 $h->execute($c->stash->{trial_id
}, $numeric_regex, $rel_type_id, $stock_type_id, $accesion_type_id);
358 while (my ($trait, $trait_id, $count, $average, $max, $min, $stddev, $stock_name, $stock_id) = $h->fetchrow_array()) {
361 if ($stddev && $average != 0) {
362 $cv = ($stddev / $average) * 100;
363 $cv = $round->round($cv) . '%';
365 if ($average) { $average = $round->round($average); }
366 if ($min) { $min = $round->round($min); }
367 if ($max) { $max = $round->round($max); }
368 if ($stddev) { $stddev = $round->round($stddev); }
371 if ($stock_name && $stock_id) {
372 $total_complete_number = scalar (@
{$stocks_per_accession->{$stock_id}});
373 push @return_array, qq{<a href
="/stock/$stock_id/view">$stock_name</a
>};
375 my $percent_missing = '';
376 if ($total_complete_number){
377 $percent_missing = 100 - sprintf("%.2f", ($count/$total_complete_number)*100)."%";
380 push @return_array, ( qq{<a href
="/cvterm/$trait_id/view">$trait</a
>}, $average, $min, $max, $stddev, $cv, $count, $percent_missing, qq{<a href
="#raw_data_histogram_well" onclick
="trait_summary_hist_change($trait_id)"><span
class="glyphicon glyphicon-stats"></span></a>} );
381 push @phenotype_data, \
@return_array;
384 $c->stash->{rest
} = { data
=> \
@phenotype_data };
387 sub trait_histogram
: Chained
('trial') PathPart
('trait_histogram') Args
(1) {
390 my $trait_id = shift;
391 my $stock_type = $c->req->param('stock_type') || 'plot';
393 my @data = $c->stash->{trial
}->get_phenotypes_for_trait($trait_id, $stock_type);
395 $c->stash->{rest
} = { data
=> \
@data };
398 sub get_trial_folder
:Chained
('trial') PathPart
('folder') Args
(0) {
402 if (!($c->user()->check_roles('curator') || $c->user()->check_roles('submitter'))) {
403 $c->stash->{rest
} = { error
=> 'You do not have the required privileges to edit the trial type of this trial.' };
407 my $project_parent = $c->stash->{trial
}->get_folder();
409 $c->stash->{rest
} = { folder
=> [ $project_parent->project_id(), $project_parent->name() ] };
413 sub get_trial_location
:Chained
('trial') PathPart
('location') Args
(0) {
416 my $location = $c->stash->{trial
}->get_location;
417 $c->stash->{rest
} = { location
=> $location };
420 sub trial_accessions
: Chained
('trial') PathPart
('accessions') Args
(0) {
423 my $schema = $c->dbic_schema("Bio::Chado::Schema");
425 my $trial = CXGN
::Trial
->new( { bcs_schema
=> $schema, trial_id
=> $c->stash->{trial_id
} });
427 my @data = $trial->get_accessions();
429 $c->stash->{rest
} = { accessions
=> \
@data };
432 sub trial_tissue_sources
: Chained
('trial') PathPart
('tissue_sources') Args
(0) {
435 my $schema = $c->dbic_schema("Bio::Chado::Schema");
437 my $trial = CXGN
::Trial
->new( { bcs_schema
=> $schema, trial_id
=> $c->stash->{trial_id
} });
438 my $data = $trial->get_tissue_sources();
439 print STDERR Dumper
$data;
440 $c->stash->{rest
} = { tissue_sources
=> $data };
443 sub trial_seedlots
: Chained
('trial') PathPart
('seedlots') Args
(0) {
446 my $schema = $c->dbic_schema("Bio::Chado::Schema");
448 my $trial = CXGN
::Trial
->new( { bcs_schema
=> $schema, trial_id
=> $c->stash->{trial_id
} });
450 my @data = $trial->get_seedlots();
452 $c->stash->{rest
} = { seedlots
=> \
@data };
455 sub trial_used_seedlots_upload
: Chained
('trial') PathPart
('upload_used_seedlots') Args
(0) {
461 my $session_id = $c->req->param("sgn_session_id");
464 my $dbh = $c->dbc->dbh;
465 my @user_info = CXGN
::Login
->new($dbh)->query_from_cookie($session_id);
467 $c->stash->{rest
} = {error
=>'You must be logged in to upload this seedlot info!'};
470 $user_id = $user_info[0];
471 $user_role = $user_info[1];
472 my $p = CXGN
::People
::Person
->new($dbh, $user_id);
473 $user_name = $p->get_username;
476 $c->stash->{rest
} = {error
=>'You must be logged in to upload this seedlot info!'};
479 $user_id = $c->user()->get_object()->get_sp_person_id();
480 $user_name = $c->user()->get_object()->get_username();
481 $user_role = $c->user->get_object->get_user_type();
484 my $schema = $c->dbic_schema("Bio::Chado::Schema");
485 my $upload = $c->req->upload('trial_upload_used_seedlot_file');
486 my $subdirectory = "trial_used_seedlot_upload";
487 my $upload_original_name = $upload->filename();
488 my $upload_tempfile = $upload->tempname;
489 my $time = DateTime
->now();
490 my $timestamp = $time->ymd()."_".$time->hms();
492 ## Store uploaded temporary file in archive
493 my $uploader = CXGN
::UploadFile
->new({
494 tempfile
=> $upload_tempfile,
495 subdirectory
=> $subdirectory,
496 archive_path
=> $c->config->{archive_path
},
497 archive_filename
=> $upload_original_name,
498 timestamp
=> $timestamp,
500 user_role
=> $user_role
502 my $archived_filename_with_path = $uploader->archive();
503 my $md5 = $uploader->get_md5($archived_filename_with_path);
504 if (!$archived_filename_with_path) {
505 $c->stash->{rest
} = {error
=> "Could not save file $upload_original_name in archive",};
508 unlink $upload_tempfile;
509 my $parser = CXGN
::Trial
::ParseUpload
->new(chado_schema
=> $schema, filename
=> $archived_filename_with_path);
510 $parser->load_plugin('TrialUsedSeedlotsXLS');
511 my $parsed_data = $parser->parse();
512 #print STDERR Dumper $parsed_data;
515 my $return_error = '';
517 if (!$parser->has_parse_errors() ){
518 $c->stash->{rest
} = {error_string
=> "Could not get parsing errors"};
521 $parse_errors = $parser->get_parse_errors();
522 #print STDERR Dumper $parse_errors;
524 foreach my $error_string (@
{$parse_errors->{'error_messages'}}){
525 $return_error .= $error_string."<br>";
528 $c->stash->{rest
} = {error_string
=> $return_error, missing_seedlots
=> $parse_errors->{'missing_seedlots'}, missing_plots
=> $parse_errors->{'missing_plots'}};
532 my $upload_used_seedlots_txn = sub {
533 while (my ($key, $val) = each(%$parsed_data)){
534 my $sl = CXGN
::Stock
::Seedlot
->new(schema
=> $schema, seedlot_id
=> $val->{seedlot_stock_id
});
536 my $transaction = CXGN
::Stock
::Seedlot
::Transaction
->new(schema
=> $schema);
537 $transaction->factor(1);
538 $transaction->from_stock([$val->{seedlot_stock_id
}, $val->{seedlot_name
}]);
539 $transaction->to_stock([$val->{plot_stock_id
}, $val->{plot_name
}]);
540 $transaction->amount($val->{amount
});
541 $transaction->weight_gram($val->{weight_gram
});
542 $transaction->timestamp($timestamp);
543 $transaction->description($val->{description
});
544 $transaction->operator($user_name);
545 $transaction->store();
547 $sl->set_current_count_property();
548 $sl->set_current_weight_property();
550 my $layout = $c->stash->{trial_layout
};
551 $layout->generate_and_cache_layout();
554 $schema->txn_do($upload_used_seedlots_txn);
557 $c->stash->{rest
} = { error
=> $@
};
558 print STDERR
"An error condition occurred, was not able to upload trial used seedlots. ($@).\n";
562 my $dbh = $c->dbc->dbh();
563 my $bs = CXGN
::BreederSearch
->new( { dbh
=>$dbh, dbname
=>$c->config->{dbname
}, } );
564 my $refresh = $bs->refresh_matviews($c->config->{dbhost
}, $c->config->{dbname
}, $c->config->{dbuser
}, $c->config->{dbpass
}, 'stockprop');
566 $c->stash->{rest
} = { success
=> 1 };
569 sub trial_upload_plants
: Chained
('trial') PathPart
('upload_plants') Args
(0) {
575 my $session_id = $c->req->param("sgn_session_id");
578 my $dbh = $c->dbc->dbh;
579 my @user_info = CXGN
::Login
->new($dbh)->query_from_cookie($session_id);
581 $c->stash->{rest
} = {error
=>'You must be logged in to upload this seedlot info!'};
584 $user_id = $user_info[0];
585 $user_role = $user_info[1];
586 my $p = CXGN
::People
::Person
->new($dbh, $user_id);
587 $user_name = $p->get_username;
590 $c->stash->{rest
} = {error
=>'You must be logged in to upload this seedlot info!'};
593 $user_id = $c->user()->get_object()->get_sp_person_id();
594 $user_name = $c->user()->get_object()->get_username();
595 $user_role = $c->user->get_object->get_user_type();
598 my $schema = $c->dbic_schema("Bio::Chado::Schema");
599 my $upload = $c->req->upload('trial_upload_plants_file');
600 my $inherits_plot_treatments = $c->req->param('upload_plants_per_plot_inherit_treatments');
601 my $plants_per_plot = $c->req->param('upload_plants_per_plot_number');
603 my $subdirectory = "trial_plants_upload";
604 my $upload_original_name = $upload->filename();
605 my $upload_tempfile = $upload->tempname;
606 my $time = DateTime
->now();
607 my $timestamp = $time->ymd()."_".$time->hms();
609 ## Store uploaded temporary file in archive
610 my $uploader = CXGN
::UploadFile
->new({
611 tempfile
=> $upload_tempfile,
612 subdirectory
=> $subdirectory,
613 archive_path
=> $c->config->{archive_path
},
614 archive_filename
=> $upload_original_name,
615 timestamp
=> $timestamp,
617 user_role
=> $user_role
619 my $archived_filename_with_path = $uploader->archive();
620 my $md5 = $uploader->get_md5($archived_filename_with_path);
621 if (!$archived_filename_with_path) {
622 $c->stash->{rest
} = {error
=> "Could not save file $upload_original_name in archive",};
625 unlink $upload_tempfile;
626 my $parser = CXGN
::Trial
::ParseUpload
->new(chado_schema
=> $schema, filename
=> $archived_filename_with_path);
627 $parser->load_plugin('TrialPlantsXLS');
628 my $parsed_data = $parser->parse();
629 #print STDERR Dumper $parsed_data;
632 my $return_error = '';
634 if (!$parser->has_parse_errors() ){
635 $c->stash->{rest
} = {error_string
=> "Could not get parsing errors"};
638 $parse_errors = $parser->get_parse_errors();
639 #print STDERR Dumper $parse_errors;
641 foreach my $error_string (@
{$parse_errors->{'error_messages'}}){
642 $return_error .= $error_string."<br>";
645 $c->stash->{rest
} = {error_string
=> $return_error, missing_plots
=> $parse_errors->{'missing_plots'}};
649 my $upload_plants_txn = sub {
651 while (my ($key, $val) = each(%$parsed_data)){
652 $plot_plant_hash{$val->{plot_stock_id
}}->{plot_name
} = $val->{plot_name
};
653 push @
{$plot_plant_hash{$val->{plot_stock_id
}}->{plant_names
}}, $val->{plant_name
};
655 my $t = CXGN
::Trial
->new( { bcs_schema
=> $c->dbic_schema("Bio::Chado::Schema"), trial_id
=> $c->stash->{trial_id
} });
656 $t->save_plant_entries(\
%plot_plant_hash, $plants_per_plot, $inherits_plot_treatments);
658 my $layout = $c->stash->{trial_layout
};
659 $layout->generate_and_cache_layout();
662 $schema->txn_do($upload_plants_txn);
665 $c->stash->{rest
} = { error
=> $@
};
666 print STDERR
"An error condition occurred, was not able to upload trial plants. ($@).\n";
670 my $dbh = $c->dbc->dbh();
671 my $bs = CXGN
::BreederSearch
->new( { dbh
=>$dbh, dbname
=>$c->config->{dbname
}, } );
672 my $refresh = $bs->refresh_matviews($c->config->{dbhost
}, $c->config->{dbname
}, $c->config->{dbuser
}, $c->config->{dbpass
}, 'stockprop');
674 $c->stash->{rest
} = { success
=> 1 };
677 sub trial_plot_gps_upload
: Chained
('trial') PathPart
('upload_plot_gps') Args
(0) {
683 my $session_id = $c->req->param("sgn_session_id");
686 my $dbh = $c->dbc->dbh;
687 my @user_info = CXGN
::Login
->new($dbh)->query_from_cookie($session_id);
689 $c->stash->{rest
} = {error
=>'You must be logged in to upload this seedlot info!'};
692 $user_id = $user_info[0];
693 $user_role = $user_info[1];
694 my $p = CXGN
::People
::Person
->new($dbh, $user_id);
695 $user_name = $p->get_username;
698 $c->stash->{rest
} = {error
=>'You must be logged in to upload this seedlot info!'};
701 $user_id = $c->user()->get_object()->get_sp_person_id();
702 $user_name = $c->user()->get_object()->get_username();
703 $user_role = $c->user->get_object->get_user_type();
706 my $schema = $c->dbic_schema("Bio::Chado::Schema");
708 #Check that trial has a location set
709 my $field_experiment_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'field_layout', 'experiment_type')->cvterm_id();
710 my $nd_geolocation_rs = $schema->resultset('NaturalDiversity::NdGeolocation')->search(
711 {'nd_experiments.type_id'=>$field_experiment_cvterm_id, 'project.project_id'=>$c->stash->{trial_id
}},
712 { 'join' => { 'nd_experiments' => {'nd_experiment_projects'=>'project'} } }
714 my $nd_geolocation = $nd_geolocation_rs->first;
715 if (!$nd_geolocation){
716 $c->stash->{rest
} = {error
=>'This trial has no location set!'};
720 my $upload = $c->req->upload('trial_upload_plot_gps_file');
721 my $subdirectory = "trial_plot_gps_upload";
722 my $upload_original_name = $upload->filename();
723 my $upload_tempfile = $upload->tempname;
724 my $time = DateTime
->now();
725 my $timestamp = $time->ymd()."_".$time->hms();
727 ## Store uploaded temporary file in archive
728 my $uploader = CXGN
::UploadFile
->new({
729 tempfile
=> $upload_tempfile,
730 subdirectory
=> $subdirectory,
731 archive_path
=> $c->config->{archive_path
},
732 archive_filename
=> $upload_original_name,
733 timestamp
=> $timestamp,
735 user_role
=> $user_role
737 my $archived_filename_with_path = $uploader->archive();
738 my $md5 = $uploader->get_md5($archived_filename_with_path);
739 if (!$archived_filename_with_path) {
740 $c->stash->{rest
} = {error
=> "Could not save file $upload_original_name in archive",};
743 unlink $upload_tempfile;
744 my $parser = CXGN
::Trial
::ParseUpload
->new(chado_schema
=> $schema, filename
=> $archived_filename_with_path);
745 $parser->load_plugin('TrialPlotGPSCoordinatesXLS');
746 my $parsed_data = $parser->parse();
747 #print STDERR Dumper $parsed_data;
750 my $return_error = '';
752 if (!$parser->has_parse_errors() ){
753 $c->stash->{rest
} = {error_string
=> "Could not get parsing errors"};
756 $parse_errors = $parser->get_parse_errors();
757 #print STDERR Dumper $parse_errors;
759 foreach my $error_string (@
{$parse_errors->{'error_messages'}}){
760 $return_error .= $error_string."<br>";
763 $c->stash->{rest
} = {error_string
=> $return_error, missing_plots
=> $parse_errors->{'missing_plots'}};
767 my $stock_geo_json_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'plot_geo_json', 'stock_property');
769 my $upload_plot_gps_txn = sub {
770 my %plot_stock_ids_hash;
771 while (my ($key, $val) = each(%$parsed_data)){
772 $plot_stock_ids_hash{$val->{plot_stock_id
}} = $val;
774 my @plot_stock_ids = keys %plot_stock_ids_hash;
775 my $plots_rs = $schema->resultset("Stock::Stock")->search({stock_id
=> {-in=>\
@plot_stock_ids}});
776 while (my $plot=$plots_rs->next){
777 my $coords = $plot_stock_ids_hash{$plot->stock_id};
784 [$coords->{WGS84_bottom_left_x
}, $coords->{WGS84_bottom_left_y
}],
785 [$coords->{WGS84_bottom_right_x
}, $coords->{WGS84_bottom_right_y
}],
786 [$coords->{WGS84_top_right_x
}, $coords->{WGS84_top_right_y
}],
787 [$coords->{WGS84_top_left_x
}, $coords->{WGS84_top_left_y
}],
788 [$coords->{WGS84_bottom_left_x
}, $coords->{WGS84_bottom_left_y
}],
796 my $geno_json_string = encode_json
$geo_json;
797 #print STDERR $geno_json_string."\n";
798 my $previous_plot_gps_rs = $schema->resultset("Stock::Stockprop")->search({stock_id
=>$plot->stock_id, type_id
=>$stock_geo_json_cvterm->cvterm_id});
799 $previous_plot_gps_rs->delete_all();
800 $plot->create_stockprops({$stock_geo_json_cvterm->name() => $geno_json_string});
802 my $layout = $c->stash->{trial_layout
};
803 $layout->generate_and_cache_layout();
806 $schema->txn_do($upload_plot_gps_txn);
809 $c->stash->{rest
} = { error
=> $@
};
810 print STDERR
"An error condition occurred, was not able to upload trial plot GPS coordinates. ($@).\n";
814 my $dbh = $c->dbc->dbh();
815 my $bs = CXGN
::BreederSearch
->new( { dbh
=>$dbh, dbname
=>$c->config->{dbname
}, } );
816 my $refresh = $bs->refresh_matviews($c->config->{dbhost
}, $c->config->{dbname
}, $c->config->{dbuser
}, $c->config->{dbpass
}, 'stockprop');
818 $c->stash->{rest
} = { success
=> 1 };
821 sub trial_additional_file_upload
: Chained
('trial') PathPart
('upload_additional_file') Args
(0) {
827 my $session_id = $c->req->param("sgn_session_id");
830 my $dbh = $c->dbc->dbh;
831 my @user_info = CXGN
::Login
->new($dbh)->query_from_cookie($session_id);
833 $c->stash->{rest
} = {error
=>'You must be logged in to upload additional trials to a file!'};
836 $user_id = $user_info[0];
837 $user_role = $user_info[1];
838 my $p = CXGN
::People
::Person
->new($dbh, $user_id);
839 $user_name = $p->get_username;
842 $c->stash->{rest
} = {error
=>'You must be logged in to upload additional files to a trial!'};
845 $user_id = $c->user()->get_object()->get_sp_person_id();
846 $user_name = $c->user()->get_object()->get_username();
847 $user_role = $c->user->get_object->get_user_type();
850 my $upload = $c->req->upload('trial_upload_additional_file');
851 my $subdirectory = "trial_additional_file_upload";
852 my $upload_original_name = $upload->filename();
853 my $upload_tempfile = $upload->tempname;
854 my $time = DateTime
->now();
855 my $timestamp = $time->ymd()."_".$time->hms();
857 ## Store uploaded temporary file in archive
858 my $uploader = CXGN
::UploadFile
->new({
859 tempfile
=> $upload_tempfile,
860 subdirectory
=> $subdirectory,
861 archive_path
=> $c->config->{archive_path
},
862 archive_filename
=> $upload_original_name,
863 timestamp
=> $timestamp,
865 user_role
=> $user_role
867 my $archived_filename_with_path = $uploader->archive();
868 my $md5 = $uploader->get_md5($archived_filename_with_path);
869 if (!$archived_filename_with_path) {
870 $c->stash->{rest
} = {error
=> "Could not save file $upload_original_name in archive",};
873 unlink $upload_tempfile;
874 my $md5checksum = $md5->hexdigest();
876 my $result = $c->stash->{trial
}->add_additional_uploaded_file($user_id, $archived_filename_with_path, $md5checksum);
877 if ($result->{error
}){
878 $c->stash->{rest
} = {error
=>$result->{error
}};
881 $c->stash->{rest
} = { success
=> 1, file_id
=> $result->{file_id
} };
884 sub get_trial_additional_file_uploaded
: Chained
('trial') PathPart
('get_uploaded_additional_file') Args
(0) {
889 $c->stash->{rest
} = {error
=>'You must be logged in to see uploaded additional files!'};
893 my $files = $c->stash->{trial
}->get_additional_uploaded_files();
894 $c->stash->{rest
} = {success
=>1, files
=>$files};
897 sub trial_controls
: Chained
('trial') PathPart
('controls') Args
(0) {
900 my $schema = $c->dbic_schema("Bio::Chado::Schema");
902 my $trial = CXGN
::Trial
->new( { bcs_schema
=> $schema, trial_id
=> $c->stash->{trial_id
} });
904 my @data = $trial->get_controls();
906 $c->stash->{rest
} = { accessions
=> \
@data };
909 sub controls_by_plot
: Chained
('trial') PathPart
('controls_by_plot') Args
(0) {
912 my $schema = $c->dbic_schema("Bio::Chado::Schema");
913 my @plot_ids = $c->req->param('plot_ids[]');
915 my $trial = CXGN
::Trial
->new({ bcs_schema
=> $schema, trial_id
=> $c->stash->{trial_id
} });
917 my @data = $trial->get_controls_by_plot(\
@plot_ids);
919 $c->stash->{rest
} = { accessions
=> \
@data };
922 sub trial_plots
: Chained
('trial') PathPart
('plots') Args
(0) {
925 my $schema = $c->dbic_schema("Bio::Chado::Schema");
927 my $trial = $c->stash->{trial
};
929 my @data = $trial->get_plots();
931 $c->stash->{rest
} = { plots
=> \
@data };
934 sub trial_has_subplots
: Chained
('trial') PathPart
('has_subplots') Args
(0) {
937 my $schema = $c->dbic_schema("Bio::Chado::Schema");
939 my $trial = $c->stash->{trial
};
940 $c->stash->{rest
} = { has_subplots
=> $trial->has_subplot_entries(), trial_name
=> $trial->get_name };
943 sub trial_subplots
: Chained
('trial') PathPart
('subplots') Args
(0) {
946 my $schema = $c->dbic_schema("Bio::Chado::Schema");
948 my $trial = $c->stash->{trial
};
950 my @data = $trial->get_subplots();
952 $c->stash->{rest
} = { subplots
=> \
@data };
955 sub trial_has_plants
: Chained
('trial') PathPart
('has_plants') Args
(0) {
958 my $schema = $c->dbic_schema("Bio::Chado::Schema");
960 my $trial = $c->stash->{trial
};
961 $c->stash->{rest
} = { has_plants
=> $trial->has_plant_entries(), trial_name
=> $trial->get_name };
964 sub trial_plants
: Chained
('trial') PathPart
('plants') Args
(0) {
967 my $schema = $c->dbic_schema("Bio::Chado::Schema");
969 my $trial = $c->stash->{trial
};
971 my @data = $trial->get_plants();
973 $c->stash->{rest
} = { plants
=> \
@data };
976 sub trial_has_tissue_samples
: Chained
('trial') PathPart
('has_tissue_samples') Args
(0) {
979 my $schema = $c->dbic_schema("Bio::Chado::Schema");
981 my $trial = $c->stash->{trial
};
982 $c->stash->{rest
} = { has_tissue_samples
=> $trial->has_tissue_sample_entries(), trial_name
=> $trial->get_name };
985 sub trial_tissue_samples
: Chained
('trial') PathPart
('tissue_samples') Args
(0) {
988 my $schema = $c->dbic_schema("Bio::Chado::Schema");
990 my $trial = $c->stash->{trial
};
992 my $data = $trial->get_tissue_samples();
994 $c->stash->{rest
} = { trial_tissue_samples
=> $data };
997 sub trial_treatments
: Chained
('trial') PathPart
('treatments') Args
(0) {
1000 my $schema = $c->dbic_schema("Bio::Chado::Schema");
1002 my $trial = $c->stash->{trial
};
1004 my $data = $trial->get_treatments();
1006 $c->stash->{rest
} = { treatments
=> $data };
1009 sub trial_add_treatment
: Chained
('trial') PathPart
('add_treatment') Args
(0) {
1014 $c->stash->{rest
} = {error
=> "You must be logged in to add a treatment"};
1018 my $schema = $c->dbic_schema('Bio::Chado::Schema');
1019 my $trial_id = $c->stash->{trial_id
};
1020 my $trial = $c->stash->{trial
};
1021 my $design = decode_json
$c->req->param('design');
1022 my $new_treatment_has_plant_entries = $c->req->param('has_plant_entries');
1023 my $new_treatment_has_subplot_entries = $c->req->param('has_subplot_entries');
1024 my $new_treatment_has_tissue_entries = $c->req->param('has_tissue_sample_entries');
1026 my $trial_design_store = CXGN
::Trial
::TrialDesignStore
->new({
1027 bcs_schema
=> $schema,
1028 trial_id
=> $trial_id,
1029 trial_name
=> $trial->get_name(),
1030 nd_geolocation_id
=> $trial->get_location()->[0],
1031 design_type
=> $trial->get_design_type(),
1033 new_treatment_has_plant_entries
=> $new_treatment_has_plant_entries,
1034 new_treatment_has_subplot_entries
=> $new_treatment_has_subplot_entries,
1035 new_treatment_has_tissue_sample_entries
=> $new_treatment_has_subplot_entries,
1036 operator
=> $c->user()->get_object()->get_username()
1038 my $error = $trial_design_store->store();
1040 $c->stash->{rest
} = {error
=> "Treatment not added: ".$error};
1042 $c->stash->{rest
} = {success
=> 1};
1046 sub trial_layout
: Chained
('trial') PathPart
('layout') Args
(0) {
1049 my $schema = $c->dbic_schema("Bio::Chado::Schema");
1051 my $layout = $c->stash->{trial_layout
};
1053 my $design = $layout->get_design();
1054 $c->stash->{rest
} = {design
=> $design};
1057 sub trial_design
: Chained
('trial') PathPart
('design') Args
(0) {
1060 my $schema = $c->dbic_schema("Bio::Chado::Schema");
1062 my $layout = $c->stash->{trial_layout
};
1064 my $design = $layout->get_design();
1065 my $design_type = $layout->get_design_type();
1066 my $plot_dimensions = $layout->get_plot_dimensions();
1068 my $plot_length = '';
1069 if ($plot_dimensions->[0]) {
1070 $plot_length = $plot_dimensions->[0];
1073 my $plot_width = '';
1074 if ($plot_dimensions->[1]){
1075 $plot_width = $plot_dimensions->[1];
1078 my $plants_per_plot = '';
1079 if ($plot_dimensions->[2]){
1080 $plants_per_plot = $plot_dimensions->[2];
1083 my $block_numbers = $layout->get_block_numbers();
1084 my $number_of_blocks = '';
1085 if ($block_numbers) {
1086 $number_of_blocks = scalar(@
{$block_numbers});
1089 my $replicate_numbers = $layout->get_replicate_numbers();
1090 my $number_of_replicates = '';
1091 if ($replicate_numbers) {
1092 $number_of_replicates = scalar(@
{$replicate_numbers});
1095 $c->stash->{rest
} = { design_type
=> $design_type, num_blocks
=> $number_of_blocks, num_reps
=> $number_of_replicates, plot_length
=> $plot_length, plot_width
=> $plot_width, plants_per_plot
=> $plants_per_plot, design
=> $design };
1098 sub get_spatial_layout
: Chained
('trial') PathPart
('coords') Args
(0) {
1102 my $schema = $c->dbic_schema("Bio::Chado::Schema");
1104 my $fieldmap = CXGN
::Trial
::FieldMap
->new({
1105 bcs_schema
=> $schema,
1106 trial_id
=> $c->stash->{trial_id
},
1108 my $return = $fieldmap->display_fieldmap();
1110 $c->stash->{rest
} = $return;
1113 sub retrieve_trial_info
: Path
('/ajax/breeders/trial_phenotyping_info') : ActionClass
('REST') { }
1114 sub retrieve_trial_info_POST
: Args
(0) {
1115 #sub retrieve_trial_info : chained('trial') Pathpart("trial_phenotyping_info") Args(0) {
1118 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
1119 my $trial_id = $c->req->param('trial_id');
1120 my $layout = CXGN
::Trial
::TrialLayout
->new({schema
=> $schema, trial_id
=> $trial_id, experiment_type
=>'field_layout'});
1121 my $design = $layout-> get_design
();
1122 #print STDERR Dumper($design);
1125 foreach my $plot_number (keys %{$design}) {
1126 push @layout_info, {
1127 plot_id
=> $design->{$plot_number}->{plot_id
},
1128 plot_number
=> $plot_number,
1129 row_number
=> $design->{$plot_number}->{row_number
},
1130 col_number
=> $design->{$plot_number}->{col_number
},
1131 block_number
=> $design->{$plot_number}-> {block_number
},
1132 rep_number
=> $design->{$plot_number}-> {rep_number
},
1133 plot_name
=> $design->{$plot_number}-> {plot_name
},
1134 accession_name
=> $design->{$plot_number}-> {accession_name
},
1135 plant_names
=> $design->{$plot_number}-> {plant_names
},
1137 @layout_info = sort { $a->{plot_number
} <=> $b->{plot_number
} } @layout_info;
1140 #print STDERR Dumper(@layout_info);
1141 $c->stash->{rest
} = {trial_info
=> \
@layout_info};
1142 #$c->stash->{layout_info} = \@layout_info;
1146 sub trial_completion_layout_section
: Chained
('trial') PathPart
('trial_completion_layout_section') Args
(0) {
1149 my $schema = $c->dbic_schema("Bio::Chado::Schema");
1151 my $trial_layout = CXGN
::Trial
::TrialLayout
->new({schema
=> $schema, trial_id
=> $c->stash->{trial_id
}, experiment_type
=> 'field_layout', verify_layout
=>1, verify_physical_map
=>1});
1152 my $trial_errors = $trial_layout->generate_and_cache_layout();
1153 my $has_layout_check = $trial_errors->{errors
}->{layout_errors
} || $trial_errors->{error
} ?
0 : 1;
1154 my $has_physical_map_check = $trial_errors->{errors
}->{physical_map_errors
} || $trial_errors->{error
} ?
0 : 1;
1155 my $has_seedlots = $trial_errors->{errors
}->{seedlot_errors
} || $trial_errors->{error
} ?
0 : 1;
1156 my $error_string = $trial_errors->{error
} ?
$trial_errors->{error
} : '';
1157 my $layout_error_string = $trial_errors->{errors
}->{layout_errors
} ?
join ', ', @
{$trial_errors->{errors
}->{layout_errors
}} : '';
1158 my $map_error_string = $trial_errors->{errors
}->{physical_map_errors
} ?
join ', ', @
{$trial_errors->{errors
}->{physical_map_errors
}} : '';
1159 my $seedlot_error_string = $trial_errors->{errors
}->{seedlot_errors
} ?
join ', ', @
{$trial_errors->{errors
}->{seedlot_errors
}} : '';
1161 $c->stash->{rest
} = {
1162 has_layout
=> $has_layout_check,
1163 layout_errors
=> $error_string." ".$layout_error_string,
1164 has_physical_map
=> $has_physical_map_check,
1165 physical_map_errors
=> $error_string." ".$map_error_string,
1166 has_seedlots
=> $has_seedlots,
1167 seedlot_errors
=> $error_string." ".$seedlot_error_string
1171 sub trial_completion_phenotype_section
: Chained
('trial') PathPart
('trial_completion_phenotype_section') Args
(0) {
1174 my $schema = $c->dbic_schema("Bio::Chado::Schema");
1176 my $plot_type_id = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'plot', 'stock_type')->cvterm_id();
1177 my $plant_type_id = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'plant', 'stock_type')->cvterm_id();
1178 my $phenotyping_experiment_type_id = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'phenotyping_experiment', 'experiment_type')->cvterm_id();
1179 my $has_phenotype_check = $schema->resultset('Phenotype::Phenotype')->search({'stock.type_id'=> [$plot_type_id, $plant_type_id], 'nd_experiment.type_id'=>$phenotyping_experiment_type_id, 'me.value' => { '!=' => ''}, 'project.project_id'=>$c->stash->{trial_id
}}, {join=>{'nd_experiment_phenotypes'=>{'nd_experiment'=>[{'nd_experiment_stocks'=>'stock' }, {'nd_experiment_projects'=>'project'}] } }, rows
=>1 });
1180 my $has_phenotypes = $has_phenotype_check->first ?
1 : 0;
1182 $c->stash->{rest
} = {has_phenotypes
=> $has_phenotypes};
1185 sub delete_field_coord
: Path
('/ajax/phenotype/delete_field_coords') Args
(0) {
1188 my $trial_id = $c->req->param('trial_id');
1190 my $schema = $c->dbic_schema('Bio::Chado::Schema');
1192 if ($self->privileges_denied($c)) {
1193 $c->stash->{rest
} = { error
=> "You have insufficient access privileges to update this map." };
1197 my $fieldmap = CXGN
::Trial
::FieldMap
->new({
1198 bcs_schema
=> $schema,
1199 trial_id
=> $trial_id,
1201 my $delete_return_error = $fieldmap->delete_fieldmap();
1202 if ($delete_return_error) {
1203 $c->stash->{rest
} = { error
=> $delete_return_error };
1207 my $dbh = $c->dbc->dbh();
1208 my $bs = CXGN
::BreederSearch
->new( { dbh
=>$dbh, dbname
=>$c->config->{dbname
}, } );
1209 my $refresh = $bs->refresh_matviews($c->config->{dbhost
}, $c->config->{dbname
}, $c->config->{dbuser
}, $c->config->{dbpass
}, 'stockprop');
1210 my $trial_layout = CXGN
::Trial
::TrialLayout
->new({ schema
=> $schema, trial_id
=> $trial_id, experiment_type
=> 'field_layout' });
1211 $trial_layout->generate_and_cache_layout();
1213 $c->stash->{rest
} = {success
=> 1};
1216 sub replace_trial_accession
: Chained
('trial') PathPart
('replace_accession') Args
(0) {
1219 my $schema = $c->dbic_schema('Bio::Chado::Schema');
1220 my $old_accession_id = $c->req->param('old_accession_id');
1221 my $new_accession = $c->req->param('new_accession');
1222 my $trial_id = $c->stash->{trial_id
};
1224 if ($self->privileges_denied($c)) {
1225 $c->stash->{rest
} = { error
=> "You have insufficient access privileges to edit this map." };
1229 if (!$new_accession){
1230 $c->stash->{rest
} = { error
=> "Provide new accession name." };
1234 my $replace_accession_fieldmap = CXGN
::Trial
::FieldMap
->new({
1235 bcs_schema
=> $schema,
1236 trial_id
=> $trial_id,
1237 old_accession_id
=> $old_accession_id,
1238 new_accession
=> $new_accession,
1241 my $return_error = $replace_accession_fieldmap->update_fieldmap_precheck();
1242 if ($return_error) {
1243 $c->stash->{rest
} = { error
=> $return_error };
1247 my $replace_return_error = $replace_accession_fieldmap->replace_trial_accession_fieldMap();
1248 if ($replace_return_error) {
1249 $c->stash->{rest
} = { error
=> $replace_return_error };
1253 $c->stash->{rest
} = { success
=> 1};
1256 sub replace_plot_accession
: Chained
('trial') PathPart
('replace_plot_accessions') Args
(0) {
1259 my $schema = $c->dbic_schema('Bio::Chado::Schema');
1260 my $old_accession = $c->req->param('old_accession');
1261 my $new_accession = $c->req->param('new_accession');
1262 my $old_plot_id = $c->req->param('old_plot_id');
1263 my $trial_id = $c->stash->{trial_id
};
1265 if ($self->privileges_denied($c)) {
1266 $c->stash->{rest
} = { error
=> "You have insufficient access privileges to edit this map." };
1270 if (!$new_accession){
1271 $c->stash->{rest
} = { error
=> "Provide new accession name." };
1275 my $replace_plot_accession_fieldmap = CXGN
::Trial
::FieldMap
->new({
1276 bcs_schema
=> $schema,
1277 trial_id
=> $trial_id,
1278 new_accession
=> $new_accession,
1279 old_accession
=> $old_accession,
1280 old_plot_id
=> $old_plot_id,
1284 my $return_error = $replace_plot_accession_fieldmap->update_fieldmap_precheck();
1285 if ($return_error) {
1286 $c->stash->{rest
} = { error
=> $return_error };
1290 print "Calling Replace Function...............\n";
1291 my $replace_return_error = $replace_plot_accession_fieldmap->replace_plot_accession_fieldMap();
1292 if ($replace_return_error) {
1293 $c->stash->{rest
} = { error
=> $replace_return_error };
1297 print "OldAccession: $old_accession, NewAcc: $new_accession, OldPlotId: $old_plot_id\n";
1298 $c->stash->{rest
} = { success
=> 1};
1301 sub substitute_accession
: Chained
('trial') PathPart
('substitute_accession') Args
(0) {
1304 my $schema = $c->dbic_schema('Bio::Chado::Schema');
1305 my $trial_id = $c->stash->{trial_id
};
1306 my $plot_1_info = $c->req->param('plot_1_info');
1307 my $plot_2_info = $c->req->param('plot_2_info');
1309 my ($plot_1_id, $accession_1) = split /,/, $plot_1_info;
1310 my ($plot_2_id, $accession_2) = split /,/, $plot_2_info;
1312 if ($self->privileges_denied($c)) {
1313 $c->stash->{rest
} = { error
=> "You have insufficient access privileges to update this map." };
1317 if ($plot_1_id == $plot_2_id){
1318 $c->stash->{rest
} = { error
=> "Choose a different plot/accession in 'select Accession 2' to perform this operation." };
1325 my $fieldmap = CXGN
::Trial
::FieldMap
->new({
1326 bcs_schema
=> $schema,
1327 trial_id
=> $trial_id,
1328 first_plot_selected
=> $plot_1_id,
1329 second_plot_selected
=> $plot_2_id,
1330 first_accession_selected
=> $accession_1,
1331 second_accession_selected
=> $accession_2,
1334 my $return_error = $fieldmap->update_fieldmap_precheck();
1335 if ($return_error) {
1336 $c->stash->{rest
} = { error
=> $return_error };
1340 my $return_check_error = $fieldmap->substitute_accession_precheck();
1341 if ($return_check_error) {
1342 $c->stash->{rest
} = { error
=> $return_check_error };
1346 my $update_return_error = $fieldmap->substitute_accession_fieldmap();
1347 if ($update_return_error) {
1348 $c->stash->{rest
} = { error
=> $update_return_error };
1352 $c->stash->{rest
} = { success
=> 1};
1355 sub create_plant_subplots
: Chained
('trial') PathPart
('create_plant_entries') Args
(0) {
1358 my $plants_per_plot = $c->req->param("plants_per_plot") || 8;
1359 my $inherits_plot_treatments = $c->req->param("inherits_plot_treatments");
1360 my $plants_with_treatments;
1361 if($inherits_plot_treatments eq '1'){
1362 $plants_with_treatments = 1;
1365 if (my $error = $self->privileges_denied($c)) {
1366 $c->stash->{rest
} = { error
=> $error };
1370 if (!$plants_per_plot || $plants_per_plot > 50) {
1371 $c->stash->{rest
} = { error
=> "Plants per plot number is required and must be smaller than 50." };
1375 my $t = CXGN
::Trial
->new( { bcs_schema
=> $c->dbic_schema("Bio::Chado::Schema"), trial_id
=> $c->stash->{trial_id
} });
1377 if ($t->create_plant_entities($plants_per_plot, $plants_with_treatments)) {
1379 my $dbh = $c->dbc->dbh();
1380 my $bs = CXGN
::BreederSearch
->new( { dbh
=>$dbh, dbname
=>$c->config->{dbname
}, } );
1381 my $refresh = $bs->refresh_matviews($c->config->{dbhost
}, $c->config->{dbname
}, $c->config->{dbuser
}, $c->config->{dbpass
}, 'stockprop');
1383 $c->stash->{rest
} = {success
=> 1};
1386 $c->stash->{rest
} = { error
=> "Error creating plant entries in controller." };
1392 sub create_tissue_samples
: Chained
('trial') PathPart
('create_tissue_samples') Args
(0) {
1395 my $tissues_per_plant = $c->req->param("tissue_samples_per_plant") || 3;
1396 my $tissue_names = decode_json
$c->req->param("tissue_samples_names");
1397 my $inherits_plot_treatments = $c->req->param("inherits_plot_treatments");
1398 my $tissues_with_treatments;
1399 if($inherits_plot_treatments eq '1'){
1400 $tissues_with_treatments = 1;
1403 if (my $error = $self->privileges_denied($c)) {
1404 $c->stash->{rest
} = { error
=> $error };
1408 if (!$c->stash->{trial
}->has_plant_entries){
1409 $c->stash->{rest
} = { error
=> "Trial must have plant entries before you can add tissue samples entries. Plant entries are added from the trial detail page." };
1413 if (!$tissue_names || scalar(@
$tissue_names) < 1){
1414 $c->stash->{rest
} = { error
=> "You must provide tissue name(s) for your samples" };
1418 if (!$tissues_per_plant || $tissues_per_plant > 50) {
1419 $c->stash->{rest
} = { error
=> "Tissues per plant is required and must be smaller than 50." };
1423 my $t = CXGN
::Trial
->new({ bcs_schema
=> $c->dbic_schema("Bio::Chado::Schema"), trial_id
=> $c->stash->{trial_id
} });
1425 if ($t->create_tissue_samples($tissue_names, $inherits_plot_treatments)) {
1426 my $dbh = $c->dbc->dbh();
1427 my $bs = CXGN
::BreederSearch
->new( { dbh
=>$dbh, dbname
=>$c->config->{dbname
}, } );
1428 my $refresh = $bs->refresh_matviews($c->config->{dbhost
}, $c->config->{dbname
}, $c->config->{dbuser
}, $c->config->{dbpass
}, 'stockprop');
1430 $c->stash->{rest
} = {success
=> 1};
1433 $c->stash->{rest
} = { error
=> "Error creating tissues samples in controller." };
1439 sub privileges_denied
{
1443 my $trial_id = $c->stash->{trial_id
};
1445 if (! $c->user) { return "Login required for modifying trial."; }
1446 my $user_id = $c->user->get_object->get_sp_person_id();
1448 if ($c->user->check_roles('curator')) {
1452 my $breeding_programs = $c->stash->{trial
}->get_breeding_programs();
1454 if ( ($c->user->check_roles('submitter')) && ( $c->user->check_roles($breeding_programs->[0]->[1]))) {
1457 return "You have insufficient privileges to modify or delete this trial.";
1460 # loading field coordinates
1462 sub upload_trial_coordinates
: Path
('/ajax/breeders/trial/coordsupload') Args
(0) {
1467 print STDERR
"User not logged in... not uploading coordinates.\n";
1468 $c->stash->{rest
} = {error
=> "You need to be logged in to upload coordinates." };
1472 if (!any
{ $_ eq "curator" || $_ eq "submitter" } ($c->user()->roles) ) {
1473 $c->stash->{rest
} = {error
=> "You have insufficient privileges to add coordinates." };
1477 my $time = DateTime
->now();
1478 my $user_id = $c->user()->get_object()->get_sp_person_id();
1479 my $user_name = $c->user()->get_object()->get_username();
1480 my $timestamp = $time->ymd()."_".$time->hms();
1481 my $subdirectory = 'trial_coords_upload';
1482 my $upload = $c->req->upload('trial_coordinates_uploaded_file');
1483 my $trial_id = $c->req->param('trial_coordinates_upload_trial_id');
1484 my $upload_tempfile = $upload->tempname;
1485 my $upload_original_name = $upload->filename();
1487 my %upload_metadata;
1489 # Store uploaded temporary file in archive
1490 print STDERR
"TEMP FILE: $upload_tempfile\n";
1491 my $uploader = CXGN
::UploadFile
->new({
1492 tempfile
=> $upload_tempfile,
1493 subdirectory
=> $subdirectory,
1494 archive_path
=> $c->config->{archive_path
},
1495 archive_filename
=> $upload_original_name,
1496 timestamp
=> $timestamp,
1497 user_id
=> $user_id,
1498 user_role
=> $c->user()->roles
1500 my $archived_filename_with_path = $uploader->archive();
1502 if (!$archived_filename_with_path) {
1503 $c->stash->{rest
} = {error
=> "Could not save file $upload_original_name in archive",};
1507 $md5 = $uploader->get_md5($archived_filename_with_path);
1508 unlink $upload_tempfile;
1510 my $error_string = '';
1511 # open file and remove return of line
1512 open(my $F, "<", $archived_filename_with_path) || die "Can't open archive file $archived_filename_with_path";
1513 my $schema = $c->dbic_schema("Bio::Chado::Schema");
1518 my ($plot,$row,$col) = split /\t/ ;
1519 my $rs = $schema->resultset("Stock::Stock")->search({uniquename
=> $plot });
1520 if ($rs->count()== 1) {
1521 my $r = $rs->first();
1522 print STDERR
"The plots $plot was found.\n Loading row $row col $col\n";
1523 $r->create_stockprops({row_number
=> $row, col_number
=> $col}, {autocreate
=> 1});
1526 print STDERR
"WARNING! $plot was not found in the database.\n";
1527 $error_string .= "WARNING! $plot was not found in the database.";
1531 my $trial_layout = CXGN
::Trial
::TrialLayout
->new({ schema
=> $c->dbic_schema("Bio::Chado::Schema"), trial_id
=> $trial_id, experiment_type
=> 'field_layout' });
1532 $trial_layout->generate_and_cache_layout();
1535 $c->stash->{rest
} = {error_string
=> $error_string};
1539 my $dbh = $c->dbc->dbh();
1540 my $bs = CXGN
::BreederSearch
->new( { dbh
=>$dbh, dbname
=>$c->config->{dbname
}, } );
1541 my $refresh = $bs->refresh_matviews($c->config->{dbhost
}, $c->config->{dbname
}, $c->config->{dbuser
}, $c->config->{dbpass
}, 'stockprop');
1543 $c->stash->{rest
} = {success
=> 1};
1546 sub crosses_in_trial
: Chained
('trial') PathPart
('crosses_in_trial') Args
(0) {
1549 my $schema = $c->dbic_schema("Bio::Chado::Schema");
1551 my $trial_id = $c->stash->{trial_id
};
1552 my $trial = CXGN
::Cross
->new({bcs_schema
=> $schema, trial_id
=> $trial_id});
1554 my $result = $trial->get_crosses_in_trial();
1556 foreach my $r (@
$result){
1557 my ($cross_id, $cross_name, $female_parent_id, $female_parent_name, $male_parent_id, $male_parent_name, $cross_type, $female_plot_id, $female_plot_name, $male_plot_id, $male_plot_name) =@
$r;
1558 push @crosses, [qq{<a href
= "/cross/$cross_id">$cross_name</a
>},
1559 qq{<a href
= "/stock/$female_parent_id/view">$female_parent_name</a
>},
1560 qq{<a href
= "/stock/$male_parent_id/view">$male_parent_name</a
>}, $cross_type,
1561 qq{<a href
= "/stock/$female_plot_id/view">$female_plot_name</a
>},
1562 qq{<a href
= "/stock/$male_plot_id/view">$male_plot_name</a
>}];
1565 $c->stash->{rest
} = { data
=> \
@crosses };
1568 sub cross_properties_trial
: Chained
('trial') PathPart
('cross_properties_trial') Args
(0) {
1571 my $schema = $c->dbic_schema("Bio::Chado::Schema");
1573 my $trial_id = $c->stash->{trial_id
};
1574 my $trial = CXGN
::Cross
->new({bcs_schema
=> $schema, trial_id
=> $trial_id});
1576 my $result = $trial->get_cross_properties_trial();
1578 my $cross_properties = $c->config->{cross_properties
};
1579 my @column_order = split ',', $cross_properties;
1582 foreach my $r (@
$result){
1583 my ($cross_id, $cross_name, $cross_props_hash) =@
$r;
1585 my @row = ( qq{<a href
= "/cross/$cross_id">$cross_name</a
>} );
1586 foreach my $key (@column_order){
1587 push @row, $cross_props_hash->{$key};
1590 push @crosses, \
@row;
1593 $c->stash->{rest
} = { data
=> \
@crosses };
1596 sub cross_progenies_trial
: Chained
('trial') PathPart
('cross_progenies_trial') Args
(0) {
1599 my $schema = $c->dbic_schema("Bio::Chado::Schema");
1601 my $trial_id = $c->stash->{trial_id
};
1602 my $trial = CXGN
::Cross
->new({bcs_schema
=> $schema, trial_id
=> $trial_id});
1604 my $result = $trial->get_cross_progenies_trial();
1606 foreach my $r (@
$result){
1607 my ($cross_id, $cross_name, $progeny_number) =@
$r;
1608 push @crosses, [qq{<a href
= "/cross/$cross_id">$cross_name</a
>}, $progeny_number];
1611 $c->stash->{rest
} = { data
=> \
@crosses };
1615 sub phenotype_heatmap
: Chained
('trial') PathPart
('heatmap') Args
(0) {
1618 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
1619 my $trial_id = $c->stash->{trial_id
};
1620 my $trait_id = $c->req->param("selected");
1622 # my $phenotypes_heatmap = CXGN::Phenotypes::TrialPhenotype->new({
1623 # bcs_schema=>$schema,
1624 # trial_id=>$trial_id,
1625 # trait_id=>$trait_id
1627 # my $phenotype = $phenotypes_heatmap->get_trial_phenotypes_heatmap();
1629 my @items = map {@
{$_}[0]} @
{$c->stash->{trial
}->get_plots()};
1630 print STDERR Dumper
(\
@items);
1631 my @trait_ids = ($trait_id);
1633 my $layout = $c->stash->{trial_layout
};
1634 my $design_type = $layout->get_design_type();
1636 my $phenotypes_search = CXGN
::Phenotypes
::SearchFactory
->instantiate(
1639 bcs_schema
=> $schema,
1640 data_level
=> 'plot',
1641 trait_list
=> \
@trait_ids,
1642 plot_list
=> \
@items,
1643 include_row_and_column_numbers
=> 1
1646 my $data = $phenotypes_search->search();
1647 my (@col_No, @row_No, @pheno_val, @plot_Name, @stock_Name, @plot_No, @block_No, @rep_No, @msg, $result, @phenoID);
1648 foreach my $d (@
$data) {
1649 my ($year, $project_name, $stock_name, $location, $trait, $value, $plot_name, $rep, $block_number, $plot_number, $row_number, $col_number, $trait_id, $project_id, $location_id, $stock_id, $plot_id, $timestamp_value, $synonyms, $design, $stock_type_name, $phenotype_id, $full_count) = @
$d;
1650 if (!$row_number && !$col_number){
1651 if ($block_number && $design_type ne 'splitplot'){
1652 $row_number = $block_number;
1653 }elsif ($rep && !$block_number && $design_type ne 'splitplot'){
1655 }elsif ($design_type eq 'splitplot'){
1660 my $plot_popUp = $plot_name."\nplot_No:".$plot_number."\nblock_No:".$block_number."\nrep_No:".$rep."\nstock:".$stock_name."\nvalue:".$value;
1661 push @
$result, {plotname
=> $plot_name, stock
=> $stock_name, plotn
=> $plot_number, blkn
=>$block_number, rep
=>$rep, row
=>$row_number, col
=>$col_number, pheno
=>$value, plot_msg
=>$plot_popUp, pheno_id
=>$phenotype_id} ;
1663 push @col_No, $col_number;
1665 push @row_No, $row_number;
1666 push @pheno_val, $value;
1667 push @plot_Name, $plot_name;
1668 push @stock_Name, $stock_name;
1669 push @plot_No, $plot_number;
1670 push @block_No, $block_number;
1672 push @phenoID, $phenotype_id;
1678 $false_coord = 'false_coord';
1679 my @row_instances = uniq
@row_No;
1680 my %unique_row_counts;
1681 $unique_row_counts{$_}++ for @row_No;
1683 for my $key (keys %unique_row_counts){
1684 push @col_number2, (1..$unique_row_counts{$key});
1686 for (my $i=0; $i < scalar(@
$result); $i++){
1687 @
$result[$i]->{'col'} = $col_number2[$i];
1688 push @col_No, $col_number2[$i];
1692 my ($min_col, $max_col) = minmax
@col_No;
1693 my ($min_row, $max_row) = minmax
@row_No;
1694 my (@unique_col,@unique_row);
1695 for my $x (1..$max_col){
1696 push @unique_col, $x;
1698 for my $y (1..$max_row){
1699 push @unique_row, $y;
1702 my $trial = CXGN
::Trial
->new({
1703 bcs_schema
=> $schema,
1704 trial_id
=> $trial_id
1706 my $data_check = $trial->get_controls();
1708 foreach my $cntrl (@
{$data_check}) {
1709 push @control_name, $cntrl->{'accession_name'};
1711 #print STDERR Dumper($result);
1712 $c->stash->{rest
} = { #phenotypes => $phenotype,
1715 pheno
=> \
@pheno_val,
1716 plotName
=> \
@plot_Name,
1717 stock
=> \
@stock_Name,
1719 block
=> \
@block_No,
1723 col_max
=> $max_col,
1724 row_max
=> $max_row,
1725 unique_col
=> \
@unique_col,
1726 unique_row
=> \
@unique_row,
1727 false_coord
=> $false_coord,
1728 phenoID
=> \
@phenoID,
1729 controls
=> \
@control_name
1733 sub get_suppress_plot_phenotype
: Chained
('trial') PathPart
('suppress_phenotype') Args
(0) {
1736 my $schema = $c->dbic_schema('Bio::Chado::Schema');
1737 my $plot_name = $c->req->param('plot_name');
1738 my $plot_pheno_value = $c->req->param('phenotype_value');
1739 my $trait_id = $c->req->param('trait_id');
1740 my $phenotype_id = $c->req->param('phenotype_id');
1741 my $trial_id = $c->stash->{trial_id
};
1742 my $trial = $c->stash->{trial
};
1743 my $user_name = $c->user()->get_object()->get_username();
1744 my $time = DateTime
->now();
1745 my $timestamp = $time->ymd()."_".$time->hms();
1747 if ($self->privileges_denied($c)) {
1748 $c->stash->{rest
} = { error
=> "You have insufficient access privileges to suppress this phenotype." };
1752 my $suppress_return_error = $trial->suppress_plot_phenotype($trait_id, $plot_name, $plot_pheno_value, $phenotype_id, $user_name, $timestamp);
1753 if ($suppress_return_error) {
1754 $c->stash->{rest
} = { error
=> $suppress_return_error };
1758 $c->stash->{rest
} = { success
=> 1};
1761 sub delete_single_assayed_trait
: Chained
('trial') PathPart
('delete_single_trait') Args
(0) {
1764 my $pheno_ids = $c->req->param('pheno_id');
1765 my $trait_ids = $c->req->param('traits_id');
1766 my $schema = $c->dbic_schema('Bio::Chado::Schema');
1767 my $trial = $c->stash->{trial
};
1770 print STDERR
"User not logged in... not deleting trait.\n";
1771 $c->stash->{rest
} = {error
=> "You need to be logged in to delete trait." };
1775 if ($self->privileges_denied($c)) {
1776 $c->stash->{rest
} = { error
=> "You have insufficient access privileges to delete assayed trait for this trial." };
1780 my $delete_trait_return_error;
1782 my $phenotypes_ids = JSON
::decode_json
($pheno_ids);
1783 $delete_trait_return_error = $trial->delete_assayed_trait($phenotypes_ids, [] );
1786 my $traits_ids = JSON
::decode_json
($trait_ids);
1787 $delete_trait_return_error = $trial->delete_assayed_trait([], $traits_ids );
1790 if ($delete_trait_return_error) {
1791 $c->stash->{rest
} = { error
=> $delete_trait_return_error };
1795 $c->stash->{rest
} = { success
=> 1};
1798 sub retrieve_plot_image
: Chained
('trial') PathPart
('retrieve_plot_images') Args
(0) {
1801 my $schema = $c->dbic_schema('Bio::Chado::Schema');
1802 my $image_ids = decode_json
$c->req->param('image_ids');
1803 my $plot_name = $c->req->param('plot_name');
1804 my $plot_id = $c->req->param('plot_id');
1805 my $trial_id = $c->stash->{trial_id
};
1808 my $dbh = $c->dbc->dbh;
1809 $stockref->{dbh
} = $dbh;
1810 $stockref->{image_ids
} = $image_ids || [] ;
1811 my $images = $stockref->{image_ids
};
1812 $dbh = $stockref->{dbh
};
1814 print STDERR Dumper
($stockref);
1815 print "$plot_name and $plot_id and $image_ids\n";
1817 my $image_html = "";
1818 my $m_image_html = "";
1822 if ($images && !$image_objects) {
1823 my @image_object_list = map { SGN
::Image
->new( $dbh , $_ ) } @
$images ;
1824 $image_objects = \
@image_object_list;
1827 if ($image_objects) { # don't display anything for empty list of images
1828 $image_html .= qq|<table cellpadding
="5">|;
1829 foreach my $image_ob (@
$image_objects) {
1831 my $image_id = $image_ob->get_image_id;
1832 my $image_name = $image_ob->get_name();
1833 my $image_description = $image_ob->get_description();
1834 my $image_img = $image_ob->get_image_url("medium");
1835 my $small_image = $image_ob->get_image_url("thumbnail");
1836 my $image_page = "/image/view/$image_id";
1839 qq|<a href
="$image_img" class="stock_image_group" rel
="gallery-figures"><img src
="$small_image" alt
="$image_description" onclick
="close_view_plot_image_dialog()"/></a> |;
1841 qq|<tr
><td width
=120>|
1845 . $image_description
1847 if ( $count < 3 ) { $image_html .= $fhtml; }
1849 push @more_is, $fhtml;
1850 } #more than 3 figures- show these in a hidden div
1852 $image_html .= "</table>"; #close the table tag or the first 3 figures
1854 $image_html .= "<script> jQuery(document).ready(function() { jQuery('a.stock_image_group').colorbox(); }); </script>\n";
1858 "<table cellpadding=5>"; #open table tag for the hidden figures #4 and on
1859 my $more = scalar(@more_is);
1860 foreach (@more_is) { $m_image_html .= $_; }
1862 $m_image_html .= "</table>"; #close tabletag for the hidden figures
1864 if (@more_is) { #html_optional_show if there are more than 3 figures
1865 $image_html .= html_optional_show
(
1867 "<b>See $more more images...</b>",
1868 qq| $m_image_html |,
1869 0, #< do not show by default
1870 'abstract_optional_show', #< don't use the default button-like style
1874 $c->stash->{rest
} = { image_html
=> $image_html};