Added eval; site now shows clean dataset missing message instead of server error...
[sgn.git] / lib / SGN / Controller / AJAX / DroneImagery / DroneImageryMainDisplay.pm
blob3c29960b7a41fbc4aa8ea81bfbd0d5b8874e0c10
2 =head1 NAME
4 SGN::Controller::AJAX::DroneImagery::DroneImageryMainDisplay - a REST controller class to provide the
5 functions for showing the main drone imagery display of all images. All other functions are
6 controlled by SGN::Controller::AJAX::DroneImagery
8 =head1 DESCRIPTION
10 =head1 AUTHOR
12 =cut
14 package SGN::Controller::AJAX::DroneImagery::DroneImageryMainDisplay;
16 use Moose;
17 use Data::Dumper;
18 use JSON;
19 use SGN::Model::Cvterm;
20 use DateTime;
21 use SGN::Image;
22 use CXGN::DroneImagery::ImagesSearch;
23 use URI::Encode qw(uri_encode uri_decode);
24 use CXGN::Calendar;
25 use Image::Size;
26 use CXGN::DroneImagery::ImageTypes;
27 #use Inline::Python;
29 BEGIN { extends 'Catalyst::Controller::REST' }
31 __PACKAGE__->config(
32 default => 'application/json',
33 stash_key => 'rest',
34 map => { 'application/json' => 'JSON', 'text/html' => 'JSON' },
37 sub raw_drone_imagery_summary_top : Path('/api/drone_imagery/raw_drone_imagery_top') : ActionClass('REST') { }
38 sub raw_drone_imagery_summary_top_GET : Args(0) {
39 my $self = shift;
40 my $c = shift;
41 my $sp_person_id = $c->user() ? $c->user->get_object()->get_sp_person_id() : undef;
42 my $schema = $c->dbic_schema("Bio::Chado::Schema", undef, $sp_person_id);
44 my $drone_run_field_trial_project_relationship_type_id_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'drone_run_on_field_trial', 'project_relationship')->cvterm_id();
45 my $drone_run_band_drone_run_project_relationship_type_id_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'drone_run_band_on_drone_run', 'project_relationship')->cvterm_id();
46 my $project_start_date_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'project_start_date', 'project_property')->cvterm_id();
47 my $drone_run_project_type_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'drone_run_project_type', 'project_property')->cvterm_id();
48 my $drone_run_is_raw_images_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'drone_run_is_raw_images', 'project_property')->cvterm_id();
49 my $drone_run_ground_control_points_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'drone_run_ground_control_points', 'project_property')->cvterm_id();
50 my $drone_run_project_averaged_temperature_gdd_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'drone_run_averaged_temperature_growing_degree_days', 'project_property')->cvterm_id();
51 my $drone_run_project_averaged_precipitation_sum_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'drone_run_averaged_precipitation_sum', 'project_property')->cvterm_id();
52 my $drone_run_related_time_cvterms_json_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'drone_run_related_time_cvterms_json', 'project_property')->cvterm_id();
53 my $process_indicator_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'drone_run_standard_process_in_progress', 'project_property')->cvterm_id();
54 my $processed_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'drone_run_standard_process_completed', 'project_property')->cvterm_id();
55 my $processed_extended_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'drone_run_standard_process_extended_completed', 'project_property')->cvterm_id();
56 my $processed_vi_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'drone_run_standard_process_vi_completed', 'project_property')->cvterm_id();
57 my $phenotypes_processed_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'drone_run_standard_process_phenotype_calculation_in_progress', 'project_property')->cvterm_id();
58 my $drone_run_band_type_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'drone_run_band_project_type', 'project_property')->cvterm_id();
59 my $drone_run_camera_rig_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'drone_run_camera_rig_description', 'project_property')->cvterm_id();
60 my $drone_run_base_date_cvterm_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'drone_run_base_date', 'project_property')->cvterm_id();
62 my $drone_run_q = "SELECT drone_run_band_project.project_id, drone_run_band_project.name, drone_run_band_project.description, drone_run_project.project_id, drone_run_project.name, drone_run_project.description, field_trial.project_id, field_trial.name, field_trial.description, drone_run_band_type.value, drone_run_date.value, drone_run_type.value, drone_run_averaged_temperature_gdd.value, drone_run_averaged_precipitation_sum.value, drone_run_related_time_cvterm_json.value, drone_run_indicator.value, drone_run_phenotypes_indicator.value, drone_run_processed.value, drone_run_processed_extended.value, drone_run_processed_vi.value, drone_run_is_raw_images.value, drone_run_ground_control_points.value, drone_run_camera_rig.value, drone_run_base_date.value
63 FROM project AS drone_run_band_project
64 JOIN projectprop AS drone_run_band_type ON(drone_run_band_project.project_id=drone_run_band_type.project_id AND drone_run_band_type.type_id=$drone_run_band_type_cvterm_id)
65 JOIN project_relationship AS drone_run_band_rel ON (drone_run_band_rel.subject_project_id = drone_run_band_project.project_id AND drone_run_band_rel.type_id = $drone_run_band_drone_run_project_relationship_type_id_cvterm_id)
66 JOIN project AS drone_run_project ON (drone_run_band_rel.object_project_id = drone_run_project.project_id)
67 JOIN projectprop AS drone_run_date ON(drone_run_project.project_id=drone_run_date.project_id AND drone_run_date.type_id=$project_start_date_type_id)
68 LEFT JOIN projectprop AS drone_run_type ON(drone_run_project.project_id=drone_run_type.project_id AND drone_run_type.type_id=$drone_run_project_type_type_id)
69 LEFT JOIN projectprop AS drone_run_is_raw_images ON(drone_run_project.project_id=drone_run_is_raw_images.project_id AND drone_run_is_raw_images.type_id=$drone_run_is_raw_images_type_id)
70 LEFT JOIN projectprop AS drone_run_ground_control_points ON(drone_run_project.project_id=drone_run_ground_control_points.project_id AND drone_run_ground_control_points.type_id=$drone_run_ground_control_points_type_id)
71 LEFT JOIN projectprop AS drone_run_averaged_temperature_gdd ON(drone_run_project.project_id=drone_run_averaged_temperature_gdd.project_id AND drone_run_averaged_temperature_gdd.type_id=$drone_run_project_averaged_temperature_gdd_type_id)
72 LEFT JOIN projectprop AS drone_run_averaged_precipitation_sum ON(drone_run_project.project_id=drone_run_averaged_precipitation_sum.project_id AND drone_run_averaged_precipitation_sum.type_id=$drone_run_project_averaged_precipitation_sum_type_id)
73 LEFT JOIN projectprop AS drone_run_related_time_cvterm_json ON(drone_run_related_time_cvterm_json.project_id = drone_run_project.project_id AND drone_run_related_time_cvterm_json.type_id = $drone_run_related_time_cvterms_json_type_id)
74 LEFT JOIN projectprop AS drone_run_indicator ON(drone_run_indicator.project_id = drone_run_project.project_id AND drone_run_indicator.type_id = $process_indicator_cvterm_id)
75 LEFT JOIN projectprop AS drone_run_phenotypes_indicator ON(drone_run_phenotypes_indicator.project_id = drone_run_project.project_id AND drone_run_phenotypes_indicator.type_id = $phenotypes_processed_cvterm_id)
76 LEFT JOIN projectprop AS drone_run_processed_extended ON(drone_run_processed_extended.project_id = drone_run_project.project_id AND drone_run_processed_extended.type_id = $processed_extended_cvterm_id)
77 LEFT JOIN projectprop AS drone_run_processed_vi ON(drone_run_processed_vi.project_id = drone_run_project.project_id AND drone_run_processed_vi.type_id = $processed_vi_cvterm_id)
78 LEFT JOIN projectprop AS drone_run_processed ON(drone_run_processed.project_id = drone_run_project.project_id AND drone_run_processed.type_id = $processed_cvterm_id)
79 LEFT JOIN projectprop AS drone_run_camera_rig ON(drone_run_camera_rig.project_id = drone_run_project.project_id AND drone_run_camera_rig.type_id = $drone_run_camera_rig_cvterm_id)
80 LEFT JOIN projectprop AS drone_run_base_date ON(drone_run_base_date.project_id = drone_run_project.project_id AND drone_run_base_date.type_id = $drone_run_base_date_cvterm_id)
81 JOIN project_relationship AS field_trial_rel ON (drone_run_project.project_id = field_trial_rel.subject_project_id AND field_trial_rel.type_id=$drone_run_field_trial_project_relationship_type_id_cvterm_id)
82 JOIN project AS field_trial ON (field_trial_rel.object_project_id = field_trial.project_id);";
83 my $h = $schema->storage->dbh()->prepare($drone_run_q);
84 $h->execute();
86 my $calendar_funcs = CXGN::Calendar->new({});
88 my %unique_drone_runs;
89 my %unique_drone_run_dates;
90 my $epoch_seconds = 0;
91 my %trial_id_hash;
92 while( my ($drone_run_band_project_id, $drone_run_band_project_name, $drone_run_band_project_desc, $drone_run_project_id, $drone_run_project_name, $drone_run_project_desc, $field_trial_project_id, $field_trial_project_name, $field_trial_project_desc, $drone_run_band_project_type, $drone_run_date, $drone_run_type, $drone_run_averaged_temperature_gdd, $drone_run_averaged_precipitation_sum, $drone_run_related_time_cvterm_json, $drone_run_indicator, $drone_run_phenotypes_indicator, $drone_run_processed, $drone_run_processed_extended, $drone_run_processed_vi, $drone_run_is_raw_images, $drone_run_ground_control_points_json, $drone_run_camera_rig, $drone_run_base_date) = $h->fetchrow_array()) {
93 my $drone_run_date_formatted = $drone_run_date ? $calendar_funcs->display_start_date($drone_run_date) : '';
95 $unique_drone_runs{$field_trial_project_name}->{$drone_run_project_id}->{bands}->{$drone_run_band_project_id}->{drone_run_band_project_name} = $drone_run_band_project_name;
96 $unique_drone_runs{$field_trial_project_name}->{$drone_run_project_id}->{bands}->{$drone_run_band_project_id}->{drone_run_band_project_description} = $drone_run_band_project_desc;
97 $unique_drone_runs{$field_trial_project_name}->{$drone_run_project_id}->{bands}->{$drone_run_band_project_id}->{drone_run_band_project_type} = $drone_run_band_project_type;
98 $unique_drone_runs{$field_trial_project_name}->{$drone_run_project_id}->{trial_id} = $field_trial_project_id;
99 $unique_drone_runs{$field_trial_project_name}->{$drone_run_project_id}->{trial_name} = $field_trial_project_name;
100 $unique_drone_runs{$field_trial_project_name}->{$drone_run_project_id}->{drone_run_project_name} = $drone_run_project_name;
101 $unique_drone_runs{$field_trial_project_name}->{$drone_run_project_id}->{drone_run_date} = $drone_run_date_formatted;
102 $unique_drone_runs{$field_trial_project_name}->{$drone_run_project_id}->{drone_run_type} = $drone_run_type;
103 $unique_drone_runs{$field_trial_project_name}->{$drone_run_project_id}->{drone_run_is_raw_images} = $drone_run_is_raw_images;
104 $unique_drone_runs{$field_trial_project_name}->{$drone_run_project_id}->{drone_run_indicator} = $drone_run_indicator;
105 $unique_drone_runs{$field_trial_project_name}->{$drone_run_project_id}->{drone_run_processed} = $drone_run_processed;
106 $unique_drone_runs{$field_trial_project_name}->{$drone_run_project_id}->{drone_run_processed_minimal_vi} = $drone_run_processed_vi;
107 $unique_drone_runs{$field_trial_project_name}->{$drone_run_project_id}->{drone_run_processed_extended} = $drone_run_processed_extended;
108 $unique_drone_runs{$field_trial_project_name}->{$drone_run_project_id}->{drone_run_phenotypes_indicator} = $drone_run_phenotypes_indicator;
109 $unique_drone_runs{$field_trial_project_name}->{$drone_run_project_id}->{drone_run_project_description} = $drone_run_project_desc;
110 $unique_drone_runs{$field_trial_project_name}->{$drone_run_project_id}->{drone_run_averaged_temperature_gdd} = $drone_run_averaged_temperature_gdd;
111 $unique_drone_runs{$field_trial_project_name}->{$drone_run_project_id}->{drone_run_averaged_precipitation_sum} = $drone_run_averaged_precipitation_sum;
112 $unique_drone_runs{$field_trial_project_name}->{$drone_run_project_id}->{drone_run_camera_rig} = $drone_run_camera_rig;
113 $unique_drone_runs{$field_trial_project_name}->{$drone_run_project_id}->{drone_run_base_date} = $drone_run_base_date ? $calendar_funcs->display_start_date($drone_run_base_date) : '';
114 $unique_drone_runs{$field_trial_project_name}->{$drone_run_project_id}->{drone_run_related_time_cvterm_json} = decode_json $drone_run_related_time_cvterm_json;
115 $unique_drone_runs{$field_trial_project_name}->{$drone_run_project_id}->{drone_run_ground_control_points} = $drone_run_ground_control_points_json ? decode_json $drone_run_ground_control_points_json : undef;
117 $trial_id_hash{$field_trial_project_name} = $field_trial_project_id;
119 if ($drone_run_date_formatted) {
120 my $date_obj = Time::Piece->strptime($drone_run_date_formatted, "%Y-%B-%d %H:%M:%S");
121 $epoch_seconds = $date_obj->epoch;
123 else {
124 $epoch_seconds++;
126 $unique_drone_run_dates{$field_trial_project_name}->{$epoch_seconds} = $drone_run_project_id;
129 my @return;
130 foreach my $trial_name (sort keys %unique_drone_runs) {
131 my %unique_drone_runs_k = %{$unique_drone_runs{$trial_name}};
133 my $drone_run_html = '<div class="panel-group" id="drone_runs_trial_accordion_table_wrapper_'.$trial_id_hash{$trial_name}.'" ><div class="panel panel-default"><div class="panel-heading"><div class="row"><div class="col-sm-10"><h4 class="panel-title"><a data-toggle="collapse" data-parent="#drone_runs_trial_accordion_table_wrapper_'.$trial_id_hash{$trial_name}.'" href="#drone_runs_trial_accordion_table_wrapper_one_'.$trial_id_hash{$trial_name}.'" >Field Trial: '.$trial_name.'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;('.scalar(keys %unique_drone_runs_k).' Imaging Events)</a></h4></div><div class="col-sm-2"><button class="btn btn-sm btn-default" name="drone_runs_trial_view_timeseries" data-field_trial_name='.$trial_name.' data-field_trial_id='.$trial_id_hash{$trial_name}.'>View TimeSeries</button></div></div></div><div id="drone_runs_trial_accordion_table_wrapper_one_'.$trial_id_hash{$trial_name}.'" class="panel-collapse collapse"><div class="panel-body">';
135 foreach my $epoch_seconds (sort keys %{$unique_drone_run_dates{$trial_name}}) {
136 my $k = $unique_drone_run_dates{$trial_name}->{$epoch_seconds};
137 my $v = $unique_drone_runs_k{$k};
138 my $drone_run_bands = $v->{bands};
139 my $drone_run_date = $v->{drone_run_date};
141 $drone_run_html .= '<div class="panel-group" id="drone_run_band_accordion_drone_run_wrapper_'.$k.'" ><div class="panel panel-default"><div class="panel-heading"><h4 class="panel-title"><a data-toggle="collapse" data-parent="#drone_run_band_accordion_drone_run_wrapper_'.$k.'" href="#drone_run_band_accordion_drone_run_wrapper_one_'.$k.'" >'.$v->{drone_run_project_name}.'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp'.$drone_run_date.'</a></h4></div><div id="drone_run_band_accordion_drone_run_wrapper_one_'.$k.'" class="panel-collapse collapse"><div class="panel-body">';
143 $drone_run_html .= '<div class="well well-sm">';
145 $drone_run_html .= '<div class="row"><div class="col-sm-6">';
146 $drone_run_html .= '<div class="row"><div class="col-sm-5"><b>Imaging Event Name</b>:</div><div class="col-sm-7"><a href="/breeders_toolbox/trial/'.$k.'" _target="blank">'.$v->{drone_run_project_name}.'</a></div></div>';
147 $drone_run_html .= '<div class="row"><div class="col-sm-5"><b>Imaging Event Type</b>:</div><div class="col-sm-7">'.$v->{drone_run_type}.'</div></div>';
148 $drone_run_html .= '<div class="row"><div class="col-sm-5"><b>Description</b>:</div><div class="col-sm-7">'.$v->{drone_run_project_description}.'</div></div>';
149 $drone_run_html .= '<div class="row"><div class="col-sm-5"><b>Date</b>:</div><div class="col-sm-7">'.$drone_run_date.'</div></div>';
150 if ($v->{drone_run_base_date}) {
151 $drone_run_html .= '<div class="row"><div class="col-sm-5"><b>Base Date</b>:</div><div class="col-sm-7">'.$v->{drone_run_base_date}.'</div></div>';
153 if ($v->{drone_run_camera_rig}) {
154 $drone_run_html .= '<div class="row"><div class="col-sm-5"><b>Camera Rig</b>:</div><div class="col-sm-7">'.$v->{drone_run_camera_rig}.'</div></div>';
156 if (defined($v->{drone_run_averaged_temperature_gdd})) {
157 $drone_run_html .= '<div class="row"><div class="col-sm-5"><b>Averaged Temperature Growing Degree Days</b>:</div><div class="col-sm-7">'.$v->{drone_run_averaged_temperature_gdd}.'&nbsp;&nbsp;&nbsp;<button class="btn btn-default btn-sm" name="drone_imagery_drone_run_calculate_gdd" data-drone_run_project_id="'.$k.'" data-field_trial_id="'.$v->{trial_id}.'">Recalculate GDD</button></div></div>';
159 else {
160 $drone_run_html .= '<div class="row"><div class="col-sm-5"><b>Growing Degree Days</b>:</div><div class="col-sm-7"><button class="btn btn-default btn-sm" name="drone_imagery_drone_run_calculate_gdd" data-drone_run_project_id="'.$k.'" data-field_trial_id="'.$v->{trial_id}.'">Calculate GDD</button></div></div>';
162 if (defined($v->{drone_run_averaged_precipitation_sum}) ) {
163 $drone_run_html .= '<div class="row"><div class="col-sm-5"><b>Averaged Precipitation Sum</b>:</div><div class="col-sm-7">'.$v->{drone_run_averaged_precipitation_sum}.'&nbsp;&nbsp;&nbsp;<button class="btn btn-default btn-sm" name="drone_imagery_drone_run_calculate_precipitation_sum" data-drone_run_project_id="'.$k.'" data-field_trial_id="'.$v->{trial_id}.'">Recalculate Precipitation Sum</button></div></div>';
165 else {
166 $drone_run_html .= '<div class="row"><div class="col-sm-5"><b>Precipitation Sum</b>:</div><div class="col-sm-7"><button class="btn btn-default btn-sm" name="drone_imagery_drone_run_calculate_precipitation_sum" data-drone_run_project_id="'.$k.'" data-field_trial_id="'.$v->{trial_id}.'">Calculate Precipitation Sum</button></div></div>';
168 my @days_after_planting_strings = split '\|', $v->{drone_run_related_time_cvterm_json}->{day};
169 my $days_after_planting_string = $days_after_planting_strings[0];
170 $drone_run_html .= '<div class="row"><div class="col-sm-5"><b>Growing Season Days</b>:</div><div class="col-sm-7">'.$days_after_planting_string.'</div></div>';
171 $drone_run_html .= '<div class="row"><div class="col-sm-5"><b>Field Trial</b>:</div><div class="col-sm-7"><a href="/breeders_toolbox/trial/'.$v->{trial_id}.'" _target="blank">'.$v->{trial_name}.'</a></div></div>';
172 $drone_run_html .= '</div><div class="col-sm-3">';
173 if ($v->{drone_run_indicator}) {
174 $drone_run_html .= '<span class="label label-info" ><span class="glyphicon glyphicon-hourglass"></span>&nbsp;&nbsp;&nbsp;Processing Images in Progress</span><br/><br/>';
176 if ($v->{drone_run_phenotypes_indicator}) {
177 $drone_run_html .= '<span class="label label-info" ><span class="glyphicon glyphicon-hourglass"></span>&nbsp;&nbsp;&nbsp;Processing Phenotypes in Progress</span><br/><br/>';
178 } elsif ($v->{drone_run_processed}) {
179 # $drone_run_html .= '<button class="btn btn-primary btn-sm" name="project_drone_imagery_phenotype_run" data-drone_run_project_id="'.$k.'" data-field_trial_id="'.$v->{trial_id}.'" data-field_trial_name="'.$v->{trial_name}.'" >Generate Phenotypes for <br/>'.$v->{drone_run_project_name}.'</button>';
181 #$drone_run_html .= '<button class="btn btn-primary btn-sm" name="project_drone_imagery_phenotype_run" data-drone_run_project_id="'.$k.'" data-field_trial_id="'.$v->{trial_id}.'" data-field_trial_name="'.$v->{trial_name}.'" >Generate Phenotypes for <br/>'.$v->{drone_run_project_name}.'</button>';
183 $drone_run_html .= '</div><div class="col-sm-3">';
184 if (!$v->{drone_run_indicator}) {
185 # if ($v->{drone_run_is_raw_images}) {
186 # $drone_run_html .= '<button class="btn btn-default btn-sm" name="project_drone_imagery_stadard_process_raw_images_add_images" data-drone_run_project_id="'.$k.'" data-field_trial_id="'.$v->{trial_id}.'" data-field_trial_name="'.$v->{trial_name}.'" >Upload More Raw Images <br/>'.$v->{drone_run_project_name}.'</button><br/><br/>';
188 # #$drone_run_html .= '<button class="btn btn-primary btn-sm" name="project_drone_imagery_standard_process_raw_images" data-drone_run_project_id="'.$k.'" data-drone_run_project_name="'.$v->{drone_run_project_name}.'" data-field_trial_id="'.$v->{trial_id}.'" data-field_trial_name="'.$v->{trial_name}.'" >Run Raw Image Standard Process For<br/>'.$v->{drone_run_project_name}.'</button><br/><br/>';
190 # $drone_run_html .= '<button class="btn btn-primary btn-sm" name="project_drone_imagery_standard_process_raw_images_interactive" data-drone_run_project_id="'.$k.'" data-drone_run_project_name="'.$v->{drone_run_project_name}.'" data-field_trial_id="'.$v->{trial_id}.'" data-field_trial_name="'.$v->{trial_name}.'" >Run Interactive Raw Image Standard Process For<br/>'.$v->{drone_run_project_name}.'</button><br/><br/>';
192 # $drone_run_html .= '<button class="btn btn-primary btn-sm" name="project_drone_imagery_phenotype_run" data-drone_run_project_id="'.$k.'" data-field_trial_id="'.$v->{trial_id}.'" data-field_trial_name="'.$v->{trial_name}.'" >Generate Phenotypes for <br/>'.$v->{drone_run_project_name}.'</button><br/><br/>';
194 # else {
195 if (!$v->{drone_run_processed}) {
196 $drone_run_html .= '<button class="btn btn-primary btn-sm" name="project_drone_imagery_standard_process" data-drone_run_project_id="'.$k.'" data-drone_run_project_name="'.$v->{drone_run_project_name}.'" data-field_trial_id="'.$v->{trial_id}.'" data-field_trial_name="'.$v->{trial_name}.'" >Run Standard Process For<br/>'.$v->{drone_run_project_name}.'</button><br/><br/>';
197 } elsif (!$v->{drone_run_processed_minimal_vi}) {
198 $drone_run_html .= '<button class="btn btn-default btn-sm" name="project_drone_imagery_standard_process_minimal_vi" data-drone_run_project_id="'.$k.'" data-drone_run_project_name="'.$v->{drone_run_project_name}.'" data-field_trial_id="'.$v->{trial_id}.'" data-field_trial_name="'.$v->{trial_name}.'" >Run Minimal Vegetitative Index Standard Process For<br/>'.$v->{drone_run_project_name}.'</button><br/><br/>';
199 } elsif (!$v->{drone_run_processed_extended}) {
200 #$drone_run_html .= '<button class="btn btn-default btn-sm" name="project_drone_imagery_standard_process_extended" data-drone_run_project_id="'.$k.'" data-drone_run_project_name="'.$v->{drone_run_project_name}.'" data-field_trial_id="'.$v->{trial_id}.'" data-field_trial_name="'.$v->{trial_name}.'" >Run Extended Standard Process For<br/>'.$v->{drone_run_project_name}.'</button><br/><br/>';
203 # if ($v->{drone_run_processed} && !$v->{drone_run_ground_control_points}) {
204 if ($v->{drone_run_processed}) {
205 $drone_run_html .= '<button class="btn btn-default btn-sm" name="project_drone_imagery_ground_control_points" data-drone_run_project_id="'.$k.'" data-drone_run_project_name="'.$v->{drone_run_project_name}.'" data-field_trial_id="'.$v->{trial_id}.'" data-field_trial_name="'.$v->{trial_name}.'" >Save Ground Control Points For<br/>'.$v->{drone_run_project_name}.'</button><br/><br/>';
209 $drone_run_html .= '<button class="btn btn-default btn-sm" name="project_drone_imagery_quality_control_check" data-drone_run_project_id="'.$k.'" data-drone_run_project_name="'.$v->{drone_run_project_name}.'" data-field_trial_id="'.$v->{trial_id}.'" data-field_trial_name="'.$v->{trial_name}.'" >Quality Control Plot Images For<br/>'.$v->{drone_run_project_name}.'</button><br/><br/>';
211 $drone_run_html .= '<button class="btn btn-danger btn-sm" name="project_drone_imagery_delete_drone_run" data-drone_run_project_id="'.$k.'" data-drone_run_project_name="'.$v->{drone_run_project_name}.'" >Delete Imaging Event</button>';
213 $drone_run_html .= '</div></div></div>';
215 $drone_run_html .= "<hr>";
217 $drone_run_html .= '<div name="drone_run_band_total_plot_image_div" id="drone_run_band_total_plot_image_count_div_'.$k.'">';
218 $drone_run_html .= '<div class="panel-group"><div class="panel panel-default panel-sm"><div class="panel-heading"><h4 class="panel-title"><a data-toggle="collapse" >Loading Plot Image Summary...</a></h4></div></div></div>';
219 $drone_run_html .= '</div>';
221 my $drone_run_band_table_html = '<table class="table table-bordered"><thead><tr><th>Image Band(s)</th><th>Images/Actions</th></thead><tbody>';
223 foreach my $drone_run_band_project_id (sort keys %$drone_run_bands) {
224 my $d = $drone_run_bands->{$drone_run_band_project_id};
226 $drone_run_band_table_html .= '<tr><td><b>Name</b>: '.$d->{drone_run_band_project_name}.'<br/><b>Description</b>: '.$d->{drone_run_band_project_description}.'<br/><b>Type</b>: '.$d->{drone_run_band_project_type}.'</td><td>';
228 $drone_run_band_table_html .= '<div class="panel-group" id="drone_run_band_accordion_'.$drone_run_band_project_id.'" ><div class="panel panel-default"><div class="panel-heading"><h4 class="panel-title"><a data-toggle="collapse" data-parent="#drone_run_band_accordion_'.$drone_run_band_project_id.'" href="#drone_run_band_accordion_one_'.$drone_run_band_project_id.'" onclick="manageDroneImageryDroneRunBandDisplay('.$drone_run_band_project_id.')">View Images</a></h4></div><div id="drone_run_band_accordion_one_'.$drone_run_band_project_id.'" class="panel-collapse collapse"><div class="panel-body">';
230 $drone_run_band_table_html .= '<div id="drone_run_band_accordian_drone_run_band_div_'.$drone_run_band_project_id.'"></div>';
232 $drone_run_band_table_html .= '</div></div></div></div>';
233 $drone_run_band_table_html .= '</td></tr>';
236 $drone_run_band_table_html .= '</tbody></table>';
238 $drone_run_html .= $drone_run_band_table_html;
240 # $drone_run_html .= '<button class="btn btn-primary btn-sm" name="project_drone_imagery_merge_channels" data-drone_run_project_id="'.$k.'" data-drone_run_project_name="'.$v->{drone_run_project_name}.'" >Merge Drone Run Bands For '.$v->{drone_run_project_name}.'</button><br/><br/>';
242 $drone_run_html .= '</div></div></div></div>';
244 $drone_run_html .= '<br/>';
246 $drone_run_html .= '</div></div></div></div>';
248 push @return, [$drone_run_html];
251 $c->stash->{rest} = { data => \@return };
254 sub raw_drone_imagery_drone_run_band_summary : Path('/api/drone_imagery/raw_drone_imagery_drone_run_band') : ActionClass('REST') { }
255 sub raw_drone_imagery_drone_run_band_summary_GET : Args(0) {
256 my $self = shift;
257 my $c = shift;
258 my $drone_run_band_project_id = $c->req->param('drone_run_band_project_id');
259 my $sp_person_id = $c->user() ? $c->user->get_object()->get_sp_person_id() : undef;
260 my $schema = $c->dbic_schema("Bio::Chado::Schema", undef, $sp_person_id);
261 my $calendar_funcs = CXGN::Calendar->new({});
263 my $main_image_types = CXGN::DroneImagery::ImageTypes::get_all_project_md_image_types_whole_images($schema);
264 my @main_image_types_array = keys %$main_image_types;
265 my $images_search = CXGN::DroneImagery::ImagesSearch->new({
266 bcs_schema=>$schema,
267 drone_run_band_project_id_list=>[$drone_run_band_project_id],
268 project_image_type_id_list=>\@main_image_types_array
270 my ($result, $total_count) = $images_search->search();
271 #print STDERR Dumper $result;
273 my $observation_unit_plot_polygon_types = CXGN::DroneImagery::ImageTypes::get_all_project_md_image_observation_unit_plot_polygon_types($schema);
274 my $observation_unit_plot_polygon_type_names;
275 while (my ($k, $v) = each %$observation_unit_plot_polygon_types) {
276 $observation_unit_plot_polygon_type_names->{$v->{name}} = $v->{display_name};
279 my @observation_unit_plot_polygon_types_array = keys %$observation_unit_plot_polygon_types;
280 my $observation_unit_polygon_imagery_search = CXGN::DroneImagery::ImagesSearch->new({
281 bcs_schema=>$schema,
282 drone_run_band_project_id_list=>[$drone_run_band_project_id],
283 project_image_type_id_list=>\@observation_unit_plot_polygon_types_array
285 my ($observation_unit_polygon_result, $observation_unit_polygon_total_count) = $observation_unit_polygon_imagery_search->search();
286 #print STDERR Dumper $observation_unit_polygon_result;
288 my %original_background_removed_threshold_terms = (
289 'threshold_background_removed_stitched_drone_imagery_blue' => 'Blue (450-520nm)',
290 'threshold_background_removed_stitched_drone_imagery_green' => 'Green (515-600nm)',
291 'threshold_background_removed_stitched_drone_imagery_red' => 'Red (600-690nm)',
292 'threshold_background_removed_stitched_drone_imagery_red_edge' => 'Red Edge (690-750nm)',
293 'threshold_background_removed_stitched_drone_imagery_nir' => 'NIR (780-3000nm)',
294 'threshold_background_removed_stitched_drone_imagery_mir' => 'MIR (3000-50000nm)',
295 'threshold_background_removed_stitched_drone_imagery_fir' => 'FIR (50000-1000000nm)',
296 'threshold_background_removed_stitched_drone_imagery_tir' => 'Thermal IR (9000-14000nm)',
297 'threshold_background_removed_stitched_drone_imagery_bw' => 'Black and White Image',
298 'threshold_background_removed_stitched_drone_imagery_rgb_channel_1' => 'RGB Color Image',
299 'threshold_background_removed_stitched_drone_imagery_rgb_channel_2' => 'RGB Color Image',
300 'threshold_background_removed_stitched_drone_imagery_rgb_channel_3' => 'RGB Color Image',
303 my %original_denoised_observation_unit_polygon_terms = (
304 'Blue (450-520nm)' => ['observation_unit_polygon_blue_imagery'],
305 'Green (515-600nm)' => ['observation_unit_polygon_green_imagery'],
306 'Red (600-690nm)' => ['observation_unit_polygon_red_imagery'],
307 'Red Edge (690-750nm)' => ['observation_unit_polygon_red_edge_imagery'],
308 'NIR (780-3000nm)' => ['observation_unit_polygon_nir_imagery'],
309 'MIR (3000-50000nm)' => ['observation_unit_polygon_mir_imagery'],
310 'FIR (50000-1000000nm)' => ['observation_unit_polygon_fir_imagery'],
311 'Thermal IR (9000-14000nm)' => ['observation_unit_polygon_tir_imagery'],
312 'Black and White Image' => ['observation_unit_polygon_bw_imagery'],
313 'RGB Color Image' => ['observation_unit_polygon_rgb_imagery', 'observation_unit_polygon_rgb_imagery_channel_1', 'observation_unit_polygon_rgb_imagery_channel_2', 'observation_unit_polygon_rgb_imagery_channel_3'],
314 'Merged 3 Bands BGR' => ['observation_unit_polygon_rgb_imagery'],
315 'Merged 3 Bands NRN' => ['observation_unit_polygon_nrn_imagery'],
316 'Merged 3 Bands NReN' => ['observation_unit_polygon_nren_imagery']
319 my $imagery_attribute_map = CXGN::DroneImagery::ImageTypes::get_imagery_attribute_map();
320 my $original_denoised_imagery_terms = CXGN::DroneImagery::ImageTypes::get_base_imagery_observation_unit_plot_polygon_term_map();
321 my $vi_map_hash = CXGN::DroneImagery::ImageTypes::get_vegetative_index_image_type_term_map();
323 my @return;
324 my %unique_drone_runs;
325 foreach (@$result) {
326 my $image_id = $_->{image_id};
327 my $image = SGN::Image->new( $schema->storage->dbh, $image_id, $c );
328 my $image_source_tag_tiny = $image->get_img_src_tag("tiny");
329 my $image_source_tag_small = $image->get_img_src_tag("thumbnail");
330 my $image_original = $image->get_image_url("original");
331 if ($_->{project_image_type_name} eq 'raw_drone_imagery') {
332 push @{$unique_drone_runs{$_->{drone_run_project_id}}->{bands}->{$_->{drone_run_band_project_id}}->{images}}, '<a href="/image/view/'.$image_id.'" target="_blank">'.$image_source_tag_tiny.'</a>';
333 $unique_drone_runs{$_->{drone_run_project_id}}->{bands}->{$_->{drone_run_band_project_id}}->{usernames}->{$_->{username}}++;
334 $unique_drone_runs{$_->{drone_run_project_id}}->{bands}->{$_->{drone_run_band_project_id}}->{drone_run_band_project_name} = $_->{drone_run_band_project_name};
335 $unique_drone_runs{$_->{drone_run_project_id}}->{bands}->{$_->{drone_run_band_project_id}}->{drone_run_band_project_description} = $_->{drone_run_band_project_description};
336 $unique_drone_runs{$_->{drone_run_project_id}}->{bands}->{$_->{drone_run_band_project_id}}->{drone_run_band_project_type} = $_->{drone_run_band_project_type};
337 $unique_drone_runs{$_->{drone_run_project_id}}->{trial_id} = $_->{trial_id};
338 $unique_drone_runs{$_->{drone_run_project_id}}->{trial_name} = $_->{trial_name};
339 $unique_drone_runs{$_->{drone_run_project_id}}->{drone_run_project_name} = $_->{drone_run_project_name};
340 $unique_drone_runs{$_->{drone_run_project_id}}->{drone_run_date} = $_->{drone_run_date};
341 $unique_drone_runs{$_->{drone_run_project_id}}->{drone_run_type} = $_->{drone_run_type};
342 $unique_drone_runs{$_->{drone_run_project_id}}->{drone_run_project_description} = $_->{drone_run_project_description};
344 elsif ($_->{project_image_type_name} eq 'stitched_drone_imagery') {
345 $unique_drone_runs{$_->{drone_run_project_id}}->{bands}->{$_->{drone_run_band_project_id}}->{stitched_image} = '<a href="/image/view/'.$image_id.'" target="_blank">'.$image_source_tag_small.'</a>';
346 $unique_drone_runs{$_->{drone_run_project_id}}->{bands}->{$_->{drone_run_band_project_id}}->{stitched_image_username} = $_->{username};
347 $unique_drone_runs{$_->{drone_run_project_id}}->{bands}->{$_->{drone_run_band_project_id}}->{stitched_image_modified_date} = $_->{image_modified_date};
348 $unique_drone_runs{$_->{drone_run_project_id}}->{bands}->{$_->{drone_run_band_project_id}}->{stitched_image_original} = $image_original;
349 $unique_drone_runs{$_->{drone_run_project_id}}->{bands}->{$_->{drone_run_band_project_id}}->{stitched_image_id} = $image_id;
350 $unique_drone_runs{$_->{drone_run_project_id}}->{bands}->{$_->{drone_run_band_project_id}}->{drone_run_band_project_name} = $_->{drone_run_band_project_name};
351 $unique_drone_runs{$_->{drone_run_project_id}}->{bands}->{$_->{drone_run_band_project_id}}->{drone_run_band_project_description} = $_->{drone_run_band_project_description};
352 $unique_drone_runs{$_->{drone_run_project_id}}->{bands}->{$_->{drone_run_band_project_id}}->{drone_run_band_project_type} = $_->{drone_run_band_project_type};
353 $unique_drone_runs{$_->{drone_run_project_id}}->{bands}->{$_->{drone_run_band_project_id}}->{usernames}->{$_->{username}}++;
354 $unique_drone_runs{$_->{drone_run_project_id}}->{trial_id} = $_->{trial_id};
355 $unique_drone_runs{$_->{drone_run_project_id}}->{trial_name} = $_->{trial_name};
356 $unique_drone_runs{$_->{drone_run_project_id}}->{drone_run_project_name} = $_->{drone_run_project_name};
357 $unique_drone_runs{$_->{drone_run_project_id}}->{drone_run_date} = $_->{drone_run_date};
358 $unique_drone_runs{$_->{drone_run_project_id}}->{drone_run_type} = $_->{drone_run_type};
359 $unique_drone_runs{$_->{drone_run_project_id}}->{drone_run_project_description} = $_->{drone_run_project_description};
361 else {
362 $unique_drone_runs{$_->{drone_run_project_id}}->{bands}->{$_->{drone_run_band_project_id}}->{$_->{project_image_type_name}} = '<a href="/image/view/'.$image_id.'" target="_blank">'.$image_source_tag_small.'</a>';
363 $unique_drone_runs{$_->{drone_run_project_id}}->{bands}->{$_->{drone_run_band_project_id}}->{$_->{project_image_type_name}."_username"} = $_->{username};
364 $unique_drone_runs{$_->{drone_run_project_id}}->{bands}->{$_->{drone_run_band_project_id}}->{$_->{project_image_type_name}."_modified_date"} = $_->{image_modified_date};
365 $unique_drone_runs{$_->{drone_run_project_id}}->{bands}->{$_->{drone_run_band_project_id}}->{$_->{project_image_type_name}."_original"} = $image_original;
366 $unique_drone_runs{$_->{drone_run_project_id}}->{bands}->{$_->{drone_run_band_project_id}}->{$_->{project_image_type_name}."_id"} = $image_id;
367 if (exists($imagery_attribute_map->{$_->{project_image_type_name}})) {
368 $unique_drone_runs{$_->{drone_run_project_id}}->{bands}->{$_->{drone_run_band_project_id}}->{$_->{project_image_type_name}."_".$imagery_attribute_map->{$_->{project_image_type_name}}->{name}} = $_->{$imagery_attribute_map->{$_->{project_image_type_name}}->{key}};
373 foreach (@$observation_unit_polygon_result) {
374 my $image_id = $_->{image_id};
375 my $image = SGN::Image->new( $schema->storage->dbh, $image_id, $c );
376 my $image_source_tag_tiny = $image->get_img_src_tag("tiny");
377 my $image_original = $image->get_image_url("original");
378 $unique_drone_runs{$_->{drone_run_project_id}}->{bands}->{$_->{drone_run_band_project_id}}->{$_->{project_image_type_name}."_polygons"} = $_->{drone_run_band_plot_polygons};
379 push @{$unique_drone_runs{$_->{drone_run_project_id}}->{bands}->{$_->{drone_run_band_project_id}}->{$_->{project_image_type_name}."_images"}}, '<a href="/image/view/'.$image_id.'" target="_blank">'.$image_source_tag_tiny.'</a>';
382 # print STDERR Dumper \%unique_drone_runs;
384 foreach my $k (sort keys %unique_drone_runs) {
385 my $v = $unique_drone_runs{$k};
387 my $drone_run_bands = $v->{bands};
389 my $drone_run_band_table_html = '';
391 foreach my $drone_run_band_project_id (sort keys %$drone_run_bands) {
392 my $d = $drone_run_bands->{$drone_run_band_project_id};
394 # If raw images were uploaded and orthomosaic will not be used.
395 if ($d->{images}) {
396 $drone_run_band_table_html .= '<div class="well well-sm"><div class="row"><div class="col-sm-6"><h5>Raw Images</h5></div><div class="col-sm-6">';
397 foreach (@{$d->{images}}) {
398 $drone_run_band_table_html .= $_;
400 $drone_run_band_table_html .= '</div></div></div>';
402 foreach my $t (@{$original_denoised_imagery_terms->{$d->{drone_run_band_project_type}}->{observation_unit_plot_polygon_types}->{base}}) {
403 if ($d->{$t."_images"}) {
404 $drone_run_band_table_html .= '<div class="well well-sm"><div class="row"><div class="col-sm-6"><h5>Assigned Plot-Polygon Images</h5></div><div class="col-sm-6">';
405 foreach (@{$d->{$t."_images"}}) {
406 $drone_run_band_table_html .= $_;
408 $drone_run_band_table_html .= '</div></div></div>';
413 # If orthomosaic was uploaded or stitched by ImageBreed on upload of raw images.
414 if ($d->{stitched_image}) {
415 $drone_run_band_table_html .= '<div class="well well-sm"><div class="row"><div class="col-sm-6"><h5>Stitched Image&nbsp;&nbsp;&nbsp;<span class="glyphicon glyphicon-remove-sign text-danger" name="drone_image_remove" data-image_id="'.$d->{stitched_image_id}.'"></span></h5><b>By</b>: '.$d->{stitched_image_username}.'<br/><b>Date</b>: '.$d->{stitched_image_modified_date}.'</div><div class="col-sm-6">'.$d->{stitched_image}.'</div></div></div>';
417 if ($d->{rotated_stitched_drone_imagery}) {
418 $drone_run_band_table_html .= '<div class="well well-sm"><div class="row"><div class="col-sm-6"><h5>Rotated Image&nbsp;&nbsp;&nbsp;<span class="glyphicon glyphicon-remove-sign text-danger" name="drone_image_remove" data-image_id="'.$d->{rotated_stitched_drone_imagery_id}.'"></span></h5><b>By</b>: '.$d->{rotated_stitched_drone_imagery_username}.'<br/><b>Date</b>: '.$d->{rotated_stitched_drone_imagery_modified_date}.'<br/><b>Rotated Angle</b>: '.$d->{rotated_stitched_drone_imagery_angle}.'</div><div class="col-sm-6">'.$d->{rotated_stitched_drone_imagery}.'</div></div></div>';
420 if ($d->{cropped_stitched_drone_imagery}) {
421 $drone_run_band_table_html .= '<div class="well well-sm"><div class="row"><div class="col-sm-6"><h5>Cropped Image&nbsp;&nbsp;&nbsp;<span class="glyphicon glyphicon-remove-sign text-danger" name="drone_image_remove" data-image_id="'.$d->{cropped_stitched_drone_imagery_id}.'"></span></h5><b>By</b>: '.$d->{cropped_stitched_drone_imagery_username}.'<br/><b>Date</b>: '.$d->{cropped_stitched_drone_imagery_modified_date}.'<br/><b>Cropped Polygon</b>: '.$d->{cropped_stitched_drone_imagery_polygon}.'</div><div class="col-sm-6">'.$d->{cropped_stitched_drone_imagery}.'</div></div></div>';
423 if ($d->{denoised_stitched_drone_imagery}) {
424 $drone_run_band_table_html .= _draw_drone_imagery_section($observation_unit_plot_polygon_type_names, $d, $d->{denoised_stitched_drone_imagery_id}, $d->{denoised_stitched_drone_imagery_username}, $d->{denoised_stitched_drone_imagery_modified_date}, undef, $d->{denoised_stitched_drone_imagery}, $original_denoised_observation_unit_polygon_terms{$d->{drone_run_band_project_type}}, $d->{stitched_image_id}, $d->{cropped_stitched_drone_imagery_id}, $d->{denoised_stitched_drone_imagery_id}, $v->{trial_id}, uri_encode($d->{stitched_image_original}), $drone_run_band_project_id, $d->{drone_run_band_project_type}, $k, $d->{denoised_stitched_drone_imagery_id}, $v->{drone_run_project_name});
426 # $drone_run_band_table_html .= '<button class="btn btn-primary btn-sm" name="project_drone_imagery_add_georeference" data-stitched_image_id="'.$d->{stitched_image_id}.'" data-cropped_stitched_image_id="'.$d->{cropped_stitched_drone_imagery_id}.'" data-denoised_stitched_image_id="'.$d->{denoised_stitched_drone_imagery_id}.'" data-field_trial_id="'.$v->{trial_id}.'" data-drone_run_project_id="'.$k.'" data-drone_run_band_project_id="'.$drone_run_band_project_id.'" >Add Georeferenced Points</button><br/><br/>';
428 foreach my $original_background_removed_threshold_term (keys %original_background_removed_threshold_terms) {
429 my $plot_polygon_type = $imagery_attribute_map->{$original_background_removed_threshold_term}->{observation_unit_plot_polygon_type};
430 if (exists($d->{$original_background_removed_threshold_term})) {
431 $drone_run_band_table_html .= _draw_drone_imagery_section($observation_unit_plot_polygon_type_names, $d, $d->{$original_background_removed_threshold_term."_id"}, $d->{$original_background_removed_threshold_term."_username"}, $d->{$original_background_removed_threshold_term."_modified_date"}, $d->{$original_background_removed_threshold_term."_threshold"}, $d->{$original_background_removed_threshold_term}, [$plot_polygon_type], $d->{stitched_image_id}, $d->{cropped_stitched_drone_imagery_id}, $d->{denoised_stitched_drone_imagery_id}, $v->{trial_id}, uri_encode($d->{stitched_image_original}), $drone_run_band_project_id, $d->{drone_run_band_project_type}, $k, $d->{$original_background_removed_threshold_term."_id"}, $v->{drone_run_project_name});
432 } else {
433 if ($d->{drone_run_band_project_type} eq $original_background_removed_threshold_terms{$original_background_removed_threshold_term}) {
434 # $drone_run_band_table_html .= '<button class="btn btn-primary btn-sm" name="project_drone_imagery_remove_background" data-denoised_stitched_image_id="'.$d->{denoised_stitched_drone_imagery_id}.'" data-field_trial_id="'.$v->{trial_id}.'" data-stitched_image="'.uri_encode($d->{stitched_image_original}).'" data-denoised_stitched_image="'.uri_encode($d->{denoised_stitched_drone_imagery_original}).'" data-drone_run_project_id="'.$k.'" data-drone_run_band_project_id="'.$drone_run_band_project_id.'" data-remove_background_current_image_id="'.$d->{denoised_stitched_drone_imagery_id}.'" data-remove_background_current_image_type="'.$original_background_removed_threshold_term.'" >Remove Background From Original Denoised Image via Threshold</button><br/><br/>';
435 # $drone_run_band_table_html .= '<button class="btn btn-default btn-sm disabled">Imagery of type '.$original_background_removed_threshold_term.' and subsequently plot polygons of type '.$plot_polygon_type.' are not found. The standard process should have covered all supported image cases. Please try again or contact us.</button><br/><br/>';
440 foreach my $ft_hpf_denoised_original_image_type_filter (keys %{$original_denoised_imagery_terms->{$d->{drone_run_band_project_type}}->{imagery_types}->{ft_hpf}}) {
441 my $ft_hpf30_denoised_imagery_type_counter = 0;
442 foreach my $ft_hpf30_denoised_original_image_type (@{$original_denoised_imagery_terms->{$d->{drone_run_band_project_type}}->{imagery_types}->{ft_hpf}->{$ft_hpf_denoised_original_image_type_filter}}) {
443 my $ft_hpf30_denoised_plot_polygon_type = $original_denoised_imagery_terms->{$d->{drone_run_band_project_type}}->{observation_unit_plot_polygon_types}->{ft_hpf}->{$ft_hpf_denoised_original_image_type_filter}->[$ft_hpf30_denoised_imagery_type_counter];
444 if ($d->{$ft_hpf30_denoised_original_image_type}) {
445 $drone_run_band_table_html .= _draw_drone_imagery_section($observation_unit_plot_polygon_type_names, $d, $d->{$ft_hpf30_denoised_original_image_type."_id"}, $d->{$ft_hpf30_denoised_original_image_type."_username"}, $d->{$ft_hpf30_denoised_original_image_type."_modified_date"}, undef, $d->{$ft_hpf30_denoised_original_image_type}, [$ft_hpf30_denoised_plot_polygon_type], $d->{stitched_image_id}, $d->{cropped_stitched_drone_imagery_id}, $d->{denoised_stitched_drone_imagery_id}, $v->{trial_id}, uri_encode($d->{stitched_image_original}), $drone_run_band_project_id, $d->{drone_run_band_project_type}, $k, $d->{$ft_hpf30_denoised_original_image_type.'_id'}, $v->{drone_run_project_name});
446 } else {
447 #$drone_run_band_table_html .= '<button class="btn btn-primary btn-sm" name="project_drone_imagery_fourier_transform_hpf30" data-image_id="'.$d->{denoised_stitched_drone_imagery_id}.'" data-field_trial_id="'.$v->{trial_id}.'" data-drone_run_project_id="'.$k.'" data-drone_run_band_project_id="'.$drone_run_band_project_id.'" data-drone_run_band_project_type="'.$d->{drone_run_band_project_type}.'", data-selected_image_type="'.$ft_hpf30_denoised_original_image_type.'" >Run Fourier Transform HPF30 ('.$ft_hpf30_denoised_original_image_type.')</button><br/><br/>';
448 # $drone_run_band_table_html .= '<button class="btn btn-default btn-sm disabled">Imagery of type '.$ft_hpf30_denoised_original_image_type.' and subsequently plot polygons of type '.$ft_hpf30_denoised_plot_polygon_type.' are not found. The standard process should have covered all supported image cases. Please try again or contact us.</button><br/><br/>';
450 $ft_hpf30_denoised_imagery_type_counter++;
454 if ($d->{drone_run_band_project_type} eq 'RGB Color Image' || $d->{drone_run_band_project_type} eq 'Merged 3 Bands BGR' || $d->{drone_run_band_project_type} eq 'Merged 3 Bands NRN' || $d->{drone_run_band_project_type} eq 'Merged 3 Bands NReN') {
455 if ($d->{drone_run_band_project_type} eq 'RGB Color Image') {
456 # $drone_run_band_table_html .= '<button class="btn btn-primary btn-sm" name="project_drone_imagery_rgb_vegetative" data-denoised_stitched_image_id="'.$d->{denoised_stitched_drone_imagery_id}.'" data-field_trial_id="'.$v->{trial_id}.'" data-stitched_image="'.uri_encode($d->{stitched_image_original}).'" data-denoised_stitched_image="'.uri_encode($d->{denoised_stitched_drone_imagery_original}).'" data-drone_run_project_id="'.$k.'" data-drone_run_band_project_id="'.$drone_run_band_project_id.'" data-drone_run_band_project_type="'.$d->{drone_run_band_project_type}.'">Convert to Vegetative Index</button><br/><br/>';
458 elsif ($d->{drone_run_band_project_type} eq 'Merged 3 Bands BGR') {
459 # $drone_run_band_table_html .= '<button class="btn btn-primary btn-sm" name="project_drone_imagery_3_band_bgr_vegetative" data-denoised_stitched_image_id="'.$d->{denoised_stitched_drone_imagery_id}.'" data-field_trial_id="'.$v->{trial_id}.'" data-stitched_image="'.uri_encode($d->{stitched_image_original}).'" data-denoised_stitched_image="'.uri_encode($d->{denoised_stitched_drone_imagery_original}).'" data-drone_run_project_id="'.$k.'" data-drone_run_band_project_id="'.$drone_run_band_project_id.'" data-drone_run_band_project_type="'.$d->{drone_run_band_project_type}.'">Convert to Vegetative Index</button><br/><br/>';
461 elsif ($d->{drone_run_band_project_type} eq 'Merged 3 Bands NRN') {
462 # $drone_run_band_table_html .= '<button class="btn btn-primary btn-sm" name="project_drone_imagery_3_band_nrn_vegetative" data-denoised_stitched_image_id="'.$d->{denoised_stitched_drone_imagery_id}.'" data-field_trial_id="'.$v->{trial_id}.'" data-stitched_image="'.uri_encode($d->{stitched_image_original}).'" data-denoised_stitched_image="'.uri_encode($d->{denoised_stitched_drone_imagery_original}).'" data-drone_run_project_id="'.$k.'" data-drone_run_band_project_id="'.$drone_run_band_project_id.'" data-drone_run_band_project_type="'.$d->{drone_run_band_project_type}.'">Convert to Vegetative Index</button><br/><br/>';
464 foreach my $imagery_term (sort keys %{$vi_map_hash->{NDVI}}) {
465 while (my ($image_type_term, $observation_unit_plot_polygon_types) = each %{$vi_map_hash->{NDVI}->{$imagery_term}}) {
466 foreach my $observation_unit_plot_polygon_type (@$observation_unit_plot_polygon_types) {
467 if ($d->{$image_type_term}) {
468 $drone_run_band_table_html .= _draw_drone_imagery_section($observation_unit_plot_polygon_type_names, $d, $d->{$image_type_term."_id"}, $d->{$image_type_term."_username"}, $d->{$image_type_term."_modified_date"}, undef, $d->{$image_type_term}, [$observation_unit_plot_polygon_type], $d->{stitched_image_id}, $d->{cropped_stitched_drone_imagery_id}, $d->{denoised_stitched_drone_imagery_id}, $v->{trial_id}, uri_encode($d->{stitched_image_original}), $drone_run_band_project_id, $d->{drone_run_band_project_type}, $k, $d->{$image_type_term.'_id'}, $v->{drone_run_project_name});
469 } else {
470 # $drone_run_band_table_html .= '<button class="btn btn-default btn-sm disabled">Imagery of type '.$image_type_term.' and subsequently plot polygons of type '.$observation_unit_plot_polygon_type.' are not found. The standard process should have covered all supported image cases. Please try again or contact us.</button><br/><br/>';
476 elsif ($d->{drone_run_band_project_type} eq 'Merged 3 Bands NReN') {
477 # $drone_run_band_table_html .= '<button class="btn btn-primary btn-sm" name="project_drone_imagery_3_band_nren_vegetative" data-denoised_stitched_image_id="'.$d->{denoised_stitched_drone_imagery_id}.'" data-field_trial_id="'.$v->{trial_id}.'" data-stitched_image="'.uri_encode($d->{stitched_image_original}).'" data-denoised_stitched_image="'.uri_encode($d->{denoised_stitched_drone_imagery_original}).'" data-drone_run_project_id="'.$k.'" data-drone_run_band_project_id="'.$drone_run_band_project_id.'" data-drone_run_band_project_type="'.$d->{drone_run_band_project_type}.'">Convert to Vegetative Index</button><br/><br/>';
479 foreach my $imagery_term (sort keys %{$vi_map_hash->{NDRE}}) {
480 while (my ($image_type_term, $observation_unit_plot_polygon_types) = each %{$vi_map_hash->{NDRE}->{$imagery_term}}) {
481 foreach my $observation_unit_plot_polygon_type (@$observation_unit_plot_polygon_types) {
482 if ($d->{$image_type_term}) {
483 $drone_run_band_table_html .= _draw_drone_imagery_section($observation_unit_plot_polygon_type_names, $d, $d->{$image_type_term."_id"}, $d->{$image_type_term."_username"}, $d->{$image_type_term."_modified_date"}, undef, $d->{$image_type_term}, [$observation_unit_plot_polygon_type], $d->{stitched_image_id}, $d->{cropped_stitched_drone_imagery_id}, $d->{denoised_stitched_drone_imagery_id}, $v->{trial_id}, uri_encode($d->{stitched_image_original}), $drone_run_band_project_id, $d->{drone_run_band_project_type}, $k, $d->{$image_type_term.'_id'}, $v->{drone_run_project_name});
484 } else {
485 # $drone_run_band_table_html .= '<button class="btn btn-default btn-sm disabled">Imagery of type '.$image_type_term.' and subsequently plot polygons of type '.$observation_unit_plot_polygon_type.' are not found. The standard process should have covered all supported image cases. Please try again or contact us.</button><br/><br/>';
492 if ($d->{drone_run_band_project_type} eq 'RGB Color Image' || $d->{drone_run_band_project_type} eq 'Merged 3 Bands BGR') {
493 foreach my $imagery_term (sort keys %{$vi_map_hash->{TGI}}) {
494 while (my ($image_type_term, $observation_unit_plot_polygon_types) = each %{$vi_map_hash->{TGI}->{$imagery_term}}) {
495 foreach my $observation_unit_plot_polygon_type (@$observation_unit_plot_polygon_types) {
496 if ($d->{$image_type_term}) {
497 $drone_run_band_table_html .= _draw_drone_imagery_section($observation_unit_plot_polygon_type_names, $d, $d->{$image_type_term."_id"}, $d->{$image_type_term."_username"}, $d->{$image_type_term."_modified_date"}, undef, $d->{$image_type_term}, [$observation_unit_plot_polygon_type], $d->{stitched_image_id}, $d->{cropped_stitched_drone_imagery_id}, $d->{denoised_stitched_drone_imagery_id}, $v->{trial_id}, uri_encode($d->{stitched_image_original}), $drone_run_band_project_id, $d->{drone_run_band_project_type}, $k, $d->{$image_type_term.'_id'}, $v->{drone_run_project_name});
498 } else {
499 # $drone_run_band_table_html .= '<button class="btn btn-default btn-sm disabled">Imagery of type '.$image_type_term.' and subsequently plot polygons of type '.$observation_unit_plot_polygon_type.' are not found. The standard process should have covered all supported image cases. Please try again or contact us.</button><br/><br/>';
504 foreach my $imagery_term (sort keys %{$vi_map_hash->{VARI}}) {
505 while (my ($image_type_term, $observation_unit_plot_polygon_types) = each %{$vi_map_hash->{VARI}->{$imagery_term}}) {
506 foreach my $observation_unit_plot_polygon_type (@$observation_unit_plot_polygon_types) {
507 if ($d->{$image_type_term}) {
508 $drone_run_band_table_html .= _draw_drone_imagery_section($observation_unit_plot_polygon_type_names, $d, $d->{$image_type_term."_id"}, $d->{$image_type_term."_username"}, $d->{$image_type_term."_modified_date"}, undef, $d->{$image_type_term}, [$observation_unit_plot_polygon_type], $d->{stitched_image_id}, $d->{cropped_stitched_drone_imagery_id}, $d->{denoised_stitched_drone_imagery_id}, $v->{trial_id}, uri_encode($d->{stitched_image_original}), $drone_run_band_project_id, $d->{drone_run_band_project_type}, $k, $d->{$image_type_term.'_id'}, $v->{drone_run_project_name});
509 } else {
510 # $drone_run_band_table_html .= '<button class="btn btn-default btn-sm disabled">Imagery of type '.$image_type_term.' and subsequently plot polygons of type '.$observation_unit_plot_polygon_type.' are not found. The standard process should have covered all supported image cases. Please contact try again or us.</button><br/><br/>';
516 } else {
517 $drone_run_band_table_html .= '<button class="btn btn-default btn-sm disabled">Vegetative index cannot be calculated on an image with a single channel.<br/>You can merge bands into a multi-channel image using the "Merge Drone Run Bands" button below this table.<br/>If the standard process was run and vegetative indices were selected, merged images should appear at the bottom of this table.</button><br/><br/>';
519 } else {
520 #$drone_run_band_table_html .= '<button class="btn btn-primary btn-sm" name="project_drone_imagery_denoise" data-cropped_stitched_image_id="'.$d->{cropped_stitched_drone_imagery_id}.'" data-field_trial_id="'.$v->{trial_id}.'" data-stitched_image="'.uri_encode($d->{stitched_image_original}).'" data-cropped_stitched_image="'.uri_encode($d->{cropped_stitched_drone_imagery_original}).'" data-drone_run_project_id="'.$k.'" data-drone_run_band_project_id="'.$drone_run_band_project_id.'" >Denoise</button><br/><br/>';
521 $drone_run_band_table_html .= '<button class="btn btn-default btn-sm disabled">Denoised imagery not found. The standard process should have covered all supported image cases. Please try again or contact us.</button><br/><br/>';
523 } else {
524 #$drone_run_band_table_html .= '<button class="btn btn-primary btn-sm" name="project_drone_imagery_crop_image" data-rotated_stitched_image_id="'.$d->{rotated_stitched_drone_imagery_id}.'" data-stitched_image_id="'.$d->{stitched_image_id}.'" data-field_trial_id="'.$v->{trial_id}.'" data-stitched_image="'.uri_encode($d->{stitched_image_original}).'" data-drone_run_project_id="'.$k.'" data-drone_run_band_project_id="'.$drone_run_band_project_id.'" >Crop Rotated Image</button><br/><br/>';
525 $drone_run_band_table_html .= '<button class="btn btn-default btn-sm disabled">Cropped imagery not found. The standard process should have covered all supported image cases. Please try again or contact us.</button><br/><br/>';
527 } else {
528 #$drone_run_band_table_html .= '<button class="btn btn-primary btn-sm" name="project_drone_imagery_rotate_image" data-stitched_image_id="'.$d->{stitched_image_id}.'" data-field_trial_id="'.$v->{trial_id}.'" data-stitched_image="'.uri_encode($d->{stitched_image_original}).'" data-drone_run_project_id="'.$k.'" data-drone_run_band_project_id="'.$drone_run_band_project_id.'" >Rotate Stitched Image</button><br/><br/>';
529 $drone_run_band_table_html .= '<button class="btn btn-default btn-sm disabled">Rotated imagery not found. The standard process should have covered all supported image cases. Please try again or contact us.</button><br/><br/>';
531 } else {
532 # $drone_run_band_table_html .= '<button class="btn btn-default btn-sm disabled">Please upload previously stitched imagery. We do not support unstitched imagery at this time. Please try again or contact us.</button><br/><br/>';
538 push @return, [$drone_run_band_table_html];
541 $c->stash->{rest} = { data => \@return };
544 sub _draw_drone_imagery_section {
545 my $observation_unit_plot_polygon_type_names = shift;
546 my $d = shift;
547 my $imagery_id = shift;
548 my $imagery_username = shift;
549 my $imagery_modified_date = shift;
550 my $threshold_value = shift;
551 my $imagery = shift;
552 my $plot_polygon_terms = shift;
553 my $stitched_image_id = shift;
554 my $cropped_stitched_drone_imagery_id = shift;
555 my $denoised_stitched_drone_imagery_id = shift;
556 my $trial_id = shift;
557 my $stitched_image_original_uri_encoded = shift;
558 my $drone_run_band_project_id = shift;
559 my $drone_run_band_project_type = shift;
560 my $drone_run_project_id = shift;
561 my $plot_polygon_background_to_use_image_id = shift;
562 my $drone_run_project_name = shift;
564 my $html .= '<div class="well well-sm"><h5>'.$observation_unit_plot_polygon_type_names->{$plot_polygon_terms->[0]}.'&nbsp;&nbsp;&nbsp;&nbsp;<span class="glyphicon glyphicon-remove-sign text-danger" name="drone_image_remove" data-image_id="'.$imagery_id.'"></span></h5><div class="row"><div class="col-sm-3"><b>By</b>: '.$imagery_username.'</br><b>Date</b>: '.$imagery_modified_date;
565 if ($threshold_value) {
566 $html .= '<br/><b>Threshold Value</b>: '.$threshold_value;
568 $html .= '<hr>'.$imagery.'</div><div class="col-sm-9">';
570 foreach my $plot_polygon_term (@$plot_polygon_terms) {
571 $html .= _draw_plot_polygon_images_panel($d, $stitched_image_id, $cropped_stitched_drone_imagery_id, $denoised_stitched_drone_imagery_id, $trial_id, $stitched_image_original_uri_encoded, $drone_run_band_project_id, $plot_polygon_term, $drone_run_band_project_type, $drone_run_project_id, $plot_polygon_background_to_use_image_id, $drone_run_project_name);
574 $html .= '</div></div></div>';
575 return $html;
578 sub _draw_plot_polygon_images_panel {
579 my $d = shift;
580 my $stitched_image_id = shift;
581 my $cropped_stitched_drone_imagery_id = shift;
582 my $denoised_stitched_drone_imagery_id = shift;
583 my $trial_id = shift;
584 my $stitched_image_original_uri_encoded = shift;
585 my $drone_run_band_project_id = shift;
586 my $plot_polygon_term = shift;
587 my $drone_run_band_project_type = shift;
588 my $drone_run_project_id = shift;
589 my $plot_polygon_background_to_use_image_id = shift;
590 my $drone_run_project_name = shift;
592 my $html .= '<div class="panel panel-default panel-sm"><div class="panel-body" style="overflow-x:auto">';
593 $html .= '<button class="btn btn-default btn-sm" name="project_drone_imagery_plot_polygons" data-stitched_image_id="'.$stitched_image_id.'" data-cropped_stitched_image_id="'.$cropped_stitched_drone_imagery_id.'" data-denoised_stitched_image_id="'.$denoised_stitched_drone_imagery_id.'" data-field_trial_id="'.$trial_id.'" data-stitched_image="'.$stitched_image_original_uri_encoded.'" data-drone_run_project_id="'.$drone_run_project_id.'" data-drone_run_band_project_id="'.$drone_run_band_project_id.'" data-background_removed_stitched_image_id="'.$plot_polygon_background_to_use_image_id.'" data-assign_plot_polygons_type="'.$plot_polygon_term.'" data-drone_run_project_name="'.$drone_run_project_name.'" >Create/View Plot Polygons</button><br/><br/>';
595 my $plot_polygon_images = '';
596 if ($d->{$plot_polygon_term."_images"}) {
597 $plot_polygon_images = scalar(@{$d->{$plot_polygon_term."_images"}})." Plot Polygons<br/><span>";
598 $plot_polygon_images .= join '', @{$d->{$plot_polygon_term."_images"}};
599 $plot_polygon_images .= "</span>";
600 # $html .= '<button class="btn btn-primary btn-sm" name="project_drone_imagery_get_phenotypes" data-field_trial_id="'.$trial_id.'" data-drone_run_project_id="'.$drone_run_project_id.'" data-drone_run_band_project_id="'.$drone_run_band_project_id.'" data-drone_run_band_project_type="'.$drone_run_band_project_type.'" data-plot_polygons_type="'.$plot_polygon_term.'" >Calculate Phenotypes</button><br/><br/>';
601 } else {
602 $plot_polygon_images = 'No Plot Polygons Assigned';
604 $html .= $plot_polygon_images;
605 $html .= '</div></div>';
606 return $html;