2 package CXGN
::Trial
::FieldMap
;
4 use CXGN
::Chado
::Cvterm
;
6 use SGN
::Model
::Cvterm
;
9 use CXGN
::Trial
::TrialLayout
;
10 #use List::Util 'max';
11 use List
::MoreUtils qw
| :all
!before
!after
|;
12 use Bio
::Chado
::Schema
;
15 has
'bcs_schema' => ( isa
=> 'Bio::Chado::Schema',
20 has
'trial_id' => (isa
=> "Int",
24 has
'experiment_type' => (isa
=> "Str",
28 has
'first_plot_selected' => (isa
=> "Int",
32 has
'second_plot_selected' => (isa
=> "Int",
36 has
'first_accession_selected' => (isa
=> "Str",
40 has
'second_accession_selected' => (isa
=> "Str",
44 has
'trial_stock_type' => (isa
=> "Str",
50 sub display_fieldmap
{
52 my $schema = $self->bcs_schema;
53 my $trial_id = $self->trial_id;
55 my $experiment_type = $self->experiment_type() ?
$self->experiment_type() : 'field_layout';
57 my $layout = CXGN
::Trial
::TrialLayout
->new({
59 trial_id
=> $trial_id,
60 experiment_type
=> $experiment_type
63 my $design = $layout-> get_design
();
64 my $design_type = $layout->get_design_type();
65 #print STDERR Dumper($design_type);
71 my @block_numbers = ();
72 my @accession_names = ();
73 my @plot_numbers_from_design = ();
74 my @plot_numbers_not_used;
78 while ( my ($k, $v) = (each %$design)) {
80 my $plot_id = $v->{plot_id
};
81 my $row_number = $v->{row_number
};
82 my $col_number = $v->{col_number
};
83 my $block_number = $v->{block_number
};
84 my $rep_number = $v->{rep_number
};
85 my $plot_name = $v->{plot_name
};
86 my $accession_name = $v->{accession_name
};
87 my $plant_names = $v->{plant_names
};
88 my $plot_number_fromDesign = $v->{plot_number
};
90 my $image_id = CXGN
::Stock
->new({
94 my @plot_image_ids = map $_->[0], $image_id->get_image_ids();
96 push @plot_numbers_not_used, $plot_number;
97 push @plot_numbers_from_design, $plot_number_fromDesign;
99 push @col_numbers, $col_number;
102 push @row_numbers, $row_number;
103 }elsif (!$row_number){
104 if ($block_number && $design_type ne 'splitplot'){
105 $row_number = $block_number;
106 push @row_numbers, $row_number;
107 }elsif ($rep_number && !$block_number && $design_type ne 'splitplot'){
108 $row_number = $rep_number;
109 push @row_numbers, $row_number;
110 }elsif ($design_type eq 'splitplot'){
111 $row_number = $rep_number;
112 push @row_numbers, $row_number;
116 push @rep_numbers, $rep_number;
119 push @block_numbers, $block_number;
121 if ($accession_name) {
122 push @accession_names, $accession_name;
125 push @plot_names, $plot_name;
130 plot_number
=> $plot_number,
131 row_number
=> $row_number,
132 col_number
=> $col_number,
133 block_number
=> $block_number,
134 rep_number
=> $rep_number,
135 plot_name
=> $plot_name,
136 accession_name
=> $accession_name,
137 plant_names
=> $plant_names,
138 plot_image_ids
=> \
@plot_image_ids,
142 @layout_info = sort { $a->{plot_number
} <=> $b->{plot_number
}} @layout_info;
146 if (scalar(@col_numbers) < 1){
148 $false_coord = 'false_coord';
149 my @row_instances = uniq
@row_numbers;
150 my %unique_row_counts;
151 $unique_row_counts{$_}++ for @row_numbers;
153 for my $key (keys %unique_row_counts){
154 push @col_number2, (1..$unique_row_counts{$key});
156 for (my $i=0; $i < scalar(@layout_info); $i++){
157 $layout_info[$i]->{'col_number'} = $col_number2[$i];
158 push @col_numbers, $col_number2[$i];
162 foreach my $hash (@layout_info){
163 push @plot_numbers, $hash->{'plot_number'};
164 push @stocks_hm, $hash->{'accession_name'};
165 if (scalar(@
{$hash->{"plant_names"}}) < 1) {
166 $plot_popUp = $hash->{'plot_name'}."\nplot_No:".$hash->{'plot_number'}."\nblock_No:".$hash->{'block_number'}."\nrep_No:".$hash->{'rep_number'}."\nstock:".$hash->{'accession_name'};
169 $plot_popUp = $hash->{'plot_name'}."\nplot_No:".$hash->{'plot_number'}."\nblock_No:".$hash->{'block_number'}."\nrep_No:".$hash->{'rep_number'}."\nstock:".$hash->{'accession_name'}."\nnumber_of_plants:".scalar(@
{$hash->{"plant_names"}});
171 push @
$result, {plotname
=> $hash->{'plot_name'}, plot_id
=> $hash->{'plot_id'}, stock
=> $hash->{'accession_name'}, plotn
=> $hash->{'plot_number'}, blkn
=>$hash->{'block_number'}, rep
=>$hash->{'rep_number'}, row
=>$hash->{'row_number'}, plot_image_ids
=>$hash->{'plot_image_ids'}, col
=>$hash->{'col_number'}, plot_msg
=>$plot_popUp} ;
173 #print STDERR Dumper(\@col_numbers);
174 #print STDERR Dumper($result);
181 my @plot_number = ();
184 foreach $my_hash (@layout_info) {
185 if ($my_hash->{'row_number'}) {
186 if ($my_hash->{'row_number'} =~ m/\d+/) {
187 if (scalar(@
{$my_hash->{"plant_names"}}) < 1) {
188 $array_msg[$my_hash->{'row_number'}-1][$my_hash->{'col_number'}-1] = "rep_number: ".$my_hash->{'rep_number'}."\nblock_number: ".$my_hash->{'block_number'}."\nrow_number: ".$my_hash->{'row_number'}."\ncol_number: ".$my_hash->{'col_number'}."\naccession_name: ".$my_hash->{'accession_name'}."\nPlot_name: ".$my_hash->{'plot_name'};
191 $array_msg[$my_hash->{'row_number'}-1][$my_hash->{'col_number'}-1] = "rep_number: ".$my_hash->{'rep_number'}."\nblock_number: ".$my_hash->{'block_number'}."\nrow_number: ".$my_hash->{'row_number'}."\ncol_number: ".$my_hash->{'col_number'}."\naccession_name: ".$my_hash->{'accession_name'}."\nnumber_of_plants:".scalar(@
{$my_hash->{"plant_names"}})."\nPlot_name: ".$my_hash->{'plot_name'};
193 $plot_id[$my_hash->{'row_number'}-1][$my_hash->{'col_number'}-1] = $my_hash->{'plot_id'};
194 $plot_number[$my_hash->{'row_number'}-1][$my_hash->{'col_number'}-1] = $my_hash->{'plot_number'};
195 $acc_name[$my_hash->{'row_number'}-1][$my_hash->{'col_number'}-1] = $my_hash->{'accession_name'};
196 $blk_no[$my_hash->{'row_number'}-1][$my_hash->{'col_number'}-1] = $my_hash->{'block_number'};
197 $rep_no[$my_hash->{'row_number'}-1][$my_hash->{'col_number'}-1] = $my_hash->{'rep_number'};
198 $plot_name[$my_hash->{'row_number'}-1][$my_hash->{'col_number'}-1] = $my_hash->{'plot_name'};
204 my $plotcounter_nu = 0;
205 if ($plot_numbers_not_used[0] =~ m/^\d{3}/){
206 foreach my $plot (@plot_numbers_not_used) {
209 for my $n (1..$plotcounter_nu){
214 my @sorted_block = sort@block_numbers;
215 my @uniq_block = uniq
(@sorted_block);
216 my ($min_rep, $max_rep) = minmax
@rep_numbers;
217 my ($min_block, $max_block) = minmax
@block_numbers;
218 my ($min_col, $max_col) = minmax
@col_numbers;
219 my ($min_row, $max_row) = minmax
@row_numbers;
220 my (@unique_col,@unique_row);
221 for my $x (1..$max_col){
222 push @unique_col, $x;
224 for my $y (1..$max_row){
225 push @unique_row, $y;
228 my $trial = CXGN
::Trial
->new({
229 bcs_schema
=> $schema,
230 trial_id
=> $trial_id
232 my $data = $trial->get_controls();
235 foreach my $cntrl (@
{$data}) {
236 push @control_name, $cntrl->{'accession_name'};
240 coord_row
=> \
@row_numbers,
241 coords
=> \
@layout_info,
242 coord_col
=> \
@col_numbers,
245 plot_msg
=> \
@array_msg,
246 rep
=> \
@rep_numbers,
247 block
=> \
@sorted_block,
248 accessions
=> \
@accession_names,
249 plot_name
=> \
@plot_name,
250 plot_id
=> \
@plot_id,
251 plot_number
=> \
@plot_number,
252 plot_numbers
=> \
@plot_numbers,
253 stocks
=> \
@stocks_hm,
255 max_block
=> $max_block,
256 sudo_plot_no
=> \
@plotcnt,
257 controls
=> \
@control_name,
261 unique_col
=> \
@unique_col,
262 unique_row
=> \
@unique_row,
263 false_coord
=> $false_coord,
265 design_type
=> $design_type,
267 #print STDERR Dumper(\%return);
271 sub delete_fieldmap
{
274 my $trial_id = $self->trial_id;
275 my $dbh = $self->bcs_schema->storage->dbh();
277 my $h = $dbh->prepare("delete from stockprop where stockprop.stockprop_id IN (select stockprop.stockprop_id from project join nd_experiment_project using(project_id) join nd_experiment_stock using(nd_experiment_id) join stock using(stock_id) join stockprop on(stock.stock_id=stockprop.stock_id) where (stockprop.type_id IN (select cvterm_id from cvterm where name='col_number') or stockprop.type_id IN (select cvterm_id from cvterm where name='row_number')) and project.project_id=? and stock.type_id IN (select cvterm_id from cvterm join cv using(cv_id) where cv.name = 'stock_type' and cvterm.name ='plot'));");
278 $h->execute($trial_id);
280 $self->_regenerate_trial_layout_cache();
285 sub update_fieldmap_precheck
{
288 my $trial_id = $self->trial_id;
290 my $trial = CXGN
::Trial
->new({
291 bcs_schema
=> $self->bcs_schema,
292 trial_id
=> $trial_id
294 my $triat_name = $trial->get_traits_assayed();
295 #print STDERR Dumper($triat_name);
297 if (scalar(@
{$triat_name}) != 0) {
298 $error = "One or more traits have been assayed for this trial; Map/Layout can not be modified. Please contact us.";
301 my $seedlots = $trial->get_seedlots();
302 if (scalar(@
$seedlots) != 0){
303 $error = "Seedlots have already been saved as the source material for the plots in this trial. Map/Layout can not be modified. Please contact us.";
308 sub substitute_accession_precheck
{
313 my $dbh = $self->bcs_schema->storage->dbh;
314 my $plot_1_id = $self->first_plot_selected;
315 my $plot_2_id = $self->second_plot_selected;
316 push @ids, $plot_1_id;
317 push @ids, $plot_2_id;
319 my $isAcontrol_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'is a control', 'stock_property' )->cvterm_id();
321 foreach my $id (@ids) {
322 my $h = $dbh->prepare("select value from stockprop where stock_id=? and type_id=?;");
323 $h->execute($id,$isAcontrol_cvterm_id);
324 while (my $plot = $h->fetchrow_array()) {
329 if (scalar(@plots) != 0) {
330 $error = "Accessions used as control/check can't be substituted between plots...";
335 sub substitute_accession_fieldmap
{
338 my $plot_1_id = $self->first_plot_selected;
339 my $plot_2_id = $self->second_plot_selected;
340 my $dbh = $self->bcs_schema->storage->dbh;
342 my @plot_1_objectIDs;
343 my @plot_2_objectIDs;
344 my $h = $dbh->prepare("select object_id from stock_relationship where subject_id=?;");
345 $h->execute($plot_1_id);
346 while (my $plot_1_objectID = $h->fetchrow_array()) {
347 push @plot_1_objectIDs, $plot_1_objectID;
350 my $h1 = $dbh->prepare("select object_id from stock_relationship where subject_id=?;");
351 $h1->execute($plot_2_id);
352 while (my $plot_2_objectID = $h1->fetchrow_array()) {
353 push @plot_2_objectIDs, $plot_2_objectID;
356 for (my $n=0; $n<scalar(@plot_2_objectIDs); $n++) {
357 my $h2 = $dbh->prepare("update stock_relationship set object_id =? where object_id=? and subject_id=?;");
358 $h2->execute($plot_1_objectIDs[$n],$plot_2_objectIDs[$n],$plot_2_id);
361 for (my $n=0; $n<scalar(@plot_2_objectIDs); $n++) {
362 my $h2 = $dbh->prepare("update stock_relationship set object_id =? where object_id=? and subject_id=?;");
363 $h2->execute($plot_2_objectIDs[$n],$plot_1_objectIDs[$n],$plot_1_id);
366 $self->_regenerate_trial_layout_cache();
371 sub replace_plot_accession_fieldMap
{
374 my $accession_id = shift;
375 my $plot_of_type_id = shift;
377 my $schema = $self->bcs_schema;
378 my $dbh = $self->bcs_schema->storage->dbh;
380 my $stockprop_rs = $schema->resultset("Stock::StockRelationship")->search({
381 subject_id
=> $plot_id,
382 type_id
=> $plot_of_type_id
385 if ($stockprop_rs->count == 1) {
386 $stockprop_rs->update({
387 object_id
=> $accession_id,
390 elsif ($stockprop_rs->count > 1) {
391 $error = "There should only be one accession linked to the plot via plot_of\n";
393 $error = "Plot entry does not exist in database.\n";
396 $self->_regenerate_trial_layout_cache();
402 sub replace_plot_name_fieldMap
{
405 my $new_plot_name = shift;
407 my $schema = $self->bcs_schema;
409 my $new_plot_name_validator = CXGN
::List
::Validate
->new();
410 my $valid_new_plot_name = @
{$new_plot_name_validator->validate($schema,'plots',[$new_plot_name])->{'missing'}};
411 if (!$valid_new_plot_name) {
412 $error .= "Plot name $new_plot_name already exists in the database";
414 my $plot_type_id = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'plot', 'stock_type')->cvterm_id();
415 my $stock_rs = $schema->resultset("Stock::Stock")->search({
416 stock_id
=> $plot_id,
417 type_id
=> $plot_type_id,
420 uniquename
=> $new_plot_name,
424 $self->_regenerate_trial_layout_cache();
429 sub replace_trial_stock_fieldMap
{
431 my $new_stock = shift;
432 my $old_stock_id = shift;
434 my $schema = $self->bcs_schema;
435 my $dbh = $self->bcs_schema->storage->dbh;
436 my $trial_id = $self->trial_id;
437 my $trial_stock_type = $self->trial_stock_type;
439 print "New Stock: $new_stock and OLD Stock: $old_stock_id\n";
441 my $new_stock_id = $schema->resultset("Stock::Stock")->search({uniquename
=> $new_stock})->first->stock_id();
442 my $accession_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'accession', 'stock_type' )->cvterm_id();
443 my $family_name_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'family_name', 'stock_type' )->cvterm_id();
444 my $cross_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'cross', 'stock_type' )->cvterm_id();
445 my $field_trial_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, "field_layout", "experiment_type")->cvterm_id();
446 my $plot_of_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, "plot_of", "stock_relationship")->cvterm_id();
447 my $plant_of_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, "plant_of", "stock_relationship")->cvterm_id();
448 my $subplot_of_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, "subplot_of", "stock_relationship")->cvterm_id();
450 my $h_update = $dbh->prepare("update stock_relationship set object_id=? where stock_relationship_id in (SELECT stock_relationship.stock_relationship_id FROM stock as accession JOIN stock_relationship on (accession.stock_id = stock_relationship.object_id) JOIN stock as plot on (plot.stock_id = stock_relationship.subject_id) JOIN nd_experiment_stock on (plot.stock_id=nd_experiment_stock.stock_id) JOIN nd_experiment using(nd_experiment_id) JOIN nd_experiment_project using(nd_experiment_id) JOIN project using(project_id) WHERE accession.type_id =? AND stock_relationship.type_id IN (?,?,?) AND project.project_id =? and nd_experiment.type_id=?) and object_id=?;");
451 if ($trial_stock_type eq 'family_name') {
452 $h_update->execute($new_stock_id,$family_name_cvterm_id,$plot_of_cvterm_id,$plant_of_cvterm_id,$subplot_of_cvterm_id,$trial_id,$field_trial_cvterm_id,$old_stock_id);
453 } elsif ($trial_stock_type eq 'cross') {
454 $h_update->execute($new_stock_id,$cross_cvterm_id,$plot_of_cvterm_id,$plant_of_cvterm_id,$subplot_of_cvterm_id,$trial_id,$field_trial_cvterm_id,$old_stock_id);
456 $h_update->execute($new_stock_id,$accession_cvterm_id,$plot_of_cvterm_id,$plant_of_cvterm_id,$subplot_of_cvterm_id,$trial_id,$field_trial_cvterm_id,$old_stock_id);
459 $self->_regenerate_trial_layout_cache();
464 sub _regenerate_trial_layout_cache
{
466 my $experiment_type = $self->experiment_type() ?
$self->experiment_type() : 'field_layout';
467 my $layout = CXGN
::Trial
::TrialLayout
->new({
468 schema
=> $self->bcs_schema,
469 trial_id
=> $self->trial_id,
470 experiment_type
=> $experiment_type
472 $layout->generate_and_cache_layout();