extensions/net.sf.basedb.meludi/trunk/src/net/sf/basedb/meludi/dao/SpecimenTube.java

Code
Comments
Other
Rev Date Author Line
2933 14 Nov 14 olle 1 package net.sf.basedb.meludi.dao;
2933 14 Nov 14 olle 2
2933 14 Nov 14 olle 3 import java.util.ArrayList;
2933 14 Nov 14 olle 4 import java.util.List;
2933 14 Nov 14 olle 5
5060 29 Oct 18 olle 6 import net.sf.basedb.core.AnnotationSimpleRestriction;
5060 29 Oct 18 olle 7 import net.sf.basedb.core.AnnotationType;
2933 14 Nov 14 olle 8 import net.sf.basedb.core.BioWell;
2933 14 Nov 14 olle 9 import net.sf.basedb.core.DbControl;
2933 14 Nov 14 olle 10 import net.sf.basedb.core.Include;
2933 14 Nov 14 olle 11 import net.sf.basedb.core.InvalidDataException;
2933 14 Nov 14 olle 12 import net.sf.basedb.core.ItemQuery;
2933 14 Nov 14 olle 13 import net.sf.basedb.core.MeasuredBioMaterial;
5060 29 Oct 18 olle 14 import net.sf.basedb.core.Operator;
2933 14 Nov 14 olle 15 import net.sf.basedb.core.Sample;
2933 14 Nov 14 olle 16 import net.sf.basedb.core.Type;
2933 14 Nov 14 olle 17 import net.sf.basedb.core.query.Expressions;
2933 14 Nov 14 olle 18 import net.sf.basedb.core.query.Hql;
2933 14 Nov 14 olle 19 import net.sf.basedb.core.query.Orders;
2933 14 Nov 14 olle 20 import net.sf.basedb.core.query.Restrictions;
2933 14 Nov 14 olle 21 import net.sf.basedb.meludi.JsonUtil;
2933 14 Nov 14 olle 22 import net.sf.basedb.meludi.Meludi;
2933 14 Nov 14 olle 23
2933 14 Nov 14 olle 24 import org.json.simple.JSONObject;
2933 14 Nov 14 olle 25
2933 14 Nov 14 olle 26 /**
2933 14 Nov 14 olle 27   Class for loading information that is related to specimen tubes.
2933 14 Nov 14 olle 28   
2966 20 Nov 14 olle 29   @author olle
2966 20 Nov 14 olle 30   @since 1.0
2933 14 Nov 14 olle 31 */
2933 14 Nov 14 olle 32 public class SpecimenTube 
2933 14 Nov 14 olle 33   extends MeludiItem<Sample>
2933 14 Nov 14 olle 34 {
2933 14 Nov 14 olle 35   /**
2933 14 Nov 14 olle 36     Find all specimen tubes associated with a given case. This method can either
2933 14 Nov 14 olle 37     load all (including merged) specimen tubes, or only specimen tubes that
2933 14 Nov 14 olle 38     are really part of the original case.
2933 14 Nov 14 olle 39   */
2966 20 Nov 14 olle 40   public static List<SpecimenTube> findByCase(DbControl dc, Case theCase, String originalCaseName)
2933 14 Nov 14 olle 41   {
2933 14 Nov 14 olle 42     ItemQuery<Sample> specimenQuery = theCase.getSample().getChildSamples();
2933 14 Nov 14 olle 43     Subtype.SPECIMEN.addFilter(dc, specimenQuery);
2933 14 Nov 14 olle 44     if (originalCaseName != null)
2933 14 Nov 14 olle 45     {
3423 24 Jun 15 olle 46       // Remove suffix starting with dot "."
3423 24 Jun 15 olle 47       int firstDotIndex = originalCaseName.indexOf(".");
3423 24 Jun 15 olle 48       if (firstDotIndex >= 0)
2933 14 Nov 14 olle 49       {
3423 24 Jun 15 olle 50         originalCaseName = originalCaseName.substring(0, firstDotIndex);
2933 14 Nov 14 olle 51       }
2933 14 Nov 14 olle 52       specimenQuery.restrict(Restrictions.like(Hql.property("name"), Expressions.parameter("name", originalCaseName + ".%", Type.STRING)));
2933 14 Nov 14 olle 53     }
2933 14 Nov 14 olle 54     specimenQuery.order(Orders.asc(Hql.property("name")));
2933 14 Nov 14 olle 55     specimenQuery.include(Include.ALL);
2933 14 Nov 14 olle 56     List<SpecimenTube> tubes = new ArrayList<SpecimenTube>();
2933 14 Nov 14 olle 57     for (Sample s : specimenQuery.list(dc))
2933 14 Nov 14 olle 58     {
2933 14 Nov 14 olle 59       tubes.add(new SpecimenTube(s));
2933 14 Nov 14 olle 60     }
2933 14 Nov 14 olle 61     return tubes;
2933 14 Nov 14 olle 62   }
2966 20 Nov 14 olle 63
2933 14 Nov 14 olle 64   /**
3418 24 Jun 15 olle 65     Find all specimen tubes that are linked by base name (name before first dot ".")
3418 24 Jun 15 olle 66     to a given name. The specimen tubes start with the same name as the argument
3418 24 Jun 15 olle 67     name and then have a suffix with a dot plus a running number. Eg. xxx.1, xxx.2, etc.
3418 24 Jun 15 olle 68   */
3418 24 Jun 15 olle 69   public static List<SpecimenTube> findByBaseName(DbControl dc, String name)
3418 24 Jun 15 olle 70   {
3418 24 Jun 15 olle 71     ItemQuery<Sample> specimenQuery = Sample.getQuery();
3418 24 Jun 15 olle 72     Subtype.SPECIMEN.addFilter(dc, specimenQuery);
3418 24 Jun 15 olle 73     specimenQuery.restrict(Restrictions.like(Hql.property("name"), Expressions.parameter("name", name + ".%", Type.STRING)));
3418 24 Jun 15 olle 74     specimenQuery.order(Orders.asc(Hql.property("name")));
3418 24 Jun 15 olle 75     specimenQuery.include(Include.ALL);
3418 24 Jun 15 olle 76
3418 24 Jun 15 olle 77     List<SpecimenTube> tubes = new ArrayList<SpecimenTube>();
3418 24 Jun 15 olle 78     for (Sample s : specimenQuery.list(dc))
3418 24 Jun 15 olle 79     {    
3418 24 Jun 15 olle 80       tubes.add(new SpecimenTube(s));
3418 24 Jun 15 olle 81     }
3418 24 Jun 15 olle 82     return tubes;
3418 24 Jun 15 olle 83   }
3418 24 Jun 15 olle 84
3418 24 Jun 15 olle 85   /**
2933 14 Nov 14 olle 86     Find all specimen tubes that are linked by name to a given case name. The assumption
2933 14 Nov 14 olle 87     is that the case has not yet been registered and we are trying to find all specimen
2933 14 Nov 14 olle 88     tubes that are associated with it. The specimen tubes start with the same name as the
2933 14 Nov 14 olle 89     case and then have a suffix with a dot plus a running number. Eg. xxx.1, xxx.2, etc.
2933 14 Nov 14 olle 90   */
2966 20 Nov 14 olle 91   public static List<SpecimenTube> findByCaseName(DbControl dc, String name)
2933 14 Nov 14 olle 92   {
3423 24 Jun 15 olle 93     // Remove suffix starting with dot "."
3423 24 Jun 15 olle 94     int firstDotIndex = name.indexOf(".");
3423 24 Jun 15 olle 95     if (firstDotIndex >= 0)
2933 14 Nov 14 olle 96     {
3423 24 Jun 15 olle 97       name = name.substring(0, firstDotIndex);
2933 14 Nov 14 olle 98     }
2966 20 Nov 14 olle 99   
2933 14 Nov 14 olle 100     ItemQuery<Sample> specimenQuery = Sample.getQuery();
2933 14 Nov 14 olle 101     Subtype.SPECIMEN.addFilter(dc, specimenQuery);
2933 14 Nov 14 olle 102     specimenQuery.restrict(Restrictions.like(Hql.property("name"), Expressions.parameter("name", name + ".%", Type.STRING)));
2933 14 Nov 14 olle 103     specimenQuery.order(Orders.asc(Hql.property("name")));
2933 14 Nov 14 olle 104     specimenQuery.include(Include.ALL);
2966 20 Nov 14 olle 105   
2933 14 Nov 14 olle 106     List<SpecimenTube> tubes = new ArrayList<SpecimenTube>();
2933 14 Nov 14 olle 107     for (Sample s : specimenQuery.list(dc))
2933 14 Nov 14 olle 108     {    
2933 14 Nov 14 olle 109       tubes.add(new SpecimenTube(s));
2933 14 Nov 14 olle 110     }
5060 29 Oct 18 olle 111
5060 29 Oct 18 olle 112     // If no specimen tubes found, check if case identified via annotation CASE_ID
5060 29 Oct 18 olle 113     if (tubes.size() == 0)
5060 29 Oct 18 olle 114     {
5060 29 Oct 18 olle 115       String caseId = name;
5060 29 Oct 18 olle 116       AnnotationType caseIdType = Annotationtype.CASE_ID.load(dc);
5060 29 Oct 18 olle 117       specimenQuery = Sample.getQuery();
5060 29 Oct 18 olle 118       Subtype.SPECIMEN.addFilter(dc, specimenQuery);
5060 29 Oct 18 olle 119       specimenQuery.restrict(new AnnotationSimpleRestriction(null, caseIdType, Operator.EQ, caseId, true, false));
5060 29 Oct 18 olle 120       specimenQuery.setIncludes(Meludi.INCLUDE_IN_CURRENT_PROJECT);
5060 29 Oct 18 olle 121       specimenQuery.order(Orders.asc(Hql.property("name")));
5060 29 Oct 18 olle 122
5060 29 Oct 18 olle 123       for (Sample s : specimenQuery.list(dc))
5060 29 Oct 18 olle 124       {    
5060 29 Oct 18 olle 125         tubes.add(new SpecimenTube(s));
5060 29 Oct 18 olle 126       }
5060 29 Oct 18 olle 127     }
2933 14 Nov 14 olle 128     return tubes;
2933 14 Nov 14 olle 129   }
2966 20 Nov 14 olle 130
2933 14 Nov 14 olle 131   /**
2933 14 Nov 14 olle 132      Find a specimen tube with the given name.
2933 14 Nov 14 olle 133      @return A specimen tube, or null if not found
2933 14 Nov 14 olle 134   */
2933 14 Nov 14 olle 135   public static SpecimenTube findByTubeName(DbControl dc, String tubeName)
2933 14 Nov 14 olle 136   {
2933 14 Nov 14 olle 137     SpecimenTube tube = null;
2933 14 Nov 14 olle 138     
2933 14 Nov 14 olle 139     ItemQuery<Sample> tubeQuery = Sample.getQuery();
2933 14 Nov 14 olle 140     Subtype.SPECIMEN.addFilter(dc, tubeQuery);
2933 14 Nov 14 olle 141     tubeQuery.restrict(Restrictions.like(Hql.property("name"), Expressions.string(tubeName)));
2933 14 Nov 14 olle 142     tubeQuery.order(Orders.desc(Hql.property("name")));        
2933 14 Nov 14 olle 143     tubeQuery.include(Include.ALL);
2933 14 Nov 14 olle 144     
2933 14 Nov 14 olle 145     List<Sample> tubes = tubeQuery.list(dc);
2933 14 Nov 14 olle 146     if (tubes.size() > 1)
2933 14 Nov 14 olle 147     {
3344 19 May 15 olle 148       String sampleIds = "";
3344 19 May 15 olle 149       for (int i = 0; i < tubes.size(); i++)
3344 19 May 15 olle 150       {
3344 19 May 15 olle 151         SpecimenTube tmpSpec = new SpecimenTube(tubes.get(i));
3344 19 May 15 olle 152         int id = tmpSpec.getItem().getId();
3344 19 May 15 olle 153         if (!sampleIds.equals(""))
3344 19 May 15 olle 154         {
3344 19 May 15 olle 155           sampleIds += ", ";
3344 19 May 15 olle 156         }
3344 19 May 15 olle 157         sampleIds += id;
3344 19 May 15 olle 158       }
2933 14 Nov 14 olle 159       throw new InvalidDataException(
2933 14 Nov 14 olle 160           "More than one specimen tube with the name " + tubeName + " was found. " +
3344 19 May 15 olle 161           " The ID values are " + sampleIds + ". " +
2933 14 Nov 14 olle 162           "This wizard can't be used until that is corrected.");
2933 14 Nov 14 olle 163     }
2933 14 Nov 14 olle 164     if (tubes.size() == 1)
2933 14 Nov 14 olle 165     {
2933 14 Nov 14 olle 166       tube = new SpecimenTube(tubes.get(0));
2933 14 Nov 14 olle 167     }
2933 14 Nov 14 olle 168     return tube;
2933 14 Nov 14 olle 169   }
2933 14 Nov 14 olle 170   
2933 14 Nov 14 olle 171   /**
2933 14 Nov 14 olle 172     Find unpartitioned specimen tubes. A specimen tube that has not been partitioned
2933 14 Nov 14 olle 173     have a 'null' {@link MeasuredBioMaterial#getOriginalQuantity()}.
2933 14 Nov 14 olle 174      @since 1.6
2933 14 Nov 14 olle 175   */
2933 14 Nov 14 olle 176   public static List<SpecimenTube> findUnPartitionedTubes(DbControl dc)
2933 14 Nov 14 olle 177   {
2933 14 Nov 14 olle 178     List<SpecimenTube> unPartitionedTubes = new ArrayList<SpecimenTube>();
2933 14 Nov 14 olle 179     
2933 14 Nov 14 olle 180     ItemQuery<Sample> tubeQuery = Sample.getQuery();
2933 14 Nov 14 olle 181     Subtype.SPECIMEN.addFilter(dc, tubeQuery);
2933 14 Nov 14 olle 182     tubeQuery.restrict(Restrictions.eq(Hql.property("originalQuantity"), null));
2933 14 Nov 14 olle 183     tubeQuery.order(Orders.desc(Hql.property("id")));
2933 14 Nov 14 olle 184     tubeQuery.setIncludes(Meludi.INCLUDE_IN_CURRENT_PROJECT);
2933 14 Nov 14 olle 185     List<Sample> tubes = tubeQuery.list(dc);
2933 14 Nov 14 olle 186     for (Sample tube : tubes)
2933 14 Nov 14 olle 187     {
2933 14 Nov 14 olle 188       BioWell well = tube.getBioWell();
3176 06 Mar 15 olle 189       String boxNameSuffix = null;
2933 14 Nov 14 olle 190
2933 14 Nov 14 olle 191       if (well != null)
2933 14 Nov 14 olle 192       {
3176 06 Mar 15 olle 193         int plateNameLen = well.getPlate().getName().length();
3176 06 Mar 15 olle 194         boxNameSuffix = well.getPlate().getName().substring(plateNameLen - 3);        
2933 14 Nov 14 olle 195       }
3176 06 Mar 15 olle 196       if (tube.countExtracts() == 0 && "_sp".equals(boxNameSuffix))
2933 14 Nov 14 olle 197       {
2933 14 Nov 14 olle 198         unPartitionedTubes.add(new SpecimenTube(tube));
2933 14 Nov 14 olle 199       }
2933 14 Nov 14 olle 200     }
2933 14 Nov 14 olle 201     return unPartitionedTubes;
2933 14 Nov 14 olle 202   }
2933 14 Nov 14 olle 203
3176 06 Mar 15 olle 204   /**
3176 06 Mar 15 olle 205     Find unprocessed specimen tubes. A specimen tube that has not been processed
3292 30 Apr 15 olle 206     has a 'null' {@link MeasuredBioMaterial#getOriginalQuantity()}.
4246 21 Nov 16 olle 207     Only specimens with created extracts will be included.
4246 21 Nov 16 olle 208
4246 21 Nov 16 olle 209     @param dc DbControl The DbControl to use.
4246 21 Nov 16 olle 210     @return List<SpecimenTube> A list of SpecimenTube items for unprocessed specimen tubes.
4246 21 Nov 16 olle 211     @since 1.2
4246 21 Nov 16 olle 212   */
3176 06 Mar 15 olle 213   public static List<SpecimenTube> findUnProcessedTubes(DbControl dc)
3176 06 Mar 15 olle 214   {
4246 21 Nov 16 olle 215     Boolean withExtracts = true;
4246 21 Nov 16 olle 216     return findUnProcessedTubes(dc, withExtracts);
4246 21 Nov 16 olle 217   }
4246 21 Nov 16 olle 218
4246 21 Nov 16 olle 219   /**
4246 21 Nov 16 olle 220     Find unprocessed specimen tubes. A specimen tube that has not been processed
4246 21 Nov 16 olle 221     has a 'null' {@link MeasuredBioMaterial#getOriginalQuantity()}.
4246 21 Nov 16 olle 222     Specimens with created extracts will be included, if value of argument
4246 21 Nov 16 olle 223     `withExtracts` is `true`, otherwise specimens without extracts.
4246 21 Nov 16 olle 224     
4246 21 Nov 16 olle 225     @param dc DbControl The DbControl to use.
4246 21 Nov 16 olle 226     @param withExtracts Boolean Flag indicating if specimens with extracts should be included.
4246 21 Nov 16 olle 227     @return List<SpecimenTube> A list of SpecimenTube items for unprocessed specimen tubes.
4246 21 Nov 16 olle 228      @since 1.2
4246 21 Nov 16 olle 229   */
4246 21 Nov 16 olle 230   public static List<SpecimenTube> findUnProcessedTubes(DbControl dc, Boolean withExtracts)
4246 21 Nov 16 olle 231   {
4246 21 Nov 16 olle 232     if (withExtracts == null)
4246 21 Nov 16 olle 233     {
4246 21 Nov 16 olle 234       withExtracts = true;
4246 21 Nov 16 olle 235     }
3176 06 Mar 15 olle 236     List<SpecimenTube> unProcessedTubes = new ArrayList<SpecimenTube>();
3176 06 Mar 15 olle 237   
3176 06 Mar 15 olle 238     ItemQuery<Sample> tubeQuery = Sample.getQuery();
3176 06 Mar 15 olle 239     Subtype.SPECIMEN.addFilter(dc, tubeQuery);
3176 06 Mar 15 olle 240     tubeQuery.restrict(Restrictions.eq(Hql.property("originalQuantity"), null));
3176 06 Mar 15 olle 241     tubeQuery.order(Orders.asc(Hql.property("name")));
3176 06 Mar 15 olle 242     tubeQuery.setIncludes(Meludi.INCLUDE_IN_CURRENT_PROJECT);
3176 06 Mar 15 olle 243     List<Sample> tubes = tubeQuery.list(dc);
3176 06 Mar 15 olle 244     for (Sample tube : tubes)
3176 06 Mar 15 olle 245     {
5068 31 Oct 18 olle 246       // Extract items are created at specimen registration in Ticket #768 (change set 3276)
4246 21 Nov 16 olle 247       if (withExtracts)
3176 06 Mar 15 olle 248       {
4246 21 Nov 16 olle 249         // Creation of extracts from specimen are optional; only include specimens with extracts
4246 21 Nov 16 olle 250         if (tube.countExtracts() > 0)
4246 21 Nov 16 olle 251         {
4246 21 Nov 16 olle 252           unProcessedTubes.add(new SpecimenTube(tube));
4246 21 Nov 16 olle 253         }        
3176 06 Mar 15 olle 254       }
4246 21 Nov 16 olle 255       else
4246 21 Nov 16 olle 256       {
4246 21 Nov 16 olle 257         if (tube.countExtracts() == 0)
4246 21 Nov 16 olle 258         {
4246 21 Nov 16 olle 259           unProcessedTubes.add(new SpecimenTube(tube));
4246 21 Nov 16 olle 260         }        
4246 21 Nov 16 olle 261       }
3176 06 Mar 15 olle 262     }
3176 06 Mar 15 olle 263     return unProcessedTubes;
3176 06 Mar 15 olle 264   }
3176 06 Mar 15 olle 265
3176 06 Mar 15 olle 266   /**
3176 06 Mar 15 olle 267     Find processed specimen tubes. A specimen tube that has been processed
3176 06 Mar 15 olle 268     has extracts.
3176 06 Mar 15 olle 269     @since 1.2
3176 06 Mar 15 olle 270   */
3176 06 Mar 15 olle 271   public static List<SpecimenTube> findProcessedTubes(DbControl dc)
3176 06 Mar 15 olle 272   {
3176 06 Mar 15 olle 273     List<SpecimenTube> processedTubes = new ArrayList<SpecimenTube>();
3176 06 Mar 15 olle 274
3176 06 Mar 15 olle 275     ItemQuery<Sample> tubeQuery = Sample.getQuery();
3176 06 Mar 15 olle 276     Subtype.SPECIMEN.addFilter(dc, tubeQuery);
3176 06 Mar 15 olle 277     //tubeQuery.restrict(Restrictions.neq(Hql.property("originalQuantity"), null));
3176 06 Mar 15 olle 278     tubeQuery.order(Orders.asc(Hql.property("name")));
3176 06 Mar 15 olle 279     tubeQuery.setIncludes(Meludi.INCLUDE_IN_CURRENT_PROJECT);
3176 06 Mar 15 olle 280     List<Sample> tubes = tubeQuery.list(dc);
3176 06 Mar 15 olle 281     for (Sample tube : tubes)
3176 06 Mar 15 olle 282     {
3176 06 Mar 15 olle 283       if (tube.countExtracts() > 0)
3176 06 Mar 15 olle 284       {
3176 06 Mar 15 olle 285         processedTubes.add(new SpecimenTube(tube));
3176 06 Mar 15 olle 286       }
3176 06 Mar 15 olle 287     }
3176 06 Mar 15 olle 288     return processedTubes;
3176 06 Mar 15 olle 289   }
3176 06 Mar 15 olle 290
2933 14 Nov 14 olle 291   private JSONObject jsonWell;
2933 14 Nov 14 olle 292   
2933 14 Nov 14 olle 293   private SpecimenTube(Sample sample)
2933 14 Nov 14 olle 294   {
2933 14 Nov 14 olle 295     super(sample);
2933 14 Nov 14 olle 296   }  
2933 14 Nov 14 olle 297   
2933 14 Nov 14 olle 298   
2933 14 Nov 14 olle 299   /**
2933 14 Nov 14 olle 300     Get the real sample that represents this speciment tube in BASE.
2933 14 Nov 14 olle 301   */
2933 14 Nov 14 olle 302   public Sample getSample()
2933 14 Nov 14 olle 303   {
2933 14 Nov 14 olle 304     return getItem();
2933 14 Nov 14 olle 305   }
2933 14 Nov 14 olle 306
2933 14 Nov 14 olle 307   @SuppressWarnings("unchecked")
2933 14 Nov 14 olle 308   @Override
2933 14 Nov 14 olle 309   protected void initJSON(JSONObject json)
2933 14 Nov 14 olle 310   {
2933 14 Nov 14 olle 311     super.initJSON(json);
2933 14 Nov 14 olle 312     if (jsonWell != null) json.put("bioWell", jsonWell);
2933 14 Nov 14 olle 313   }
2933 14 Nov 14 olle 314   
2933 14 Nov 14 olle 315   /**
2933 14 Nov 14 olle 316     Load information about the plate and location the current RNA
2933 14 Nov 14 olle 317     is located on.
2933 14 Nov 14 olle 318   */
2933 14 Nov 14 olle 319   public JSONObject loadBioPlateLocation()
2933 14 Nov 14 olle 320   {
2933 14 Nov 14 olle 321     if (jsonWell == null)
2933 14 Nov 14 olle 322     {
2933 14 Nov 14 olle 323       jsonWell = JsonUtil.getBioWellAsJSON(getItem().getBioWell(), true);
2933 14 Nov 14 olle 324     }
2933 14 Nov 14 olle 325     return jsonWell;
2933 14 Nov 14 olle 326   }
2933 14 Nov 14 olle 327
2933 14 Nov 14 olle 328 }