Changeset 3832


Ignore:
Timestamp:
Apr 7, 2016, 3:41:43 PM (6 years ago)
Author:
Nicklas Nordborg
Message:

References #875: Soft and hard target amount for NeoPrep?

The "Library preparation design" wizards have been updated.

The "Amount of RNA" input field has been replaced with a protocol selection list and the amount and volumes are taken from the RNATargetAmount, RNAMinimalAmount and RNATargetVolume annotations.

The initial selected protocol is selected based on the RNATargetAmount (0.15 for NeoPrep? and 0.50 for manual). There is currently no way to only use the project default setting to select a protocol since there are two variants of the wizard.

The "Auto-select" function is now based on the selected protocol instead of the amount.

A new annotation type DilutionVolume has been created and is used to store the target volume when diluting the RNA. This is used by the lab protocols to get rid of the hard-coded volumes.

The "Auto-design" is still using hard-coded volumes. This need to be fixed.

Location:
extensions/net.sf.basedb.reggie/trunk
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • extensions/net.sf.basedb.reggie/trunk/resources/libprep/auto_select_rna.js

    r3316 r3832  
    1818   
    1919    Events.addEventHandler('normalizationProtocol', 'change', autoselect.protocolOnChange);
    20     Reggie.loadProtocols('RNA_NORMALIZATION_PROTOCOL', 'normalizationProtocol', 'RNA_TARGET_AMOUNT,RNA_TARGET_VOLUME');
     20    Reggie.loadProtocols('RNA_NORMALIZATION_PROTOCOL', 'normalizationProtocol', 'RNA_TARGET_AMOUNT,RNA_MINIMAL_AMOUNT,RNA_TARGET_VOLUME');
    2121    autoselect.setPreNormalize();
    2222  }
     
    4343    {
    4444      hasInitProtocols = true;
     45      var selectedProtocol = Data.int('page-data', 'protocol-id');
    4546     
    4647      if (frm.normalizationProtocol.length == 0)
     
    5051      }
    5152     
    52       var targetRnaAmount = parseFloat(frm.quantity_regular.value);
    53       var closestAlternateProtocolIndex = -1;
    54       var closestRnaAmount = 999;
    55      
    5653      for (var i=0; i < frm.normalizationProtocol.length; i++)
    5754      {
    5855        var p = frm.normalizationProtocol[i].item;
    59         frm.normalizationProtocol[i].text = p.name + ' (' + (p.RNATargetAmount || '? ') + 'µg in '+(p.RNATargetVolume || '? ')+'µl)';
     56        var unit = 'µg';
     57        var factor = 1;
     58        if (p.RNATargetAmount < 0.5)
     59        {
     60          unit = 'ng';
     61          factor = 1000;
     62        }
    6063       
    61         // Adjust default selected protocol to match the expected RNA amount
    62         // The protocol must be an alternate project default and have a RNATargetAmount value
    63         if (p.alternateDefault && p.RNATargetAmount)
    64         {
    65           var tmp = Math.abs(targetRnaAmount-p.RNATargetAmount);
    66           if (tmp < closestRnaAmount)
    67           {
    68             closestRnaAmount = tmp;
    69             closestAlternateProtocolIndex = i;
    70           }
    71         }
     64        var text = p.name + ' (';
     65        if (p.RNAMinimalAmount) text += Reggie.formatNumber(p.RNAMinimalAmount * factor, '', 1) + '-';
     66        text += p.RNATargetAmount ? Reggie.formatNumber(p.RNATargetAmount * factor, '', 1) : '? ';
     67        text += unit;
     68        text += ' in '+(p.RNATargetVolume || '? ')+'µl)';
     69        frm.normalizationProtocol[i].text = text;
     70       
     71        if (p.id == selectedProtocol) frm.normalizationProtocol.selectedIndex = i;
    7272      }
    7373     
    74       if (closestAlternateProtocolIndex != -1)
    75       {
    76         frm.normalizationProtocol.selectedIndex = closestAlternateProtocolIndex;
    77       }
    7874    }
    7975  }
  • extensions/net.sf.basedb.reggie/trunk/resources/libprep/auto_select_rna.jsp

    r3270 r3832  
    2525  final String title = "Options for auto-selecting RNA";
    2626 
     27  String protocolId = request.getParameter("protocol");
    2728  String requiredQuantity = request.getParameter("quantity");
    2829  int numToSelect = Values.getInt(request.getParameter("numToSelect"));
     
    4243    data-num-to-select="<%=numToSelect%>"
    4344    data-ignore="[<%=HTML.encodeTags(ignore)%>]"
     45    data-protocol-id="<%=HTML.encodeTags(protocolId)%>"
    4446  ></div>
    4547
  • extensions/net.sf.basedb.reggie/trunk/resources/libprep/mrna_protocol.js

    r3757 r3832  
    55 
    66  var LOW_QUANTITY_WARNING_FACTOR = 2;
     7  var DEFAULT_DILUTION_VOLUME = 50; //µl
    78
    89  // Page initialization
     
    162163    rna.external = Reggie.isExternal(rna.name);
    163164    rna.isYellow = rna.specimen && rna.specimen.YellowLabel != null;
     165    if (!lib.DilutionVolume) lib.DilutionVolume = DEFAULT_DILUTION_VOLUME;
    164166   
    165167    // Set the 'QC' flag
     
    182184      else
    183185      {
    184         var totalVolume = mrna.DilutionConc ? 1000 * rna.usedQuantity / mrna.DilutionConc : 50;
     186        var totalVolume = mrna.DilutionConc ? 1000 * rna.usedQuantity / mrna.DilutionConc : lib.DilutionVolume;
    185187        rna.water = totalVolume-rna.volume;
    186         if (totalVolume > 50)
     188        if (totalVolume > lib.DilutionVolume)
    187189        {
    188           remarks[remarks.length] = 'Large mix; Use 50µl';
     190          remarks[remarks.length] = 'Large mix; Use '+Reggie.formatNumber(lib.DilutionVolume, 'µl', 1);
    189191        }
    190192      }
  • extensions/net.sf.basedb.reggie/trunk/resources/libprep/neoprep_protocol.js

    r3809 r3832  
    55 
    66  var LOW_QUANTITY_WARNING_FACTOR = 2;
     7  var DEFAULT_DILUTION_VOLUME = 15; //µl
    78
    89  // Page initialization
     
    244245    rna.external = Reggie.isExternal(rna.name);
    245246    rna.isYellow = rna.specimen && rna.specimen.YellowLabel != null;
    246    
     247    if (!lib.DilutionVolume) lib.DilutionVolume = DEFAULT_DILUTION_VOLUME;
     248
    247249    // Set the 'QC' flag
    248250    rna.qc = lib.UseForQC;
     
    264266      else
    265267      {
    266         var totalVolume = lib.DilutionConc ? 1000 * rna.usedQuantity / lib.DilutionConc : 15;
     268        var totalVolume = lib.DilutionConc ? 1000 * rna.usedQuantity / lib.DilutionConc : lib.DilutionVolume;
    267269        rna.water = totalVolume-rna.volume;
    268         if (totalVolume > 15)
    269         {
    270           remarks[remarks.length] = 'Large mix; Use 15µl';
     270        if (totalVolume > lib.DilutionVolume)
     271        {
     272          remarks[remarks.length] = 'Large mix; Use '+Reggie.formatNumber(lib.DilutionVolume, 'µl', 1);
    271273        }
    272274      }
  • extensions/net.sf.basedb.reggie/trunk/resources/libprep/select_rna.js

    r3809 r3832  
     1var MINIMAL_RNA_VOLUME = 1.0; // µl
     2// Default initial volumes (can be overridden by protocols)
     3var TOTAL_VOLUME = 50; // µl
     4var QUANTITY_REGULAR = 0.5; // µg
     5var QUANTITY_QC = 0.6; // µg
     6var QUANTITY_MINIMAL = QUANTITY_REGULAR;
     7
     8
    19var SelectRna = function()
    210{
     
    412  var barcodesByName = [];
    513  var autoDesign = 0;
     14  var hasInitProtocols = false;
    615 
    716  var EXTERNAL_RNA_NAME = 'External.r';
     
    1120  var pen;
    1221 
    13   var quantitiesAreValid = false;
    1422  var subtypeRna;
    1523  var subtypeRnaNormalized
     
    2533    Events.addEventHandler('pool_schema', 'change', selectrna.poolSchemaOnChange);
    2634    Events.addEventHandler('barcode_variant', 'change', selectrna.barcodeVariantOnChange);
    27     Events.addEventHandler('quantity_regular', 'change', selectrna.quantityOnChange);
    28     Events.addEventHandler('quantity_qc', 'change', selectrna.quantityOnChange);
    29     Events.addEventHandler('quantity_regular', 'keypress', Events.numberOnly);
    30     Events.addEventHandler('quantity_qc', 'keypress', Events.numberOnly);
     35    Events.addEventHandler('normalizationProtocol', 'change', selectrna.protocolOnChange);
    3136   
    3237    Events.addEventHandler('warning_quantity', 'change', selectrna.warningLevelOnChange);
     
    96101   
    97102    var isNeoPrep = Data.int('page-data', 'is-neoprep');
    98     TOTAL_VOLUME = isNeoPrep ? 15 : 50; // µl
    99     MINIMAL_RNA_VOLUME = 1.0; // µl
    100    
    101     Doc.element('totalVolume').innerHTML = TOTAL_VOLUME;
    102    
     103    // Change default for NeoPrep
     104    if (isNeoPrep)
     105    {
     106      TOTAL_VOLUME = 15;
     107      QUANTITY_REGULAR = 0.12;
     108      QUANTITY_MINIMAL = 0.015;
     109      QUANTITY_QC = QUANTITY_REGULAR;
     110    }
     111   
     112    Reggie.loadProtocols('RNA_NORMALIZATION_PROTOCOL', 'normalizationProtocol', 'RNA_TARGET_AMOUNT,RNA_MINIMAL_AMOUNT,RNA_TARGET_VOLUME');
     113
    103114    var url = '../MRna.servlet?ID='+App.getSessionId();
    104115    url += '&cmd=GetNextAutoGeneratedPlateName';
     
    134145      frm.stratagene[frm.stratagene.length] = new Option(name, s.name);
    135146    }
    136    
     147
    137148    var url = '../LibPrep.servlet?ID='+App.getSessionId();
    138149    url += '&cmd=GetAllBarcodeInfo';
    139150    Wizard.asyncJsonRequest(url, selectrna.barcodesLoaded);
    140151  }
    141 
     152 
    142153
    143154  selectrna.barcodesLoaded = function(response)
     
    161172    Doc.element('select-barcode-all').innerHTML = selectBarcodeHtml;
    162173   
    163     selectrna.quantityOnChange();
     174    //selectrna.quantityOnChange();
    164175    selectrna.warningLevelOnChange();   
    165176   
     
    232243  }
    233244 
    234   selectrna.quantityOnChange = function(event)
     245  selectrna.protocolOnChange = function()
    235246  {
    236247    var frm = document.forms['reggie'];
    237     quantitiesAreValid = false;
    238    
    239     var qRegular = parseFloat(frm.quantity_regular.value);
    240     if (!(qRegular > 0))
    241     {
    242       Wizard.setInputStatus('quantities', 'invalid', 'Amount must be ≥ 0.');
    243       return;
    244     }
    245     var qQc = parseFloat(frm.quantity_qc.value);
    246     if (!(qQc > qRegular))
    247     {
    248       Wizard.setInputStatus('quantities', 'invalid', 'Amount QC must be &gt; ' + qRegular + '.');
    249       return;
    250     }
    251    
    252     quantitiesAreValid = true;
    253     QUANTITY_REGULAR = qRegular;
    254     QUANTITY_QC = qQc;
    255    
    256     Wizard.setInputStatus('quantities', 'valid');
    257     if (event) Plate.paint(Plate.getWells());
     248
     249    if (!hasInitProtocols)
     250    {
     251      hasInitProtocols = true;
     252     
     253      if (frm.normalizationProtocol.length == 0)
     254      {
     255        Wizard.setFatalError('No RNA dilution protocols found. Please ask the server administrator to create at least one protocol.');
     256        return;
     257      }
     258     
     259      var closestAlternateProtocolIndex = -1;
     260      var closestRnaAmount = 999;
     261      for (var i=0; i < frm.normalizationProtocol.length; i++)
     262      {
     263        var p = frm.normalizationProtocol[i].item;
     264       
     265        var unit = 'µg';
     266        var factor = 1;
     267        if (p.RNATargetAmount < 0.5)
     268        {
     269          unit = 'ng';
     270          factor = 1000;
     271        }
     272       
     273        var text = p.name + ' (';
     274        if (p.RNAMinimalAmount) text += Reggie.formatNumber(p.RNAMinimalAmount * factor, '', 1) + '-';
     275        text += p.RNATargetAmount ? Reggie.formatNumber(p.RNATargetAmount * factor, '', 1) : '? ';
     276        text += unit;
     277        text += ' in '+(p.RNATargetVolume || '? ')+'µl)';
     278        frm.normalizationProtocol[i].text = text;
     279       
     280        // Adjust default selected protocol to match the expected RNA amount
     281        // The protocol must be an alternate project default and have a RNATargetAmount value
     282        if (p.alternateDefault && p.RNATargetAmount)
     283        {
     284          var tmp = Math.abs(QUANTITY_REGULAR-p.RNATargetAmount);
     285          if (tmp < closestRnaAmount)
     286          {
     287            closestRnaAmount = tmp;
     288            closestAlternateProtocolIndex = i;
     289          }
     290        }
     291      }
     292     
     293      if (closestAlternateProtocolIndex != -1)
     294      {
     295        frm.normalizationProtocol.selectedIndex = closestAlternateProtocolIndex;
     296      }
     297     
     298      if (autoDesign) frm.normalizationProtocol.disabled = true;
     299    }
     300
     301    var protocol = frm.normalizationProtocol[frm.normalizationProtocol.selectedIndex].item;
     302    if (!protocol || !protocol.RNATargetAmount || !protocol.RNATargetVolume)
     303    {
     304      protocol = {};
     305      if (!protocol.RNATargetAmount) protocol.RNATargetAmount = 1.1;
     306      if (!protocol.RNATargetVolume) protocol.RNATargetVolume = 50;
     307     
     308      var msg = 'Missing normalization data; assuming ';
     309      msg += protocol.RNATargetAmount+ 'µg in '+protocol.RNATargetVolume+'µl.';
     310      Wizard.setInputStatus('normalizationProtocol', 'warning',  msg);
     311    }
     312    else
     313    {
     314      Wizard.setInputStatus('normalizationProtocol', 'valid');
     315    }
     316    if (!protocol.RNAMinimalAmount) protocol.RNAMinimalAmount = protocol.RNATargetAmount;
     317   
     318    QUANTITY_REGULAR = protocol.RNATargetAmount;
     319    QUANTITY_QC = QUANTITY_REGULAR+0.12;
     320    TOTAL_VOLUME = protocol.RNATargetVolume;
     321    QUANTITY_MINIMAL = protocol.RNAMinimalAmount;
     322    Plate.paint(Plate.getWells());
    258323  }
    259324
     
    488553    url += '&tmpfilter:INT:itemSubtype='+subtypeRna.id+'|'+subtypeRnaNormalized.id;
    489554    url += '&tmpfilter:DATE:creationEvent.eventDate='+encodeURIComponent('<>');
    490     var minQuantity = parseFloat(frm.quantity_regular.value);
    491     if (!isNaN(minQuantity))
    492     {
    493       url += '&tmpfilter:FLOAT:remainingQuantity='+encodeURIComponent('>='+minQuantity);
    494     }
     555    url += '&tmpfilter:FLOAT:remainingQuantity='+encodeURIComponent('>='+QUANTITY_MINIMAL);
    495556    url += '&'+encodeURIComponent('tmpfilter:STRING:&childCreationEvents(event.bioMaterial.name)')+'='+encodeURIComponent('<>%.m');
    496557
     
    578639    var url = 'auto_select_rna.jsp?ID='+App.getSessionId();
    579640    url += '&numToSelect='+selected.length;
    580     url += '&quantity='+encodeURIComponent(frm.quantity_regular.value);
     641    url += '&protocol='+frm.normalizationProtocol.value;
     642    url += '&quantity='+encodeURIComponent(QUANTITY_REGULAR);
    581643    url += '&ignore='+ignore.join(',');
    582644    Dialogs.openPopup(url, 'AutoSelectRNA', 750, 500);
     
    11041166  selectrna.validateStep1 = function(event)
    11051167  {
    1106     if (!quantitiesAreValid)
    1107     {
    1108       event.preventDefault();
    1109       return;
    1110     }
    1111 
    11121168    var frm = document.forms['reggie'];
    11131169    var numErrors = 0;
     
    12241280        tmp.rna.usedQuantity = rna.usedQuantity;
    12251281        tmp.rna.dilutionConc = rna.dilutionConc;
     1282        tmp.rna.dilutionVolume = TOTAL_VOLUME;
    12261283        tmp.rna.qc = rna.qc;
    12271284        tmp.rna.comment = rna.comment;
     
    16731730          warningMsg[warningMsg.length] = 'Large mix';
    16741731        }
     1732        else if (volRNA > TOTAL_VOLUME)
     1733        {
     1734          volRNA = TOTAL_VOLUME;
     1735          rna.usedQuantity = volRNA * info.NDConc / 1000; // µg
     1736          rna.dilutionConc = info.NDConc;
     1737          water = 0;
     1738        }
    16751739       
    16761740        if (info.remainingQuantity)
    16771741        {
    1678           text += '<div class="quantity">'+Numbers.formatNumber(info.remainingQuantity, 2) + 'µg</div>';
    1679           // Must have at least 0.5µg or 0.6µg (if default values are used)
    1680           var remainLimit = rna.qc ? QUANTITY_QC : QUANTITY_REGULAR;
    1681           if (info.remainingQuantity < remainLimit)
     1742          var useNanoGram = info.remainingQuantity < 0.5;
     1743          text += '<div class="quantity">'+(useNanoGram ? Reggie.formatNumber(info.remainingQuantity * 1000, 'ng', 1):Reggie.formatNumber(info.remainingQuantity, 'µg', 2)) + '</div>';
     1744         
     1745          App.debug(rna.name+':'+info.remainingQuantity +':'+ rna.usedQuantity +':'+ rna.usedQuantity +':'+ QUANTITY_MINIMAL);
     1746         
     1747          if (info.remainingQuantity < rna.usedQuantity || rna.usedQuantity < QUANTITY_MINIMAL)
    16821748          {
    16831749            well.setError('Not enough RNA');
  • extensions/net.sf.basedb.reggie/trunk/resources/libprep/select_rna.jsp

    r3809 r3832  
    415415      </tr>
    416416      <tr>
    417         <td class="prompt">Amount of RNA</td>
     417        <td class="prompt">Dilution protocol</td>
    418418        <td class="input">
    419           Normal
    420           <input type="text" class="text required" name="quantity_regular" id="quantity_regular"
    421             value="<%=isNeoPrep ? "0.12" : "0.5"%>" style="width: 4em;" <%=autoDesign ? "disabled" : ""%>>µg,
    422           QC
    423           <input type="text" class="text required" name="quantity_qc" id="quantity_qc"
    424             value="0.6" style="width: 4em;" <%=isNeoPrep || autoDesign ? "disabled" : "" %>>µg
    425           (Diluted to <span id="totalVolume"></span>µl)
    426         </td>
    427         <td class="status" id="quantities.status"></td>
     419          <select name="normalizationProtocol" id="normalizationProtocol" class="required"></select>
     420        </td>
     421        <td class="status" id="normalizationProtocol.status"></td>
    428422        <td class="help">
    429           <span id="quantities.message" class="message" style="display: none;"></span>
    430           Specify the amount of RNA to use. Aliquots for QC usually need 0.12µg extra.
     423          <span id="normalizationProtocol.message" class="message"></span>
     424          Select the protocol that specifies the amount and volume of RNA
     425          that is needed for the library preparation.
    431426        </td>
    432427      </tr>
  • extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/dao/Annotationtype.java

    r3829 r3832  
    753753 
    754754  /**
     755    Expected volume after diluting RNA to be processed
     756    to libraries. Used on "mRNA" and "Library" items.
     757    @since 4.3
     758  */
     759  public static final Annotationtype DILUTION_VOLUME =
     760    new Annotationtype("DilutionVolume", Type.FLOAT, false, Item.EXTRACT);
     761 
     762  /**
    755763    Annotation for mRNA and pre-normalized RNA dilution date.
    756764    @since 2.12, 2.18
  • extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/servlet/InstallServlet.java

    r3829 r3832  
    413413        jsonChecks.add(checkAnnotationType(dc, Annotationtype.USE_FOR_QC, 1, null, effectivePermissionsUse, createIfMissing));
    414414        jsonChecks.add(checkAnnotationType(dc, Annotationtype.DILUTION_CONC, 1, null, effectivePermissionsUse, createIfMissing));
     415        jsonChecks.add(checkAnnotationType(dc, Annotationtype.DILUTION_VOLUME, 1, null, effectivePermissionsUse, createIfMissing));
    415416       
    416417        jsonChecks.add(checkAnnotationType(dc, Annotationtype.FLAG, 1,
     
    655656          Annotationtype.POOL_SCHEMA, Annotationtype.PLATE_PROCESS_RESULT,
    656657          Annotationtype.DILUTION_DATE, Annotationtype.DILUTION_OPERATOR,
    657           Annotationtype.DILUTION_CONC, Annotationtype.USE_FOR_QC,
     658          Annotationtype.DILUTION_CONC, Annotationtype.DILUTION_VOLUME,
     659          Annotationtype.USE_FOR_QC,
    658660          Annotationtype.PURIFICATION_DATE, Annotationtype.PURIFICATION_OPERATOR,
    659661          Annotationtype.FRAGMENTATION_DATE, Annotationtype.FRAGMENTATION_OPERATOR,
     
    666668       
    667669        jsonChecks.add(checkAnnotationTypeCategory(dc, Subtype.LIBRARY, createIfMissing,
    668             Annotationtype.DILUTION_CONC,
     670            Annotationtype.DILUTION_CONC, Annotationtype.DILUTION_VOLUME,
    669671            Annotationtype.QUBIT_CONC, Annotationtype.QUBIT_CONC_AFTER_SPEEDVAC,
    670672            Annotationtype.CA_SIZE, Annotationtype.CA_MOLARITY,
  • extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/servlet/LibPrepServlet.java

    r3760 r3832  
    266266          {
    267267            lib.loadAnnotations(dc, "DilutionConc", Annotationtype.DILUTION_CONC, null);
     268            lib.loadAnnotations(dc, "DilutionVolume", Annotationtype.DILUTION_VOLUME, null);
    268269            lib.loadAnnotations(dc, "UseForQC", Annotationtype.USE_FOR_QC, null);
    269270           
  • extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/servlet/MRnaServlet.java

    r3809 r3832  
    201201          r.loadBioPlateLocation();
    202202          r.loadAnnotations(dc, "DilutionConc", Annotationtype.DILUTION_CONC, null);
     203          r.loadAnnotations(dc, "DilutionVolume", Annotationtype.DILUTION_VOLUME, null);
    203204          r.loadAnnotations(dc, "UseForQC", Annotationtype.USE_FOR_QC, null);
    204205          Rna rna = r.getRna();
     
    535536          }
    536537          Annotationtype.DILUTION_CONC.setAnnotationValue(dc, childExtract, jsonRna.get("dilutionConc"));
     538          Annotationtype.DILUTION_VOLUME.setAnnotationValue(dc, childExtract, jsonRna.get("dilutionVolume"));
    537539
    538540          if (jsonBarcode != null)
     
    574576            dc.saveItem(discardedRNA);
    575577          }
     578         
     579          //jsonMessages.add(childExtract.getName() + "; used="+usedQuantity + "; conc="+jsonRna.get("dilutionConc"));
    576580         
    577581          dc.saveItem(childExtract);
Note: See TracChangeset for help on using the changeset viewer.