diff --git a/db/00187/AddBreederRole.pm b/db/00187/AddBreederRole.pm new file mode 100644 index 0000000000..deb8ffe6d4 --- /dev/null +++ b/db/00187/AddBreederRole.pm @@ -0,0 +1,77 @@ +#!/usr/bin/env perl + + +=head1 NAME + +AddBreederRole + +=head1 SYNOPSIS + +mx-run AddBreederRole [options] -H hostname -D dbname -u username [-F] + +this is a subclass of L +see the perldoc of parent class for more details. + +=head1 DESCRIPTION + +This patch adds vendor role on sgn_people.sp_roles + +This subclass uses L. The parent class uses L + +=head1 AUTHOR + + Chris Simoes < ccs263@cornell.edu > + +=head1 COPYRIGHT & LICENSE + +Copyright 2010 Boyce Thompson Institute for Plant Research + +This program is free software; you can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut + + +package AddBreederRole; + +use Moose; + +extends 'CXGN::Metadata::Dbpatch'; + + +has '+description' => ( default => <<'' ); +This patch adds vendor role on sgn_people.sp_roles + +has '+prereq' => ( + default => sub { + [], + }, + ); + +sub patch { + my $self=shift; + + print STDOUT "Executing the patch:\n " . $self->name . ".\n\nDescription:\n ". $self->description . ".\n\nExecuted by:\n " . $self->username . " ."; + + print STDOUT "\nChecking if this db_patch was executed before or if previous db_patches have been executed.\n"; + + print STDOUT "\nExecuting the SQL commands.\n"; + + + + $self->dbh->do(< +see the perldoc of parent class for more details. + +=head1 DESCRIPTION +This patch adds phenotype_property cvterm for storing a suppressed plot phenotype. +This subclass uses L. The parent class uses L + +=head1 AUTHOR + +Chris Simoes + +=head1 COPYRIGHT & LICENSE + +Copyright 2010 Boyce Thompson Institute for Plant Research + +This program is free software; you can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut + + +package AddValidatePhenotypeCvterm; + +use Moose; +use Bio::Chado::Schema; +use Try::Tiny; +extends 'CXGN::Metadata::Dbpatch'; + + +has '+description' => ( default => <<'' ); +This patch adds phenotype_property cvterm for storing a suppressed plot phenotype. + +has '+prereq' => ( + default => sub { + [], + }, + + ); + +sub patch { + my $self=shift; + + print STDOUT "Executing the patch:\n " . $self->name . ".\n\nDescription:\n ". $self->description . ".\n\nExecuted by:\n " . $self->username . " ."; + + print STDOUT "\nChecking if this db_patch was executed before or if previous db_patches have been executed.\n"; + + print STDOUT "\nExecuting the SQL commands.\n"; + my $schema = Bio::Chado::Schema->connect( sub { $self->dbh->clone } ); + + + print STDERR "INSERTING CV TERMS...\n"; + + my $terms = { + 'project_property' => [ + 'validated_phenotype', + ] + }; + + foreach my $t (keys %$terms){ + foreach (@{$terms->{$t}}){ + $schema->resultset("Cv::Cvterm")->create_with({ + name => $_, + cv => $t + }); + } + } + + +print "You're done!\n"; +} + + +#### +1; # +#### diff --git a/js/source/entries/mixedmodels.js b/js/source/entries/mixedmodels.js index 7eec211a6c..cb683f3c57 100644 --- a/js/source/entries/mixedmodels.js +++ b/js/source/entries/mixedmodels.js @@ -103,10 +103,12 @@ export function init(main_div) { $('#mixed_model_analysis_prepare_button').click(function () { dataset_id = get_dataset_id(); + var dataset_trait_outliers = $('#dataset_trait_outliers').is(':checked') ? 1 : 0; + if (dataset_id != false) { $.ajax({ url: '/ajax/mixedmodels/prepare', - data: { 'dataset_id': get_dataset_id() }, + data: { 'dataset_id': get_dataset_id(),'dataset_trait_outliers': dataset_trait_outliers, }, success: function (r) { if (r.error) { alert(r.error); diff --git a/js/source/entries/qualitycontrol.js b/js/source/entries/qualitycontrol.js new file mode 100755 index 0000000000..802f565015 --- /dev/null +++ b/js/source/entries/qualitycontrol.js @@ -0,0 +1,690 @@ +import '../legacy/jquery.js'; +import '../legacy/d3/d3v4Min.js'; + +var version = '0.01'; + +export function init(main_div) { + if (!(main_div instanceof HTMLElement)) { + main_div = document.getElementById(main_div.startsWith("#") ? main_div.slice(1) : main_div); + } + + var dataset_id; + get_select_box("datasets", "qc_dataset_select", { "checkbox_name": "qc_dataset_select_checkbox" }); + + jQuery('#qc_analysis_prepare_button').removeClass('active').addClass('inactive'); + + $(document).on('click', 'input[name=select_engine]', function (e) { + get_model_string(); + }); + + let outliers = []; + var trait_selected; + var tempfile; + let allData = []; + var all_traits; + + $('#qc_analysis_prepare_button').click(function () { + dataset_id = get_dataset_id(); + if (dataset_id != false) { + $.ajax({ + url: '/ajax/qualitycontrol/prepare', + data: { 'dataset_id': get_dataset_id() }, + success: function (r) { + if (r.error) { + alert(r.error); + } else { + + if (r.tempfile) { + $('#tempfile').html(r.tempfile); + } + updateBoxplot(); + } + }, + error: function (jqXHR, textStatus, errorThrown) { + console.error('AJAX request failed: ', textStatus, errorThrown); + alert('Error in AJAX request: ' + errorThrown); + } + }); + } + }); + $(function() { + var handle = $("#custom-handle"); + $("#outliers_range").slider({ + orientation: "horizontal", + range: "min", + max: 10, + min: 0, + value: 1.5, + step: 0.1, + create: function() { + handle.text($(this).slider("value")); + }, + slide: function(event, ui) { + handle.text(ui.value); + isFixedMinMax = false; + updateBoxplot(isFixedMinMax, minVal, maxVal); // Update the boxplot when the slider value changes + } + }); + }); + + $('#qc_analysis_prepare_button').click(function () { + dataset_id = get_dataset_id(); + if (dataset_id != false) { + $.ajax({ + url: '/ajax/qualitycontrol/prepare', + data: { 'dataset_id': dataset_id }, // No need to call get_dataset_id() again + success: function (r) { + if (r.error) { + alert(r.error); + } else { + if (r.selected_variable) { + populateTraitDropdown(r.selected_variable); // Populate dropdown with traits + all_traits = r.selected_variable; + } + if (r.tempfile) { + $('#tempfile').html(r.tempfile); + } + } + }, + error: function (jqXHR, textStatus, errorThrown) { + alert('Error in AJAX request: ' + errorThrown); + } + }); + } + }); + + let isFixedMinMax = false; + let minVal; + let maxVal; + + $('#selected_variable').on('change', function () { + trait_selected = $('#trait_select').val(); // Get the selected trait from the dropdown + + if (!trait_selected) { + $('#trait_boxplot').html('Please select a trait to see the boxplot!'); + return; + } + + // Fetch tempfile value + tempfile = $('#tempfile').html(); + + // Check if tempfile is not empty + if (!tempfile || tempfile.trim() === '') { + return; // Exit if tempfile is empty + } + + var outlierMultiplier = $('#outliers_range').slider("value"); + if (!outlierMultiplier || isNaN(outlierMultiplier)) { + outlierMultiplier = 1.5; } + + $.ajax({ + url: '/ajax/qualitycontrol/grabdata', + data: { 'file': tempfile, 'trait': trait_selected }, + success: function (r) { + $('#working_modal').modal("hide"); + if (r.message) { + alert(r.message); + return; + } else { + const result = drawBoxplot(r.data, trait_selected, outlierMultiplier, isFixedMinMax, minVal, maxVal ); + outliers = result.outliers; // Extract the outliers + allData = r.data; + populateOutlierTable(r.data, trait_selected); + populateCleanTable(r.data, outliers, trait_selected); + } + + }, + error: function (e) { + alert('Error during AJAX request!'); + } + }); + + }); + + $("#fixed-min-max").click(function() { + isFixedMinMax = true; + + let dataset_id = get_dataset_id(); + minVal = parseFloat(document.getElementById("min-limit").value); + maxVal = parseFloat(document.getElementById("max-limit").value); + + if (dataset_id) { + $.ajax({ + url: '/ajax/qualitycontrol/prepare', + data: { 'dataset_id': dataset_id }, + success: function (r) { + if (r.error) { + alert(r.error); + } else { + if (r.selected_variable) { + updateBoxplot(isFixedMinMax, minVal, maxVal); + } + if (r.tempfile) { + $('#tempfile').html(r.tempfile); + } + } + }, + error: function (jqXHR, textStatus, errorThrown) { + alert('Error in AJAX request: ' + errorThrown); + } + }); + } + }); + + const checkedTraits = []; + $('#select_traits_button').on('click', function () { + populateOtherTraits(all_traits, trait_selected); + $(document).on('change', 'input[name="new_trait_options"]', function() { + $('input[name="new_trait_options"]:checked').each(function() { + checkedTraits.push($(this).val()); // Get the value of each checked checkbox + }); + }); + }); + + + $('#store_outliers_button').click(function () { + console.log("The other is:", checkedTraits); + $.ajax({ + url: '/ajax/qualitycontrol/storeoutliers', + method: "POST", + data: {"outliers": JSON.stringify(outliers), "othertraits": JSON.stringify(checkedTraits) + }, + success: function(response) { + if(response.is_curator === 1) { + $('#store_outliers_button').prop("disabled", false); + alert('Outliers successfully stored!'); + } else { + $('#store_outliers_button').prop("disabled", true); + alert("Only curators or breeders are allowed to validated trials. Please contact a curator.", response.is_curator); + } + + + }, + error: function(xhr, status, error) { + alert('Error saving outliers: ' + error); + console.log(xhr, status); + } + }); + }); + + $('#restore_outliers_button').click(function () { + $.ajax({ + url: '/ajax/qualitycontrol/datarestore', + data: { 'file': tempfile, 'trait': trait_selected }, + success: function (r) { + $('#working_modal').modal("hide"); + if (r.message) { + alert(r.message); + return; + } else { + var trialNames = r.data; + $.ajax({ + url: '/ajax/qualitycontrol/restoreoutliers', + method: "POST", + data: {"outliers": JSON.stringify(trialNames), "trait":trait_selected, + }, + success: function (r) { + if (r.is_curator === 1) { + $('#restore_outliers_button').prop("disabled", false); + alert("Data successfully restored!"); + } else { + $('#restore_outliers_button').prop("disabled", true); + alert("Only curators are allowed undo validated trial. Please contact a curator."); + } + }, + error: function () { + alert('Error during restore!'); + } + }); + } + }, + error: function () { + alert('Error during AJAX request!'); + } + }); + }); + +} + +function populateOtherTraits(traitsHTML, traitSelected) { + const $traitContainer = $('#other_traits'); + $traitContainer.empty(); + + const $traits = $(traitsHTML); // Parse the HTML into jQuery elements + const traitsArray = $traits.map(function() { + return $(this).val(); // Get the value of each trait input element + }).get(); // Convert jQuery object to a regular array + + const filteredTraits = traitsArray.filter(trait => !traitSelected.includes(trait)); + + filteredTraits.forEach(trait => { + const $checkbox = $('', { + type: 'checkbox', + name: 'new_trait_options', + value: trait + }); + + const $label = $('