2 * visualize and compare gebvs of a training population
3 * and a selection population (genetic gain).
4 * normal distribution plotting using d3.
5 * uses methods from solGS.normalDistribution and solGS.linePlot js libraries
7 * Isaak Y Tecle <iyt2@cornell.edu>
11 var solGS = solGS || function solGS() {};
15 ggPlotDivPrefix: "#gg_plot",
16 ggMsgDiv: "#gg_message",
17 ggPopsDiv: "#gg_pops_select_div",
18 ggPopsSelectMenuId: "#gg_pops_select",
20 gebvsComparison: function () {
21 var gebvParams = this.getGeneticGainArgs();
24 if (!gebvParams.training_pop_id) {
25 missing = "training population id";
28 if (!gebvParams.selection_pop_id) {
29 missing += ", selection population id";
32 if (!gebvParams.trait_id) {
33 missing += ", trait id";
36 var ggMsgDiv = this.ggMsgDiv;
39 .html("Can not compare GEBVs. I am missing " + missing + ".")
42 this.plotGeneticGainBoxplot(gebvParams);
46 getGeneticGainArgs: function () {
47 var canvas = this.canvas;
49 var trainingPopId = jQuery(`${canvas} #training_pop_id`).val();
50 var trainingPopName = jQuery(`${canvas} #training_pop_name`).val();
51 var selectionPopId = jQuery("#gg_selected_pop_id").val() || jQuery("#selection_pop_id").val();
52 var trainingTraitsIds = jQuery(canvas).find("#training_traits_ids").val();
53 var traitId = jQuery("#trait_id").val();
54 var protocolId = jQuery("#genotyping_protocol_id").val();
56 if (document.URL.match(/solgs\/traits\/all\/population\/|solgs\/models\/combined\/trials\//)) {
57 if (trainingTraitsIds) {
58 trainingTraitsIds = trainingTraitsIds.split(",");
63 training_pop_id: trainingPopId,
64 training_pop_name: trainingPopName,
65 selection_pop_id: selectionPopId,
66 training_traits_ids: trainingTraitsIds,
68 genotyping_protocol_id: protocolId,
74 plotGeneticGainBoxplot: function (ggArgs) {
75 var canvas = this.canvas;
76 var ggMsgDiv = this.ggMsgDiv;
79 ggArgs = JSON.stringify(ggArgs)
80 jQuery(` ${canvas} .multi-spinner-container`).show();
81 jQuery("#check_genetic_gain").hide();
82 jQuery(ggMsgDiv).html("Please wait... plotting genetic gain").show();
87 data: {'arguments': ggArgs},
88 url: "/solgs/genetic/gain/boxplot",
89 success: function (res) {
91 jQuery(`${canvas} .multi-spinner-container`).hide();
92 jQuery(ggMsgDiv).empty();
94 solGS.showMessage(ggMsgDiv, res.Error);
98 /\/solgs\/traits\/all\/population\/|solgs\/models\/combined\/trials\//
101 jQuery("#check_genetic_gain").show();
104 var boxplot = res.boxplot;
105 var boxplotData = res.boxplot_data;
106 var plot = '<img src= "' + boxplot + '">';
109 var fileNameBoxplot = boxplot.split("/").pop();
110 boxplotFile = '<a href="' + boxplot + '" download=' + fileNameBoxplot + ">boxplot</a>";
112 var fileNameData = boxplotData.split("/").pop();
113 var dataFile = '<a href="' + boxplotData + '" download=' + fileNameData + ">Data</a>";
116 '<div style="margin-top: 20px">' +
119 "<br /> <strong>Download:</strong> " +
126 jQuery(`${canvas} .multi-spinner-container`).hide();
127 jQuery("#gg_message").empty();
131 /\/solgs\/traits\/all\/population\/|solgs\/models\/combined\/trials\//
134 jQuery("#check_genetic_gain").show();
137 jQuery(`${canvas} .multi-spinner-container`).hide();
138 showMessage("There is no genetic gain plot for this dataset.");
139 jQuery("#check_genetic_gain").show();
143 error: function (res) {
144 jQuery(`${canvas} .multi-spinner-container`).hide();
145 solGS.showMessage(ggMsgDiv, "Error occured plotting the genetic gain.");
146 jQuery("#check_genetic_gain").show();
151 getTrainingPopulationGEBVs: function (gebvParams) {
152 var ggMsgDiv = this.ggMsgDiv;
157 url: "/solgs/get/gebvs/training/population",
158 success: function (res) {
159 if (res.gebv_exists) {
160 jQuery(ggMsgDiv).empty();
161 trainingGEBVs = res.gebv_arrayref;
164 solGS.geneticGain.getSelectionPopulationGEBVs(gebvParams);
167 jQuery(ggMsgDiv).html("There is no GEBV data for the training population.").show();
172 .html("Error occured checking for GEBV data for the training population.")
178 getSelectionPopulationGEBVs: function (gebvParams) {
179 var ggMsgDiv = this.ggMsgDiv;
185 url: "/solgs/get/gebvs/selection/population",
186 success: function (res) {
187 if (res.gebv_exists) {
188 jQuery(ggMsgDiv).empty();
190 selectionGEBVs = res.gebv_arrayref;
192 if (selectionGEBVs && trainingGEBVs) {
193 jQuery(ggMsgDiv).html("Please wait... plotting gebvs").show();
195 solGS.geneticGain.plotGEBVs(trainingGEBVs, selectionGEBVs);
197 jQuery(ggMsgDiv).empty();
198 jQuery("#check_genetic_gain").hide();
201 jQuery(ggMsgDiv).html("There is no GEBV data for the selection population.").show();
206 .html("Error occured checking for GEBV data for the selection population.")
212 populateGeneticGainMenu: function (newPop) {
213 var ggArgs = this.getGeneticGainArgs();
216 if (ggArgs.training_pop_id.match(/list/) == null) {
217 var trialSelPopsList = solGS.selectionPopulation.getPredictedTrialTypeSelectionPops();
218 if (trialSelPopsList) {
219 ggPops.push(trialSelPopsList);
223 var menu = new SelectMenu(this.ggPopsDiv, this.ggPopsSelectMenuId);
226 menu.updateOptions(newPop);
228 menu.populateMenu(ggPops);
233 getSelPopPredictedTraits: function (ggArgs) {
234 var ggMsgDiv = this.ggMsgDiv;
235 var canvas = this.canvas;
237 var args = JSON.stringify(ggArgs);
241 data: {'arguments': args},
242 url: "/solgs/selection/population/predicted/traits",
243 success: function (res) {
244 if (res.selection_traits) {
245 var ggArgs = solGS.geneticGain.getGeneticGainArgs();
246 jQuery(`${canvas} #selection_traits_ids`).val(res.selection_traits);
247 solGS.geneticGain.plotGeneticGainBoxplot(ggArgs);
249 jQuery(ggMsgDiv).html("This selection population has no predicted traits.").show();
255 "Error occured checking for predicted traits for the selection population " +
263 plotGEBVs: function (trainingGEBVs, selectionGEBVs) {
264 var normalDistTraining = new solGS.normalDistribution();
266 var trainingNormalDistData = normalDistTraining.getNormalDistData(trainingGEBVs);
268 var gebvZScoresT = normalDistTraining.getYValuesZScores(trainingNormalDistData);
270 var yValuesT = normalDistTraining.getPValues(trainingNormalDistData);
272 var zScoresPT = normalDistTraining.getZScoresP(trainingNormalDistData);
274 var xYT = normalDistTraining.getYValuesP(trainingNormalDistData);
276 var xValuesT = normalDistTraining.getYValues(trainingGEBVs);
278 var trMean = ss.mean(xValuesT);
280 var stdT = trMean <= 0 ? -1.0 : 1.0;
282 var xMT = normalDistTraining.getObsValueZScore(gebvZScoresT, stdT);
284 var normalDistSelection = new solGS.normalDistribution();
286 var selectionNormalDistData = normalDistSelection.getNormalDistData(selectionGEBVs);
288 var gebvZScoresS = normalDistSelection.getYValuesZScores(selectionNormalDistData);
290 var yValuesS = normalDistSelection.getPValues(selectionNormalDistData);
292 var zScoresPS = normalDistSelection.getZScoresP(selectionNormalDistData);
294 var xYS = normalDistSelection.getYValuesP(selectionNormalDistData);
296 var xValuesS = normalDistSelection.getYValues(selectionGEBVs);
298 var slMean = ss.mean(xValuesS);
300 var stdS = slMean <= 0 ? -1.0 : 1.0;
302 var xMS = normalDistTraining.getObsValueZScore(gebvZScoresS, stdS);
304 var svgId = "#compare_gebvs_canvas";
305 var plotId = "#compare_gebvs_plot";
307 var trColor = "#02bcff";
308 var slColor = "#ff1302";
309 var axLabelColor = "#ff8d02";
310 var yLabel = "Probability";
311 var xLabel = "GEBVs";
314 "Normal distribution curves of GEBVs " + "for the training and selection populations.";
319 x_axis_label: xLabel,
320 y_axis_label: yLabel,
321 axis_label_color: axLabelColor,
325 legend: "Training population",
330 legend: "Selection population",
336 var linePlot = solGS.linePlot(allData);
338 var trainingMidlineData = [
340 [trMean, d3.max(yValuesT)],
343 var selectionMidlineData = [
345 [slMean, d3.max(yValuesS)],
351 return linePlot.xScale(d[0]);
354 return linePlot.yScale(d[1]);
359 .attr("d", midLine(trainingMidlineData))
360 .attr("stroke", trColor)
361 .attr("stroke-width", "3")
362 .attr("fill", "none")
363 .on("mouseover", function (d) {
367 .attr("id", "tr_mean")
368 .text(d3.format(".2f")(trMean))
371 "font-weight": "bold",
373 .attr("x", linePlot.xScale(xMT[0]))
374 .attr("y", linePlot.yScale(d3.max(yValuesT) * 0.5));
377 .on("mouseout", function () {
378 d3.selectAll("text#tr_mean").remove();
383 .attr("d", midLine(selectionMidlineData))
384 .attr("stroke", slColor)
385 .attr("stroke-width", "3")
386 .attr("fill", "none")
387 .on("mouseover", function (d) {
391 .attr("id", "sl_mean")
392 .text(d3.format(".2f")(slMean))
395 "font-weight": "bold",
397 .attr("x", linePlot.xScale(xMS[0]))
398 .attr("y", linePlot.yScale(d3.max(yValuesS) * 0.5));
401 .on("mouseout", function () {
402 d3.selectAll("text#sl_mean").remove();
410 jQuery(document).ready(function () {
411 jQuery("#check_genetic_gain").on("click", function () {
412 var page = document.URL;
414 if (page.match(/solgs\/selection\//)) {
415 solGS.geneticGain.gebvsComparison();
417 var selectedPopId = jQuery("#gg_selected_pop_id").val();
418 var selectedPopType = jQuery("#gg_selected_pop_type").val();
419 var selectedPopName = jQuery("#gg_selected_pop_name").val();
421 jQuery("#gg_message")
422 .css({ "padding-left": "0px" })
423 .html("checking predicted traits for selection population " + selectedPopName);
425 var ggArgs = solGS.geneticGain.getGeneticGainArgs();
426 solGS.geneticGain.getSelPopPredictedTraits(ggArgs);
431 jQuery(document).ready(function () {
432 var page = document.URL;
434 if (page.match(/solgs\/traits\/all\/|solgs\/models\/combined\/trials\//) != null) {
435 setTimeout(function () {
436 solGS.geneticGain.populateGeneticGainMenu();
441 jQuery(document).ready(function () {
442 var ggPopsDiv = solGS.geneticGain.ggPopsDiv;
443 jQuery(ggPopsDiv).change(function () {
445 var selectedPop = jQuery("option:selected", this).data("pop");
447 jQuery("#gg_selected_pop_name").val(selectedPop.name);
448 jQuery("#gg_selected_pop_id").val(selectedPop.id);
449 jQuery("#gg_selected_pop_type").val(selectedPop.pop_type);