minor fixes
[sgn.git] / js / solGS / selectionIndex.js
blob82252fe61f3a5ba79d38c7d589f26330c81cd21b
1 /** 
2 * selection index form, calculation and presentation
3 * @author Isaak Y Tecle <iyt2@cornell.edu>
5 */
7 JSAN.use('jquery.blockUI');
10 jQuery(document).ready( function () {
11     
12     setTimeout(function(){listSelectionIndexPopulations()}, 5000);
13        
14 });
17 jQuery("#rank_genotypes").live("click", function() {        
18     var modelId        = jQuery("#model_id").val();
19     var selectionPopId = jQuery("#selected_population_id").val();
20     var popType        = jQuery("#selected_population_type").val();
21    
22     selectionIndex(modelId, selectionPopId);        
23 });
26 function listSelectionIndexPopulations ()  {
27    
28     var modelData = getTrainingPopulationData();
29     var trainingPopIdName = JSON.stringify(modelData);
30    
31     var  popsList =  '<dl id="selected_population" class="si_dropdown">'
32         + '<dt> <a href="#"><span>Choose a population</span></a></dt>'
33         + '<dd>'
34         + '<ul>'
35         + '<li>'
36         + '<a href="#">' + modelData.name + '<span class=value>' + trainingPopIdName + '</span></a>'
37         + '</li>';  
39     popsList += '</ul></dd></dl>'; 
40    
41     jQuery("#select_a_population_div").empty().append(popsList).show();
42      
43     var dbSelPopsList;
44     if( modelData.id.match(/uploaded/) == null) {
45         dbSelPopsList = addSelectionPopulations();
46     }
48     if (dbSelPopsList) {
49             jQuery("#select_a_population_div ul").append(dbSelPopsList); 
50     }
51       
52     var userUploadedSelExists = jQuery("#uploaded_selection_pops_table").doesExist();
53     if( userUploadedSelExists == true) {
54         var userSelPops = listUploadedSelPopulations();
55         if (userSelPops) {
57             jQuery("#select_a_population_div ul").append(userSelPops);  
58         }
59     }
61     getSelectionPopTraits(modelData.id, modelData.id);
64    jQuery(".si_dropdown dt a").click(function() {
65             jQuery(".si_dropdown dd ul").toggle();
66         });
67                  
68     jQuery(".si_dropdown dd ul li a").click(function() {
69       
70         var text = jQuery(this).html();
71         
72         jQuery(".si_dropdown dt a span").html(text);
73         jQuery(".si_dropdown dd ul").hide();
74                 
75         var idPopName = jQuery("#selected_population").find("dt a span.value").html();
76         idPopName     = JSON.parse(idPopName);
77         modelId = jQuery("#model_id").val();
78                    
79         selectedPopId   = idPopName.id;
80         selectedPopName = idPopName.name;
81         selectedPopType = idPopName.pop_type;
82       
83         jQuery("#selected_population_name").val(selectedPopName);
84         jQuery("#selected_population_id").val(selectedPopId);
85         jQuery("#selected_population_type").val(selectedPopType);        
86             
87         getSelectionPopTraits(modelId, selectedPopId);
88                                          
89     });
90                        
91     jQuery(".si_dropdown").bind('click', function(e) {
92         var clicked = jQuery(e.target);
93                     
94         if (! clicked.parents().hasClass("si_dropdown"))
95             jQuery(".si_dropdown dd ul").hide();
96         
97         e.preventDefault();
98     });           
101        
102 function addSelectionPopulations(){
103       
104     var selPopsTable = jQuery("#selection_pops_list").html();  
105     var selPopsRows  = jQuery(selPopsTable).find("tr");
107     var predictedPop = [];
108     var popsList = '';
109        
110     for (var i = 1; i < selPopsRows.length; i++) {
111         var row    = selPopsRows[i];
112         var popRow = row.innerHTML;
113        
114         predictedPop = popRow.match(/\/solgs\/selection\//g);
115            
116         if (predictedPop) {
117             if (predictedPop.length > 1) {
118                 var selPopsInput  = row.getElementsByTagName("input")[0];
119                 var idPopName     = selPopsInput.value;
120                 var idPopNameCopy = idPopName;
121                 idPopNameCopy     = JSON.parse(idPopNameCopy);
122                 var popName       = idPopNameCopy.name;
123                         
124                 popsList += '<li>'
125                     + '<a href="#">' + popName + '<span class=value>' + idPopName + '</span></a>'
126                     + '</li>';
127             }
128         }
129     }
131     return popsList;
135 function getSelectionPopTraits (modelId, selectedPopId) {
137     if (modelId === selectedPopId) {selectedPopId=undefined;}
138    
139     jQuery.ajax({
140         type: 'POST',
141         dataType: "json",
142         url: '/solgs/selection/index/form',
143         data: {'pred_pop_id': selectedPopId, 'training_pop_id': modelId},
144         success: function(res) {
145                 
146             if (res.status == 'success') {
147                 var table;
148                 var traits = res.traits;
149                 
150                 if (traits.length > 1) {
151                     table  = selectionIndexForm(traits);
152                 } else {
153                     var msg = 'There is only one trait with valid GEBV predictions.';
154                     jQuery("#select_a_population_div").empty(); 
155                     jQuery("#select_a_population_div_text").empty().append(msg);      
156                 }
157     
158                 jQuery('#selection_index_form').empty().append(table);
159      
160             }                                               
161         }
162     });
166 function  selectionIndexForm(predictedTraits) {   
167     var cnt = 1;
168     var row = '';
169     var totalCount = 1;
170    
171     for (var i=0; i < predictedTraits.length; i++) { 
172         var tdCell  = '<td>' + predictedTraits[i]  + ':</td>';
173         var rowTag  = '';
174                   
175         if ( cnt === 3 ) {
176             rowTag = '</tr><tr>';
177         }
178                
179         row += tdCell 
180             + '<td><input type="text" name=' +  predictedTraits[i]
181             + ' size = 5px '
182             + '></td>'  
183             + rowTag;
184                                                            
185         if (cnt === 3 ) { cnt=0;}
186         cnt++;
187         totalCount++;                          
188     }
189    
190     var rankButton =  '<tr><td>'
191         +  '<input style="position:relative;" " class="button" type="submit" value="Calculate" name= "rank" id="rank_genotypes"'     
192         +  '</td></tr>';
194     var table = '<br /> <table id="selection_index_table" style="align:left;width:90%"><tr>' 
195         +  row + '</tr>' 
196         + rankButton 
197         + '</table>';
198         
199     return table;
203 function applySelectionIndex(params, legend, trainingPopId, predictionPopId) {
204    
205     if (params) {                      
206         jQuery.blockUI.defaults.applyPlatformOpacityRules = false;
207         jQuery.blockUI({message: 'Please wait..'});
208             
209         var action;
210            
211         if (!predictionPopId) {     
212             predictionPopId = 'undef';      
213         }
214         
215         var action = '/solgs/calculate/selection/index/' + trainingPopId +  '/' + predictionPopId;
216           
217         jQuery.ajax({
218             type: 'POST',
219             dataType: "json",
220             url: action,
221             data: params,
222             success: function(res){                       
223                 var suc = res.status;
224                 var table;
225                 if (suc == 'success' ) {
226                        
227                     var genos = new Object();
228               
229                     genos = res.genotypes;
230                     var download_link = res.link;
231                     var indexFile     = res.index_file;
232                         
233                     table = '<table  style="text-align:left; border:0px; padding: 1px; width:75%;">';
234                     table += '<tr><th>Genotypes</th><th>Selection indices</th></tr>';
235                        
236                     var sorted = []; 
237                     for (var geno in genos) {
238                         sorted.push([geno, genos[geno]]);
239                         sorted = sorted.sort(function(a, b) {return b[1] - a[1]});
240                     }
242                     for (var i=0; i<sorted.length; i++) {
243                         table += '<tr>';
244                         table += '<td>' 
245                             + sorted[i][0] + '</td>' + '<td>' 
246                             + sorted[i][1] + '</td>';
247                         table += '</tr>';                          
248                     }
249                         
250                     table += '</table>';                    
251                     table += '<br>[ ' + download_link + ' ]';
252                     table += '<br>' + legend + '<br/><br/>';
253                 } else {
254                     table = res.status + ' Ranking the genotypes failed..Please report the problem.';
255                 }
256                         
257                 jQuery('#top_genotypes').append(table).show(); 
258                 jQuery('#selected_pop').val('');
259                               
260                 var popId;
261                 var type;
262                 if (predictionPopId && predictionPopId !== trainingPopId) {
263                     popId = predictionPopId;
264                     type  = 'selection';                    
265                 } else {                    
266                     popId = trainingPopId;
267                     type  = 'training';
268                 }
270                 formatGenCorInputData(popId, type, indexFile);
271                 
272                 jQuery("#si_correlation_message")
273                     .css({"padding-left": '0px'})
274                     .html("Running correlation analysis..."); 
275                 
276             },
277             error: function(res){
278                 alert('error occured calculating selection index.');
279                 jQuery.unblockUI(); 
280             }
281         });
282     }           
286 function validateRelativeWts(nm, val) {    
287     
288      if (isNaN(val) && nm != 'all') {
289          alert('the relative weight of trait '+nm+ 
290                ' must be a number.'
291                );            
292          return;
293      } else if (!val && nm != 'all') {
294          alert('You need to assign a relative weight to trait '+nm+'.' 
295                +' If you want to exclude the trait assign 0 to it.'
296                );            
297          return;
298     // }// else if (val < 0 && nm != 'all') {
299       //   alert('The relative weight to trait '+nm+
300       //         ' must be a positive number.'
301       //         );            
302      //    return;
303      } else if (nm == 'all' && val == 0) {
304          alert('At least two traits must be assigned relative weight.');      
305          return; 
306      } else {
307          return true;
308      }
312 function sumElements (elements) {
313     var sum = 0;
314     for (var i=0; i<elements.length; i++) {            
315         if (!isNaN(elements[i])) {
316             sum = parseFloat(sum) +  parseFloat(elements[i]);
317         }
318     }
319     return sum;
322     
323 function selectionIndex ( trainingPopId, predictionPopId ) {    
324        
325     if (!predictionPopId) {
326         predictionPopId = jQuery("#default_selected_population_id").val();
327     }
328    
329     var legendValues = legendParams();
330     
331     var legend   = legendValues.legend;
332     var params   = legendValues.params;
333     var validate = legendValues.validate;
334   
335     if (params && validate) {
336         applySelectionIndex(legendValues.params, legendValues.legend, trainingPopId, predictionPopId);
337     }
341 function legendParams () {
342     
343     var predPopName   = jQuery("#selected_population_name").val();
344    
345     if (!predPopName) {
346         predPopName = jQuery("#default_selected_population_name").val();
347     }
349     var rel_form = document.getElementById('selection_index_form');
350     var all = rel_form.getElementsByTagName('input');
351     var params, validate;
352     var allValues = [];
353     
354     var legend =  "<div id=\"si_legend_" 
355                     + predPopName.replace(/\s/g, "") 
356                     + "\">";
358     legend += '<b>Relative weights</b>:';
360      for (var i = 0; i < all.length; i++) {         
361          var nm = all[i].name;
362          var val = all[i].value;
364          if (val != 'Calculate')  {
365              if (nm != 'prediction_pop_name') {
366                  
367                  allValues.push(val);
368                  validate = validateRelativeWts(nm, val);
369               
370                  if (validate) {
371                      if (i == 0) { 
372                          params = nm+'='+val; 
373                      } else {
374                          params = params +'&'+ nm + '=' + val;
375                      }                               
376                      legend += '<b> ' + nm + '</b>' + ': '+ val;
377                  }
378              }
379          }            
380      } 
381   
382      var sum = sumElements(allValues);
383      validate = validateRelativeWts('all', sum);
384         
385      for (var i=0;  i<allValues.length; i++)  {
386         // (isNaN(allValues[i]) || allValues[i] < 0) 
387          if (isNaN(allValues[i])) { 
388              params = undefined;
389          }
390      }
391         
392      if (predPopName) {
393          legend += '<br/><b>Name</b>: ' + predPopName + '<br/></div';
394      }      
396     return {'legend' : legend, 
397             'params': params, 
398             'validate' : validate
399            };
403 function listUploadedSelPopulations ()  {
404    
405     var selPopsDivUploaded   = document.getElementById("uploaded_selection_populations");
406     var selPopsTableUploaded = selPopsDivUploaded.getElementsByTagName("table");
407     var selPopsRowsUploaded  = selPopsTableUploaded[0].rows;
408     var predictedPopUploaded = [];
409    
410     var popsList ='';
411     for (var i = 1; i < selPopsRowsUploaded.length; i++) {
412         var row    = selPopsRowsUploaded[i];
413         var popRow = row.innerHTML;
414             
415         predictedPopUploaded = popRow.match(/\/solgs\/selection\//g);
416       
417         if (predictedPopUploaded) {
418             var selPopsInput  = row.getElementsByTagName("input")[0];
419             var idPopName     = selPopsInput.value;     
420             var idPopNameCopy = idPopName;
421             idPopNameCopy     = JSON.parse(idPopNameCopy);
422             var popName       = idPopNameCopy.name;
423            
424             popsList += '<li>'
425                 + '<a href="#">' + popName + '<span class=value>' + idPopName + '</span></a>'
426                 + '</li>';
427         } else {
428             popsList = undefined;
429         }
430     }
432    return popsList; 
436 function getTrainingPopulationData () {
438     var modelId   = jQuery("#model_id").val();
439     var modelName = jQuery("#model_name").val();
440     var popType   = jQuery("#default_selected_population_type").val();
442     return {'id' : modelId, 'name' : modelName, 'pop_type': popType};