extensions/net.sf.basedb.reggie/trunk/resources/flaggedalignment/search.js

Code
Comments
Other
Rev Date Author Line
4794 07 May 18 nicklas 1 var Search = function()
4794 07 May 18 nicklas 2 {
4794 07 May 18 nicklas 3   var search = {};
4794 07 May 18 nicklas 4   var debug = 0;
4794 07 May 18 nicklas 5   
4797 08 May 18 nicklas 6   var bugIcons = [ 'bug-yellow.png', 'bug-red.png', 'bomb.png' ];
4797 08 May 18 nicklas 7   
7209 26 May 23 nicklas 8   var tumors;
7209 26 May 23 nicklas 9   var normals;
4794 07 May 18 nicklas 10   var firstLoad = true;
5001 04 Oct 18 nicklas 11   var numChangedFormElements = 0;
4794 07 May 18 nicklas 12   
4794 07 May 18 nicklas 13   var itemByName = {}; // To keep track of which QiaCubes and LibPlates we have already seen
6589 21 Feb 22 nicklas 14   var assaysByName = {}; // Maps alignment/genotypecall name -> alignment/genotypecall object
7209 26 May 23 nicklas 15   var tumorsByPat = {}; // Maps patient name -> [] of tumors for that patient
4794 07 May 18 nicklas 16   
4794 07 May 18 nicklas 17   // Page initialization
4794 07 May 18 nicklas 18   search.initPage = function()
4794 07 May 18 nicklas 19   {
4794 07 May 18 nicklas 20     // Step 1
4794 07 May 18 nicklas 21     Events.addEventHandler('noFilter', 'change', search.filterOnChange);
4794 07 May 18 nicklas 22     Events.addEventHandler('highHetFilter', 'change', search.filterOnChange);
4794 07 May 18 nicklas 23     Events.addEventHandler('libPlateFilter', 'change', search.filterOnChange);
4794 07 May 18 nicklas 24     Events.addEventHandler('qiaCubeFilter', 'change', search.filterOnChange);
4797 08 May 18 nicklas 25     Events.addEventHandler('recentFilters', 'change', search.recentFilterOnChange);
4794 07 May 18 nicklas 26     
4817 21 May 18 nicklas 27     Events.addEventHandler('mode-genotype', 'change', search.modeOnChange);
4817 21 May 18 nicklas 28     Events.addEventHandler('mode-reprocess', 'change', search.modeOnChange);
4975 21 Sep 18 nicklas 29     Events.addEventHandler('mode-resolve', 'change', search.modeOnChange);
4817 21 May 18 nicklas 30     
5001 04 Oct 18 nicklas 31     Events.addEventHandler('itemTable', 'change', search.changedFormData);
5001 04 Oct 18 nicklas 32     
4817 21 May 18 nicklas 33     Buttons.addClickHandler('goreprocess', search.goReProcess);
4975 21 Sep 18 nicklas 34     Buttons.addClickHandler('goresolve', search.goResolve);
4794 07 May 18 nicklas 35
4794 07 May 18 nicklas 36     var url = '../Genotype.servlet?ID='+App.getSessionId();
4794 07 May 18 nicklas 37     url += '&cmd=GetFlaggedAlignments';
4794 07 May 18 nicklas 38     Wizard.showLoadingAnimation('Loading flagged alignments...');
4794 07 May 18 nicklas 39     Wizard.asyncJsonRequest(url, search.onAlignmentsLoaded);
4794 07 May 18 nicklas 40   }
4794 07 May 18 nicklas 41   
4794 07 May 18 nicklas 42   search.onAlignmentsLoaded = function(response)
4794 07 May 18 nicklas 43   {
7209 26 May 23 nicklas 44     tumors = response.tumors;
7209 26 May 23 nicklas 45     normals = response.normals;
6589 21 Feb 22 nicklas 46     
7209 26 May 23 nicklas 47     for (var itemNo = 0; itemNo < normals.length; itemNo++)
6589 21 Feb 22 nicklas 48     {
7209 26 May 23 nicklas 49       var item = normals[itemNo];
7209 26 May 23 nicklas 50       assaysByName[item.name] = item;
6589 21 Feb 22 nicklas 51     }
6589 21 Feb 22 nicklas 52
4794 07 May 18 nicklas 53     if (firstLoad) 
4794 07 May 18 nicklas 54     {
7209 26 May 23 nicklas 55       if (tumors.length == 0)
5005 04 Oct 18 nicklas 56       {
5005 04 Oct 18 nicklas 57         Wizard.setFatalError('No flagged alignments available for processing.');
5005 04 Oct 18 nicklas 58         return;
5005 04 Oct 18 nicklas 59       }
4794 07 May 18 nicklas 60       search.initFilterLists();
4794 07 May 18 nicklas 61     }
4794 07 May 18 nicklas 62     else 
4794 07 May 18 nicklas 63     {
4794 07 May 18 nicklas 64       search.updateFilterLists();
4794 07 May 18 nicklas 65     }
4794 07 May 18 nicklas 66     firstLoad = false;
4794 07 May 18 nicklas 67     search.primaryAnalysis();
4794 07 May 18 nicklas 68
4817 21 May 18 nicklas 69     Doc.show('navigation');
4794 07 May 18 nicklas 70     search.updateTable();
4794 07 May 18 nicklas 71   }
4794 07 May 18 nicklas 72   
4794 07 May 18 nicklas 73   /**
5001 04 Oct 18 nicklas 74     All changes to form elements will enable a warning when trying to 
5001 04 Oct 18 nicklas 75     go somewhere else.
5001 04 Oct 18 nicklas 76   */
5001 04 Oct 18 nicklas 77   search.changedFormData = function(event)
5001 04 Oct 18 nicklas 78   {
5001 04 Oct 18 nicklas 79     var ctrl = event.target;
5001 04 Oct 18 nicklas 80     
5001 04 Oct 18 nicklas 81     // Check if the control element has changed -- we need different checks for different element types
5001 04 Oct 18 nicklas 82     var modified = false;
5001 04 Oct 18 nicklas 83     if (ctrl.tagName == 'INPUT' && ctrl.type == 'text')
5001 04 Oct 18 nicklas 84     {
5001 04 Oct 18 nicklas 85       // For text elements we can simply compare the current value with the original value
5001 04 Oct 18 nicklas 86       modified = ctrl.defaultValue != ctrl.value;
5001 04 Oct 18 nicklas 87     }
5001 04 Oct 18 nicklas 88     else if (ctrl.tagName == 'SELECT')
5001 04 Oct 18 nicklas 89     {
5001 04 Oct 18 nicklas 90       modified = ctrl.value != ''; // Works, since we always have no value for the default selection
5001 04 Oct 18 nicklas 91     }
5001 04 Oct 18 nicklas 92     else if (ctrl.tagName == 'INPUT' && ctrl.type == 'checkbox')
5001 04 Oct 18 nicklas 93     {
5001 04 Oct 18 nicklas 94       modified = ctrl.checked; // Works, since all checkboxes are unchecked by default
5001 04 Oct 18 nicklas 95     }
5001 04 Oct 18 nicklas 96     
5001 04 Oct 18 nicklas 97     // Did the modified status change for the control?
5001 04 Oct 18 nicklas 98     if (ctrl.modified != modified)
5001 04 Oct 18 nicklas 99     {
5001 04 Oct 18 nicklas 100       ctrl.modified = modified;
5001 04 Oct 18 nicklas 101       // We need to apply the class to the parent (<td>) element since <select> elements don't support ::after/::before
5001 04 Oct 18 nicklas 102       Doc.addOrRemoveClass(ctrl.parentNode, 'modified', modified);
5001 04 Oct 18 nicklas 103       numChangedFormElements += modified ? 1 : -1; //Update counter for changed elements
5001 04 Oct 18 nicklas 104       if (numChangedFormElements < 0) numChangedFormElements = 0; // Just to be safe...
5001 04 Oct 18 nicklas 105       Wizard.setNoConfirmOnFirstStep(numChangedFormElements == 0);
5001 04 Oct 18 nicklas 106     }
5001 04 Oct 18 nicklas 107   }
5001 04 Oct 18 nicklas 108   
5001 04 Oct 18 nicklas 109   /**
4794 07 May 18 nicklas 110     Initialize the QiaCube and LibPlate filter lists.
4794 07 May 18 nicklas 111     This is done on the first load only.
4794 07 May 18 nicklas 112   */
4794 07 May 18 nicklas 113   search.initFilterLists = function()
4794 07 May 18 nicklas 114   {
4794 07 May 18 nicklas 115     var allQiaCubes = [];
4794 07 May 18 nicklas 116     var allLibPlates = [];
4794 07 May 18 nicklas 117     
7209 26 May 23 nicklas 118     for (var itemNo = 0; itemNo < tumors.length; itemNo++)
4794 07 May 18 nicklas 119     {
7209 26 May 23 nicklas 120       var tumor = tumors[itemNo];
7209 26 May 23 nicklas 121       var rna = tumor.rna;
6589 21 Feb 22 nicklas 122       if (rna)
4794 07 May 18 nicklas 123       {
6589 21 Feb 22 nicklas 124         var qiaCubeRun = rna.QIACUBE_DATE + '#' + rna.QIACUBE_RUN_NO;
6589 21 Feb 22 nicklas 125         var qiaCubeRunPos = qiaCubeRun + '@' + rna.QIACUBE_POSITION;
6589 21 Feb 22 nicklas 126     
6589 21 Feb 22 nicklas 127         var qiaCube = itemByName[qiaCubeRun];
6589 21 Feb 22 nicklas 128         if (!qiaCube)
4794 07 May 18 nicklas 129         {
6589 21 Feb 22 nicklas 130           qiaCube = new QiaCube(rna.QIACUBE_DATE, rna.QIACUBE_RUN_NO);
6589 21 Feb 22 nicklas 131           qiaCube.posCount = 1;
6589 21 Feb 22 nicklas 132           allQiaCubes[allQiaCubes.length] = qiaCube;
6589 21 Feb 22 nicklas 133           itemByName[qiaCubeRun] = qiaCube;
4794 07 May 18 nicklas 134           itemByName[qiaCubeRunPos] = qiaCube;
4794 07 May 18 nicklas 135         }
6589 21 Feb 22 nicklas 136         else
6589 21 Feb 22 nicklas 137         {
6589 21 Feb 22 nicklas 138           if (!itemByName[qiaCubeRunPos])
6589 21 Feb 22 nicklas 139           {
6589 21 Feb 22 nicklas 140             qiaCube.posCount++;
6589 21 Feb 22 nicklas 141             itemByName[qiaCubeRunPos] = qiaCube;
6589 21 Feb 22 nicklas 142           }
6589 21 Feb 22 nicklas 143         }
4794 07 May 18 nicklas 144       }
4794 07 May 18 nicklas 145       
7209 26 May 23 nicklas 146       var lib = tumor.lib;
6589 21 Feb 22 nicklas 147       if (lib)
4794 07 May 18 nicklas 148       {
6589 21 Feb 22 nicklas 149         var libPlate = lib.bioWell.bioPlate;
6589 21 Feb 22 nicklas 150     
6589 21 Feb 22 nicklas 151         var plate = itemByName[libPlate.name];
6589 21 Feb 22 nicklas 152         if (!plate)
4794 07 May 18 nicklas 153         {
6589 21 Feb 22 nicklas 154           plate = new LibPlate(libPlate.name);
6589 21 Feb 22 nicklas 155           plate.posCount = 1;
6589 21 Feb 22 nicklas 156           allLibPlates[allLibPlates.length] = plate;
6589 21 Feb 22 nicklas 157           itemByName[libPlate.name] = plate;
4794 07 May 18 nicklas 158           itemByName[platePos] = plate;
4794 07 May 18 nicklas 159         }
6589 21 Feb 22 nicklas 160         else
6589 21 Feb 22 nicklas 161         {
6589 21 Feb 22 nicklas 162           var platePos = libPlate.name+'@'+lib.bioWell.location;
6589 21 Feb 22 nicklas 163           if (!itemByName[platePos])
6589 21 Feb 22 nicklas 164           {
6589 21 Feb 22 nicklas 165             plate.posCount++;
6589 21 Feb 22 nicklas 166             itemByName[platePos] = plate;
6589 21 Feb 22 nicklas 167           }
6589 21 Feb 22 nicklas 168         }
4794 07 May 18 nicklas 169       }
4794 07 May 18 nicklas 170     }
4794 07 May 18 nicklas 171     
4794 07 May 18 nicklas 172     // Sort in logical order
4794 07 May 18 nicklas 173     allQiaCubes.sort(Sort.sortByName);
4794 07 May 18 nicklas 174     allLibPlates.sort(Sort.sortByName);
4794 07 May 18 nicklas 175     
4794 07 May 18 nicklas 176     var frm = document.forms['reggie'];
4794 07 May 18 nicklas 177     for (var plateNo = 0; plateNo < allLibPlates.length; plateNo++)
4794 07 May 18 nicklas 178     {
4794 07 May 18 nicklas 179       var libPlate = allLibPlates[plateNo];
4794 07 May 18 nicklas 180       var option = new Option(libPlate.name + " [" + libPlate.posCount + "]", libPlate.name);
4794 07 May 18 nicklas 181       option.libPlate = libPlate;
4794 07 May 18 nicklas 182       frm.libPlateFilter[frm.libPlateFilter.length] = option;
4794 07 May 18 nicklas 183     }
4794 07 May 18 nicklas 184     for (var qiaCubeNo = 0; qiaCubeNo < allQiaCubes.length; qiaCubeNo++)
4794 07 May 18 nicklas 185     {
4794 07 May 18 nicklas 186       var qiaCube = allQiaCubes[qiaCubeNo];
4794 07 May 18 nicklas 187       var option = new Option(qiaCube.title + " [" + qiaCube.posCount + "]", qiaCube.name);
4794 07 May 18 nicklas 188       option.qiaCube = qiaCube;
4794 07 May 18 nicklas 189       frm.qiaCubeFilter[frm.qiaCubeFilter.length] = option;
4794 07 May 18 nicklas 190     }
4794 07 May 18 nicklas 191   }
4794 07 May 18 nicklas 192   
4794 07 May 18 nicklas 193   
4794 07 May 18 nicklas 194   /**
4794 07 May 18 nicklas 195     Update the QiaCube and LibPlate filter lists with new options.
4794 07 May 18 nicklas 196     This is done after the first load. The options are added to the end of the lists.
4794 07 May 18 nicklas 197   */
4794 07 May 18 nicklas 198   search.updateFilterLists = function()
4794 07 May 18 nicklas 199   {
4794 07 May 18 nicklas 200     var frm = document.forms['reggie'];
4794 07 May 18 nicklas 201     
7209 26 May 23 nicklas 202     for (var itemNo = 0; itemNo < tumors.length; itemNo++)
4794 07 May 18 nicklas 203     {
7209 26 May 23 nicklas 204       var tumor = tumors[itemNo];
7209 26 May 23 nicklas 205       if (tumor.specimen)
4794 07 May 18 nicklas 206       {
7209 26 May 23 nicklas 207         var rna = tumor.rna;
4818 22 May 18 nicklas 208         var qiaCubeRun = rna.QIACUBE_DATE + '#' + rna.QIACUBE_RUN_NO;
4818 22 May 18 nicklas 209         var qiaCubeRunPos = qiaCubeRun + '@' + rna.QIACUBE_POSITION;
4818 22 May 18 nicklas 210         var qiaCube = itemByName[qiaCubeRun];
4818 22 May 18 nicklas 211         if (!qiaCube)
4818 22 May 18 nicklas 212         {
4818 22 May 18 nicklas 213           qiaCube = new QiaCube(rna.QIACUBE_DATE, rna.QIACUBE_RUN_NO);
4818 22 May 18 nicklas 214           itemByName[qiaCubeRun] = qiaCube;
4818 22 May 18 nicklas 215           var option = new Option(qiaCube.title, qiaCube.name);
4818 22 May 18 nicklas 216           option.qiaCube = qiaCube;
4818 22 May 18 nicklas 217           frm.qiaCubeFilter[frm.qiaCubeFilter.length] = option;
4818 22 May 18 nicklas 218         }
4794 07 May 18 nicklas 219       }
4794 07 May 18 nicklas 220       
7209 26 May 23 nicklas 221       var lib = tumor.lib;
4818 22 May 18 nicklas 222       if (lib)
4794 07 May 18 nicklas 223       {
4818 22 May 18 nicklas 224         var libPlate = lib.bioWell.bioPlate;
4818 22 May 18 nicklas 225         var plate = itemByName[libPlate.name];
4818 22 May 18 nicklas 226         if (!plate)
4818 22 May 18 nicklas 227         {
4818 22 May 18 nicklas 228           plate = new LibPlate(libPlate.name);
4818 22 May 18 nicklas 229           itemByName[libPlate.name] = plate;
4818 22 May 18 nicklas 230           
4818 22 May 18 nicklas 231           var option = new Option(libPlate.name, libPlate.name);
4818 22 May 18 nicklas 232           option.libPlate = libPlate;
4818 22 May 18 nicklas 233           frm.libPlateFilter[frm.libPlateFilter.length] = option;
4818 22 May 18 nicklas 234         }
4794 07 May 18 nicklas 235       }
4794 07 May 18 nicklas 236     }
4794 07 May 18 nicklas 237   }
4794 07 May 18 nicklas 238   
4794 07 May 18 nicklas 239   /**
4794 07 May 18 nicklas 240     Callback when some of the filter options has changed.
4794 07 May 18 nicklas 241     This method will detect which one was modified, and
4794 07 May 18 nicklas 242     reset all other filters. Then, it will issue a 
4794 07 May 18 nicklas 243     request to the server to load alignments related to the
4794 07 May 18 nicklas 244     selected filter.
4794 07 May 18 nicklas 245   */
4794 07 May 18 nicklas 246   search.filterOnChange = function(event)
4794 07 May 18 nicklas 247   {
4794 07 May 18 nicklas 248     var frm = document.forms['reggie'];
4794 07 May 18 nicklas 249     
4794 07 May 18 nicklas 250     var noFilter = Doc.element('noFilter');
4794 07 May 18 nicklas 251     var highHet = Doc.element('highHetFilter');
4794 07 May 18 nicklas 252     var libPlate = Doc.element('libPlateFilter');
4794 07 May 18 nicklas 253     var qiaCube = Doc.element('qiaCubeFilter');
4794 07 May 18 nicklas 254     
4817 21 May 18 nicklas 255     if (event)
4817 21 May 18 nicklas 256     {
4817 21 May 18 nicklas 257       if (event.target != noFilter) noFilter.checked = false;
4817 21 May 18 nicklas 258       if (event.target != highHet) highHet.checked = false;
4817 21 May 18 nicklas 259       if (event.target != libPlate) libPlate.selectedIndex = 0;
4817 21 May 18 nicklas 260       if (event.target != qiaCube) qiaCube.selectedIndex = 0;
4817 21 May 18 nicklas 261     }
4817 21 May 18 nicklas 262     
5001 04 Oct 18 nicklas 263     if (numChangedFormElements > 0)
5001 04 Oct 18 nicklas 264     {
5001 04 Oct 18 nicklas 265       if (!confirm('There are unsaved changes. Discard changes?')) return;
5001 04 Oct 18 nicklas 266     }
5001 04 Oct 18 nicklas 267     
4794 07 May 18 nicklas 268     var url = '../Genotype.servlet?ID='+App.getSessionId();
4794 07 May 18 nicklas 269     url += '&cmd=GetFlaggedAlignments';
4794 07 May 18 nicklas 270     
4794 07 May 18 nicklas 271     var msg = 'Loading flagged alignments...';
4794 07 May 18 nicklas 272     var hasFilter = false;
4797 08 May 18 nicklas 273     var newRecentFilter = null;
4794 07 May 18 nicklas 274     if (libPlate.selectedIndex > 0)
4794 07 May 18 nicklas 275     {
4794 07 May 18 nicklas 276       url += '&libPlateFilter='+encodeURIComponent(libPlate.value);
4794 07 May 18 nicklas 277       msg = 'Loading alignments related to ' + libPlate.value;
4794 07 May 18 nicklas 278       hasFilter = true;
4797 08 May 18 nicklas 279       newRecentFilter = { 'value': 'lp:'+libPlate.value, 'text': libPlate.value };
4794 07 May 18 nicklas 280     }
4794 07 May 18 nicklas 281     else if (qiaCube.selectedIndex > 0)
4794 07 May 18 nicklas 282     {
4794 07 May 18 nicklas 283       var qiaCube = frm.qiaCubeFilter[frm.qiaCubeFilter.selectedIndex].qiaCube;
4794 07 May 18 nicklas 284       url += '&qiaCubeFilter='+encodeURIComponent(qiaCube.name);
4794 07 May 18 nicklas 285       msg = 'Loading alignments related to QiaCube ' + qiaCube.title;
4794 07 May 18 nicklas 286       hasFilter = true;
4797 08 May 18 nicklas 287       newRecentFilter = { 'value': 'qc:'+qiaCube.name, 'text': qiaCube.title };
4794 07 May 18 nicklas 288     }
4794 07 May 18 nicklas 289     else if (highHet.checked)
4794 07 May 18 nicklas 290     {
4794 07 May 18 nicklas 291       url += '&highHetFilter=1';
4794 07 May 18 nicklas 292       hasFilter = true;
4794 07 May 18 nicklas 293     }
4794 07 May 18 nicklas 294     else
4794 07 May 18 nicklas 295     {
4794 07 May 18 nicklas 296       noFilter.checked = true;
4817 21 May 18 nicklas 297       Forms.checkRadio(frm.mode, 'genotype');
4794 07 May 18 nicklas 298     }
4794 07 May 18 nicklas 299     
4970 13 Sep 18 nicklas 300     Wizard.hideGoNextConfirmation();
4794 07 May 18 nicklas 301     Wizard.showLoadingAnimation(msg);
4794 07 May 18 nicklas 302     Wizard.asyncJsonRequest(url, search.onAlignmentsLoaded);
4794 07 May 18 nicklas 303     
4797 08 May 18 nicklas 304     if (newRecentFilter != null)
4797 08 May 18 nicklas 305     {
4797 08 May 18 nicklas 306       var recentFilter = Doc.element('recentFilters');
4797 08 May 18 nicklas 307       for (var i = 0; i < recentFilter.length; i++)
4797 08 May 18 nicklas 308       {
4797 08 May 18 nicklas 309         if (recentFilter[i].value == newRecentFilter.value)
4797 08 May 18 nicklas 310         {
4797 08 May 18 nicklas 311           recentFilter.remove(i);
4797 08 May 18 nicklas 312           break;
4797 08 May 18 nicklas 313         }
4797 08 May 18 nicklas 314       }
4797 08 May 18 nicklas 315       recentFilter.add(new Option(newRecentFilter.text, newRecentFilter.value), 1);
4797 08 May 18 nicklas 316       Doc.show(recentFilter, 'inline');
4797 08 May 18 nicklas 317     }
4797 08 May 18 nicklas 318     
4817 21 May 18 nicklas 319     // Hide buttons while updating and disable mode changes
4817 21 May 18 nicklas 320     Doc.hide('navigation');
4817 21 May 18 nicklas 321     Doc.element('mode-reprocess').disabled = true;
4817 21 May 18 nicklas 322     Doc.element('mode-resolve').disabled = true;
4817 21 May 18 nicklas 323     
4817 21 May 18 nicklas 324     if (hasFilter && !highHet.checked)
4794 07 May 18 nicklas 325     {
4797 08 May 18 nicklas 326       search.updateTable(true);
4794 07 May 18 nicklas 327     }
4794 07 May 18 nicklas 328     else
4794 07 May 18 nicklas 329     {
4794 07 May 18 nicklas 330       Doc.element('itemTable').innerHTML = '';
4794 07 May 18 nicklas 331     }
4794 07 May 18 nicklas 332   }
4794 07 May 18 nicklas 333   
4799 09 May 18 nicklas 334
4797 08 May 18 nicklas 335   search.recentFilterOnChange = function(event)
4797 08 May 18 nicklas 336   {
4797 08 May 18 nicklas 337     var list = event.currentTarget;
4797 08 May 18 nicklas 338     var value = list.value;
4797 08 May 18 nicklas 339     var prefix = value.substr(0, 3);
4797 08 May 18 nicklas 340     list.selectedIndex = 0;
4797 08 May 18 nicklas 341     if (prefix == 'qc:')
4797 08 May 18 nicklas 342     {
4797 08 May 18 nicklas 343       Data.set(event.currentTarget, 'qiacuberun', value.substr(3));
4797 08 May 18 nicklas 344       search.setQiaCubeFilter(event);
4797 08 May 18 nicklas 345     }
4797 08 May 18 nicklas 346     else if (prefix == 'lp:')
4797 08 May 18 nicklas 347     {
4797 08 May 18 nicklas 348       Data.set(event.currentTarget, 'libplate', value.substr(3));
4797 08 May 18 nicklas 349       search.setLibPlateFilter(event);
4797 08 May 18 nicklas 350     }
4797 08 May 18 nicklas 351     
4797 08 May 18 nicklas 352   }
4797 08 May 18 nicklas 353   
4794 07 May 18 nicklas 354   /**
4794 07 May 18 nicklas 355     Event handler for clicking on a QiaCube run, which should
4794 07 May 18 nicklas 356     enable the filter for that run and re-load alignments 
4794 07 May 18 nicklas 357     related to it. Updating the selected item in the filter list
4794 07 May 18 nicklas 358     and sending a 'change' event should do the trick.
4794 07 May 18 nicklas 359   */
4794 07 May 18 nicklas 360   search.setQiaCubeFilter = function(event)
4794 07 May 18 nicklas 361   {
4794 07 May 18 nicklas 362     var qiaCubeRun = Data.get(event.currentTarget, 'qiacuberun');
4794 07 May 18 nicklas 363     var frm = document.forms['reggie'];
4794 07 May 18 nicklas 364     Forms.selectListOption(frm.qiaCubeFilter, qiaCubeRun);
4794 07 May 18 nicklas 365     Events.sendChangeEvent(frm.qiaCubeFilter);
4794 07 May 18 nicklas 366   }
4794 07 May 18 nicklas 367   
4794 07 May 18 nicklas 368   /**
4794 07 May 18 nicklas 369     Event handler for clicking on a LibPlate, which should
4794 07 May 18 nicklas 370     enable the filter for that run and re-load alignments 
4794 07 May 18 nicklas 371     related to it. Updating the selected item in the filter list
4794 07 May 18 nicklas 372     and sending a 'change' event should do the trick.
4794 07 May 18 nicklas 373   */
4794 07 May 18 nicklas 374   search.setLibPlateFilter = function(event)
4794 07 May 18 nicklas 375   {
4794 07 May 18 nicklas 376     var libplate = Data.get(event.currentTarget, 'libplate');
4794 07 May 18 nicklas 377     var frm = document.forms['reggie'];
4794 07 May 18 nicklas 378     Forms.selectListOption(frm.libPlateFilter, libplate);
4794 07 May 18 nicklas 379     Events.sendChangeEvent(frm.libPlateFilter);
4794 07 May 18 nicklas 380   }
4794 07 May 18 nicklas 381
4794 07 May 18 nicklas 382   
4797 08 May 18 nicklas 383   search.updateTable = function(noContextAnalysis)
4794 07 May 18 nicklas 384   {
4794 07 May 18 nicklas 385     var frm = document.forms['reggie'];
4794 07 May 18 nicklas 386     
4794 07 May 18 nicklas 387     var stepTitle = 'Flagged alignments';
4794 07 May 18 nicklas 388     var filter = null;
4975 21 Sep 18 nicklas 389     var filterType = null;
4794 07 May 18 nicklas 390     var positionProperty = null;
4794 07 May 18 nicklas 391     var highHetFilter = false;
4794 07 May 18 nicklas 392     var qiacubefilter = false;
4794 07 May 18 nicklas 393     var libplatefilter = false;
4794 07 May 18 nicklas 394     var qiaCube = null;
4794 07 May 18 nicklas 395     var libPlate = null;
4794 07 May 18 nicklas 396     
4794 07 May 18 nicklas 397     if (Doc.element('highHetFilter').checked)
4794 07 May 18 nicklas 398     {
7209 26 May 23 nicklas 399       tumors.sort(Sort.sortTumorsByLibPlatePosition);
4794 07 May 18 nicklas 400       highHetFilter = true;
4817 21 May 18 nicklas 401       filter = Filter.hetFilter(65);
4975 21 Sep 18 nicklas 402       filterType = 'HET';
4975 21 Sep 18 nicklas 403       positionProperty = Property.LibPlatePosition;
4817 21 May 18 nicklas 404       stepTitle = 'Alignments with HET &gt; 65%';
4794 07 May 18 nicklas 405     }
4794 07 May 18 nicklas 406     else if (frm.qiaCubeFilter.selectedIndex > 0)
4794 07 May 18 nicklas 407     {
7209 26 May 23 nicklas 408       tumors.sort(Sort.sortTumorsByQiaCubePosition);
4794 07 May 18 nicklas 409       qiaCube = frm.qiaCubeFilter[frm.qiaCubeFilter.selectedIndex].qiaCube;
4797 08 May 18 nicklas 410       qiacubefilter = qiaCube.name;
4794 07 May 18 nicklas 411       filter = Filter.qiaCubeFilter(qiaCube.name);
4975 21 Sep 18 nicklas 412       filterType = 'QIACUBE';
4794 07 May 18 nicklas 413       positionProperty = Property.QiaCubePosition;
4794 07 May 18 nicklas 414       stepTitle = 'Alignments related to QiaCube ' + qiaCube.title;
4794 07 May 18 nicklas 415     }
4794 07 May 18 nicklas 416     else if (frm.libPlateFilter.selectedIndex > 0)
4794 07 May 18 nicklas 417     {
7209 26 May 23 nicklas 418       tumors.sort(Sort.sortTumorsByLibPlatePosition);
4794 07 May 18 nicklas 419       libPlate = frm.libPlateFilter[frm.libPlateFilter.selectedIndex].libPlate;
4797 08 May 18 nicklas 420       libplatefilter = libPlate.name;
4794 07 May 18 nicklas 421       filter = Filter.libPlateFilter(libPlate.name);
4975 21 Sep 18 nicklas 422       filterType = 'LIBPLATE';
4794 07 May 18 nicklas 423       positionProperty = Property.LibPlatePosition;
4794 07 May 18 nicklas 424       stepTitle = 'Alignments related to ' + libPlate.name;
4794 07 May 18 nicklas 425     }
4794 07 May 18 nicklas 426     else
4794 07 May 18 nicklas 427     {
4794 07 May 18 nicklas 428       // No filter
7209 26 May 23 nicklas 429       tumors.sort(Sort.sortTumorsByQiaCubePosition);
4794 07 May 18 nicklas 430     }
4794 07 May 18 nicklas 431     
4975 21 Sep 18 nicklas 432     if (filter && positionProperty && !noContextAnalysis && !highHetFilter)
4794 07 May 18 nicklas 433     {
4794 07 May 18 nicklas 434       search.contextAnalysis(filter, positionProperty);
4794 07 May 18 nicklas 435     }
4794 07 May 18 nicklas 436
4794 07 May 18 nicklas 437     var filtered = [];
4794 07 May 18 nicklas 438     var tbody = [];
4794 07 May 18 nicklas 439     if (filter)
4794 07 May 18 nicklas 440     {
4794 07 May 18 nicklas 441       var lastPos = null;
4817 21 May 18 nicklas 442       var lastStartTb = null;
7209 26 May 23 nicklas 443       for (var itemNo = 0; itemNo < tumors.length; itemNo++)
4794 07 May 18 nicklas 444       {
7209 26 May 23 nicklas 445         var tumor = tumors[itemNo];
7209 26 May 23 nicklas 446         if (filter(tumor)) 
4794 07 May 18 nicklas 447         {
7209 26 May 23 nicklas 448           filtered[filtered.length] = tumor;
4817 21 May 18 nicklas 449           var tb = { 'start': 1, 'end': 1 }; // The default is to start a new <tbody> section for each alignment
7209 26 May 23 nicklas 450           tb.rowspan = tumor.compare ? (tumor.compare.messages.length || 1) : 1; // A <tbody> typically spans over number-or-messages rows
4817 21 May 18 nicklas 451           tb.tbodyspan = tb.rowspan;
4794 07 May 18 nicklas 452           tbody[tbody.length] = tb;
4794 07 May 18 nicklas 453           if (positionProperty)
4794 07 May 18 nicklas 454           {
7209 26 May 23 nicklas 455             var pos = positionProperty(tumor);
4794 07 May 18 nicklas 456             if (pos == lastPos)
4794 07 May 18 nicklas 457             {
4817 21 May 18 nicklas 458               // If we are at the same position, we should not start a new <tbody> section
4817 21 May 18 nicklas 459               // Adjust properties accordingly
4794 07 May 18 nicklas 460               tbody[tbody.length-2].end = 0;
4794 07 May 18 nicklas 461               tb.start = 0;
4817 21 May 18 nicklas 462               lastStartTb.tbodyspan += tb.rowspan;
4794 07 May 18 nicklas 463             }
4817 21 May 18 nicklas 464             else
4817 21 May 18 nicklas 465             {
4817 21 May 18 nicklas 466               // New position in the context
4817 21 May 18 nicklas 467               lastPos = pos;
4817 21 May 18 nicklas 468               lastStartTb = tb;
4817 21 May 18 nicklas 469             }
4794 07 May 18 nicklas 470           }
4794 07 May 18 nicklas 471         }
4794 07 May 18 nicklas 472       }
4794 07 May 18 nicklas 473     }
4794 07 May 18 nicklas 474     else
4794 07 May 18 nicklas 475     {
7209 26 May 23 nicklas 476       filtered = tumors;
4794 07 May 18 nicklas 477     }
4794 07 May 18 nicklas 478     
4794 07 May 18 nicklas 479     var html = '';
4818 22 May 18 nicklas 480     
4818 22 May 18 nicklas 481     if (filter)
4818 22 May 18 nicklas 482     {
4818 22 May 18 nicklas 483       html += '<thead class="mode-reprocess"><tr>';
4970 13 Sep 18 nicklas 484       html += '<th colspan="4"></th>';
4970 13 Sep 18 nicklas 485       html += '<th colspan="3" class="mode-reprocess-header">Remaining quantity</th>';
4970 13 Sep 18 nicklas 486       html += '<th colspan="10"></th>';
4818 22 May 18 nicklas 487       html += '</tr></thead>';
4818 22 May 18 nicklas 488     }
4818 22 May 18 nicklas 489     
4794 07 May 18 nicklas 490     html += '<thead class="bg-filled-100">';
4794 07 May 18 nicklas 491     html += '<tr>';
4794 07 May 18 nicklas 492     html += '<th>Patient</th>';
4970 13 Sep 18 nicklas 493     html += '<th class="'+(qiacubefilter?'':'mode-genotype')+'">QiaCube</th>';
4970 13 Sep 18 nicklas 494     html += '<th class="'+(libplatefilter||highHetFilter?'':'mode-genotype')+'">LibPlate</th>';
4794 07 May 18 nicklas 495     html += '<th>HET</th>';
4794 07 May 18 nicklas 496     html += '<th>Alignment</th>';
4817 21 May 18 nicklas 497     if (filter)
4817 21 May 18 nicklas 498     {
4817 21 May 18 nicklas 499       html += '<th class="mode-reprocess dottedleft num-col">Specimen<br>(mg)</th>';
4817 21 May 18 nicklas 500       html += '<th class="mode-reprocess num-col">Lysate<br>(µl)</th>';
4817 21 May 18 nicklas 501       html += '<th class="mode-reprocess num-col">RNA<br>(µg)</th>';
4970 13 Sep 18 nicklas 502       html += '<th class="mode-reprocess" id="reprocess-header">Re-process</th>';
4981 25 Sep 18 nicklas 503       // Note! "mode-resolve" columns here to get the same order for grouping
4981 25 Sep 18 nicklas 504       html += '<th class="mode-resolve dottedleft">Ok</th>';
4982 26 Sep 18 nicklas 505       html += '<th class="mode-resolve" colspan="2">DoNotUse<span style="float:right;">FutureGT</span></th>';
4976 24 Sep 18 nicklas 506       html += '<th class="mode-resolve comment-col">Comment</th>';
4976 24 Sep 18 nicklas 507
4970 13 Sep 18 nicklas 508       html += '<th class="mode-reprocess comment-col">Comment</th>';
4970 13 Sep 18 nicklas 509       html += '<th class="mode-reprocess flag-col dottedright">Flag</th>';
4817 21 May 18 nicklas 510     }
4817 21 May 18 nicklas 511     html += '<th></th>';
4794 07 May 18 nicklas 512     html += '<th class="dottedleft" colspan="2">Warnings and messages</th>';
6589 21 Feb 22 nicklas 513     html += '<th class="dottedleft">Alignment/GenotypeCall</th>';
7209 26 May 23 nicklas 514     html += '<th>Pipeline</th>';
4794 07 May 18 nicklas 515     html += '<th>HET</th>';
4817 21 May 18 nicklas 516     html += '<th class="mode-genotype">QiaCube</th>';
7209 26 May 23 nicklas 517     html += '<th class="mode-genotype">Plate/Chip</th>';
4794 07 May 18 nicklas 518     html += '<th>Patient</th>';
4794 07 May 18 nicklas 519     html += '</tr>';
4794 07 May 18 nicklas 520     html += '</thead>';
4794 07 May 18 nicklas 521     
4794 07 May 18 nicklas 522     var numListed = 0;
4794 07 May 18 nicklas 523     for (var itemNo = 0; itemNo < filtered.length; itemNo++)
4794 07 May 18 nicklas 524     {
7209 26 May 23 nicklas 525       var tumor = filtered[itemNo];
7209 26 May 23 nicklas 526       var cmp = tumor.compare;
7209 26 May 23 nicklas 527       var lib = tumor.lib;
7209 26 May 23 nicklas 528       var rna = tumor.rna;
7209 26 May 23 nicklas 529       var lys = tumor.lysate;
7209 26 May 23 nicklas 530       var sp = tumor.specimen;
4976 24 Sep 18 nicklas 531       var recommendReprocess = false;
4976 24 Sep 18 nicklas 532       var recommendDoNotUse = false;
4817 21 May 18 nicklas 533       
4818 22 May 18 nicklas 534       var libPlate = lib ? lib.bioWell.bioPlate : null;
4794 07 May 18 nicklas 535       numListed++;
4794 07 May 18 nicklas 536
4794 07 May 18 nicklas 537       var tb = tbody[itemNo] || { 'start': 1, 'end': 1 };
4980 25 Sep 18 nicklas 538       var rowspan = tb.rowspan || (cmp ? cmp.messages.length : 0) || 1;
4817 21 May 18 nicklas 539       var tbodySpan = tb.tbodyspan || rowspan;
4794 07 May 18 nicklas 540       
4794 07 May 18 nicklas 541       if (!tb.start)
4794 07 May 18 nicklas 542       {
4817 21 May 18 nicklas 543         html += '<tr class="dotted-above">';
4794 07 May 18 nicklas 544       }
4817 21 May 18 nicklas 545       else
4817 21 May 18 nicklas 546       {
4976 24 Sep 18 nicklas 547         // Try to give a re-process recommendation based on the assumption that the
4976 24 Sep 18 nicklas 548         // current alignment is incorrect. We look for other alignments from the same
4976 24 Sep 18 nicklas 549         // patient and specimen but with either a different RNA or Library
7209 26 May 23 nicklas 550         if (filter && tumor.flagged && !tumor.QC_GENOTYPE_VERIFIED && sp)
4976 24 Sep 18 nicklas 551         {
4976 24 Sep 18 nicklas 552           recommendReprocess = true; 
7209 26 May 23 nicklas 553           var otherTumors = tumorsByPat[sp.patientName];
7209 26 May 23 nicklas 554           for (var otherNo = 0; otherNo < otherTumors.length; otherNo++)
4976 24 Sep 18 nicklas 555           {
7209 26 May 23 nicklas 556             var otherT = otherTumors[otherNo];        
7209 26 May 23 nicklas 557             if (otherT.bugged && otherT.buglevel > 0) continue; // Ignore items that we "know" to be incorrect
4976 24 Sep 18 nicklas 558             
7209 26 May 23 nicklas 559             var sameLib = otherT.lib && otherT.lib.id == lib.id;
7209 26 May 23 nicklas 560             var sameRNA = otherT.rna && otherT.rna.id == rna.id;
7209 26 May 23 nicklas 561             var sameSp = otherT.specimen && otherT.specimen.id == sp.id;
4976 24 Sep 18 nicklas 562             if (sameSp)
4976 24 Sep 18 nicklas 563             {
4976 24 Sep 18 nicklas 564               if (!sameRNA && qiacubefilter || !sameLib && (libplatefilter || highHetFilter)) 
4976 24 Sep 18 nicklas 565               {
4976 24 Sep 18 nicklas 566                 recommendReprocess = false;
4976 24 Sep 18 nicklas 567               }
4976 24 Sep 18 nicklas 568               if (!sameLib && highHetFilter) recommendDoNotUse = true;
4976 24 Sep 18 nicklas 569             }
4976 24 Sep 18 nicklas 570           }
4976 24 Sep 18 nicklas 571         }
4976 24 Sep 18 nicklas 572         
7209 26 May 23 nicklas 573         html += '<tbody class="highlight'+(recommendReprocess ? ' recommend-reprocess' : '')+(recommendDoNotUse ? ' recommend-donotuse' : '')+'" id="section.'+tumor.tmpId+'"><tr>';
4818 22 May 18 nicklas 574         html += '<td rowspan="'+tbodySpan+'">'+(sp ? HTMLHelper.colorMatch(sp.patientName, null, 'Click to highlight this patient') : '')+'</td>';
4970 13 Sep 18 nicklas 575         html += '<td rowspan="'+tbodySpan+'" class="'+(qiacubefilter?'':'mode-genotype')+'">'+(sp ? HTMLHelper.qiaCubeLink(rna.QIACUBE_DATE, rna.QIACUBE_RUN_NO, rna.QIACUBE_POSITION, qiacubefilter, false) : '')+'</td>';
4975 21 Sep 18 nicklas 576         if (!qiacubefilter)
4817 21 May 18 nicklas 577         {
4818 22 May 18 nicklas 578           html += '<td rowspan="'+tbodySpan+'">'+(libPlate ? HTMLHelper.libPlateLink(libPlate.name, lib.bioWell.location, libplatefilter, false):'')+'</td>';
4817 21 May 18 nicklas 579         }
4817 21 May 18 nicklas 580       }
4794 07 May 18 nicklas 581       
7209 26 May 23 nicklas 582       var tmp = search.getAlignmentHtml(tumor);
4794 07 May 18 nicklas 583       
4975 21 Sep 18 nicklas 584       if (qiacubefilter)
4794 07 May 18 nicklas 585       {
4975 21 Sep 18 nicklas 586         html += '<td rowspan="'+rowspan+'" class="mode-genotype">'+(libPlate ? HTMLHelper.libPlateLink(libPlate.name, lib.bioWell.location, libplatefilter, false):'')+'</td>';
4794 07 May 18 nicklas 587       }
7209 26 May 23 nicklas 588       html += '<td rowspan="'+rowspan+'">'+Reggie.formatNumber(tumor.QC_GENOTYPE_HET_PCT, '%', -1)+'</td>';
4817 21 May 18 nicklas 589       html += '<td rowspan="'+rowspan+'" class="text-col">'+tmp.name+'</td>';
4970 13 Sep 18 nicklas 590       if (filter)
4817 21 May 18 nicklas 591       {
4970 13 Sep 18 nicklas 592         if (tb.start)
4970 13 Sep 18 nicklas 593         {
4970 13 Sep 18 nicklas 594           html += '<td rowspan="'+tbodySpan+'" class="mode-reprocess dottedleft num-col">'+(sp ? Reggie.formatNumber(sp.remainingQuantity/1000, null, 1, 1) : '')+'</td>';
4970 13 Sep 18 nicklas 595           html += '<td rowspan="'+tbodySpan+'" class="mode-reprocess num-col">'+(lys ? Math.round(lys.remainingQuantity) : '')+'</td>';
4970 13 Sep 18 nicklas 596           html += '<td rowspan="'+tbodySpan+'" class="mode-reprocess num-col">'+(sp ? Reggie.formatNumber(rna.remainingQuantity, null, 2, 2) : '')+'</td>';
7209 26 May 23 nicklas 597           html += '<td rowspan="'+tbodySpan+'" class="mode-reprocess reprocess-col editable">'+(sp ? HTMLHelper.reprocessOptions(tumor, recommendReprocess) : '')+'</td>';
4975 21 Sep 18 nicklas 598
7209 26 May 23 nicklas 599           html += '<td rowspan="'+tbodySpan+'" class="mode-resolve dottedleft editable">'+(sp ? HTMLHelper.okToUseOptions(tumor, filterType) : '')+'</td>';
7209 26 May 23 nicklas 600           html += '<td rowspan="'+tbodySpan+'" class="mode-resolve editable">'+(sp ? HTMLHelper.resolveOptions(tumor, filterType, tbodySpan==rowspan) : '')+'</td>';
7209 26 May 23 nicklas 601           html += '<td rowspan="'+tbodySpan+'" class="mode-resolve editable">'+(sp ? HTMLHelper.futureGtOptions(tumor, filterType) : '')+'</td>';
7209 26 May 23 nicklas 602           html += '<td rowspan="'+tbodySpan+'" class="mode-resolve comment-col dottedright editable">'+(sp ? HTMLHelper.resolveComment(tumor) : '')+'</td>';
4970 13 Sep 18 nicklas 603         }
4970 13 Sep 18 nicklas 604         
7209 26 May 23 nicklas 605         var flagged = tumor.flagged;
7209 26 May 23 nicklas 606         var isTumor = tumor.name;
7209 26 May 23 nicklas 607         html += '<td rowspan="'+rowspan+'" class="mode-reprocess comment-col editable">'+(isTumor ? HTMLHelper.qcCommentInput(tumor) : '')+'</td>';        
7209 26 May 23 nicklas 608         html += '<td rowspan="'+rowspan+'" class="mode-reprocess flag-col dottedright editable">'+(isTumor && sp && !flagged ? HTMLHelper.qcFlagCheckbox(tumor) : '')+'</td>';
4817 21 May 18 nicklas 609       }
4817 21 May 18 nicklas 610       html += '<td rowspan="'+rowspan+'" class="icon-col">'+tmp.icons+'</td>';
4817 21 May 18 nicklas 611
4817 21 May 18 nicklas 612       html += '<td rowspan="'+rowspan+'" class="dottedleft bg-messages">'+tmp.tooltip+'</td>';
4794 07 May 18 nicklas 613       // The first message is on the main <tr>
4818 22 May 18 nicklas 614       if (cmp && cmp.messages.length > 0)
4794 07 May 18 nicklas 615       {
4794 07 May 18 nicklas 616         var msg = cmp.messages[0];
7209 26 May 23 nicklas 617         html += search.getMessageHtml(msg, tumor, assaysByName, qiacubefilter, libplatefilter);
4794 07 May 18 nicklas 618       }
4794 07 May 18 nicklas 619       else
4794 07 May 18 nicklas 620       {
7209 26 May 23 nicklas 621         html += '<td class="bg-messages"></td><td class="dottedleft" colspan="6"></td>';
4794 07 May 18 nicklas 622       }
4817 21 May 18 nicklas 623       html += '</tr>';
4794 07 May 18 nicklas 624       
4794 07 May 18 nicklas 625       // If there are more messages, add more <tr>
4818 22 May 18 nicklas 626       if (cmp)
4794 07 May 18 nicklas 627       {
4818 22 May 18 nicklas 628         for (var mNo = 1; mNo < cmp.messages.length; mNo++)
4818 22 May 18 nicklas 629         {
4818 22 May 18 nicklas 630           var msg = cmp.messages[mNo];
7209 26 May 23 nicklas 631           html += '<tr>'+search.getMessageHtml(msg, tumor, assaysByName, qiacubefilter, libplatefilter) + '</tr>';
4818 22 May 18 nicklas 632         }
4794 07 May 18 nicklas 633       }
4794 07 May 18 nicklas 634       
4794 07 May 18 nicklas 635       if (tb.end)
4794 07 May 18 nicklas 636       {
4794 07 May 18 nicklas 637         html += '</tbody>';
4794 07 May 18 nicklas 638       }
4794 07 May 18 nicklas 639     }
4794 07 May 18 nicklas 640     
5005 04 Oct 18 nicklas 641     if (numListed == 0)
5005 04 Oct 18 nicklas 642     {
5005 04 Oct 18 nicklas 643       html += '<tbody><tr><td colspan="20">No alignments matched the filter</td></tr></tbody>';
5005 04 Oct 18 nicklas 644       Doc.element('mode-genotype').checked = true;
5005 04 Oct 18 nicklas 645     }
5005 04 Oct 18 nicklas 646     
4794 07 May 18 nicklas 647     Doc.element('itemTable').innerHTML = html;
4794 07 May 18 nicklas 648     Doc.element('step-1-title').innerHTML = stepTitle + ' (' + numListed + ')';
4794 07 May 18 nicklas 649     
4794 07 May 18 nicklas 650     Doc.show('step-1');
4817 21 May 18 nicklas 651     
5005 04 Oct 18 nicklas 652     var enableReprocess = numListed > 0 && filter && !noContextAnalysis;
4975 21 Sep 18 nicklas 653     var enableResolve = enableReprocess;
4817 21 May 18 nicklas 654     Doc.element('mode-reprocess').disabled = !enableReprocess;
4975 21 Sep 18 nicklas 655     Doc.element('mode-resolve').disabled = !enableResolve;
4817 21 May 18 nicklas 656     search.modeOnChange();
4794 07 May 18 nicklas 657
4794 07 May 18 nicklas 658     var cs = document.getElementsByClassName('case-summary');
4794 07 May 18 nicklas 659     for (var i = 0; i < cs.length; i++)
4794 07 May 18 nicklas 660     {
5019 10 Oct 18 nicklas 661       Events.addEventHandler(cs[i], 'click', Reggie.openCaseSummaryPopupOnEvent);
4794 07 May 18 nicklas 662     }
4794 07 May 18 nicklas 663     
4794 07 May 18 nicklas 664     var lnk = document.getElementsByClassName('qiacube-link');
4794 07 May 18 nicklas 665     for (var i = 0; i < lnk.length; i++)
4794 07 May 18 nicklas 666     {
4794 07 May 18 nicklas 667       Events.addEventHandler(lnk[i], 'click', search.setQiaCubeFilter);
4794 07 May 18 nicklas 668     }
4794 07 May 18 nicklas 669     var lnk = document.getElementsByClassName('libplate-link');
4794 07 May 18 nicklas 670     for (var i = 0; i < lnk.length; i++)
4794 07 May 18 nicklas 671     {
4794 07 May 18 nicklas 672       Events.addEventHandler(lnk[i], 'click', search.setLibPlateFilter);
4794 07 May 18 nicklas 673     }
4794 07 May 18 nicklas 674     
4794 07 May 18 nicklas 675     var cm = document.getElementsByClassName('colormatch');
4794 07 May 18 nicklas 676     for (var i = 0; i < cm.length; i++)
4794 07 May 18 nicklas 677     {
4794 07 May 18 nicklas 678       Events.addEventHandler(cm[i], 'click', search.colorMatch);
4794 07 May 18 nicklas 679     }
4975 21 Sep 18 nicklas 680     
4980 25 Sep 18 nicklas 681     var options = document.getElementsByClassName('reprocess-options');
4980 25 Sep 18 nicklas 682     for (var i = 0; i < options.length; i++)
4980 25 Sep 18 nicklas 683     {
4980 25 Sep 18 nicklas 684       Events.addEventHandler(options[i], 'change', search.reprocessOptionOnChange);
4980 25 Sep 18 nicklas 685     }
4980 25 Sep 18 nicklas 686     
4975 21 Sep 18 nicklas 687     var options = document.getElementsByClassName('donotuse-options');
4975 21 Sep 18 nicklas 688     for (var i = 0; i < options.length; i++)
4975 21 Sep 18 nicklas 689     {
4975 21 Sep 18 nicklas 690       Events.addEventHandler(options[i], 'change', search.doNotUseOptionOnChange);
4975 21 Sep 18 nicklas 691     }
4975 21 Sep 18 nicklas 692
4975 21 Sep 18 nicklas 693     var checks = document.getElementsByClassName('oktouse');
4975 21 Sep 18 nicklas 694     for (var i = 0; i < checks.length; i++)
4975 21 Sep 18 nicklas 695     {
4975 21 Sep 18 nicklas 696       Events.addEventHandler(checks[i], 'change', search.okToUseOnChange);
4975 21 Sep 18 nicklas 697     }
5001 04 Oct 18 nicklas 698     
5001 04 Oct 18 nicklas 699     // Reset the change detection flags.
5001 04 Oct 18 nicklas 700     Wizard.setNoConfirmOnFirstStep(true);
5001 04 Oct 18 nicklas 701     numChangedFormElements = 0;
4794 07 May 18 nicklas 702   }
4794 07 May 18 nicklas 703   
4794 07 May 18 nicklas 704   
4794 07 May 18 nicklas 705   /**
4794 07 May 18 nicklas 706     Primary analysis of of problems related to alignments that
4794 07 May 18 nicklas 707     can be determined without knowledge of context and without need
4794 07 May 18 nicklas 708     to find information about related (same patient) alignments.
4794 07 May 18 nicklas 709   */
4794 07 May 18 nicklas 710   search.primaryAnalysis = function()
4794 07 May 18 nicklas 711   {
4794 07 May 18 nicklas 712     // Reset this mapping, since we are only interested in alignments in the 
4794 07 May 18 nicklas 713     // current context (eg. QiaCube run or LibPlate)
7209 26 May 23 nicklas 714     tumorsByPat = {};
4794 07 May 18 nicklas 715     
7209 26 May 23 nicklas 716     for (var itemNo = 0; itemNo < tumors.length; itemNo++)
4794 07 May 18 nicklas 717     {
7209 26 May 23 nicklas 718       var tumor = tumors[itemNo];
4818 22 May 18 nicklas 719
4794 07 May 18 nicklas 720       // Reset bug info
7209 26 May 23 nicklas 721       tumor.tmpId = itemNo; // Just to give each item a unique identified that we can use in gui form elements
7209 26 May 23 nicklas 722       tumor.bugged = 0;
7209 26 May 23 nicklas 723       tumor.buglevel = 0;
7209 26 May 23 nicklas 724       tumor.bugText = [];
4980 25 Sep 18 nicklas 725       
4818 22 May 18 nicklas 726       // We need to be able to lookup alignments by name and patient name
7209 26 May 23 nicklas 727       if (!tumor.specimen)
4821 23 May 18 nicklas 728       {
7209 26 May 23 nicklas 729         tumor.bugText[tumor.bugText.length] = 'External';
4821 23 May 18 nicklas 730       }
4823 24 May 18 nicklas 731       else
4821 23 May 18 nicklas 732       {
7209 26 May 23 nicklas 733         var patName = tumor.specimen.patientName;
7209 26 May 23 nicklas 734         var tumorsForPat = tumorsByPat[patName] || [];
7209 26 May 23 nicklas 735         if (tumorsForPat.length == 0) tumorsByPat[patName] = tumorsForPat;
7209 26 May 23 nicklas 736         tumorsForPat[tumorsForPat.length] = tumor;
4818 22 May 18 nicklas 737       }
7209 26 May 23 nicklas 738       if (tumor.name)
4823 24 May 18 nicklas 739       {
7209 26 May 23 nicklas 740         assaysByName[tumor.name] = tumor;
7209 26 May 23 nicklas 741         if (tumor.QC_GENOTYPE_STATUS != 'Checked')
4823 24 May 18 nicklas 742         {
7209 26 May 23 nicklas 743           tumor.bugText[tumor.bugText.length] = 'Genotyping is disabled for this alignment';
4823 24 May 18 nicklas 744         }
4823 24 May 18 nicklas 745       }
4823 24 May 18 nicklas 746       else
4823 24 May 18 nicklas 747       {
7209 26 May 23 nicklas 748         tumor.bugText[tumor.bugText.length] = tumor.lib ? 
4823 24 May 18 nicklas 749           'No alignment from this Library' : 'No alignment from this RNA';
7209 26 May 23 nicklas 750         var libOrRna = tumor.lib || tumor.rna || {};
4980 25 Sep 18 nicklas 751         // Copy DO_NOT_USE information to make it easier to handle in other places
7209 26 May 23 nicklas 752         tumor.DO_NOT_USE = libOrRna.DO_NOT_USE;
7209 26 May 23 nicklas 753         tumor.DO_NOT_USE_COMMENT = libOrRna.DO_NOT_USE_COMMENT
4823 24 May 18 nicklas 754       }
4818 22 May 18 nicklas 755       
7209 26 May 23 nicklas 756       var cmp = tumor.compare;
4818 22 May 18 nicklas 757       if (cmp)
4818 22 May 18 nicklas 758       {
4818 22 May 18 nicklas 759         if (cmp.hasVerifiedMismatch)
4818 22 May 18 nicklas 760         {
7209 26 May 23 nicklas 761           tumor.bugged = 1;
7209 26 May 23 nicklas 762           if (tumor.QC_GENOTYPE_VERIFIED)
4818 22 May 18 nicklas 763           {
4818 22 May 18 nicklas 764             // This is strange -- two VERIFIED alignments with a mismatch!!
7209 26 May 23 nicklas 765             tumor.buglevel = 2;
7209 26 May 23 nicklas 766             tumor.bugText[tumor.bugText.length] = 'Verified Ã— 2 mismatch!!';
4818 22 May 18 nicklas 767           }
4818 22 May 18 nicklas 768           else
4818 22 May 18 nicklas 769           {
7209 26 May 23 nicklas 770             tumor.buglevel = 1;
7209 26 May 23 nicklas 771             tumor.bugText[tumor.bugText.length] = 'Verified mismatch';
4818 22 May 18 nicklas 772           }
4818 22 May 18 nicklas 773         }
4818 22 May 18 nicklas 774       }
4818 22 May 18 nicklas 775       
7209 26 May 23 nicklas 776       if (tumor.QC_GENOTYPE_HET_PCT > 65 && !tumor.QC_GENOTYPE_VERIFIED)
4797 08 May 18 nicklas 777       {
7209 26 May 23 nicklas 778         tumor.bugged = 1;
7209 26 May 23 nicklas 779         tumor.buglevel = 1;
7209 26 May 23 nicklas 780         tumor.bugText[tumor.bugText.length] = 'High HET';
4797 08 May 18 nicklas 781       }
4980 25 Sep 18 nicklas 782       
7209 26 May 23 nicklas 783       if (tumor.DO_NOT_USE)
4980 25 Sep 18 nicklas 784       {
5024 15 Oct 18 nicklas 785         var doNotUseFlags = {};
7209 26 May 23 nicklas 786         doNotUseFlags[tumor.DO_NOT_USE] = 1;
7209 26 May 23 nicklas 787         tumor.bugText[tumor.bugText.length] = search.doNotUseMessage(tumor);
7209 26 May 23 nicklas 788         search.addDoNotUseMessageIfDifferent(tumor, tumor.lib, doNotUseFlags);
7209 26 May 23 nicklas 789         search.addDoNotUseMessageIfDifferent(tumor, tumor.rna, doNotUseFlags);
7209 26 May 23 nicklas 790         search.addDoNotUseMessageIfDifferent(tumor, tumor.lysate, doNotUseFlags);
7209 26 May 23 nicklas 791         search.addDoNotUseMessageIfDifferent(tumor, tumor.specimen, doNotUseFlags);
7209 26 May 23 nicklas 792         if (!tumor.bugged)
4980 25 Sep 18 nicklas 793         {
7209 26 May 23 nicklas 794           tumor.bugged = 1;
7209 26 May 23 nicklas 795           tumor.buglevel = 1;
4980 25 Sep 18 nicklas 796         }
4980 25 Sep 18 nicklas 797       }
4980 25 Sep 18 nicklas 798       
4997 03 Oct 18 nicklas 799       // Copy information about current re-processing flag to the 'alignment' object to make it easier to find later
4997 03 Oct 18 nicklas 800       var currentReProcess = null;
7209 26 May 23 nicklas 801       if (tumor.specimen && tumor.specimen.AutoProcessing == 'ReProcess')
4997 03 Oct 18 nicklas 802       {
4997 03 Oct 18 nicklas 803         currentReProcess = 'Specimen';
4997 03 Oct 18 nicklas 804       }
7209 26 May 23 nicklas 805       else if (tumor.lysate && tumor.lysate.AutoProcessing == 'ReProcess')
4997 03 Oct 18 nicklas 806       {
4997 03 Oct 18 nicklas 807         currentReProcess = 'Lysate';
4997 03 Oct 18 nicklas 808       }
7209 26 May 23 nicklas 809       else if (tumor.rna && tumor.rna.AutoProcessing == 'ReProcess')
4997 03 Oct 18 nicklas 810       {
4997 03 Oct 18 nicklas 811         currentReProcess = 'RNA';
4997 03 Oct 18 nicklas 812       }
7209 26 May 23 nicklas 813       tumor.currentReProcess = currentReProcess;
4794 07 May 18 nicklas 814     }
4794 07 May 18 nicklas 815   }
4794 07 May 18 nicklas 816   
5024 15 Oct 18 nicklas 817   search.doNotUseMessage = function(item)
5024 15 Oct 18 nicklas 818   {
5024 15 Oct 18 nicklas 819     return '<span class="donotuse">['+Strings.encodeTags(item.DO_NOT_USE)+']</span> ' + Strings.encodeTags(item.DO_NOT_USE_COMMENT);
5024 15 Oct 18 nicklas 820   }
4794 07 May 18 nicklas 821   
5024 15 Oct 18 nicklas 822   // Add 'bugtext' messages about DO_NOT_USE, but only one message for each reason
7209 26 May 23 nicklas 823   search.addDoNotUseMessageIfDifferent = function(tumor, item, doNotUseFlags)
5024 15 Oct 18 nicklas 824   {
5416 09 May 19 nicklas 825     if (item && item.DO_NOT_USE && !doNotUseFlags[item.DO_NOT_USE])
5024 15 Oct 18 nicklas 826     {
5024 15 Oct 18 nicklas 827       doNotUseFlags[item.DO_NOT_USE] = 1;
7209 26 May 23 nicklas 828       tumor.bugText[tumor.bugText.length] = search.doNotUseMessage(item);
5024 15 Oct 18 nicklas 829     }
5024 15 Oct 18 nicklas 830   }
5024 15 Oct 18 nicklas 831   
4794 07 May 18 nicklas 832   /**
4794 07 May 18 nicklas 833     Analysis of problems related to a given context (eg. a QiaCube or LibPlate).
4794 07 May 18 nicklas 834     The context is given by a all alignments matching the given filter.
4794 07 May 18 nicklas 835     
4794 07 May 18 nicklas 836     1. For each alignment in the context we will search for a LOW_MISMATCH warning.
4794 07 May 18 nicklas 837     2. A LOW_MISMATCH means that we have two similar alignments that have different patients (very unlikely!)
4794 07 May 18 nicklas 838     3. So, we take that other patient and search for other alignments in the given context that
4794 07 May 18 nicklas 839        have the same patient.
4794 07 May 18 nicklas 840     4. If we find another alignment this could be a possible mixup with that position.
4794 07 May 18 nicklas 841   */
4794 07 May 18 nicklas 842   search.contextAnalysis = function(filter, positionProperty)
4794 07 May 18 nicklas 843   {
7209 26 May 23 nicklas 844     for (var itemNo = 0; itemNo < tumors.length; itemNo++)
4794 07 May 18 nicklas 845     {
7209 26 May 23 nicklas 846       var tumor = tumors[itemNo];
7209 26 May 23 nicklas 847       if (!tumor.compare) continue; // No alignment/genotype data in this position, skip ahead
4818 22 May 18 nicklas 848       
7209 26 May 23 nicklas 849       var filterValue = filter(tumor);
4794 07 May 18 nicklas 850       if (filterValue == null) continue; // Not in the given context
4794 07 May 18 nicklas 851       
7209 26 May 23 nicklas 852       var cmp = tumor.compare;
4794 07 May 18 nicklas 853       var possiblePositions = [];
4794 07 May 18 nicklas 854       var possiblePats = [];
4794 07 May 18 nicklas 855       
4794 07 May 18 nicklas 856       for (var mNo = 0; mNo < cmp.messages.length; mNo++)
4794 07 May 18 nicklas 857       {
4794 07 May 18 nicklas 858         var msg = cmp.messages[mNo];
4794 07 May 18 nicklas 859         if (msg.category != 'LOW_MISMATCH') continue; // We are only interested in 'LOW_MISMATCH' warnings
4794 07 May 18 nicklas 860         
6589 21 Feb 22 nicklas 861         var otherA = assaysByName[msg.otherAssay];
6589 21 Feb 22 nicklas 862         if (!otherA) continue;
6589 21 Feb 22 nicklas 863         if (otherA.bugged && otherA.buglevel > 0) continue; // The other assay is a known problem, so we ignore it here
4794 07 May 18 nicklas 864         
4794 07 May 18 nicklas 865         // If the other alignment is in the same context it may not be useful unless it is a verified alignment
4794 07 May 18 nicklas 866         if (filter(otherA) && !otherA.QC_GENOTYPE_VERIFIED) continue;
4794 07 May 18 nicklas 867         
4794 07 May 18 nicklas 868         // This is our candidate patient
4794 07 May 18 nicklas 869         var otherPat = otherA.specimen.patientName;
4797 08 May 18 nicklas 870         
4794 07 May 18 nicklas 871         // Find alignments in the same context for the candiate patient
7209 26 May 23 nicklas 872         var tumorsForPat = tumorsByPat[otherPat] || [];
7209 26 May 23 nicklas 873         for (var i = 0; i < tumorsForPat.length; i++)
4794 07 May 18 nicklas 874         {
7209 26 May 23 nicklas 875           var otherB = tumorsForPat[i];
4794 07 May 18 nicklas 876           var posB = positionProperty(otherB);
4794 07 May 18 nicklas 877           if (filter(otherB) && possiblePositions.indexOf(posB) == -1)
4794 07 May 18 nicklas 878           {
4794 07 May 18 nicklas 879             // Save the position (eg, Plate coordinate or QiaCube position)
4794 07 May 18 nicklas 880             possiblePositions[possiblePositions.length] = posB;
4794 07 May 18 nicklas 881           }
4794 07 May 18 nicklas 882         }
4794 07 May 18 nicklas 883         if (possiblePats.indexOf(otherPat) == -1) possiblePats[possiblePats.length] = otherPat;
4794 07 May 18 nicklas 884       }
4794 07 May 18 nicklas 885       
4794 07 May 18 nicklas 886       if (possiblePositions.length > 0)
4794 07 May 18 nicklas 887       {
4794 07 May 18 nicklas 888         // If we have found other positions, we report them to the user
7209 26 May 23 nicklas 889         tumor.bugged = 1;
4794 07 May 18 nicklas 890         var text = 'Is this from ';
4794 07 May 18 nicklas 891         for (var posNo = 0; posNo < possiblePositions.length; posNo++)
4794 07 May 18 nicklas 892         {
4794 07 May 18 nicklas 893           var pos = possiblePositions[posNo];
4794 07 May 18 nicklas 894           if (posNo > 0) text += posNo == possiblePositions.length-1 ? ' or ' : ', ';
4794 07 May 18 nicklas 895           text += HTMLHelper.colorMatch(filterValue + '@' + pos, '@'+pos, 'Click to highlight this position');
4794 07 May 18 nicklas 896         }
4799 09 May 18 nicklas 897         text += '/';
4799 09 May 18 nicklas 898         for (var patNo = 0; patNo < possiblePats.length; patNo++)
4799 09 May 18 nicklas 899         {
4799 09 May 18 nicklas 900           var pat = possiblePats[patNo];
4799 09 May 18 nicklas 901           if (patNo > 0) text += patNo == possiblePats.length-1 ? ' or ' : ', ';
4799 09 May 18 nicklas 902           text += HTMLHelper.colorMatch(pat, null, 'Click to highlight this patient');
4799 09 May 18 nicklas 903         }
4794 07 May 18 nicklas 904         text += '?';
7209 26 May 23 nicklas 905         tumor.bugText[tumor.bugText.length] = text;
4794 07 May 18 nicklas 906       }
4794 07 May 18 nicklas 907       else if (possiblePats.length > 0)
4794 07 May 18 nicklas 908       {
4794 07 May 18 nicklas 909         // We found a low mismatch but not any other sample with the same patient
4794 07 May 18 nicklas 910         // The mixup is probably not in the selected context
4794 07 May 18 nicklas 911         var text = 'Could not find sample related to ';
4794 07 May 18 nicklas 912         for (var patNo = 0; patNo < possiblePats.length; patNo++)
4794 07 May 18 nicklas 913         {
4794 07 May 18 nicklas 914           var pat = possiblePats[patNo];
4794 07 May 18 nicklas 915           if (patNo > 0) text += patNo == possiblePats.length-1 ? ' or ' : ', ';
4794 07 May 18 nicklas 916           text += HTMLHelper.colorMatch(pat, null, 'Click to highlight this patient');
4794 07 May 18 nicklas 917         }
7209 26 May 23 nicklas 918         tumor.bugText[tumor.bugText.length] = text;
4794 07 May 18 nicklas 919       }
4794 07 May 18 nicklas 920     }
4794 07 May 18 nicklas 921     
4794 07 May 18 nicklas 922   }
4794 07 May 18 nicklas 923   
4794 07 May 18 nicklas 924   /**
4794 07 May 18 nicklas 925     EVent handler for highlighting related items with the same
4794 07 May 18 nicklas 926     colormatch tag. For all items tagged with 'colormatch' we highlight
4794 07 May 18 nicklas 927     all elements with the same 'match' value as the clicked element.
4799 09 May 18 nicklas 928     Two different colors are supported by holding down CTRL, ALT or SHIFT
4797 08 May 18 nicklas 929     while clicking.
4794 07 May 18 nicklas 930   */
4794 07 May 18 nicklas 931   search.colorMatch = function(event)
4794 07 May 18 nicklas 932   {
4799 09 May 18 nicklas 933     var toMatch = Data.get(event.currentTarget, 'match');
4797 08 May 18 nicklas 934     var specialKey = event.altKey || event.ctrlKey || event.shiftKey;
4797 08 May 18 nicklas 935     var matchedClass = specialKey ? 'colormatched-2' : 'colormatched';
4794 07 May 18 nicklas 936     var cm = document.getElementsByClassName('colormatch');
4799 09 May 18 nicklas 937     var add = !event.currentTarget.classList.contains(matchedClass);
4794 07 May 18 nicklas 938     for (var i = 0; i < cm.length; i++)
4794 07 May 18 nicklas 939     {
4794 07 May 18 nicklas 940       var e = cm[i];
4797 08 May 18 nicklas 941       Doc.addOrRemoveClass(e, matchedClass, Data.get(e, 'match') == toMatch && add);
4794 07 May 18 nicklas 942     }
4794 07 May 18 nicklas 943   }
4794 07 May 18 nicklas 944   
4980 25 Sep 18 nicklas 945   /**
4980 25 Sep 18 nicklas 946     Display a warning icon if the selected re-process option is marked 'donotuse'.
4980 25 Sep 18 nicklas 947   */
4980 25 Sep 18 nicklas 948   search.reprocessOptionOnChange = function(event)
4980 25 Sep 18 nicklas 949   {
4980 25 Sep 18 nicklas 950     var opt = event.currentTarget[event.currentTarget.selectedIndex];
4980 25 Sep 18 nicklas 951     var tmpId = event.currentTarget.id.replace('reprocess.', '');
4980 25 Sep 18 nicklas 952     Doc.addOrRemoveClass('section.'+tmpId, 'reprocess-warning', opt.classList.contains('donotuse'));
4980 25 Sep 18 nicklas 953   }
4980 25 Sep 18 nicklas 954   
4975 21 Sep 18 nicklas 955   // Enable/disable the DoNotUse list depending on if the OkToUse is checked or not
4975 21 Sep 18 nicklas 956   search.okToUseOnChange = function(event)
4975 21 Sep 18 nicklas 957   {
4975 21 Sep 18 nicklas 958     var tmpId = event.currentTarget.id.replace('oktouse.', '');
4975 21 Sep 18 nicklas 959     var doNotUseList = Doc.element('donotuse.'+tmpId);
4981 25 Sep 18 nicklas 960     var futureGtCheck = Doc.element('futuregt.'+tmpId);
4975 21 Sep 18 nicklas 961     var commentField = Doc.element('resolvecomment.'+tmpId);
4975 21 Sep 18 nicklas 962     if (event.currentTarget.checked)
4975 21 Sep 18 nicklas 963     {
4975 21 Sep 18 nicklas 964       doNotUseList.selectedIndex = 0;
5001 04 Oct 18 nicklas 965       Events.sendChangeEvent(doNotUseList);
4975 21 Sep 18 nicklas 966       Doc.removeClass(doNotUseList, 'required');
4975 21 Sep 18 nicklas 967       Doc.removeClass(commentField, 'required');
4975 21 Sep 18 nicklas 968       doNotUseList.disabled = true;
4981 25 Sep 18 nicklas 969       futureGtCheck.disabled = true;
4975 21 Sep 18 nicklas 970     }
4975 21 Sep 18 nicklas 971     else
4975 21 Sep 18 nicklas 972     {
4975 21 Sep 18 nicklas 973       Doc.addClass(doNotUseList, 'required');
4975 21 Sep 18 nicklas 974       doNotUseList.disabled = false;
4975 21 Sep 18 nicklas 975     }
4975 21 Sep 18 nicklas 976   }
4975 21 Sep 18 nicklas 977
4975 21 Sep 18 nicklas 978   
4975 21 Sep 18 nicklas 979   // Mark the corresponding comment field as required if the DoNotUse flag is going to be set
4975 21 Sep 18 nicklas 980   search.doNotUseOptionOnChange = function(event)
4975 21 Sep 18 nicklas 981   {
4975 21 Sep 18 nicklas 982     var tmpId = event.currentTarget.id.replace('donotuse.', '');
4975 21 Sep 18 nicklas 983     var value = event.currentTarget.value;    
4981 25 Sep 18 nicklas 984     var futureGtCheck = Doc.element('futuregt.'+tmpId);
5001 04 Oct 18 nicklas 985     if (value == '')
5001 04 Oct 18 nicklas 986     {
5001 04 Oct 18 nicklas 987       futureGtCheck.checked = false;
5001 04 Oct 18 nicklas 988       Events.sendChangeEvent(futureGtCheck);
5001 04 Oct 18 nicklas 989     }
4981 25 Sep 18 nicklas 990     futureGtCheck.disabled = value == '';
4975 21 Sep 18 nicklas 991     var commentField = Doc.element('resolvecomment.'+tmpId);
4975 21 Sep 18 nicklas 992     Doc.addOrRemoveClass(commentField, 'required', value != '');
4975 21 Sep 18 nicklas 993   }
4975 21 Sep 18 nicklas 994   
4799 09 May 18 nicklas 995   search.getAlignmentHtml = function(alignment, refAlignment)
4794 07 May 18 nicklas 996   {
4794 07 May 18 nicklas 997     var tmp = {};
4794 07 May 18 nicklas 998     
4818 22 May 18 nicklas 999     var itemName = alignment.name;
4818 22 May 18 nicklas 1000     var suffix = '';
4818 22 May 18 nicklas 1001     var markedName = refAlignment ? HTMLHelper.tagCommonPartOfName(refAlignment.name, itemName) : null;
4794 07 May 18 nicklas 1002     
4818 22 May 18 nicklas 1003     if (!itemName)
4818 22 May 18 nicklas 1004     {
4818 22 May 18 nicklas 1005       var subtype = null;
4818 22 May 18 nicklas 1006       if (alignment.lib)
4818 22 May 18 nicklas 1007       {
4818 22 May 18 nicklas 1008         itemName = alignment.lib.name;
4818 22 May 18 nicklas 1009         subtype = 'Library';
4818 22 May 18 nicklas 1010       }
4818 22 May 18 nicklas 1011       else if (alignment.rna)
4818 22 May 18 nicklas 1012       {
4818 22 May 18 nicklas 1013         itemName = alignment.rna.name;
4818 22 May 18 nicklas 1014         subtype = 'RNA';
4818 22 May 18 nicklas 1015       }
4818 22 May 18 nicklas 1016       markedName = itemName;
4818 22 May 18 nicklas 1017       if (subtype)
4818 22 May 18 nicklas 1018       {
4818 22 May 18 nicklas 1019         suffix = ' <span class="itemsubtype">('+subtype+')</span>';
4818 22 May 18 nicklas 1020       }
4818 22 May 18 nicklas 1021     }
4818 22 May 18 nicklas 1022     
4818 22 May 18 nicklas 1023     tmp.name = HTMLHelper.colorMatch(itemName, markedName, 'Click to highlight this item') + suffix;
4818 22 May 18 nicklas 1024     
4794 07 May 18 nicklas 1025     var icons = '';
4794 07 May 18 nicklas 1026     var tooltip = '';
4794 07 May 18 nicklas 1027     
4818 22 May 18 nicklas 1028     if (alignment.specimen)
4794 07 May 18 nicklas 1029     {
4818 22 May 18 nicklas 1030       tmp.name += '<img src="../images/case_summary.png" class="link case-summary" data-name="'+Strings.encodeTags(itemName)+'" title="Show case summary">';
4818 22 May 18 nicklas 1031     }
4970 13 Sep 18 nicklas 1032     if (alignment.QC_GENOTYPE_COMMENT)
4970 13 Sep 18 nicklas 1033     {
4970 13 Sep 18 nicklas 1034       icons += '<img src="../images/comment.png" title="'+Strings.encodeTags(alignment.QC_GENOTYPE_COMMENT)+'">';
4970 13 Sep 18 nicklas 1035     }
4980 25 Sep 18 nicklas 1036     if (alignment.DO_NOT_USE)
4980 25 Sep 18 nicklas 1037     {
4980 25 Sep 18 nicklas 1038       icons += '<img src="../images/donotuse.png" title="DoNotUse-'+Strings.encodeTags(alignment.DO_NOT_USE+': '+alignment.DO_NOT_USE_COMMENT)+'">';
4980 25 Sep 18 nicklas 1039     }
4997 03 Oct 18 nicklas 1040     if (alignment.currentReProcess)
4997 03 Oct 18 nicklas 1041     {
4997 03 Oct 18 nicklas 1042       icons += '<img src="../images/reprocess.png" title="Re-processing is scheduled from '+alignment.currentReProcess+'">';
4997 03 Oct 18 nicklas 1043     }
4997 03 Oct 18 nicklas 1044     
4975 21 Sep 18 nicklas 1045     if (alignment.flagged)
4818 22 May 18 nicklas 1046     {
4975 21 Sep 18 nicklas 1047       // We need this class to search for flagged alignments on the "right" side of the table (see goResolve() method)
4975 21 Sep 18 nicklas 1048       var cls = refAlignment ? 'paired-alignment' : 'primary-alignment';
4975 21 Sep 18 nicklas 1049       icons += '<img src="../images/flag.png" title="This alignment is already flagged" class="'+cls+'" data-id="'+alignment.id+'">';
4794 07 May 18 nicklas 1050     }
4794 07 May 18 nicklas 1051     if (alignment.QC_GENOTYPE_VERIFIED) 
4794 07 May 18 nicklas 1052     {
4794 07 May 18 nicklas 1053       var img = alignment.QC_GENOTYPE_VERIFIED == 'Lysate' ? 'gt-verified-lysate.png' : 'gt-verified.png';
4794 07 May 18 nicklas 1054       tooltip = Strings.encodeTags('Verified by '+alignment.QC_GENOTYPE_VERIFIED);
4794 07 May 18 nicklas 1055       icons += '<img src="../images/'+img+'" title="'+tooltip+'">';
4794 07 May 18 nicklas 1056     }
4797 08 May 18 nicklas 1057     if (alignment.bugged)
4794 07 May 18 nicklas 1058     {
4797 08 May 18 nicklas 1059       var img = bugIcons[alignment.buglevel];
4981 25 Sep 18 nicklas 1060       // .replace will strip simple HTML tags
4981 25 Sep 18 nicklas 1061       var imgTitle = alignment.buglevel > 0 && alignment.bugText.length > 0 ? alignment.bugText[0].replace(/<\/?[^>]+(>|$)/g, '') : '';
4797 08 May 18 nicklas 1062       icons += '<img src="../images/'+img+'" title="'+imgTitle+'">';
4797 08 May 18 nicklas 1063     }
4818 22 May 18 nicklas 1064     if (alignment.bugText && alignment.bugText.length > 0)
4797 08 May 18 nicklas 1065     {
4794 07 May 18 nicklas 1066       tooltip = alignment.bugText.join('<br>');
4794 07 May 18 nicklas 1067     }
4794 07 May 18 nicklas 1068     
4794 07 May 18 nicklas 1069     tmp.icons = icons;
4794 07 May 18 nicklas 1070     tmp.tooltip = tooltip;
4794 07 May 18 nicklas 1071     return tmp;
4794 07 May 18 nicklas 1072   }
4794 07 May 18 nicklas 1073   
6589 21 Feb 22 nicklas 1074   search.getMessageHtml = function(message, aligned, assaysByName, qiacubefilter, libplatefilter)
4794 07 May 18 nicklas 1075   {
4794 07 May 18 nicklas 1076     var html = '';
4797 08 May 18 nicklas 1077     var msgClass= "bg-messages";
6589 21 Feb 22 nicklas 1078     if (message.otherAssay)
4794 07 May 18 nicklas 1079     {
6589 21 Feb 22 nicklas 1080       var otherAssay = assaysByName[message.otherAssay];
6589 21 Feb 22 nicklas 1081       var tmp = search.getAlignmentHtml(otherAssay, aligned);
7209 26 May 23 nicklas 1082       html += '<td class="dottedleft text-col">';
4794 07 May 18 nicklas 1083       html += tmp.name+tmp.icons;
7209 26 May 23 nicklas 1084       html += '</td>';
7209 26 May 23 nicklas 1085       html += '<td>'+HTMLHelper.shortPipeline(otherAssay.PIPELINE)+'</td>';
6589 21 Feb 22 nicklas 1086       if (otherAssay)
4794 07 May 18 nicklas 1087       {
6589 21 Feb 22 nicklas 1088         if (otherAssay.buglevel == 1 && (qiacubefilter || libplatefilter)) msgClass += ' ignored-mismatch';
6589 21 Feb 22 nicklas 1089         html += '<td>'+Reggie.formatNumber(otherAssay.QC_GENOTYPE_HET_PCT, '%', -1)+'</td>';
6589 21 Feb 22 nicklas 1090         var rna = otherAssay.rna || {};
6590 21 Feb 22 nicklas 1091         var dna = otherAssay.dna || {};
6590 21 Feb 22 nicklas 1092         var lib = otherAssay.lib;
6590 21 Feb 22 nicklas 1093         var chip = otherAssay.chip;
6589 21 Feb 22 nicklas 1094         var specimen = otherAssay.specimen || {};
4794 07 May 18 nicklas 1095         
4817 21 May 18 nicklas 1096         html += '<td class="mode-genotype">'+HTMLHelper.qiaCubeLink(rna.QIACUBE_DATE, rna.QIACUBE_RUN_NO, rna.QIACUBE_POSITION, qiacubefilter, false)+'</td>';
6590 21 Feb 22 nicklas 1097         html += '<td class="mode-genotype">';
6590 21 Feb 22 nicklas 1098         if (lib)
6590 21 Feb 22 nicklas 1099         {
6590 21 Feb 22 nicklas 1100           var libWell = lib.bioWell || {};
6590 21 Feb 22 nicklas 1101           var libPlate = libWell.bioPlate || {};
6590 21 Feb 22 nicklas 1102           html +=  HTMLHelper.libPlateLink(libPlate.name, libWell.location, libplatefilter, false);
6590 21 Feb 22 nicklas 1103         }
6590 21 Feb 22 nicklas 1104         else if (chip)
6590 21 Feb 22 nicklas 1105         {
6592 21 Feb 22 nicklas 1106           html += HTMLHelper.beadChipLink(chip.name, dna.BeadChipPosition);
6590 21 Feb 22 nicklas 1107         }
7209 26 May 23 nicklas 1108         else if (dna && dna.bioWell)
7209 26 May 23 nicklas 1109         {
7209 26 May 23 nicklas 1110           var dnaWell = dna.bioWell || {};
7209 26 May 23 nicklas 1111           var dnaPlate = dnaWell.bioPlate || {};
7209 26 May 23 nicklas 1112           html +=  HTMLHelper.platePos(dnaPlate.name, dnaWell.location);
7209 26 May 23 nicklas 1113         }
6590 21 Feb 22 nicklas 1114         html += '</td>';
6589 21 Feb 22 nicklas 1115         html += '<td>'+HTMLHelper.colorMatch(specimen.patientName, null, 'Click to highlight this patient')+'</td>';
4794 07 May 18 nicklas 1116       }
4794 07 May 18 nicklas 1117     }
4794 07 May 18 nicklas 1118     else 
4794 07 May 18 nicklas 1119     {
7209 26 May 23 nicklas 1120       html += '<td class="dottedleft" colspan="6"></td>';
4794 07 May 18 nicklas 1121     }
4797 08 May 18 nicklas 1122     html = '<td class="' + msgClass+ '" title="'+(message.messageTooltip || '')+'">'+Strings.encodeTags(message.message) + '</td>' + html;
4794 07 May 18 nicklas 1123     return html;
4794 07 May 18 nicklas 1124   }
4794 07 May 18 nicklas 1125   
4817 21 May 18 nicklas 1126   search.modeOnChange = function()
4817 21 May 18 nicklas 1127   {
4817 21 May 18 nicklas 1128     var frm = document.forms['reggie'];
4818 22 May 18 nicklas 1129     var mode = Forms.getCheckedRadio(frm.mode).value;
4817 21 May 18 nicklas 1130     Data.set('itemTable', 'mode', mode);
4817 21 May 18 nicklas 1131     Doc.showHide('goreprocess', mode == 'reprocess');
4975 21 Sep 18 nicklas 1132     Doc.showHide('goresolve', mode == 'resolve');
4970 13 Sep 18 nicklas 1133     Wizard.hideGoNextConfirmation();
4817 21 May 18 nicklas 1134   }
4817 21 May 18 nicklas 1135   
4817 21 May 18 nicklas 1136   search.goReProcess = function()
4817 21 May 18 nicklas 1137   {
4970 13 Sep 18 nicklas 1138     Wizard.hideGoNextConfirmation();
4970 13 Sep 18 nicklas 1139     Doc.hide('wizard-status');
4817 21 May 18 nicklas 1140     var frm = document.forms['reggie'];
4970 13 Sep 18 nicklas 1141     var items = [];
7209 26 May 23 nicklas 1142     for (var itemNo = 0; itemNo < tumors.length; itemNo++)
4817 21 May 18 nicklas 1143     {
7209 26 May 23 nicklas 1144       var tumor = tumors[itemNo];
4970 13 Sep 18 nicklas 1145       
4970 13 Sep 18 nicklas 1146       // Get the form elements for this item
7209 26 May 23 nicklas 1147       var listE = Doc.element('reprocess.'+tumor.tmpId);
7209 26 May 23 nicklas 1148       var flagE = Doc.element('flag.'+tumor.tmpId);
7209 26 May 23 nicklas 1149       var commentE = Doc.element('comment.'+tumor.tmpId);
4970 13 Sep 18 nicklas 1150       
7209 26 May 23 nicklas 1151       var item = { 'id': tumor.id };
4970 13 Sep 18 nicklas 1152       var changed = false;
4970 13 Sep 18 nicklas 1153       
4970 13 Sep 18 nicklas 1154       // Check if a re-processing option was selected
4970 13 Sep 18 nicklas 1155       if (listE && listE.value)
4817 21 May 18 nicklas 1156       {
4970 13 Sep 18 nicklas 1157         changed = true;
4970 13 Sep 18 nicklas 1158         if (listE.value == 'specimen')
4817 21 May 18 nicklas 1159         {
7209 26 May 23 nicklas 1160           item.reprocess = {'type': 'SAMPLE', 'id': tumor.specimen.id };
4817 21 May 18 nicklas 1161         }
4970 13 Sep 18 nicklas 1162         else if (listE.value == 'lysate')
4817 21 May 18 nicklas 1163         {
7209 26 May 23 nicklas 1164           item.reprocess = {'type': 'EXTRACT', 'id': tumor.lysate.id };
4817 21 May 18 nicklas 1165         }
4970 13 Sep 18 nicklas 1166         else if (listE.value == 'rna')
4817 21 May 18 nicklas 1167         {
7209 26 May 23 nicklas 1168           item.reprocess = {'type': 'EXTRACT', 'id': tumor.rna.id };
4817 21 May 18 nicklas 1169         }
4817 21 May 18 nicklas 1170       }
4970 13 Sep 18 nicklas 1171       if (flagE && flagE.checked)
4970 13 Sep 18 nicklas 1172       {
4970 13 Sep 18 nicklas 1173         changed = true;
4970 13 Sep 18 nicklas 1174         item.flag = true;
4970 13 Sep 18 nicklas 1175       }
7209 26 May 23 nicklas 1176       if (commentE && Strings.trim(commentE.value) != Strings.trim(tumor.QC_GENOTYPE_COMMENT))
4970 13 Sep 18 nicklas 1177       {
4970 13 Sep 18 nicklas 1178         changed = true;
4970 13 Sep 18 nicklas 1179         item.comment = commentE.value;
4970 13 Sep 18 nicklas 1180       }
4970 13 Sep 18 nicklas 1181       
4970 13 Sep 18 nicklas 1182       if (changed) items[items.length] = item;
4817 21 May 18 nicklas 1183     }
4817 21 May 18 nicklas 1184     
4970 13 Sep 18 nicklas 1185     if (items.length == 0)
4817 21 May 18 nicklas 1186     {
4970 13 Sep 18 nicklas 1187       Wizard.showGoNextConfirmation(false, 'No changes have been made!');
4817 21 May 18 nicklas 1188       return;
4817 21 May 18 nicklas 1189     }
4817 21 May 18 nicklas 1190     
4970 13 Sep 18 nicklas 1191     Doc.addClass('step-1', 'disabled');
4970 13 Sep 18 nicklas 1192     Doc.hide('navigation');
4970 13 Sep 18 nicklas 1193     
4970 13 Sep 18 nicklas 1194     
4970 13 Sep 18 nicklas 1195     // Include filter settings in the registration URL so that a new list can be generated
4970 13 Sep 18 nicklas 1196     var highHet = Doc.element('highHetFilter');
4970 13 Sep 18 nicklas 1197     var libPlate = Doc.element('libPlateFilter');
4970 13 Sep 18 nicklas 1198     var qiaCube = Doc.element('qiaCubeFilter');
4970 13 Sep 18 nicklas 1199     
4817 21 May 18 nicklas 1200     var url = '../Genotype.servlet?ID='+App.getSessionId();
4817 21 May 18 nicklas 1201     url += '&cmd=ReprocessItems';
4970 13 Sep 18 nicklas 1202     if (libPlate.selectedIndex > 0)
4970 13 Sep 18 nicklas 1203     {
4970 13 Sep 18 nicklas 1204       url += '&libPlateFilter='+encodeURIComponent(libPlate.value);
4970 13 Sep 18 nicklas 1205     }
4970 13 Sep 18 nicklas 1206     else if (qiaCube.selectedIndex > 0)
4970 13 Sep 18 nicklas 1207     {
4970 13 Sep 18 nicklas 1208       url += '&qiaCubeFilter='+encodeURIComponent(qiaCube.value);
4970 13 Sep 18 nicklas 1209     }
4970 13 Sep 18 nicklas 1210     else if (highHet.checked)
4970 13 Sep 18 nicklas 1211     {
4970 13 Sep 18 nicklas 1212       url += '&highHetFilter=1';
4970 13 Sep 18 nicklas 1213     }
4817 21 May 18 nicklas 1214     
4817 21 May 18 nicklas 1215     var submitInfo = {};
4970 13 Sep 18 nicklas 1216     submitInfo.items = items;
4970 13 Sep 18 nicklas 1217     Wizard.showLoadingAnimation('Saving changes...');
4817 21 May 18 nicklas 1218     Wizard.asyncJsonRequest(url, search.reprocessResults, 'POST', JSON.stringify(submitInfo));
4817 21 May 18 nicklas 1219   }
4794 07 May 18 nicklas 1220
4817 21 May 18 nicklas 1221   search.reprocessResults = function(response)
4817 21 May 18 nicklas 1222   {
4970 13 Sep 18 nicklas 1223     search.onAlignmentsLoaded(response);
4970 13 Sep 18 nicklas 1224     Doc.show('navigation');
4970 13 Sep 18 nicklas 1225     Doc.removeClass('step-1', 'disabled');
4817 21 May 18 nicklas 1226     Wizard.showFinalMessage(response.messages);
4817 21 May 18 nicklas 1227   }
4817 21 May 18 nicklas 1228   
4975 21 Sep 18 nicklas 1229   
4975 21 Sep 18 nicklas 1230   search.goResolve = function()
4975 21 Sep 18 nicklas 1231   {
5017 09 Oct 18 nicklas 1232     var verifyCheck = Doc.element('verifyGoNext');
5017 09 Oct 18 nicklas 1233     var acceptPartial = verifyCheck !=null && verifyCheck.checked;
5017 09 Oct 18 nicklas 1234     
4975 21 Sep 18 nicklas 1235     Wizard.hideGoNextConfirmation();
4975 21 Sep 18 nicklas 1236     Doc.hide('wizard-status');
4975 21 Sep 18 nicklas 1237     var frm = document.forms['reggie'];
4975 21 Sep 18 nicklas 1238     // We generate a list of items that should either be marked as DoNotUse or OkToUse
4975 21 Sep 18 nicklas 1239     var items = [];
4975 21 Sep 18 nicklas 1240     // This list will are flagged alignements that have a relation to the items in the above list
4975 21 Sep 18 nicklas 1241     // The are potential candidates to be unflagged due to not having any more issues with other alignments
4975 21 Sep 18 nicklas 1242     var flaggedPairs = [];
4975 21 Sep 18 nicklas 1243     var numInvalid = 0;
5017 09 Oct 18 nicklas 1244     var numCanAllowIfPartial = 0;
5017 09 Oct 18 nicklas 1245     
7209 26 May 23 nicklas 1246     for (var itemNo = 0; itemNo < tumors.length; itemNo++)
4975 21 Sep 18 nicklas 1247     {
7209 26 May 23 nicklas 1248       var tumor = tumors[itemNo];
4975 21 Sep 18 nicklas 1249       
4975 21 Sep 18 nicklas 1250       // Assume that selection is valid
7209 26 May 23 nicklas 1251       Doc.removeClass('section.'+tumor.tmpId, 'invalid');
4975 21 Sep 18 nicklas 1252       
4975 21 Sep 18 nicklas 1253       // Get the form elements for this item
7209 26 May 23 nicklas 1254       var okToUse = Doc.element('oktouse.'+tumor.tmpId);
7209 26 May 23 nicklas 1255       var doNotUse = Doc.element('donotuse.'+tumor.tmpId);
7209 26 May 23 nicklas 1256       var futureGt = Doc.element('futuregt.'+tumor.tmpId);
7209 26 May 23 nicklas 1257       var comment = Doc.element('resolvecomment.'+tumor.tmpId);
4975 21 Sep 18 nicklas 1258       
4975 21 Sep 18 nicklas 1259       var item = null;
4975 21 Sep 18 nicklas 1260       if (doNotUse)
4975 21 Sep 18 nicklas 1261       {
4975 21 Sep 18 nicklas 1262         if (okToUse && okToUse.checked)
4975 21 Sep 18 nicklas 1263         {
4975 21 Sep 18 nicklas 1264           if (okToUse.value == 'ok-rna')
4975 21 Sep 18 nicklas 1265           {
7209 26 May 23 nicklas 1266             item = {'type': 'EXTRACT', 'id': tumor.rna.id, 'okToUse': true, 'sort': 6 };
4975 21 Sep 18 nicklas 1267           }
4975 21 Sep 18 nicklas 1268           else if (okToUse.value == 'ok-library')
4975 21 Sep 18 nicklas 1269           {
7209 26 May 23 nicklas 1270             item = {'type': 'EXTRACT', 'id': tumor.lib.id, 'okToUse': true, 'sort': 7 };
4975 21 Sep 18 nicklas 1271           }
4975 21 Sep 18 nicklas 1272         }
4975 21 Sep 18 nicklas 1273         else if (doNotUse.value == 'specimen')
4975 21 Sep 18 nicklas 1274         {
7209 26 May 23 nicklas 1275           item = {'type': 'SAMPLE', 'id': tumor.specimen.id, 'doNotUse': 'Specimen', 'sort': 1 };
4975 21 Sep 18 nicklas 1276         }
4975 21 Sep 18 nicklas 1277         else if (doNotUse.value == 'lysate')
4975 21 Sep 18 nicklas 1278         {
7209 26 May 23 nicklas 1279           item = {'type': 'EXTRACT', 'id': tumor.lysate.id, 'doNotUse': 'Lysate', 'sort': 2 };
4975 21 Sep 18 nicklas 1280         }
4975 21 Sep 18 nicklas 1281         else if (doNotUse.value == 'rna')
4975 21 Sep 18 nicklas 1282         {
7209 26 May 23 nicklas 1283           item = {'type': 'EXTRACT', 'id': tumor.rna.id, 'doNotUse': 'RNA', 'sort': 3 };
4975 21 Sep 18 nicklas 1284         }
4982 26 Sep 18 nicklas 1285         else if (doNotUse.value == 'prenormalized')
4982 26 Sep 18 nicklas 1286         {
7209 26 May 23 nicklas 1287           item = {'type': 'EXTRACT', 'id': tumor.preNormalizedRna.id, 'doNotUse': 'PreNormalizedRNA', 'sort': 4 };
4982 26 Sep 18 nicklas 1288         }
4975 21 Sep 18 nicklas 1289         else if (doNotUse.value == 'library')
4975 21 Sep 18 nicklas 1290         {
7209 26 May 23 nicklas 1291           item = {'type': 'EXTRACT', 'id': tumor.lib.id, 'doNotUse': 'Library', 'sort': 5 };
4975 21 Sep 18 nicklas 1292         }
7209 26 May 23 nicklas 1293         else if (tumor.flagged && doNotUse.classList.contains('required'))
4975 21 Sep 18 nicklas 1294         {
4975 21 Sep 18 nicklas 1295           // A flagged item must have a specific option selected (when filtered on QiaCube or LibPlate)
5017 09 Oct 18 nicklas 1296           numCanAllowIfPartial++;
5017 09 Oct 18 nicklas 1297           if (!acceptPartial)
5017 09 Oct 18 nicklas 1298           {
7209 26 May 23 nicklas 1299             Doc.addClass('section.'+tumor.tmpId, 'invalid');
5017 09 Oct 18 nicklas 1300             numInvalid++;
5017 09 Oct 18 nicklas 1301           }
4975 21 Sep 18 nicklas 1302         }
4981 25 Sep 18 nicklas 1303         if (doNotUse.value && futureGt)
4981 25 Sep 18 nicklas 1304         {
4981 25 Sep 18 nicklas 1305           item.futureGt = futureGt.checked;
4981 25 Sep 18 nicklas 1306         }
4975 21 Sep 18 nicklas 1307       }
4975 21 Sep 18 nicklas 1308       if (item && comment)
4975 21 Sep 18 nicklas 1309       {
4975 21 Sep 18 nicklas 1310         item.comment = Strings.trim(comment.value);
4975 21 Sep 18 nicklas 1311         if (item.doNotUse && item.comment == '')
4975 21 Sep 18 nicklas 1312         {
4975 21 Sep 18 nicklas 1313           // A comment must be specified for all items marked with DoNotUse
7209 26 May 23 nicklas 1314           Doc.addClass('section.'+tumor.tmpId, 'invalid');
4975 21 Sep 18 nicklas 1315           numInvalid++;
4975 21 Sep 18 nicklas 1316         }
4975 21 Sep 18 nicklas 1317       }
4975 21 Sep 18 nicklas 1318       if (item != null)
4975 21 Sep 18 nicklas 1319       {
4975 21 Sep 18 nicklas 1320         items[items.length] = item;
4975 21 Sep 18 nicklas 1321         
4975 21 Sep 18 nicklas 1322         // Find flagged alignments that are related to the selected item
4975 21 Sep 18 nicklas 1323         // We take help from the <tbody> section and look for tags with 'paired-alignment' class
7209 26 May 23 nicklas 1324         var sectR = Doc.element('section.'+tumor.tmpId);
4975 21 Sep 18 nicklas 1325         var flagged = sectR.getElementsByClassName('paired-alignment');
4975 21 Sep 18 nicklas 1326         for (var fNo = 0; fNo < flagged.length; fNo++)
4975 21 Sep 18 nicklas 1327         {
4975 21 Sep 18 nicklas 1328           flaggedPairs[flaggedPairs.length] = Data.int(flagged[fNo], 'id');
4975 21 Sep 18 nicklas 1329         }
4975 21 Sep 18 nicklas 1330       }
4975 21 Sep 18 nicklas 1331     }
4975 21 Sep 18 nicklas 1332
4975 21 Sep 18 nicklas 1333     if (numInvalid > 0)
4975 21 Sep 18 nicklas 1334     {
5017 09 Oct 18 nicklas 1335       if (numCanAllowIfPartial > 0)
5017 09 Oct 18 nicklas 1336       {
5017 09 Oct 18 nicklas 1337         Wizard.showGoNextConfirmation(true, 'Mark the checkbox to allow partial registration.', acceptPartial);
5017 09 Oct 18 nicklas 1338       }
4975 21 Sep 18 nicklas 1339       Wizard.notifyError();
4975 21 Sep 18 nicklas 1340       return;
4975 21 Sep 18 nicklas 1341     }
4975 21 Sep 18 nicklas 1342     
4975 21 Sep 18 nicklas 1343     if (items.length == 0)
4975 21 Sep 18 nicklas 1344     {
4975 21 Sep 18 nicklas 1345       Wizard.showGoNextConfirmation(false, 'No changes have been made!');
4975 21 Sep 18 nicklas 1346       return;
4975 21 Sep 18 nicklas 1347     }
5017 09 Oct 18 nicklas 1348
4975 21 Sep 18 nicklas 1349     Doc.addClass('step-1', 'disabled');
4975 21 Sep 18 nicklas 1350     Doc.hide('navigation');
4975 21 Sep 18 nicklas 1351     
4975 21 Sep 18 nicklas 1352     // Include filter settings in the registration URL so that a new list can be generated
4975 21 Sep 18 nicklas 1353     var highHet = Doc.element('highHetFilter');
4975 21 Sep 18 nicklas 1354     var libPlate = Doc.element('libPlateFilter');
4975 21 Sep 18 nicklas 1355     var qiaCube = Doc.element('qiaCubeFilter');
4975 21 Sep 18 nicklas 1356     
4975 21 Sep 18 nicklas 1357     var url = '../Genotype.servlet?ID='+App.getSessionId();
4975 21 Sep 18 nicklas 1358     url += '&cmd=ResolveProblems';
4975 21 Sep 18 nicklas 1359     if (libPlate.selectedIndex > 0)
4975 21 Sep 18 nicklas 1360     {
4975 21 Sep 18 nicklas 1361       url += '&libPlateFilter='+encodeURIComponent(libPlate.value);
4975 21 Sep 18 nicklas 1362     }
4975 21 Sep 18 nicklas 1363     else if (qiaCube.selectedIndex > 0)
4975 21 Sep 18 nicklas 1364     {
4975 21 Sep 18 nicklas 1365       url += '&qiaCubeFilter='+encodeURIComponent(qiaCube.value);
4975 21 Sep 18 nicklas 1366     }
4975 21 Sep 18 nicklas 1367     else if (highHet.checked)
4975 21 Sep 18 nicklas 1368     {
4975 21 Sep 18 nicklas 1369       url += '&highHetFilter=1';
4975 21 Sep 18 nicklas 1370     }
4975 21 Sep 18 nicklas 1371     
4978 24 Sep 18 nicklas 1372     // Sort items in the "correct" order. All DoNotUse items before OkToUse
4978 24 Sep 18 nicklas 1373     // and Specimen -> Lysate -> RNA -> Library
4978 24 Sep 18 nicklas 1374     // This will prevent prevent problems with non-deterministic result if
4978 24 Sep 18 nicklas 1375     // selecting, for example, "Specimen" and "RNA" from the same parent-child chain
4978 24 Sep 18 nicklas 1376     // With sorting the highest level (Specimen) wins
4978 24 Sep 18 nicklas 1377     items.sort(Sort.sortDoNotUseItems);
4978 24 Sep 18 nicklas 1378     
4975 21 Sep 18 nicklas 1379     var submitInfo = {};
4975 21 Sep 18 nicklas 1380     submitInfo.items = items;
4975 21 Sep 18 nicklas 1381     submitInfo.paired = flaggedPairs;  
4975 21 Sep 18 nicklas 1382     
4975 21 Sep 18 nicklas 1383     Wizard.showLoadingAnimation('Saving changes...');
4975 21 Sep 18 nicklas 1384     Wizard.asyncJsonRequest(url, search.resolveResults, 'POST', JSON.stringify(submitInfo));
4975 21 Sep 18 nicklas 1385   }
4975 21 Sep 18 nicklas 1386   
4975 21 Sep 18 nicklas 1387   search.resolveResults = function(response)
4975 21 Sep 18 nicklas 1388   {
4975 21 Sep 18 nicklas 1389     search.onAlignmentsLoaded(response);
4975 21 Sep 18 nicklas 1390     Doc.show('navigation');
4975 21 Sep 18 nicklas 1391     Doc.removeClass('step-1', 'disabled');
4975 21 Sep 18 nicklas 1392     Wizard.showFinalMessage(response.messages);
4975 21 Sep 18 nicklas 1393   }
4975 21 Sep 18 nicklas 1394
4794 07 May 18 nicklas 1395   return search;
4794 07 May 18 nicklas 1396 }();
4794 07 May 18 nicklas 1397
4794 07 May 18 nicklas 1398 Doc.onLoad(Search.initPage);
4794 07 May 18 nicklas 1399
4794 07 May 18 nicklas 1400 /**
4794 07 May 18 nicklas 1401   Represents a QiaCube in the QiaCube filter list.
4794 07 May 18 nicklas 1402   The date and run number is the important information.
4794 07 May 18 nicklas 1403 */
4794 07 May 18 nicklas 1404 function QiaCube(date, runNo)
4794 07 May 18 nicklas 1405 {
4794 07 May 18 nicklas 1406   this.date = date;
4794 07 May 18 nicklas 1407   this.runNo = runNo;
4794 07 May 18 nicklas 1408   this.name = date + '#' + runNo;
4794 07 May 18 nicklas 1409   this.title = Reggie.reformatDate(date) + '#' + runNo;
4794 07 May 18 nicklas 1410 }
4794 07 May 18 nicklas 1411
4794 07 May 18 nicklas 1412 /**
4794 07 May 18 nicklas 1413   Represents a LibPlate in the LibPlate filter list.
4794 07 May 18 nicklas 1414   The name is the only important information.
4794 07 May 18 nicklas 1415 */
4794 07 May 18 nicklas 1416 function LibPlate(name)
4794 07 May 18 nicklas 1417 {
4794 07 May 18 nicklas 1418   this.name = name;
4794 07 May 18 nicklas 1419 }
4794 07 May 18 nicklas 1420
4794 07 May 18 nicklas 1421 // Placeholder for various sort functions
4794 07 May 18 nicklas 1422 var Sort = function()
4794 07 May 18 nicklas 1423 {
4794 07 May 18 nicklas 1424   var sort = {};
4794 07 May 18 nicklas 1425   
4794 07 May 18 nicklas 1426   // Sort items by name
4794 07 May 18 nicklas 1427   sort.sortByName = function(a, b)
4794 07 May 18 nicklas 1428   {
4794 07 May 18 nicklas 1429     return a.name == b.name ? 0 : (a.name < b.name ? -1 : 1);
4794 07 May 18 nicklas 1430   }
4794 07 May 18 nicklas 1431
7209 26 May 23 nicklas 1432   // Sort tumors by patient name
4794 07 May 18 nicklas 1433   // If they are equals sort by alignment name
7209 26 May 23 nicklas 1434   sort.sortTumorsByPatientName = function(a, b)
4794 07 May 18 nicklas 1435   {
4821 23 May 18 nicklas 1436     var patA = a.specimen ? a.specimen.patientName : 'zz'+(a.name || a.rna.name);
4821 23 May 18 nicklas 1437     var patB = b.specimen ? b.specimen.patientName : 'zz'+(b.name || b.rna.name);
4794 07 May 18 nicklas 1438     return patA == patB ? sort.sortByName(a, b) : (patA < patB ? -1 : 1);
4794 07 May 18 nicklas 1439   }
4794 07 May 18 nicklas 1440   
7209 26 May 23 nicklas 1441   // Sort tumors by LibPlate position (columns before rows)
7209 26 May 23 nicklas 1442   sort.sortTumorsByLibPlatePosition = function(a, b)
4794 07 May 18 nicklas 1443   {
4821 23 May 18 nicklas 1444     var plateA = a.lib ? a.lib.bioWell.bioPlate.name : 'zz'+(a.name || a.rna.name);
4821 23 May 18 nicklas 1445     var plateB = b.lib ? b.lib.bioWell.bioPlate.name : 'zz'+(b.name || b.rna.name);
4794 07 May 18 nicklas 1446
4794 07 May 18 nicklas 1447     if (plateA != plateB) return plateA < plateB ? -1 : 1;
4794 07 May 18 nicklas 1448     
4794 07 May 18 nicklas 1449     var posA = a.lib.bioWell;
4794 07 May 18 nicklas 1450     var posB = b.lib.bioWell;
4794 07 May 18 nicklas 1451     if (posA.column != posB.column) return posA.column < posB.column ? -1 : 1;
4794 07 May 18 nicklas 1452     
4794 07 May 18 nicklas 1453     return posA.row < posB.row ? -1 : 1;
4794 07 May 18 nicklas 1454   }
4794 07 May 18 nicklas 1455   
7209 26 May 23 nicklas 1456   // Sort tumors by QiaCube position
7209 26 May 23 nicklas 1457   sort.sortTumorsByQiaCubePosition = function(a, b)
4794 07 May 18 nicklas 1458   {
4794 07 May 18 nicklas 1459     var qiaCubeA = a.rna.QIACUBE_DATE + '#' + a.rna.QIACUBE_RUN_NO;
4794 07 May 18 nicklas 1460     var qiaCubeB = b.rna.QIACUBE_DATE + '#' + b.rna.QIACUBE_RUN_NO;
4794 07 May 18 nicklas 1461
4794 07 May 18 nicklas 1462     if (qiaCubeA != qiaCubeB) return qiaCubeA < qiaCubeB ? -1 : 1;
4794 07 May 18 nicklas 1463
4794 07 May 18 nicklas 1464     var posA = a.rna.QIACUBE_POSITION;
4794 07 May 18 nicklas 1465     var posB = b.rna.QIACUBE_POSITION;
4982 26 Sep 18 nicklas 1466     if (posA != posB) return posA < posB ? -1 : 1;
4982 26 Sep 18 nicklas 1467     
5024 15 Oct 18 nicklas 1468     // Sort flagged before not flagged
5024 15 Oct 18 nicklas 1469     if (a.flagged != b.flagged) return a.flagged ? -1 : 1;
5024 15 Oct 18 nicklas 1470     
4982 26 Sep 18 nicklas 1471     // Critical, sort pre-normalized RNA before regular RNA to
4982 26 Sep 18 nicklas 1472     // enable the 'PreNormalizedRNA' option in the 'DoNotUse' selection list
4982 26 Sep 18 nicklas 1473     if (a.preNormalizedRna && !b.preNormalizedRna) return -1;
4982 26 Sep 18 nicklas 1474     if (b.preNormalizedRna && !a.preNormalizedRna) return 1;
4982 26 Sep 18 nicklas 1475     
4982 26 Sep 18 nicklas 1476     return sort.sortByName(a, b);
4794 07 May 18 nicklas 1477   }
4794 07 May 18 nicklas 1478   
4978 24 Sep 18 nicklas 1479   // Sort items that are sent for "DoNotUse" or "OkToUse" by the 'sort' propert.
4978 24 Sep 18 nicklas 1480   sort.sortDoNotUseItems = function(a, b)
4978 24 Sep 18 nicklas 1481   {
4978 24 Sep 18 nicklas 1482     return a.sort == b.sort ? a.id - b.id : a.sort - b.sort;
4978 24 Sep 18 nicklas 1483   }
4978 24 Sep 18 nicklas 1484   
4794 07 May 18 nicklas 1485   return sort;
4794 07 May 18 nicklas 1486 }();
4794 07 May 18 nicklas 1487
4794 07 May 18 nicklas 1488 //Placeholder for various filter functions
4794 07 May 18 nicklas 1489 var Filter = function()
4794 07 May 18 nicklas 1490 {
4794 07 May 18 nicklas 1491   var filter = {};
4794 07 May 18 nicklas 1492   
4794 07 May 18 nicklas 1493   // Creates a filter that accepts alignments related to
4794 07 May 18 nicklas 1494   // the given QiaCube run. The filter value should
4794 07 May 18 nicklas 1495   // be formatted as <date>#<runNo>
4794 07 May 18 nicklas 1496   filter.qiaCubeFilter = function(qiaCubeRun)
4794 07 May 18 nicklas 1497   {
6589 21 Feb 22 nicklas 1498     return function(assay)
4794 07 May 18 nicklas 1499     {
6589 21 Feb 22 nicklas 1500       var rna = assay.rna;
6589 21 Feb 22 nicklas 1501       return rna && qiaCubeRun == rna.QIACUBE_DATE + '#' + rna.QIACUBE_RUN_NO ? qiaCubeRun : null;
4794 07 May 18 nicklas 1502     }
4794 07 May 18 nicklas 1503   }
4794 07 May 18 nicklas 1504   
4794 07 May 18 nicklas 1505   // Creates a filter that accepts alignments related
4794 07 May 18 nicklas 1506   // to the given LibPlate. The filter value is the name
4794 07 May 18 nicklas 1507   // of the plate,
4794 07 May 18 nicklas 1508   filter.libPlateFilter = function(libPlateName)
4794 07 May 18 nicklas 1509   {
6589 21 Feb 22 nicklas 1510     return function(assay)
4794 07 May 18 nicklas 1511     {
6589 21 Feb 22 nicklas 1512       return assay.lib && libPlateName == assay.lib.bioWell.bioPlate.name ? libPlateName : null;
4794 07 May 18 nicklas 1513     }
4794 07 May 18 nicklas 1514   }
4794 07 May 18 nicklas 1515   
4817 21 May 18 nicklas 1516   // Creates a filter that accepts alignments with a HET
4817 21 May 18 nicklas 1517   // percentage above the specified limit
4817 21 May 18 nicklas 1518   filter.hetFilter = function(hetLimit)
4817 21 May 18 nicklas 1519   {
6589 21 Feb 22 nicklas 1520     return function(assay)
4817 21 May 18 nicklas 1521     {
6589 21 Feb 22 nicklas 1522       return assay.QC_GENOTYPE_HET_PCT > hetLimit;
4817 21 May 18 nicklas 1523     }
4817 21 May 18 nicklas 1524   }
4817 21 May 18 nicklas 1525   
4794 07 May 18 nicklas 1526   return filter;
4794 07 May 18 nicklas 1527 }();
4794 07 May 18 nicklas 1528
4794 07 May 18 nicklas 1529 // Placeholder for various functions that help us get a property from an alignment 
4794 07 May 18 nicklas 1530 var Property = function()
4794 07 May 18 nicklas 1531 {
4794 07 May 18 nicklas 1532   var property = {};
4794 07 May 18 nicklas 1533   
4794 07 May 18 nicklas 1534   // Get the QiaCube position from the alignment
4794 07 May 18 nicklas 1535   property.QiaCubePosition = function(alignment)
4794 07 May 18 nicklas 1536   {
4794 07 May 18 nicklas 1537     return alignment.rna.QIACUBE_POSITION;
4794 07 May 18 nicklas 1538   }
4794 07 May 18 nicklas 1539   
4794 07 May 18 nicklas 1540   // Get the LibPlate position from the alignment
4794 07 May 18 nicklas 1541   property.LibPlatePosition = function(alignment)
4794 07 May 18 nicklas 1542   {
4794 07 May 18 nicklas 1543     return alignment.lib.bioWell.location;
4794 07 May 18 nicklas 1544   }
4794 07 May 18 nicklas 1545   
4794 07 May 18 nicklas 1546   return property;
4794 07 May 18 nicklas 1547 }();
4794 07 May 18 nicklas 1548
4794 07 May 18 nicklas 1549 /**
4794 07 May 18 nicklas 1550   Helper functions for generating various HTML outputs.
4794 07 May 18 nicklas 1551 */
4794 07 May 18 nicklas 1552 var HTMLHelper = function()
4794 07 May 18 nicklas 1553 {
4794 07 May 18 nicklas 1554   var helper = {};
4794 07 May 18 nicklas 1555   
4794 07 May 18 nicklas 1556   var colorMatchTargets = {};
4794 07 May 18 nicklas 1557   var colorMatchIndex = 0;
4794 07 May 18 nicklas 1558   
7209 26 May 23 nicklas 1559   var SHORT_PIPELINE = {
7209 26 May 23 nicklas 1560     'RNAseq/Hisat/StringTie': 'RNAseq',
7209 26 May 23 nicklas 1561     'DNA/Normal/WGS': 'WGS/Normal',
7209 26 May 23 nicklas 1562     'DNA/Genotyping': 'Genotyping'
7209 26 May 23 nicklas 1563   };
7209 26 May 23 nicklas 1564   
4794 07 May 18 nicklas 1565   /**
4794 07 May 18 nicklas 1566     Create the link for a QiaCube run. It will typically show the date#run@pos
4794 07 May 18 nicklas 1567     and will also output colormatch functionality for either the entire QiaCube run 
4794 07 May 18 nicklas 1568     or the position (in filtered view)
4794 07 May 18 nicklas 1569   */
4797 08 May 18 nicklas 1570   helper.qiaCubeLink = function(qiaCubeDate, qiaCubeRun, qiaCubePos, filterValue, shortForm)
4794 07 May 18 nicklas 1571   {
6589 21 Feb 22 nicklas 1572     if (!qiaCubeDate) return '';
4794 07 May 18 nicklas 1573     var runId = qiaCubeDate+'#'+qiaCubeRun;
4794 07 May 18 nicklas 1574     var runPosId = runId+'@'+qiaCubePos;
4794 07 May 18 nicklas 1575     var html = '';
4794 07 May 18 nicklas 1576     if (!shortForm)
4794 07 May 18 nicklas 1577     {
4794 07 May 18 nicklas 1578       html += '<span class="link qiacube-link" data-qiacuberun="'+runId+'" title="Filter on this QiaCube run">';
4794 07 May 18 nicklas 1579       html += Reggie.reformatDate(qiaCubeDate) + '#' + qiaCubeRun;
4794 07 May 18 nicklas 1580       html += '</span>';
4794 07 May 18 nicklas 1581     }
4794 07 May 18 nicklas 1582     html += '@'+qiaCubePos;
4797 08 May 18 nicklas 1583     var isFiltered = filterValue == runId;
4794 07 May 18 nicklas 1584     return HTMLHelper.colorMatch(isFiltered ? runPosId : runId, html, isFiltered ? 'Click to highlight this position' : 'Click to highlight this QiaCube');
4794 07 May 18 nicklas 1585   }
4794 07 May 18 nicklas 1586   
4794 07 May 18 nicklas 1587   /**
4794 07 May 18 nicklas 1588     Create the link for a LibPlate position. It will typically show the name and position
4794 07 May 18 nicklas 1589     and will also output colormatch functionality for either the entire LibPlate 
4794 07 May 18 nicklas 1590     or the position (in filtered view).
4794 07 May 18 nicklas 1591   */
4797 08 May 18 nicklas 1592   helper.libPlateLink = function(libPlateName, libPlatePos, filterValue, shortForm)
4794 07 May 18 nicklas 1593   {
6589 21 Feb 22 nicklas 1594     if (!libPlateName) return '';
4794 07 May 18 nicklas 1595     var html = '';
4794 07 May 18 nicklas 1596     if (!shortForm)
4794 07 May 18 nicklas 1597     {
4794 07 May 18 nicklas 1598       html = '<span class="link libplate-link" data-libplate="'+libPlateName+'" title="Filter on this plate">';
4794 07 May 18 nicklas 1599       html += Strings.encodeTags(libPlateName);
4794 07 May 18 nicklas 1600       html += '</span>&nbsp;';
4794 07 May 18 nicklas 1601     }
4794 07 May 18 nicklas 1602     html += libPlatePos;
4797 08 May 18 nicklas 1603     var isFiltered = filterValue == libPlateName;
4794 07 May 18 nicklas 1604     return HTMLHelper.colorMatch(isFiltered ? libPlateName+'@'+libPlatePos : libPlateName, html, isFiltered ? 'Click to highlight this position' : 'Click to highlight this LibPlate');
4794 07 May 18 nicklas 1605   }
7209 26 May 23 nicklas 1606
7209 26 May 23 nicklas 1607   /**
7209 26 May 23 nicklas 1608     Output unlinked plate position.
7209 26 May 23 nicklas 1609   */
7209 26 May 23 nicklas 1610   helper.platePos = function(plateName, platePos)
7209 26 May 23 nicklas 1611   {
7209 26 May 23 nicklas 1612     if (!plateName) return '';
7209 26 May 23 nicklas 1613     var html = Strings.encodeTags(plateName)+'&nbsp;'+Strings.encodeTags(platePos);
7209 26 May 23 nicklas 1614     return HTMLHelper.colorMatch(plateName, html, 'Click to highlight this Plate');
7209 26 May 23 nicklas 1615   }
7209 26 May 23 nicklas 1616
4794 07 May 18 nicklas 1617   
6592 21 Feb 22 nicklas 1618   helper.beadChipLink = function(beadChipName, beadChipPosition)
6590 21 Feb 22 nicklas 1619   {
6592 21 Feb 22 nicklas 1620     if (!beadChipName) return '';
6592 21 Feb 22 nicklas 1621     var html = Strings.encodeTags(beadChipName)+'&nbsp;'+Strings.encodeTags(beadChipPosition);
6592 21 Feb 22 nicklas 1622     return HTMLHelper.colorMatch(beadChipName, html, 'Click to highlight this BeadChip');
6590 21 Feb 22 nicklas 1623   }
6590 21 Feb 22 nicklas 1624   
4799 09 May 18 nicklas 1625   /**
7209 26 May 23 nicklas 1626     Due to space constrains we display a shorter version of the pipeline annotation.
7209 26 May 23 nicklas 1627   */
7209 26 May 23 nicklas 1628   helper.shortPipeline = function(pipeline)
7209 26 May 23 nicklas 1629   {
7209 26 May 23 nicklas 1630     return SHORT_PIPELINE[pipeline] || Strings.encodeTags(pipeline);
7209 26 May 23 nicklas 1631   }
7209 26 May 23 nicklas 1632   
7209 26 May 23 nicklas 1633   /**
4799 09 May 18 nicklas 1634     Return 'name2' with markup indicating which parts of the name
4799 09 May 18 nicklas 1635     are common with 'name1'.
4799 09 May 18 nicklas 1636   */
4799 09 May 18 nicklas 1637   helper.tagCommonPartOfName = function(name1, name2)
4799 09 May 18 nicklas 1638   {
4799 09 May 18 nicklas 1639     var n1 = name1.split('.');
4799 09 May 18 nicklas 1640     var n2 = name2.split('.');
4799 09 May 18 nicklas 1641     var i = 0;
4799 09 May 18 nicklas 1642     
4799 09 May 18 nicklas 1643     var common = '';
4799 09 May 18 nicklas 1644     var sep = '.';
4799 09 May 18 nicklas 1645     while (i < n1.length && i < n2.length && n1[i] == n2[i])
4799 09 May 18 nicklas 1646     {
4799 09 May 18 nicklas 1647       common += n1[i] + sep;
4799 09 May 18 nicklas 1648       i++;
4799 09 May 18 nicklas 1649     }
4799 09 May 18 nicklas 1650     
4799 09 May 18 nicklas 1651     var diff = '';
4799 09 May 18 nicklas 1652     sep = '';
4799 09 May 18 nicklas 1653     while (i < n2.length)
4799 09 May 18 nicklas 1654     {
4799 09 May 18 nicklas 1655       diff += sep + n2[i];
4799 09 May 18 nicklas 1656       i++;
4799 09 May 18 nicklas 1657       sep = '.';
4799 09 May 18 nicklas 1658     }
4799 09 May 18 nicklas 1659     
4799 09 May 18 nicklas 1660     var html = '';
4799 09 May 18 nicklas 1661     if (common.length > 0) html += '<span class="commonpart">'+Strings.encodeTags(common)+'</span>';
4799 09 May 18 nicklas 1662     if (diff.length > 0) html += '<span class="diffpart">'+Strings.encodeTags(diff)+'</span>';
4799 09 May 18 nicklas 1663     return html;
4799 09 May 18 nicklas 1664   }
4799 09 May 18 nicklas 1665
4799 09 May 18 nicklas 1666   
4794 07 May 18 nicklas 1667   // Creates a "ColorMatch" tag for the given text
4794 07 May 18 nicklas 1668   helper.colorMatch = function(plainText, formattedText, tooltip)
4794 07 May 18 nicklas 1669   {
4794 07 May 18 nicklas 1670     var target = colorMatchTargets[plainText];
4794 07 May 18 nicklas 1671     if (!target)
4794 07 May 18 nicklas 1672     {
4794 07 May 18 nicklas 1673       colorMatchIndex++;
4794 07 May 18 nicklas 1674       target = 'CM'+colorMatchIndex;
4794 07 May 18 nicklas 1675       colorMatchTargets[plainText] = target;
4794 07 May 18 nicklas 1676     }
4794 07 May 18 nicklas 1677     if (!formattedText) formattedText = Strings.encodeTags(plainText);
4794 07 May 18 nicklas 1678
4794 07 May 18 nicklas 1679     var html = '<span class="colormatch" data-match="'+target+'"';
4794 07 May 18 nicklas 1680     if (tooltip) html += ' title="'+tooltip+'"';
4794 07 May 18 nicklas 1681     html += '>'+formattedText+'</span>';
4794 07 May 18 nicklas 1682     return html;
4794 07 May 18 nicklas 1683   }
4794 07 May 18 nicklas 1684   
4817 21 May 18 nicklas 1685   
4976 24 Sep 18 nicklas 1686   helper.reprocessOptions = function(aligned, recommendReprocess)
4817 21 May 18 nicklas 1687   {
4820 22 May 18 nicklas 1688     var id = 'reprocess.'+aligned.tmpId;
4976 24 Sep 18 nicklas 1689     var title = '';
4976 24 Sep 18 nicklas 1690     
5001 04 Oct 18 nicklas 1691     var html = '';
4980 25 Sep 18 nicklas 1692     html += '<select id="'+id+'" class="reprocess-options" name="'+id+'" '+(recommendReprocess? 'title="Re-processing is recommended"':'')+'>';
4998 03 Oct 18 nicklas 1693     if (!aligned.currentReProcess) html += '<option value="" selected>&nbsp;';
4998 03 Oct 18 nicklas 1694     html += helper.reprocessOption('Specimen', 'specimen', aligned.currentReProcess, aligned.specimen.DO_NOT_USE);
4998 03 Oct 18 nicklas 1695     html += helper.reprocessOption('Lysate', 'lysate', aligned.currentReProcess, aligned.lysate.DO_NOT_USE);
4998 03 Oct 18 nicklas 1696     html += helper.reprocessOption('RNA', 'rna', aligned.currentReProcess, aligned.rna.DO_NOT_USE);
5001 04 Oct 18 nicklas 1697     html += '</select>';
4817 21 May 18 nicklas 1698     
4997 03 Oct 18 nicklas 1699     if (aligned.currentReProcess != null)
4817 21 May 18 nicklas 1700     {
4997 03 Oct 18 nicklas 1701       html += '<img src="../images/info.png" title="Re-processing is already scheduled from '+aligned.currentReProcess+'">';
4817 21 May 18 nicklas 1702     }
4817 21 May 18 nicklas 1703     
4817 21 May 18 nicklas 1704     return html;
4817 21 May 18 nicklas 1705   }
4817 21 May 18 nicklas 1706   
4980 25 Sep 18 nicklas 1707   helper.reprocessOption = function(text, value, currentReProcess, doNotUse)
4980 25 Sep 18 nicklas 1708   {
4980 25 Sep 18 nicklas 1709     var opt = '<option ';
4980 25 Sep 18 nicklas 1710     if (currentReProcess==text)
4980 25 Sep 18 nicklas 1711     {
4980 25 Sep 18 nicklas 1712       opt += 'value="" selected';
4980 25 Sep 18 nicklas 1713     }
4980 25 Sep 18 nicklas 1714     else
4980 25 Sep 18 nicklas 1715     {
4980 25 Sep 18 nicklas 1716       opt += 'value="'+value+'"';
4980 25 Sep 18 nicklas 1717     }
4980 25 Sep 18 nicklas 1718     if (doNotUse) opt += ' class="donotuse" title="'+text+' is marked as DoNotUse"';  
4980 25 Sep 18 nicklas 1719     opt += '>'+text;
4980 25 Sep 18 nicklas 1720     if (doNotUse) opt += ' (!)';
4980 25 Sep 18 nicklas 1721     return opt;
4980 25 Sep 18 nicklas 1722   }
4980 25 Sep 18 nicklas 1723   
4970 13 Sep 18 nicklas 1724   helper.qcCommentInput = function(aligned)
4970 13 Sep 18 nicklas 1725   {
4970 13 Sep 18 nicklas 1726     var id = 'comment.'+aligned.tmpId;
4970 13 Sep 18 nicklas 1727     html = '<input type="text" id="'+id+'" name="'+id+'" value="'+Strings.encodeTags(aligned.QC_GENOTYPE_COMMENT)+'">';
4970 13 Sep 18 nicklas 1728     return html;
4970 13 Sep 18 nicklas 1729   }
4970 13 Sep 18 nicklas 1730   
4970 13 Sep 18 nicklas 1731   helper.qcFlagCheckbox = function(aligned)
4970 13 Sep 18 nicklas 1732   {
4970 13 Sep 18 nicklas 1733     var id = 'flag.'+aligned.tmpId;
4970 13 Sep 18 nicklas 1734     html = '<input type="checkbox" id="'+id+'" name="'+id+'">';
4970 13 Sep 18 nicklas 1735     return html;
4970 13 Sep 18 nicklas 1736   }
4970 13 Sep 18 nicklas 1737
4981 25 Sep 18 nicklas 1738   helper.okToUseOptions = function(aligned, filterType)
4981 25 Sep 18 nicklas 1739   {
4981 25 Sep 18 nicklas 1740     var html = '';
4981 25 Sep 18 nicklas 1741     if (aligned.flagged && !aligned.DO_NOT_USE) 
4981 25 Sep 18 nicklas 1742     {
4981 25 Sep 18 nicklas 1743       var idOkToUse = 'oktouse.'+aligned.tmpId;
4981 25 Sep 18 nicklas 1744       var okValue = filterType == 'QIACUBE' ? 'ok-rna' : 'ok-library';
4981 25 Sep 18 nicklas 1745       html += '<input type="checkbox" value="'+okValue+'" id="'+idOkToUse+'" name="'+idOkToUse+'" class="oktouse" title="Check this to indicate that the flagged item is ok to use.">';
4981 25 Sep 18 nicklas 1746     }
4981 25 Sep 18 nicklas 1747     return html;
4981 25 Sep 18 nicklas 1748   }
4981 25 Sep 18 nicklas 1749   
4975 21 Sep 18 nicklas 1750   /**
4975 21 Sep 18 nicklas 1751     We generate a checkbox (if the item is flagged) and a 
4975 21 Sep 18 nicklas 1752     selection list with "DoNotUse" options.
4975 21 Sep 18 nicklas 1753   */
5018 10 Oct 18 nicklas 1754   helper.resolveOptions = function(aligned, filterType, singleAlignment)
4975 21 Sep 18 nicklas 1755   {
4975 21 Sep 18 nicklas 1756     var html = '';
5024 15 Oct 18 nicklas 1757     var idDoNotUse = 'donotuse.'+aligned.tmpId;
5024 15 Oct 18 nicklas 1758     var cls = aligned.flagged && filterType != 'HET' ? 'required' : '';
5024 15 Oct 18 nicklas 1759   
5024 15 Oct 18 nicklas 1760     html += '<select id="'+idDoNotUse+'" name="'+idDoNotUse+'" class="donotuse-options '+cls+'">';
5024 15 Oct 18 nicklas 1761     html += '<option value="">&nbsp;';
5024 15 Oct 18 nicklas 1762     if (filterType != 'QIACUBE' || singleAlignment)
4975 21 Sep 18 nicklas 1763     {
5024 15 Oct 18 nicklas 1764       html += '<option value="library">Library';
4975 21 Sep 18 nicklas 1765     }
5024 15 Oct 18 nicklas 1766     if (aligned.preNormalizedRna)
4975 21 Sep 18 nicklas 1767     {
5024 15 Oct 18 nicklas 1768       html += '<option value="prenormalized">PreNormalizedRNA';
4975 21 Sep 18 nicklas 1769     }
5024 15 Oct 18 nicklas 1770     html += '<option value="rna">RNA';
5024 15 Oct 18 nicklas 1771     html += '<option value="lysate">Lysate';
5024 15 Oct 18 nicklas 1772     html += '<option value="specimen">Specimen';
5024 15 Oct 18 nicklas 1773     html += '</select>';
4975 21 Sep 18 nicklas 1774
4975 21 Sep 18 nicklas 1775     return html;
4975 21 Sep 18 nicklas 1776   }
4981 25 Sep 18 nicklas 1777   
4981 25 Sep 18 nicklas 1778   helper.futureGtOptions = function(aligned, filterType)
4981 25 Sep 18 nicklas 1779   {
4981 25 Sep 18 nicklas 1780     var html = '';
5024 15 Oct 18 nicklas 1781     var idFutureGt = 'futuregt.'+aligned.tmpId;
5024 15 Oct 18 nicklas 1782     html += '<input type="checkbox" id="'+idFutureGt+'" name="'+idFutureGt+'" disabled title="Check this to use the alignment in future genotype checks.">';
4981 25 Sep 18 nicklas 1783     return html;
4981 25 Sep 18 nicklas 1784   }
4975 21 Sep 18 nicklas 1785
4981 25 Sep 18 nicklas 1786
4975 21 Sep 18 nicklas 1787   helper.resolveComment = function(aligned)
4975 21 Sep 18 nicklas 1788   {
4980 25 Sep 18 nicklas 1789     var html = '';
5024 15 Oct 18 nicklas 1790     var id = 'resolvecomment.'+aligned.tmpId;
5024 15 Oct 18 nicklas 1791     html += '<input type="text" id="'+id+'" name="'+id+'" value="'+Strings.encodeTags(aligned.QC_GENOTYPE_COMMENT)+'">';
4975 21 Sep 18 nicklas 1792     return html;
4975 21 Sep 18 nicklas 1793   }
4975 21 Sep 18 nicklas 1794
4975 21 Sep 18 nicklas 1795   
4794 07 May 18 nicklas 1796   return helper;
4794 07 May 18 nicklas 1797 }();