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

Code
Comments
Other
Rev Date Author Line
1911 19 Mar 13 nicklas 1 package net.sf.basedb.reggie.servlet;
1911 19 Mar 13 nicklas 2
1911 19 Mar 13 nicklas 3 import java.io.IOException;
1959 03 May 13 nicklas 4 import java.util.Arrays;
1970 08 May 13 nicklas 5 import java.util.Date;
1911 19 Mar 13 nicklas 6 import java.util.List;
1911 19 Mar 13 nicklas 7
1911 19 Mar 13 nicklas 8 import javax.servlet.ServletException;
1911 19 Mar 13 nicklas 9 import javax.servlet.http.HttpServlet;
1911 19 Mar 13 nicklas 10 import javax.servlet.http.HttpServletRequest;
1911 19 Mar 13 nicklas 11 import javax.servlet.http.HttpServletResponse;
1911 19 Mar 13 nicklas 12
1911 19 Mar 13 nicklas 13 import org.json.simple.JSONArray;
1911 19 Mar 13 nicklas 14 import org.json.simple.JSONObject;
1911 19 Mar 13 nicklas 15
2040 03 Oct 13 nicklas 16 import net.sf.basedb.clients.web.util.HTML;
2141 18 Nov 13 nicklas 17 import net.sf.basedb.core.AnyToAny;
1934 17 Apr 13 nicklas 18 import net.sf.basedb.core.BioMaterialEvent;
1934 17 Apr 13 nicklas 19 import net.sf.basedb.core.BioMaterialEventSource;
3247 14 Apr 15 nicklas 20 import net.sf.basedb.core.ItemList;
1911 19 Mar 13 nicklas 21 import net.sf.basedb.core.BioPlate;
2104 25 Oct 13 nicklas 22 import net.sf.basedb.core.BioWell;
1911 19 Mar 13 nicklas 23 import net.sf.basedb.core.DbControl;
1911 19 Mar 13 nicklas 24 import net.sf.basedb.core.Extract;
1911 19 Mar 13 nicklas 25 import net.sf.basedb.core.ItemQuery;
1934 17 Apr 13 nicklas 26 import net.sf.basedb.core.ItemSubtype;
1970 08 May 13 nicklas 27 import net.sf.basedb.core.Protocol;
1911 19 Mar 13 nicklas 28 import net.sf.basedb.core.SessionControl;
1959 03 May 13 nicklas 29 import net.sf.basedb.core.Type;
1911 19 Mar 13 nicklas 30 import net.sf.basedb.core.query.Annotations;
1911 19 Mar 13 nicklas 31 import net.sf.basedb.core.query.Expressions;
1911 19 Mar 13 nicklas 32 import net.sf.basedb.core.query.Hql;
1911 19 Mar 13 nicklas 33 import net.sf.basedb.core.query.Orders;
1911 19 Mar 13 nicklas 34 import net.sf.basedb.core.query.Restrictions;
3762 19 Feb 16 nicklas 35 import net.sf.basedb.core.snapshot.SnapshotManager;
2598 22 Aug 14 nicklas 36 import net.sf.basedb.reggie.JsonUtil;
1911 19 Mar 13 nicklas 37 import net.sf.basedb.reggie.Reggie;
5384 26 Apr 19 nicklas 38 import net.sf.basedb.reggie.activity.ActivityDef;
3059 19 Dec 14 nicklas 39 import net.sf.basedb.reggie.counter.CounterService;
1911 19 Mar 13 nicklas 40 import net.sf.basedb.reggie.dao.Annotationtype;
1987 23 May 13 nicklas 41 import net.sf.basedb.reggie.dao.BiomaterialList;
1911 19 Mar 13 nicklas 42 import net.sf.basedb.reggie.dao.BioplateType;
1911 19 Mar 13 nicklas 43 import net.sf.basedb.reggie.dao.Library;
5434 17 May 19 nicklas 44 import net.sf.basedb.reggie.dao.Pipeline;
1934 17 Apr 13 nicklas 45 import net.sf.basedb.reggie.dao.PooledLibrary;
1911 19 Mar 13 nicklas 46 import net.sf.basedb.reggie.dao.ReactionPlate;
4897 10 Jul 18 nicklas 47 import net.sf.basedb.reggie.dao.ReggieItem;
2161 09 Dec 13 nicklas 48 import net.sf.basedb.reggie.dao.ReggieRole;
1987 23 May 13 nicklas 49 import net.sf.basedb.reggie.dao.Rna;
1934 17 Apr 13 nicklas 50 import net.sf.basedb.reggie.dao.Subtype;
1911 19 Mar 13 nicklas 51 import net.sf.basedb.util.Values;
1911 19 Mar 13 nicklas 52 import net.sf.basedb.util.error.ThrowableUtil;
1911 19 Mar 13 nicklas 53
1911 19 Mar 13 nicklas 54
1911 19 Mar 13 nicklas 55 public class PoolServlet 
1911 19 Mar 13 nicklas 56   extends HttpServlet 
1911 19 Mar 13 nicklas 57 {
1911 19 Mar 13 nicklas 58
1959 03 May 13 nicklas 59   /**
3107 27 Jan 15 nicklas 60     Default target molarity in nM when mixing libraries.
1959 03 May 13 nicklas 61   */
3107 27 Jan 15 nicklas 62   private static final float DEFAULT_TARGET_MOLARITY_IN_POOL = 2f;
1911 19 Mar 13 nicklas 63
1959 03 May 13 nicklas 64   /**
3107 27 Jan 15 nicklas 65     Default volume in µl to use from each lib in the pool
1959 03 May 13 nicklas 66   */
2025 25 Sep 13 nicklas 67   private static final float DEFAULT_TARGET_VOLUME_IN_POOL_PER_LIB = 5f;
1959 03 May 13 nicklas 68   
1959 03 May 13 nicklas 69   /**
1959 03 May 13 nicklas 70     If the volume to use from the lib is lower than this limit, 
1959 03 May 13 nicklas 71     we mix a larger amount to begin with, but only use the same target volume
1959 03 May 13 nicklas 72     (the extra is left in a temporary plate).
1959 03 May 13 nicklas 73   */
1974 14 May 13 nicklas 74   private static final float LIMIT_FOR_EXTRA_LARGE_MIX = 1f;
1959 03 May 13 nicklas 75   
1959 03 May 13 nicklas 76   /**
1975 15 May 13 nicklas 77     Factor to apply when making an extra large mix.
1975 15 May 13 nicklas 78     In the common case 2.0 means mixing 10µl instead of 5µl. But, only
1959 03 May 13 nicklas 79     5µl is used for the pool and the remaining 5µl is saved in a temporary
1959 03 May 13 nicklas 80     location.
1959 03 May 13 nicklas 81   */
1975 15 May 13 nicklas 82   private static final float EXTRA_LARGE_MIX_FACTOR = 2.0f;
1959 03 May 13 nicklas 83   
1959 03 May 13 nicklas 84   
1911 19 Mar 13 nicklas 85   private static final long serialVersionUID = -5652847260721336320L;
1911 19 Mar 13 nicklas 86
1911 19 Mar 13 nicklas 87   public PoolServlet()
1911 19 Mar 13 nicklas 88   {}
1911 19 Mar 13 nicklas 89
1911 19 Mar 13 nicklas 90   @Override
1911 19 Mar 13 nicklas 91   protected void doGet(HttpServletRequest req, HttpServletResponse resp)
1911 19 Mar 13 nicklas 92     throws ServletException, IOException 
1911 19 Mar 13 nicklas 93   {
1911 19 Mar 13 nicklas 94     String cmd = req.getParameter("cmd");
2598 22 Aug 14 nicklas 95     JsonUtil.setJsonResponseHeaders(resp);
1911 19 Mar 13 nicklas 96     
1911 19 Mar 13 nicklas 97     JSONObject json = new JSONObject();
1911 19 Mar 13 nicklas 98     json.put("status", "ok");
1911 19 Mar 13 nicklas 99     
3975 26 May 16 nicklas 100     final SessionControl sc = Reggie.getSessionControl(req);
1911 19 Mar 13 nicklas 101     DbControl dc = null;
1911 19 Mar 13 nicklas 102     try
1911 19 Mar 13 nicklas 103     {
3059 19 Dec 14 nicklas 104       if ("GetLibraryPlatesForPooling".equals(cmd))
1911 19 Mar 13 nicklas 105       {
1911 19 Mar 13 nicklas 106         /*
1911 19 Mar 13 nicklas 107           Find all Library bioplates for pooling.
1911 19 Mar 13 nicklas 108         */
6333 15 Jun 21 nicklas 109         dc = sc.newDbControl(":Create pooled libraries");
1952 24 Apr 13 nicklas 110         
1952 24 Apr 13 nicklas 111         // Find Library items with remaining quantity==original quantity
1952 24 Apr 13 nicklas 112         ItemQuery<Extract> libQuery = Extract.getQuery();
1952 24 Apr 13 nicklas 113         libQuery.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
1952 24 Apr 13 nicklas 114         Subtype.LIBRARY.addFilter(dc, libQuery);
2032 02 Oct 13 nicklas 115         libQuery.restrict(Restrictions.neq(Hql.property("originalQuantity"), null));
2032 02 Oct 13 nicklas 116         libQuery.restrict(Restrictions.eq(Hql.property("originalQuantity"), Hql.property("remainingQuantity")));
1987 23 May 13 nicklas 117         // Must NOT have a Flag annotation
1987 23 May 13 nicklas 118         libQuery.join(Annotations.leftJoin(null, Annotationtype.FLAG.load(dc), "flg"));
1987 23 May 13 nicklas 119         libQuery.restrict(Restrictions.eq(Hql.alias("flg"), null));
1952 24 Apr 13 nicklas 120         
1911 19 Mar 13 nicklas 121         ItemQuery<BioPlate> query = BioPlate.getQuery();
1911 19 Mar 13 nicklas 122         query.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
5883 26 Mar 20 nicklas 123         // Only Library bioplates that are not destroyed
5883 26 Mar 20 nicklas 124         BioplateType.LIBRARY.addFilter(dc, query, true);
3309 06 May 15 nicklas 125         
1911 19 Mar 13 nicklas 126         // Must have a PLATE_PROCESS_RESULT=Success annotation
1911 19 Mar 13 nicklas 127         query.join(Annotations.leftJoin(null, Annotationtype.PLATE_PROCESS_RESULT.load(dc), "ppr"));
1911 19 Mar 13 nicklas 128         query.restrict(Restrictions.eq(Hql.alias("ppr"), Expressions.string(ReactionPlate.PROCESS_SUCCESSFUL)));
1911 19 Mar 13 nicklas 129         
1952 24 Apr 13 nicklas 130         query.join(Hql.innerJoin("bioWells", "bw"));
1952 24 Apr 13 nicklas 131         query.join(Hql.innerJoin("bw", "bioMaterial", "bm"));
1952 24 Apr 13 nicklas 132         
1952 24 Apr 13 nicklas 133         query.restrict(Restrictions.eq(Hql.alias("bm"), Expressions.any(libQuery)));
2907 07 Nov 14 nicklas 134         query.order(Orders.asc(Hql.property("name")));
1952 24 Apr 13 nicklas 135         query.setDistinct(true);
1952 24 Apr 13 nicklas 136         
1911 19 Mar 13 nicklas 137         List<BioPlate> plates = query.list(dc);
1911 19 Mar 13 nicklas 138         JSONArray jsonPlates = new JSONArray();
1911 19 Mar 13 nicklas 139         for (BioPlate plate : plates)
1911 19 Mar 13 nicklas 140         {
1959 03 May 13 nicklas 141           jsonPlates.add(getJSONForLibPlate(dc, plate));
1911 19 Mar 13 nicklas 142         }
1911 19 Mar 13 nicklas 143         json.put("bioplates", jsonPlates);
1911 19 Mar 13 nicklas 144       }
1959 03 May 13 nicklas 145       else if ("GetLibPlateInfo".equals(cmd))
1959 03 May 13 nicklas 146       {
1959 03 May 13 nicklas 147         // Load information about a single library bioplate
1959 03 May 13 nicklas 148         int libPlateId = Values.getInt(req.getParameter("bioplate"));
6333 15 Jun 21 nicklas 149         dc = sc.newDbControl(":Create pooled libraries");
1959 03 May 13 nicklas 150         BioPlate libPlate = BioPlate.getById(dc, libPlateId);
1959 03 May 13 nicklas 151         json.put("libPlate", getJSONForLibPlate(dc, libPlate));
1959 03 May 13 nicklas 152         
1959 03 May 13 nicklas 153       }
2137 13 Nov 13 nicklas 154       else if ("GetLibraryInfo".equals(cmd))
2137 13 Nov 13 nicklas 155       {
2805 15 Oct 14 nicklas 156         // Get information about a list of libraries
2805 15 Oct 14 nicklas 157         Integer[] libId = Values.getInt(req.getParameter("libraries").split(","));
6333 15 Jun 21 nicklas 158         dc = sc.newDbControl(":Create pooled libraries");
3762 19 Feb 16 nicklas 159         SnapshotManager manager = new SnapshotManager();
2137 13 Nov 13 nicklas 160         
2805 15 Oct 14 nicklas 161         JSONArray jsonLibs = new JSONArray();
2805 15 Oct 14 nicklas 162         for (int i = 0; i < libId.length; i++)
2805 15 Oct 14 nicklas 163         {
2805 15 Oct 14 nicklas 164           Library lib = Library.getById(dc, libId[i]);
2805 15 Oct 14 nicklas 165           lib.loadBioPlateLocation();
2805 15 Oct 14 nicklas 166           addPoolingCalculationsToLib(dc, lib, null);
2805 15 Oct 14 nicklas 167           lib.setAnnotation("comment", lib.getExtract().getDescription());
5436 17 May 19 nicklas 168           lib.loadAnnotations(dc, "pipeline", Annotationtype.PIPELINE, null);
4984 27 Sep 18 nicklas 169           lib.loadDoNotUseAnnotations(dc, manager);
3762 19 Feb 16 nicklas 170           Rna rna = lib.getRna(dc, true);
5436 17 May 19 nicklas 171           if (rna != null) lib.setAnnotation("specimen", rna.loadYellowLabelInfo(dc, manager));
2805 15 Oct 14 nicklas 172           jsonLibs.add(lib.asJSONObject());
2805 15 Oct 14 nicklas 173         }
2805 15 Oct 14 nicklas 174         json.put("libraries", jsonLibs);
2137 13 Nov 13 nicklas 175         
2137 13 Nov 13 nicklas 176       }
1911 19 Mar 13 nicklas 177       else if ("GetLibraryInfoForPlate".equals(cmd))
1911 19 Mar 13 nicklas 178       {
1959 03 May 13 nicklas 179         // Get information about libraries on a single library bioplate
1959 03 May 13 nicklas 180         // Calculate mixing volumes for pooling using the target molarity
1959 03 May 13 nicklas 181         // and volumes
1911 19 Mar 13 nicklas 182         int libPlateId = Values.getInt(req.getParameter("bioplate"));
6333 15 Jun 21 nicklas 183         dc = sc.newDbControl(":Create pooled libraries");
3762 19 Feb 16 nicklas 184         SnapshotManager manager = new SnapshotManager();
1911 19 Mar 13 nicklas 185
1911 19 Mar 13 nicklas 186         BioPlate libPlate = BioPlate.getById(dc, libPlateId);
1911 19 Mar 13 nicklas 187
1911 19 Mar 13 nicklas 188         ItemQuery<Extract> query = Extract.getQuery();
1911 19 Mar 13 nicklas 189         query.join(Hql.innerJoin(null, "bioWell", "bw", true));
1911 19 Mar 13 nicklas 190         query.join(Hql.innerJoin("bw", "bioPlate", "bp"));
1911 19 Mar 13 nicklas 191         query.restrict(Restrictions.eq(Hql.alias("bp"), Hql.entity(libPlate)));
2032 02 Oct 13 nicklas 192         query.restrict(Restrictions.neq(Hql.property("originalQuantity"), null)); // Get rid of Stratagene, etc.
1911 19 Mar 13 nicklas 193         query.order(Orders.asc(Hql.property("bw", "column")));
1911 19 Mar 13 nicklas 194         query.order(Orders.asc(Hql.property("bw", "row")));
1911 19 Mar 13 nicklas 195
1911 19 Mar 13 nicklas 196         List<Library> libs = Library.toList(query.list(dc));
1911 19 Mar 13 nicklas 197         
1911 19 Mar 13 nicklas 198         JSONArray jsonLibs = new JSONArray();
1911 19 Mar 13 nicklas 199         for (Library lib : libs)
1911 19 Mar 13 nicklas 200         {
1911 19 Mar 13 nicklas 201           lib.loadBioPlateLocation();
2137 13 Nov 13 nicklas 202           addPoolingCalculationsToLib(dc, lib, null);
1987 23 May 13 nicklas 203           lib.setAnnotation("comment", lib.getExtract().getDescription());
3762 19 Feb 16 nicklas 204           Rna rna = lib.getRna(dc, true);
3762 19 Feb 16 nicklas 205           lib.setAnnotation("specimen", rna.loadYellowLabelInfo(dc, manager));
1911 19 Mar 13 nicklas 206           jsonLibs.add(lib.asJSONObject());
1911 19 Mar 13 nicklas 207         }
1911 19 Mar 13 nicklas 208
1911 19 Mar 13 nicklas 209         json.put("libraries", jsonLibs);
1959 03 May 13 nicklas 210         
1959 03 May 13 nicklas 211         // Send some info about the target molarity and volume used in the pooling calculations
1959 03 May 13 nicklas 212         // back to the client for presentation purposes
1959 03 May 13 nicklas 213         JSONObject poolInfo = new JSONObject();
3107 27 Jan 15 nicklas 214         poolInfo.put("targetMolarity", DEFAULT_TARGET_MOLARITY_IN_POOL);
2025 25 Sep 13 nicklas 215         poolInfo.put("targetVolumePerLib", DEFAULT_TARGET_VOLUME_IN_POOL_PER_LIB);
2025 25 Sep 13 nicklas 216         poolInfo.put("extraLargeMixFactor", EXTRA_LARGE_MIX_FACTOR);
2025 25 Sep 13 nicklas 217         poolInfo.put("limitForExtraLargeMix", LIMIT_FOR_EXTRA_LARGE_MIX);
1959 03 May 13 nicklas 218         json.put("poolInfo", poolInfo);
1911 19 Mar 13 nicklas 219       }
1934 17 Apr 13 nicklas 220       else if ("GetNextAutoGeneratedPoolNames".equals(cmd))
1934 17 Apr 13 nicklas 221       {
1959 03 May 13 nicklas 222         // Get the pool names for the next number of pools to create
6333 15 Jun 21 nicklas 223         dc = sc.newDbControl(":Create pooled libraries");
1934 17 Apr 13 nicklas 224         int numNames = Values.getInt(req.getParameter("numNames"));
4883 04 Jul 18 nicklas 225         json.put("names", PooledLibrary.getNextNames(dc, numNames));
2137 13 Nov 13 nicklas 226         JSONObject poolInfo = new JSONObject();
3107 27 Jan 15 nicklas 227         poolInfo.put("targetMolarity", DEFAULT_TARGET_MOLARITY_IN_POOL);
2137 13 Nov 13 nicklas 228         poolInfo.put("targetVolumePerLib", DEFAULT_TARGET_VOLUME_IN_POOL_PER_LIB);
2137 13 Nov 13 nicklas 229         poolInfo.put("extraLargeMixFactor", EXTRA_LARGE_MIX_FACTOR);
2137 13 Nov 13 nicklas 230         poolInfo.put("limitForExtraLargeMix", LIMIT_FOR_EXTRA_LARGE_MIX);
2137 13 Nov 13 nicklas 231         json.put("poolInfo", poolInfo);
1934 17 Apr 13 nicklas 232       }
1959 03 May 13 nicklas 233       else if ("GetUnprocessedPools".equals(cmd))
1959 03 May 13 nicklas 234       {
1959 03 May 13 nicklas 235         // Get all PooledLibrary items with no creation date
6333 15 Jun 21 nicklas 236         dc = sc.newDbControl(":Register pooled libraries");
1959 03 May 13 nicklas 237         
5434 17 May 19 nicklas 238         List<PooledLibrary> pools = PooledLibrary.findUnprocessedPools(dc, Pipeline.RNA_SEQ);
1959 03 May 13 nicklas 239         JSONArray jsonPools = new JSONArray();
1959 03 May 13 nicklas 240         for (PooledLibrary pool : pools)
1959 03 May 13 nicklas 241         {
2091 21 Oct 13 nicklas 242           pool.loadLibPlates(dc);
1959 03 May 13 nicklas 243           pool.loadAnnotations(dc, "molarity", Annotationtype.POOL_MOLARITY, null);
1959 03 May 13 nicklas 244           pool.loadAnnotations(dc, "conc", Annotationtype.POOL_CONC, null);
2141 18 Nov 13 nicklas 245           pool.loadAnnotations(dc, "isManual", Annotationtype.POOL_IS_MANUAL, null);
1959 03 May 13 nicklas 246           pool.setAnnotation("remainingQuantity", pool.getExtract().getRemainingQuantity());
2044 07 Oct 13 nicklas 247           pool.setAnnotation("comments", pool.getExtract().getDescription());
1959 03 May 13 nicklas 248           jsonPools.add(pool.asJSONObject());
1959 03 May 13 nicklas 249         }
1959 03 May 13 nicklas 250         json.put("pools", jsonPools);
1959 03 May 13 nicklas 251       }
1959 03 May 13 nicklas 252       
1959 03 May 13 nicklas 253       else if ("GetLibraryInfoForPools".equals(cmd))
1959 03 May 13 nicklas 254       {
1959 03 May 13 nicklas 255         // Get information about the libraries that are pooled in the given PooledLibrary items
6333 15 Jun 21 nicklas 256         dc = sc.newDbControl(":Lab protocols for pooling");
3762 19 Feb 16 nicklas 257         SnapshotManager manager = new SnapshotManager();
1959 03 May 13 nicklas 258         String[] tmp = req.getParameter("pools").split(",");
1959 03 May 13 nicklas 259         List<Integer> poolIds = Arrays.asList(Values.getInt(tmp));
1959 03 May 13 nicklas 260         
1959 03 May 13 nicklas 261         ItemQuery<Extract> poolQuery = Extract.getQuery();
1959 03 May 13 nicklas 262         poolQuery.restrict(Restrictions.in(Hql.property("id"), Expressions.parameter("pools", Type.INT)));
1959 03 May 13 nicklas 263         poolQuery.setParameter("pools", poolIds, Type.INT);
1959 03 May 13 nicklas 264         
1959 03 May 13 nicklas 265         List<PooledLibrary> pools = PooledLibrary.toList(poolQuery.list(dc));
1959 03 May 13 nicklas 266         
1959 03 May 13 nicklas 267         JSONArray jsonPools = new JSONArray();
1959 03 May 13 nicklas 268         for (PooledLibrary pool : pools)
1959 03 May 13 nicklas 269         {
1959 03 May 13 nicklas 270           BioMaterialEvent poolCreationEvent = pool.getExtract().getCreationEvent();
1959 03 May 13 nicklas 271           List<Library> libs = Library.getByPool(dc, pool);
1959 03 May 13 nicklas 272           JSONArray jsonLibs = new JSONArray();
1959 03 May 13 nicklas 273           for (Library lib : libs)
1959 03 May 13 nicklas 274           {
1959 03 May 13 nicklas 275             lib.loadBioPlateLocation();
2137 13 Nov 13 nicklas 276             addPoolingCalculationsToLib(dc, lib, pool);
1987 23 May 13 nicklas 277             lib.setAnnotation("comment", lib.getExtract().getDescription());
3762 19 Feb 16 nicklas 278             Rna rna = lib.getRna(dc, true);
3762 19 Feb 16 nicklas 279             lib.setAnnotation("specimen", rna.loadYellowLabelInfo(dc, manager));
1959 03 May 13 nicklas 280             jsonLibs.add(lib.asJSONObject());
1959 03 May 13 nicklas 281           }
1959 03 May 13 nicklas 282           
1959 03 May 13 nicklas 283           pool.setAnnotation("libraries", jsonLibs);
1959 03 May 13 nicklas 284           pool.loadAnnotations(dc, "molarity", Annotationtype.POOL_MOLARITY, null);
1959 03 May 13 nicklas 285           pool.loadAnnotations(dc, "conc", Annotationtype.POOL_CONC, null);
2040 03 Oct 13 nicklas 286           pool.setAnnotation("comments", HTML.niceFormat(pool.getExtract().getDescription()));
2027 30 Sep 13 nicklas 287           
2027 30 Sep 13 nicklas 288           Float targetVolumePerLib = (Float)Annotationtype.POOL_TARGET_VOLUME_PER_LIB.getAnnotationValue(dc, pool.getExtract());
2027 30 Sep 13 nicklas 289           if (targetVolumePerLib == null) targetVolumePerLib = DEFAULT_TARGET_VOLUME_IN_POOL_PER_LIB;
2027 30 Sep 13 nicklas 290           pool.setAnnotation("targetVolumePerLib", targetVolumePerLib);
2140 18 Nov 13 nicklas 291           Float targetPoolMolarity = (Float)Annotationtype.POOL_TARGET_MOLARITY.getAnnotationValue(dc, pool.getExtract());
3107 27 Jan 15 nicklas 292           if (targetPoolMolarity == null) targetPoolMolarity = DEFAULT_TARGET_MOLARITY_IN_POOL;
2140 18 Nov 13 nicklas 293           pool.setAnnotation("targetPoolMolarity", targetPoolMolarity);
2041 04 Oct 13 nicklas 294           String mixingStrategy = (String)Annotationtype.POOL_MIXING_STRATEGY.getAnnotationValue(dc, pool.getExtract());
2041 04 Oct 13 nicklas 295           if (mixingStrategy == null) mixingStrategy = PooledLibrary.MIXING_STRATEGY_FIXED;
2041 04 Oct 13 nicklas 296           pool.setAnnotation("mixingStrategy", mixingStrategy);
2041 04 Oct 13 nicklas 297           
1959 03 May 13 nicklas 298           pool.setAnnotation("originalQuantity", pool.getExtract().getOriginalQuantity());
1959 03 May 13 nicklas 299           jsonPools.add(pool.asJSONObject());
1959 03 May 13 nicklas 300         }
1959 03 May 13 nicklas 301         json.put("pools", jsonPools);
1959 03 May 13 nicklas 302         
1959 03 May 13 nicklas 303         JSONObject poolInfo = new JSONObject();
2025 25 Sep 13 nicklas 304         poolInfo.put("extraLargeMixFactor", EXTRA_LARGE_MIX_FACTOR);
2025 25 Sep 13 nicklas 305         poolInfo.put("limitForExtraLargeMix", LIMIT_FOR_EXTRA_LARGE_MIX);
1959 03 May 13 nicklas 306         json.put("poolInfo", poolInfo);
1959 03 May 13 nicklas 307       }
1911 19 Mar 13 nicklas 308     }
1911 19 Mar 13 nicklas 309     catch (Throwable t)
1911 19 Mar 13 nicklas 310     {
1911 19 Mar 13 nicklas 311       t.printStackTrace();
1911 19 Mar 13 nicklas 312       json.clear();
1911 19 Mar 13 nicklas 313       json.put("status", "error");
1911 19 Mar 13 nicklas 314       json.put("message", t.getMessage());
1911 19 Mar 13 nicklas 315       json.put("stacktrace", ThrowableUtil.stackTraceToString(t));
1911 19 Mar 13 nicklas 316     }
1911 19 Mar 13 nicklas 317     finally
1911 19 Mar 13 nicklas 318     {
1911 19 Mar 13 nicklas 319       if (dc != null) dc.close();
1911 19 Mar 13 nicklas 320       json.writeJSONString(resp.getWriter());
1911 19 Mar 13 nicklas 321     }
1911 19 Mar 13 nicklas 322     
1911 19 Mar 13 nicklas 323   }
1911 19 Mar 13 nicklas 324
1911 19 Mar 13 nicklas 325   @Override
1911 19 Mar 13 nicklas 326   protected void doPost(HttpServletRequest req, HttpServletResponse resp)
1911 19 Mar 13 nicklas 327     throws ServletException, IOException 
1911 19 Mar 13 nicklas 328   {
1911 19 Mar 13 nicklas 329     String cmd = req.getParameter("cmd");
2598 22 Aug 14 nicklas 330     JsonUtil.setJsonResponseHeaders(resp);
1911 19 Mar 13 nicklas 331     
1911 19 Mar 13 nicklas 332     JSONObject json = new JSONObject();
1911 19 Mar 13 nicklas 333     json.put("status", "ok");
1911 19 Mar 13 nicklas 334     
1911 19 Mar 13 nicklas 335     JSONArray jsonMessages = new JSONArray();
1911 19 Mar 13 nicklas 336   
3975 26 May 16 nicklas 337     final SessionControl sc = Reggie.getSessionControl(req);
1911 19 Mar 13 nicklas 338     DbControl dc = null;
1911 19 Mar 13 nicklas 339     try
1911 19 Mar 13 nicklas 340     {
1934 17 Apr 13 nicklas 341       if ("CreatePools".equals(cmd))
1911 19 Mar 13 nicklas 342       {
6333 15 Jun 21 nicklas 343         dc = sc.newDbControl(":Create pooled libraries");
2161 09 Dec 13 nicklas 344
2161 09 Dec 13 nicklas 345         ReggieRole.checkPermission(dc, "'" + cmd + "' wizard", ReggieRole.LIBRARY_PREP, ReggieRole.ADMINISTRATOR);
2161 09 Dec 13 nicklas 346
1959 03 May 13 nicklas 347         // Create PooledLibrary items from a Library bioplate
3752 17 Feb 16 nicklas 348         JSONObject jsonReq = JsonUtil.parseRequest(req);
1934 17 Apr 13 nicklas 349         JSONArray jsonPools = (JSONArray)jsonReq.get("pools");
1987 23 May 13 nicklas 350         JSONArray jsonFlagged = (JSONArray)jsonReq.get("flagged");
1934 17 Apr 13 nicklas 351         
1934 17 Apr 13 nicklas 352         ItemSubtype pooledLibraryType = Subtype.POOLED_LIBRARY.load(dc);
1959 03 May 13 nicklas 353         ItemSubtype libraryType = Subtype.LIBRARY.load(dc);
1934 17 Apr 13 nicklas 354         
1959 03 May 13 nicklas 355         //jsonMessages.add("Target molarity: " + TARGET_MOLARITY_IN_POOL + "; Mix " + TARGET_VOLUME_IN_POOL_PER_LIB + "µl, or " + (TARGET_VOLUME_IN_POOL_PER_LIB * (1+EXTRA_LARGE_MIX_FACTOR)) + " if &lt; " + LIMIT_FOR_EXTRA_LARGE_MIX + "µl");
1959 03 May 13 nicklas 356         
1959 03 May 13 nicklas 357         for (int poolNo = 0; poolNo < jsonPools.size(); poolNo++)
1934 17 Apr 13 nicklas 358         {
1959 03 May 13 nicklas 359           JSONObject jsonPool = (JSONObject)jsonPools.get(poolNo);
1934 17 Apr 13 nicklas 360           JSONArray jsonLibs = (JSONArray)jsonPool.get("libs");
1987 23 May 13 nicklas 361           JSONArray jsonExcluded = (JSONArray)jsonPool.get("excluded");
1934 17 Apr 13 nicklas 362           
2141 18 Nov 13 nicklas 363           Number libPlateId = (Number)jsonPool.get("libPlate");
2184 09 Jan 14 nicklas 364           String mixingStrategy = (String)jsonPool.get("mixingStrategy");
2184 09 Jan 14 nicklas 365           Number targetVolumeInPoolPerLib = (Number)jsonPool.get("targetVolumeInPoolPerLib");
2184 09 Jan 14 nicklas 366           Number targetPoolMolarity = (Number)jsonPool.get("targetPoolMolarity");
2141 18 Nov 13 nicklas 367           
1959 03 May 13 nicklas 368           // Create PooledLibrary item
1934 17 Apr 13 nicklas 369           Extract pool = Extract.getNew(dc);
1934 17 Apr 13 nicklas 370           pool.setItemSubtype(pooledLibraryType);
4897 10 Jul 18 nicklas 371           pool.setName(ReggieItem.ensureNonExistingItem(dc, Subtype.POOLED_LIBRARY, (String)jsonPool.get("name")));
2042 04 Oct 13 nicklas 372           pool.setDescription((String)jsonPool.get("comment"));
5434 17 May 19 nicklas 373           Pipeline.RNA_SEQ.setAnnotation(dc, pool);
2027 30 Sep 13 nicklas 374           Annotationtype.POOL_TARGET_VOLUME_PER_LIB.setAnnotationValue(dc, pool, targetVolumeInPoolPerLib.floatValue());
2140 18 Nov 13 nicklas 375           Annotationtype.POOL_TARGET_MOLARITY.setAnnotationValue(dc, pool, targetPoolMolarity.floatValue());
2041 04 Oct 13 nicklas 376           Annotationtype.POOL_MIXING_STRATEGY.setAnnotationValue(dc, pool, mixingStrategy);
1934 17 Apr 13 nicklas 377           
2141 18 Nov 13 nicklas 378           // Link with library plate
2141 18 Nov 13 nicklas 379           if (libPlateId != null)
2141 18 Nov 13 nicklas 380           {
2141 18 Nov 13 nicklas 381             BioPlate libPlate = BioPlate.getById(dc, libPlateId.intValue());
2141 18 Nov 13 nicklas 382             AnyToAny libPlateLink = AnyToAny.getNew(dc, pool, libPlate, "LibPlate", true);
2141 18 Nov 13 nicklas 383             dc.saveItemIf(pool, libPlateLink, false);
2141 18 Nov 13 nicklas 384           }
2141 18 Nov 13 nicklas 385           else
2141 18 Nov 13 nicklas 386           {
2141 18 Nov 13 nicklas 387             Annotationtype.POOL_IS_MANUAL.setAnnotationValue(dc, pool, true);
2141 18 Nov 13 nicklas 388           }
2141 18 Nov 13 nicklas 389           
1934 17 Apr 13 nicklas 390           BioMaterialEvent poolEvent = pool.getCreationEvent();
1934 17 Apr 13 nicklas 391           
2027 30 Sep 13 nicklas 392           // Total pool quantities
2140 18 Nov 13 nicklas 393           float poolVolume = ((Number)jsonPool.get("ebVolumeExtra")).floatValue();  // volume in pool (µl)
2027 30 Sep 13 nicklas 394           float poolQuantity = 0f; // quantity of DNA in pool (µg)
2027 30 Sep 13 nicklas 395           float poolAmount = 0f;  // Amount of DNA in pool (nano-mole)
1959 03 May 13 nicklas 396           
1959 03 May 13 nicklas 397           for (int libNo = 0; libNo < jsonLibs.size(); libNo++)
1934 17 Apr 13 nicklas 398           {
1959 03 May 13 nicklas 399             JSONObject jsonLib = (JSONObject)jsonLibs.get(libNo);
1934 17 Apr 13 nicklas 400             Number libId = (Number)jsonLib.get("id");
1934 17 Apr 13 nicklas 401
1959 03 May 13 nicklas 402             // Load the library item
4886 04 Jul 18 nicklas 403             Library l = Library.getById(dc, libId.intValue());
4886 04 Jul 18 nicklas 404             Extract lib = l.getItem();
1987 23 May 13 nicklas 405             lib.setDescription((String)jsonLib.get("comment"));
1934 17 Apr 13 nicklas 406             
2027 30 Sep 13 nicklas 407             // Load molarity and concentration for lib
2454 23 May 14 nicklas 408             Float libMolarity = (Float)Annotationtype.LIBRARY_MOLARITY_EST.getAnnotationValue(dc, lib);
1934 17 Apr 13 nicklas 409             Float originalConc = (Float)Annotationtype.QUBIT_CONC.getAnnotationValue(dc, lib);
1934 17 Apr 13 nicklas 410             Float speedVacConc = (Float)Annotationtype.QUBIT_CONC_AFTER_SPEEDVAC.getAnnotationValue(dc, lib);
3310 07 May 15 nicklas 411             Float libConcEst = (Float)Annotationtype.LIBRARY_CONC_EST.getAnnotationValue(dc, lib);
3310 07 May 15 nicklas 412             Float libConc = Reggie.firstNonNull(libConcEst, speedVacConc, originalConc);
2027 30 Sep 13 nicklas 413
2027 30 Sep 13 nicklas 414             // Get mixing information from the request
4887 05 Jul 18 nicklas 415             float libVolumeInPool = ((Number)jsonLib.get("volume")).floatValue();
4887 05 Jul 18 nicklas 416             float ebVolumeInPool = ((Number)jsonLib.get("eb")).floatValue();
2027 30 Sep 13 nicklas 417             float mixFactor = ((Number)jsonLib.get("mixFactor")).floatValue();
1987 23 May 13 nicklas 418             
2027 30 Sep 13 nicklas 419             // Calculate amount of DNA and resulting mix molarity
4887 05 Jul 18 nicklas 420             float libAmountInPool = libVolumeInPool * libMolarity;
4887 05 Jul 18 nicklas 421             float libQuantityInPool = libVolumeInPool * libConc / 1000;
4887 05 Jul 18 nicklas 422             float mixVolumeInPool = libVolumeInPool + ebVolumeInPool;
4887 05 Jul 18 nicklas 423             float mixMolarity = libAmountInPool / mixVolumeInPool;
4887 05 Jul 18 nicklas 424             float mixConc = 1000 * libQuantityInPool / mixVolumeInPool;
2027 30 Sep 13 nicklas 425
1959 03 May 13 nicklas 426             // Add the library to the pooling event
1959 03 May 13 nicklas 427             BioMaterialEventSource poolSrc = poolEvent.addSource(lib);
4887 05 Jul 18 nicklas 428             poolSrc.setUsedQuantity(libQuantityInPool);
1952 24 Apr 13 nicklas 429             
1975 15 May 13 nicklas 430             if (mixFactor > 1.001)
1959 03 May 13 nicklas 431             {
1959 03 May 13 nicklas 432               // Create 'dil' extract for keeping track of remaining quantity that has been mixed
4887 05 Jul 18 nicklas 433               float totalMixVolume = mixVolumeInPool * mixFactor;
4887 05 Jul 18 nicklas 434               float extraQuantity = libQuantityInPool * (mixFactor - 1f);
1959 03 May 13 nicklas 435               Extract dil = Extract.getNew(dc);
1959 03 May 13 nicklas 436               dil.setItemSubtype(libraryType);
4886 04 Jul 18 nicklas 437               dil.setName(l.getNextTemporaryDilName(dc));
2186 10 Jan 14 nicklas 438               Number targetVolume = (Number)jsonLib.get("targetVolume");
2186 10 Jan 14 nicklas 439               if (targetVolume != null)
2186 10 Jan 14 nicklas 440               {
2186 10 Jan 14 nicklas 441                 Annotationtype.POOL_TARGET_VOLUME_PER_LIB.setAnnotationValue(dc, dil, targetVolume.floatValue());
2186 10 Jan 14 nicklas 442               }
4887 05 Jul 18 nicklas 443               dil.setDescription("Represents the remaining " + Values.formatNumber(totalMixVolume - mixVolumeInPool, 1) + 
4887 05 Jul 18 nicklas 444                 "µl aliquot after mixing " + Values.formatNumber(totalMixVolume, 1) + 
2104 25 Oct 13 nicklas 445                 "µl solution before pooling. Stored at a temporary location until the pool has been completed.");
1959 03 May 13 nicklas 446               BioMaterialEventSource libSrc = dil.getCreationEvent().addSource(lib);
2027 30 Sep 13 nicklas 447               Annotationtype.POOL_MOLARITY.setAnnotationValue(dc, dil, mixMolarity);
2027 30 Sep 13 nicklas 448               Annotationtype.POOL_CONC.setAnnotationValue(dc, dil, mixConc);
2027 30 Sep 13 nicklas 449               libSrc.setUsedQuantity(extraQuantity);
2027 30 Sep 13 nicklas 450               dil.setOriginalQuantity(extraQuantity);
1976 15 May 13 nicklas 451               dil.setTag(lib.getTag());
1959 03 May 13 nicklas 452               dc.saveItem(dil);
2027 30 Sep 13 nicklas 453               /*
2027 30 Sep 13 nicklas 454               jsonMessages.add("Created " + dil.getName() + 
2027 30 Sep 13 nicklas 455                 "; " + Values.formatNumber(mixMolarity, 2) + "nM / "+
2027 30 Sep 13 nicklas 456                 Values.formatNumber(1000 * extraQuantity / mixConc, 1) + "µl");
2027 30 Sep 13 nicklas 457               */
1959 03 May 13 nicklas 458             }
1959 03 May 13 nicklas 459             
2027 30 Sep 13 nicklas 460             // Summarize quantity, volumes, molarity for the pool
4887 05 Jul 18 nicklas 461             poolQuantity += libQuantityInPool;
4887 05 Jul 18 nicklas 462             poolVolume += mixVolumeInPool;
4887 05 Jul 18 nicklas 463             poolAmount += libAmountInPool;
2027 30 Sep 13 nicklas 464
2027 30 Sep 13 nicklas 465             /*
2027 30 Sep 13 nicklas 466             jsonMessages.add("Using " + Values.formatNumber(libQuantity*1000, 2) + "+" + 
2027 30 Sep 13 nicklas 467                 Values.formatNumber(extraQuantity*1000, 2) +"ng of " + 
2027 30 Sep 13 nicklas 468                 Values.formatNumber(lib.getOriginalQuantity()*1000,2) + "ng from " + 
2027 30 Sep 13 nicklas 469                 lib.getName()+"; molarity="+Values.formatNumber(libMolarity, 2) + " (" + Values.formatNumber(mixMolarity, 2) + ")");
2027 30 Sep 13 nicklas 470               */
1934 17 Apr 13 nicklas 471           }
1934 17 Apr 13 nicklas 472           
2027 30 Sep 13 nicklas 473           float poolConc = 1000 * poolQuantity / poolVolume;
2027 30 Sep 13 nicklas 474           float poolMolarity = poolAmount / poolVolume;
2027 30 Sep 13 nicklas 475           
1959 03 May 13 nicklas 476           pool.setOriginalQuantity(poolQuantity);
2027 30 Sep 13 nicklas 477           Annotationtype.POOL_CONC.setAnnotationValue(dc, pool, poolConc);
2027 30 Sep 13 nicklas 478           Annotationtype.POOL_MOLARITY.setAnnotationValue(dc, pool, poolMolarity);
1934 17 Apr 13 nicklas 479           dc.saveItem(pool);
1934 17 Apr 13 nicklas 480           
1987 23 May 13 nicklas 481           String excluded = "";
1987 23 May 13 nicklas 482           if (jsonExcluded.size() > 0)
1987 23 May 13 nicklas 483           {
1987 23 May 13 nicklas 484             for (int libNo = 0; libNo < jsonExcluded.size(); libNo++)
1987 23 May 13 nicklas 485             {
1987 23 May 13 nicklas 486               JSONObject jsonLib = (JSONObject)jsonExcluded.get(libNo);
1987 23 May 13 nicklas 487               Number libId = (Number)jsonLib.get("id");
1987 23 May 13 nicklas 488
1987 23 May 13 nicklas 489               // Load the library item
1987 23 May 13 nicklas 490               Extract lib = Extract.getById(dc, libId.intValue());
1987 23 May 13 nicklas 491               lib.setDescription((String)jsonLib.get("comment"));
1987 23 May 13 nicklas 492               Annotationtype.FLAG.setAnnotationValue(dc, lib, Rna.FLAG_EXCLUDED_FROM_POOL);
1987 23 May 13 nicklas 493             }
1987 23 May 13 nicklas 494
1987 23 May 13 nicklas 495             excluded = " (" + jsonExcluded.size() + " excluded)";
1987 23 May 13 nicklas 496           }
1987 23 May 13 nicklas 497           
2027 30 Sep 13 nicklas 498           jsonMessages.add("Created '" + pool.getName() + "' from " + jsonLibs.size() + " libraries" + excluded + 
2027 30 Sep 13 nicklas 499             "; " + Values.formatNumber(poolMolarity, 2) + "nM / " +
2027 30 Sep 13 nicklas 500             Values.formatNumber(poolVolume, 1) + "µl");
1934 17 Apr 13 nicklas 501         }
1975 15 May 13 nicklas 502         
1987 23 May 13 nicklas 503         // Process flagged items; add parent RNA to the 'Flagged RNA' list
1987 23 May 13 nicklas 504         if (jsonFlagged.size() > 0)
1987 23 May 13 nicklas 505         {
1987 23 May 13 nicklas 506           int numFlagged = 0;
3247 14 Apr 15 nicklas 507           ItemList flaggedList = BiomaterialList.FLAGGED_RNA.load(dc);
1987 23 May 13 nicklas 508           for (int flagNo = 0; flagNo < jsonFlagged.size(); flagNo++)
1987 23 May 13 nicklas 509           {
1987 23 May 13 nicklas 510             JSONObject jsonLib = (JSONObject)jsonFlagged.get(flagNo);
1987 23 May 13 nicklas 511             Number libId = (Number)jsonLib.get("id");
1987 23 May 13 nicklas 512   
1987 23 May 13 nicklas 513             // Load the library item
1987 23 May 13 nicklas 514             Extract lib = Extract.getById(dc, libId.intValue());
5553 12 Aug 19 nicklas 515             if (!Reggie.isExternalItem(lib.getName()))
1987 23 May 13 nicklas 516             {
2907 07 Nov 14 nicklas 517               Library l = Library.get(lib);
3309 06 May 15 nicklas 518               Rna r = l.getRna(dc, false);
2907 07 Nov 14 nicklas 519               Extract rna = r.getExtract();
1987 23 May 13 nicklas 520               Annotationtype.FLAG.setAnnotationValue(dc, rna, jsonLib.get("flag"));
1987 23 May 13 nicklas 521               rna.setDescription((String)jsonLib.get("comment"));
1987 23 May 13 nicklas 522               flaggedList.add(rna);
1987 23 May 13 nicklas 523               numFlagged++;
1987 23 May 13 nicklas 524             }
1987 23 May 13 nicklas 525             
1987 23 May 13 nicklas 526           }
1987 23 May 13 nicklas 527           if (numFlagged > 0)
1987 23 May 13 nicklas 528           {
1987 23 May 13 nicklas 529             jsonMessages.add(numFlagged + " RNA items flagged for re-processing");
1987 23 May 13 nicklas 530           }
1987 23 May 13 nicklas 531         }
1987 23 May 13 nicklas 532         
2829 17 Oct 14 nicklas 533         dc.commit();
1970 08 May 13 nicklas 534       }
1970 08 May 13 nicklas 535       else if ("RegisterPooledLibraries".equals(cmd))
1970 08 May 13 nicklas 536       {
6333 15 Jun 21 nicklas 537         dc = sc.newDbControl(":Register pooled libraries");
2161 09 Dec 13 nicklas 538
2161 09 Dec 13 nicklas 539         ReggieRole.checkPermission(dc, "'" + cmd + "' wizard", ReggieRole.LIBRARY_PREP, ReggieRole.ADMINISTRATOR);
2161 09 Dec 13 nicklas 540
3752 17 Feb 16 nicklas 541         JSONObject jsonReq = JsonUtil.parseRequest(req);
1934 17 Apr 13 nicklas 542         
1970 08 May 13 nicklas 543         Number poolProtocolId = (Number)jsonReq.get("poolProtocol");
1970 08 May 13 nicklas 544         Date poolDate = Reggie.CONVERTER_STRING_TO_DATE.convert((String)jsonReq.get("poolDate"));
1970 08 May 13 nicklas 545         String operator = Values.getStringOrNull((String)jsonReq.get("poolOperator"));
1970 08 May 13 nicklas 546         
1970 08 May 13 nicklas 547         Protocol poolProtocol = poolProtocolId == null ? null : Protocol.getById(dc, poolProtocolId.intValue());
1976 15 May 13 nicklas 548
1976 15 May 13 nicklas 549         ItemQuery<Extract> dilQuery = Extract.getQuery();
4886 04 Jul 18 nicklas 550         dilQuery.restrict(Restrictions.like(Hql.property("name"), Expressions.parameter("dilName", Type.STRING)));
1976 15 May 13 nicklas 551         dilQuery.restrict(Restrictions.eq(Hql.property("creationEvent.eventDate"), null));
1976 15 May 13 nicklas 552         dilQuery.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
1970 08 May 13 nicklas 553         
4886 04 Jul 18 nicklas 554         JSONArray jsonPools = (JSONArray)jsonReq.get("pools");
5382 24 Apr 19 nicklas 555         int numLibs = 0;
1970 08 May 13 nicklas 556         for (int i = 0; i < jsonPools.size(); i++)
1970 08 May 13 nicklas 557         {
2044 07 Oct 13 nicklas 558           JSONObject jsonPool = (JSONObject)jsonPools.get(i);
2044 07 Oct 13 nicklas 559           Number poolId = (Number)jsonPool.get("id");
1976 15 May 13 nicklas 560           PooledLibrary pool = PooledLibrary.getById(dc, poolId.intValue());
1976 15 May 13 nicklas 561           Extract poolExtract = pool.getExtract();
1976 15 May 13 nicklas 562           BioMaterialEvent creationEvent = poolExtract.getCreationEvent();
1970 08 May 13 nicklas 563           
1970 08 May 13 nicklas 564           creationEvent.setEventDate(poolDate);
1970 08 May 13 nicklas 565           creationEvent.setProtocol(poolProtocol);
2044 07 Oct 13 nicklas 566           poolExtract.setDescription(Values.getStringOrNull((String)jsonPool.get("comments")));
2191 13 Jan 14 nicklas 567           Annotationtype.POOL_OPERATOR.setAnnotationValue(dc, poolExtract, operator);
2066 15 Oct 13 nicklas 568           Annotationtype.POOL_DATE.setAnnotationValue(dc, poolExtract, poolDate);
1970 08 May 13 nicklas 569           
1976 15 May 13 nicklas 570           // Check if there are any .dil items
1976 15 May 13 nicklas 571           List<Library> libs = Library.getByPool(dc, pool);
5382 24 Apr 19 nicklas 572           numLibs += libs.size();
1976 15 May 13 nicklas 573           for (Library lib : libs)
1976 15 May 13 nicklas 574           {
4886 04 Jul 18 nicklas 575             dilQuery.setParameter("dilName", lib.getName()+".dil%", Type.STRING);
1976 15 May 13 nicklas 576             List<Extract> result = dilQuery.list(dc);
1976 15 May 13 nicklas 577             if (result.size() == 1)
1976 15 May 13 nicklas 578             {
1976 15 May 13 nicklas 579               Extract dil = result.get(0);
1976 15 May 13 nicklas 580               BioMaterialEvent dilEvent = dil.getCreationEvent();
1976 15 May 13 nicklas 581               dilEvent.setEventDate(poolDate);
1976 15 May 13 nicklas 582               dilEvent.setProtocol(poolProtocol);
2104 25 Oct 13 nicklas 583               
2104 25 Oct 13 nicklas 584               // Create event for destroying the biomaterial
2104 25 Oct 13 nicklas 585               BioMaterialEvent discardDil = dil.newEvent();
2104 25 Oct 13 nicklas 586               discardDil.setEventDate(poolDate);
2104 25 Oct 13 nicklas 587               discardDil.setProtocol(poolProtocol);
2104 25 Oct 13 nicklas 588               discardDil.setUsedQuantity(dil.getOriginalQuantity());
2104 25 Oct 13 nicklas 589               discardDil.setComment("Destroyed this aliquot after pooling was completed.");
2104 25 Oct 13 nicklas 590               dc.saveItem(discardDil);
2104 25 Oct 13 nicklas 591
2104 25 Oct 13 nicklas 592               BioWell libWell = lib.getExtract().getBioWell();
2104 25 Oct 13 nicklas 593               String location = libWell == null ? "" : " (" + libWell.getCoordinate() + ")";
2104 25 Oct 13 nicklas 594               
2104 25 Oct 13 nicklas 595               jsonMessages.add(dil.getName() + location + " aliquot registered as destroyed");
1976 15 May 13 nicklas 596             }
5384 26 Apr 19 nicklas 597           }
2104 25 Oct 13 nicklas 598           jsonMessages.add(pool.getName() + " registered as completed.");
1970 08 May 13 nicklas 599         }
5384 26 Apr 19 nicklas 600         String nPools = jsonPools.size() == 1 ? "one pool" : jsonPools.size() + " pools";
5421 13 May 19 nicklas 601         ActivityDef.POOLED_LIBRARIES.create(dc, nPools, numLibs);
1970 08 May 13 nicklas 602         
1959 03 May 13 nicklas 603         dc.commit();
1911 19 Mar 13 nicklas 604       }
1911 19 Mar 13 nicklas 605       json.put("messages", jsonMessages);
3059 19 Dec 14 nicklas 606       CounterService.getInstance().setForceCount();
1911 19 Mar 13 nicklas 607     }
1911 19 Mar 13 nicklas 608     catch (Throwable t)
1911 19 Mar 13 nicklas 609     {
1911 19 Mar 13 nicklas 610       t.printStackTrace();
1911 19 Mar 13 nicklas 611       json.clear();
1911 19 Mar 13 nicklas 612       json.put("status", "error");
1911 19 Mar 13 nicklas 613       json.put("message", t.getMessage());
1911 19 Mar 13 nicklas 614       json.put("stacktrace", ThrowableUtil.stackTraceToString(t));
1911 19 Mar 13 nicklas 615     }
1911 19 Mar 13 nicklas 616     finally
1911 19 Mar 13 nicklas 617     {
1911 19 Mar 13 nicklas 618       if (dc != null) dc.close();
1911 19 Mar 13 nicklas 619       json.writeJSONString(resp.getWriter());
1911 19 Mar 13 nicklas 620     }
1911 19 Mar 13 nicklas 621     
1911 19 Mar 13 nicklas 622   }
1911 19 Mar 13 nicklas 623   
1959 03 May 13 nicklas 624   
2137 13 Nov 13 nicklas 625   private void addPoolingCalculationsToLib(DbControl dc, Library lib, PooledLibrary pool)
1911 19 Mar 13 nicklas 626   {
1959 03 May 13 nicklas 627     // Load original and SpeedVac:ed concentrations
1959 03 May 13 nicklas 628     // Note that most libs have not been speedvaced and only have an original concentration
1959 03 May 13 nicklas 629     Extract libEx = lib.getExtract();
1959 03 May 13 nicklas 630     Float originalConc = (Float)Annotationtype.QUBIT_CONC.getAnnotationValue(dc, libEx);
1959 03 May 13 nicklas 631     Float speedVacConc = (Float)Annotationtype.QUBIT_CONC_AFTER_SPEEDVAC.getAnnotationValue(dc, libEx);
3309 06 May 15 nicklas 632     Float libConcEst = (Float)Annotationtype.LIBRARY_CONC_EST.getAnnotationValue(dc, libEx);
3309 06 May 15 nicklas 633     
1959 03 May 13 nicklas 634     lib.setAnnotation("originalConc", originalConc);
1959 03 May 13 nicklas 635     lib.setAnnotation("speedVacConc", speedVacConc);
3309 06 May 15 nicklas 636     lib.setAnnotation("libConcEst", libConcEst);
1911 19 Mar 13 nicklas 637     
3309 06 May 15 nicklas 638     Float usedConc = Reggie.firstNonNull(libConcEst, speedVacConc, originalConc);
3309 06 May 15 nicklas 639     
1959 03 May 13 nicklas 640     // Load molarity as calculated from Caliper/Qubit measurements
2454 23 May 14 nicklas 641     Float molarity = (Float)Annotationtype.LIBRARY_MOLARITY_EST.getAnnotationValue(dc, libEx);
1959 03 May 13 nicklas 642     lib.setAnnotation("molarity", molarity);
2454 23 May 14 nicklas 643     lib.loadAnnotations(dc, "libraryFracAdpt", Annotationtype.LIBRARY_FRAC_ADPT, null);
1959 03 May 13 nicklas 644     
1959 03 May 13 nicklas 645     // Load remaining quantity of the lib
2137 13 Nov 13 nicklas 646     Float remain = libEx.getRemainingQuantity();
1959 03 May 13 nicklas 647
1959 03 May 13 nicklas 648     if (pool != null)
1911 19 Mar 13 nicklas 649     {
1959 03 May 13 nicklas 650       // A pool has been "designed", use the quantities as stored in the database
1959 03 May 13 nicklas 651       Float usedQuantity = pool.getExtract().getCreationEvent().getUsedQuantity(libEx);
1959 03 May 13 nicklas 652       lib.setAnnotation("usedQuantity", usedQuantity);
1959 03 May 13 nicklas 653       Float usedVolumeForMix = 1000 * usedQuantity / usedConc;
2025 25 Sep 13 nicklas 654       
2140 18 Nov 13 nicklas 655       // Add the used quantity back since we want the remaining quantity *before* pooling
2140 18 Nov 13 nicklas 656       if (remain != null) remain += usedQuantity; 
1959 03 May 13 nicklas 657       
2140 18 Nov 13 nicklas 658       // The actual volume used when pooling
2140 18 Nov 13 nicklas 659       lib.setAnnotation("actualVolume", usedVolumeForMix);
2140 18 Nov 13 nicklas 660       
2027 30 Sep 13 nicklas 661       // Check if '.dil' exists    
1959 03 May 13 nicklas 662       ItemQuery<Extract> query = Extract.getQuery();
4886 04 Jul 18 nicklas 663       query.restrict(Restrictions.like(Hql.property("name"), Expressions.string(lib.getName()+".dil%")));
1959 03 May 13 nicklas 664       query.restrict(Restrictions.eq(Hql.property("creationEvent.eventDate"), null));
1959 03 May 13 nicklas 665       query.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
1959 03 May 13 nicklas 666       List<Extract> result = query.list(dc);
1959 03 May 13 nicklas 667       if (result.size() == 1)
1959 03 May 13 nicklas 668       {
1959 03 May 13 nicklas 669         Extract dil = result.get(0);
1959 03 May 13 nicklas 670         Float dilQuantity = dil.getOriginalQuantity();
1975 15 May 13 nicklas 671         lib.setAnnotation("mixFactor", (dilQuantity + usedQuantity) / usedQuantity);
2184 09 Jan 14 nicklas 672         // Add the used quantity back since we want the remaining quantity *before* pooling
2186 10 Jan 14 nicklas 673         Float targetVolume = (Float)Annotationtype.POOL_TARGET_VOLUME_PER_LIB.getAnnotationValue(dc, dil);
2186 10 Jan 14 nicklas 674         if (targetVolume != null)
2186 10 Jan 14 nicklas 675         {
2186 10 Jan 14 nicklas 676           lib.setAnnotation("targetVolume", targetVolume);
2186 10 Jan 14 nicklas 677         }
2184 09 Jan 14 nicklas 678         if (remain != null) remain += dilQuantity; 
4886 04 Jul 18 nicklas 679       }
1959 03 May 13 nicklas 680       
1959 03 May 13 nicklas 681       lib.setAnnotation("dils", result.size());
1911 19 Mar 13 nicklas 682     }
2140 18 Nov 13 nicklas 683     
2140 18 Nov 13 nicklas 684     lib.setAnnotation("remainingQuantity", remain);
3309 06 May 15 nicklas 685     if (remain != null && usedConc != null)
2140 18 Nov 13 nicklas 686     {
2140 18 Nov 13 nicklas 687       // Remaining volume in µl
3309 06 May 15 nicklas 688       lib.setAnnotation("remainingVolume", 1000 * remain / usedConc);
2140 18 Nov 13 nicklas 689     }
1911 19 Mar 13 nicklas 690   }
1959 03 May 13 nicklas 691   
2137 13 Nov 13 nicklas 692   
1959 03 May 13 nicklas 693   private JSONObject getJSONForLibPlate(DbControl dc, BioPlate libPlate)
1959 03 May 13 nicklas 694   {
1959 03 May 13 nicklas 695     JSONObject jsonPlate = new JSONObject();
1959 03 May 13 nicklas 696     jsonPlate.put("id", libPlate.getId());
1959 03 May 13 nicklas 697     jsonPlate.put("name", libPlate.getName());
1959 03 May 13 nicklas 698     jsonPlate.put("comments", libPlate.getDescription());
1959 03 May 13 nicklas 699     jsonPlate.put("poolSchema", Annotationtype.POOL_SCHEMA.getAnnotationValue(dc, libPlate));
1959 03 May 13 nicklas 700     jsonPlate.put("barcodeVariant", Annotationtype.BARCODE_VARIANT.getAnnotationValue(dc, libPlate));
3310 07 May 15 nicklas 701     jsonPlate.put("rows", libPlate.getRows());
3310 07 May 15 nicklas 702     jsonPlate.put("columns", libPlate.getColumns());
1959 03 May 13 nicklas 703     return jsonPlate;
1959 03 May 13 nicklas 704   }
1911 19 Mar 13 nicklas 705 }