extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/servlet/HistologyServlet.java

Code
Comments
Other
Rev Date Author Line
1589 20 Mar 12 nicklas 1 package net.sf.basedb.reggie.servlet;
1589 20 Mar 12 nicklas 2
5432 17 May 19 nicklas 3 import java.awt.image.BufferedImage;
1589 20 Mar 12 nicklas 4 import java.io.IOException;
3368 08 Jun 15 nicklas 5 import java.io.InputStream;
3368 08 Jun 15 nicklas 6 import java.io.OutputStream;
1589 20 Mar 12 nicklas 7 import java.util.Date;
2243 21 Feb 14 nicklas 8 import java.util.HashSet;
1589 20 Mar 12 nicklas 9 import java.util.List;
1591 21 Mar 12 nicklas 10 import java.util.Set;
1591 21 Mar 12 nicklas 11 import java.util.TreeSet;
1589 20 Mar 12 nicklas 12
5432 17 May 19 nicklas 13 import javax.imageio.IIOImage;
5432 17 May 19 nicklas 14 import javax.imageio.ImageIO;
5432 17 May 19 nicklas 15 import javax.imageio.ImageWriteParam;
5432 17 May 19 nicklas 16 import javax.imageio.ImageWriter;
5432 17 May 19 nicklas 17 import javax.imageio.stream.MemoryCacheImageOutputStream;
5432 17 May 19 nicklas 18
1589 20 Mar 12 nicklas 19 import javax.servlet.ServletException;
1589 20 Mar 12 nicklas 20 import javax.servlet.http.HttpServlet;
1589 20 Mar 12 nicklas 21 import javax.servlet.http.HttpServletRequest;
1589 20 Mar 12 nicklas 22 import javax.servlet.http.HttpServletResponse;
1589 20 Mar 12 nicklas 23
1589 20 Mar 12 nicklas 24 import org.json.simple.JSONArray;
1589 20 Mar 12 nicklas 25 import org.json.simple.JSONObject;
1589 20 Mar 12 nicklas 26
3121 06 Feb 15 nicklas 27 import net.sf.basedb.core.AnnotationType;
1684 04 Jun 12 nicklas 28 import net.sf.basedb.core.AnyToAny;
1589 20 Mar 12 nicklas 29 import net.sf.basedb.core.BioMaterialEvent;
3368 08 Jun 15 nicklas 30 import net.sf.basedb.core.Directory;
3368 08 Jun 15 nicklas 31 import net.sf.basedb.core.File;
3247 14 Apr 15 nicklas 32 import net.sf.basedb.core.ItemList;
1589 20 Mar 12 nicklas 33 import net.sf.basedb.core.BioPlate;
1589 20 Mar 12 nicklas 34 import net.sf.basedb.core.BioPlateEvent;
1589 20 Mar 12 nicklas 35 import net.sf.basedb.core.BioPlateEventParticipant;
1589 20 Mar 12 nicklas 36 import net.sf.basedb.core.BioPlateEventType;
1589 20 Mar 12 nicklas 37 import net.sf.basedb.core.BioPlateType;
1589 20 Mar 12 nicklas 38 import net.sf.basedb.core.BioWell;
1589 20 Mar 12 nicklas 39 import net.sf.basedb.core.DbControl;
1695 11 Jun 12 nicklas 40 import net.sf.basedb.core.Include;
1681 01 Jun 12 nicklas 41 import net.sf.basedb.core.Item;
3368 08 Jun 15 nicklas 42 import net.sf.basedb.core.ItemNotFoundException;
1589 20 Mar 12 nicklas 43 import net.sf.basedb.core.ItemQuery;
1589 20 Mar 12 nicklas 44 import net.sf.basedb.core.MeasuredBioMaterial;
3368 08 Jun 15 nicklas 45 import net.sf.basedb.core.Path;
1589 20 Mar 12 nicklas 46 import net.sf.basedb.core.PlateGeometry;
1684 04 Jun 12 nicklas 47 import net.sf.basedb.core.Protocol;
1591 21 Mar 12 nicklas 48 import net.sf.basedb.core.Sample;
1589 20 Mar 12 nicklas 49 import net.sf.basedb.core.SessionControl;
1589 20 Mar 12 nicklas 50 import net.sf.basedb.core.data.PlateCoordinate;
2134 11 Nov 13 nicklas 51 import net.sf.basedb.core.query.Annotations;
1668 25 May 12 nicklas 52 import net.sf.basedb.core.query.Expressions;
1589 20 Mar 12 nicklas 53 import net.sf.basedb.core.query.Hql;
1589 20 Mar 12 nicklas 54 import net.sf.basedb.core.query.Orders;
1668 25 May 12 nicklas 55 import net.sf.basedb.core.query.Restrictions;
2598 22 Aug 14 nicklas 56 import net.sf.basedb.reggie.JsonUtil;
1589 20 Mar 12 nicklas 57 import net.sf.basedb.reggie.Reggie;
5384 26 Apr 19 nicklas 58 import net.sf.basedb.reggie.activity.ActivityDef;
3059 19 Dec 14 nicklas 59 import net.sf.basedb.reggie.counter.CounterService;
1668 25 May 12 nicklas 60 import net.sf.basedb.reggie.dao.Annotationtype;
2242 21 Feb 14 nicklas 61 import net.sf.basedb.reggie.dao.BiomaterialList;
1589 20 Mar 12 nicklas 62 import net.sf.basedb.reggie.dao.BioplateType;
5791 16 Dec 19 nicklas 63 import net.sf.basedb.reggie.dao.DoNotUse;
2134 11 Nov 13 nicklas 64 import net.sf.basedb.reggie.dao.HeGlass;
1669 29 May 12 nicklas 65 import net.sf.basedb.reggie.dao.Histology;
1668 25 May 12 nicklas 66 import net.sf.basedb.reggie.dao.ReactionPlate;
2161 09 Dec 13 nicklas 67 import net.sf.basedb.reggie.dao.ReggieRole;
1589 20 Mar 12 nicklas 68 import net.sf.basedb.reggie.dao.Subtype;
3368 08 Jun 15 nicklas 69 import net.sf.basedb.util.FileUtil;
1591 21 Mar 12 nicklas 70 import net.sf.basedb.util.NameableComparator;
1589 20 Mar 12 nicklas 71 import net.sf.basedb.util.Values;
1589 20 Mar 12 nicklas 72 import net.sf.basedb.util.error.ThrowableUtil;
5371 16 Apr 19 nicklas 73 import net.sf.basedb.util.excel.XlsxTableWriter;
5371 16 Apr 19 nicklas 74 import net.sf.basedb.util.excel.XlsxToCsvUtil;
5309 15 Feb 19 nicklas 75 import net.sf.basedb.util.export.TableWriter;
1589 20 Mar 12 nicklas 76
1589 20 Mar 12 nicklas 77
1589 20 Mar 12 nicklas 78 public class HistologyServlet 
1589 20 Mar 12 nicklas 79   extends HttpServlet 
1589 20 Mar 12 nicklas 80 {
1589 20 Mar 12 nicklas 81
1589 20 Mar 12 nicklas 82
1589 20 Mar 12 nicklas 83   private static final long serialVersionUID = 5206470616942098596L;
1589 20 Mar 12 nicklas 84
1589 20 Mar 12 nicklas 85   public HistologyServlet()
1589 20 Mar 12 nicklas 86   {}
1589 20 Mar 12 nicklas 87
1589 20 Mar 12 nicklas 88   @Override
1589 20 Mar 12 nicklas 89   protected void doGet(HttpServletRequest req, HttpServletResponse resp)
1589 20 Mar 12 nicklas 90     throws ServletException, IOException 
1589 20 Mar 12 nicklas 91   {
1589 20 Mar 12 nicklas 92     String cmd = req.getParameter("cmd");
2598 22 Aug 14 nicklas 93     JsonUtil.setJsonResponseHeaders(resp);
1589 20 Mar 12 nicklas 94     
1589 20 Mar 12 nicklas 95     JSONObject json = new JSONObject();
1589 20 Mar 12 nicklas 96     json.put("status", "ok");
1589 20 Mar 12 nicklas 97   
3975 26 May 16 nicklas 98     final SessionControl sc = Reggie.getSessionControl(req);
1589 20 Mar 12 nicklas 99     DbControl dc = null;
1589 20 Mar 12 nicklas 100     try
1589 20 Mar 12 nicklas 101     {
3059 19 Dec 14 nicklas 102       if ("GetHistologyWorkLists".equals(cmd))
1681 01 Jun 12 nicklas 103       {
6332 15 Jun 21 nicklas 104         dc = sc.newDbControl(":Create Histology work list");
1681 01 Jun 12 nicklas 105         
3247 14 Apr 15 nicklas 106         ItemQuery<ItemList> query = ItemList.getQuery();
1681 01 Jun 12 nicklas 107         query.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
2371 23 Apr 14 nicklas 108         query.restrict(Restrictions.eq(Hql.property("externalId"), Expressions.string(Histology.WORK_LIST_ID)));
2371 23 Apr 14 nicklas 109         if (!Values.getBoolean(req.getParameter("all")))
2199 17 Jan 14 nicklas 110         {
2371 23 Apr 14 nicklas 111           query.join(Annotations.leftJoin(null, Annotationtype.EMBED_DATE.load(dc), "em"));
2371 23 Apr 14 nicklas 112           query.restrict(Restrictions.eq(Hql.alias("em"), null));
2199 17 Jan 14 nicklas 113         }
1681 01 Jun 12 nicklas 114         query.order(Orders.desc(Hql.property("id")));
1681 01 Jun 12 nicklas 115         
3247 14 Apr 15 nicklas 116         List<ItemList> result = query.list(dc);
1681 01 Jun 12 nicklas 117         JSONArray jsonLists = new JSONArray();
3247 14 Apr 15 nicklas 118         for (ItemList list: result)
1681 01 Jun 12 nicklas 119         {
1681 01 Jun 12 nicklas 120           JSONObject jsonList = new JSONObject();
1681 01 Jun 12 nicklas 121           
1681 01 Jun 12 nicklas 122           jsonList.put("id", list.getId());
1681 01 Jun 12 nicklas 123           jsonList.put("name", list.getName());
1681 01 Jun 12 nicklas 124           jsonList.put("size", list.getSize());
2199 17 Jan 14 nicklas 125           int totalBlocks = 1 + (list.getSize()-1) / Histology.SAMPLES_PER_BLOCK;
2199 17 Jan 14 nicklas 126           jsonList.put("blocks", totalBlocks);
1681 01 Jun 12 nicklas 127           
1681 01 Jun 12 nicklas 128           jsonLists.add(jsonList);
1681 01 Jun 12 nicklas 129         }
1681 01 Jun 12 nicklas 130         json.put("workLists", jsonLists);
1681 01 Jun 12 nicklas 131       }
1681 01 Jun 12 nicklas 132       
1983 21 May 13 nicklas 133       else if ("GetUnembeddedHistologyItems".equals(cmd))
1589 20 Mar 12 nicklas 134       {
1589 20 Mar 12 nicklas 135         /*
1669 29 May 12 nicklas 136           Find Histology items that are not embedded on
1684 04 Jun 12 nicklas 137           paraffin blocks and not part of any work list.
1589 20 Mar 12 nicklas 138         */
6332 15 Jun 21 nicklas 139         dc = sc.newDbControl(":Create Histology work list");
1681 01 Jun 12 nicklas 140         List<Histology> histology = Histology.findUnembeddedHistologyItems(dc, true, 100);
1589 20 Mar 12 nicklas 141         
1669 29 May 12 nicklas 142         JSONArray jsonHistology = new JSONArray();
1669 29 May 12 nicklas 143         for (Histology h : histology)
1589 20 Mar 12 nicklas 144         {
1669 29 May 12 nicklas 145           h.loadBioPlateLocation();
1669 29 May 12 nicklas 146           jsonHistology.add(h.asJSONObject());
1589 20 Mar 12 nicklas 147         }
1669 29 May 12 nicklas 148         
1669 29 May 12 nicklas 149         json.put("histology", jsonHistology);
1589 20 Mar 12 nicklas 150       }
1692 08 Jun 12 nicklas 151       
1692 08 Jun 12 nicklas 152       else if ("GetHistologyWorkListInfo".equals(cmd))
1692 08 Jun 12 nicklas 153       {
1692 08 Jun 12 nicklas 154         /*
1692 08 Jun 12 nicklas 155           Get information about a histology work list and paraffin blocks it is associated with.
1692 08 Jun 12 nicklas 156         */
6332 15 Jun 21 nicklas 157         dc = sc.newDbControl(":Histology wizards");
1692 08 Jun 12 nicklas 158         int workListId = Values.getInt(req.getParameter("workListId"));
3247 14 Apr 15 nicklas 159         ItemList workList = ItemList.getById(dc, workListId);
1692 08 Jun 12 nicklas 160         
1692 08 Jun 12 nicklas 161         JSONObject jsonList = new JSONObject();
1692 08 Jun 12 nicklas 162         jsonList.put("id", workList.getId());
1692 08 Jun 12 nicklas 163         jsonList.put("name", workList.getName());
1692 08 Jun 12 nicklas 164         jsonList.put("size", workList.getSize());
1692 08 Jun 12 nicklas 165         
1692 08 Jun 12 nicklas 166         JSONArray jsonBlocks = new JSONArray();
1692 08 Jun 12 nicklas 167         int totalBlocks = 1 + (workList.getSize()-1) / Histology.SAMPLES_PER_BLOCK;
1692 08 Jun 12 nicklas 168         for (int blockNo = 1; blockNo <= totalBlocks; blockNo++)
1692 08 Jun 12 nicklas 169         {
1692 08 Jun 12 nicklas 170           AnyToAny link = AnyToAny.getByName(dc, workList, "block." + blockNo);
1692 08 Jun 12 nicklas 171           ReactionPlate plate = ReactionPlate.getById(dc, link.getToId(), BioplateType.PARAFFIN_BLOCK);
1692 08 Jun 12 nicklas 172           jsonBlocks.add(plate.asJSONObject());
1692 08 Jun 12 nicklas 173         }
1692 08 Jun 12 nicklas 174         jsonList.put("blocks", jsonBlocks);
1692 08 Jun 12 nicklas 175         json.put("workList", jsonList);
1692 08 Jun 12 nicklas 176       }
1591 21 Mar 12 nicklas 177       else if ("GetParaffinBlocks".equals(cmd))
1591 21 Mar 12 nicklas 178       {
1591 21 Mar 12 nicklas 179         /*
1591 21 Mar 12 nicklas 180           Find all paraffin blocks that has no child HEglass plates.
1591 21 Mar 12 nicklas 181           
1591 21 Mar 12 nicklas 182           The best way to do that is to find all 'Histology' samples located on 
1591 21 Mar 12 nicklas 183           a paraffin block that has no 'Stained' child item.
1591 21 Mar 12 nicklas 184         */
6332 15 Jun 21 nicklas 185         dc = sc.newDbControl(":Register HE glass");
1591 21 Mar 12 nicklas 186         ItemQuery<Sample> query = Sample.getQuery();
1591 21 Mar 12 nicklas 187         query.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
1591 21 Mar 12 nicklas 188         Subtype.HISTOLOGY.addFilter(dc, query);
1591 21 Mar 12 nicklas 189         query.join(Hql.innerJoin(null, "bioWell", "well", true));
1591 21 Mar 12 nicklas 190         query.join(Hql.innerJoin("well", "bioPlate", "bp", true));
1591 21 Mar 12 nicklas 191         BioplateType.PARAFFIN_BLOCK.addFilter(dc, query, "bp", true);
1591 21 Mar 12 nicklas 192         
1668 25 May 12 nicklas 193         // Create a query that load all Histology samples that has at least one Stained child sample
1668 25 May 12 nicklas 194         ItemQuery<Sample> subquery = Sample.getQuery();
1668 25 May 12 nicklas 195         subquery.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
1668 25 May 12 nicklas 196         // Filter on RNA subtype
1668 25 May 12 nicklas 197         Subtype.HISTOLOGY.addFilter(dc, subquery);
1668 25 May 12 nicklas 198         // Join child items and filter on STAINED subtype
1668 25 May 12 nicklas 199         subquery.join(Hql.innerJoin("childCreationEvents", "cce"));
1668 25 May 12 nicklas 200         subquery.join(Hql.innerJoin("cce", "event", "evt", null, false));
1668 25 May 12 nicklas 201         subquery.join(Hql.innerJoin("evt", "bioMaterial", "bm", null, false));
1668 25 May 12 nicklas 202         Subtype.STAINED.addFilter(dc, subquery, "bm");
1591 21 Mar 12 nicklas 203         
1668 25 May 12 nicklas 204         // Filter on id not equal to any that has a STAINED child
1668 25 May 12 nicklas 205         query.restrict(Restrictions.neq(Hql.property("id"), Expressions.all(subquery)));
2244 21 Feb 14 nicklas 206                 
1591 21 Mar 12 nicklas 207         List<Sample> samples = query.list(dc);
1591 21 Mar 12 nicklas 208         Set<BioPlate> plates = new TreeSet<BioPlate>(new NameableComparator<BioPlate>(false));
1591 21 Mar 12 nicklas 209         for (Sample s : samples)
1591 21 Mar 12 nicklas 210         {
1591 21 Mar 12 nicklas 211           plates.add(s.getBioWell().getPlate());
1591 21 Mar 12 nicklas 212         }
1591 21 Mar 12 nicklas 213         
1591 21 Mar 12 nicklas 214         JSONArray jsonPlates = new JSONArray();
1591 21 Mar 12 nicklas 215         for (BioPlate plate : plates)
1591 21 Mar 12 nicklas 216         {
1591 21 Mar 12 nicklas 217           JSONObject jsonPlate = new JSONObject();
1591 21 Mar 12 nicklas 218           jsonPlate.put("id", plate.getId());
1591 21 Mar 12 nicklas 219           jsonPlate.put("name", plate.getName());
1591 21 Mar 12 nicklas 220           jsonPlates.add(jsonPlate);
1591 21 Mar 12 nicklas 221         }
1591 21 Mar 12 nicklas 222         json.put("plates", jsonPlates);
1668 25 May 12 nicklas 223       }
1668 25 May 12 nicklas 224       else if ("GetParaffinBlockInfo".equals(cmd))
1668 25 May 12 nicklas 225       {
1668 25 May 12 nicklas 226         /*
1668 25 May 12 nicklas 227           Get information about the histology items on a paraffin block.
1668 25 May 12 nicklas 228         */
1668 25 May 12 nicklas 229         int bioPlateId = Values.getInt(req.getParameter("bioPlateId"));
1668 25 May 12 nicklas 230
6332 15 Jun 21 nicklas 231         dc = sc.newDbControl(":Register HE glass");
1668 25 May 12 nicklas 232         ReactionPlate paraffinBlock = ReactionPlate.getById(dc, bioPlateId, BioplateType.PARAFFIN_BLOCK);
1668 25 May 12 nicklas 233         paraffinBlock.loadBioWells(dc, true);
1777 12 Dec 12 nicklas 234         paraffinBlock.setAnnotation("comment", paraffinBlock.getBioPlate().getDescription());
1591 21 Mar 12 nicklas 235         
1668 25 May 12 nicklas 236         // Load child HEglass plates
1668 25 May 12 nicklas 237         List<ReactionPlate> heGlassPlates = paraffinBlock.findChildPlates(dc, BioplateType.HE_GLASS);
1774 11 Dec 12 nicklas 238                 
1668 25 May 12 nicklas 239         if (heGlassPlates.size() > 0)
1668 25 May 12 nicklas 240         {
1668 25 May 12 nicklas 241           JSONArray jsonHeGlass = new JSONArray();
1668 25 May 12 nicklas 242           for (ReactionPlate heGlass : heGlassPlates)
1668 25 May 12 nicklas 243           {
1777 12 Dec 12 nicklas 244             BioPlate hePlate = heGlass.getBioPlate();
1668 25 May 12 nicklas 245             heGlass.loadBioWells(dc, true);
1668 25 May 12 nicklas 246             heGlass.loadBioMaterialAnnotations(dc, "GoodStain", Annotationtype.GOOD_STAIN, null);
1777 12 Dec 12 nicklas 247             heGlass.setAnnotation("comment", hePlate.getDescription());
3121 06 Feb 15 nicklas 248             heGlass.loadAnnotations(dc, "IHC", Annotationtype.IHC, null);
1694 08 Jun 12 nicklas 249             
1774 11 Dec 12 nicklas 250             if (hePlate.getTray() != null && hePlate.getPosition() != null)
1694 08 Jun 12 nicklas 251             {
1774 11 Dec 12 nicklas 252               heGlass.setAnnotation("storageBox", hePlate.getTray());
1774 11 Dec 12 nicklas 253               heGlass.setAnnotation("position", hePlate.getPosition());
1694 08 Jun 12 nicklas 254             }
1694 08 Jun 12 nicklas 255             
1668 25 May 12 nicklas 256             jsonHeGlass.add(heGlass.asJSONObject());
1668 25 May 12 nicklas 257           }
1668 25 May 12 nicklas 258           paraffinBlock.setAnnotation("heGlass", jsonHeGlass);
1668 25 May 12 nicklas 259         }
1668 25 May 12 nicklas 260         
1668 25 May 12 nicklas 261         json.put("paraffinBlock", paraffinBlock.asJSONObject());
1591 21 Mar 12 nicklas 262       }
1695 11 Jun 12 nicklas 263       
1695 11 Jun 12 nicklas 264       else if ("FindLastUsedHeGlassPosition".equals(cmd))
1695 11 Jun 12 nicklas 265       {
6332 15 Jun 21 nicklas 266         dc = sc.newDbControl(":Register HE glass");
1695 11 Jun 12 nicklas 267         
1695 11 Jun 12 nicklas 268         ItemQuery<BioPlate> query = BioPlate.getQuery();
1695 11 Jun 12 nicklas 269         query.include(Reggie.INCLUDE_IN_CURRENT_PROJECT);
1695 11 Jun 12 nicklas 270         BioplateType.HE_GLASS.addFilter(dc, query, true);
1695 11 Jun 12 nicklas 271         query.order(Orders.desc(Hql.property("id")));
1695 11 Jun 12 nicklas 272         query.setMaxResults(1);
1695 11 Jun 12 nicklas 273         
1695 11 Jun 12 nicklas 274         List<BioPlate> result = query.list(dc);
1695 11 Jun 12 nicklas 275         if (result.size() == 1)
1695 11 Jun 12 nicklas 276         {
1695 11 Jun 12 nicklas 277           BioPlate heGlass = result.get(0);
1774 11 Dec 12 nicklas 278           if (heGlass.getTray() != null && heGlass.getPosition() != null)
1695 11 Jun 12 nicklas 279           {
1774 11 Dec 12 nicklas 280             json.put("storageBox", Values.getInt(heGlass.getTray()));
1774 11 Dec 12 nicklas 281             json.put("position", Values.getInt(heGlass.getPosition()));
1695 11 Jun 12 nicklas 282           }
1695 11 Jun 12 nicklas 283         }
3121 06 Feb 15 nicklas 284         
3121 06 Feb 15 nicklas 285         AnnotationType ihc = Annotationtype.IHC.get(dc);
3121 06 Feb 15 nicklas 286         JSONArray jsonIhc = new JSONArray();
3121 06 Feb 15 nicklas 287         jsonIhc.addAll(ihc.getValues());
3121 06 Feb 15 nicklas 288         json.put("ihc", jsonIhc);
1695 11 Jun 12 nicklas 289       }
1691 07 Jun 12 nicklas 290       else if ("DownloadHEGlassLabels".equals(cmd))
1691 07 Jun 12 nicklas 291       {
1691 07 Jun 12 nicklas 292         json = null; // No JSON output
1691 07 Jun 12 nicklas 293         
1691 07 Jun 12 nicklas 294         int workListId = Values.getInt(req.getParameter("workListId"));
1691 07 Jun 12 nicklas 295         int numSlidesPerBlock = Values.getInt(req.getParameter("numSlides"), 5);
5309 15 Feb 19 nicklas 296         String format = Values.getString(req.getParameter("format"), "csv");
5309 15 Feb 19 nicklas 297         
5309 15 Feb 19 nicklas 298         String baseFilename = "he-glass-labels-" + Reggie.CONVERTER_DATE_TO_STRING_WITH_SEPARATOR.convert(new Date());
1691 07 Jun 12 nicklas 299
6332 15 Jun 21 nicklas 300         dc = sc.newDbControl(":Download HE glass labels");
1691 07 Jun 12 nicklas 301         
3247 14 Apr 15 nicklas 302         ItemList workList = ItemList.getById(dc, workListId);
1692 08 Jun 12 nicklas 303         int totalBlocks = 1 + (workList.getSize()-1) / Histology.SAMPLES_PER_BLOCK;
1691 07 Jun 12 nicklas 304         
5309 15 Feb 19 nicklas 305         TableWriter tw = null;
5309 15 Feb 19 nicklas 306         XlsxTableWriter xls = null;
5309 15 Feb 19 nicklas 307         if ("xlsx".equals(format))
5309 15 Feb 19 nicklas 308         {
5309 15 Feb 19 nicklas 309           resp.setHeader("Content-Disposition", "attachment; filename="+baseFilename+".xlsx");
5371 16 Apr 19 nicklas 310           resp.setContentType(XlsxToCsvUtil.XLSX_MIME_TYPE);
5309 15 Feb 19 nicklas 311           xls = new XlsxTableWriter("HeGlassLabels");
5309 15 Feb 19 nicklas 312           tw = xls;
5309 15 Feb 19 nicklas 313         }
5309 15 Feb 19 nicklas 314         else
5309 15 Feb 19 nicklas 315         {
5309 15 Feb 19 nicklas 316           resp.setHeader("Content-Disposition", "attachment; filename="+baseFilename+".csv");
5309 15 Feb 19 nicklas 317           resp.setContentType("text/plain");
5309 15 Feb 19 nicklas 318           resp.setCharacterEncoding("UTF-8");
5309 15 Feb 19 nicklas 319           tw = new TableWriter(resp.getWriter());
5309 15 Feb 19 nicklas 320           // The LABEL header is only required in the CSV format
5309 15 Feb 19 nicklas 321           tw.tablePrintData("LABEL");
5309 15 Feb 19 nicklas 322         }
1691 07 Jun 12 nicklas 323         
1691 07 Jun 12 nicklas 324         for (int blockNo = 1; blockNo <= totalBlocks; blockNo++)
1691 07 Jun 12 nicklas 325         {
1691 07 Jun 12 nicklas 326           AnyToAny link = AnyToAny.getByName(dc, workList, "block." + blockNo);
5309 15 Feb 19 nicklas 327           BioPlate block = (BioPlate)link.getTo();          
1691 07 Jun 12 nicklas 328           String heGlassPrefix = block.getName().replace("PB", "HE");
1691 07 Jun 12 nicklas 329           for (int slideNo = 1; slideNo <= numSlidesPerBlock; slideNo++)
1691 07 Jun 12 nicklas 330           {
5309 15 Feb 19 nicklas 331             tw.tablePrintData(heGlassPrefix + "." + slideNo);
1691 07 Jun 12 nicklas 332           }
1691 07 Jun 12 nicklas 333         }
1691 07 Jun 12 nicklas 334         
5309 15 Feb 19 nicklas 335         if (xls != null) 
5309 15 Feb 19 nicklas 336         {
5309 15 Feb 19 nicklas 337           xls.getSheet().setColumnWidth(0, 18*256);
5309 15 Feb 19 nicklas 338           xls.saveTo(resp.getOutputStream());
5309 15 Feb 19 nicklas 339           xls.close();
5309 15 Feb 19 nicklas 340         }
5309 15 Feb 19 nicklas 341
5309 15 Feb 19 nicklas 342         tw.flush();
1691 07 Jun 12 nicklas 343       }
2134 11 Nov 13 nicklas 344       else if ("GetHeGlassToScore".equals(cmd))
2134 11 Nov 13 nicklas 345       {
6332 15 Jun 21 nicklas 346         dc = sc.newDbControl(":Score HE glass");
2134 11 Nov 13 nicklas 347         
2134 11 Nov 13 nicklas 348         String name = Values.getStringOrNull(req.getParameter("name"));
2134 11 Nov 13 nicklas 349         
2134 11 Nov 13 nicklas 350         JSONArray jsonHeGlasses = new JSONArray();
2134 11 Nov 13 nicklas 351         if (name == null)
2134 11 Nov 13 nicklas 352         {
2134 11 Nov 13 nicklas 353           // No name specified...
2134 11 Nov 13 nicklas 354           // ... find the name of first unscored glass that is not destroyed
2134 11 Nov 13 nicklas 355           ItemQuery<BioPlate> tmpQuery = BioPlate.getQuery();
2134 11 Nov 13 nicklas 356           tmpQuery.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
2134 11 Nov 13 nicklas 357           BioplateType.HE_GLASS.addFilter(dc, tmpQuery, true);
2134 11 Nov 13 nicklas 358           tmpQuery.join(Annotations.leftJoin(null, Annotationtype.SCORE_COMPLETE.load(dc), "sc"));
2134 11 Nov 13 nicklas 359           tmpQuery.restrict(Restrictions.eq(Hql.alias("sc"), null));
2134 11 Nov 13 nicklas 360           tmpQuery.order(Orders.asc(Hql.property("name")));
2134 11 Nov 13 nicklas 361           tmpQuery.setMaxResults(1);
2134 11 Nov 13 nicklas 362           List<BioPlate> result = tmpQuery.list(dc);
2134 11 Nov 13 nicklas 363           if (result.size() > 0)
2134 11 Nov 13 nicklas 364           {
2134 11 Nov 13 nicklas 365             name = result.get(0).getName();
2134 11 Nov 13 nicklas 366           }
2134 11 Nov 13 nicklas 367         }
2134 11 Nov 13 nicklas 368         
2134 11 Nov 13 nicklas 369         if (name != null)
2134 11 Nov 13 nicklas 370         {
2134 11 Nov 13 nicklas 371           // Now, find all HE glass that are related to the original
2134 11 Nov 13 nicklas 372           int dotIndex = name.indexOf('.');
2134 11 Nov 13 nicklas 373           String prefix = dotIndex > 0 ? name.substring(0, dotIndex) : name;
2134 11 Nov 13 nicklas 374           ItemQuery<BioPlate> query = BioPlate.getQuery();
2134 11 Nov 13 nicklas 375           query.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
2134 11 Nov 13 nicklas 376           BioplateType.HE_GLASS.addFilter(dc, query, false);
2134 11 Nov 13 nicklas 377           query.restrict(Restrictions.rlike(Hql.property("name"), Expressions.string("^" + prefix + "\\.[0-9]+$")));
2134 11 Nov 13 nicklas 378           query.order(Orders.asc(Hql.property("name")));
2134 11 Nov 13 nicklas 379           
2134 11 Nov 13 nicklas 380           List<HeGlass> plates = HeGlass.toList(query.list(dc));
2134 11 Nov 13 nicklas 381           for (HeGlass heGlass : plates)
2134 11 Nov 13 nicklas 382           {
2134 11 Nov 13 nicklas 383             heGlass.loadSampleScores(dc);
2134 11 Nov 13 nicklas 384             heGlass.loadAnnotations(dc, "ScoreComplete", Annotationtype.SCORE_COMPLETE, null);
3125 09 Feb 15 nicklas 385             heGlass.loadAnnotations(dc, "IHC", Annotationtype.IHC, null);
6017 09 Oct 20 nicklas 386             heGlass.setAnnotation("ndpiImage", JsonUtil.loadLinkedItem(dc, heGlass.getItem(), "NDPI Image", Item.FILE, null));
2134 11 Nov 13 nicklas 387             jsonHeGlasses.add(heGlass.asJSONObject());
2134 11 Nov 13 nicklas 388           }
2134 11 Nov 13 nicklas 389         }
2134 11 Nov 13 nicklas 390         json.put("name", name);
2134 11 Nov 13 nicklas 391         json.put("heGlasses", jsonHeGlasses);
2134 11 Nov 13 nicklas 392       }
2134 11 Nov 13 nicklas 393       else if ("GetUncompletedHeGlass".equals(cmd))
2134 11 Nov 13 nicklas 394       {
6332 15 Jun 21 nicklas 395         dc = sc.newDbControl(":Score HE glass");
2134 11 Nov 13 nicklas 396         JSONArray jsonHeGlasses = new JSONArray();
2134 11 Nov 13 nicklas 397
2134 11 Nov 13 nicklas 398         ItemQuery<BioPlate> query = BioPlate.getQuery();
2134 11 Nov 13 nicklas 399         query.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
2134 11 Nov 13 nicklas 400         BioplateType.HE_GLASS.addFilter(dc, query, false);
2134 11 Nov 13 nicklas 401         query.join(Annotations.leftJoin(null, Annotationtype.SCORE_COMPLETE.load(dc), "sc"));
2134 11 Nov 13 nicklas 402         query.restrict(Restrictions.eq(Hql.alias("sc"), Expressions.bool(false)));
2134 11 Nov 13 nicklas 403         query.order(Orders.asc(Hql.property("name")));
2134 11 Nov 13 nicklas 404           
2134 11 Nov 13 nicklas 405         List<HeGlass> plates = HeGlass.toList(query.list(dc));
2134 11 Nov 13 nicklas 406         for (HeGlass heGlass : plates)
2134 11 Nov 13 nicklas 407         {
2134 11 Nov 13 nicklas 408           heGlass.setAnnotation("numUncompleteSamples", heGlass.countUncompletedSamples(dc));
2134 11 Nov 13 nicklas 409           jsonHeGlasses.add(heGlass.asJSONObject());
2134 11 Nov 13 nicklas 410         }
2134 11 Nov 13 nicklas 411         
2134 11 Nov 13 nicklas 412         json.put("heGlasses", jsonHeGlasses);
2134 11 Nov 13 nicklas 413       }
2134 11 Nov 13 nicklas 414       
1589 20 Mar 12 nicklas 415     }
1589 20 Mar 12 nicklas 416     catch (Throwable t)
1589 20 Mar 12 nicklas 417     {
1589 20 Mar 12 nicklas 418       t.printStackTrace();
1691 07 Jun 12 nicklas 419       if (json != null)
1691 07 Jun 12 nicklas 420       {
1691 07 Jun 12 nicklas 421         json.clear();
1691 07 Jun 12 nicklas 422         json.put("status", "error");
1691 07 Jun 12 nicklas 423         json.put("message", t.getMessage());
1691 07 Jun 12 nicklas 424         json.put("stacktrace", ThrowableUtil.stackTraceToString(t));
1691 07 Jun 12 nicklas 425       }
1691 07 Jun 12 nicklas 426       else
1691 07 Jun 12 nicklas 427       {
1691 07 Jun 12 nicklas 428         resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, t.getMessage());
1691 07 Jun 12 nicklas 429       }
1589 20 Mar 12 nicklas 430     }
1589 20 Mar 12 nicklas 431     finally
1589 20 Mar 12 nicklas 432     {
1589 20 Mar 12 nicklas 433       if (dc != null) dc.close();
1691 07 Jun 12 nicklas 434       if (json != null)
1691 07 Jun 12 nicklas 435       {
1691 07 Jun 12 nicklas 436         json.writeJSONString(resp.getWriter());
1691 07 Jun 12 nicklas 437       }
1589 20 Mar 12 nicklas 438     }
1589 20 Mar 12 nicklas 439   }
1589 20 Mar 12 nicklas 440
1589 20 Mar 12 nicklas 441   @SuppressWarnings("unchecked")
1589 20 Mar 12 nicklas 442   @Override
1589 20 Mar 12 nicklas 443   protected void doPost(HttpServletRequest req, HttpServletResponse resp)
1589 20 Mar 12 nicklas 444     throws ServletException, IOException 
1589 20 Mar 12 nicklas 445   {
1589 20 Mar 12 nicklas 446     String cmd = req.getParameter("cmd");
2598 22 Aug 14 nicklas 447     JsonUtil.setJsonResponseHeaders(resp);
1589 20 Mar 12 nicklas 448     
1589 20 Mar 12 nicklas 449     JSONObject json = new JSONObject();
1589 20 Mar 12 nicklas 450     json.put("status", "ok");
1589 20 Mar 12 nicklas 451     
1589 20 Mar 12 nicklas 452     JSONArray jsonMessages = new JSONArray();
1589 20 Mar 12 nicklas 453   
3975 26 May 16 nicklas 454     final SessionControl sc = Reggie.getSessionControl(req);
1589 20 Mar 12 nicklas 455     DbControl dc = null;
1589 20 Mar 12 nicklas 456     try
1589 20 Mar 12 nicklas 457     {
1681 01 Jun 12 nicklas 458       if ("CreateWorkList".equals(cmd))
1589 20 Mar 12 nicklas 459       {
6332 15 Jun 21 nicklas 460         dc = sc.newDbControl(":Create Histology work list");
2161 09 Dec 13 nicklas 461
2161 09 Dec 13 nicklas 462         ReggieRole.checkPermission(dc, "'" + cmd + "' wizard", ReggieRole.HISTOLOGY, ReggieRole.ADMINISTRATOR);
2161 09 Dec 13 nicklas 463
3752 17 Feb 16 nicklas 464         JSONObject jsonReq = JsonUtil.parseRequest(req);
1681 01 Jun 12 nicklas 465         JSONArray jsonHistology = (JSONArray)jsonReq.get("histology");
2161 09 Dec 13 nicklas 466                 
3247 14 Apr 15 nicklas 467         ItemList workList = ItemList.getNew(dc, Item.SAMPLE);
2190 13 Jan 14 nicklas 468         workList.setExternalId(Histology.WORK_LIST_ID);
1681 01 Jun 12 nicklas 469         workList.setName((String)jsonReq.get("name"));
2172 11 Dec 13 nicklas 470         workList.setDescription((String)jsonReq.get("comments"));
1681 01 Jun 12 nicklas 471         dc.saveItem(workList);
1684 04 Jun 12 nicklas 472         jsonMessages.add("Created '" + workList.getName() + "' with " + jsonHistology.size() + " samples");
1684 04 Jun 12 nicklas 473
1684 04 Jun 12 nicklas 474         int blockNo = 0;
1684 04 Jun 12 nicklas 475         PlateGeometry geometry = BioplateType.PARAFFIN_BLOCK.getPlateGeometry(dc);
1684 04 Jun 12 nicklas 476         BioPlateType paraffinBlockType = BioplateType.PARAFFIN_BLOCK.load(dc);
1681 01 Jun 12 nicklas 477         
1681 01 Jun 12 nicklas 478         for (int i = 0; i < jsonHistology.size(); ++i)
1681 01 Jun 12 nicklas 479         {
1692 08 Jun 12 nicklas 480           if (i % Histology.SAMPLES_PER_BLOCK == 0)
1684 04 Jun 12 nicklas 481           {
1684 04 Jun 12 nicklas 482             // Create a new Paraffin block and associate it with the list
1684 04 Jun 12 nicklas 483             blockNo++;
1684 04 Jun 12 nicklas 484             BioPlate paraffinBlock = BioPlate.getNew(dc, geometry, paraffinBlockType);
4892 09 Jul 18 nicklas 485             paraffinBlock.setName(BioplateType.PARAFFIN_BLOCK.getNextPlateName(dc, true));
1684 04 Jun 12 nicklas 486             dc.saveItem(paraffinBlock);
1684 04 Jun 12 nicklas 487             
1684 04 Jun 12 nicklas 488             AnyToAny listBlock = AnyToAny.getNew(dc, workList, paraffinBlock, "block."+blockNo, true);
1684 04 Jun 12 nicklas 489             dc.saveItem(listBlock);
1684 04 Jun 12 nicklas 490
1684 04 Jun 12 nicklas 491             jsonMessages.add("Created '" + paraffinBlock.getName() + "' (empty)");
1684 04 Jun 12 nicklas 492           }
1684 04 Jun 12 nicklas 493           
1681 01 Jun 12 nicklas 494           Number hisId = (Number)jsonHistology.get(i);
1681 01 Jun 12 nicklas 495           workList.add(Sample.getById(dc, hisId.intValue()));
1681 01 Jun 12 nicklas 496         }
1681 01 Jun 12 nicklas 497         
1681 01 Jun 12 nicklas 498         dc.commit();
1681 01 Jun 12 nicklas 499         
1681 01 Jun 12 nicklas 500         JSONObject jsonList = new JSONObject();
1681 01 Jun 12 nicklas 501         jsonList.put("id", workList.getId());
1681 01 Jun 12 nicklas 502         jsonList.put("name", workList.getName());
1681 01 Jun 12 nicklas 503         jsonList.put("size", workList.getSize());
1681 01 Jun 12 nicklas 504         json.put("workList", jsonList);
1681 01 Jun 12 nicklas 505       }
1681 01 Jun 12 nicklas 506       else if ("MoveHistologySamplesToParaffinBlocks".equals(cmd))
1681 01 Jun 12 nicklas 507       {
6332 15 Jun 21 nicklas 508         dc = sc.newDbControl(":Register paraffin blocks");
2161 09 Dec 13 nicklas 509
2161 09 Dec 13 nicklas 510         ReggieRole.checkPermission(dc, "'" + cmd + "' wizard", ReggieRole.HISTOLOGY, ReggieRole.ADMINISTRATOR);
2161 09 Dec 13 nicklas 511
3752 17 Feb 16 nicklas 512         JSONObject jsonReq = JsonUtil.parseRequest(req);
1692 08 Jun 12 nicklas 513         JSONArray jsonBlocks = (JSONArray)jsonReq.get("blocks");
1692 08 Jun 12 nicklas 514         Number workListId = (Number)jsonReq.get("id");
1589 20 Mar 12 nicklas 515         
2344 09 Apr 14 nicklas 516         Date embedDate = Reggie.CONVERTER_STRING_TO_DATE.convert((String)jsonReq.get("embedDate"));
1692 08 Jun 12 nicklas 517         Number protocolId = (Number)jsonReq.get("protocolId");
1774 11 Dec 12 nicklas 518         String storageBox = null;
1692 08 Jun 12 nicklas 519         
3247 14 Apr 15 nicklas 520         ItemList workList = ItemList.getById(dc, workListId.intValue());
2371 23 Apr 14 nicklas 521         Annotationtype.EMBED_DATE.setAnnotationValue(dc, workList, embedDate);
1692 08 Jun 12 nicklas 522         Protocol protocol = protocolId != null ? Protocol.getById(dc, protocolId.intValue()) : null;
1589 20 Mar 12 nicklas 523         
1683 01 Jun 12 nicklas 524         BioPlateEvent placeEvent = BioPlateEvent.getNew(dc, BioPlateEventType.getById(dc, BioPlateEventType.PLACE_ON_PLATE));
2344 09 Apr 14 nicklas 525         placeEvent.setEventDate(embedDate);
2344 09 Apr 14 nicklas 526         placeEvent.setName("Embed Histology items on paraffin blocks");
1684 04 Jun 12 nicklas 527         placeEvent.setProtocol(protocol);
1683 01 Jun 12 nicklas 528         dc.saveItem(placeEvent);
1683 01 Jun 12 nicklas 529
6183 26 Mar 21 nicklas 530         ItemQuery<Sample> query = workList.getMembers();
1695 11 Jun 12 nicklas 531         query.include(Include.ALL);
1683 01 Jun 12 nicklas 532         // Join the creation event and bioplate
1683 01 Jun 12 nicklas 533         query.join(Hql.innerJoin(null, "creationEvent", "ce", true));
1683 01 Jun 12 nicklas 534         query.join(Hql.leftJoin(null, "bioWell", "bw", null, true));
1683 01 Jun 12 nicklas 535         query.join(Hql.leftJoin("bw", "bioPlate", "bp", null, true));
1589 20 Mar 12 nicklas 536         
1683 01 Jun 12 nicklas 537         // Sort by bioplate position -- those without plate are sorted last by id
1683 01 Jun 12 nicklas 538         query.order(Orders.asc(Hql.expression("coalesce(bp.name, 'zzzz')", null)));
1683 01 Jun 12 nicklas 539         query.order(Orders.asc(Hql.property("bw", "row")));
1683 01 Jun 12 nicklas 540         query.order(Orders.asc(Hql.property("bw", "column")));
1683 01 Jun 12 nicklas 541         query.order(Orders.asc(Hql.property("id")));
1683 01 Jun 12 nicklas 542         
1589 20 Mar 12 nicklas 543         // Store the biomaterial on the plate in a temporary list
1683 01 Jun 12 nicklas 544         List<Sample> allBioMaterial = query.list(dc);
1589 20 Mar 12 nicklas 545
1589 20 Mar 12 nicklas 546         PlateCoordinate[] moveTo = new PlateCoordinate[] 
1683 01 Jun 12 nicklas 547             {
1683 01 Jun 12 nicklas 548               new PlateCoordinate(2, 0), new PlateCoordinate(1, 0), new PlateCoordinate(0, 0), 
1683 01 Jun 12 nicklas 549               new PlateCoordinate(2, 1), new PlateCoordinate(1, 1)
1683 01 Jun 12 nicklas 550             }; // We fill each block C1, B1, A1, C2, B2 (A2 is left empty)
1683 01 Jun 12 nicklas 551         
1683 01 Jun 12 nicklas 552         
1683 01 Jun 12 nicklas 553         PlateGeometry geometry = BioplateType.PARAFFIN_BLOCK.getPlateGeometry(dc);
1683 01 Jun 12 nicklas 554         BioPlateType paraffinBlockType = BioplateType.PARAFFIN_BLOCK.load(dc);
1683 01 Jun 12 nicklas 555         
1683 01 Jun 12 nicklas 556         BioPlate paraffinBlock = null;
1683 01 Jun 12 nicklas 557         BioPlateEventParticipant blockEvent = null;
1692 08 Jun 12 nicklas 558         int blockPos = Histology.SAMPLES_PER_BLOCK; // Start outside trigger creation of a new paraffin block
1683 01 Jun 12 nicklas 559         int blockNo = 0;
1684 04 Jun 12 nicklas 560         int remainingBioMaterial = allBioMaterial.size();
1683 01 Jun 12 nicklas 561
1683 01 Jun 12 nicklas 562         for (Sample his : allBioMaterial)
1589 20 Mar 12 nicklas 563         {
1692 08 Jun 12 nicklas 564           if (blockPos == Histology.SAMPLES_PER_BLOCK)
1589 20 Mar 12 nicklas 565           {
1692 08 Jun 12 nicklas 566             JSONObject jsonBlock = (JSONObject)jsonBlocks.get(blockNo);
1774 11 Dec 12 nicklas 567             storageBox = Values.getStringOrNull((String)jsonBlock.get("storageBox"));
1692 08 Jun 12 nicklas 568             Number blockId = (Number)jsonBlock.get("id");
1683 01 Jun 12 nicklas 569             blockPos = 0;
1683 01 Jun 12 nicklas 570             blockNo++;
1684 04 Jun 12 nicklas 571             
1692 08 Jun 12 nicklas 572             paraffinBlock = BioPlate.getById(dc, blockId.intValue());
2344 09 Apr 14 nicklas 573             paraffinBlock.setEventDate(embedDate);
1774 11 Dec 12 nicklas 574             paraffinBlock.setTray(storageBox);
1776 11 Dec 12 nicklas 575             paraffinBlock.setDescription(Values.getStringOrNull((String)jsonBlock.get("comment")));
1589 20 Mar 12 nicklas 576             
1684 04 Jun 12 nicklas 577             // Attach the new paraffin block to the PLACE-ON-PLATE event
1683 01 Jun 12 nicklas 578             blockEvent = placeEvent.addParticipant(paraffinBlock, "destination", blockNo);
1683 01 Jun 12 nicklas 579             dc.saveItem(blockEvent);
1683 01 Jun 12 nicklas 580             
1692 08 Jun 12 nicklas 581             int numSamples = remainingBioMaterial > Histology.SAMPLES_PER_BLOCK ? Histology.SAMPLES_PER_BLOCK : remainingBioMaterial;
1684 04 Jun 12 nicklas 582             
1774 11 Dec 12 nicklas 583             jsonMessages.add("Moved " + numSamples + " samples to '" + paraffinBlock.getName() + "'");
1589 20 Mar 12 nicklas 584           }
1589 20 Mar 12 nicklas 585           
1684 04 Jun 12 nicklas 586           // Register date and protocol
1684 04 Jun 12 nicklas 587           BioMaterialEvent createEvent = his.getCreationEvent();
2344 09 Apr 14 nicklas 588           createEvent.setEventDate(embedDate);
1684 04 Jun 12 nicklas 589           createEvent.setProtocol(protocol);
1684 04 Jun 12 nicklas 590           
1683 01 Jun 12 nicklas 591           // Move the biomaterial -- keep track of the old location for message
1683 01 Jun 12 nicklas 592           BioWell oldWell = his.getBioWell();
1683 01 Jun 12 nicklas 593           his.setBioWell(paraffinBlock.getBioWell(moveTo[blockPos]));
1683 01 Jun 12 nicklas 594           // Register an event for it
1683 01 Jun 12 nicklas 595           BioMaterialEvent bmEvent = his.newEvent(blockEvent);
1683 01 Jun 12 nicklas 596           if (oldWell != null)
1683 01 Jun 12 nicklas 597           {
1683 01 Jun 12 nicklas 598             bmEvent.setComment("Moved from " + oldWell.getCoordinate() + " on '" +oldWell.getPlate().getName() + "'.");
1683 01 Jun 12 nicklas 599           }
1683 01 Jun 12 nicklas 600           dc.saveItem(bmEvent);
1683 01 Jun 12 nicklas 601           blockPos++;
1684 04 Jun 12 nicklas 602           remainingBioMaterial--;
1589 20 Mar 12 nicklas 603         }
1589 20 Mar 12 nicklas 604         
5421 13 May 19 nicklas 605         ActivityDef.EMBEDDED_SAMPLES.merge(dc, allBioMaterial.size());
5381 24 Apr 19 nicklas 606         
1774 11 Dec 12 nicklas 607         if (storageBox != null)
1774 11 Dec 12 nicklas 608         {
1774 11 Dec 12 nicklas 609           sc.setUserClientSetting("net.sf.basedb.reggie.histology.last-block-box", storageBox);
1774 11 Dec 12 nicklas 610         }
1692 08 Jun 12 nicklas 611
1589 20 Mar 12 nicklas 612         dc.commit();
1589 20 Mar 12 nicklas 613       }
1668 25 May 12 nicklas 614       
1668 25 May 12 nicklas 615       else if ("RegisterHEGlass".equals(cmd))
1668 25 May 12 nicklas 616       {
6332 15 Jun 21 nicklas 617         dc = sc.newDbControl(":Register HE glass");
2161 09 Dec 13 nicklas 618
2161 09 Dec 13 nicklas 619         ReggieRole.checkPermission(dc, "'" + cmd + "' wizard", ReggieRole.HISTOLOGY, ReggieRole.ADMINISTRATOR);
3752 17 Feb 16 nicklas 620         JSONObject jsonReq = JsonUtil.parseRequest(req);
1668 25 May 12 nicklas 621         JSONObject jsonPlate = (JSONObject)jsonReq.get("paraffinBlock");
1668 25 May 12 nicklas 622         JSONArray jsonWells = (JSONArray)jsonPlate.get("bioWells");
1694 08 Jun 12 nicklas 623         JSONArray jsonHeGlass = (JSONArray)jsonPlate.get("heGlass");
1668 25 May 12 nicklas 624
1668 25 May 12 nicklas 625         Number plateId = (Number)jsonPlate.get("id");
1686 04 Jun 12 nicklas 626         Number protocolId = (Number)jsonPlate.get("protocolId");
1668 25 May 12 nicklas 627         Date stainDate = Reggie.CONVERTER_STRING_TO_DATE.convert((String)jsonPlate.get("stainDate"));
1686 04 Jun 12 nicklas 628         Protocol protocol = protocolId == null ? null : Protocol.getById(dc, protocolId.intValue());
1668 25 May 12 nicklas 629
1668 25 May 12 nicklas 630         // Load the paraffin block, the histology items on it
2242 21 Feb 14 nicklas 631         // and check if some items should be flagged
1668 25 May 12 nicklas 632         BioPlate pb = BioPlate.getById(dc, plateId.intValue());
1777 12 Dec 12 nicklas 633         pb.setDescription(Values.getStringOrNull((String)jsonPlate.get("comment")));
1778 12 Dec 12 nicklas 634         int numHeGlass = jsonHeGlass.size(); 
2242 21 Feb 14 nicklas 635         int numFlagged = 0;
2242 21 Feb 14 nicklas 636         int numUnflagged = 0;
3247 14 Apr 15 nicklas 637         ItemList flaggedHistology = BiomaterialList.FLAGGED_HISTOLOGY.load(dc);
1668 25 May 12 nicklas 638         for (int i = 0; i < jsonWells.size(); ++i)
1668 25 May 12 nicklas 639         {
1668 25 May 12 nicklas 640           JSONObject jsonWell = (JSONObject)jsonWells.get(i);
2244 21 Feb 14 nicklas 641           JSONObject jsonHistology = (JSONObject)jsonWell.get("bioMaterial");
2244 21 Feb 14 nicklas 642           if (jsonHistology != null)
1668 25 May 12 nicklas 643           {
2244 21 Feb 14 nicklas 644             Number goodStain = (Number)jsonWell.get("GoodStain");
2244 21 Feb 14 nicklas 645             Number hisId = (Number)jsonHistology.get("id");
2244 21 Feb 14 nicklas 646             MeasuredBioMaterial histology = Sample.getById(dc, hisId.intValue());
2244 21 Feb 14 nicklas 647
1668 25 May 12 nicklas 648             jsonWell.put("histology", histology);
2244 21 Feb 14 nicklas 649             histology.setDescription((String)jsonHistology.get("comment"));
2242 21 Feb 14 nicklas 650             String flag = (String)Annotationtype.FLAG.getAnnotationValue(dc, histology);
2242 21 Feb 14 nicklas 651             if (goodStain.intValue() == 0)
2242 21 Feb 14 nicklas 652             {
2242 21 Feb 14 nicklas 653               if (flag == null)
2242 21 Feb 14 nicklas 654               {
2242 21 Feb 14 nicklas 655                 // Flag the histology if it is not already flagged
2242 21 Feb 14 nicklas 656                 numFlagged++;
2242 21 Feb 14 nicklas 657                 Annotationtype.FLAG.setAnnotationValue(dc, histology, Histology.FLAG_NO_GOOD_STAIN);
2242 21 Feb 14 nicklas 658                 flaggedHistology.add(histology);
2242 21 Feb 14 nicklas 659               }
2242 21 Feb 14 nicklas 660             }
2242 21 Feb 14 nicklas 661             else if (flag != null)
2242 21 Feb 14 nicklas 662             {
2242 21 Feb 14 nicklas 663               // Remove the flag
2242 21 Feb 14 nicklas 664               numUnflagged++;
2242 21 Feb 14 nicklas 665               Annotationtype.FLAG.setAnnotationValue(dc, histology, null);
5364 16 Apr 19 nicklas 666               flaggedHistology.removeItem(histology);
2242 21 Feb 14 nicklas 667             }
1668 25 May 12 nicklas 668           }
1668 25 May 12 nicklas 669         }
1668 25 May 12 nicklas 670
1668 25 May 12 nicklas 671         String heGlassPrefix = pb.getName().replace("PB", "HE");
1668 25 May 12 nicklas 672   
1668 25 May 12 nicklas 673         // Create bioplate event
1668 25 May 12 nicklas 674         BioPlateEventType createBioMaterial = BioPlateEventType.getById(dc, BioPlateEventType.CREATE_BIOMATERIAL);
1668 25 May 12 nicklas 675         BioPlateEvent stainEvent = BioPlateEvent.getNew(dc, createBioMaterial);
1668 25 May 12 nicklas 676         stainEvent.setName("HE stain");
1668 25 May 12 nicklas 677         stainEvent.addParticipant(pb, "paraffin-block", 1);
1668 25 May 12 nicklas 678         stainEvent.setEventDate(stainDate);
1686 04 Jun 12 nicklas 679         stainEvent.setProtocol(protocol);
1668 25 May 12 nicklas 680         
1668 25 May 12 nicklas 681         // Create required number of child glass plates
1668 25 May 12 nicklas 682         int numNewHEGlass = 0;
1778 12 Dec 12 nicklas 683         for (int stainNo = 1; stainNo <= numHeGlass; ++stainNo)
1668 25 May 12 nicklas 684         {
1694 08 Jun 12 nicklas 685           JSONObject jsonGlass = (JSONObject)jsonHeGlass.get(stainNo-1);
1774 11 Dec 12 nicklas 686           String storageBox = Values.getStringOrNull((String)jsonGlass.get("storageBox"));
1774 11 Dec 12 nicklas 687           String position = Values.getStringOrNull((String)jsonGlass.get("position"));
3121 06 Feb 15 nicklas 688           String ihc = Values.getStringOrNull((String)jsonGlass.get("IHC"));
1777 12 Dec 12 nicklas 689           String comment = Values.getStringOrNull((String)jsonGlass.get("comment"));
1694 08 Jun 12 nicklas 690           
1668 25 May 12 nicklas 691           // Try to find an existing HE glass
4892 09 Jul 18 nicklas 692           String heGlassName = heGlassPrefix + "." + stainNo;
1668 25 May 12 nicklas 693           ReactionPlate hePlate = ReactionPlate.findByNameAndType(dc, heGlassName, BioplateType.HE_GLASS);
1668 25 May 12 nicklas 694           BioPlate heGlass = null;
1668 25 May 12 nicklas 695           BioPlateEventParticipant stainEventParticipant = null;
1668 25 May 12 nicklas 696           if (hePlate != null)
1668 25 May 12 nicklas 697           {
1668 25 May 12 nicklas 698             // Use the existing HE glass
1668 25 May 12 nicklas 699             heGlass = hePlate.getBioPlate();
1668 25 May 12 nicklas 700           }
1668 25 May 12 nicklas 701           else
1668 25 May 12 nicklas 702           {
1668 25 May 12 nicklas 703             // Create a new HE glass item
1668 25 May 12 nicklas 704             heGlass = BioPlate.getNew(dc, BioplateType.HE_GLASS.getPlateGeometry(dc), BioplateType.HE_GLASS.load(dc));
4892 09 Jul 18 nicklas 705             heGlass.setName(heGlassName); // Safe, since we just made a check if the HEglass exists or not
1668 25 May 12 nicklas 706             heGlass.setEventDate(stainDate);
1668 25 May 12 nicklas 707             dc.saveItem(heGlass);
1668 25 May 12 nicklas 708             
1668 25 May 12 nicklas 709             stainEventParticipant = stainEvent.addParticipant(heGlass, "glass", stainNo);
1668 25 May 12 nicklas 710             numNewHEGlass++;
1668 25 May 12 nicklas 711           }
1668 25 May 12 nicklas 712           
1774 11 Dec 12 nicklas 713           heGlass.setTray(storageBox);
1774 11 Dec 12 nicklas 714           heGlass.setPosition(position);
1777 12 Dec 12 nicklas 715           heGlass.setDescription(comment);
3121 06 Feb 15 nicklas 716           Annotationtype.IHC.setAnnotationValue(dc, heGlass, ihc);
1694 08 Jun 12 nicklas 717           
1668 25 May 12 nicklas 718           int numGoodStains = 0;
1668 25 May 12 nicklas 719           for (int w = 0; w < jsonWells.size(); ++w)
1668 25 May 12 nicklas 720           {
1668 25 May 12 nicklas 721             JSONObject jsonWell = (JSONObject)jsonWells.get(w);
1668 25 May 12 nicklas 722             Sample histology = (Sample)jsonWell.get("histology");
1668 25 May 12 nicklas 723             if (histology != null)
1668 25 May 12 nicklas 724             {
1668 25 May 12 nicklas 725               Number goodStain = (Number)jsonWell.get("GoodStain");
1668 25 May 12 nicklas 726               BioWell hisWell = histology.getBioWell();
4892 09 Jul 18 nicklas 727               String stainedName = histology.getName() + ".he" + stainNo;
1668 25 May 12 nicklas 728               
1668 25 May 12 nicklas 729               // The HE glass have switched columns compared to the paraffin block
1668 25 May 12 nicklas 730               PlateCoordinate hisCoordinate = hisWell.getPlateCoordinate();
1668 25 May 12 nicklas 731               PlateCoordinate heCoordinate = new PlateCoordinate(hisCoordinate.getRow(), 1-hisCoordinate.getColumn());
1668 25 May 12 nicklas 732
1668 25 May 12 nicklas 733               MeasuredBioMaterial stained = null;
1668 25 May 12 nicklas 734               if (hePlate != null)
1668 25 May 12 nicklas 735               {
1668 25 May 12 nicklas 736                 // Use the existing biomaterial
1668 25 May 12 nicklas 737                 stained = heGlass.getBioMaterial(heCoordinate);
1668 25 May 12 nicklas 738               }
1668 25 May 12 nicklas 739               else
1668 25 May 12 nicklas 740               {
1668 25 May 12 nicklas 741                 // Create new child biomaterial
1668 25 May 12 nicklas 742                 stained = Sample.getNew(dc, stainEventParticipant);
1668 25 May 12 nicklas 743                 stained.setItemSubtype(Subtype.STAINED.load(dc));
4892 09 Jul 18 nicklas 744                 stained.setName(stainedName); // Safe, since this is a new stain
1668 25 May 12 nicklas 745                 stained.setBioWell(heGlass.getBioWell(heCoordinate));
2244 21 Feb 14 nicklas 746                 stained.setDescription(histology.getDescription());
1668 25 May 12 nicklas 747                 dc.saveItem(stained);
1668 25 May 12 nicklas 748
1668 25 May 12 nicklas 749                 BioMaterialEvent creationEvent = stained.getCreationEvent();
1668 25 May 12 nicklas 750                 creationEvent.setSource(histology);
5791 16 Dec 19 nicklas 751                 DoNotUse.copyDoNotUseAnnotations(dc, histology, stained, false);
1668 25 May 12 nicklas 752                 creationEvent.setEventDate(stainDate);
1686 04 Jun 12 nicklas 753                 creationEvent.setProtocol(protocol);
1668 25 May 12 nicklas 754               }
1668 25 May 12 nicklas 755   
1668 25 May 12 nicklas 756               if (goodStain.intValue() == stainNo)
1668 25 May 12 nicklas 757               {
1668 25 May 12 nicklas 758                 Annotationtype.GOOD_STAIN.setAnnotationValue(dc, stained, true);
1668 25 May 12 nicklas 759                 numGoodStains++;
1668 25 May 12 nicklas 760               }
1668 25 May 12 nicklas 761               else
1668 25 May 12 nicklas 762               {
1668 25 May 12 nicklas 763                 // Remove the value if it existed
1668 25 May 12 nicklas 764                 Annotationtype.GOOD_STAIN.setAnnotationValue(dc, stained, null);
1668 25 May 12 nicklas 765               }
1668 25 May 12 nicklas 766               
1668 25 May 12 nicklas 767             }
1668 25 May 12 nicklas 768           }
1668 25 May 12 nicklas 769           if (hePlate == null)
1668 25 May 12 nicklas 770           {
3121 06 Feb 15 nicklas 771             jsonMessages.add("Created '" + heGlass.getName() + "' " + (ihc != null ? "(" + ihc + ")" : "") + " with " +  numGoodStains + " good stains.");
1668 25 May 12 nicklas 772           }
1668 25 May 12 nicklas 773           else
1668 25 May 12 nicklas 774           {
3121 06 Feb 15 nicklas 775             jsonMessages.add("Updated '" + heGlass.getName() + "' " + (ihc != null ? "(" + ihc + ")" : "") + " with " +  numGoodStains + " good stains.");
1668 25 May 12 nicklas 776           }
1668 25 May 12 nicklas 777         }
2242 21 Feb 14 nicklas 778         if (numFlagged > 0)
2242 21 Feb 14 nicklas 779         {
2242 21 Feb 14 nicklas 780           jsonMessages.add(numFlagged + " items added to Flagged histology list.");
2242 21 Feb 14 nicklas 781         }
2242 21 Feb 14 nicklas 782         if (numUnflagged > 0)
2242 21 Feb 14 nicklas 783         {
2242 21 Feb 14 nicklas 784           jsonMessages.add(numUnflagged + " items removed from Flagged histology list.");          
2242 21 Feb 14 nicklas 785         }
1668 25 May 12 nicklas 786         if (numNewHEGlass > 0)
1668 25 May 12 nicklas 787         {
1668 25 May 12 nicklas 788           dc.saveItem(stainEvent);
1668 25 May 12 nicklas 789         }
1668 25 May 12 nicklas 790         
5381 24 Apr 19 nicklas 791         if (numNewHEGlass > 0)
5381 24 Apr 19 nicklas 792         {
5421 13 May 19 nicklas 793           ActivityDef.STAINED_HEGLASS.merge(dc, numNewHEGlass);
5381 24 Apr 19 nicklas 794         }
5381 24 Apr 19 nicklas 795         
1668 25 May 12 nicklas 796         dc.commit();
1668 25 May 12 nicklas 797       }
2134 11 Nov 13 nicklas 798       else if ("SaveHeScore".equals(cmd))
2134 11 Nov 13 nicklas 799       {
6332 15 Jun 21 nicklas 800         dc = sc.newDbControl(":Score HE glass");
2161 09 Dec 13 nicklas 801
2161 09 Dec 13 nicklas 802         ReggieRole.checkPermission(dc, "'" + cmd + "' wizard", ReggieRole.HISTOLOGY, ReggieRole.ADMINISTRATOR);
2161 09 Dec 13 nicklas 803
3752 17 Feb 16 nicklas 804         JSONObject jsonReq = JsonUtil.parseRequest(req);
2134 11 Nov 13 nicklas 805         JSONArray jsonSamples = (JSONArray)jsonReq.get("samples");
2134 11 Nov 13 nicklas 806         JSONArray jsonHeGlass = (JSONArray)jsonReq.get("heGlass");
2134 11 Nov 13 nicklas 807
2243 21 Feb 14 nicklas 808         Set<Sample> histologyItems = new HashSet<Sample>();
2243 21 Feb 14 nicklas 809
2134 11 Nov 13 nicklas 810         // Update scores on samples
5381 24 Apr 19 nicklas 811         int numScoreComplete = 0;
2134 11 Nov 13 nicklas 812         for (int sampleNo = 0; sampleNo < jsonSamples.size(); ++sampleNo)
2134 11 Nov 13 nicklas 813         {
2134 11 Nov 13 nicklas 814           JSONObject jsonSample = (JSONObject)jsonSamples.get(sampleNo);
2134 11 Nov 13 nicklas 815           Number sampleId = (Number)jsonSample.get("id");
2134 11 Nov 13 nicklas 816           Boolean goodStain = (Boolean)jsonSample.get("GoodStain");
2134 11 Nov 13 nicklas 817           Boolean scoreComplete = (Boolean)jsonSample.get("ScoreComplete");
3169 06 Mar 15 nicklas 818           String ihc = (String)jsonSample.get("IHC");
2134 11 Nov 13 nicklas 819           
2134 11 Nov 13 nicklas 820           Sample he = Sample.getById(dc, sampleId.intValue());
2134 11 Nov 13 nicklas 821           
3169 06 Mar 15 nicklas 822           if (ihc != null)
2134 11 Nov 13 nicklas 823           {
3169 06 Mar 15 nicklas 824             String ihcQuality = (String)jsonSample.get("IHCQuality");
3169 06 Mar 15 nicklas 825             Annotationtype.IHC_QUALITY.setAnnotationValue(dc, he, ihcQuality);
3169 06 Mar 15 nicklas 826             if (ihcQuality != null)
3169 06 Mar 15 nicklas 827             {
3169 06 Mar 15 nicklas 828               jsonMessages.add("IHC quality set for sample: " + he.getName());
3169 06 Mar 15 nicklas 829             }
2134 11 Nov 13 nicklas 830           }
2134 11 Nov 13 nicklas 831           else
2134 11 Nov 13 nicklas 832           {
3169 06 Mar 15 nicklas 833             Annotationtype.GOOD_STAIN.setAnnotationValue(dc, he, goodStain);
3169 06 Mar 15 nicklas 834             Annotationtype.SCORE_INVASIVE_CANCER.setAnnotationValue(dc, he, jsonSample.get("ScoreInvasiveCancer"));
3169 06 Mar 15 nicklas 835             Annotationtype.SCORE_INSITU_CANCER.setAnnotationValue(dc, he, jsonSample.get("ScoreInsituCancer"));
3169 06 Mar 15 nicklas 836             Annotationtype.SCORE_LYMPHOCYTES.setAnnotationValue(dc, he, jsonSample.get("ScoreLymphocytes"));
3169 06 Mar 15 nicklas 837             Annotationtype.SCORE_NORMAL.setAnnotationValue(dc, he, jsonSample.get("ScoreNormal"));
3169 06 Mar 15 nicklas 838             Annotationtype.SCORE_STROMA.setAnnotationValue(dc, he, jsonSample.get("ScoreStroma"));
3169 06 Mar 15 nicklas 839             Annotationtype.SCORE_FAT.setAnnotationValue(dc, he, jsonSample.get("ScoreFat"));
3169 06 Mar 15 nicklas 840             Annotationtype.SCORE_COMPLETE.setAnnotationValue(dc, he, scoreComplete);
3169 06 Mar 15 nicklas 841
3169 06 Mar 15 nicklas 842             if (Boolean.TRUE.equals(scoreComplete))
3169 06 Mar 15 nicklas 843             {
5381 24 Apr 19 nicklas 844               numScoreComplete++;
3169 06 Mar 15 nicklas 845               jsonMessages.add("Scoring complete for sample: " + he.getName() + (Boolean.TRUE.equals(goodStain) ? " (GoodStain)" : ""));
3169 06 Mar 15 nicklas 846             }
3169 06 Mar 15 nicklas 847             else if (Boolean.FALSE.equals(scoreComplete))
3169 06 Mar 15 nicklas 848             {
3169 06 Mar 15 nicklas 849               jsonMessages.add("Score updated for sample: " + he.getName() + " (Not complete)");
3169 06 Mar 15 nicklas 850             }
3169 06 Mar 15 nicklas 851             else
3169 06 Mar 15 nicklas 852             {
3169 06 Mar 15 nicklas 853               jsonMessages.add("Scores removed from sample: " + he.getName());
3169 06 Mar 15 nicklas 854             }
3169 06 Mar 15 nicklas 855             
3169 06 Mar 15 nicklas 856             // Get parent Histology item for later checking of good stains
3169 06 Mar 15 nicklas 857             histologyItems.add((Sample)he.getParent());
2134 11 Nov 13 nicklas 858           }
3169 06 Mar 15 nicklas 859           he.setDescription(Values.getStringOrNull((String)jsonSample.get("comments")));
2134 11 Nov 13 nicklas 860         }
2134 11 Nov 13 nicklas 861         
2134 11 Nov 13 nicklas 862         // ScoreComplete on HE glass
2134 11 Nov 13 nicklas 863         for (int glassNo = 0; glassNo < jsonHeGlass.size(); ++glassNo)
2134 11 Nov 13 nicklas 864         {
2134 11 Nov 13 nicklas 865           JSONObject jsonGlass = (JSONObject)jsonHeGlass.get(glassNo);
2134 11 Nov 13 nicklas 866           Number glassId = (Number)jsonGlass.get("id");
2134 11 Nov 13 nicklas 867           Boolean scoreComplete = (Boolean)jsonGlass.get("ScoreComplete");
2134 11 Nov 13 nicklas 868           
2134 11 Nov 13 nicklas 869           BioPlate heGlass = BioPlate.getById(dc, glassId.intValue());
2134 11 Nov 13 nicklas 870           Annotationtype.SCORE_COMPLETE.setAnnotationValue(dc, heGlass, scoreComplete);
3169 06 Mar 15 nicklas 871           boolean ihc = Annotationtype.IHC.getAnnotationValue(dc, heGlass) != null;
2134 11 Nov 13 nicklas 872           
2134 11 Nov 13 nicklas 873           if (Boolean.TRUE.equals(scoreComplete))
2134 11 Nov 13 nicklas 874           {
3169 06 Mar 15 nicklas 875             if (ihc)
3169 06 Mar 15 nicklas 876             {
3169 06 Mar 15 nicklas 877               jsonMessages.add("Quality complete for IHC glass: " + heGlass.getName());
3169 06 Mar 15 nicklas 878             }
3169 06 Mar 15 nicklas 879             else
3169 06 Mar 15 nicklas 880             {
3169 06 Mar 15 nicklas 881               jsonMessages.add("Scoring complete for HE glass: " + heGlass.getName());
3169 06 Mar 15 nicklas 882             }
2134 11 Nov 13 nicklas 883           }
2134 11 Nov 13 nicklas 884           else
2134 11 Nov 13 nicklas 885           {
3169 06 Mar 15 nicklas 886             if (ihc)
3169 06 Mar 15 nicklas 887             {
3169 06 Mar 15 nicklas 888               jsonMessages.add("Quality updated for IHC glass: " + heGlass.getName() + " (Not complete)");
3169 06 Mar 15 nicklas 889             }
3169 06 Mar 15 nicklas 890             else
3169 06 Mar 15 nicklas 891             {
3169 06 Mar 15 nicklas 892               jsonMessages.add("Score updated for HE glass: " + heGlass.getName() + " (Not complete)");
3169 06 Mar 15 nicklas 893             }
2134 11 Nov 13 nicklas 894           }
2134 11 Nov 13 nicklas 895         }
2134 11 Nov 13 nicklas 896         
2243 21 Feb 14 nicklas 897         // Check flagged histology items
2243 21 Feb 14 nicklas 898         int numFlagged = 0;
2243 21 Feb 14 nicklas 899         int numUnflagged = 0;
3247 14 Apr 15 nicklas 900         ItemList flaggedHistology = BiomaterialList.FLAGGED_HISTOLOGY.load(dc);
2243 21 Feb 14 nicklas 901         for (Sample histology : histologyItems)
2243 21 Feb 14 nicklas 902         {
2243 21 Feb 14 nicklas 903           String flag = (String)Annotationtype.FLAG.getAnnotationValue(dc, histology);
2243 21 Feb 14 nicklas 904           
2243 21 Feb 14 nicklas 905           ItemQuery<Sample> heQuery = histology.getChildSamples();
2243 21 Feb 14 nicklas 906           Subtype.STAINED.addFilter(dc, heQuery);
2243 21 Feb 14 nicklas 907           heQuery.include(Reggie.INCLUDE_IN_CURRENT_PROJECT);
2243 21 Feb 14 nicklas 908           boolean hasGoodStain = false;
2243 21 Feb 14 nicklas 909           for (Sample stained : heQuery.list(dc))
2243 21 Feb 14 nicklas 910           {
2243 21 Feb 14 nicklas 911             if (Boolean.TRUE.equals(Annotationtype.GOOD_STAIN.getAnnotationValue(dc, stained)))
2243 21 Feb 14 nicklas 912             {
2243 21 Feb 14 nicklas 913               hasGoodStain = true;
2243 21 Feb 14 nicklas 914               break;
2243 21 Feb 14 nicklas 915             }
2243 21 Feb 14 nicklas 916           }
2243 21 Feb 14 nicklas 917           
2243 21 Feb 14 nicklas 918           if (hasGoodStain)
2243 21 Feb 14 nicklas 919           {
2243 21 Feb 14 nicklas 920             if (flag != null)
2243 21 Feb 14 nicklas 921             {
2243 21 Feb 14 nicklas 922               // Remove the flag
2243 21 Feb 14 nicklas 923               numUnflagged++;
2243 21 Feb 14 nicklas 924               Annotationtype.FLAG.setAnnotationValue(dc, histology, null);
5364 16 Apr 19 nicklas 925               flaggedHistology.removeItem(histology);
2243 21 Feb 14 nicklas 926             }
2243 21 Feb 14 nicklas 927           }
2243 21 Feb 14 nicklas 928           else
2243 21 Feb 14 nicklas 929           {
2243 21 Feb 14 nicklas 930             if (flag == null)
2243 21 Feb 14 nicklas 931             {
2243 21 Feb 14 nicklas 932               // Flag the histology since it has no good stain and is not already flagged
2243 21 Feb 14 nicklas 933               numFlagged++;
2243 21 Feb 14 nicklas 934               Annotationtype.FLAG.setAnnotationValue(dc, histology, Histology.FLAG_NO_GOOD_STAIN);
2243 21 Feb 14 nicklas 935               flaggedHistology.add(histology);
2243 21 Feb 14 nicklas 936             }
2243 21 Feb 14 nicklas 937           }
2243 21 Feb 14 nicklas 938           
2243 21 Feb 14 nicklas 939         }
2243 21 Feb 14 nicklas 940         
2243 21 Feb 14 nicklas 941         if (numFlagged > 0)
2243 21 Feb 14 nicklas 942         {
2243 21 Feb 14 nicklas 943           jsonMessages.add(numFlagged + " items added to Flagged histology list.");
2243 21 Feb 14 nicklas 944         }
2243 21 Feb 14 nicklas 945         if (numUnflagged > 0)
2243 21 Feb 14 nicklas 946         {
2243 21 Feb 14 nicklas 947           jsonMessages.add(numUnflagged + " items removed from Flagged histology list.");          
2243 21 Feb 14 nicklas 948         }
5381 24 Apr 19 nicklas 949         if (numScoreComplete > 0)
5381 24 Apr 19 nicklas 950         {
5421 13 May 19 nicklas 951           ActivityDef.SCORED_HISTOLOGY.merge(dc, numScoreComplete);
5381 24 Apr 19 nicklas 952         }
2243 21 Feb 14 nicklas 953
2134 11 Nov 13 nicklas 954         dc.commit();
2134 11 Nov 13 nicklas 955       }
1668 25 May 12 nicklas 956       
3368 08 Jun 15 nicklas 957       else if ("UploadImage".equals(cmd))
3368 08 Jun 15 nicklas 958       {
3368 08 Jun 15 nicklas 959         
6332 15 Jun 21 nicklas 960         dc = sc.newDbControl(":Register HE glass");
3368 08 Jun 15 nicklas 961         ReggieRole.checkPermission(dc, "'" + cmd + "' wizard", ReggieRole.HISTOLOGY, ReggieRole.ADMINISTRATOR);
3368 08 Jun 15 nicklas 962
3368 08 Jun 15 nicklas 963         int hisId = Values.getInt(req.getParameter("sampleId"));
3372 09 Jun 15 nicklas 964         String originalFilename = req.getParameter("filename");
3372 09 Jun 15 nicklas 965         String originalExtension = originalFilename.substring(originalFilename.lastIndexOf('.')); 
3372 09 Jun 15 nicklas 966         // Should be '.jpg', '.png' or '.tif'
3368 08 Jun 15 nicklas 967         
3372 09 Jun 15 nicklas 968         // Convert TIFF to JPG
3372 09 Jun 15 nicklas 969         boolean isTiff = originalExtension.contains("tif");
3372 09 Jun 15 nicklas 970         String extension = isTiff ? ".jpg" : originalExtension;
3372 09 Jun 15 nicklas 971         
3368 08 Jun 15 nicklas 972         Sample his = Sample.getById(dc, hisId);
3368 08 Jun 15 nicklas 973         String imageFileName = Path.makeSafeFilename(his.getName(), "") + extension;
3368 08 Jun 15 nicklas 974         
3368 08 Jun 15 nicklas 975         // Image
3368 08 Jun 15 nicklas 976         File imageFile = null;
3368 08 Jun 15 nicklas 977         AnyToAny imageLink = null;
3368 08 Jun 15 nicklas 978         try
3368 08 Jun 15 nicklas 979         {
3368 08 Jun 15 nicklas 980           imageLink = AnyToAny.getByName(dc, his, "image");
3368 08 Jun 15 nicklas 981           if (imageLink.getToType() == Item.FILE)
3368 08 Jun 15 nicklas 982           {
3368 08 Jun 15 nicklas 983             // This is linked to an existing file already, replace it
3368 08 Jun 15 nicklas 984             imageFile = (File)imageLink.getTo();
3368 08 Jun 15 nicklas 985             if (!imageFile.getName().endsWith(extension))
3368 08 Jun 15 nicklas 986             {
3368 08 Jun 15 nicklas 987               imageFile.setName(imageFileName);
3368 08 Jun 15 nicklas 988             }
3368 08 Jun 15 nicklas 989           }
3368 08 Jun 15 nicklas 990         }
3368 08 Jun 15 nicklas 991         catch (ItemNotFoundException ex)
3368 08 Jun 15 nicklas 992         {} // No link to a file, create new below
3368 08 Jun 15 nicklas 993         
3368 08 Jun 15 nicklas 994         // Create new file?
3368 08 Jun 15 nicklas 995         if (imageFile == null)
3368 08 Jun 15 nicklas 996         {
5784 12 Dec 19 nicklas 997           String path = Histology.getImageFolder(his.getName());
3368 08 Jun 15 nicklas 998           
3368 08 Jun 15 nicklas 999           Directory imageDir = Directory.getNew(dc, new Path(path, Path.Type.DIRECTORY));
3368 08 Jun 15 nicklas 1000           imageFile = File.getFile(dc, imageDir, imageFileName, true);
3368 08 Jun 15 nicklas 1001           if (!imageFile.isInDatabase()) 
3368 08 Jun 15 nicklas 1002           {
3368 08 Jun 15 nicklas 1003             dc.saveItem(imageFile);
3368 08 Jun 15 nicklas 1004           }
3368 08 Jun 15 nicklas 1005         }
3368 08 Jun 15 nicklas 1006         imageFile.setMimeTypeAuto(null, null);
3368 08 Jun 15 nicklas 1007         
3368 08 Jun 15 nicklas 1008         // Need to create new link?
3368 08 Jun 15 nicklas 1009         if (imageLink == null)
3368 08 Jun 15 nicklas 1010         {
3368 08 Jun 15 nicklas 1011           imageLink = AnyToAny.getNew(dc, his, imageFile, "image", false);
3368 08 Jun 15 nicklas 1012           dc.saveItem(imageLink);
3368 08 Jun 15 nicklas 1013         }
3368 08 Jun 15 nicklas 1014         else
3368 08 Jun 15 nicklas 1015         {
3368 08 Jun 15 nicklas 1016           imageLink.setTo(imageFile);
3368 08 Jun 15 nicklas 1017           imageLink.setUsingTo(false);
3368 08 Jun 15 nicklas 1018         }
3372 09 Jun 15 nicklas 1019         imageLink.setDescription("Original filename: " + originalFilename);
3372 09 Jun 15 nicklas 1020         imageFile.setDescription("Original filename: " + originalFilename);
3368 08 Jun 15 nicklas 1021         
3368 08 Jun 15 nicklas 1022         json.put("image", imageFile.getPath().toString());
3368 08 Jun 15 nicklas 1023         
3368 08 Jun 15 nicklas 1024         InputStream upload = req.getInputStream();
3368 08 Jun 15 nicklas 1025         OutputStream out = imageFile.getUploadStream(false, false);
3368 08 Jun 15 nicklas 1026         
3372 09 Jun 15 nicklas 1027         if (isTiff)
3372 09 Jun 15 nicklas 1028         {
5432 17 May 19 nicklas 1029           BufferedImage image = ImageIO.read(upload);
5432 17 May 19 nicklas 1030           // NOTE! In case the JPG writer can't handle the image a conversion to
5432 17 May 19 nicklas 1031           // RGB might be needed, but it seems like the images from the microscope
5432 17 May 19 nicklas 1032           // works as they are
5432 17 May 19 nicklas 1033           /*
5432 17 May 19 nicklas 1034           int imageType = image.getType();
5432 17 May 19 nicklas 1035           if (imageType != BufferedImage.TYPE_INT_RGB && imageType != BufferedImage.TYPE_INT_ARGB)
5432 17 May 19 nicklas 1036           {
5432 17 May 19 nicklas 1037             // Convert image to RGB type if it is not already
5432 17 May 19 nicklas 1038             BufferedImage rgb = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_RGB);
5432 17 May 19 nicklas 1039             Graphics2D g2 =  rgb.createGraphics();
5432 17 May 19 nicklas 1040             g2.drawImage(image, 0, 0, Color.WHITE, null);
5432 17 May 19 nicklas 1041             g2.dispose();
5432 17 May 19 nicklas 1042             image = rgb;
5432 17 May 19 nicklas 1043           }
5432 17 May 19 nicklas 1044           */
5432 17 May 19 nicklas 1045           ImageWriter jpgWriter = ImageIO.getImageWritersByFormatName("jpg").next();
5432 17 May 19 nicklas 1046           ImageWriteParam jpgParam = jpgWriter.getDefaultWriteParam();
5432 17 May 19 nicklas 1047           jpgParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
5432 17 May 19 nicklas 1048           jpgParam.setCompressionQuality(0.9f);
3372 09 Jun 15 nicklas 1049           
5432 17 May 19 nicklas 1050           jpgWriter.setOutput(new MemoryCacheImageOutputStream(out));
5432 17 May 19 nicklas 1051           jpgWriter.write(null, new IIOImage(image, null, null), jpgParam);
5432 17 May 19 nicklas 1052           jpgWriter.dispose();
3372 09 Jun 15 nicklas 1053         }
3372 09 Jun 15 nicklas 1054         else
3372 09 Jun 15 nicklas 1055         {
3372 09 Jun 15 nicklas 1056           FileUtil.copy(upload, out);
3372 09 Jun 15 nicklas 1057         }
3372 09 Jun 15 nicklas 1058         Thread.sleep(500);  // To make the 'Uploading...' animation be visible and not just flash      
3368 08 Jun 15 nicklas 1059         out.flush();
3368 08 Jun 15 nicklas 1060         dc.commit();
3368 08 Jun 15 nicklas 1061       }
3369 08 Jun 15 nicklas 1062       else if ("DeleteImage".equals(cmd))
3369 08 Jun 15 nicklas 1063       {
3369 08 Jun 15 nicklas 1064         
6332 15 Jun 21 nicklas 1065         dc = sc.newDbControl(":Register HE glass");
3369 08 Jun 15 nicklas 1066         ReggieRole.checkPermission(dc, "'" + cmd + "' wizard", ReggieRole.HISTOLOGY, ReggieRole.ADMINISTRATOR);
3369 08 Jun 15 nicklas 1067
3369 08 Jun 15 nicklas 1068         int hisId = Values.getInt(req.getParameter("sampleId"));
3369 08 Jun 15 nicklas 1069         Sample his = Sample.getById(dc, hisId);
3369 08 Jun 15 nicklas 1070         
3369 08 Jun 15 nicklas 1071         try
3369 08 Jun 15 nicklas 1072         {
3369 08 Jun 15 nicklas 1073           AnyToAny imageLink = AnyToAny.getByName(dc, his, "image");
3369 08 Jun 15 nicklas 1074           if (imageLink.getToType() == Item.FILE)
3369 08 Jun 15 nicklas 1075           {
3369 08 Jun 15 nicklas 1076             File imageFile = (File)imageLink.getTo();
3369 08 Jun 15 nicklas 1077             dc.deleteItem(imageFile);
3369 08 Jun 15 nicklas 1078           }
3369 08 Jun 15 nicklas 1079         }
3369 08 Jun 15 nicklas 1080         catch (ItemNotFoundException ex)
3369 08 Jun 15 nicklas 1081         {}
3369 08 Jun 15 nicklas 1082         
3369 08 Jun 15 nicklas 1083         dc.commit();
3369 08 Jun 15 nicklas 1084       }
3368 08 Jun 15 nicklas 1085       
1589 20 Mar 12 nicklas 1086       json.put("messages", jsonMessages);
3059 19 Dec 14 nicklas 1087       CounterService.getInstance().setForceCount();
1589 20 Mar 12 nicklas 1088     }
1589 20 Mar 12 nicklas 1089     catch (Throwable t)
1589 20 Mar 12 nicklas 1090     {
1589 20 Mar 12 nicklas 1091       t.printStackTrace();
1589 20 Mar 12 nicklas 1092       json.clear();
1589 20 Mar 12 nicklas 1093       json.put("status", "error");
1589 20 Mar 12 nicklas 1094       json.put("message", t.getMessage());
1589 20 Mar 12 nicklas 1095       json.put("stacktrace", ThrowableUtil.stackTraceToString(t));
1589 20 Mar 12 nicklas 1096     }
1589 20 Mar 12 nicklas 1097     finally
1589 20 Mar 12 nicklas 1098     {
1589 20 Mar 12 nicklas 1099       if (dc != null) dc.close();
1589 20 Mar 12 nicklas 1100       json.writeJSONString(resp.getWriter());
1589 20 Mar 12 nicklas 1101     }
1589 20 Mar 12 nicklas 1102     
1589 20 Mar 12 nicklas 1103   }
1589 20 Mar 12 nicklas 1104   
1589 20 Mar 12 nicklas 1105 }