extensions/net.sf.basedb.reggie/trunk/resources/libprep/pool_protocol.js

Code
Comments
Other
Rev Date Author Line
2662 12 Sep 14 nicklas 1 var Protocol = function()
2662 12 Sep 14 nicklas 2 {
2662 12 Sep 14 nicklas 3   var protocol = {};
2702 26 Sep 14 nicklas 4   var debug = 0;
2662 12 Sep 14 nicklas 5   
2662 12 Sep 14 nicklas 6   var pools;
2662 12 Sep 14 nicklas 7   var libPlate;
2662 12 Sep 14 nicklas 8
2662 12 Sep 14 nicklas 9   var POOL_CURRENT_SCHEMA;
2662 12 Sep 14 nicklas 10   var POOL_CURRENT_BARCODE_VARIANT;
2662 12 Sep 14 nicklas 11
2662 12 Sep 14 nicklas 12   // Page initialization
2662 12 Sep 14 nicklas 13   protocol.initPage = function()
2662 12 Sep 14 nicklas 14   {
2662 12 Sep 14 nicklas 15     var pageId = Doc.getPageId();
2662 12 Sep 14 nicklas 16     if (pageId == 'protocol')
2662 12 Sep 14 nicklas 17     {
2662 12 Sep 14 nicklas 18       Buttons.addClickHandler('print-button', Wizard.goPrint);  
2662 12 Sep 14 nicklas 19       protocol.initializeProtocol();
2662 12 Sep 14 nicklas 20     }
2662 12 Sep 14 nicklas 21     else
2662 12 Sep 14 nicklas 22     {
2662 12 Sep 14 nicklas 23       Events.addEventHandler('bioplate', 'change', protocol.bioplateOnChange);
2662 12 Sep 14 nicklas 24       Events.addEventHandler('listview', 'click', protocol.viewProtocol);
2662 12 Sep 14 nicklas 25       Events.addEventHandler('plateview', 'click', protocol.viewProtocol);
2662 12 Sep 14 nicklas 26
2662 12 Sep 14 nicklas 27       var url = '../Pool.servlet?ID='+App.getSessionId();
2662 12 Sep 14 nicklas 28       url += '&cmd=GetUnprocessedPools';
2662 12 Sep 14 nicklas 29       Wizard.showLoadingAnimation('Loading pools...');
2662 12 Sep 14 nicklas 30       Wizard.asyncJsonRequest(url, protocol.initializeStep1);
2662 12 Sep 14 nicklas 31     }
2662 12 Sep 14 nicklas 32   }
2662 12 Sep 14 nicklas 33
2662 12 Sep 14 nicklas 34
2662 12 Sep 14 nicklas 35   protocol.initializeStep1 = function(response)
2662 12 Sep 14 nicklas 36   {
2662 12 Sep 14 nicklas 37     var frm = document.forms['reggie'];
2662 12 Sep 14 nicklas 38     pools = response.pools;
2662 12 Sep 14 nicklas 39     
2662 12 Sep 14 nicklas 40     // We get a list of pools from the servlet
2662 12 Sep 14 nicklas 41     // Each pool has a list of libraries 
2662 12 Sep 14 nicklas 42     // We want to find the Library bioplates that are unique
2662 12 Sep 14 nicklas 43     // within a pool (eg. all libraries are from the same bioplate)
2662 12 Sep 14 nicklas 44     if (pools.length == 0)
2662 12 Sep 14 nicklas 45     {
2662 12 Sep 14 nicklas 46       Wizard.setFatalError('No pools available for processing.');
2662 12 Sep 14 nicklas 47       return;
2662 12 Sep 14 nicklas 48     }
2662 12 Sep 14 nicklas 49     
2662 12 Sep 14 nicklas 50     var poolsList = frm.pools;
2662 12 Sep 14 nicklas 51     var plateList = frm.bioplate;
2662 12 Sep 14 nicklas 52     var libPlates = [];
2662 12 Sep 14 nicklas 53     for (var poolNo=0; poolNo < pools.length; poolNo++)
2662 12 Sep 14 nicklas 54     {
2662 12 Sep 14 nicklas 55       var pool = pools[poolNo];
2662 12 Sep 14 nicklas 56       
2662 12 Sep 14 nicklas 57       // Shortcut to single-plate pools
2662 12 Sep 14 nicklas 58       var libPlateForPool = pool.libPlates.length == 1 && !pool.isManual ? pool.libPlates[0] : null;
2662 12 Sep 14 nicklas 59       pool.libPlate = libPlateForPool;
2662 12 Sep 14 nicklas 60
2662 12 Sep 14 nicklas 61       // If the pool has a single library bioplate add it to the selection list
2662 12 Sep 14 nicklas 62       // If the pool doesn't have a single library bioplate, nothing is added to
2662 12 Sep 14 nicklas 63       // the list and the pool can only be selected when the 'manual pools' option is
2662 12 Sep 14 nicklas 64       // active for the bioplates list
2662 12 Sep 14 nicklas 65       if (libPlateForPool != null && !libPlates[libPlateForPool.name])
2662 12 Sep 14 nicklas 66       {
2662 12 Sep 14 nicklas 67         libPlates[libPlateForPool.name] = libPlateForPool;
2662 12 Sep 14 nicklas 68         var plateOption = new Option(libPlateForPool.name, libPlateForPool.id);
2662 12 Sep 14 nicklas 69         plateOption.plate = libPlateForPool;
2662 12 Sep 14 nicklas 70         plateList[plateList.length] = plateOption;
2662 12 Sep 14 nicklas 71       }
2662 12 Sep 14 nicklas 72
2662 12 Sep 14 nicklas 73     }
2662 12 Sep 14 nicklas 74     if (plateList.length > 1) plateList.selectedIndex = 1;
2662 12 Sep 14 nicklas 75
2662 12 Sep 14 nicklas 76     protocol.bioplateOnChange();
2662 12 Sep 14 nicklas 77     Doc.show('step-1');
2662 12 Sep 14 nicklas 78     Doc.show('gonext');
2662 12 Sep 14 nicklas 79   }
2662 12 Sep 14 nicklas 80   
2662 12 Sep 14 nicklas 81   
2662 12 Sep 14 nicklas 82   // Add pools to the pools list based on the bioplate selection
2662 12 Sep 14 nicklas 83   protocol.bioplateOnChange = function()
2662 12 Sep 14 nicklas 84   {
2662 12 Sep 14 nicklas 85     var frm = document.forms['reggie'];
2662 12 Sep 14 nicklas 86     
2662 12 Sep 14 nicklas 87     var libPlateId = parseInt(frm.bioplate.value);
2662 12 Sep 14 nicklas 88
2662 12 Sep 14 nicklas 89     // Clear current list
2662 12 Sep 14 nicklas 90     frm.pools.length = 0;
2662 12 Sep 14 nicklas 91     
2662 12 Sep 14 nicklas 92     for (var poolNo = 0; poolNo < pools.length; poolNo++)
2662 12 Sep 14 nicklas 93     {
2662 12 Sep 14 nicklas 94       var pool = pools[poolNo];
2662 12 Sep 14 nicklas 95       // If a libplate is selected, only show pools that have all libraries from that plate
2662 12 Sep 14 nicklas 96       // If no libplate is selected, only show pools that have libraries from multiple plates
2662 12 Sep 14 nicklas 97       var addPool = (libPlateId &&  pool.libPlate && pool.libPlate.id == libPlateId) || (!libPlateId && pool.libPlate == null);
2662 12 Sep 14 nicklas 98       if (addPool)
2662 12 Sep 14 nicklas 99       {
2662 12 Sep 14 nicklas 100         var name = pool.name;
2662 12 Sep 14 nicklas 101         if (pool.libPlate == null)
2662 12 Sep 14 nicklas 102         {
2662 12 Sep 14 nicklas 103           
2662 12 Sep 14 nicklas 104           name += ' - ';
2662 12 Sep 14 nicklas 105           var numPlates = pool.libPlates.length;
2662 12 Sep 14 nicklas 106           var title = '';
2662 12 Sep 14 nicklas 107           if (numPlates <= 2)
2662 12 Sep 14 nicklas 108           {
2662 12 Sep 14 nicklas 109             for (var plateNo=0; plateNo < numPlates; plateNo++)
2662 12 Sep 14 nicklas 110             {
2662 12 Sep 14 nicklas 111               var libPlate = pool.libPlates[plateNo];
2662 12 Sep 14 nicklas 112               if (plateNo > 0) name += ', ';
2662 12 Sep 14 nicklas 113               name += libPlate.name;
2662 12 Sep 14 nicklas 114             }
2662 12 Sep 14 nicklas 115           }
2662 12 Sep 14 nicklas 116           else
2662 12 Sep 14 nicklas 117           {
2662 12 Sep 14 nicklas 118             name += pool.libPlates[0].name + ' + ' + (numPlates-1) + ' more...';
2662 12 Sep 14 nicklas 119             for (var plateNo=0; plateNo < numPlates; plateNo++)
2662 12 Sep 14 nicklas 120             {
2662 12 Sep 14 nicklas 121               var libPlate = pool.libPlates[plateNo];
2662 12 Sep 14 nicklas 122               if (plateNo > 0) title += ', ';
2662 12 Sep 14 nicklas 123               title += libPlate.name;
2662 12 Sep 14 nicklas 124             }
2662 12 Sep 14 nicklas 125           }
2662 12 Sep 14 nicklas 126         }
2662 12 Sep 14 nicklas 127
4583 21 Sep 17 nicklas 128         var option = new Option(name, pool.id, false, libPlateId || frm.pools.length == 0);
2662 12 Sep 14 nicklas 129         option.pool = pool;
2662 12 Sep 14 nicklas 130         frm.pools[frm.pools.length] = option;
2662 12 Sep 14 nicklas 131       }
2662 12 Sep 14 nicklas 132     }
2662 12 Sep 14 nicklas 133     
2662 12 Sep 14 nicklas 134     Wizard.setInputStatus('pools');
2662 12 Sep 14 nicklas 135     if (libPlateId)
2662 12 Sep 14 nicklas 136     {
2662 12 Sep 14 nicklas 137       frm.pools.disabled = true;
2662 12 Sep 14 nicklas 138       Doc.removeClass('plateview', 'disabled');
2662 12 Sep 14 nicklas 139     }
2662 12 Sep 14 nicklas 140     else
2662 12 Sep 14 nicklas 141     {
2662 12 Sep 14 nicklas 142       frm.pools.disabled = false;
2662 12 Sep 14 nicklas 143       Doc.addClass('plateview', 'disabled');
2662 12 Sep 14 nicklas 144     }
2662 12 Sep 14 nicklas 145   }
2662 12 Sep 14 nicklas 146   
2662 12 Sep 14 nicklas 147   protocol.viewProtocol = function(event)
2662 12 Sep 14 nicklas 148   {
2662 12 Sep 14 nicklas 149     if (event.currentTarget.className.indexOf('disabled')>=0) return;
2662 12 Sep 14 nicklas 150     
2662 12 Sep 14 nicklas 151     var frm = document.forms['reggie'];
2662 12 Sep 14 nicklas 152     var libPlateId = parseInt(frm.bioplate.value);
2662 12 Sep 14 nicklas 153     
2662 12 Sep 14 nicklas 154     if (libPlateId == 0)
2662 12 Sep 14 nicklas 155     {
2662 12 Sep 14 nicklas 156       // 'manual' option selected, check that at least one pool is selected
2662 12 Sep 14 nicklas 157       var numSelectedPools = 0;
2662 12 Sep 14 nicklas 158       for (var poolNo = 0; poolNo < frm.pools.length; poolNo++)
2662 12 Sep 14 nicklas 159       {
2662 12 Sep 14 nicklas 160         if (frm.pools[poolNo].selected) numSelectedPools++;
2662 12 Sep 14 nicklas 161       }
2662 12 Sep 14 nicklas 162       
2662 12 Sep 14 nicklas 163       if (numSelectedPools == 0)
2662 12 Sep 14 nicklas 164       {
2662 12 Sep 14 nicklas 165         Wizard.setInputStatus('pools', 'invalid', 'Select at least one pool');
2662 12 Sep 14 nicklas 166         Wizard.notifyError();
2662 12 Sep 14 nicklas 167         return;
2662 12 Sep 14 nicklas 168       }
2662 12 Sep 14 nicklas 169       Wizard.setInputStatus('pools', 'valid');
2662 12 Sep 14 nicklas 170     }
2662 12 Sep 14 nicklas 171
2662 12 Sep 14 nicklas 172     var type = Data.get(event.currentTarget, 'protocol-type');
2662 12 Sep 14 nicklas 173     frm.pools.disabled = false;
2662 12 Sep 14 nicklas 174     frm.view.value = type;
2662 12 Sep 14 nicklas 175     frm.submit();
2662 12 Sep 14 nicklas 176     frm.pools.disabled = (libPlateId != 0);
2662 12 Sep 14 nicklas 177   }
2662 12 Sep 14 nicklas 178
2662 12 Sep 14 nicklas 179   protocol.loadLibPlate = function()
2662 12 Sep 14 nicklas 180   {
2662 12 Sep 14 nicklas 181     var libPlateId = Data.get('page-data', 'libplate');
2662 12 Sep 14 nicklas 182     var url = '../Pool.servlet?ID='+App.getSessionId();
2662 12 Sep 14 nicklas 183     url += '&cmd=GetLibPlateInfo&bioplate='+libPlateId;    
2662 12 Sep 14 nicklas 184     Wizard.showLoadingAnimation('Loading library bioplate information...');
2662 12 Sep 14 nicklas 185     Wizard.asyncJsonRequest(url, protocol.initializeProtocol);
2662 12 Sep 14 nicklas 186   }
2662 12 Sep 14 nicklas 187   
2662 12 Sep 14 nicklas 188   protocol.loadPools = function()
2662 12 Sep 14 nicklas 189   {
2662 12 Sep 14 nicklas 190     var pools = Data.get('page-data', 'pools');
2662 12 Sep 14 nicklas 191     var libPlateId = Data.get('page-data', 'libplate');
2662 12 Sep 14 nicklas 192
2662 12 Sep 14 nicklas 193     var url = '../Pool.servlet?ID='+App.getSessionId();
2662 12 Sep 14 nicklas 194     url += '&cmd=GetLibraryInfoForPools&pools='+pools+'&bioplate='+libPlateId;
2662 12 Sep 14 nicklas 195
2662 12 Sep 14 nicklas 196     Wizard.showLoadingAnimation('Loading pooled library information...');
2662 12 Sep 14 nicklas 197     Wizard.asyncJsonRequest(url, protocol.initializeProtocol);
2662 12 Sep 14 nicklas 198   }
2662 12 Sep 14 nicklas 199   
2662 12 Sep 14 nicklas 200   protocol.initializeProtocol = function(response)
2662 12 Sep 14 nicklas 201   {
2662 12 Sep 14 nicklas 202     var libPlateId = Data.int('page-data', 'libplate');
2662 12 Sep 14 nicklas 203     var view = Data.get('page-data', 'view');
2662 12 Sep 14 nicklas 204
2662 12 Sep 14 nicklas 205     if (!response)
2662 12 Sep 14 nicklas 206     {
2662 12 Sep 14 nicklas 207       if (libPlateId)
2662 12 Sep 14 nicklas 208       {
2662 12 Sep 14 nicklas 209         protocol.loadLibPlate(libPlateId);
2662 12 Sep 14 nicklas 210       }
2662 12 Sep 14 nicklas 211       else
2662 12 Sep 14 nicklas 212       {
2662 12 Sep 14 nicklas 213         protocol.loadPools();
2662 12 Sep 14 nicklas 214       }
2662 12 Sep 14 nicklas 215       return;
2662 12 Sep 14 nicklas 216     }
2662 12 Sep 14 nicklas 217     else if (response.libPlate)
2662 12 Sep 14 nicklas 218     {
2662 12 Sep 14 nicklas 219       libPlate = response.libPlate;
2662 12 Sep 14 nicklas 220       POOL_CURRENT_SCHEMA = PoolSchema.getById(libPlate.poolSchema);
2662 12 Sep 14 nicklas 221       POOL_CURRENT_BARCODE_VARIANT = PoolSchema.getBarcodeVariantByName(POOL_CURRENT_SCHEMA, libPlate.barcodeVariant);
2662 12 Sep 14 nicklas 222       protocol.loadPools();
2662 12 Sep 14 nicklas 223       return;
2662 12 Sep 14 nicklas 224     }
2662 12 Sep 14 nicklas 225     
2662 12 Sep 14 nicklas 226     pools = response.pools;
2662 12 Sep 14 nicklas 227     var poolInfo = response.poolInfo;
2662 12 Sep 14 nicklas 228
2662 12 Sep 14 nicklas 229     var pageTitle = 'Lab protocol for pooling ';
2662 12 Sep 14 nicklas 230     // Pre-process the Library items
2662 12 Sep 14 nicklas 231     for (var i = 0; i < pools.length; i++)
2662 12 Sep 14 nicklas 232     {
2662 12 Sep 14 nicklas 233       var pool = pools[i];
2662 12 Sep 14 nicklas 234       if (i > 0) pageTitle += ', '
2662 12 Sep 14 nicklas 235       pageTitle += ' ' + pool.name;
2662 12 Sep 14 nicklas 236       
2662 12 Sep 14 nicklas 237       // Calculate some pool quantities
2662 12 Sep 14 nicklas 238       pool.volume = 1000 * pool.originalQuantity / pool.conc;
2662 12 Sep 14 nicklas 239
2662 12 Sep 14 nicklas 240       for (var libNo = 0; libNo < pool.libraries.length; libNo++)
2662 12 Sep 14 nicklas 241       {
2662 12 Sep 14 nicklas 242         var lib = pool.libraries[libNo];
2662 12 Sep 14 nicklas 243         PoolMix.calculateLibVolumeForProtocol(lib, pool.targetPoolMolarity, pool.targetVolumePerLib, pool.mixingStrategy, true);
2662 12 Sep 14 nicklas 244         PoolMix.calculateEbVolume(lib, pool.targetPoolMolarity, pool.targetVolumePerLib, pool.mixingStrategy);
2662 12 Sep 14 nicklas 245         protocol.checkAndPreProcessLibrary(lib, pool, POOL_CURRENT_SCHEMA, POOL_CURRENT_BARCODE_VARIANT, view);        
2662 12 Sep 14 nicklas 246       }
2662 12 Sep 14 nicklas 247
2662 12 Sep 14 nicklas 248       pool.extra = PoolMix.calculateFinalPoolInfo(pool.libraries, pool.targetPoolMolarity, pool.targetVolumePerLib, pool.mixingStrategy);
2662 12 Sep 14 nicklas 249     }
2662 12 Sep 14 nicklas 250     
2662 12 Sep 14 nicklas 251     if (!libPlate)
2662 12 Sep 14 nicklas 252     {
2662 12 Sep 14 nicklas 253       document.title = pageTitle;
2662 12 Sep 14 nicklas 254     }
2662 12 Sep 14 nicklas 255     
2662 12 Sep 14 nicklas 256     if (view == 'list')
2662 12 Sep 14 nicklas 257     {
2662 12 Sep 14 nicklas 258       protocol.viewAsList(pools, POOL_CURRENT_SCHEMA, POOL_CURRENT_BARCODE_VARIANT);
2662 12 Sep 14 nicklas 259     }
2662 12 Sep 14 nicklas 260     else
2662 12 Sep 14 nicklas 261     {
2662 12 Sep 14 nicklas 262       protocol.viewAsPlate(pools, POOL_CURRENT_SCHEMA, POOL_CURRENT_BARCODE_VARIANT);
2662 12 Sep 14 nicklas 263     }
2662 12 Sep 14 nicklas 264     
2662 12 Sep 14 nicklas 265   }
2662 12 Sep 14 nicklas 266   
2662 12 Sep 14 nicklas 267   
2662 12 Sep 14 nicklas 268   protocol.checkAndPreProcessLibrary = function(lib, pool, schema, barcodeVariant, view)
2662 12 Sep 14 nicklas 269   {
2662 12 Sep 14 nicklas 270     var well = lib.bioWell;
2662 12 Sep 14 nicklas 271     var remarks = [];
2662 12 Sep 14 nicklas 272
3762 19 Feb 16 nicklas 273     lib.isYellow = lib.specimen && lib.specimen.YellowLabel != null;
3762 19 Feb 16 nicklas 274     
2662 12 Sep 14 nicklas 275     // Check if default barcode has been modified
2662 12 Sep 14 nicklas 276     if (barcodeVariant)
2662 12 Sep 14 nicklas 277     {
2662 12 Sep 14 nicklas 278       var indexSet = barcodeVariant.indexSets[well.column];
2662 12 Sep 14 nicklas 279       if (indexSet)
2662 12 Sep 14 nicklas 280       {
2662 12 Sep 14 nicklas 281         var defaultBarcode = indexSet.barcodes[well.row];
2662 12 Sep 14 nicklas 282         if (defaultBarcode && lib.barcode.name != defaultBarcode)
2662 12 Sep 14 nicklas 283         {
2662 12 Sep 14 nicklas 284           remarks[remarks.length] = 'Modified barcode';
2662 12 Sep 14 nicklas 285           lib.barcode.modified = true;
2662 12 Sep 14 nicklas 286         }
2662 12 Sep 14 nicklas 287       }
2662 12 Sep 14 nicklas 288     }
2662 12 Sep 14 nicklas 289     
2662 12 Sep 14 nicklas 290     if (lib.molarity)
2662 12 Sep 14 nicklas 291     {
2662 12 Sep 14 nicklas 292       if (lib.speedVacConc != null)
2662 12 Sep 14 nicklas 293       {
2662 12 Sep 14 nicklas 294         remarks[remarks.length] = 'SpeedVac';
2662 12 Sep 14 nicklas 295       }
2662 12 Sep 14 nicklas 296   
2662 12 Sep 14 nicklas 297       if (lib.mixFactor > 1)
2662 12 Sep 14 nicklas 298       {
2662 12 Sep 14 nicklas 299         // Larger mix than default
2662 12 Sep 14 nicklas 300         if (view != 'plate')
2662 12 Sep 14 nicklas 301         {
2662 12 Sep 14 nicklas 302           remarks[remarks.length] = '<span class="mix-remark">Mix <span class="volume">'+Numbers.formatNumber(lib.actualVolume*lib.mixFactor, 1) + '</span>+<span class="eb">' + Numbers.formatNumber(lib.actualEb*lib.mixFactor, 1)+'µl</span></span>';
2662 12 Sep 14 nicklas 303         }
2662 12 Sep 14 nicklas 304         remarks[remarks.length] = 'Use <b>' + Numbers.formatNumber(lib.actualVolume+lib.actualEb, 1) + 'µl</b> in pool';
2662 12 Sep 14 nicklas 305       }
2662 12 Sep 14 nicklas 306
2662 12 Sep 14 nicklas 307       lib.remarks = remarks;
2662 12 Sep 14 nicklas 308     }
2662 12 Sep 14 nicklas 309     
2662 12 Sep 14 nicklas 310     if (lib.comment) remarks[remarks.length] = lib.comment;
2662 12 Sep 14 nicklas 311   }
2662 12 Sep 14 nicklas 312
2662 12 Sep 14 nicklas 313   protocol.viewAsPlate = function(pools, schema, barcodeVariant)
3310 07 May 15 nicklas 314   {
3310 07 May 15 nicklas 315     var columns = libPlate.columns;
3310 07 May 15 nicklas 316     var rows = libPlate.rows;
3310 07 May 15 nicklas 317     
3310 07 May 15 nicklas 318     var html = '<tr id="pool-row"></tr>';
3310 07 May 15 nicklas 319     html += '<tr class="header">';
3310 07 May 15 nicklas 320     html += '<th></th>';
3310 07 May 15 nicklas 321     for (var c = 0; c < columns; c++)
3310 07 May 15 nicklas 322     {
3310 07 May 15 nicklas 323       html += '<th id="col.'+c+'">'+(c+1)+'</th>';
3310 07 May 15 nicklas 324     }
3310 07 May 15 nicklas 325     html += '</tr>';
3310 07 May 15 nicklas 326     html += '<tbody>';
3310 07 May 15 nicklas 327     
3310 07 May 15 nicklas 328     for (var r = 0; r < rows; r++)
3310 07 May 15 nicklas 329     {
3310 07 May 15 nicklas 330       html += '<tr class="row-'+r+'">';
5883 26 Mar 20 nicklas 331       html += '<th id="row.'+r+'" class="rowheader">'+(Reggie.wellToAlpha(r))+'</th>';
3310 07 May 15 nicklas 332
3310 07 May 15 nicklas 333       for (var c = 0; c < columns; c++)
3310 07 May 15 nicklas 334       {
3310 07 May 15 nicklas 335         html += '<td class="well col-'+c+'" id="well.'+r+'.'+c+'"';
3310 07 May 15 nicklas 336         html += ' data-col="'+c+'" data-row="'+r+'"';
3310 07 May 15 nicklas 337         html += ' title="Select/deselect this well"></td>';
3310 07 May 15 nicklas 338       }
3310 07 May 15 nicklas 339       html += '</tr>';
3310 07 May 15 nicklas 340     }
3310 07 May 15 nicklas 341     html += '</tbody>';
3310 07 May 15 nicklas 342     Doc.element('plateview').innerHTML = html;
3310 07 May 15 nicklas 343     
3310 07 May 15 nicklas 344     Plate.init(rows, columns, schema, WellPainter);
3310 07 May 15 nicklas 345
2662 12 Sep 14 nicklas 346     for (var poolNo = 0; poolNo < pools.length; poolNo++)
2662 12 Sep 14 nicklas 347     {
2662 12 Sep 14 nicklas 348       var pool = pools[poolNo];
2662 12 Sep 14 nicklas 349       for (var libNo = 0; libNo < pool.libraries.length; libNo++)
2662 12 Sep 14 nicklas 350       {
2662 12 Sep 14 nicklas 351         var lib = pool.libraries[libNo];
2662 12 Sep 14 nicklas 352         var well = lib.bioWell;
2662 12 Sep 14 nicklas 353         Plate.getWell(well.row, well.column).setExtract(lib);
2662 12 Sep 14 nicklas 354       }
2662 12 Sep 14 nicklas 355     }
2662 12 Sep 14 nicklas 356
2662 12 Sep 14 nicklas 357     WellPainter.barcodeVariant = barcodeVariant;
5883 26 Mar 20 nicklas 358     PoolSchema.buildPoolTableRow(schema, libPlate.columns, false, null, null);
2662 12 Sep 14 nicklas 359     
2662 12 Sep 14 nicklas 360     Doc.show('all-protocol');
2662 12 Sep 14 nicklas 361     
2662 12 Sep 14 nicklas 362     for (var poolNo = 0; poolNo < pools.length; poolNo++)
2662 12 Sep 14 nicklas 363     {
2662 12 Sep 14 nicklas 364       var pool = pools[poolNo];
2662 12 Sep 14 nicklas 365       var realPoolNo = schema.getPoolNumForColumn(pool.libraries[0].bioWell.column);
2662 12 Sep 14 nicklas 366       
2662 12 Sep 14 nicklas 367       var poolData = '<div class="pool-data">';
2662 12 Sep 14 nicklas 368       poolData += pool.libraries.length + ' libs • ';
2662 12 Sep 14 nicklas 369       poolData += Numbers.formatNumber(pool.molarity, 2)+'nM • ';
2662 12 Sep 14 nicklas 370       poolData += Numbers.formatNumber(pool.volume, 1) + 'µl';
2662 12 Sep 14 nicklas 371       if (pool.mixingStrategy == 'dynamic')
2662 12 Sep 14 nicklas 372       {
2662 12 Sep 14 nicklas 373         poolData += ' • <span class="pool-eb">'+Numbers.formatNumber(pool.extra.ebVolumeExtra, 1, 'µl')+'</span>';
2662 12 Sep 14 nicklas 374       }
2662 12 Sep 14 nicklas 375       poolData += '<br>Mixing strategy: ' + pool.mixingStrategy;
2662 12 Sep 14 nicklas 376       poolData += '<div class="comments">'+pool.comments+'</div>';
2662 12 Sep 14 nicklas 377       poolData += '</div>';
2662 12 Sep 14 nicklas 378       
2662 12 Sep 14 nicklas 379       Doc.element('pool.'+realPoolNo).innerHTML = Strings.encodeTags(pool.name) + poolData;
2662 12 Sep 14 nicklas 380     }
3762 19 Feb 16 nicklas 381     Plate.paint(Plate.getWells());
2662 12 Sep 14 nicklas 382   }
2662 12 Sep 14 nicklas 383
2662 12 Sep 14 nicklas 384   protocol.viewAsList = function(pools, schema, barcodeVariant)
2662 12 Sep 14 nicklas 385   {
3310 07 May 15 nicklas 386     if (libPlate)
3310 07 May 15 nicklas 387     {
3310 07 May 15 nicklas 388       Plate.init(libPlate.rows, libPlate.columns, schema, null);
3310 07 May 15 nicklas 389     }
3762 19 Feb 16 nicklas 390     var homeUrl = Data.get('page-data', 'home-url');
3762 19 Feb 16 nicklas 391     var yellowImg = '<img src="'+homeUrl+'/images/yellow-label-small.png">';
2662 12 Sep 14 nicklas 392     for (var poolNo = 0; poolNo < pools.length; poolNo++)
2662 12 Sep 14 nicklas 393     {
2662 12 Sep 14 nicklas 394       var pool = pools[poolNo];
2662 12 Sep 14 nicklas 395       var wellsInPool = null;
2662 12 Sep 14 nicklas 396       if (schema)
2662 12 Sep 14 nicklas 397       {
2662 12 Sep 14 nicklas 398         var realPoolNo = schema.getPoolNumForColumn(pool.libraries[0].bioWell.column);
2662 12 Sep 14 nicklas 399         wellsInPool = Plate.getPool(realPoolNo);
2662 12 Sep 14 nicklas 400       }
2662 12 Sep 14 nicklas 401       
2662 12 Sep 14 nicklas 402       var html = '';
2662 12 Sep 14 nicklas 403       var tbody = Doc.element('listview.'+pool.id+'.body');
2662 12 Sep 14 nicklas 404       
2662 12 Sep 14 nicklas 405       var wellIndex = 0;
2662 12 Sep 14 nicklas 406       for (var j = 0; j < pool.libraries.length; j++)
2662 12 Sep 14 nicklas 407       {
2662 12 Sep 14 nicklas 408         var lib = pool.libraries[j];
2662 12 Sep 14 nicklas 409         var well = lib.bioWell;
2662 12 Sep 14 nicklas 410         
2662 12 Sep 14 nicklas 411         var tr = document.createElement('tr');
2662 12 Sep 14 nicklas 412         if (schema)
2662 12 Sep 14 nicklas 413         {
2662 12 Sep 14 nicklas 414           wellIndex = protocol.createMissingRows(tbody, wellsInPool, wellIndex, well, barcodeVariant);
2662 12 Sep 14 nicklas 415           tr.className = well.column % 2 == 0 ? "evencol" : "oddcol";
2662 12 Sep 14 nicklas 416         }
2662 12 Sep 14 nicklas 417         else
2662 12 Sep 14 nicklas 418         {
2662 12 Sep 14 nicklas 419           tr.className = 'evencol';
2662 12 Sep 14 nicklas 420         }
2662 12 Sep 14 nicklas 421     
2662 12 Sep 14 nicklas 422         if (barcodeVariant)
2662 12 Sep 14 nicklas 423         {
2662 12 Sep 14 nicklas 424           var indexSet = barcodeVariant.indexSets[well.column];
2662 12 Sep 14 nicklas 425           if (indexSet)
2662 12 Sep 14 nicklas 426           {
2662 12 Sep 14 nicklas 427             tr.className = lib && lib.barcode.modified ? 'bg-modified' : indexSet.color;
2662 12 Sep 14 nicklas 428           }
2662 12 Sep 14 nicklas 429         }
3762 19 Feb 16 nicklas 430         var img = '';
3762 19 Feb 16 nicklas 431         if (lib.isYellow) 
3762 19 Feb 16 nicklas 432         {
3762 19 Feb 16 nicklas 433           tr.className += ' yellow-specimen';
3762 19 Feb 16 nicklas 434           img = yellowImg;
3762 19 Feb 16 nicklas 435         }
3762 19 Feb 16 nicklas 436         
3762 19 Feb 16 nicklas 437         protocol.addColumn(tr, 'lib if-yellow', img+Strings.encodeTags(lib.name));
2662 12 Sep 14 nicklas 438         protocol.addColumn(tr, 'remain', Numbers.formatNumber((lib.remainingVolume), 1));
2662 12 Sep 14 nicklas 439         protocol.addColumn(tr, 'molarity', Numbers.formatNumber(lib.molarity, 2));
2662 12 Sep 14 nicklas 440         if (!libPlate)
2662 12 Sep 14 nicklas 441         {
2662 12 Sep 14 nicklas 442           protocol.addColumn(tr, 'workplate', Strings.encodeTags(well.bioPlate.name + ' ' + well.location));
2662 12 Sep 14 nicklas 443         }
2662 12 Sep 14 nicklas 444         else
2662 12 Sep 14 nicklas 445         {
2662 12 Sep 14 nicklas 446           protocol.addColumn(tr, 'workplate', Strings.encodeTags(well.location));
2662 12 Sep 14 nicklas 447         }
2662 12 Sep 14 nicklas 448         var mixFactor = lib.mixFactor || 1.0;
2662 12 Sep 14 nicklas 449         protocol.addColumn(tr, 'volume', mixFactor > 1.0 ? '—' : Numbers.formatNumber(lib.actualVolume, 1));
2662 12 Sep 14 nicklas 450         protocol.addColumn(tr, 'eb', pool.mixingStrategy == 'dynamic' || mixFactor > 1.0 ? '—' : Numbers.formatNumber(lib.actualEb, 1));
2662 12 Sep 14 nicklas 451         protocol.addColumn(tr, "remarks", lib.remarks.join('; '));
2662 12 Sep 14 nicklas 452         tbody.appendChild(tr);
2662 12 Sep 14 nicklas 453       }
2837 20 Oct 14 nicklas 454       if (schema && wellIndex < wellsInPool.length)
2662 12 Sep 14 nicklas 455       {
2662 12 Sep 14 nicklas 456         protocol.createMissingRows(tbody, wellsInPool, wellIndex, null, barcodeVariant);
2662 12 Sep 14 nicklas 457       }
2662 12 Sep 14 nicklas 458       
2662 12 Sep 14 nicklas 459       var poolData = '<div class="pool-data">';
2662 12 Sep 14 nicklas 460       poolData += pool.libraries.length + ' libs; ';
2662 12 Sep 14 nicklas 461       poolData += Numbers.formatNumber(pool.molarity, 2)+'nM; ';
2662 12 Sep 14 nicklas 462       poolData += Numbers.formatNumber(pool.volume, 1) + 'µl';
2662 12 Sep 14 nicklas 463       poolData += '<br>Mixing strategy: ' + pool.mixingStrategy;
2662 12 Sep 14 nicklas 464       poolData += '</div>';
2662 12 Sep 14 nicklas 465       Doc.element('molarity.'+pool.id).innerHTML = poolData;
2662 12 Sep 14 nicklas 466       Doc.element('eb-volume.'+pool.id).innerHTML = Numbers.formatNumber(Math.max(0, pool.extra.ebVolumeExtra), 1);
2662 12 Sep 14 nicklas 467       Doc.show('pool.'+pool.id);
2662 12 Sep 14 nicklas 468     }
2662 12 Sep 14 nicklas 469     
2662 12 Sep 14 nicklas 470     Doc.show('all-protocol');
2662 12 Sep 14 nicklas 471   }
2662 12 Sep 14 nicklas 472   
2662 12 Sep 14 nicklas 473   protocol.createMissingRows = function(table, wellsInPool, wellIndex, well, barcodeVariant)
2662 12 Sep 14 nicklas 474   {
2662 12 Sep 14 nicklas 475     var wellAtIndex = wellsInPool[wellIndex]; // Empty??
2662 12 Sep 14 nicklas 476     if (!well) well = {'row': -1, 'column': -1};
2662 12 Sep 14 nicklas 477     while (wellAtIndex.row != well.row || wellAtIndex.column != well.column)
2662 12 Sep 14 nicklas 478     {
2662 12 Sep 14 nicklas 479       var tr = document.createElement('tr');
2662 12 Sep 14 nicklas 480       tr.className = 'empty';
2662 12 Sep 14 nicklas 481       if (barcodeVariant)
2662 12 Sep 14 nicklas 482       {
2662 12 Sep 14 nicklas 483         var indexSet = barcodeVariant.indexSets[wellAtIndex.column];
2662 12 Sep 14 nicklas 484         if (indexSet) tr.className += ' ' + indexSet.color;
2662 12 Sep 14 nicklas 485       }
2662 12 Sep 14 nicklas 486       
2662 12 Sep 14 nicklas 487       protocol.addColumn(tr, 'lib', 'not pooled');
2662 12 Sep 14 nicklas 488       protocol.addColumn(tr, 'remain', '');
2662 12 Sep 14 nicklas 489       protocol.addColumn(tr, 'molarity', '');
2662 12 Sep 14 nicklas 490       protocol.addColumn(tr, 'workplate', Reggie.wellToAlpha(wellAtIndex.row) + (wellAtIndex.column+1));
2662 12 Sep 14 nicklas 491       protocol.addColumn(tr, 'volume', '');
2662 12 Sep 14 nicklas 492       protocol.addColumn(tr, 'eb', '');
2662 12 Sep 14 nicklas 493       protocol.addColumn(tr, 'remarks', '');
2662 12 Sep 14 nicklas 494       table.appendChild(tr);
2662 12 Sep 14 nicklas 495       wellIndex++;
2662 12 Sep 14 nicklas 496       if (wellIndex >= wellsInPool.length) break;
2662 12 Sep 14 nicklas 497       wellAtIndex = wellsInPool[wellIndex];
2662 12 Sep 14 nicklas 498     }
2662 12 Sep 14 nicklas 499     return wellIndex+1;
2662 12 Sep 14 nicklas 500   }
2662 12 Sep 14 nicklas 501   
2662 12 Sep 14 nicklas 502   protocol.addColumn = function(tr, className, html)
2662 12 Sep 14 nicklas 503   {
2662 12 Sep 14 nicklas 504     var td = document.createElement('td');
2662 12 Sep 14 nicklas 505     td.className = className;
2662 12 Sep 14 nicklas 506     td.innerHTML = html;
2662 12 Sep 14 nicklas 507     tr.appendChild(td);
2662 12 Sep 14 nicklas 508   }
2662 12 Sep 14 nicklas 509
2662 12 Sep 14 nicklas 510   
2662 12 Sep 14 nicklas 511   return protocol;
2662 12 Sep 14 nicklas 512 }();
2662 12 Sep 14 nicklas 513
2662 12 Sep 14 nicklas 514 Doc.onLoad(Protocol.initPage);
2662 12 Sep 14 nicklas 515
2662 12 Sep 14 nicklas 516
2662 12 Sep 14 nicklas 517 var WellPainter = function()
2662 12 Sep 14 nicklas 518 {
2662 12 Sep 14 nicklas 519   var painter = {};
2662 12 Sep 14 nicklas 520   
2662 12 Sep 14 nicklas 521   painter.getClassNameForWell = function(well, schema)
2662 12 Sep 14 nicklas 522   {
2662 12 Sep 14 nicklas 523     var cls = '';
2662 12 Sep 14 nicklas 524     var indexSet = painter.barcodeVariant.indexSets[well.column];
2662 12 Sep 14 nicklas 525     if (indexSet)
2662 12 Sep 14 nicklas 526     {
2662 12 Sep 14 nicklas 527       var lib = well.extract;
2662 12 Sep 14 nicklas 528       cls += lib && lib.barcode.modified ? 'bg-modified' : indexSet.color;
3762 19 Feb 16 nicklas 529       if (lib && lib.isYellow) cls += ' yellow-specimen';
2662 12 Sep 14 nicklas 530     }
2662 12 Sep 14 nicklas 531     return cls;
2662 12 Sep 14 nicklas 532   }
2662 12 Sep 14 nicklas 533   
2662 12 Sep 14 nicklas 534   painter.getWellText = function(well, schema)
2662 12 Sep 14 nicklas 535   {
2662 12 Sep 14 nicklas 536     var text = '';
2662 12 Sep 14 nicklas 537     var lib = well.extract;
2662 12 Sep 14 nicklas 538     if (lib)
2662 12 Sep 14 nicklas 539     {
2662 12 Sep 14 nicklas 540       var name = lib.name;
2662 12 Sep 14 nicklas 541       var mixFactor = lib.mixFactor || 1.0;
2662 12 Sep 14 nicklas 542       var i = name.indexOf('.m');
3310 07 May 15 nicklas 543       var displayName = i == -1 ? Strings.encodeTags(name) : Strings.encodeTags(name.substring(0, i+1))+'<br>&nbsp;'+Strings.encodeTags(name.substring(i));
3762 19 Feb 16 nicklas 544       text += '<div class="lib if-yellow">'+displayName+'</div>';
2662 12 Sep 14 nicklas 545       text += '<div><span class="volume">'+Numbers.formatNumber(lib.actualVolume*mixFactor, 1)+'µl</span>';
2662 12 Sep 14 nicklas 546       if (lib.mixingStrategy == 'fixed' || lib.mixFactor > 1)
2662 12 Sep 14 nicklas 547       {
2662 12 Sep 14 nicklas 548         text += '<span class="eb">'+Numbers.formatNumber(lib.actualEb*mixFactor, 1)+'µl</span>';
2662 12 Sep 14 nicklas 549       }
2662 12 Sep 14 nicklas 550       else
2662 12 Sep 14 nicklas 551       {
2662 12 Sep 14 nicklas 552         text += '<span class="eb">—</span>';
2662 12 Sep 14 nicklas 553       }
2662 12 Sep 14 nicklas 554       //text+=lib.eb+':'+lib.mixFactor;
2662 12 Sep 14 nicklas 555       text += '</div>';
2662 12 Sep 14 nicklas 556       text += '<div class="remarks">'+ lib.remarks.join('; ') + '</div>';
2662 12 Sep 14 nicklas 557     }
2662 12 Sep 14 nicklas 558     return text;
2662 12 Sep 14 nicklas 559   }
2662 12 Sep 14 nicklas 560
2662 12 Sep 14 nicklas 561   return painter;
2662 12 Sep 14 nicklas 562 }();
2662 12 Sep 14 nicklas 563
2662 12 Sep 14 nicklas 564