Changeset 2134


Ignore:
Timestamp:
Nov 11, 2013, 2:07:37 PM (10 years ago)
Author:
Nicklas Nordborg
Message:

References #489: Histology scoring wizard

Merge development branch (brances/ticket-489) to trunk.

Location:
extensions/net.sf.basedb.reggie/trunk
Files:
20 edited
7 copied

Legend:

Unmodified
Added
Removed
  • extensions/net.sf.basedb.reggie/trunk

  • extensions/net.sf.basedb.reggie/trunk/META-INF/extensions.xml

    r2133 r2134  
    151151      <ref index="1">net.sf.basedb.clients.web.listcolumn.sample</ref>
    152152      <ref index="1">net.sf.basedb.clients.web.listcolumn.extract</ref>
     153      <ref index="1">net.sf.basedb.clients.web.listcolumn.bioplate</ref>
    153154    </extends>
    154155    <index>2</index>
     
    156157      <name>Reggie column</name>
    157158      <description>
    158         Add a column to the list page of samples and extract for
    159         including some reggie-specific links.
     159        Add a column to the list page of samples, extract and bioplates
     160        for including some reggie-specific links.
    160161      </description>
    161162    </about>
     
    194195  </extension>
    195196 
     197  <extension
     198    id="net.sf.basedb.reggie.toolbar.histology-score"
     199    extends="net.sf.basedb.clients.web.toolbar.item.bioplate"
     200    >
     201    <about>
     202      <name>Histology score</name>
     203      <description>
     204        Adds a button to the toolbar of paraffin blocks and
     205        HE stain bioplates that start the 'histology scoring wizard'.
     206      </description>
     207    </about>
     208    <action-factory>
     209      <factory-class>
     210        net.sf.basedb.reggie.extensions.HistologyScoreButtonFactory
     211      </factory-class>
     212    </action-factory>
     213  </extension>
    196214 
    197215</extensions>
  • extensions/net.sf.basedb.reggie/trunk/resources/index.jsp

    r2063 r2134  
    104104      url = 'Histology.servlet?ID=<%=ID%>&cmd=CountParaffinBlocksWithoutHeGlass';
    105105    }
     106    else if (what == 'unscored-heglass')
     107    {
     108      url = 'Histology.servlet?ID=<%=ID%>&cmd=CountUnscoredHeGlass';
     109    }
    106110    else if (what == 'lysate')
    107111    {
     
    206210      var count = error ? -1 : response.count;
    207211      setCount('count.paraffin-blocks-without-heglass', count, 'paraffin blocks', msg);
     212      startCounting('unscored-heglass');
     213    }
     214    else if (currentCount == 'unscored-heglass')
     215    {
     216      var msg = error || 'Number of unscored HE glass';
     217      var count = error ? -1 : response.count;
     218      setCount('count.unscored-heglass', count, 'HE glass', msg);
    208219      startCounting('lysate');
    209220    }
     
    429440            <li><a href="sampleproc/histology_protocol.jsp?ID=<%=ID%>">Lab tracking protocol for FFPE/HE</a> <span class="counter" id="count.histology-lists" title="Counting..."><img src="images/loading-small.gif"></span>
    430441            <li><a href="sampleproc/histology_block.jsp?ID=<%=ID%>">Register paraffin blocks</a> <span class="counter" id="count.paraffin-blocks" title="Counting..."><img src="images/loading-small.gif"></span>
    431             <li><a href="sampleproc/histology_glass.jsp?ID=<%=ID%>">Register histology HE glass information</a> <span class="counter" id="count.paraffin-blocks-without-heglass" title="Counting..."><img src="images/loading-small.gif"></span>
     442            <li><a href="sampleproc/histology_glass.jsp?ID=<%=ID%>">Register HE glass</a> <span class="counter" id="count.paraffin-blocks-without-heglass" title="Counting..."><img src="images/loading-small.gif"></span>
     443            <li><a href="sampleproc/histology_score.jsp?ID=<%=ID%>">Score HE glass</a> <span class="counter" id="count.unscored-heglass" title="Counting..."><img src="images/loading-small.gif"></span>
    432444            </ul>
    433445          </dd>
  • extensions/net.sf.basedb.reggie/trunk/resources/reports/case_summary.jsp

    r2106 r2134  
    281281}
    282282
     283function asPercent(value)
     284{
     285  var result = '';
     286  if (value != null)
     287  {
     288    result = value + '%';
     289  }
     290  return result;
     291}
     292
    283293function init()
    284294{
     
    463473
    464474      var stained = h.stainDate ? true : false;
     475      var bestStain = stained ? h.bestStain : null;
     476      var scored = bestStain && bestStain.ScoreComplete != null ? true : false;
     477       
    465478      addColumn('histology.stained', stained ? formatDate(h.stainDate) : 'No');
    466479      addColumn('histology.nofSlides', stained ? h.numStains : null);
    467       addColumn('histology.heGlass', stained ? asBioPlateLocation(h.bestStain) : null);
     480      addColumn('histology.heGlass', stained ? asBioPlateLocation(bestStain.bioWell) : null);
    468481      addColumn('histology.stainProtocol', stained ? makeLink('PROTOCOL', h.stainProtocol, truncateAt) : null);
     482     
     483      addColumn('histology.scored', scored ? (bestStain.ScoreComplete ? 'Complete' : 'In progress') : 'No');
     484      addColumn('histology.scoreInvasiveCancer', scored ? asPercent(bestStain.ScoreInvasiveCancer) : null);
     485      addColumn('histology.scoreInsituCancer', scored ? asPercent(bestStain.ScoreInsituCancer) : null);
     486      addColumn('histology.scoreLymphocytes', scored ? asPercent(bestStain.ScoreLymphocytes) : null);
     487      addColumn('histology.scoreNormal', scored ? asPercent(bestStain.ScoreNormal) : null);
     488      addColumn('histology.scoreStroma', scored ? asPercent(bestStain.ScoreStroma) : null);
     489      addColumn('histology.scoreFat', scored ? asPercent(bestStain.ScoreFat) : null);
     490      addColumn('histology.scoreComments', scored ? truncate(bestStain.comments, truncateAt) : null);
    469491    }
    470492  }
     
    11231145              <th>Protocol</th>
    11241146            </tr>
     1147            <tr id="histology.scored" class="subtitle">
     1148              <th>Scored</th>
     1149            </tr>
     1150            <tr id="histology.scoreInvasiveCancer" class="dynamic-column">
     1151              <th>Invasive cancer</th>
     1152            </tr>
     1153            <tr id="histology.scoreInsituCancer" class="dynamic-column">
     1154              <th>Insitu cancer</th>
     1155            </tr>
     1156            <tr id="histology.scoreLymphocytes" class="dynamic-column">
     1157              <th>Lymphocytes</th>
     1158            </tr>
     1159            <tr id="histology.scoreNormal" class="dynamic-column">
     1160              <th>Normal</th>
     1161            </tr>
     1162            <tr id="histology.scoreStroma" class="dynamic-column">
     1163              <th>Stroma</th>
     1164            </tr>
     1165            <tr id="histology.scoreFat" class="dynamic-column">
     1166              <th>Fat</th>
     1167            </tr>
     1168            <tr id="histology.scoreComments" class="comment dynamic-column">
     1169              <th>Comments</th>
     1170            </tr>
    11251171          </tbody>
    11261172          </table>
  • extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/JsonUtil.java

    r1940 r2134  
    6060
    6161  @SuppressWarnings("unchecked")
    62   public static JSONObject getBioWellAsJSON(BioWell well)
     62  public static JSONObject getBioWellAsJSON(BioWell well, boolean includePlateInfo)
    6363  {
    6464    if (well == null) return null;
     
    7171    json.put("canAdd", well.canAddBioMaterial());
    7272    json.put("canRemove", well.canClearBioMaterial());
     73   
     74    if (includePlateInfo)
     75    {       
     76      BioPlate plate = well.getPlate();
     77      JSONObject jsonPlate = new JSONObject();
     78      jsonPlate.put("id", plate.getId());
     79      jsonPlate.put("name", plate.getName());
     80      jsonPlate.put("barcode", plate.getBarcode());
     81      jsonPlate.put("editable", plate.hasPermission(Permission.WRITE));
    7382     
    74     BioPlate plate = well.getPlate();
    75     JSONObject jsonPlate = new JSONObject();
    76     jsonPlate.put("id", plate.getId());
    77     jsonPlate.put("name", plate.getName());
    78     jsonPlate.put("barcode", plate.getBarcode());
    79     jsonPlate.put("editable", plate.hasPermission(Permission.WRITE));
    80    
    81     Hardware storage = plate.getFreezer();
    82     if (storage != null || plate.getSection() != null || plate.getTray() != null || plate.getPosition() != null)
    83     {
    84       JSONObject jsonStorage = new JSONObject();
    85       if (storage != null)
     83      Hardware storage = plate.getFreezer();
     84      if (storage != null || plate.getSection() != null || plate.getTray() != null || plate.getPosition() != null)
    8685      {
    87         jsonStorage.put("id", storage.getId());
    88         jsonStorage.put("name", storage.getName());
     86        JSONObject jsonStorage = new JSONObject();
     87        if (storage != null)
     88        {
     89          jsonStorage.put("id", storage.getId());
     90          jsonStorage.put("name", storage.getName());
     91        }
     92        jsonStorage.put("section", plate.getSection());
     93        jsonStorage.put("tray", plate.getTray());
     94        jsonStorage.put("position", plate.getPosition());
     95        jsonPlate.put("storage", jsonStorage);
    8996      }
    90       jsonStorage.put("section", plate.getSection());
    91       jsonStorage.put("tray", plate.getTray());
    92       jsonStorage.put("position", plate.getPosition());
    93       jsonPlate.put("storage", jsonStorage);
     97     
     98      json.put("bioPlate", jsonPlate);
    9499    }
    95    
    96     json.put("bioPlate", jsonPlate);
    97100    return json;
    98101  }
  • extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/dao/Annotationtype.java

    r2102 r2134  
    242242  public static final Annotationtype GOOD_STAIN =
    243243    new Annotationtype("GoodStain", Type.BOOLEAN, Item.SAMPLE);
     244
     245 
     246  /**
     247    The "ScoreComplete" annotation type, used for histology samples
     248    (Stained) and bioplates (HE glass). It is a boolean annotation type.
     249    @since 2.14
     250  */
     251  public static final Annotationtype SCORE_COMPLETE =
     252    new Annotationtype("ScoreComplete", Type.BOOLEAN, Item.SAMPLE, Item.BIOPLATE);
     253
     254
     255  /**
     256    The "ScoreInvasiveCancer" annotation type, used for histology samples
     257    (Stained). It is an integer annotation type.
     258    @since 2.14
     259  */
     260  public static final Annotationtype SCORE_INVASIVE_CANCER =
     261    new Annotationtype("ScoreInvasiveCancer", Type.INT, Item.SAMPLE);
     262
     263  /**
     264    The "ScoreInsituCancer" annotation type, used for histology samples
     265    (Stained). It is an integer annotation type.
     266    @since 2.14
     267  */
     268  public static final Annotationtype SCORE_INSITU_CANCER =
     269    new Annotationtype("ScoreInsituCancer", Type.INT, Item.SAMPLE);
     270
     271  /**
     272    The "ScoreLymphocytes" annotation type, used for histology samples
     273    (Stained). It is an integer annotation type.
     274    @since 2.14
     275  */
     276  public static final Annotationtype SCORE_LYMPHOCYTES =
     277    new Annotationtype("ScoreLymphocytes", Type.INT, Item.SAMPLE);
     278
     279  /**
     280    The "ScoreNormal" annotation type, used for histology samples
     281    (Stained). It is an integer annotation type.
     282    @since 2.14
     283  */
     284  public static final Annotationtype SCORE_NORMAL =
     285    new Annotationtype("ScoreNormal", Type.INT, Item.SAMPLE);
     286
     287  /**
     288    The "ScoreStroma" annotation type, used for histology samples
     289    (Stained). It is an integer annotation type.
     290    @since 2.14
     291  */
     292  public static final Annotationtype SCORE_STROMA =
     293    new Annotationtype("ScoreStroma", Type.INT, Item.SAMPLE);
     294
     295  /**
     296    The "ScoreFat" annotation type, used for histology samples
     297    (Stained). It is an integer annotation type.
     298    @since 2.14
     299  */
     300  public static final Annotationtype SCORE_FAT =
     301    new Annotationtype("ScoreFat", Type.INT, Item.SAMPLE);
    244302 
    245303  /**
  • extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/dao/CDna.java

    r2082 r2134  
    102102    if (jsonWell == null)
    103103    {
    104       jsonWell = JsonUtil.getBioWellAsJSON(getItem().getBioWell());
     104      jsonWell = JsonUtil.getBioWellAsJSON(getItem().getBioWell(), true);
    105105    }
    106106    return jsonWell;
  • extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/dao/Dna.java

    r2098 r2134  
    107107    if (jsonWell == null)
    108108    {
    109       jsonWell = JsonUtil.getBioWellAsJSON(getItem().getBioWell());
     109      jsonWell = JsonUtil.getBioWellAsJSON(getItem().getBioWell(), true);
    110110    }
    111111    return jsonWell;
  • extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/dao/FlowThrough.java

    r2098 r2134  
    107107    if (jsonWell == null)
    108108    {
    109       jsonWell = JsonUtil.getBioWellAsJSON(getItem().getBioWell());
     109      jsonWell = JsonUtil.getBioWellAsJSON(getItem().getBioWell(), true);
    110110    }
    111111    return jsonWell;
  • extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/dao/Histology.java

    r1831 r2134  
    157157    if (jsonWell == null)
    158158    {
    159       jsonWell = JsonUtil.getBioWellAsJSON(getItem().getBioWell());
     159      jsonWell = JsonUtil.getBioWellAsJSON(getItem().getBioWell(), true);
    160160    }
    161161    return jsonWell;
  • extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/dao/Library.java

    r2050 r2134  
    141141    if (well != null)
    142142    {
    143       jsonWell = JsonUtil.getBioWellAsJSON(well);
     143      jsonWell = JsonUtil.getBioWellAsJSON(well, true);
    144144    }
    145145
  • extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/dao/Lysate.java

    r1831 r2134  
    130130    if (jsonWell == null)
    131131    {
    132       jsonWell = JsonUtil.getBioWellAsJSON(getItem().getBioWell());
     132      jsonWell = JsonUtil.getBioWellAsJSON(getItem().getBioWell(), true);
    133133    }
    134134    return jsonWell;
  • extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/dao/MRna.java

    r2050 r2134  
    113113    if (jsonWell == null)
    114114    {
    115       jsonWell = JsonUtil.getBioWellAsJSON(getItem().getBioWell());
     115      jsonWell = JsonUtil.getBioWellAsJSON(getItem().getBioWell(), true);
    116116    }
    117117    return jsonWell;
  • extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/dao/Rna.java

    r2020 r2134  
    367367    if (jsonWell == null)
    368368    {
    369       jsonWell = JsonUtil.getBioWellAsJSON(getItem().getBioWell());
     369      jsonWell = JsonUtil.getBioWellAsJSON(getItem().getBioWell(), true);
    370370    }
    371371    return jsonWell;
  • extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/dao/SpecimenTube.java

    r1826 r2134  
    213213    if (jsonWell == null)
    214214    {
    215       jsonWell = JsonUtil.getBioWellAsJSON(getItem().getBioWell());
     215      jsonWell = JsonUtil.getBioWellAsJSON(getItem().getBioWell(), true);
    216216    }
    217217    return jsonWell;
  • extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/extensions/ReggieListColumnsFactory.java

    r1915 r2134  
    66import net.sf.basedb.clients.web.extensions.list.ListColumnAction;
    77import net.sf.basedb.core.BioMaterial;
     8import net.sf.basedb.core.BioPlate;
    89import net.sf.basedb.core.DbControl;
     10import net.sf.basedb.core.Item;
    911import net.sf.basedb.reggie.Reggie;
    1012import net.sf.basedb.util.extensions.InvokationContext;
    1113
    1214/**
    13   Factory that add a "Reggie" column to the sample and extract list pages.
    14   In this column, we can add reggie-specific information, such as a link
    15   to the "Case summary" function for all items that
     15  Factory that add a "Reggie" column to the sample, extract and bioplate
     16  list pages. In this column, we can add reggie-specific information, such as a
     17  link to the "Case summary" function for all items that
    1618  can be matched to a case name, eg. it starts with 7 digits, optionally
    1719  followed by a dot.
     20 
     21  In 2.14: Added link to Histology scoring wizard for PB and HE plates.
    1822 
    1923  @author Nicklas
     
    3438    String ID = jspContext.getSessionControl().getId();
    3539    String reggieHome = jspContext.getHome(context.getExtension());
    36     ColumnAction action = new ColumnAction(ID, reggieHome);
     40    Item guiItem = jspContext.getGuiContext().getItem();
     41    ListColumnAction action = null;
     42    if (guiItem == Item.BIOPLATE)
     43    {
     44      action = new BioPlateColumnAction(ID, reggieHome);
     45    }
     46    else if (guiItem == Item.SAMPLE || guiItem == Item.EXTRACT)
     47    {
     48      action = new BioMaterialColumnAction(ID, reggieHome);
     49    }
    3750    return new ListColumnAction[] { action };
    3851  }
    3952
    40   static class ColumnAction
     53  static class BioMaterialColumnAction
    4154    extends AbstractListColumnBean<BioMaterial, String>
    4255  {
     
    4457    private final String reggieHome;
    4558   
    46     ColumnAction(String ID, String reggieHome)
     59    BioMaterialColumnAction(String ID, String reggieHome)
    4760    {
    4861      this.ID = ID;
     
    7083    }
    7184  }
     85 
     86  static class BioPlateColumnAction
     87    extends AbstractListColumnBean<BioPlate, String>
     88  {
     89    private final String ID;
     90    private final String reggieHome;
     91   
     92    BioPlateColumnAction(String ID, String reggieHome)
     93    {
     94      this.ID = ID;
     95      this.reggieHome = reggieHome;
     96      setId("reggie");
     97      setTitle("Reggie");
     98    }
     99 
     100    @Override
     101    public String getValue(DbControl dc, BioPlate plate)
     102    {
     103      String value = null;
     104      String name = plate.getName();
     105      if (name != null && HistologyScoreButtonFactory.HE_PLATE_PATTERN.matcher(name).matches())
     106      {
     107        String heName = "HE" + name.substring(2, 7);
     108        StringBuilder sb = new StringBuilder();
     109        sb.append("<a href=\"" + reggieHome + "/sampleproc/histology_score.jsp?ID="+ID+"&name="+heName+"\"");
     110        sb.append(" title=\"Goto HE glass scoring wizard\"");
     111        sb.append("><img src=\""+reggieHome+"/images/microscope.png\">");
     112        sb.append("</a>");
     113        value = sb.toString();
     114      }
     115      return value;
     116    }
     117  }
     118
    72119}
  • extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/servlet/CaseSummaryServlet.java

    r2103 r2134  
    430430  }
    431431
     432  @SuppressWarnings("unchecked")
    432433  private void loadHistologyInfo(DbControl dc, Histology his)
    433434  {
     
    472473      if (goodIsGood)
    473474      {
    474         his.setAnnotation("bestStain", JsonUtil.getBioWellAsJSON(good.getBioWell()));
     475        JSONObject jsonGood = new JSONObject();
     476        jsonGood.put("id", good.getId());
     477        jsonGood.put("name", good.getName());
     478        jsonGood.put("bioWell", JsonUtil.getBioWellAsJSON(good.getBioWell(), true));
     479        jsonGood.put("comments", good.getDescription());
     480       
     481        jsonGood.put("ScoreComplete", Annotationtype.SCORE_COMPLETE.getAnnotationValue(dc, good));
     482        jsonGood.put("ScoreInvasiveCancer", Annotationtype.SCORE_INVASIVE_CANCER.getAnnotationValue(dc, good));
     483        jsonGood.put("ScoreInsituCancer", Annotationtype.SCORE_INSITU_CANCER.getAnnotationValue(dc, good));
     484        jsonGood.put("ScoreLymphocytes", Annotationtype.SCORE_LYMPHOCYTES.getAnnotationValue(dc, good));
     485        jsonGood.put("ScoreNormal", Annotationtype.SCORE_NORMAL.getAnnotationValue(dc, good));
     486        jsonGood.put("ScoreStroma", Annotationtype.SCORE_STROMA.getAnnotationValue(dc, good));
     487        jsonGood.put("ScoreFat", Annotationtype.SCORE_FAT.getAnnotationValue(dc, good));
     488       
     489        his.setAnnotation("bestStain", jsonGood);
    475490      }
    476491    }
     
    564579      rna.setAnnotation("nofQc", rnaqc.size());
    565580      rna.setAnnotation("qcProtocol", JsonUtil.getProtocolAsJSON(lastQc.getProtocol()));
    566       rna.setAnnotation("qcPlate", JsonUtil.getBioWellAsJSON(lastQc.getBioWell()));
     581      rna.setAnnotation("qcPlate", JsonUtil.getBioWellAsJSON(lastQc.getBioWell(), true));
    567582      rna.setAnnotation("qcComment", lastQc.getDescription());
    568583
  • extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/servlet/HistologyServlet.java

    r1983 r2134  
    3737import net.sf.basedb.core.SessionControl;
    3838import net.sf.basedb.core.data.PlateCoordinate;
     39import net.sf.basedb.core.query.Annotations;
    3940import net.sf.basedb.core.query.Expressions;
    4041import net.sf.basedb.core.query.Hql;
     
    4445import net.sf.basedb.reggie.dao.Annotationtype;
    4546import net.sf.basedb.reggie.dao.BioplateType;
     47import net.sf.basedb.reggie.dao.HeGlass;
    4648import net.sf.basedb.reggie.dao.Histology;
    4749import net.sf.basedb.reggie.dao.ReactionPlate;
     
    344346       
    345347      }
     348      else if ("CountUnscoredHeGlass".equals(cmd))
     349      {
     350        dc = sc.newDbControl();
     351        ItemQuery<BioPlate> query = BioPlate.getQuery();
     352        query.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
     353        BioplateType.HE_GLASS.addFilter(dc, query, true);
     354       
     355        // Missing of 'false' for SCORE_COMPLETE annotation
     356        query.join(Annotations.leftJoin(null, Annotationtype.SCORE_COMPLETE.load(dc), "sc"));
     357        query.restrict(
     358          Restrictions.or(
     359            Restrictions.eq(Hql.alias("sc"), null),
     360            Restrictions.eq(Hql.alias("sc"), Expressions.bool(false))
     361          ));
     362       
     363        long count = query.count(dc);
     364        json.put("count", count);
     365      }
     366      else if ("GetHeGlassToScore".equals(cmd))
     367      {
     368        dc = sc.newDbControl();
     369       
     370        String name = Values.getStringOrNull(req.getParameter("name"));
     371       
     372        JSONArray jsonHeGlasses = new JSONArray();
     373        if (name == null)
     374        {
     375          // No name specified...
     376          // ... find the name of first unscored glass that is not destroyed
     377          ItemQuery<BioPlate> tmpQuery = BioPlate.getQuery();
     378          tmpQuery.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
     379          BioplateType.HE_GLASS.addFilter(dc, tmpQuery, true);
     380          tmpQuery.join(Annotations.leftJoin(null, Annotationtype.SCORE_COMPLETE.load(dc), "sc"));
     381          tmpQuery.restrict(Restrictions.eq(Hql.alias("sc"), null));
     382          tmpQuery.order(Orders.asc(Hql.property("name")));
     383          tmpQuery.setMaxResults(1);
     384          List<BioPlate> result = tmpQuery.list(dc);
     385          if (result.size() > 0)
     386          {
     387            name = result.get(0).getName();
     388          }
     389        }
     390       
     391        if (name != null)
     392        {
     393          // Now, find all HE glass that are related to the original
     394          int dotIndex = name.indexOf('.');
     395          String prefix = dotIndex > 0 ? name.substring(0, dotIndex) : name;
     396          ItemQuery<BioPlate> query = BioPlate.getQuery();
     397          query.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
     398          BioplateType.HE_GLASS.addFilter(dc, query, false);
     399          query.restrict(Restrictions.rlike(Hql.property("name"), Expressions.string("^" + prefix + "\\.[0-9]+$")));
     400          query.order(Orders.asc(Hql.property("name")));
     401         
     402          List<HeGlass> plates = HeGlass.toList(query.list(dc));
     403          for (HeGlass heGlass : plates)
     404          {
     405            heGlass.loadSampleScores(dc);
     406            heGlass.loadAnnotations(dc, "ScoreComplete", Annotationtype.SCORE_COMPLETE, null);
     407           
     408            jsonHeGlasses.add(heGlass.asJSONObject());
     409          }
     410        }
     411        json.put("name", name);
     412        json.put("heGlasses", jsonHeGlasses);
     413      }
     414      else if ("GetUncompletedHeGlass".equals(cmd))
     415      {
     416        dc = sc.newDbControl();
     417        JSONArray jsonHeGlasses = new JSONArray();
     418
     419        ItemQuery<BioPlate> query = BioPlate.getQuery();
     420        query.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
     421        BioplateType.HE_GLASS.addFilter(dc, query, false);
     422        query.join(Annotations.leftJoin(null, Annotationtype.SCORE_COMPLETE.load(dc), "sc"));
     423        query.restrict(Restrictions.eq(Hql.alias("sc"), Expressions.bool(false)));
     424        query.order(Orders.asc(Hql.property("name")));
     425         
     426        List<HeGlass> plates = HeGlass.toList(query.list(dc));
     427        for (HeGlass heGlass : plates)
     428        {
     429          heGlass.setAnnotation("numUncompleteSamples", heGlass.countUncompletedSamples(dc));
     430          jsonHeGlasses.add(heGlass.asJSONObject());
     431        }
     432       
     433        json.put("heGlasses", jsonHeGlasses);
     434      }
     435     
    346436    }
    347437    catch (Throwable t)
     
    680770        {
    681771          dc.saveItem(stainEvent);
     772        }
     773       
     774        dc.commit();
     775      }
     776      else if ("SaveHeScore".equals(cmd))
     777      {
     778        JSONObject jsonReq = (JSONObject)new JSONParser().parse(req.getReader());
     779        JSONArray jsonSamples = (JSONArray)jsonReq.get("samples");
     780        JSONArray jsonHeGlass = (JSONArray)jsonReq.get("heGlass");
     781        dc = sc.newDbControl();
     782
     783        // Update scores on samples
     784        for (int sampleNo = 0; sampleNo < jsonSamples.size(); ++sampleNo)
     785        {
     786          JSONObject jsonSample = (JSONObject)jsonSamples.get(sampleNo);
     787          Number sampleId = (Number)jsonSample.get("id");
     788          Boolean goodStain = (Boolean)jsonSample.get("GoodStain");
     789          Boolean scoreComplete = (Boolean)jsonSample.get("ScoreComplete");
     790         
     791          Sample he = Sample.getById(dc, sampleId.intValue());
     792         
     793          Annotationtype.GOOD_STAIN.setAnnotationValue(dc, he, goodStain);
     794          Annotationtype.SCORE_INVASIVE_CANCER.setAnnotationValue(dc, he, jsonSample.get("ScoreInvasiveCancer"));
     795          Annotationtype.SCORE_INSITU_CANCER.setAnnotationValue(dc, he, jsonSample.get("ScoreInsituCancer"));
     796          Annotationtype.SCORE_LYMPHOCYTES.setAnnotationValue(dc, he, jsonSample.get("ScoreLymphocytes"));
     797          Annotationtype.SCORE_NORMAL.setAnnotationValue(dc, he, jsonSample.get("ScoreNormal"));
     798          Annotationtype.SCORE_STROMA.setAnnotationValue(dc, he, jsonSample.get("ScoreStroma"));
     799          Annotationtype.SCORE_FAT.setAnnotationValue(dc, he, jsonSample.get("ScoreFat"));
     800          Annotationtype.SCORE_COMPLETE.setAnnotationValue(dc, he, scoreComplete);
     801          he.setDescription(Values.getStringOrNull((String)jsonSample.get("comments")));
     802         
     803          if (Boolean.TRUE.equals(scoreComplete))
     804          {
     805            jsonMessages.add("Scoring complete for sample: " + he.getName() + (Boolean.TRUE.equals(goodStain) ? " (GoodStain)" : ""));
     806          }
     807          else if (Boolean.FALSE.equals(scoreComplete))
     808          {
     809            jsonMessages.add("Score updated for sample: " + he.getName() + " (Not complete)");
     810          }
     811          else
     812          {
     813            jsonMessages.add("Scores removed from sample: " + he.getName());
     814          }
     815        }
     816       
     817        // ScoreComplete on HE glass
     818        for (int glassNo = 0; glassNo < jsonHeGlass.size(); ++glassNo)
     819        {
     820          JSONObject jsonGlass = (JSONObject)jsonHeGlass.get(glassNo);
     821          Number glassId = (Number)jsonGlass.get("id");
     822          Boolean scoreComplete = (Boolean)jsonGlass.get("ScoreComplete");
     823         
     824          BioPlate heGlass = BioPlate.getById(dc, glassId.intValue());
     825         
     826          Annotationtype.SCORE_COMPLETE.setAnnotationValue(dc, heGlass, scoreComplete);
     827         
     828          if (Boolean.TRUE.equals(scoreComplete))
     829          {
     830            jsonMessages.add("Scoring complete for HE glass: " + heGlass.getName());
     831          }
     832          else
     833          {
     834            jsonMessages.add("Score updated for HE glass: " + heGlass.getName() + " (Not complete)");
     835           
     836          }
    682837        }
    683838       
  • extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/servlet/InstallServlet.java

    r2116 r2134  
    230230
    231231        jsonChecks.add(checkAnnotationType(dc, Annotationtype.GOOD_STAIN, 1, null, effectiveOptions, createIfMissing));
     232        jsonChecks.add(checkAnnotationType(dc, Annotationtype.SCORE_COMPLETE, 1, null, effectiveOptions, createIfMissing));
     233        jsonChecks.add(checkAnnotationType(dc, Annotationtype.SCORE_INVASIVE_CANCER, 1, null, effectiveOptions, createIfMissing));
     234        jsonChecks.add(checkAnnotationType(dc, Annotationtype.SCORE_INSITU_CANCER, 1, null, effectiveOptions, createIfMissing));
     235        jsonChecks.add(checkAnnotationType(dc, Annotationtype.SCORE_LYMPHOCYTES, 1, null, effectiveOptions, createIfMissing));
     236        jsonChecks.add(checkAnnotationType(dc, Annotationtype.SCORE_NORMAL, 1, null, effectiveOptions, createIfMissing));
     237        jsonChecks.add(checkAnnotationType(dc, Annotationtype.SCORE_STROMA, 1, null, effectiveOptions, createIfMissing));
     238        jsonChecks.add(checkAnnotationType(dc, Annotationtype.SCORE_FAT, 1, null, effectiveOptions, createIfMissing));
    232239       
    233240        jsonChecks.add(checkAnnotationType(dc, Annotationtype.QIACUBE_DATE, 1, null, effectiveOptions, createIfMissing));
     
    330337       
    331338        jsonChecks.add(checkAnnotationTypeCategory(dc, Subtype.STAINED, createIfMissing,
    332             Annotationtype.GOOD_STAIN));
     339            Annotationtype.GOOD_STAIN, Annotationtype.SCORE_COMPLETE, Annotationtype.SCORE_INVASIVE_CANCER,
     340            Annotationtype.SCORE_INSITU_CANCER, Annotationtype.SCORE_LYMPHOCYTES, Annotationtype.SCORE_NORMAL,
     341            Annotationtype.SCORE_STROMA, Annotationtype.SCORE_FAT));
    333342       
    334343        jsonChecks.add(checkAnnotationTypeCategory(dc, Subtype.LYSATE, createIfMissing,
  • extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/servlet/SpecimenTubeServlet.java

    r2082 r2134  
    144144          while (free != null)
    145145          {
    146             jsonWells.add(JsonUtil.getBioWellAsJSON(free));
     146            jsonWells.add(JsonUtil.getBioWellAsJSON(free, true));
    147147            if (jsonWells.size() == nofTubes) break;
    148148            free = getNextFreeWell(free);
Note: See TracChangeset for help on using the changeset viewer.