Changeset 4975


Ignore:
Timestamp:
Sep 21, 2018, 8:36:33 AM (4 years ago)
Author:
Nicklas Nordborg
Message:

References #1054: Even more functionality in the Flagged alignment wizard

Implemented functionality for marking items as "Ok to use" or "Do not use". The selection can be done on Specimen, Lysate, RNA or Library level and will affect all downstream child items.

The functionality is only available if a filter is active. If the filter is a Qiacube or Libplate filter it is a requirement that an option is selected for all flagged items. If the "Do not use" option is used a comment is required.

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

Legend:

Unmodified
Added
Removed
  • extensions/net.sf.basedb.reggie/trunk/resources/flaggedalignment/search.js

    r4970 r4975  
    2525    Events.addEventHandler('mode-genotype', 'change', search.modeOnChange);
    2626    Events.addEventHandler('mode-reprocess', 'change', search.modeOnChange);
     27    Events.addEventHandler('mode-resolve', 'change', search.modeOnChange);
    2728   
    2829    Buttons.addClickHandler('goreprocess', search.goReProcess);
    29     // Navigation
    30     /*
    31     Buttons.addClickHandler('gocancel', Wizard.cancelWizard);
    32     Buttons.addClickHandler('gorestart', Wizard.restartWizard);
    33     Buttons.addClickHandler('gonext', Wizard.goNextOnClick);
    34     Buttons.addClickHandler('goregister', Wizard.goRegister);
    35    
    36     // Final registration
    37     Events.addEventHandler('wizard', 'wizard-submit', search.submit);
    38     */
     30    Buttons.addClickHandler('goresolve', search.goResolve);
    3931
    4032    var url = '../Genotype.servlet?ID='+App.getSessionId();
     
    9082        allQiaCubes[allQiaCubes.length] = qiaCube;
    9183        itemByName[qiaCubeRun] = qiaCube;
     84        itemByName[qiaCubeRunPos] = qiaCube;
    9285      }
    9386      else
     
    110103        allLibPlates[allLibPlates.length] = plate;
    111104        itemByName[libPlate.name] = plate;
     105        itemByName[platePos] = plate;
    112106      }
    113107      else
     
    334328    var stepTitle = 'Flagged alignments';
    335329    var filter = null;
     330    var filterType = null;
    336331    var positionProperty = null;
    337332    var highHetFilter = false;
     
    343338    if (Doc.element('highHetFilter').checked)
    344339    {
    345       alignments.sort(Sort.sortAlignmentsByPatientName);
     340      alignments.sort(Sort.sortAlignmentsByLibPlatePosition);
    346341      highHetFilter = true;
    347342      filter = Filter.hetFilter(65);
     343      filterType = 'HET';
     344      positionProperty = Property.LibPlatePosition;
    348345      stepTitle = 'Alignments with HET > 65%';
    349346    }
     
    354351      qiacubefilter = qiaCube.name;
    355352      filter = Filter.qiaCubeFilter(qiaCube.name);
     353      filterType = 'QIACUBE';
    356354      positionProperty = Property.QiaCubePosition;
    357355      stepTitle = 'Alignments related to QiaCube ' + qiaCube.title;
     
    363361      libplatefilter = libPlate.name;
    364362      filter = Filter.libPlateFilter(libPlate.name);
     363      filterType = 'LIBPLATE';
    365364      positionProperty = Property.LibPlatePosition;
    366365      stepTitle = 'Alignments related to ' + libPlate.name;
     
    372371    }
    373372   
    374     if (filter && positionProperty && !noContextAnalysis)
     373    if (filter && positionProperty && !noContextAnalysis && !highHetFilter)
    375374    {
    376375      search.contextAnalysis(filter, positionProperty);
     
    445444      html += '<th class="mode-reprocess comment-col">Comment</th>';
    446445      html += '<th class="mode-reprocess flag-col dottedright">Flag</th>';
     446     
     447      html += '<th class="mode-resolve dottedleft">Ok / Do not use?</th>';
     448      html += '<th class="mode-resolve comment-col">Comment</th>';
    447449    }
    448450    html += '<th></th>';
     
    479481      else
    480482      {
    481         html += '<tbody class="highlight"><tr>';
     483        html += '<tbody class="highlight" id="section.'+aligned.tmpId+'"><tr>';
    482484        html += '<td rowspan="'+tbodySpan+'">'+(sp ? HTMLHelper.colorMatch(sp.patientName, null, 'Click to highlight this patient') : '')+'</td>';
    483485        html += '<td rowspan="'+tbodySpan+'" class="'+(qiacubefilter?'':'mode-genotype')+'">'+(sp ? HTMLHelper.qiaCubeLink(rna.QIACUBE_DATE, rna.QIACUBE_RUN_NO, rna.QIACUBE_POSITION, qiacubefilter, false) : '')+'</td>';
    484         if (libplatefilter)
     486        if (!qiacubefilter)
    485487        {
    486488          html += '<td rowspan="'+tbodySpan+'">'+(libPlate ? HTMLHelper.libPlateLink(libPlate.name, lib.bioWell.location, libplatefilter, false):'')+'</td>';
     
    490492      var tmp = search.getAlignmentHtml(aligned);
    491493     
    492       if (!libplatefilter)
    493       {
    494         html += '<td rowspan="'+rowspan+'" class="'+(highHetFilter?'':'mode-genotype')+'">'+(libPlate ? HTMLHelper.libPlateLink(libPlate.name, lib.bioWell.location, libplatefilter, false):'')+'</td>';
     494      if (qiacubefilter)
     495      {
     496        html += '<td rowspan="'+rowspan+'" class="mode-genotype">'+(libPlate ? HTMLHelper.libPlateLink(libPlate.name, lib.bioWell.location, libplatefilter, false):'')+'</td>';
    495497      }
    496498      html += '<td rowspan="'+rowspan+'">'+Reggie.formatNumber(aligned.QC_GENOTYPE_HET_PCT, '%', -1)+'</td>';
     
    504506          html += '<td rowspan="'+tbodySpan+'" class="mode-reprocess num-col">'+(sp ? Reggie.formatNumber(rna.remainingQuantity, null, 2, 2) : '')+'</td>';
    505507          html += '<td rowspan="'+tbodySpan+'" class="mode-reprocess">'+(sp ? HTMLHelper.reprocessOptions(aligned) : '')+'</td>';
     508
     509          html += '<td rowspan="'+tbodySpan+'" class="mode-resolve dottedleft">'+(sp ? HTMLHelper.resolveOptions(aligned, filterType) : '')+'</td>';
     510          html += '<td rowspan="'+tbodySpan+'" class="mode-resolve comment-col dottedright">'+(sp ? HTMLHelper.resolveComment(aligned) : '')+'</td>';
    506511        }
    507512       
    508         var flagged = aligned.compare && aligned.compare.flagged;
     513        var flagged = aligned.flagged;
    509514        var isAlignment = aligned.name;
    510515        html += '<td rowspan="'+rowspan+'" class="mode-reprocess comment-col">'+(isAlignment ? HTMLHelper.qcCommentInput(aligned) : '')+'</td>';       
     
    548553   
    549554    var enableReprocess = filter && !noContextAnalysis;
     555    var enableResolve = enableReprocess;
    550556    Doc.element('mode-reprocess').disabled = !enableReprocess;
     557    Doc.element('mode-resolve').disabled = !enableResolve;
    551558    search.modeOnChange();
    552559
     
    573580      Events.addEventHandler(cm[i], 'click', search.colorMatch);
    574581    }
     582   
     583    var options = document.getElementsByClassName('donotuse-options');
     584    for (var i = 0; i < options.length; i++)
     585    {
     586      Events.addEventHandler(options[i], 'change', search.doNotUseOptionOnChange);
     587    }
     588
     589    var checks = document.getElementsByClassName('oktouse');
     590    for (var i = 0; i < checks.length; i++)
     591    {
     592      Events.addEventHandler(checks[i], 'change', search.okToUseOnChange);
     593    }
     594
    575595  }
    576596 
     
    683703       
    684704        var otherA = alignmentByName[msg.alignment];
    685         if (otherA.bugged) continue; // The other alignment is a known problem, so we ignore it here
     705        if (otherA.bugged && otherA.bugLevel > 0) continue; // The other alignment is a known problem, so we ignore it here
    686706       
    687707        // If the other alignment is in the same context it may not be useful unless it is a verified alignment
     
    765785  }
    766786 
     787  // Enable/disable the DoNotUse list depending on if the OkToUse is checked or not
     788  search.okToUseOnChange = function(event)
     789  {
     790    var tmpId = event.currentTarget.id.replace('oktouse.', '');
     791    var doNotUseList = Doc.element('donotuse.'+tmpId);
     792    var commentField = Doc.element('resolvecomment.'+tmpId);
     793    if (event.currentTarget.checked)
     794    {
     795      doNotUseList.selectedIndex = 0;
     796      Doc.removeClass(doNotUseList, 'required');
     797      Doc.removeClass(commentField, 'required');
     798      doNotUseList.disabled = true;
     799    }
     800    else
     801    {
     802      Doc.addClass(doNotUseList, 'required');
     803      doNotUseList.disabled = false;
     804    }
     805  }
     806
     807 
     808  // Mark the corresponding comment field as required if the DoNotUse flag is going to be set
     809  search.doNotUseOptionOnChange = function(event)
     810  {
     811    var tmpId = event.currentTarget.id.replace('donotuse.', '');
     812    var value = event.currentTarget.value;   
     813    var commentField = Doc.element('resolvecomment.'+tmpId);
     814    Doc.addOrRemoveClass(commentField, 'required', value != '');
     815  }
     816 
    767817  search.getAlignmentHtml = function(alignment, refAlignment)
    768818  {
     
    806856      icons += '<img src="../images/comment.png" title="'+Strings.encodeTags(alignment.QC_GENOTYPE_COMMENT)+'">';
    807857    }
    808     if (alignment.compare && alignment.compare.flagged)
    809     {
    810       icons += '<img src="../images/flag.png" title="This alignment is already flagged">';
     858    if (alignment.flagged)
     859    {
     860      // We need this class to search for flagged alignments on the "right" side of the table (see goResolve() method)
     861      var cls = refAlignment ? 'paired-alignment' : 'primary-alignment';
     862      icons += '<img src="../images/flag.png" title="This alignment is already flagged" class="'+cls+'" data-id="'+alignment.id+'">';
    811863    }
    812864    if (alignment.QC_GENOTYPE_VERIFIED)
     
    881933    Data.set('itemTable', 'mode', mode);
    882934    Doc.showHide('goreprocess', mode == 'reprocess');
    883     // Doc.showHide('goresolve', mode == 'resolve');
     935    Doc.showHide('goresolve', mode == 'resolve');
    884936    Wizard.hideGoNextConfirmation();
    885937  }
     
    9781030  }
    9791031 
     1032 
     1033  search.goResolve = function()
     1034  {
     1035    Wizard.hideGoNextConfirmation();
     1036    Doc.hide('wizard-status');
     1037    var frm = document.forms['reggie'];
     1038    // We generate a list of items that should either be marked as DoNotUse or OkToUse
     1039    var items = [];
     1040    // This list will are flagged alignements that have a relation to the items in the above list
     1041    // The are potential candidates to be unflagged due to not having any more issues with other alignments
     1042    var flaggedPairs = [];
     1043    var numInvalid = 0;
     1044    for (var itemNo = 0; itemNo < alignments.length; itemNo++)
     1045    {
     1046      var aligned = alignments[itemNo];
     1047     
     1048      // Assume that selection is valid
     1049      Doc.removeClass('section.'+aligned.tmpId, 'invalid');
     1050     
     1051      // Get the form elements for this item
     1052      var okToUse = Doc.element('oktouse.'+aligned.tmpId);
     1053      var doNotUse = Doc.element('donotuse.'+aligned.tmpId);
     1054      var comment = Doc.element('resolvecomment.'+aligned.tmpId);
     1055     
     1056      var item = null;
     1057      if (doNotUse)
     1058      {
     1059        if (okToUse && okToUse.checked)
     1060        {
     1061          if (okToUse.value == 'ok-rna')
     1062          {
     1063            item = {'type': 'EXTRACT', 'id': aligned.rna.id, 'okToUse': true };
     1064          }
     1065          else if (okToUse.value == 'ok-library')
     1066          {
     1067            item = {'type': 'EXTRACT', 'id': aligned.lib.id, 'okToUse': true };
     1068          }
     1069        }
     1070        else if (doNotUse.value == 'specimen')
     1071        {
     1072          item = {'type': 'SAMPLE', 'id': aligned.specimen.id, 'doNotUse': 'Specimen' };
     1073        }
     1074        else if (doNotUse.value == 'lysate')
     1075        {
     1076          item = {'type': 'EXTRACT', 'id': aligned.lysate.id, 'doNotUse': 'Lysate' };
     1077        }
     1078        else if (doNotUse.value == 'rna')
     1079        {
     1080          item = {'type': 'EXTRACT', 'id': aligned.rna.id, 'doNotUse': 'RNA' };
     1081        }
     1082        else if (doNotUse.value == 'library')
     1083        {
     1084          item = {'type': 'EXTRACT', 'id': aligned.lib.id, 'doNotUse': 'Library' };
     1085        }
     1086        else if (aligned.flagged && doNotUse.classList.contains('required'))
     1087        {
     1088          // A flagged item must have a specific option selected (when filtered on QiaCube or LibPlate)
     1089          Doc.addClass('section.'+aligned.tmpId, 'invalid');
     1090          numInvalid++;
     1091        }
     1092      }
     1093      if (item && comment)
     1094      {
     1095        item.comment = Strings.trim(comment.value);
     1096        if (item.doNotUse && item.comment == '')
     1097        {
     1098          // A comment must be specified for all items marked with DoNotUse
     1099          Doc.addClass('section.'+aligned.tmpId, 'invalid');
     1100          numInvalid++;
     1101        }
     1102      }
     1103      if (item != null)
     1104      {
     1105        items[items.length] = item;
     1106       
     1107        // Find flagged alignments that are related to the selected item
     1108        // We take help from the <tbody> section and look for tags with 'paired-alignment' class
     1109        var sectR = Doc.element('section.'+aligned.tmpId);
     1110        var flagged = sectR.getElementsByClassName('paired-alignment');
     1111        for (var fNo = 0; fNo < flagged.length; fNo++)
     1112        {
     1113          flaggedPairs[flaggedPairs.length] = Data.int(flagged[fNo], 'id');
     1114        }
     1115      }
     1116    }
     1117
     1118    if (numInvalid > 0)
     1119    {
     1120      Wizard.notifyError();
     1121      return;
     1122    }
     1123   
     1124    if (items.length == 0)
     1125    {
     1126      Wizard.showGoNextConfirmation(false, 'No changes have been made!');
     1127      return;
     1128    }
     1129   
     1130    Doc.addClass('step-1', 'disabled');
     1131    Doc.hide('navigation');
     1132   
     1133    // Include filter settings in the registration URL so that a new list can be generated
     1134    var highHet = Doc.element('highHetFilter');
     1135    var libPlate = Doc.element('libPlateFilter');
     1136    var qiaCube = Doc.element('qiaCubeFilter');
     1137   
     1138    var url = '../Genotype.servlet?ID='+App.getSessionId();
     1139    url += '&cmd=ResolveProblems';
     1140    if (libPlate.selectedIndex > 0)
     1141    {
     1142      url += '&libPlateFilter='+encodeURIComponent(libPlate.value);
     1143    }
     1144    else if (qiaCube.selectedIndex > 0)
     1145    {
     1146      url += '&qiaCubeFilter='+encodeURIComponent(qiaCube.value);
     1147    }
     1148    else if (highHet.checked)
     1149    {
     1150      url += '&highHetFilter=1';
     1151    }
     1152   
     1153    var submitInfo = {};
     1154    submitInfo.items = items;
     1155    submitInfo.paired = flaggedPairs;
     1156   
     1157    Wizard.showLoadingAnimation('Saving changes...');
     1158    Wizard.asyncJsonRequest(url, search.resolveResults, 'POST', JSON.stringify(submitInfo));
     1159  }
     1160 
     1161  search.resolveResults = function(response)
     1162  {
     1163    search.onAlignmentsLoaded(response);
     1164    Doc.show('navigation');
     1165    Doc.removeClass('step-1', 'disabled');
     1166    Wizard.showFinalMessage(response.messages);
     1167  }
     1168
    9801169  return search;
    9811170}();
     
    12661455  }
    12671456
     1457  /**
     1458    We generate a checkbox (if the item is flagged) and a
     1459    selection list with "DoNotUse" options.
     1460  */
     1461  helper.resolveOptions = function(aligned, filterType)
     1462  {
     1463    var idDoNotUse = 'donotuse.'+aligned.tmpId;
     1464    var idOkToUse = 'oktouse.'+aligned.tmpId;
     1465   
     1466    var cls = aligned.flagged && filterType != 'HET' ? 'required' : '';
     1467
     1468    var html = '';
     1469    if (aligned.flagged)
     1470    {
     1471      var okValue = filterType == 'QIACUBE' ? 'ok-rna' : 'ok-library';
     1472      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.">';
     1473    }
     1474    else
     1475    {
     1476      // Dummy checkbox that is hidden. Used to make the selection lists align
     1477      html += '<input type="checkbox" style="visibility: hidden;">';
     1478    }
     1479   
     1480    html += '<select id="'+idDoNotUse+'" name="'+idDoNotUse+'" class="donotuse-options '+cls+'">';
     1481    html += '<option value="">&nbsp;';
     1482    if (filterType != 'QIACUBE')
     1483    {
     1484      html += '<option value="library">Library';
     1485    }
     1486    html += '<option value="rna">RNA';
     1487    html += '<option value="lysate">Lysate';
     1488    html += '<option value="specimen">Specimen';
     1489    html += '</select>';
     1490
     1491    return html;
     1492  }
     1493
     1494  helper.resolveComment = function(aligned)
     1495  {
     1496    var id = 'resolvecomment.'+aligned.tmpId;
     1497    html = '<input type="text" id="'+id+'" name="'+id+'" value="'+Strings.encodeTags(aligned.QC_GENOTYPE_COMMENT)+'">';
     1498    return html;
     1499  }
     1500
     1501 
    12681502  return helper;
    12691503}();
  • extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/servlet/GenotypeServlet.java

    r4970 r4975  
    1919import org.json.simple.JSONObject;
    2020
     21import net.sf.basedb.core.Annotatable;
    2122import net.sf.basedb.core.AnnotationBatcher;
    2223import net.sf.basedb.core.AnnotationType;
     24import net.sf.basedb.core.BasicItem;
    2325import net.sf.basedb.core.BioMaterial;
    2426import net.sf.basedb.core.BioSource;
     
    3032import net.sf.basedb.core.ItemList;
    3133import net.sf.basedb.core.ItemQuery;
     34import net.sf.basedb.core.ItemSubtype;
     35import net.sf.basedb.core.RawBioAssay;
    3236import net.sf.basedb.core.Sample;
    3337import net.sf.basedb.core.SessionControl;
    3438import net.sf.basedb.core.SimpleProgressReporter;
     39import net.sf.basedb.core.Subtypable;
    3540import net.sf.basedb.core.query.Annotations;
     41import net.sf.basedb.core.query.Expressions;
    3642import net.sf.basedb.core.query.Hql;
    3743import net.sf.basedb.core.query.Orders;
     44import net.sf.basedb.core.query.Restriction;
     45import net.sf.basedb.core.query.Restrictions;
    3846import net.sf.basedb.core.snapshot.SnapshotManager;
    3947import net.sf.basedb.reggie.JsonUtil;
     
    480488        dc.commit();
    481489      }
     490      else if ("ResolveProblems".equals(cmd))
     491      {
     492        dc = sc.newDbControl();
     493
     494        ReggieRole.checkPermission(dc, "'" + cmd + "' wizard", ReggieRole.PREP_CURATOR, ReggieRole.ADMINISTRATOR);
     495
     496        JSONObject jsonReq = JsonUtil.parseRequest(req);
     497        JSONArray jsonItems = (JSONArray)jsonReq.get("items");
     498        Set<Number> jsonPaired = new HashSet<Number>((JSONArray)jsonReq.get("paired"));
     499       
     500        ItemSubtype mergedType = Subtype.MERGED_SEQUENCES.get(dc);
     501        ItemSubtype alignedType = Subtype.ALIGNED_SEQUENCES.get(dc);
     502        ItemList flaggedAlignments = BiomaterialList.FLAGGED_ALIGNMENT.get(dc);
     503       
     504        GenoTypeChecker checker = new GenoTypeChecker();
     505        checker.preloadVcfForFlaggedAlignments(dc);
     506        checker.preloadSpecimenData(dc);
     507
     508        int numRootDoNotUse = 0;
     509        int numTotalDoNotUse = 0;
     510        int numUnflagged = 0;
     511        int numDisabled = 0;
     512        int numOkToUse = 0;
     513        int numAutoUnflagged = 0;
     514       
     515        JSONArray jsonDebug = new JSONArray();
     516        Set<BasicItem> alreadyProcessed = new HashSet<>();
     517       
     518        for (int itemNo = 0; itemNo < jsonItems.size(); itemNo++)
     519        {
     520          JSONObject jsonItem = (JSONObject)jsonItems.get(itemNo);
     521         
     522          Item itemType = Item.valueOf((String)jsonItem.get("type"));
     523          Number itemId = (Number)jsonItem.get("id");
     524          // Only one of the options below should be set
     525          String doNotUse = (String)jsonItem.get("doNotUse");
     526          boolean okToUse = Boolean.TRUE.equals(jsonItem.get("okToUse"));
     527          String comment = (String)jsonItem.get("comment");
     528         
     529          // The root item is typically a Library, RNA, Lysate or Specimen (same as indicated by the DoNotUse value)
     530          BioMaterial rootItem = (BioMaterial)itemType.getById(dc, itemId.intValue());
     531          if (alreadyProcessed.contains(rootItem))
     532          {
     533            jsonDebug.add("[Debug]Already processed: "+ rootItem + " [" + doNotUse + "]");
     534            continue;
     535          }
     536         
     537          // Load all downstream items (by matching the name)
     538          List<BasicItem> allChildItems = getAllChildItems(dc, rootItem);
     539         
     540          for (BasicItem basicItem : allChildItems)
     541          {
     542            if (alreadyProcessed.contains(basicItem))
     543            {
     544              jsonDebug.add("[Debug]Already processed: "+ basicItem + " [" + doNotUse + "]");
     545              continue;
     546            }
     547            alreadyProcessed.add(basicItem);
     548           
     549            ItemSubtype subtype = null;
     550            if (basicItem instanceof Subtypable)
     551            {
     552              subtype = ((Subtypable)basicItem).getItemSubtype();
     553            }
     554           
     555            Annotatable a = (Annotatable)basicItem;
     556
     557            // Set the DoNotUse and DoNotUseComment annotations
     558            if (doNotUse != null)
     559            {
     560              Annotationtype.DO_NOT_USE.setAnnotationValue(dc, a, doNotUse);
     561              Annotationtype.DO_NOT_USE_COMMENT.setAnnotationValue(dc, a, comment);
     562              jsonDebug.add("[Debug]Do not use: " + basicItem + " ["+doNotUse+"]");
     563              numTotalDoNotUse++;
     564              if (basicItem == rootItem) numRootDoNotUse++;
     565            }
     566           
     567            // Alignments need special handling
     568            if (alignedType.equals(subtype))
     569            {
     570              DerivedBioAssay dba = (DerivedBioAssay)basicItem;
     571
     572              // If there is no current status it is probably an alignment that have no GT data (eg. legacy pipeline)
     573              String currentQcStatus = (String)Annotationtype.QC_GENOTYPE_STATUS.getAnnotationValue(dc, a);
     574
     575              // Remove it from the flagged alignments list
     576              // We check the size before and after to see if the alignment was in the list to begin with
     577              int sizeBefore = flaggedAlignments.getSize();
     578              flaggedAlignments.remove(dba);
     579              int sizeAfter = flaggedAlignments.getSize();
     580              if (sizeAfter < sizeBefore)
     581              {
     582                jsonDebug.add("[Debug]Unflagged: " + basicItem + " [" + sizeAfter + "<" + sizeBefore + "]");
     583                numUnflagged++;
     584              }
     585             
     586              // Remove it from the GenotypeChecker to make the auto-unflag functionality work
     587              if (checker.remove(dba))
     588              {
     589                jsonDebug.add("[Debug]Removed: "+ dba);
     590              }
     591             
     592              if (currentQcStatus != null)
     593              {
     594                // Disable alignment from future GT checks
     595                if (doNotUse != null)
     596                {
     597                  Annotationtype.QC_GENOTYPE_STATUS.setAnnotationValue(dc, dba, "Disabled");
     598                  jsonDebug.add("[Debug]Disabled: " + basicItem);
     599                  numDisabled++;
     600                }
     601                else if (okToUse)
     602                {
     603                  Annotationtype.QC_GENOTYPE_STATUS.setAnnotationValue(dc, dba, "Checked");
     604                  if (comment != null) Annotationtype.QC_GENOTYPE_COMMENT.setAnnotationValue(dc, dba, comment);
     605                  jsonDebug.add("[Debug]OkToUse: " + basicItem + " [" + comment + "]");
     606                  numOkToUse++;
     607                }
     608              }
     609            }
     610          }
     611        }
     612       
     613        // Handles related (flagged alignments) that may no longer see any genotype errors after
     614        // removing the DoNotUse/OkToUse alignments from the flagged alignments list
     615        for (Number id : jsonPaired)
     616        {
     617          //Number id = (Number)jsonPaired.get(itemNo);
     618          DerivedBioAssay dba = DerivedBioAssay.getById(dc, id.intValue());
     619          if (checker.isFlagged(dba))
     620          {
     621            CompareData cmp = checker.check(dc, dba);
     622            if (!cmp.getRecommendFlag())
     623            {
     624              flaggedAlignments.remove(dba);
     625              jsonDebug.add("[Debug]Auto-unflag:" + dba);
     626              numAutoUnflagged++;
     627            }
     628            else
     629            {
     630              jsonDebug.add("[Debug]Still flagged: "+ dba);
     631            }
     632          }
     633          else
     634          {
     635            jsonDebug.add("[Debug]Not flagged: " + dba);
     636          }
     637        }
     638
     639        if (numRootDoNotUse > 0)
     640        {
     641          jsonMessages.add(numRootDoNotUse + " main items and " + (numTotalDoNotUse-numRootDoNotUse) + " related items marked as DoNotUse.");
     642        }
     643       
     644        if (numDisabled > 0)
     645        {
     646          jsonMessages.add(numDisabled + " alignments have been disabled for future genotype checks.");
     647        }
     648
     649        if (numOkToUse > 0)
     650        {
     651          jsonMessages.add(numOkToUse + " alignments are ok to use.");
     652        }
     653       
     654        if (numAutoUnflagged > 0)
     655        {
     656          jsonMessages.add(numAutoUnflagged + " related alignments have been automatically unflagged.");
     657        }
     658       
     659        jsonMessages.addAll(jsonDebug);
     660       
     661        dc.commit();
     662       
     663        // Reload flagged alignments so that the browser can update the table
     664        dc = sc.newDbControl();
     665        json.put("alignments", loadFlaggedAlignments(dc, req));
     666        dc.commit();
     667      }
    482668     
    483669      json.put("messages", jsonMessages);
     
    600786  private JSONArray loadFlaggedAlignments(DbControl dc, HttpServletRequest req)
    601787  {
    602     GenoTypeChecker checker = new GenoTypeChecker();
    603    
    604788    String libPlateFilter = req.getParameter("libPlateFilter");
    605789    String qiaCubeFilter = req.getParameter("qiaCubeFilter");
    606790    boolean highHetFilter = Values.getBoolean(req.getParameter("highHetFilter"));
    607791   
     792    GenoTypeChecker checker = new GenoTypeChecker();
    608793    checker.preloadVcfForFlaggedAlignments(dc);
    609794    checker.preloadSpecimenData(dc);
     
    660845      as.loadAnnotations(dc, manager, "QC_GENOTYPE_COMMENT", Annotationtype.QC_GENOTYPE_COMMENT, null);
    661846      as.setAnnotation("QC_GENOTYPE_STATUS", qcStatus);
     847      as.setAnnotation("flagged", checker.isFlagged(as.getItem()));
    662848      Library lib = as.getLibrary(dc);
    663849      lib.loadBioPlateLocation();
     
    744930  }
    745931 
     932  private List<BasicItem> getAllChildItems(DbControl dc, BioMaterial item)
     933  {
     934    List<BasicItem> allItems = new ArrayList<BasicItem>();
     935    allItems.add(item);
     936   
     937    Restriction byName = Restrictions.like(Hql.property("name"), Expressions.string(item.getName()+".%"));
     938   
     939    // Find child extracts
     940    ItemQuery<Extract> extractQuery = Extract.getQuery();
     941    extractQuery.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
     942    extractQuery.restrict(byName);
     943    allItems.addAll(extractQuery.list(dc));
     944   
     945    // Find child derived bioassays
     946    ItemQuery<DerivedBioAssay> dbaQuery = DerivedBioAssay.getQuery();
     947    dbaQuery.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
     948    dbaQuery.restrict(byName);
     949    allItems.addAll(dbaQuery.list(dc));
     950   
     951    // Find child raw bioassays
     952    ItemQuery<RawBioAssay> rawQuery = RawBioAssay.getQuery();
     953    rawQuery.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
     954    rawQuery.restrict(byName);
     955    allItems.addAll(rawQuery.list(dc));
     956   
     957    return allItems;
     958  }
     959
    746960}
  • extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/vcf/CompareData.java

    r4819 r4975  
    107107 
    108108  /**
     109    Is the recommendation that the alignment should be
     110    disabled or not?
     111    @since 4.20
     112  */
     113  public boolean getRecommendDisable()
     114  {
     115    return recommendDisable;
     116  }
     117 
     118  /**
    109119    Set a flag indicating that the recommended action
    110120    is to flag this alignment that further investigations
     
    114124  {
    115125    this.recommendFlag = true;
     126  }
     127 
     128  /**
     129    Is the recommendation that the alignment should be
     130    flagged or not?
     131    @since 4.20
     132  */
     133  public boolean getRecommendFlag()
     134  {
     135    return recommendFlag;
    116136  }
    117137 
  • extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/vcf/GenoTypeChecker.java

    r4821 r4975  
    180180   
    181181    return query;
     182  }
     183 
     184  /**
     185    Is the given derived bioassay flagged?
     186    (=member of the "Flagged alignemnts" list).
     187    @since 4.20
     188  */
     189  public boolean isFlagged(DerivedBioAssay alignment)
     190  {
     191    return flaggedAlignments.contains(alignment.getId());
     192  }
     193 
     194  /**
     195    Remove the given derived bioassay from genotype comparisons.
     196    Intended to be used as part of unflagging and resolving process
     197    so that we can check if remaining flagged alignments still get
     198    error or not.
     199    @since 4.20
     200  */
     201  public boolean remove(DerivedBioAssay alignment)
     202  {
     203    flaggedAlignments.remove(alignment.getId());
     204    return preloaded.remove(alignment) != null;
    182205  }
    183206 
Note: See TracChangeset for help on using the changeset viewer.