diff --git a/js/source/modules/wizard-downloads.js b/js/source/modules/wizard-downloads.js index 37a8c55561..ca7cb5af53 100644 --- a/js/source/modules/wizard-downloads.js +++ b/js/source/modules/wizard-downloads.js @@ -196,6 +196,7 @@ export function WizardDownloads(main_id,wizard){ var entry_numbers = d3.selectAll('.wizard-download-phenotypes-entry-numbers').property('checked')?1:0; var trait_synonyms = d3.selectAll('.wizard-download-phenotypes-trait-synonyms').property('checked')?1:0; var intercrop = d3.selectAll('.wizard-download-phenotypes-intercrop').property('checked')?1:0; + var pedigree_parents = d3.selectAll('.wizard-download-phenotypes-pedigree_parents').property('checked')?1:0; var outliers = d3.selectAll('.wizard-download-phenotypes-outliers').property('checked')?1:0; var names = JSON.stringify(d3.select(".wizard-download-phenotypes-name").node().value.split(",")); var min = d3.select(".wizard-download-phenotypes-min").node().value; @@ -206,7 +207,7 @@ export function WizardDownloads(main_id,wizard){ //alert('start date = '+phenotype_start_date); //alert('repetitive type = '+repetitive_measurements); - + var url = document.location.origin+'/breeders/trials/phenotype/download'; openWindowWithPost(url, { trial_list: trial_ids, @@ -229,7 +230,7 @@ export function WizardDownloads(main_id,wizard){ trait_contains: names, include_row_and_column_numbers: 1, exclude_phenotype_outlier: outliers, - include_pedigree_parents: 0, + include_pedigree_parents: pedigree_parents, repetitive_measurements: repetitive_measurements, phenotype_start_date: phenotype_start_date, phenotype_end_date: phenotype_end_date @@ -244,7 +245,7 @@ export function WizardDownloads(main_id,wizard){ var years = categories.indexOf("years")!=-1 ? selections["years"] : []; var tissue_samples = categories.indexOf("tissue_sample")!=-1 ? selections["tissue_sample"] : []; var protocols = categories.indexOf("protocols")!=-1 ? selections["protocols"] : []; - var instances = categories.indexOf("instances")!=-1 ? selections["instances"] : []; + var instances = categories.indexOf("instances")!=-1 ? selections["instances"] : []; main.selectAll(".wizard-download-high-dim-phenotypes-info") .attr("value",`${trials.length||"Too few"} trials`); @@ -279,7 +280,7 @@ export function WizardDownloads(main_id,wizard){ //alert('start date = '+phenotype_start_date); //alert('repetitive type = '+repetitive_measurements); - + var url = document.location.origin+'/breeders/trials/phenotype/download'; openWindowWithPost(url, { trial_list: trial_ids, @@ -302,7 +303,7 @@ export function WizardDownloads(main_id,wizard){ intercrop: intercrop, include_row_and_column_numbers: 1, //exclude_phenotype_outlier: outliers, - include_pedigree_parents: 0, + include_pedigree_parents: pedigree_parents, //repetitive_measurements: repetitive_measurements, phenotype_start_date: phenotype_start_date, phenotype_end_date: phenotype_end_date diff --git a/lib/CXGN/Phenotypes/PhenotypeMatrix.pm b/lib/CXGN/Phenotypes/PhenotypeMatrix.pm index a20e0ecf07..d83a82691b 100644 --- a/lib/CXGN/Phenotypes/PhenotypeMatrix.pm +++ b/lib/CXGN/Phenotypes/PhenotypeMatrix.pm @@ -244,7 +244,6 @@ sub get_phenotype_matrix { my $include_entry_numbers = $self->include_entry_numbers; my $include_trait_synonyms = $self->include_trait_synonyms; my %trial_entry_numbers; - $self->trait_repeat_types( $self->retrieve_trait_repeat_types() ); print STDERR "GET PHENOMATRIX ".$self->search_type."\n"; @@ -274,6 +273,7 @@ sub get_phenotype_matrix { end_date => $self->end_date(), include_dateless_items => $self->include_dateless_items(), include_intercrop_stocks => $include_intercrop_stocks, + include_pedigree_parents => $include_pedigree_parents, limit=>$self->limit, offset=>$self->offset } @@ -435,7 +435,7 @@ sub get_phenotype_matrix { else { ### NATIVE ??!! $data = $phenotypes_search->search(); - #print STDERR "the download data structure =". Dumper($data)."\n"; +# print STDERR "the download data structure =". Dumper($data)."\n"; my %obsunit_data; my %traits; @@ -445,6 +445,10 @@ sub get_phenotype_matrix { my @unique_obsunit_list = (); my %seen_obsunits; + if ($include_pedigree_parents){ + push @metadata_headers, ('germplasmPedigreeFemaleParentName', 'germplasmPedigreeFemaleParentDbId', 'germplasmPedigreeMaleParentName', 'germplasmPedigreeMaleParentDbId'); + } + # Add intercrop stock headers, if requested if ( $include_intercrop_stocks ) { push(@metadata_headers, 'intercropGermplasmDbId', 'intercropGermplasmName'); @@ -535,6 +539,10 @@ sub get_phenotype_matrix { $d->{plant_number} ]; + if ($include_pedigree_parents) { + push(@{$obsunit_data{$obsunit_id}->{metadata}}, ($d->{'female_parent_name'}, $d->{'female_parent_id'}, $d->{'male_parent_name'}, $d->{'male_parent_id'})); + } + # add intercrop stocks, if requested if ( $include_intercrop_stocks ) { my @ic_stock_ids; diff --git a/lib/CXGN/Phenotypes/Search/Native.pm b/lib/CXGN/Phenotypes/Search/Native.pm index 39328804e4..4b21990504 100644 --- a/lib/CXGN/Phenotypes/Search/Native.pm +++ b/lib/CXGN/Phenotypes/Search/Native.pm @@ -227,6 +227,8 @@ sub search { my $plant_of_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'plant_of', 'stock_relationship')->cvterm_id(); my $subplot_of_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'subplot_of', 'stock_relationship')->cvterm_id(); my $tissue_sample_of_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'tissue_sample_of', 'stock_relationship')->cvterm_id(); + my $female_parent_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'female_parent', 'stock_relationship')->cvterm_id(); + my $male_parent_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, 'male_parent', 'stock_relationship')->cvterm_id(); my $include_timestamp = $self->include_timestamp; my $numeric_regex = '^-?[0-9]+([,.][0-9]+)?$'; @@ -274,7 +276,7 @@ sub search { } } - + #For performace reasons it is faster to include specific stock_ids in the query. if ($self->data_level eq 'analysis_instance'){ if (!$self->plot_list){ @@ -346,7 +348,7 @@ sub search { LEFT JOIN stockprop AS is_a_control ON (observationunit.stock_id=is_a_control.stock_id AND is_a_control.type_id = $is_a_control_type_id) "; $design_layout_select = " ,rep.value, block_number.value, plot_number.value, is_a_control.value, row_number.value, col_number.value, plant_number.value"; } - + if ($self->exclude_phenotype_outlier) { $phenotypeprop_sql = "JOIN ( SELECT phenotype_id @@ -360,13 +362,17 @@ sub search { ON not_outliers.phenotype_id = nd_experiment_phenotype.phenotype_id" }; - my $from_clause = " FROM stock as observationunit + my $from_clause = " FROM stock as observationunit LEFT JOIN stock_relationship ON (observationunit.stock_id=stock_relationship.subject_id) AND stock_relationship.type_id IN ($analysis_instance_of_type_id, $plot_of_type_id, $plant_of_type_id, $subplot_of_type_id, $tissue_sample_of_type_id) LEFT JOIN stock_relationship AS icsr ON (observationunit.stock_id=icsr.subject_id) AND icsr.type_id = $intercrop_plot_rel_type_id LEFT JOIN stock AS ics ON (icsr.object_id=ics.stock_id) LEFT JOIN cvterm as observationunit_type ON (observationunit_type.cvterm_id = observationunit.type_id) JOIN stock as germplasm ON (stock_relationship.object_id=germplasm.stock_id) AND germplasm.type_id IN ($accession_type_id, $analysis_result_type_id, $cross_type_id, $family_name_type_id) $design_layout_sql + LEFT JOIN stock_relationship AS female_relationship ON (germplasm.stock_id = female_relationship.object_id) AND female_relationship.type_id = $female_parent_type_id + LEFT JOIN stock AS female_parent ON (female_relationship.subject_id = female_parent.stock_id) + LEFT JOIN stock_relationship AS male_relationship ON (germplasm.stock_id = male_relationship.object_id) AND male_relationship.type_id = $male_parent_type_id + LEFT JOIN stock AS male_parent ON (male_relationship.subject_id = male_parent.stock_id) LEFT JOIN nd_experiment_stock ON(nd_experiment_stock.stock_id=observationunit.stock_id) LEFT JOIN nd_experiment_phenotype ON (nd_experiment_phenotype.nd_experiment_id=nd_experiment_stock.nd_experiment_id) LEFT JOIN phenotype USING(phenotype_id) @@ -395,80 +401,88 @@ sub search { LEFT JOIN project_relationship folder_rel ON (project.project_id = folder_rel.subject_project_id AND folder_rel.type_id = $folder_rel_type_id) LEFT JOIN project folder ON (folder.project_id = folder_rel.object_project_id)"; - my $select_clause = "SELECT observationunit.stock_id, - observationunit.uniquename, - observationunit_type.name, - germplasm.uniquename, - germplasm.stock_id, - project.project_id, - project.name, - project.description, - plot_width.value, - plot_length.value, - field_size.value, - field_trial_is_planned_to_be_genotyped.value, - field_trial_is_planned_to_cross.value, - breeding_program.project_id, - breeding_program.name, - breeding_program.description, - year.value, - design.value, - location.value, - planting_date.value, - harvest_date.value, - folder.project_id, - folder.name, - folder.description, - cvterm.cvterm_id, - (((cvterm.name::text || '|'::text) || db.name::text) || ':'::text) || dbxref.accession::text, + my $select_clause = "SELECT observationunit.stock_id, + observationunit.uniquename, + observationunit_type.name, + germplasm.uniquename, + germplasm.stock_id, + project.project_id, + project.name, + project.description, + plot_width.value, + plot_length.value, + field_size.value, + field_trial_is_planned_to_be_genotyped.value, + field_trial_is_planned_to_cross.value, + breeding_program.project_id, + breeding_program.name, + breeding_program.description, + year.value, + design.value, + location.value, + planting_date.value, + harvest_date.value, + folder.project_id, + folder.name, + folder.description, + cvterm.cvterm_id, + (((cvterm.name::text || '|'::text) || db.name::text) || ':'::text) || dbxref.accession::text, MIN(cvtermsynonym.synonym), - phenotype.value, - phenotype.uniquename, - phenotype.phenotype_id, - phenotype.collect_date, - phenotype.operator, - additional_info.value, - external_references.value, - count(phenotype.phenotype_id) OVER() AS full_count, + phenotype.value, + phenotype.uniquename, + phenotype.phenotype_id, + phenotype.collect_date, + phenotype.operator, + additional_info.value, + female_parent.uniquename, + female_parent.stock_id, + male_parent.uniquename, + male_parent.stock_id, + external_references.value, + count(phenotype.phenotype_id) OVER() AS full_count, string_agg(distinct(notes.value), ', ') AS notes, - STRING_AGG(DISTINCT(ics.stock_id)::text, '|'), + STRING_AGG(DISTINCT(ics.stock_id)::text, '|'), STRING_AGG(DISTINCT(ics.uniquename), ',') ".$design_layout_select; my $order_clause = " ORDER BY 6, 2, 30"; - my $group_by = " GROUP BY observationunit.stock_id, - observationunit.uniquename, - observationunit_type.name, - germplasm.uniquename, - germplasm.stock_id, - project.project_id, - project.name, + my $group_by = " GROUP BY observationunit.stock_id, + observationunit.uniquename, + observationunit_type.name, + germplasm.uniquename, + germplasm.stock_id, + project.project_id, + project.name, project.description, - plot_width.value, - plot_length.value, - field_size.value, - field_trial_is_planned_to_be_genotyped.value, - field_trial_is_planned_to_cross.value, - breeding_program.project_id, - breeding_program.name, - breeding_program.description, - year.value, - design.value, - location.value, - planting_date.value, - harvest_date.value, - folder.project_id, - folder.name, - folder.description, - cvterm.cvterm_id, - (((cvterm.name::text || '|'::text) || db.name::text) || ':'::text) || dbxref.accession::text, - phenotype.value, - phenotype.uniquename, - phenotype.phenotype_id, - phenotype.collect_date, - phenotype.operator, - additional_info.value, + plot_width.value, + plot_length.value, + field_size.value, + field_trial_is_planned_to_be_genotyped.value, + field_trial_is_planned_to_cross.value, + breeding_program.project_id, + breeding_program.name, + breeding_program.description, + year.value, + design.value, + location.value, + planting_date.value, + harvest_date.value, + folder.project_id, + folder.name, + folder.description, + cvterm.cvterm_id, + (((cvterm.name::text || '|'::text) || db.name::text) || ':'::text) || dbxref.accession::text, + phenotype.value, + phenotype.uniquename, + phenotype.phenotype_id, + phenotype.collect_date, + phenotype.operator, + additional_info.value, + female_parent.uniquename, + female_parent.stock_id, + male_parent.uniquename, + male_parent.stock_id, external_references.value ".$design_layout_select; my @where_clause; @@ -476,7 +490,7 @@ sub search { print STDERR "Native search Accession list is ".Dumper($accession_list)."\n"; my $analysis_result_stock_list = $self->analysis_result_stock_list; - + if ($self->analysis_result_stock_list && scalar(@{$self->analysis_result_stock_list})>0) { print STDERR "Native search adding analysis result_stock_list to sql\n"; my $accession_sql = _sql_from_arrayref($self->analysis_result_stock_list); @@ -607,10 +621,10 @@ sub search { my $stock_type_id = SGN::Model::Cvterm->get_cvterm_row($schema, $data_level, 'stock_type')->cvterm_id(); push @where_clause, "observationunit.type_id = $stock_type_id"; #ONLY plot or plant or subplot or tissue_sample } else { - push @where_clause, "(observationunit.type_id = $plot_type_id + push @where_clause, "(observationunit.type_id = $plot_type_id OR observationunit.type_id = $plant_type_id - OR observationunit.type_id = $analysis_instance_id - OR observationunit.type_id = $subplot_type_id + OR observationunit.type_id = $analysis_instance_id + OR observationunit.type_id = $subplot_type_id OR observationunit.type_id = $tissue_sample_type_id)"; #plots AND plants AND subplots AND tissue_samples } @@ -638,7 +652,7 @@ sub search { my $calendar_funcs = CXGN::Calendar->new({}); - while (my ($observationunit_stock_id, $observationunit_uniquename, $observationunit_type_name, $germplasm_uniquename, $germplasm_stock_id, $project_project_id, $project_name, $project_description, $plot_width, $plot_length, $field_size, $field_trial_is_planned_to_be_genotyped, $field_trial_is_planned_to_cross, $breeding_program_project_id, $breeding_program_name, $breeding_program_description, $year, $design, $location_id, $planting_date, $harvest_date, $folder_id, $folder_name, $folder_description, $trait_id, $trait_name, $trait_synonym, $phenotype_value, $phenotype_uniquename, $phenotype_id, $phenotype_collect_date, $phenotype_operator, $phenotype_additional_info, $phenotype_external_references, $full_count, $notes, $intercrop_stock_id, $intercrop_stock_name, $rep_select, $block_number_select, $plot_number_select, $is_a_control_select, $row_number_select, $col_number_select, $plant_number) = $h->fetchrow_array()) { + while (my ($observationunit_stock_id, $observationunit_uniquename, $observationunit_type_name, $germplasm_uniquename, $germplasm_stock_id, $project_project_id, $project_name, $project_description, $plot_width, $plot_length, $field_size, $field_trial_is_planned_to_be_genotyped, $field_trial_is_planned_to_cross, $breeding_program_project_id, $breeding_program_name, $breeding_program_description, $year, $design, $location_id, $planting_date, $harvest_date, $folder_id, $folder_name, $folder_description, $trait_id, $trait_name, $trait_synonym, $phenotype_value, $phenotype_uniquename, $phenotype_id, $phenotype_collect_date, $phenotype_operator, $phenotype_additional_info, $female_parent_name, $female_parent_id, $male_parent_name, $male_parent_id, $phenotype_external_references, $full_count, $notes, $intercrop_stock_id, $intercrop_stock_name, $rep_select, $block_number_select, $plot_number_select, $is_a_control_select, $row_number_select, $col_number_select, $plant_number) = $h->fetchrow_array()) { my $timestamp_value; my $operator_value; if ($include_timestamp) { @@ -712,6 +726,10 @@ sub search { obsunit_type_name => $observationunit_type_name, accession_uniquename => $germplasm_uniquename, accession_stock_id => $germplasm_stock_id, + female_parent_name => $female_parent_name, + female_parent_id => $female_parent_id, + male_parent_name => $male_parent_name, + male_parent_id => $male_parent_id, synonyms => $synonyms, trial_id => $project_project_id, trial_name => $project_name, diff --git a/lib/CXGN/Trial/Download/Plugin/TrialPhenotypeExcel.pm b/lib/CXGN/Trial/Download/Plugin/TrialPhenotypeExcel.pm index 22ae2ebcbc..43ec8408f5 100644 --- a/lib/CXGN/Trial/Download/Plugin/TrialPhenotypeExcel.pm +++ b/lib/CXGN/Trial/Download/Plugin/TrialPhenotypeExcel.pm @@ -100,11 +100,11 @@ sub download { my $phenotype_start_date = $self->start_date(); my $phenotype_end_date = $self->end_date(); my $repetitive_measurements = $self->repetitive_measurements(); - + my $include_pedigree_parents = $self->include_pedigree_parents(); $self->trial_download_log($trial_id, "trial phenotypes"); - + my @data; if ($self->data_level() eq 'metadata'){ my $metadata_search = CXGN::Phenotypes::MetaDataMatrix->new( @@ -137,7 +137,8 @@ sub download { include_trait_synonyms=>$include_trait_synonyms, phenotype_start_date => $phenotype_start_date, phenotype_end_date => $phenotype_end_date, - repetitive_measurements => $repetitive_measurements + repetitive_measurements => $repetitive_measurements, + include_pedigree_parents=>$include_pedigree_parents, ); @data = $phenotypes_search->get_phenotype_matrix(); } diff --git a/lib/SGN/Controller/BreedersToolbox/Download.pm b/lib/SGN/Controller/BreedersToolbox/Download.pm index dd33977fd1..f2afb0a0a7 100644 --- a/lib/SGN/Controller/BreedersToolbox/Download.pm +++ b/lib/SGN/Controller/BreedersToolbox/Download.pm @@ -249,7 +249,7 @@ sub download_phenotypes_action : Path('/breeders/trials/phenotype/download') Arg my $repetitive_measurements = $c->req->param("repetitive_measurements") || "average"; my $timestamp_option = $c->req->param("timestamp") && $c->req->param("timestamp") ne 'null' ? $c->req->param("timestamp") : 0; my $exclude_phenotype_outlier = $c->req->param("exclude_phenotype_outlier") && $c->req->param("exclude_phenotype_outlier") ne 'null' && $c->req->param("exclude_phenotype_outlier") ne 'undefined' ? $c->req->param("exclude_phenotype_outlier") : 0; - my $include_pedigree_parents = $c->req->param('include_pedigree_parents'); + my $include_pedigree_parents = $c->req->param("include_pedigree_parents") && $c->req->param("include_pedigree_parents") ne 'null' && $c->req->param("include_pedigree_parents") ne 'undefined' ? $c->req->param("include_pedigree_parents") : 0; my $include_intercrop_stocks = $c->req->param("intercrop") && $c->req->param("intercrop") ne 'null' && $c->req->param("intercrop") ne 'undefined' ? $c->req->param("intercrop") : 0; my $include_entry_numbers = $c->req->param("entry_numbers") && $c->req->param("entry_numbers") ne 'null' ? $c->req->param("entry_numbers") : 0; my $include_trait_synonyms = $c->req->param("trait_synonyms") && $c->req->param("trait_synonyms") ne 'null' ? $c->req->param("trait_synonyms") : 0; @@ -577,6 +577,7 @@ sub download_action : Path('/breeders/download_action') Args(0) { my $include_entry_numbers = $c->req->param("entry_numbers") || 0; my $include_trait_synonyms = $c->req->param("trait_synonyms") || 0; my $timestamp_included = $c->req->param("timestamp") || 0; + my $include_pedigree_parents = $c->req->param("pedigrees") || 0; # parameters for outliers download my @trait_ids = split(',', $c->req->param("trait_ids_list")); @@ -693,6 +694,7 @@ sub download_action : Path('/breeders/download_action') Args(0) { include_entry_numbers=>$include_entry_numbers, include_trait_synonyms=>$include_trait_synonyms, data_level=>$datalevel, + include_pedigree_parents=>$include_pedigree_parents, ); @data = $phenotypes_search->get_phenotype_matrix(); } diff --git a/mason/breeders_toolbox/breeder_search_page.mas b/mason/breeders_toolbox/breeder_search_page.mas index c2cfcb928d..083f6bb12f 100644 --- a/mason/breeders_toolbox/breeder_search_page.mas +++ b/mason/breeders_toolbox/breeder_search_page.mas @@ -10,6 +10,7 @@ $dataset_id => undef my $default_include_entry_numbers = $c->get_conf('pheno_download_default_include_entry_numbers'); my $default_include_trait_synonyms = $c->get_conf('pheno_download_default_include_trait_synonyms'); my $default_supress_outliers = $c->get_conf('exclude_phenotype_outliers'); + my $default_include_pedigree_parents = $c->get_conf('pheno_download_default_include_pedigree_parents'); %once> <& /util/import_javascript.mas, entries => ["wizard"] &> @@ -453,6 +454,16 @@ $dataset_id => undef +