extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/dao/Histology.java

Code
Comments
Other
Rev Date Author Line
1669 29 May 12 nicklas 1 package net.sf.basedb.reggie.dao;
1669 29 May 12 nicklas 2
1669 29 May 12 nicklas 3 import java.util.ArrayList;
1669 29 May 12 nicklas 4 import java.util.List;
1669 29 May 12 nicklas 5
1669 29 May 12 nicklas 6 import org.json.simple.JSONObject;
1669 29 May 12 nicklas 7
1669 29 May 12 nicklas 8 import net.sf.basedb.core.DbControl;
1669 29 May 12 nicklas 9 import net.sf.basedb.core.ItemQuery;
1669 29 May 12 nicklas 10 import net.sf.basedb.core.Sample;
1826 07 Feb 13 nicklas 11 import net.sf.basedb.core.Type;
1681 01 Jun 12 nicklas 12 import net.sf.basedb.core.query.Expressions;
1669 29 May 12 nicklas 13 import net.sf.basedb.core.query.Hql;
1669 29 May 12 nicklas 14 import net.sf.basedb.core.query.Orders;
1669 29 May 12 nicklas 15 import net.sf.basedb.core.query.Restrictions;
1826 07 Feb 13 nicklas 16 import net.sf.basedb.reggie.JsonUtil;
1669 29 May 12 nicklas 17 import net.sf.basedb.reggie.Reggie;
1669 29 May 12 nicklas 18
1669 29 May 12 nicklas 19 /**
1669 29 May 12 nicklas 20   Class for loading information that is related to Histology samples.
1669 29 May 12 nicklas 21   
1669 29 May 12 nicklas 22   @author nicklas
1669 29 May 12 nicklas 23   @since 2.7
1669 29 May 12 nicklas 24 */
1669 29 May 12 nicklas 25 public class Histology 
1669 29 May 12 nicklas 26   extends ReggieItem<Sample>
1669 29 May 12 nicklas 27 {
1669 29 May 12 nicklas 28
1681 01 Jun 12 nicklas 29   /**
2190 13 Jan 14 nicklas 30     This ID is used on Histology work lists for the external ID attribute.
1681 01 Jun 12 nicklas 31   */
2190 13 Jan 14 nicklas 32   public static final String WORK_LIST_ID = "net.sf.basedb.reggie.histology.work-list";
2190 13 Jan 14 nicklas 33
1669 29 May 12 nicklas 34   /**
2242 21 Feb 14 nicklas 35     Flag value for the {@link Annotationtype#FLAG} annotation when a Histology item has failed
2242 21 Feb 14 nicklas 36     to get a GoodStain.
2242 21 Feb 14 nicklas 37     @since 2.15
2242 21 Feb 14 nicklas 38   */
2242 21 Feb 14 nicklas 39   public static final String FLAG_NO_GOOD_STAIN = "NoGoodStain";
2190 13 Jan 14 nicklas 40
2190 13 Jan 14 nicklas 41   /**
1692 08 Jun 12 nicklas 42     The number of samples per paraffin block.
1692 08 Jun 12 nicklas 43   */
1692 08 Jun 12 nicklas 44   public static final int SAMPLES_PER_BLOCK = 5;
1692 08 Jun 12 nicklas 45   
1692 08 Jun 12 nicklas 46   /**
3368 08 Jun 15 nicklas 47     Path on BASE file system to histology images.
3368 08 Jun 15 nicklas 48     @since 3.6
3368 08 Jun 15 nicklas 49   */
3368 08 Jun 15 nicklas 50   public static final String IMAGE_DIR = "/home/SCANB/HistologyImages";
5784 12 Dec 19 nicklas 51
5784 12 Dec 19 nicklas 52   /**
5784 12 Dec 19 nicklas 53     Path on BASE file system to histology images for external specimen.
5784 12 Dec 19 nicklas 54     @since 4.25
5784 12 Dec 19 nicklas 55   */
5784 12 Dec 19 nicklas 56   public static final String EXTERNAL_IMAGE_DIR = "/home/External/HistologyImages";
5784 12 Dec 19 nicklas 57     
3368 08 Jun 15 nicklas 58   
3368 08 Jun 15 nicklas 59   /**
3368 08 Jun 15 nicklas 60     Get the folder for storing image for the given sample name.
3368 08 Jun 15 nicklas 61     
3368 08 Jun 15 nicklas 62     We want to use a prefix in the BASE file system to prevent
3368 08 Jun 15 nicklas 63     several thousands of subfolders or files inside a single folder.
3368 08 Jun 15 nicklas 64     The prefix should only be used if the name folder starts with
3368 08 Jun 15 nicklas 65     digits. The first level is the first two digits and the second level is 
3368 08 Jun 15 nicklas 66     the first four digits.
3368 08 Jun 15 nicklas 67     
5784 12 Dec 19 nicklas 68     For external items the prefix is the taken from the characters before
5784 12 Dec 19 nicklas 69     the first underscore (_).    
3368 08 Jun 15 nicklas 70     
3368 08 Jun 15 nicklas 71     Examples:
5784 12 Dec 19 nicklas 72       1234567.1.his.he1 --> {IMAGE_DIR}/12/1234/
5784 12 Dec 19 nicklas 73       NN_External.his.he1 --> {EXTERNAL_IMAGE_DIR}/NN/
5784 12 Dec 19 nicklas 74       
5784 12 Dec 19 nicklas 75     @since 3.6, 4.25
3368 08 Jun 15 nicklas 76   */
3368 08 Jun 15 nicklas 77   public static String getImageFolder(String name)
3368 08 Jun 15 nicklas 78   {
5784 12 Dec 19 nicklas 79     if (Reggie.isExternalItem(name))
5784 12 Dec 19 nicklas 80     {
5784 12 Dec 19 nicklas 81       // Get characters before first _
5784 12 Dec 19 nicklas 82       return Histology.EXTERNAL_IMAGE_DIR + name.replaceFirst("^(.+?)_.*", "/$1/");
5784 12 Dec 19 nicklas 83     }
5784 12 Dec 19 nicklas 84     else
5784 12 Dec 19 nicklas 85     {
5784 12 Dec 19 nicklas 86       // If the name starts with 7 digits+'.'+at least one more digit
5784 12 Dec 19 nicklas 87       // insert prefix based on first 2+4 digits
5784 12 Dec 19 nicklas 88       return Histology.IMAGE_DIR + name.replaceFirst("^((\\d{2})\\d{2})\\d{3}\\.\\d+.*", "/$2/$1/");
5784 12 Dec 19 nicklas 89     }
3368 08 Jun 15 nicklas 90   }
3368 08 Jun 15 nicklas 91
3368 08 Jun 15 nicklas 92   
3368 08 Jun 15 nicklas 93   /**
1669 29 May 12 nicklas 94     Find Histology samples that have not yet been embedded in paraffin blocks. 
1669 29 May 12 nicklas 95     The query will look for samples with the {@link Subtype#HISTOLOGY} subtype 
1669 29 May 12 nicklas 96     that has no 'created' date. Since the Histology items are currently stored
1669 29 May 12 nicklas 97     in temporary boxes, the list is sorted by bioplate and position.
1681 01 Jun 12 nicklas 98     @param excludeWorkLists TRUE to exclude Histology items that have been picked and saved in a work list
1669 29 May 12 nicklas 99   */
1681 01 Jun 12 nicklas 100   public static List<Histology> findUnembeddedHistologyItems(DbControl dc, boolean excludeWorkLists, int maxResults)
1669 29 May 12 nicklas 101   {
1669 29 May 12 nicklas 102     List<Histology> histology = new ArrayList<Histology>();
1669 29 May 12 nicklas 103     
1669 29 May 12 nicklas 104     // Create a query that load all Histology samples without created date
1669 29 May 12 nicklas 105     ItemQuery<Sample> query = Sample.getQuery();
1669 29 May 12 nicklas 106     query.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
1669 29 May 12 nicklas 107     // Filter on Lysate subtype
1669 29 May 12 nicklas 108     Subtype.HISTOLOGY.addFilter(dc, query);
1669 29 May 12 nicklas 109     // Filter on created date == null
1669 29 May 12 nicklas 110     query.restrict(Restrictions.eq(Hql.property("ce", "eventDate"), null));
1681 01 Jun 12 nicklas 111     // Filter on not present in a work list 
1681 01 Jun 12 nicklas 112     if (excludeWorkLists)
1681 01 Jun 12 nicklas 113     {
1681 01 Jun 12 nicklas 114       ItemQuery<Sample> workQuery = Sample.getQuery();
1681 01 Jun 12 nicklas 115       workQuery.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
3342 19 May 15 nicklas 116       String subquery = "select mmb from ItemListData lst INNER JOIN lst.members mmb where lst.externalId=:externalId and lst.removed=false";
3342 19 May 15 nicklas 117       workQuery.restrict(Hql.restriction("$id NOT IN ("+subquery+")", "$"));
3342 19 May 15 nicklas 118       workQuery.setParameter("externalId", WORK_LIST_ID, Type.STRING);
1681 01 Jun 12 nicklas 119     }
1669 29 May 12 nicklas 120     
1669 29 May 12 nicklas 121     // Join the creation event and bioplate
1681 01 Jun 12 nicklas 122     query.join(Hql.innerJoin(null, "creationEvent", "ce", true));
1669 29 May 12 nicklas 123     query.join(Hql.leftJoin(null, "bioWell", "bw", null, true));
1669 29 May 12 nicklas 124     query.join(Hql.leftJoin("bw", "bioPlate", "bp", null, true));
1669 29 May 12 nicklas 125     
1682 01 Jun 12 nicklas 126     // Sort by bioplate position -- those without plate are sorted last by id
1682 01 Jun 12 nicklas 127     query.order(Orders.asc(Hql.expression("coalesce(bp.name, 'zzzz')", null)));
1669 29 May 12 nicklas 128     query.order(Orders.asc(Hql.property("bw", "row")));
1669 29 May 12 nicklas 129     query.order(Orders.asc(Hql.property("bw", "column")));
1669 29 May 12 nicklas 130     query.order(Orders.asc(Hql.property("id")));
1669 29 May 12 nicklas 131     
1669 29 May 12 nicklas 132     query.setMaxResults(maxResults);
1669 29 May 12 nicklas 133         
1669 29 May 12 nicklas 134     List<Sample> samples = query.list(dc);
1669 29 May 12 nicklas 135     for (Sample s : samples)
1669 29 May 12 nicklas 136     {
1669 29 May 12 nicklas 137       histology.add(new Histology(s));
1669 29 May 12 nicklas 138     }
1669 29 May 12 nicklas 139     return histology;
1669 29 May 12 nicklas 140   }
1669 29 May 12 nicklas 141   
1669 29 May 12 nicklas 142   /**
1826 07 Feb 13 nicklas 143     Find all histology items by case name. This method will check for {@link Subtype#HISTOLOGY} samples 
1826 07 Feb 13 nicklas 144     with a name matching the case name (eg. xxx.his).
1826 07 Feb 13 nicklas 145     @since 2.11
1826 07 Feb 13 nicklas 146   */
1826 07 Feb 13 nicklas 147   public static List<Histology> findByCaseName(DbControl dc, String name)
1831 08 Feb 13 nicklas 148   {    
1826 07 Feb 13 nicklas 149     // Get rid of suffixes in the name (eg. 'C' which is used for pre-neoadjuvant forms)
1826 07 Feb 13 nicklas 150     if (name.length() > 7) name = name.substring(0, 7);    
1826 07 Feb 13 nicklas 151     
1826 07 Feb 13 nicklas 152     // Look for a blood case with the given name 
1826 07 Feb 13 nicklas 153     ItemQuery<Sample> histologyQuery = Sample.getQuery();
1826 07 Feb 13 nicklas 154     Subtype.HISTOLOGY.addFilter(dc, histologyQuery);
2917 11 Nov 14 nicklas 155     histologyQuery.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
1831 08 Feb 13 nicklas 156     histologyQuery.restrict(Restrictions.like(Hql.property("name"), Expressions.parameter("name", name+".%", Type.STRING)));
2917 11 Nov 14 nicklas 157     histologyQuery.order(Orders.asc(Hql.property("name")));
2917 11 Nov 14 nicklas 158
1826 07 Feb 13 nicklas 159     List<Sample> tmp = histologyQuery.list(dc);
1826 07 Feb 13 nicklas 160     List<Histology> histology = new ArrayList<Histology>(tmp.size());
1826 07 Feb 13 nicklas 161     for (Sample s : tmp)
1826 07 Feb 13 nicklas 162     {
1826 07 Feb 13 nicklas 163       histology.add(new Histology(s));
1826 07 Feb 13 nicklas 164     }
1826 07 Feb 13 nicklas 165     return histology;
1826 07 Feb 13 nicklas 166   }
1826 07 Feb 13 nicklas 167
1826 07 Feb 13 nicklas 168   
1826 07 Feb 13 nicklas 169   /**
1681 01 Jun 12 nicklas 170     Get a Histology when the id is known.
1669 29 May 12 nicklas 171   */
1669 29 May 12 nicklas 172   public static Histology getById(DbControl dc, int id)
1669 29 May 12 nicklas 173   {
1669 29 May 12 nicklas 174     return new Histology(Sample.getById(dc, id));
1669 29 May 12 nicklas 175   }
1669 29 May 12 nicklas 176   
1669 29 May 12 nicklas 177   
1669 29 May 12 nicklas 178   private JSONObject jsonWell;
1669 29 May 12 nicklas 179   
1669 29 May 12 nicklas 180   private Histology(Sample sample)
1669 29 May 12 nicklas 181   {
1669 29 May 12 nicklas 182     super(sample);
1669 29 May 12 nicklas 183
1669 29 May 12 nicklas 184   }  
1669 29 May 12 nicklas 185   
1669 29 May 12 nicklas 186   
1669 29 May 12 nicklas 187   /**
1669 29 May 12 nicklas 188     Get the real sample that represents this Histology item in BASE.
1669 29 May 12 nicklas 189   */
1669 29 May 12 nicklas 190   public Sample getSample()
1669 29 May 12 nicklas 191   {
1669 29 May 12 nicklas 192     return getItem();
1669 29 May 12 nicklas 193   }
1669 29 May 12 nicklas 194
1669 29 May 12 nicklas 195   @Override
1669 29 May 12 nicklas 196   protected void initJSON(JSONObject json) 
1669 29 May 12 nicklas 197   {
1669 29 May 12 nicklas 198     super.initJSON(json);
1669 29 May 12 nicklas 199     if (jsonWell != null) json.put("bioWell", jsonWell);
1669 29 May 12 nicklas 200     
1669 29 May 12 nicklas 201   }
1669 29 May 12 nicklas 202
1669 29 May 12 nicklas 203   /**
1669 29 May 12 nicklas 204     Load information about the plate and location the current RNA
1669 29 May 12 nicklas 205     is located on.
1669 29 May 12 nicklas 206   */
1669 29 May 12 nicklas 207   public JSONObject loadBioPlateLocation()
1669 29 May 12 nicklas 208   {
1826 07 Feb 13 nicklas 209     if (jsonWell == null)
1669 29 May 12 nicklas 210     {
2134 11 Nov 13 nicklas 211       jsonWell = JsonUtil.getBioWellAsJSON(getItem().getBioWell(), true);
1669 29 May 12 nicklas 212     }
1669 29 May 12 nicklas 213     return jsonWell;
1669 29 May 12 nicklas 214   }
1826 07 Feb 13 nicklas 215
1669 29 May 12 nicklas 216   
1669 29 May 12 nicklas 217 }