2 * kinship analysis and result plotting using d3
3 * Isaak Y Tecle <iyt2@cornell.edu>
7 var solGS = solGS || function solGS() {};
10 canvas: "#kinship_canvas",
11 kinshipPlotDivPrefix: "#kinship_plot",
12 kinshipMsgDiv: "#kinship_message",
13 kinshipPopsSelectMenuId: "#kinship_pops_select",
14 kinshipPopsDiv: "#kinship_pops_select_div",
15 kinshipPopsDataDiv: "#kinship_pops_data_div",
17 getKinshipArgs: function () {
18 var page = location.pathname;
25 if (page.match(/solgs\/trait\/|solgs\/model\/combined\/trials\/|\/breeders\/trial\//)) {
26 trainingPopId = jQuery("#training_pop_id").val();
28 trainingPopId = jQuery("#trial_id").val();
30 kinshipPopId = trainingPopId;
31 } else if (page.match(/kinship\/analysis/)) {
32 kinshipUrlArgs = this.getKinshipArgsFromUrl();
33 kinshipPopId = kinshipUrlArgs.kinship_pop_id;
34 dataStr = kinshipUrlArgs.data_structure;
35 protocolId = kinshipUrlArgs.genotyping_protocol_id;
36 } else if (page.match(/\/selection\/|\/prediction\//)) {
37 selectionPopId = jQuery("#selection_pop_id").val();
38 kinshipPopId = selectionPopId;
39 } else if (page.match(/solgs\/traits\/all\/population\/|models\/combined\/trials\//)) {
40 trainingPopId = jQuery("#training_pop_id").val();
41 kinshipPopId = trainingPopId;
44 if (page.match(/combined/)) {
45 var comboPopsId = trainingPopId;
52 if (String(kinshipPopId).match(/list/)) {
54 } else if (String(kinshipPopId).match(/dataset/)) {
58 if (dataStr == "list") {
59 if (isNaN(kinshipPopId)) {
60 listId = kinshipPopId.replace("list_", "");
62 listId = kinshipPopId;
64 } else if (dataStr == "dataset") {
65 if (isNaN(kinshipPopId)) {
66 datasetId = kinshipPopId.replace("dataset_", "");
68 datasetId = kinshipPopId;
72 var protocolId = jQuery("#genotyping_protocol_id").val();
73 var traitId = jQuery("#trait_id").val();
76 kinship_pop_id: kinshipPopId,
77 training_pop_id: trainingPopId,
79 dataset_id: datasetId,
80 combo_pops_id: comboPopsId,
81 selection_pop_id: selectionPopId,
82 data_structure: dataStr,
83 genotyping_protocol_id: protocolId,
85 analysis_type: "kinship analysis",
89 getKinshipArgsFromUrl: function () {
90 var page = location.pathname;
91 if (page == "/kinship/analysis/") {
92 page = "/kinship/analysis";
94 var urlArgs = page.replace("/kinship/analysis", "");
97 var args = urlArgs.split(/\/+/);
98 var selectId = args[1];
99 var protocolId = args[3];
103 var popId = selectId.match(reg)[0];
104 if (selectId.match(/dataset/)) {
106 } else if (selectId.match(/list/)) {
111 kinship_pop_id: popId,
112 data_structure: dataStr,
113 genotyping_protocol_id: protocolId,
123 getTableTdId: function (kinshipPopId) {
124 return `kinship_${kinshipPopId}`;
128 createTable: function (tableId) {
130 `<table id="${tableId}" class="table table-striped"><thead><tr>` +
131 "<th>Population</th>" +
132 "<th>Data structure type</th>" +
133 "<th>Ownership</th>" +
134 "<th>Data type</th>" +
135 "<th>Run Kinship</th>" +
136 "</tr></thead></table>";
141 getKinshipPopId: function (selectedId, dataStr) {
145 pcaPopId = `${dataStr}_${selectedId}`;
147 pcaPopId = selectedId;
153 createRowElements: function (kinshipPop) {
154 var popId = kinshipPop.id;
155 var popName = kinshipPop.name;
156 var dataStr = kinshipPop.data_str;
158 var kinshipPopId = solGS.kinship.getKinshipPopId(popId, dataStr);
160 var dataTypeOpts = this.getDataTypeOpts({
166 dataTypeOpts = this.createDataTypeSelect(dataTypeOpts, kinshipPopId);
172 if (dataStr.match(/dataset/)) {
174 } else if (dataStr.match(/list/)) {
177 var protocolId = solGS.genotypingProtocol.getGenotypingProtocolId("kinship_div");
180 kinship_pop_id: kinshipPopId,
181 data_structure: dataStr,
182 dataset_id: datasetId,
184 kinship_pop_name: popName,
185 genotyping_protocol_id: protocolId,
186 analysis_type: "kinship analysis",
189 kinshipArgs = JSON.stringify(kinshipArgs);
191 var runKinshipBtnId = this.getRunKinshipBtnId(kinshipPopId);
193 `<button type="button" id=${runKinshipBtnId}` +
194 ` class="btn btn-success" data-selected-pop='${kinshipArgs}'>Run kinship</button>`;
196 if (dataStr.match(/dataset/)) {
197 popName = `<a href="/dataset/${popId}">${popName}</a>`;
199 var rowData = [popName,
200 dataStr, kinshipPop.owner, dataTypeOpts, runKinshipBtn, `${dataStr}_${popId}`];
205 displayKinshipPopsTable: function (tableId, data) {
207 var table = jQuery(`#${tableId}`).DataTable({
214 'rowId': function (a) {
219 table.rows.add(data).draw();
224 getKinshipPopsRows: function(kinshipPops) {
226 var kinshipPopsRows = [];
228 for (var i = 0; i < kinshipPops.length; i++) {
229 if (kinshipPops[i]) {
230 var kinshipPopRow = this.createRowElements(kinshipPops[i]);
231 kinshipPopsRows.push(kinshipPopRow);
235 return kinshipPopsRows;
239 getKinshipPops: function () {
241 var list = new solGSList();
242 var lists = list.getLists(["accessions", "trials"]);
243 lists = list.addDataStrAttr(lists);
245 var datasets = solGS.dataset.getDatasetPops(["accessions", "trials"]);
247 var kinshipPops = [lists, datasets];
249 return kinshipPops.flat();
253 getDataTypeOpts: function (args) {
254 var dataTypeOpts = ["Genotype"];
260 createDataTypeSelect: function (opts) {
261 var dataTypeGroup = '<select class="form-control" id="kinship_data_type_select">';
263 for (var i = 0; i < opts.length; i++) {
264 dataTypeGroup += '<option value="' + opts[i] + '">' + opts[i] + "</option>";
266 dataTypeGroup += "</select>";
268 return dataTypeGroup;
271 getSelectedPopKinshipArgs: function (runKinshipElemId) {
274 var selectedPopDiv = document.getElementById(runKinshipElemId);
275 if (selectedPopDiv) {
276 var selectedPopData = selectedPopDiv.dataset;
278 kinshipArgs = JSON.parse(selectedPopData.selectedPop);
279 var kinshipPopId = kinshipArgs.data_str + "_" + kinshipArgs.id;
281 var protocolId = solGS.genotypingProtocol.getGenotypingProtocolId("kinship_div");
282 var page = `/kinship/analysis/${kinshipPopId}/gp/${protocolId}`;
284 kinshipArgs["analysis_type"] = "kinship analysis";
285 kinshipArgs["genotyping_protocol_id"] = protocolId;
286 kinshipArgs["analysis_page"] = page;
292 checkCachedKinship: function (page, args) {
293 args = JSON.stringify(args);
295 var checkCached = jQuery.ajax({
302 url: "/solgs/check/cached/result/",
308 runKinshipAnalysis: function (args) {
309 var kinArgs = JSON.stringify(args);
311 var runKinship = jQuery.ajax({
314 data: { arguments: kinArgs },
315 url: "/run/kinship/analysis/",
321 addDowloandLinks: function (res) {
322 var popName = res.kinship_pop_name;
323 var kinFileId = res.kinship_file_id;
324 var kinshipFile = res.kinship_table_file;
326 var aveFile = res.kinship_averages_file;
327 var inbreedingFile = res.inbreeding_file;
329 var fileNameKinship = kinshipFile.split("/").pop();
330 var fileNameAve = aveFile.split("/").pop();
331 var fileNameInbreeding = inbreedingFile.split("/").pop();
334 '<a href="' + kinshipFile + '" download=' + fileNameKinship + ">Kinship matrix</a>";
336 aveFile = '<a href="' + aveFile + '" download=' + fileNameAve + ">Average kinship</a>";
343 ">Inbreeding coefficients</a>";
345 var kinDownloadBtn = "download_" + "kinship_plot_" + kinFileId;
347 "<a href='#' onclick='event.preventDefault();' id='" + kinDownloadBtn + "'> plot</a>";
349 var links = "<strong>Download:</strong> ";
352 links = links + popName + " ";
355 links = links + kinshipFile + " | " + aveFile + " | " + inbreedingFile + " | " + kinPlotLink;
360 getRunKinshipBtnId: function (rowId) {
361 if (location.pathname.match(/kinship\/analysis/) && rowId) {
362 return `run_kinship_${rowId}`;
364 return "run_kinship";
368 getKinshipPopId: function (selectId, dataStr) {
371 kinshipPopId = `${dataStr}_${selectId}`;
373 kinshipPopId = selectId;
382 jQuery(document).ready(function () {
383 jQuery("#kinship_div").on("click", function (e) {
384 var runKinshipBtnId = e.target.id;
385 if (runKinshipBtnId.match(/run_kinship/)) {
386 var kinshipArgs = solGS.kinship.getKinshipArgs();
387 var kinshipPopId = kinshipArgs.kinship_pop_id;
389 kinshipArgs = solGS.kinship.getSelectedPopKinshipArgs(runKinshipBtnId);
392 kinshipPopId = kinshipArgs.kinship_pop_id;
393 var protocolId = solGS.genotypingProtocol.getGenotypingProtocolId("kinship_div");
395 var canvas = solGS.kinship.canvas;
396 var kinshipPlotDivId = solGS.kinship.kinshipPlotDivPrefix;
397 var kinshipMsgDiv = solGS.kinship.kinshipMsgDiv;
398 runKinshipBtnId = `#${runKinshipBtnId}`;
399 var kinshipUrl = `/kinship/analysis/${kinshipPopId}/gp/${protocolId}`;
400 // solGS.kinship.generateKinshipUrl(kinshipPopId);
401 kinshipArgs["analysis_page"] = kinshipUrl;
403 jQuery(runKinshipBtnId).hide();
404 jQuery(`${canvas} .multi-spinner-container`).show();
406 jQuery(runKinshipBtnId).hide();
407 jQuery(kinshipMsgDiv).text("Running kinship... please wait...it may take minutes.").show();
409 jQuery(`${canvas} .multi-spinner-container`).show();
411 .checkCachedKinship(kinshipUrl, kinshipArgs)
412 .done(function (res) {
414 jQuery(kinshipMsgDiv).html("Generating heatmap... please wait...").show();
416 kinshipPlotDivId = `${kinshipPlotDivId}_${res.kinship_file_id}`;
418 var links = solGS.kinship.addDowloandLinks(res);
419 solGS.heatmap.plot(res.data, canvas, kinshipPlotDivId, links);
421 jQuery(`${canvas} .multi-spinner-container`).hide();
422 jQuery(kinshipMsgDiv).empty();
423 jQuery(runKinshipBtnId).show();
426 jQuery(`${canvas} .multi-spinner-container`).hide();
427 jQuery(kinshipMsgDiv).empty();
430 "<p>This analysis may take a long time. " +
431 "Do you want to submit the analysis and get an email when it completes?</p>";
433 var jobSubmit = '<div id= "kinship_submit">' + title + "</div>";
435 jQuery(jobSubmit).appendTo("body");
437 jQuery("#kinship_submit").dialog({
441 title: "Kinship job submission",
445 class: "btn btn-success",
448 jQuery(this).dialog("close");
450 solGS.submitJob.checkUserLogin(kinshipUrl, kinshipArgs);
455 text: "No, I will wait till it completes.",
456 class: "btn btn-warning",
459 jQuery(this).dialog("close");
461 jQuery(kinshipMsgDiv).text("Running kinship... please wait...it may take minutes.").show();
462 jQuery(`${canvas} .multi-spinner-container`).show();
465 .runKinshipAnalysis(kinshipArgs)
466 .done(function (res) {
468 jQuery(kinshipMsgDiv)
469 .html("Generating heatmap... please wait...")
472 kinshipPlotDivId = `${kinshipPlotDivId}_${res.kinship_file_id}`;
474 var links = solGS.kinship.addDowloandLinks(res);
475 solGS.heatmap.plot(res.data, canvas, kinshipPlotDivId, links);
477 jQuery(`${canvas} .multi-spinner-container`).hide();
478 jQuery(kinshipMsgDiv).empty();
479 jQuery(runKinshipBtnId).show();
481 jQuery(`${canvas} .multi-spinner-container`).hide();
482 jQuery(kinshipMsgDiv)
484 "padding-left": "0px",
486 .html("This population has no kinship output data.")
489 jQuery(runKinshipBtnId).show();
493 jQuery(kinshipMsgDiv)
494 .html("Error occured running the kinship.")
498 jQuery(`${canvas} .multi-spinner-container`).hide();
505 class: "btn btn-info",
506 id: "cancel_queue_info",
508 jQuery(this).dialog("close");
509 jQuery(runKinshipBtnId).show();
517 jQuery(kinshipMsgDiv).html("Error occured running the kinship.").show().fadeOut(8400);
518 jQuery(`${canvas} .multi-spinner-container`).hide();
524 jQuery(document).ready(function () {
525 var url = location.pathname;
527 if (url.match(/kinship\/analysis/)) {
528 var args = solGS.kinship.getKinshipArgsFromUrl();
529 if (args.kinship_pop_id) {
530 if (args.data_structure) {
531 args["kinship_pop_id"] = args.data_structure + "_" + args.kinship_pop_id;
533 solGS.kinship.checkCachedKinship(url, args).done(function (res) {
535 var kinshipMsgDiv = solGS.kinship.kinshipMsgDiv;
536 var canvas = solGS.kinship.canvas;
538 jQuery(kinshipMsgDiv).html("Generating heatmap... please wait...").show();
539 jQuery(`${canvas} .multi-spinner-container`).show();
541 var kinshipPlotDivId = solGS.kinship.kinshipPlotDivPrefix;
542 kinshipPlotDivId = `${kinshipPlotDivId}_${res.kinship_file_id}`;
544 var links = solGS.kinship.addDowloandLinks(res);
545 solGS.heatmap.plot(res.data, canvas, kinshipPlotDivId, links);
547 jQuery(`${canvas} .multi-spinner-container`).hide();
548 jQuery(kinshipMsgDiv).empty();
555 jQuery(document).ready(function () {
556 var kinshipCanvas = solGS.kinship.canvas;
557 jQuery(kinshipCanvas).on("click", "a", function (e) {
558 var buttonId = e.target.id;
559 var kinshipPlotId = buttonId.replace(/download_/, "");
560 saveSvgAsPng(document.getElementById("#" + kinshipPlotId), kinshipPlotId + ".png", { scale: 1 });
564 jQuery(document).ready(function () {
565 var url = location.pathname;
567 if (url.match(/kinship\/analysis/)) {
568 kinshipPopsDataDiv = solGS.kinship.kinshipPopsDataDiv;
569 var tableId = 'kinship_pops_table';
570 var kinshipPopsTable = solGS.kinship.createTable(tableId);
571 jQuery(kinshipPopsDataDiv).append(kinshipPopsTable).show();
573 var kinshipPops = solGS.kinship.getKinshipPops();
574 var kinshipPopsRows = solGS.kinship.getKinshipPopsRows(kinshipPops);
576 solGS.kinship.displayKinshipPopsTable(tableId, kinshipPopsRows);
577 jQuery("#add_new_pops").show();