extensions/net.sf.basedb.meludi/trunk/src/net/sf/basedb/meludi/dao/ReactionPlate.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
2933 14 Nov 14 olle 6 import org.json.simple.JSONArray;
2933 14 Nov 14 olle 7 import org.json.simple.JSONObject;
2933 14 Nov 14 olle 8
2933 14 Nov 14 olle 9 import net.sf.basedb.core.AnnotationType;
2933 14 Nov 14 olle 10 import net.sf.basedb.core.BioMaterial;
2933 14 Nov 14 olle 11 import net.sf.basedb.core.BioPlate;
2933 14 Nov 14 olle 12 import net.sf.basedb.core.BioPlateEvent;
2933 14 Nov 14 olle 13 import net.sf.basedb.core.BioPlateType;
2933 14 Nov 14 olle 14 import net.sf.basedb.core.BioWell;
2933 14 Nov 14 olle 15 import net.sf.basedb.core.DbControl;
2933 14 Nov 14 olle 16 import net.sf.basedb.core.HasAnnotationRestriction;
2933 14 Nov 14 olle 17 import net.sf.basedb.core.Include;
2933 14 Nov 14 olle 18 import net.sf.basedb.core.InvalidDataException;
2933 14 Nov 14 olle 19 import net.sf.basedb.core.Item;
2933 14 Nov 14 olle 20 import net.sf.basedb.core.ItemQuery;
2933 14 Nov 14 olle 21 import net.sf.basedb.core.ItemSubtype;
2933 14 Nov 14 olle 22 import net.sf.basedb.core.MeasuredBioMaterial;
2933 14 Nov 14 olle 23 import net.sf.basedb.core.PlateGeometry;
2933 14 Nov 14 olle 24 import net.sf.basedb.core.SystemItems;
2933 14 Nov 14 olle 25 import net.sf.basedb.core.Type;
2933 14 Nov 14 olle 26 import net.sf.basedb.core.query.Expressions;
2933 14 Nov 14 olle 27 import net.sf.basedb.core.query.Hql;
2933 14 Nov 14 olle 28 import net.sf.basedb.core.query.Orders;
2933 14 Nov 14 olle 29 import net.sf.basedb.core.query.Restrictions;
2933 14 Nov 14 olle 30 import net.sf.basedb.meludi.JsonUtil;
2933 14 Nov 14 olle 31 import net.sf.basedb.meludi.Meludi;
2933 14 Nov 14 olle 32 import net.sf.basedb.meludi.converter.IdentityConverter;
2933 14 Nov 14 olle 33 import net.sf.basedb.meludi.converter.ValueConverter;
2933 14 Nov 14 olle 34
2933 14 Nov 14 olle 35 /**
2933 14 Nov 14 olle 36   Class for loading information that is related to reaction bioplates.
2933 14 Nov 14 olle 37   
2933 14 Nov 14 olle 38   @author nicklas
2933 14 Nov 14 olle 39   @since 2.4
2933 14 Nov 14 olle 40 */
2933 14 Nov 14 olle 41 public class ReactionPlate
2933 14 Nov 14 olle 42   extends MeludiItem<BioPlate>
2933 14 Nov 14 olle 43 {
2933 14 Nov 14 olle 44
2933 14 Nov 14 olle 45   /**
2933 14 Nov 14 olle 46     Value for the {@link Annotationtype#PLATE_PROCESS_RESULT} annotation 
2933 14 Nov 14 olle 47     when the processing of the bioplate was successful.
2933 14 Nov 14 olle 48     @since 2.12
2933 14 Nov 14 olle 49   */
2933 14 Nov 14 olle 50   public static final String PROCESS_SUCCESSFUL = "Successful";
2933 14 Nov 14 olle 51   
2933 14 Nov 14 olle 52   /**
2933 14 Nov 14 olle 53     Value for the {@link Annotationtype#PLATE_PROCESS_RESULT} annotation when
2933 14 Nov 14 olle 54     the processing of the entire bioplate failed.
2933 14 Nov 14 olle 55     @since 2.12
2933 14 Nov 14 olle 56   */
2933 14 Nov 14 olle 57   public static final String PROCESS_FAILED = "Failed";
2933 14 Nov 14 olle 58   
2933 14 Nov 14 olle 59   /**
2933 14 Nov 14 olle 60     Find all active reaction plates which can hold biomaterial items of the given 
2933 14 Nov 14 olle 61     subtype. Active plates are plates that:
2933 14 Nov 14 olle 62     
2933 14 Nov 14 olle 63     <ul>
2933 14 Nov 14 olle 64     <li>Are not marked as destroyed
2933 14 Nov 14 olle 65     <li>Have at least the specified number of free wells
2933 14 Nov 14 olle 66     <li>Have no value set for the 'run date' annotation
2933 14 Nov 14 olle 67     </ul>
2933 14 Nov 14 olle 68     
2933 14 Nov 14 olle 69     @param dc
2933 14 Nov 14 olle 70     @param bioPlateType The required bioplate type, or null to not filter on bioplate type
2933 14 Nov 14 olle 71     @param subtype A biomaterial subtype, or null to not filter on subtype
2933 14 Nov 14 olle 72     @param runDateAnnotation The name of an annotation type, or null to not filter on annotation
2933 14 Nov 14 olle 73     @return
2933 14 Nov 14 olle 74   */
2933 14 Nov 14 olle 75   public static List<ReactionPlate> findActiveByBioMaterialSubtype(DbControl dc, 
2933 14 Nov 14 olle 76     BioplateType bioPlateType, Subtype subtype, int numFreeWells, Annotationtype runDateAnnotation)
2933 14 Nov 14 olle 77   {
2933 14 Nov 14 olle 78     ItemQuery<BioPlate> query = BioPlate.getQuery();
2933 14 Nov 14 olle 79     query.setIncludes(Meludi.INCLUDE_IN_CURRENT_PROJECT);
2933 14 Nov 14 olle 80     if (subtype != null || bioPlateType != null)
2933 14 Nov 14 olle 81     {
2933 14 Nov 14 olle 82       query.join(Hql.innerJoin("bioPlateType", "bpt"));
2933 14 Nov 14 olle 83       if (bioPlateType != null) bioPlateType.addFilter(dc, query, false);
2933 14 Nov 14 olle 84       if (subtype != null) subtype.addFilter(dc, query, "bpt");
2933 14 Nov 14 olle 85     }
2933 14 Nov 14 olle 86     
2933 14 Nov 14 olle 87     query.restrict(Restrictions.eq(Hql.property("destroyed"), Expressions.parameter("destroyed", false, Type.BOOLEAN)));
2933 14 Nov 14 olle 88     query.restrict(Restrictions.gteq(Hql.property("freeWells"), Expressions.integer(numFreeWells)));
2933 14 Nov 14 olle 89     if (runDateAnnotation != null)
2933 14 Nov 14 olle 90     {
2933 14 Nov 14 olle 91       AnnotationType at = runDateAnnotation.load(dc);
3385 10 Jun 15 olle 92       query.restrict(new HasAnnotationRestriction(null, at, false, true, false));
2933 14 Nov 14 olle 93     }
2933 14 Nov 14 olle 94     query.order(Orders.asc(Hql.property("name")));
2933 14 Nov 14 olle 95     
2933 14 Nov 14 olle 96     List<BioPlate> tmp = query.list(dc);
2933 14 Nov 14 olle 97     List<ReactionPlate> plates = new ArrayList<ReactionPlate>(tmp.size());
2933 14 Nov 14 olle 98     for (BioPlate plate : tmp)
2933 14 Nov 14 olle 99     {
2933 14 Nov 14 olle 100       plates.add(new ReactionPlate(plate, bioPlateType));
2933 14 Nov 14 olle 101     }
2933 14 Nov 14 olle 102     return plates;
2933 14 Nov 14 olle 103   }
2933 14 Nov 14 olle 104   
2933 14 Nov 14 olle 105   /**
3180 17 Mar 15 olle 106     Find all active reaction plates which can hold biomaterial items of the given 
3180 17 Mar 15 olle 107     subtype and have names starting with an optional prefix. Active plates are plates that:
3180 17 Mar 15 olle 108   
3180 17 Mar 15 olle 109     <ul>
3180 17 Mar 15 olle 110     <li>Do not have e created date set
3180 17 Mar 15 olle 111     <li>Are not marked as destroyed
3180 17 Mar 15 olle 112     <li>Have at least the specified number of free wells
3180 17 Mar 15 olle 113     <li>Have no value set for the 'run date' annotation
3180 17 Mar 15 olle 114     </ul>
3180 17 Mar 15 olle 115   
3180 17 Mar 15 olle 116     @param dc
3180 17 Mar 15 olle 117     @param bioPlateType The required bioplate type, or null to not filter on bioplate type
3180 17 Mar 15 olle 118     @param subtype A biomaterial subtype, or null to not filter on subtype
3180 17 Mar 15 olle 119     @param prefix Optional prefix in plate name
3180 17 Mar 15 olle 120     @param numFreeWells Minimum number of free wells
3180 17 Mar 15 olle 121     @param runDateAnnotation The name of an annotation type, or null to not filter on annotation
3180 17 Mar 15 olle 122     @return
3180 17 Mar 15 olle 123   */
3180 17 Mar 15 olle 124   public static List<ReactionPlate> findActiveByBioPlateType(DbControl dc, 
3180 17 Mar 15 olle 125     BioplateType bioPlateType, Subtype subtype, String prefix, int numFreeWells, Annotationtype runDateAnnotation)
3180 17 Mar 15 olle 126   {
3180 17 Mar 15 olle 127     ItemQuery<BioPlate> query = BioPlate.getQuery();
3180 17 Mar 15 olle 128     query.setIncludes(Meludi.INCLUDE_IN_CURRENT_PROJECT);
3180 17 Mar 15 olle 129     if (subtype != null || bioPlateType != null)
3180 17 Mar 15 olle 130     {
3180 17 Mar 15 olle 131       query.join(Hql.innerJoin("bioPlateType", "bpt"));
3180 17 Mar 15 olle 132       if (bioPlateType != null) bioPlateType.addFilter(dc, query, false);
3180 17 Mar 15 olle 133       if (subtype != null) subtype.addFilter(dc, query, "bpt");
3180 17 Mar 15 olle 134     }
3180 17 Mar 15 olle 135     if (prefix != null && !prefix.equals(""))
3180 17 Mar 15 olle 136     {
3180 17 Mar 15 olle 137       query.restrict(Restrictions.like(Hql.property("name"), Expressions.parameter("name", prefix + "%", Type.STRING)));
3180 17 Mar 15 olle 138     }
3180 17 Mar 15 olle 139   
3180 17 Mar 15 olle 140     query.restrict(Restrictions.eq(Hql.property("eventDate"), null));
3180 17 Mar 15 olle 141     query.restrict(Restrictions.eq(Hql.property("destroyed"), Expressions.parameter("destroyed", false, Type.BOOLEAN)));
3180 17 Mar 15 olle 142     query.restrict(Restrictions.gteq(Hql.property("freeWells"), Expressions.integer(numFreeWells)));
3180 17 Mar 15 olle 143     if (runDateAnnotation != null)
3180 17 Mar 15 olle 144     {
3180 17 Mar 15 olle 145       AnnotationType at = runDateAnnotation.load(dc);
3385 10 Jun 15 olle 146       query.restrict(new HasAnnotationRestriction(null, at, false, true, false));
3180 17 Mar 15 olle 147     }
3180 17 Mar 15 olle 148     query.order(Orders.asc(Hql.property("name")));
3180 17 Mar 15 olle 149   
3180 17 Mar 15 olle 150     List<BioPlate> tmp = query.list(dc);
3180 17 Mar 15 olle 151     List<ReactionPlate> plates = new ArrayList<ReactionPlate>(tmp.size());
3180 17 Mar 15 olle 152     for (BioPlate plate : tmp)
3180 17 Mar 15 olle 153     {
3180 17 Mar 15 olle 154       plates.add(new ReactionPlate(plate, bioPlateType));
3180 17 Mar 15 olle 155     }
3180 17 Mar 15 olle 156     return plates;
3180 17 Mar 15 olle 157   }
3180 17 Mar 15 olle 158
3180 17 Mar 15 olle 159   /**
3206 20 Mar 15 olle 160     Find all reaction plates which can hold biomaterial items of the given 
3206 20 Mar 15 olle 161     subtype and have names starting with an optional prefix. Plates included are plates that:
3206 20 Mar 15 olle 162
3206 20 Mar 15 olle 163     <ul>
3206 20 Mar 15 olle 164     <li>Have at least the specified number of free wells
3206 20 Mar 15 olle 165     <li>Have no value set for the 'run date' annotation
3206 20 Mar 15 olle 166     </ul>
3206 20 Mar 15 olle 167
3206 20 Mar 15 olle 168     @param dc
3254 17 Apr 15 olle 169     @param bioPlateType BioPlateType The required bioplate type, or null to not filter on bioplate type
3254 17 Apr 15 olle 170     @param subtype Subtype A biomaterial subtype, or null to not filter on subtype
3254 17 Apr 15 olle 171     @param prefix String Optional prefix in plate name
3254 17 Apr 15 olle 172     @param numFreeWells int Minimum number of free wells
3254 17 Apr 15 olle 173     @param runDateAnnotation Annotationtype The name of an annotation type, or null to not filter on annotation
3206 20 Mar 15 olle 174     @return
3206 20 Mar 15 olle 175   */
3206 20 Mar 15 olle 176   public static List<ReactionPlate> findByBioPlateType(DbControl dc, 
3206 20 Mar 15 olle 177     BioplateType bioPlateType, Subtype subtype, String prefix, int numFreeWells, Annotationtype runDateAnnotation)
3206 20 Mar 15 olle 178   {
3254 17 Apr 15 olle 179     Boolean destroyed = false;
3254 17 Apr 15 olle 180     Boolean orderDesc = false;
3254 17 Apr 15 olle 181     List<ReactionPlate> plates = findByBioPlateType(dc, bioPlateType, subtype, prefix, numFreeWells, runDateAnnotation, destroyed, orderDesc);
3254 17 Apr 15 olle 182     return plates;
3254 17 Apr 15 olle 183   }
3254 17 Apr 15 olle 184
3254 17 Apr 15 olle 185   /**
3254 17 Apr 15 olle 186     Find all reaction plates which can hold biomaterial items of the given 
3254 17 Apr 15 olle 187     subtype and have names starting with an optional prefix. Plates included are plates that:
3254 17 Apr 15 olle 188
3254 17 Apr 15 olle 189     <ul>
3254 17 Apr 15 olle 190     <li>Have at least the specified number of free wells
3254 17 Apr 15 olle 191     <li>Have no value set for the 'run date' annotation
3254 17 Apr 15 olle 192     </ul>
3254 17 Apr 15 olle 193
3254 17 Apr 15 olle 194     @param dc
3254 17 Apr 15 olle 195     @param bioPlateType BioPlateType The required bioplate type, or null to not filter on bioplate type
3254 17 Apr 15 olle 196     @param subtype Subtype A biomaterial subtype, or null to not filter on subtype
3254 17 Apr 15 olle 197     @param prefix String Optional prefix in plate name
3254 17 Apr 15 olle 198     @param numFreeWells int Minimum number of free wells
3254 17 Apr 15 olle 199     @param runDateAnnotation Annotationtype The name of an annotation type, or null to not filter on annotation
3254 17 Apr 15 olle 200     @param destroyed Boolean Flag indicating if plates should have been marked as destroyed (`null` value includes all plates)
3254 17 Apr 15 olle 201     @param orderDesc Boolean Flag indicating if list should be sorted in descending order (`false` or `null` gives ascending order).
3254 17 Apr 15 olle 202     @return
3254 17 Apr 15 olle 203    */
3254 17 Apr 15 olle 204   public static List<ReactionPlate> findByBioPlateType(DbControl dc, 
3254 17 Apr 15 olle 205     BioplateType bioPlateType, Subtype subtype, String prefix, int numFreeWells, Annotationtype runDateAnnotation, Boolean destroyed, Boolean orderDesc)
3254 17 Apr 15 olle 206   {
3206 20 Mar 15 olle 207     ItemQuery<BioPlate> query = BioPlate.getQuery();
3206 20 Mar 15 olle 208     query.setIncludes(Meludi.INCLUDE_IN_CURRENT_PROJECT);
3206 20 Mar 15 olle 209     if (subtype != null || bioPlateType != null)
3206 20 Mar 15 olle 210     {
3206 20 Mar 15 olle 211       query.join(Hql.innerJoin("bioPlateType", "bpt"));
3206 20 Mar 15 olle 212       if (bioPlateType != null) bioPlateType.addFilter(dc, query, false);
3206 20 Mar 15 olle 213       if (subtype != null) subtype.addFilter(dc, query, "bpt");
3206 20 Mar 15 olle 214     }
3206 20 Mar 15 olle 215     if (prefix != null && !prefix.equals(""))
3206 20 Mar 15 olle 216     {
3206 20 Mar 15 olle 217       query.restrict(Restrictions.like(Hql.property("name"), Expressions.parameter("name", prefix + "%", Type.STRING)));
3206 20 Mar 15 olle 218     }
3206 20 Mar 15 olle 219
3206 20 Mar 15 olle 220     //query.restrict(Restrictions.eq(Hql.property("eventDate"), null));
3254 17 Apr 15 olle 221     if (destroyed != null)
3254 17 Apr 15 olle 222     {
3254 17 Apr 15 olle 223       query.restrict(Restrictions.eq(Hql.property("destroyed"), Expressions.parameter("destroyed", destroyed, Type.BOOLEAN)));
3254 17 Apr 15 olle 224     }
3206 20 Mar 15 olle 225     query.restrict(Restrictions.gteq(Hql.property("freeWells"), Expressions.integer(numFreeWells)));
3206 20 Mar 15 olle 226     if (runDateAnnotation != null)
3206 20 Mar 15 olle 227     {
3206 20 Mar 15 olle 228       AnnotationType at = runDateAnnotation.load(dc);
3385 10 Jun 15 olle 229       query.restrict(new HasAnnotationRestriction(null, at, false, true, false));
3206 20 Mar 15 olle 230     }
3254 17 Apr 15 olle 231     if (orderDesc != null && orderDesc)
3254 17 Apr 15 olle 232     {
3254 17 Apr 15 olle 233       query.order(Orders.desc(Hql.property("name")));
3254 17 Apr 15 olle 234     }
3254 17 Apr 15 olle 235     else
3254 17 Apr 15 olle 236     {
3254 17 Apr 15 olle 237       query.order(Orders.asc(Hql.property("name")));
3254 17 Apr 15 olle 238     }
3206 20 Mar 15 olle 239
3206 20 Mar 15 olle 240     List<BioPlate> tmp = query.list(dc);
3206 20 Mar 15 olle 241     List<ReactionPlate> plates = new ArrayList<ReactionPlate>(tmp.size());
3206 20 Mar 15 olle 242     for (BioPlate plate : tmp)
3206 20 Mar 15 olle 243     {
3206 20 Mar 15 olle 244       plates.add(new ReactionPlate(plate, bioPlateType));
3206 20 Mar 15 olle 245     }
3206 20 Mar 15 olle 246     return plates;
3206 20 Mar 15 olle 247   }
3206 20 Mar 15 olle 248
3206 20 Mar 15 olle 249   /**
2933 14 Nov 14 olle 250     Find a reaction plate given it's name and plate type. If more than one
2933 14 Nov 14 olle 251     plate is found an exception is thrown. If no plate is found null is
2933 14 Nov 14 olle 252     returned.
2933 14 Nov 14 olle 253     @since 2.7
2933 14 Nov 14 olle 254   */
2933 14 Nov 14 olle 255   public static ReactionPlate findByNameAndType(DbControl dc, String plateName, BioplateType plateType)
2933 14 Nov 14 olle 256   {
2933 14 Nov 14 olle 257     ItemQuery<BioPlate> query = BioPlate.getQuery();
2933 14 Nov 14 olle 258     query.include(Meludi.INCLUDE_IN_CURRENT_PROJECT);
2933 14 Nov 14 olle 259     if (plateType != null)
2933 14 Nov 14 olle 260     {
2933 14 Nov 14 olle 261       plateType.addFilter(dc, query, true);
2933 14 Nov 14 olle 262     }
2933 14 Nov 14 olle 263     
2933 14 Nov 14 olle 264     query.restrict(Restrictions.eq(Hql.property("name"), Expressions.string(plateName)));
2933 14 Nov 14 olle 265     
2933 14 Nov 14 olle 266     ReactionPlate plate = null;
2933 14 Nov 14 olle 267     List<BioPlate> result = query.list(dc);
2933 14 Nov 14 olle 268     if (result.size() > 1)
2933 14 Nov 14 olle 269     {
2933 14 Nov 14 olle 270       throw new InvalidDataException("Found > 1 BioPlate["+plateName+"]");
2933 14 Nov 14 olle 271     }
2933 14 Nov 14 olle 272     else if (result.size() == 1)
2933 14 Nov 14 olle 273     {
2933 14 Nov 14 olle 274       plate = new ReactionPlate(result.get(0), plateType);
2933 14 Nov 14 olle 275     }
2933 14 Nov 14 olle 276     
2933 14 Nov 14 olle 277     return plate;
2933 14 Nov 14 olle 278   }
2933 14 Nov 14 olle 279   
2933 14 Nov 14 olle 280   public static ReactionPlate getById(DbControl dc, int bioPlateId, BioplateType plateType)
2933 14 Nov 14 olle 281   {
2933 14 Nov 14 olle 282     BioPlate plate = BioPlate.getById(dc, bioPlateId);
2933 14 Nov 14 olle 283     return plate == null ? null : new ReactionPlate(plate, plateType);
2933 14 Nov 14 olle 284   }
2933 14 Nov 14 olle 285   
2933 14 Nov 14 olle 286   public static ReactionPlate getNew(DbControl dc, BioplateType bioplateType)
2933 14 Nov 14 olle 287   {
2933 14 Nov 14 olle 288     BioPlate plate = BioPlate.getNew(dc, bioplateType.getPlateGeometry(dc), bioplateType.load(dc));
2933 14 Nov 14 olle 289     return new ReactionPlate(plate, bioplateType);
2933 14 Nov 14 olle 290   }
2933 14 Nov 14 olle 291   
2933 14 Nov 14 olle 292   private final BioplateType plateType;
2933 14 Nov 14 olle 293   private JSONArray jsonWells;
2933 14 Nov 14 olle 294   
2933 14 Nov 14 olle 295   private ReactionPlate(BioPlate plate, BioplateType plateType)
2933 14 Nov 14 olle 296   {
2933 14 Nov 14 olle 297     super(plate);
2933 14 Nov 14 olle 298     this.plateType = plateType;
2933 14 Nov 14 olle 299   }
2933 14 Nov 14 olle 300   
2933 14 Nov 14 olle 301   
2933 14 Nov 14 olle 302   /**
2933 14 Nov 14 olle 303     Get the real bioplate that represents this reaction plate in BASE.
2933 14 Nov 14 olle 304   */
2933 14 Nov 14 olle 305   public BioPlate getBioPlate()
2933 14 Nov 14 olle 306   {
2933 14 Nov 14 olle 307     return getItem();
2933 14 Nov 14 olle 308   }
2933 14 Nov 14 olle 309   
2933 14 Nov 14 olle 310   /**
2933 14 Nov 14 olle 311     Get the type of reaction plate (if known)
2933 14 Nov 14 olle 312     @return Can be null
2933 14 Nov 14 olle 313     @since 2.7
2933 14 Nov 14 olle 314   */
2933 14 Nov 14 olle 315   public BioplateType getBioplateType()
2933 14 Nov 14 olle 316   {
2933 14 Nov 14 olle 317     return plateType;
2933 14 Nov 14 olle 318   }
2933 14 Nov 14 olle 319   
2933 14 Nov 14 olle 320   @SuppressWarnings("unchecked")
2933 14 Nov 14 olle 321   public void loadBioWells(DbControl dc, boolean loadBioMaterial)
2933 14 Nov 14 olle 322   {
2933 14 Nov 14 olle 323     if (jsonWells != null) return;
2933 14 Nov 14 olle 324     
2933 14 Nov 14 olle 325     BioPlate plate = getItem();
2933 14 Nov 14 olle 326     int rows = plate.getRows();
2933 14 Nov 14 olle 327     int cols = plate.getColumns();
2933 14 Nov 14 olle 328     
2933 14 Nov 14 olle 329     jsonWells = new JSONArray();
2933 14 Nov 14 olle 330     for (int r = 0; r < rows; ++r)
2933 14 Nov 14 olle 331     {
2933 14 Nov 14 olle 332       for (int c = 0; c < cols; ++c)
2933 14 Nov 14 olle 333       {
2933 14 Nov 14 olle 334         BioWell well = plate.getBioWell(r, c);
2933 14 Nov 14 olle 335         JSONObject jsonWell = new JSONObject();
2933 14 Nov 14 olle 336         jsonWell.put("id", well.getId());
2933 14 Nov 14 olle 337         jsonWell.put("row", well.getRow());
2933 14 Nov 14 olle 338         jsonWell.put("column", well.getColumn());
2933 14 Nov 14 olle 339         jsonWell.put("canAdd", well.canAddBioMaterial());
2933 14 Nov 14 olle 340         jsonWell.put("canRemove", well.canClearBioMaterial());
2933 14 Nov 14 olle 341         
2933 14 Nov 14 olle 342         if (loadBioMaterial)
2933 14 Nov 14 olle 343         {
2933 14 Nov 14 olle 344           MeasuredBioMaterial bm = well.getBioMaterial();
2933 14 Nov 14 olle 345           if (bm != null)
2933 14 Nov 14 olle 346           {
2933 14 Nov 14 olle 347             JSONObject jsonBm = new JSONObject();
2933 14 Nov 14 olle 348             jsonBm.put("id", bm.getId());
2933 14 Nov 14 olle 349             jsonBm.put("name", bm.getName());
2933 14 Nov 14 olle 350             jsonBm.put("comment", bm.getDescription());
2933 14 Nov 14 olle 351             jsonWell.put("bioMaterial", jsonBm);
2933 14 Nov 14 olle 352           }
2933 14 Nov 14 olle 353         }
2933 14 Nov 14 olle 354         
2933 14 Nov 14 olle 355         jsonWells.add(jsonWell);
2933 14 Nov 14 olle 356       }
2933 14 Nov 14 olle 357     }  
2933 14 Nov 14 olle 358   }
2933 14 Nov 14 olle 359   
2933 14 Nov 14 olle 360   /**
2933 14 Nov 14 olle 361     Load biomaterial annotations for the given annotation type and store the values in
2933 14 Nov 14 olle 362     the given JSON key. Single-valued annotation types are stored as a simple
2933 14 Nov 14 olle 363     key-value pair. Multi-valued annotation types are stored as a
2933 14 Nov 14 olle 364     key-array pair (even if there is only one value in the array).
2933 14 Nov 14 olle 365     NOTE! The {@link #loadBioWells(DbControl, boolean)} must be called first to
2933 14 Nov 14 olle 366     load the well AND biomaterial information for the plate
2933 14 Nov 14 olle 367     @since 2.7
2933 14 Nov 14 olle 368   */
2933 14 Nov 14 olle 369   @SuppressWarnings("unchecked")
2933 14 Nov 14 olle 370   public void loadBioMaterialAnnotations(DbControl dc, String jsonKey, Annotationtype annotationType, ValueConverter converter)
2933 14 Nov 14 olle 371   {
2933 14 Nov 14 olle 372     if (jsonWells == null) return;
2933 14 Nov 14 olle 373     
2933 14 Nov 14 olle 374     if (converter == null) converter = IdentityConverter.INSTANCE;
2933 14 Nov 14 olle 375     AnnotationType at = annotationType.load(dc);
2933 14 Nov 14 olle 376     
2933 14 Nov 14 olle 377     for (int i = 0; i < jsonWells.size(); ++i)
2933 14 Nov 14 olle 378     {
2933 14 Nov 14 olle 379       JSONObject jsonWell = (JSONObject)jsonWells.get(i);
2933 14 Nov 14 olle 380       JSONObject jsonBm = (JSONObject)jsonWell.get("bioMaterial");
2933 14 Nov 14 olle 381       
2933 14 Nov 14 olle 382       if (jsonBm == null) continue; // with the next well
2933 14 Nov 14 olle 383       
2933 14 Nov 14 olle 384       Number id = (Number)jsonBm.get("id");
2933 14 Nov 14 olle 385       BioMaterial bm = BioMaterial.getById(dc, id.intValue());
2933 14 Nov 14 olle 386       
2933 14 Nov 14 olle 387       if (at.getMultiplicity() == 1)
2933 14 Nov 14 olle 388       {
2933 14 Nov 14 olle 389         jsonBm.put(jsonKey, converter.convert(annotationType.getAnnotationValue(dc, bm)));
2933 14 Nov 14 olle 390       }
2933 14 Nov 14 olle 391       else
2933 14 Nov 14 olle 392       {
2933 14 Nov 14 olle 393         jsonBm.put(jsonKey, JsonUtil.toArray(annotationType.getAnnotationValues(dc, bm), converter));
2933 14 Nov 14 olle 394       }
2933 14 Nov 14 olle 395     }
2933 14 Nov 14 olle 396   }
2933 14 Nov 14 olle 397
2933 14 Nov 14 olle 398   
2933 14 Nov 14 olle 399   /**
2933 14 Nov 14 olle 400     Find all child bioplates of a give type to this reaction plate. Since there is
2933 14 Nov 14 olle 401     no actual database reference between child and parent plates the plates are
2933 14 Nov 14 olle 402     located by name as follows:
2933 14 Nov 14 olle 403     
2933 14 Nov 14 olle 404     The plate prefix of this reacation plate is replaced with the plate prefix
2933 14 Nov 14 olle 405     of the given bioPlateType.
2933 14 Nov 14 olle 406     
2933 14 Nov 14 olle 407     @param dc 
2933 14 Nov 14 olle 408     @param bioPlateType The type of child plates to find
2933 14 Nov 14 olle 409     @return
2933 14 Nov 14 olle 410   */
2933 14 Nov 14 olle 411   public List<ReactionPlate> findChildPlates(DbControl dc, BioplateType childType)
2933 14 Nov 14 olle 412   {
2933 14 Nov 14 olle 413     // Replace the parent prefix with the child prefix
2933 14 Nov 14 olle 414     String prefix = getName().replace(this.getBioplateType().getPlateNamePrefix(), childType.getPlateNamePrefix());
2933 14 Nov 14 olle 415     
2933 14 Nov 14 olle 416     ItemQuery<BioPlate> query = BioPlate.getQuery();
2933 14 Nov 14 olle 417     query.include(Meludi.INCLUDE_IN_CURRENT_PROJECT);
2933 14 Nov 14 olle 418     // Find plates with prefix + . + numeric suffix
2933 14 Nov 14 olle 419     query.restrict(Restrictions.rlike(Hql.property("name"), Expressions.string("^" + prefix + "\\.[0-9]+$")));
2933 14 Nov 14 olle 420     childType.addFilter(dc, query, true);
2933 14 Nov 14 olle 421     
2933 14 Nov 14 olle 422     List<BioPlate> tmp = query.list(dc);
2933 14 Nov 14 olle 423     List<ReactionPlate> plates = new ArrayList<ReactionPlate>(tmp.size());
2933 14 Nov 14 olle 424     for (BioPlate plate : tmp)
2933 14 Nov 14 olle 425     {
2933 14 Nov 14 olle 426       plates.add(new ReactionPlate(plate, childType));
2933 14 Nov 14 olle 427     }
2933 14 Nov 14 olle 428     return plates;
2933 14 Nov 14 olle 429   }
2933 14 Nov 14 olle 430
2933 14 Nov 14 olle 431   /**
2933 14 Nov 14 olle 432     Find all bioplate events for the current bioplate. If
2933 14 Nov 14 olle 433     a role is specified, the list is filter to only
2933 14 Nov 14 olle 434     include events where the bioplate has the given role.
2933 14 Nov 14 olle 435     @since 2.12
2933 14 Nov 14 olle 436   */
2933 14 Nov 14 olle 437   public List<BioPlateEvent> findEvents(DbControl dc, String eventType, String role)
2933 14 Nov 14 olle 438   {
2933 14 Nov 14 olle 439     ItemQuery<BioPlateEvent> query = getItem().getEvents();
2933 14 Nov 14 olle 440     if (eventType != null)
2933 14 Nov 14 olle 441     {
2933 14 Nov 14 olle 442       int eventTypeId = SystemItems.getId(eventType);
2933 14 Nov 14 olle 443       if (eventTypeId != 0)
2933 14 Nov 14 olle 444       {
2933 14 Nov 14 olle 445         // Restrict on event type
2933 14 Nov 14 olle 446         query.restrict(Restrictions.eq(Hql.property("eventType"), Expressions.integer(eventTypeId)));
2933 14 Nov 14 olle 447       }
2933 14 Nov 14 olle 448       
2933 14 Nov 14 olle 449     }
2933 14 Nov 14 olle 450     if (role != null)
2933 14 Nov 14 olle 451     {
2933 14 Nov 14 olle 452       // Restrict on role
2933 14 Nov 14 olle 453       query.restrict(Restrictions.eq(
2933 14 Nov 14 olle 454         Hql.property(Item.BIOPLATEEVENTPARTICIPANT.getAlias(), "role"), Expressions.string(role)));
2933 14 Nov 14 olle 455     }
2933 14 Nov 14 olle 456     query.setIncludes(Include.ALL);
2933 14 Nov 14 olle 457     return query.list(dc);
2933 14 Nov 14 olle 458   }
2933 14 Nov 14 olle 459   
2933 14 Nov 14 olle 460   @SuppressWarnings("unchecked")
2933 14 Nov 14 olle 461   @Override
2933 14 Nov 14 olle 462   protected void initJSON(JSONObject json)
2933 14 Nov 14 olle 463   {
2933 14 Nov 14 olle 464     super.initJSON(json);
2933 14 Nov 14 olle 465     BioPlate plate = getItem();
2933 14 Nov 14 olle 466     BioPlateType plateType = plate.getBioPlateType();
2933 14 Nov 14 olle 467     PlateGeometry geometry = plate.getPlateGeometry();
2933 14 Nov 14 olle 468     ItemSubtype bioMaterialSubtype = plateType.getItemSubtype();
2933 14 Nov 14 olle 469     
2933 14 Nov 14 olle 470     json.put("freeWells", plate.getFreeWells());
2933 14 Nov 14 olle 471     json.put("usedWells", plate.getUsedWells());
2933 14 Nov 14 olle 472     json.put("barcode", plate.getBarcode());
2933 14 Nov 14 olle 473     
2933 14 Nov 14 olle 474     JSONObject jsonBioPlateType = new JSONObject();
2933 14 Nov 14 olle 475     jsonBioPlateType.put("id", plateType.getId());
2933 14 Nov 14 olle 476     jsonBioPlateType.put("bioMaterialType", plateType.getBioMaterialType().name());
2933 14 Nov 14 olle 477     json.put("bioPlateType", jsonBioPlateType);
2933 14 Nov 14 olle 478     
2933 14 Nov 14 olle 479     JSONObject jsonGeometry = new JSONObject();
2933 14 Nov 14 olle 480     jsonGeometry.put("id", geometry.getId());
2933 14 Nov 14 olle 481     jsonGeometry.put("rows", geometry.getRows());
2933 14 Nov 14 olle 482     jsonGeometry.put("columns", geometry.getColumns());
2933 14 Nov 14 olle 483     json.put("geometry", jsonGeometry);
2933 14 Nov 14 olle 484     
2933 14 Nov 14 olle 485     if (bioMaterialSubtype != null)
2933 14 Nov 14 olle 486     {
2933 14 Nov 14 olle 487       json.put("bioMaterialSubtype", Subtype.get(bioMaterialSubtype).asJSONObject(null));
2933 14 Nov 14 olle 488     }
2933 14 Nov 14 olle 489     if (jsonWells != null)
2933 14 Nov 14 olle 490     {
2933 14 Nov 14 olle 491       json.put("bioWells", jsonWells);
2933 14 Nov 14 olle 492     }
2933 14 Nov 14 olle 493   }
2933 14 Nov 14 olle 494
2933 14 Nov 14 olle 495   
2933 14 Nov 14 olle 496 }