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

Code
Comments
Other
Rev Date Author Line
2197 14 Jan 14 nicklas 1 package net.sf.basedb.reggie.servlet;
2197 14 Jan 14 nicklas 2
2197 14 Jan 14 nicklas 3 import java.io.IOException;
4044 02 Aug 16 nicklas 4 import java.util.ArrayList;
2197 14 Jan 14 nicklas 5 import java.util.Date;
5867 18 Mar 20 nicklas 6 import java.util.HashMap;
2226 13 Feb 14 nicklas 7 import java.util.HashSet;
2197 14 Jan 14 nicklas 8 import java.util.List;
5867 18 Mar 20 nicklas 9 import java.util.Map;
2226 13 Feb 14 nicklas 10 import java.util.Set;
5885 30 Mar 20 nicklas 11 import java.util.TreeMap;
2197 14 Jan 14 nicklas 12
2197 14 Jan 14 nicklas 13 import javax.servlet.ServletException;
2197 14 Jan 14 nicklas 14 import javax.servlet.http.HttpServlet;
2197 14 Jan 14 nicklas 15 import javax.servlet.http.HttpServletRequest;
2197 14 Jan 14 nicklas 16 import javax.servlet.http.HttpServletResponse;
2197 14 Jan 14 nicklas 17
3699 18 Jan 16 nicklas 18 import org.jdom2.Document;
2197 14 Jan 14 nicklas 19 import org.json.simple.JSONArray;
2197 14 Jan 14 nicklas 20 import org.json.simple.JSONObject;
6661 01 Apr 22 nicklas 21 import org.slf4j.LoggerFactory;
2197 14 Jan 14 nicklas 22
2236 20 Feb 14 nicklas 23 import net.sf.basedb.core.AnyToAny;
3629 26 Nov 15 nicklas 24 import net.sf.basedb.core.BioMaterialEvent;
5867 18 Mar 20 nicklas 25 import net.sf.basedb.core.BioPlate;
5867 18 Mar 20 nicklas 26 import net.sf.basedb.core.BioPlateType;
5867 18 Mar 20 nicklas 27 import net.sf.basedb.core.BioWell;
3692 13 Jan 16 nicklas 28 import net.sf.basedb.core.BooleanParameterType;
3247 14 Apr 15 nicklas 29 import net.sf.basedb.core.ItemList;
2197 14 Jan 14 nicklas 30 import net.sf.basedb.core.DbControl;
2197 14 Jan 14 nicklas 31 import net.sf.basedb.core.DerivedBioAssay;
2226 13 Feb 14 nicklas 32 import net.sf.basedb.core.Extract;
2224 12 Feb 14 nicklas 33 import net.sf.basedb.core.Hardware;
3692 13 Jan 16 nicklas 34 import net.sf.basedb.core.IntegerParameterType;
5867 18 Mar 20 nicklas 35 import net.sf.basedb.core.Item;
2641 09 Sep 14 nicklas 36 import net.sf.basedb.core.ItemNotFoundException;
2197 14 Jan 14 nicklas 37 import net.sf.basedb.core.ItemQuery;
5867 18 Mar 20 nicklas 38 import net.sf.basedb.core.ItemSubtype;
3692 13 Jan 16 nicklas 39 import net.sf.basedb.core.Job;
2197 14 Jan 14 nicklas 40 import net.sf.basedb.core.PhysicalBioAssay;
2224 12 Feb 14 nicklas 41 import net.sf.basedb.core.Protocol;
2197 14 Jan 14 nicklas 42 import net.sf.basedb.core.SessionControl;
6981 17 Jan 23 nicklas 43 import net.sf.basedb.core.StringParameterType;
5867 18 Mar 20 nicklas 44 import net.sf.basedb.core.Tag;
5867 18 Mar 20 nicklas 45 import net.sf.basedb.core.Type;
2197 14 Jan 14 nicklas 46 import net.sf.basedb.core.query.Annotations;
2228 14 Feb 14 nicklas 47 import net.sf.basedb.core.query.Expressions;
2197 14 Jan 14 nicklas 48 import net.sf.basedb.core.query.Hql;
5885 30 Mar 20 nicklas 49 import net.sf.basedb.core.query.Orders;
2197 14 Jan 14 nicklas 50 import net.sf.basedb.core.query.Restrictions;
3697 18 Jan 16 nicklas 51 import net.sf.basedb.core.signal.ExtensionSignalTransporter;
4306 17 Jan 17 nicklas 52 import net.sf.basedb.opengrid.CmdResult;
6661 01 Apr 22 nicklas 53 import net.sf.basedb.opengrid.JobDefinition;
4306 17 Jan 17 nicklas 54 import net.sf.basedb.opengrid.JobStatus;
4306 17 Jan 17 nicklas 55 import net.sf.basedb.opengrid.OpenGrid;
4306 17 Jan 17 nicklas 56 import net.sf.basedb.opengrid.OpenGridCluster;
4306 17 Jan 17 nicklas 57 import net.sf.basedb.opengrid.OpenGridSession;
4306 17 Jan 17 nicklas 58 import net.sf.basedb.opengrid.ScriptBuilder;
4306 17 Jan 17 nicklas 59 import net.sf.basedb.opengrid.service.JobCompletionHandler;
4306 17 Jan 17 nicklas 60 import net.sf.basedb.opengrid.service.OpenGridService;
2598 22 Aug 14 nicklas 61 import net.sf.basedb.reggie.JsonUtil;
2197 14 Jan 14 nicklas 62 import net.sf.basedb.reggie.Reggie;
3129 10 Feb 15 nicklas 63 import net.sf.basedb.reggie.XmlConfig;
5384 26 Apr 19 nicklas 64 import net.sf.basedb.reggie.activity.ActivityDef;
3059 19 Dec 14 nicklas 65 import net.sf.basedb.reggie.counter.CounterService;
2197 14 Jan 14 nicklas 66 import net.sf.basedb.reggie.dao.Annotationtype;
5885 30 Mar 20 nicklas 67 import net.sf.basedb.reggie.dao.BarcodeSet;
2226 13 Feb 14 nicklas 68 import net.sf.basedb.reggie.dao.BiomaterialList;
2236 20 Feb 14 nicklas 69 import net.sf.basedb.reggie.dao.BioplateType;
2197 14 Jan 14 nicklas 70 import net.sf.basedb.reggie.dao.FlowCell;
5470 05 Jun 19 nicklas 71 import net.sf.basedb.reggie.dao.Pipeline;
2226 13 Feb 14 nicklas 72 import net.sf.basedb.reggie.dao.PooledLibrary;
2236 20 Feb 14 nicklas 73 import net.sf.basedb.reggie.dao.ReactionPlate;
2197 14 Jan 14 nicklas 74 import net.sf.basedb.reggie.dao.ReggieRole;
2197 14 Jan 14 nicklas 75 import net.sf.basedb.reggie.dao.SequencingRun;
2197 14 Jan 14 nicklas 76 import net.sf.basedb.reggie.dao.Subtype;
5855 09 Mar 20 nicklas 77 import net.sf.basedb.reggie.extensions.ReggieSignalHandlerFactory;
4306 17 Jan 17 nicklas 78 import net.sf.basedb.reggie.grid.ScriptUtil;
5867 18 Mar 20 nicklas 79 import net.sf.basedb.util.EqualsHelper;
5885 30 Mar 20 nicklas 80 import net.sf.basedb.util.NameableComparator;
2224 12 Feb 14 nicklas 81 import net.sf.basedb.util.Values;
3699 18 Jan 16 nicklas 82 import net.sf.basedb.util.XmlUtil2;
2197 14 Jan 14 nicklas 83 import net.sf.basedb.util.error.ThrowableUtil;
7080 27 Mar 23 nicklas 84 import net.sf.basedb.util.extensions.logging.ExtensionsLog;
7080 27 Mar 23 nicklas 85 import net.sf.basedb.util.extensions.logging.ExtensionsLogger;
5885 30 Mar 20 nicklas 86 import net.sf.basedb.util.formatter.WellCoordinateFormatter;
2197 14 Jan 14 nicklas 87
2197 14 Jan 14 nicklas 88
2197 14 Jan 14 nicklas 89 public class SequencingRunServlet 
2197 14 Jan 14 nicklas 90   extends HttpServlet 
2197 14 Jan 14 nicklas 91 {
2197 14 Jan 14 nicklas 92
2197 14 Jan 14 nicklas 93   private static final long serialVersionUID = 5275254325858237519L;
7080 27 Mar 23 nicklas 94   private static final ExtensionsLogger logger = 
7080 27 Mar 23 nicklas 95       ExtensionsLog.getLogger("net.sf.basedb.reggie", true).wrap(LoggerFactory.getLogger(SequencingRunServlet.class));
2197 14 Jan 14 nicklas 96
2197 14 Jan 14 nicklas 97   public SequencingRunServlet()
2197 14 Jan 14 nicklas 98   {}
2197 14 Jan 14 nicklas 99
2197 14 Jan 14 nicklas 100   @Override
2197 14 Jan 14 nicklas 101   protected void doGet(HttpServletRequest req, HttpServletResponse resp)
2197 14 Jan 14 nicklas 102     throws ServletException, IOException 
2197 14 Jan 14 nicklas 103   {
2197 14 Jan 14 nicklas 104     String cmd = req.getParameter("cmd");
2598 22 Aug 14 nicklas 105     JsonUtil.setJsonResponseHeaders(resp);
2197 14 Jan 14 nicklas 106     
2197 14 Jan 14 nicklas 107     JSONObject json = new JSONObject();
2197 14 Jan 14 nicklas 108     json.put("status", "ok");
2197 14 Jan 14 nicklas 109     
3975 26 May 16 nicklas 110     final SessionControl sc = Reggie.getSessionControl(req);
2197 14 Jan 14 nicklas 111     DbControl dc = null;
4306 17 Jan 17 nicklas 112     OpenGridSession ogSession = null;
2197 14 Jan 14 nicklas 113     try
2197 14 Jan 14 nicklas 114     {
2197 14 Jan 14 nicklas 115
3633 30 Nov 15 nicklas 116       if ("SearchRunArchive".equals(cmd))
2197 14 Jan 14 nicklas 117       {
3564 28 Oct 15 nicklas 118         String clusterId = Values.getStringOrNull(req.getParameter("cluster"));
6334 15 Jun 21 nicklas 119         dc = sc.newDbControl(":Register sequencing ended");
3564 28 Oct 15 nicklas 120         
4306 17 Jan 17 nicklas 121         OpenGridCluster cluster = OpenGridService.getInstance().getClusterById(dc, clusterId);
3564 28 Oct 15 nicklas 122         if (cluster == null)
3564 28 Oct 15 nicklas 123         {
3564 28 Oct 15 nicklas 124           throw new ItemNotFoundException("OpenGridScheduler[" + clusterId + "]");
3564 28 Oct 15 nicklas 125         }
3564 28 Oct 15 nicklas 126         
3564 28 Oct 15 nicklas 127         // Get global options
4306 17 Jan 17 nicklas 128         XmlConfig cfg = Reggie.getConfig(cluster.getId());
4306 17 Jan 17 nicklas 129         if (cfg == null)
4306 17 Jan 17 nicklas 130         {
4306 17 Jan 17 nicklas 131           throw new ItemNotFoundException("No configuration in reggie-config.xml for cluster: " + cluster.getId());
4306 17 Jan 17 nicklas 132         }
4306 17 Jan 17 nicklas 133         String flowCellId = ScriptUtil.checkValidScriptParameter(Values.getStringOrNull(req.getParameter("FlowCellID")));
3699 18 Jan 16 nicklas 134
4306 17 Jan 17 nicklas 135         ogSession = cluster.connect(5);
4306 17 Jan 17 nicklas 136         CmdResult<String> result = getRunParametersXml(ogSession, flowCellId);
3564 28 Oct 15 nicklas 137         
3564 28 Oct 15 nicklas 138         int exitStatus = result.getExitStatus();
3564 28 Oct 15 nicklas 139         json.put("exitStatus", exitStatus);
3564 28 Oct 15 nicklas 140         json.put("stdout", result.getStdout());
3564 28 Oct 15 nicklas 141         json.put("stderr", result.getStderr());
3564 28 Oct 15 nicklas 142         
3564 28 Oct 15 nicklas 143         if (exitStatus == 0)
3564 28 Oct 15 nicklas 144         {
3636 01 Dec 15 nicklas 145           String stdout[] = result.getStdout().split("\n", 3);
3636 01 Dec 15 nicklas 146           json.put("dataFolder", stdout[0]);
3636 01 Dec 15 nicklas 147           json.put("endDateTime", Values.getStringOrNull(stdout[1]));
3636 01 Dec 15 nicklas 148           json.put("runParameters", stdout[2]); 
3564 28 Oct 15 nicklas 149         }
3564 28 Oct 15 nicklas 150       }
3564 28 Oct 15 nicklas 151       else if ("GetActiveSequencingRuns".equals(cmd))
3564 28 Oct 15 nicklas 152       {
5471 05 Jun 19 nicklas 153         Pipeline pipeline = Pipeline.getByCName(req.getParameter("pipeline"));
6334 15 Jun 21 nicklas 154         dc = sc.newDbControl(":Register sequencing ended");
4883 04 Jul 18 nicklas 155         
2197 14 Jan 14 nicklas 156         ItemQuery<DerivedBioAssay> query = DerivedBioAssay.getQuery();
2197 14 Jan 14 nicklas 157         query.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
2197 14 Jan 14 nicklas 158         Subtype.SEQUENCING_RUN.addFilter(dc, query);
5471 05 Jun 19 nicklas 159         pipeline.addFilter(dc, query);
2197 14 Jan 14 nicklas 160         // Must have a SEQUENCING_START annotation
2197 14 Jan 14 nicklas 161         query.join(Annotations.leftJoin(null, Annotationtype.SEQUENCING_START.load(dc), "sst"));
2197 14 Jan 14 nicklas 162         query.restrict(Restrictions.neq(Hql.alias("sst"), null));
2197 14 Jan 14 nicklas 163         // Must NOT have a SEQUENCING_END annotation
2197 14 Jan 14 nicklas 164         query.join(Annotations.leftJoin(null, Annotationtype.SEQUENCING_END.load(dc), "sse"));
2197 14 Jan 14 nicklas 165         query.restrict(Restrictions.eq(Hql.alias("sse"), null));
2225 13 Feb 14 nicklas 166
2197 14 Jan 14 nicklas 167         JSONArray jsonRuns = new JSONArray();
6665 05 Apr 22 nicklas 168         List<SequencingRun> runs = SequencingRun.toList(query.list(dc));
2197 14 Jan 14 nicklas 169         for (SequencingRun run : runs)
2197 14 Jan 14 nicklas 170         {
2225 13 Feb 14 nicklas 171           run.loadAnnotations(dc, "SequencingStart", Annotationtype.SEQUENCING_START, Reggie.CONVERTER_DATE_TO_STRING);
2225 13 Feb 14 nicklas 172           run.loadAnnotations(dc, "HiSeqPosition", Annotationtype.HISEQ_POSITION, null);
5471 05 Jun 19 nicklas 173           run.loadAnnotations(dc, "pipeline", Annotationtype.PIPELINE, null);
3632 30 Nov 15 nicklas 174           Hardware sequencer = run.getDerivedBioAssay().getHardware();
3632 30 Nov 15 nicklas 175           if (sequencer != null)
3632 30 Nov 15 nicklas 176           {
3632 30 Nov 15 nicklas 177             JSONObject jsonSequencer = new JSONObject();
3632 30 Nov 15 nicklas 178             jsonSequencer.put("id", sequencer.getId());
3632 30 Nov 15 nicklas 179             jsonSequencer.put("name", sequencer.getName());
3632 30 Nov 15 nicklas 180             jsonSequencer.put("SerialNumber", Annotationtype.SERIAL_NUMBER.getAnnotationValue(dc, sequencer));
3632 30 Nov 15 nicklas 181             run.setAnnotation("sequencer", jsonSequencer);
3632 30 Nov 15 nicklas 182           }
2197 14 Jan 14 nicklas 183           run.setAnnotation("comments", run.getDerivedBioAssay().getDescription());
2197 14 Jan 14 nicklas 184           
2225 13 Feb 14 nicklas 185           FlowCell fc = FlowCell.getBySequencingRun(dc, run);
2225 13 Feb 14 nicklas 186           fc.loadAnnotations(dc, "FlowCellID", Annotationtype.FLOWCELL_ID, null);
2412 09 May 14 nicklas 187           fc.loadAnnotations(dc, "FlowCellType", Annotationtype.FLOWCELL_TYPE, null);
3632 30 Nov 15 nicklas 188           fc.loadAnnotations(dc, "SequencingCycles", Annotationtype.SEQUENCING_CYCLES, null);
2225 13 Feb 14 nicklas 189           fc.setAnnotation("comments", fc.getItem().getDescription());
2225 13 Feb 14 nicklas 190           
3692 13 Jan 16 nicklas 191           // Load Auto-analyze job
3692 13 Jan 16 nicklas 192           Job autoAnalyze = run.getDerivedBioAssay().getJob();
3692 13 Jan 16 nicklas 193           if (autoAnalyze != null)
3692 13 Jan 16 nicklas 194           {
3692 13 Jan 16 nicklas 195             JSONObject jsonJob = new JSONObject();
3692 13 Jan 16 nicklas 196             jsonJob.put("id", autoAnalyze.getId());
3692 13 Jan 16 nicklas 197             jsonJob.put("name", autoAnalyze.getName());
3718 22 Jan 16 nicklas 198             jsonJob.put("status", autoAnalyze.getStatus().name());
3718 22 Jan 16 nicklas 199             jsonJob.put("progress", autoAnalyze.getPercentComplete());
3718 22 Jan 16 nicklas 200             jsonJob.put("message", autoAnalyze.getStatusMessage());
3692 13 Jan 16 nicklas 201             run.setAnnotation("autoAnalyze", jsonJob);
3692 13 Jan 16 nicklas 202           }
3692 13 Jan 16 nicklas 203           
2236 20 Feb 14 nicklas 204           // Load pools on flow cell
2236 20 Feb 14 nicklas 205           List<PooledLibrary> pools = PooledLibrary.getByFlowCell(dc, fc);
2236 20 Feb 14 nicklas 206           JSONArray jsonPools = new JSONArray();
2236 20 Feb 14 nicklas 207           for (PooledLibrary pool : pools)
2236 20 Feb 14 nicklas 208           {
5473 05 Jun 19 nicklas 209             pool.setAnnotation("libPlates", loadLibPlates(dc, pool));
2236 20 Feb 14 nicklas 210             jsonPools.add(pool.asJSONObject());
2236 20 Feb 14 nicklas 211           }
2236 20 Feb 14 nicklas 212           fc.setAnnotation("pools", jsonPools);
2236 20 Feb 14 nicklas 213           
2225 13 Feb 14 nicklas 214           run.setAnnotation("flowCell", fc.asJSONObject());
2197 14 Jan 14 nicklas 215           jsonRuns.add(run.asJSONObject());
2197 14 Jan 14 nicklas 216         }
2197 14 Jan 14 nicklas 217         
2197 14 Jan 14 nicklas 218         json.put("sequencingRuns", jsonRuns);
2197 14 Jan 14 nicklas 219       }
2226 13 Feb 14 nicklas 220       else if ("GetUnconfirmedSequencingRuns".equals(cmd))
2226 13 Feb 14 nicklas 221       {
5478 10 Jun 19 nicklas 222         Pipeline pipeline = Pipeline.getByCName(req.getParameter("pipeline"));
6334 15 Jun 21 nicklas 223         dc = sc.newDbControl(":Confirm sequencing completed");
2226 13 Feb 14 nicklas 224         ItemQuery<DerivedBioAssay> query = DerivedBioAssay.getQuery();
2226 13 Feb 14 nicklas 225         query.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
2226 13 Feb 14 nicklas 226         Subtype.SEQUENCING_RUN.addFilter(dc, query);
5478 10 Jun 19 nicklas 227         pipeline.addFilter(dc, query);
2226 13 Feb 14 nicklas 228         // Must have a SEQUENCING_END annotation
2226 13 Feb 14 nicklas 229         query.join(Annotations.leftJoin(null, Annotationtype.SEQUENCING_END.load(dc), "sse"));
2226 13 Feb 14 nicklas 230         query.restrict(Restrictions.neq(Hql.alias("sse"), null));
2228 14 Feb 14 nicklas 231         // Must have SEQUENCING_CONFIRMED=FALSE|NULL annotation
2228 14 Feb 14 nicklas 232         query.join(Annotations.leftJoin(null, Annotationtype.SEQUENCING_CONFIRMED.load(dc), "scf"));
2228 14 Feb 14 nicklas 233         query.restrict(
2228 14 Feb 14 nicklas 234             Restrictions.or(
2228 14 Feb 14 nicklas 235               Restrictions.eq(Hql.alias("scf"), Expressions.bool(false)),
2228 14 Feb 14 nicklas 236               Restrictions.eq(Hql.alias("scf"), null)
2228 14 Feb 14 nicklas 237             ));
2226 13 Feb 14 nicklas 238         
2226 13 Feb 14 nicklas 239         JSONArray jsonRuns = new JSONArray();
2226 13 Feb 14 nicklas 240         List<SequencingRun> runs = SequencingRun.toList(query.list(dc));
2226 13 Feb 14 nicklas 241         for (SequencingRun run : runs)
2226 13 Feb 14 nicklas 242         {
5478 10 Jun 19 nicklas 243           run.loadAnnotations(dc, "pipeline", Annotationtype.PIPELINE, null);
2226 13 Feb 14 nicklas 244           run.loadAnnotations(dc, "SequencingStart", Annotationtype.SEQUENCING_START, Reggie.CONVERTER_DATE_TO_STRING);
2226 13 Feb 14 nicklas 245           run.loadAnnotations(dc, "SequencingEnd", Annotationtype.SEQUENCING_END, Reggie.CONVERTER_DATETIME_TO_STRING);
2226 13 Feb 14 nicklas 246           run.loadAnnotations(dc, "HiSeqPosition", Annotationtype.HISEQ_POSITION, null);
2228 14 Feb 14 nicklas 247           run.loadAnnotations(dc, "SequencingResult", Annotationtype.SEQUENCING_RESULT, null);
2641 09 Sep 14 nicklas 248           run.loadAnnotations(dc, "DataFilesFolder", Annotationtype.DATA_FILES_FOLDER, null);
2226 13 Feb 14 nicklas 249           run.setAnnotation("comments", run.getDerivedBioAssay().getDescription());
2641 09 Sep 14 nicklas 250
2236 20 Feb 14 nicklas 251           // Load flow cell information
2226 13 Feb 14 nicklas 252           FlowCell fc = FlowCell.getBySequencingRun(dc, run);
2226 13 Feb 14 nicklas 253           PhysicalBioAssay pba = fc.getItem();
2226 13 Feb 14 nicklas 254           fc.loadAnnotations(dc, "FlowCellID", Annotationtype.FLOWCELL_ID, null);
2412 09 May 14 nicklas 255           fc.loadAnnotations(dc, "FlowCellType", Annotationtype.FLOWCELL_TYPE, null);
2226 13 Feb 14 nicklas 256           fc.setAnnotation("numLanes", pba.getSize());
2226 13 Feb 14 nicklas 257           fc.setAnnotation("comments", pba.getDescription());
2641 09 Sep 14 nicklas 258
2641 09 Sep 14 nicklas 259           String flowCellType = (String)Annotationtype.FLOWCELL_TYPE.getAnnotationValue(dc, pba);
2641 09 Sep 14 nicklas 260           String seqCycles = (String)Annotationtype.SEQUENCING_CYCLES.getAnnotationValue(dc, run.getDerivedBioAssay());
2641 09 Sep 14 nicklas 261           run.setAnnotation("SequencingCycles", seqCycles);
5545 06 Aug 19 nicklas 262           run.setAnnotation("ReadString", DemuxMergeServlet.sequencingCycles2ReadStringPicard(seqCycles, pipeline, flowCellType));
2641 09 Sep 14 nicklas 263
2236 20 Feb 14 nicklas 264           // Load pools on flow cell
2236 20 Feb 14 nicklas 265           List<PooledLibrary> pools = PooledLibrary.getByFlowCell(dc, fc);
2236 20 Feb 14 nicklas 266           JSONArray jsonPools = new JSONArray();
2236 20 Feb 14 nicklas 267           for (PooledLibrary pool : pools)
2236 20 Feb 14 nicklas 268           {
5473 05 Jun 19 nicklas 269             pool.setAnnotation("libPlates", loadLibPlates(dc, pool));
2236 20 Feb 14 nicklas 270             jsonPools.add(pool.asJSONObject());
2236 20 Feb 14 nicklas 271           }
2236 20 Feb 14 nicklas 272           fc.setAnnotation("pools", jsonPools);
2236 20 Feb 14 nicklas 273           
2226 13 Feb 14 nicklas 274           run.setAnnotation("flowCell", fc.asJSONObject());
2226 13 Feb 14 nicklas 275           jsonRuns.add(run.asJSONObject());
2226 13 Feb 14 nicklas 276         }
2226 13 Feb 14 nicklas 277         
2226 13 Feb 14 nicklas 278         json.put("sequencingRuns", jsonRuns);
2226 13 Feb 14 nicklas 279       }
2641 09 Sep 14 nicklas 280       else if ("GetSeqRunInfoForDataCheck".equals(cmd))
2641 09 Sep 14 nicklas 281       {
6334 15 Jun 21 nicklas 282         dc = sc.newDbControl(":Check sequencing files");
2641 09 Sep 14 nicklas 283         int seqRunId = Values.getInt(req.getParameter("seqrun"));
2641 09 Sep 14 nicklas 284
2641 09 Sep 14 nicklas 285         SequencingRun run = SequencingRun.getById(dc, seqRunId);
2641 09 Sep 14 nicklas 286         FlowCell fc = FlowCell.getBySequencingRun(dc, run);
2641 09 Sep 14 nicklas 287         
2641 09 Sep 14 nicklas 288         run.loadAnnotations(dc, "DataFilesFolder", Annotationtype.DATA_FILES_FOLDER, null);
2641 09 Sep 14 nicklas 289         String flowCellType = (String)Annotationtype.FLOWCELL_TYPE.getAnnotationValue(dc, fc.getItem());
2641 09 Sep 14 nicklas 290         String seqCycles = (String)Annotationtype.SEQUENCING_CYCLES.getAnnotationValue(dc, run.getItem());
5545 06 Aug 19 nicklas 291         Pipeline pipeline = Pipeline.getByName((String)Annotationtype.PIPELINE.getAnnotationValue(dc, run.getItem()));
5545 06 Aug 19 nicklas 292         run.setAnnotation("pipeline", pipeline.getName());
2641 09 Sep 14 nicklas 293         run.setAnnotation("SequencingCycles", seqCycles);
5545 06 Aug 19 nicklas 294         run.setAnnotation("ReadString", DemuxMergeServlet.sequencingCycles2ReadStringPicard(seqCycles, pipeline, flowCellType));
2641 09 Sep 14 nicklas 295         fc.loadAnnotations(dc, "FlowCellID", Annotationtype.FLOWCELL_ID, null);
2641 09 Sep 14 nicklas 296         fc.setAnnotation("FlowCellType", flowCellType);
2641 09 Sep 14 nicklas 297         fc.setAnnotation("numLanes", fc.getItem().getSize());
2641 09 Sep 14 nicklas 298         run.setAnnotation("flowCell", fc.asJSONObject());
2641 09 Sep 14 nicklas 299         
2641 09 Sep 14 nicklas 300         json.put("seqRun", run.asJSONObject());
2641 09 Sep 14 nicklas 301       }
2641 09 Sep 14 nicklas 302       else if ("CheckIlluminaDataFiles".equals(cmd))
2641 09 Sep 14 nicklas 303       {
6334 15 Jun 21 nicklas 304         dc = sc.newDbControl(":Check sequencing files");
2641 09 Sep 14 nicklas 305         
2641 09 Sep 14 nicklas 306         String clusterId = Values.getStringOrNull(req.getParameter("cluster"));
2890 03 Nov 14 nicklas 307         String node = Values.getStringOrNull(req.getParameter("node"));
7031 09 Feb 23 nicklas 308         int timeout = Values.getInt(req.getParameter("timeout"), 60);
2890 03 Nov 14 nicklas 309         // Verify that the node parameter is really a node
2890 03 Nov 14 nicklas 310         if (node != null && !node.startsWith("compute-")) node = null;
2890 03 Nov 14 nicklas 311         
4306 17 Jan 17 nicklas 312         OpenGridCluster cluster = OpenGridService.getInstance().getClusterById(dc, clusterId);
2641 09 Sep 14 nicklas 313         if (cluster == null)
2641 09 Sep 14 nicklas 314         {
4306 17 Jan 17 nicklas 315           throw new ItemNotFoundException("OpenGridCluster[" + clusterId + "]");
2641 09 Sep 14 nicklas 316         }
2641 09 Sep 14 nicklas 317         
2641 09 Sep 14 nicklas 318         int seqRunId = Values.getInt(req.getParameter("seqrun"));
4306 17 Jan 17 nicklas 319         String readString = ScriptUtil.checkValidScriptParameter(Values.getStringOrNull(req.getParameter("readString")));
2641 09 Sep 14 nicklas 320         int laneNo = Values.getInt(req.getParameter("lane"));
3704 19 Jan 16 nicklas 321
2641 09 Sep 14 nicklas 322         SequencingRun seqRun = SequencingRun.getById(dc, seqRunId);
4306 17 Jan 17 nicklas 323         String dataFolder = ScriptUtil.checkValidScriptParameter((String)Annotationtype.DATA_FILES_FOLDER.getAnnotationValue(dc, seqRun.getItem()));
2641 09 Sep 14 nicklas 324
4306 17 Jan 17 nicklas 325         ogSession = cluster.connect(5);
7031 09 Feb 23 nicklas 326         CmdResult<String> result = checkIlluminaDirectory(ogSession, node, dataFolder, readString, laneNo, timeout);
2910 10 Nov 14 nicklas 327         int exitStatus = result.getExitStatus();
2910 10 Nov 14 nicklas 328         
2910 10 Nov 14 nicklas 329         json.put("exitStatus", exitStatus);
2641 09 Sep 14 nicklas 330         json.put("stdout", result.getStdout());
2641 09 Sep 14 nicklas 331         json.put("stderr", result.getStderr());
2641 09 Sep 14 nicklas 332       }
5885 30 Mar 20 nicklas 333       else if ("GenerateFakeSampleSheet".equals(cmd))
5885 30 Mar 20 nicklas 334       {
5885 30 Mar 20 nicklas 335         // Generates a fake sample sheet for an external sequencing
6334 15 Jun 21 nicklas 336         dc = sc.newDbControl(":Register external sequencing ");
5885 30 Mar 20 nicklas 337         
5885 30 Mar 20 nicklas 338         String template = Reggie.getTemplateFile("/net/sf/basedb/reggie/templates/external-sequencing-sample-sheet.csv");
5885 30 Mar 20 nicklas 339
5885 30 Mar 20 nicklas 340         int plateId = Values.getInt(req.getParameter("plateId"));
5885 30 Mar 20 nicklas 341         BioPlate plate = BioPlate.getById(dc, plateId);
5885 30 Mar 20 nicklas 342         
5885 30 Mar 20 nicklas 343         ItemQuery<Extract> query = Extract.getQuery();
5885 30 Mar 20 nicklas 344         query.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
5885 30 Mar 20 nicklas 345         query.join(Hql.innerJoin(null, "bioWell", "bw", true));
5885 30 Mar 20 nicklas 346         query.join(Hql.innerJoin("bw", "bioPlate", "bp"));
5885 30 Mar 20 nicklas 347         query.restrict(Restrictions.eq(Hql.alias("bp"), Hql.entity(plate)));
5885 30 Mar 20 nicklas 348         query.order(Orders.asc(Hql.property("bw", "column")));
5885 30 Mar 20 nicklas 349         query.order(Orders.asc(Hql.property("bw", "row")));
5885 30 Mar 20 nicklas 350         List<Extract> libs = query.list(dc);
5885 30 Mar 20 nicklas 351         
5885 30 Mar 20 nicklas 352         ItemQuery<Tag> tagQuery = Tag.getQuery();
5885 30 Mar 20 nicklas 353         tagQuery.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
5885 30 Mar 20 nicklas 354         Pipeline.RNA_SEQ.addFilter(dc, tagQuery);
5885 30 Mar 20 nicklas 355         BarcodeSet.TRUSEQ_UNIQUE_DUAL.addFilter(dc, tagQuery);
5885 30 Mar 20 nicklas 356         List<Tag> tags = tagQuery.list(dc);
5885 30 Mar 20 nicklas 357         
5885 30 Mar 20 nicklas 358         String now = Reggie.CONVERTER_DATE_TO_STRING.convert(new Date());
5885 30 Mar 20 nicklas 359         int fakeRow = 0;
5885 30 Mar 20 nicklas 360         int fakeCol = 0;
5885 30 Mar 20 nicklas 361         WellCoordinateFormatter rowF = new WellCoordinateFormatter(true);
5885 30 Mar 20 nicklas 362         WellCoordinateFormatter colF = new WellCoordinateFormatter(false);
5885 30 Mar 20 nicklas 363         StringBuilder sb = new StringBuilder();
5885 30 Mar 20 nicklas 364         for (int i = 0; i < libs.size() && i < tags.size(); i++)
5885 30 Mar 20 nicklas 365         {
5885 30 Mar 20 nicklas 366           Extract lib = libs.get(i);
5885 30 Mar 20 nicklas 367           Tag tag = tags.get(i);
5885 30 Mar 20 nicklas 368           String index1 = (String)Annotationtype.BARCODE_SEQUENCE.getAnnotationValue(dc, tag);
5885 30 Mar 20 nicklas 369           String index2 = (String)Annotationtype.BARCODE_SEQUENCE_2.getAnnotationValue(dc, tag);
5885 30 Mar 20 nicklas 370           
5885 30 Mar 20 nicklas 371           String fakeCoordinate = rowF.format(fakeRow)+"0"+colF.format(fakeCol);
5889 06 Apr 20 nicklas 372           sb.append(lib.getId()).append(",").append(lib.getName());
5885 30 Mar 20 nicklas 373           sb.append(",FakePlate").append(now).append(",").append(fakeCoordinate).append(",").append(fakeCoordinate);
5885 30 Mar 20 nicklas 374           sb.append(",").append(tag.getName()).append(",").append(index1);
5885 30 Mar 20 nicklas 375           sb.append(",").append(tag.getName()).append(",").append(index2);
5885 30 Mar 20 nicklas 376           sb.append(",FakeProject,FakeDescription");
5885 30 Mar 20 nicklas 377           sb.append("\n");
5885 30 Mar 20 nicklas 378         }
5885 30 Mar 20 nicklas 379         
5885 30 Mar 20 nicklas 380         template = template.replace("${DATE}", now);
5885 30 Mar 20 nicklas 381         template = template.replace("${DATA}", sb.toString());
5885 30 Mar 20 nicklas 382         
5885 30 Mar 20 nicklas 383         json.put("sampleSheet", template);
5885 30 Mar 20 nicklas 384       }
2197 14 Jan 14 nicklas 385     }
2197 14 Jan 14 nicklas 386     catch (Throwable t)
2197 14 Jan 14 nicklas 387     {
2197 14 Jan 14 nicklas 388       t.printStackTrace();
2197 14 Jan 14 nicklas 389       json.clear();
2197 14 Jan 14 nicklas 390       json.put("status", "error");
2197 14 Jan 14 nicklas 391       json.put("message", t.getMessage());
2197 14 Jan 14 nicklas 392       json.put("stacktrace", ThrowableUtil.stackTraceToString(t));
2197 14 Jan 14 nicklas 393     }
2197 14 Jan 14 nicklas 394     finally
2197 14 Jan 14 nicklas 395     {
4306 17 Jan 17 nicklas 396       OpenGrid.close(ogSession);
2197 14 Jan 14 nicklas 397       if (dc != null) dc.close();
2197 14 Jan 14 nicklas 398       json.writeJSONString(resp.getWriter());
2197 14 Jan 14 nicklas 399     }
2197 14 Jan 14 nicklas 400     
2197 14 Jan 14 nicklas 401   }
2197 14 Jan 14 nicklas 402
2197 14 Jan 14 nicklas 403   @Override
2197 14 Jan 14 nicklas 404   protected void doPost(HttpServletRequest req, HttpServletResponse resp)
2197 14 Jan 14 nicklas 405     throws ServletException, IOException 
2197 14 Jan 14 nicklas 406   {
2197 14 Jan 14 nicklas 407     String cmd = req.getParameter("cmd");
2598 22 Aug 14 nicklas 408     JsonUtil.setJsonResponseHeaders(resp);
2197 14 Jan 14 nicklas 409     
2197 14 Jan 14 nicklas 410     JSONObject json = new JSONObject();
2197 14 Jan 14 nicklas 411     json.put("status", "ok");
2197 14 Jan 14 nicklas 412     JSONArray jsonMessages = new JSONArray();
2197 14 Jan 14 nicklas 413   
3975 26 May 16 nicklas 414     final SessionControl sc = Reggie.getSessionControl(req);
2197 14 Jan 14 nicklas 415     DbControl dc = null;
2197 14 Jan 14 nicklas 416     try
2197 14 Jan 14 nicklas 417     {
2224 12 Feb 14 nicklas 418       if ("RegisterSequencingStarted".equals(cmd))
2197 14 Jan 14 nicklas 419       {
6334 15 Jun 21 nicklas 420         dc = sc.newDbControl(":Register sequencing started");
5488 12 Jun 19 nicklas 421         Pipeline pipeline = Pipeline.getByCName(req.getParameter("pipeline"));
5488 12 Jun 19 nicklas 422
5488 12 Jun 19 nicklas 423         ReggieRole.checkPermission(dc, "'" + cmd + "' wizard", pipeline == Pipeline.RNA_SEQ ? ReggieRole.LIBRARY_PREP : ReggieRole.MIPS_LIBRARY_PREP, ReggieRole.ADMINISTRATOR);
2224 12 Feb 14 nicklas 424         
3752 17 Feb 16 nicklas 425         JSONObject jsonReq = JsonUtil.parseRequest(req);
2224 12 Feb 14 nicklas 426         JSONObject jsonSeq = (JSONObject)jsonReq.get("sequencingRun");
2224 12 Feb 14 nicklas 427         JSONObject jsonFlowCell = (JSONObject)jsonReq.get("flowCell");
3692 13 Jan 16 nicklas 428         JSONObject jsonAutoAnalyze = (JSONObject)jsonReq.get("autoAnalyze");
2197 14 Jan 14 nicklas 429
3629 26 Nov 15 nicklas 430         boolean failed = Boolean.TRUE.equals(jsonReq.get("failed"));
3629 26 Nov 15 nicklas 431         ItemList flaggedPools = null;
3629 26 Nov 15 nicklas 432         Set<Extract> pools = null;
3629 26 Nov 15 nicklas 433         int numFlagged = 0;
3629 26 Nov 15 nicklas 434         if (failed)
3629 26 Nov 15 nicklas 435         {
3629 26 Nov 15 nicklas 436           flaggedPools = BiomaterialList.FLAGGED_POOL.load(dc);
3629 26 Nov 15 nicklas 437           pools = new HashSet<Extract>();
3629 26 Nov 15 nicklas 438         }
3629 26 Nov 15 nicklas 439         
2224 12 Feb 14 nicklas 440         Number sequencerId = (Number)jsonSeq.get("sequencer");
2224 12 Feb 14 nicklas 441         Hardware sequencer = sequencerId == null ? null : Hardware.getById(dc, sequencerId.intValue());
2224 12 Feb 14 nicklas 442         Number protocolId = (Number)jsonSeq.get("protocol");
2224 12 Feb 14 nicklas 443         Protocol protocol = protocolId == null ? null : Protocol.getById(dc, protocolId.intValue());
3629 26 Nov 15 nicklas 444         String comments = Values.getStringOrNull((String)jsonSeq.get("comments"));
3629 26 Nov 15 nicklas 445         String operator = Values.getStringOrNull((String)jsonSeq.get("operator"));
3629 26 Nov 15 nicklas 446         String flowCellBarcode = (String)jsonFlowCell.get("FlowCellID");
3629 26 Nov 15 nicklas 447         Date startDate = Reggie.CONVERTER_STRING_TO_DATE.convert((String)jsonSeq.get("startDate"));
2224 12 Feb 14 nicklas 448
3629 26 Nov 15 nicklas 449         // Update flow cell information
2224 12 Feb 14 nicklas 450         Number flowCellId = (Number)jsonFlowCell.get("id");
2224 12 Feb 14 nicklas 451         PhysicalBioAssay flowCell = PhysicalBioAssay.getById(dc, flowCellId.intValue());
3629 26 Nov 15 nicklas 452         BioMaterialEvent createEvent = flowCell.getCreationEvent();
3629 26 Nov 15 nicklas 453         createEvent.setEventDate(startDate);
3629 26 Nov 15 nicklas 454         createEvent.setProtocol(protocol);
3629 26 Nov 15 nicklas 455         createEvent.setHardware(sequencer);
3629 26 Nov 15 nicklas 456         flowCell.setDescription(comments);
3629 26 Nov 15 nicklas 457         Annotationtype.CLUSTER_OPERATOR.setAnnotationValue(dc, flowCell, operator);
3629 26 Nov 15 nicklas 458         Annotationtype.CLUSTER_START.setAnnotationValue(dc, flowCell, startDate);
3629 26 Nov 15 nicklas 459         Annotationtype.FLOWCELL_ID.setAnnotationValue(dc, flowCell, flowCellBarcode);
5475 05 Jun 19 nicklas 460         String flowCellType = (String)Annotationtype.FLOWCELL_TYPE.getAnnotationValue(dc, flowCell);
3629 26 Nov 15 nicklas 461         
3629 26 Nov 15 nicklas 462         // Load pool aliquots for all lanes and set creation date
3629 26 Nov 15 nicklas 463         ItemQuery<Extract> aliquotQuery = flowCell.getExtracts(0);
3629 26 Nov 15 nicklas 464         aliquotQuery.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
3629 26 Nov 15 nicklas 465         for (Extract poolA : aliquotQuery.list(dc))
2239 21 Feb 14 nicklas 466         {
3629 26 Nov 15 nicklas 467           poolA.getCreationEvent().setEventDate(startDate);
3629 26 Nov 15 nicklas 468           if (failed)
3629 26 Nov 15 nicklas 469           {
3629 26 Nov 15 nicklas 470             // If sequencing failed, we flag the pools and add them to the 'Flagged pools' list.
3629 26 Nov 15 nicklas 471             // Typically, most pools have enough material to try again but that
3629 26 Nov 15 nicklas 472             // the responsibility of another wizard
3629 26 Nov 15 nicklas 473             Extract pool = (Extract)poolA.getParent();
3629 26 Nov 15 nicklas 474             if (!pools.contains(pool))
3629 26 Nov 15 nicklas 475             {
3629 26 Nov 15 nicklas 476               pools.add(pool);
3629 26 Nov 15 nicklas 477               flaggedPools.add(pool);
3629 26 Nov 15 nicklas 478               numFlagged++;
3629 26 Nov 15 nicklas 479               Annotationtype.FLAG.setAnnotationValue(dc, pool, PooledLibrary.FLAG_SEQUENCING_FAILED);
3629 26 Nov 15 nicklas 480               Annotationtype.AUTO_PROCESSING.setAnnotationValue(dc, pool, "Disable");
3629 26 Nov 15 nicklas 481             }
3629 26 Nov 15 nicklas 482           }
2239 21 Feb 14 nicklas 483         }
3629 26 Nov 15 nicklas 484         
3629 26 Nov 15 nicklas 485         if (failed)
2344 09 Apr 14 nicklas 486         {
3629 26 Nov 15 nicklas 487           Annotationtype.PLATE_PROCESS_RESULT.setAnnotationValue(dc, flowCell, ReactionPlate.PROCESS_FAILED);
3629 26 Nov 15 nicklas 488           jsonMessages.add("Flow cell '" + flowCell.getName() + "' registered with status: " + (ReactionPlate.PROCESS_FAILED));
3629 26 Nov 15 nicklas 489           if (numFlagged > 0)
3629 26 Nov 15 nicklas 490           {
3629 26 Nov 15 nicklas 491             jsonMessages.add("Added " + numFlagged + " pools to '" + flaggedPools.getName() + "' list.");
3629 26 Nov 15 nicklas 492           }
2344 09 Apr 14 nicklas 493         }
3629 26 Nov 15 nicklas 494         else
3629 26 Nov 15 nicklas 495         {
3629 26 Nov 15 nicklas 496           Annotationtype.PLATE_PROCESS_RESULT.setAnnotationValue(dc, flowCell, ReactionPlate.PROCESS_SUCCESSFUL);
3692 13 Jan 16 nicklas 497           
3692 13 Jan 16 nicklas 498           // Create job for keeping track of sequencing run
4883 04 Jul 18 nicklas 499           String seqRunName = SequencingRun.getNextName(dc);
3692 13 Jan 16 nicklas 500           Job job = null;
3692 13 Jan 16 nicklas 501           if (jsonAutoAnalyze != null)
3692 13 Jan 16 nicklas 502           {
3692 13 Jan 16 nicklas 503             boolean debug = Boolean.TRUE.equals(jsonAutoAnalyze.get("debug"));
3692 13 Jan 16 nicklas 504             Number priority = (Number)jsonAutoAnalyze.get("priority");
6981 17 Jan 23 nicklas 505             String partition = Values.getStringOrNull((String)jsonAutoAnalyze.get("partition"));
3692 13 Jan 16 nicklas 506             String clusterId = (String)jsonAutoAnalyze.get("cluster");
3692 13 Jan 16 nicklas 507             
4306 17 Jan 17 nicklas 508             OpenGridCluster cluster = OpenGridService.getInstance().getClusterById(dc, clusterId);
3692 13 Jan 16 nicklas 509             if (cluster == null)
3692 13 Jan 16 nicklas 510             {
4306 17 Jan 17 nicklas 511               throw new ItemNotFoundException("OpenGridCluster[" + clusterId + "]");
3692 13 Jan 16 nicklas 512             }
3692 13 Jan 16 nicklas 513             
3692 13 Jan 16 nicklas 514             job = Job.getNew(dc, null, null, null);
4325 30 Jan 17 nicklas 515             job.setItemSubtype(Subtype.SEQUENCING_RUN_JOB.get(dc));
3692 13 Jan 16 nicklas 516             job.setPluginVersion("reggie-"+Reggie.VERSION);
3692 13 Jan 16 nicklas 517             job.setSendMessage(Values.getBoolean(sc.getUserClientSetting("plugins.sendmessage"), false));
3692 13 Jan 16 nicklas 518             job.setName(seqRunName + (debug ? " (debug)" : ""));
3692 13 Jan 16 nicklas 519             if (debug)
3692 13 Jan 16 nicklas 520             {
3692 13 Jan 16 nicklas 521               job.setParameterValue("debug", new BooleanParameterType(), debug);
3692 13 Jan 16 nicklas 522             }
3692 13 Jan 16 nicklas 523             if (priority != null)
3692 13 Jan 16 nicklas 524             {
3692 13 Jan 16 nicklas 525               job.setParameterValue("priority", new IntegerParameterType(), priority.intValue());
3692 13 Jan 16 nicklas 526             }
6981 17 Jan 23 nicklas 527             if (partition != null)
6981 17 Jan 23 nicklas 528             {
6981 17 Jan 23 nicklas 529               job.setParameterValue("partition", new StringParameterType(), partition);
6981 17 Jan 23 nicklas 530             }
3629 26 Nov 15 nicklas 531
3692 13 Jan 16 nicklas 532             job.setScheduled(cluster.getId(), null);
3692 13 Jan 16 nicklas 533             job.setExternalId(flowCellBarcode);
4306 17 Jan 17 nicklas 534             
5855 09 Mar 20 nicklas 535             String signalURI = ReggieSignalHandlerFactory.getSignalUri(flowCellType, flowCellBarcode);
5855 09 Mar 20 nicklas 536             if (signalURI != null)
5855 09 Mar 20 nicklas 537             {
5855 09 Mar 20 nicklas 538               job.setSignalTransporter(ExtensionSignalTransporter.class, signalURI);
5855 09 Mar 20 nicklas 539             }
3692 13 Jan 16 nicklas 540             
3692 13 Jan 16 nicklas 541             dc.saveItem(job);
3692 13 Jan 16 nicklas 542           }
3692 13 Jan 16 nicklas 543
3629 26 Nov 15 nicklas 544           // Create new SequencingRun item
3692 13 Jan 16 nicklas 545           DerivedBioAssay sequenceRun = DerivedBioAssay.getNew(dc, true, job);
3629 26 Nov 15 nicklas 546           sequenceRun.setItemSubtype(Subtype.SEQUENCING_RUN.get(dc));
4883 04 Jul 18 nicklas 547           sequenceRun.setName(seqRunName);
3629 26 Nov 15 nicklas 548           sequenceRun.setDescription(comments);
3629 26 Nov 15 nicklas 549           sequenceRun.setHardware(sequencer);
3629 26 Nov 15 nicklas 550           sequenceRun.setProtocol(protocol);
3629 26 Nov 15 nicklas 551           dc.saveItem(sequenceRun);
5470 05 Jun 19 nicklas 552           pipeline.setAnnotation(dc, sequenceRun);
3629 26 Nov 15 nicklas 553           Annotationtype.SEQUENCING_OPERATOR.setAnnotationValue(dc, sequenceRun, operator);
3629 26 Nov 15 nicklas 554           Annotationtype.HISEQ_POSITION.setAnnotationValue(dc, sequenceRun, jsonSeq.get("position"));
3629 26 Nov 15 nicklas 555           sequenceRun.addPhysicalBioAssay(flowCell);
3629 26 Nov 15 nicklas 556   
3629 26 Nov 15 nicklas 557           // Set run parameters
3629 26 Nov 15 nicklas 558           Annotationtype.SEQUENCING_START.setAnnotationValue(dc, sequenceRun, startDate);
3629 26 Nov 15 nicklas 559           jsonMessages.add("Sequencing started for flow cell '" + flowCell.getName() + "': " + sequenceRun.getName());
5470 05 Jun 19 nicklas 560           ActivityDef activity = pipeline == Pipeline.MIPS ? ActivityDef.MIPS_SEQUENCING_STARTED : ActivityDef.RNA_SEQUENCING_STARTED;
5470 05 Jun 19 nicklas 561           activity.create(dc, flowCell.getName(), 1);
5382 24 Apr 19 nicklas 562
3692 13 Jan 16 nicklas 563           if (job != null)
3692 13 Jan 16 nicklas 564           {
3699 18 Jan 16 nicklas 565             Annotationtype.AUTO_PROCESSING.setAnnotationValue(dc, sequenceRun, "AutoConfirm");
3692 13 Jan 16 nicklas 566             jsonMessages.add("Auto-analyze enabled on " + job.getServer());
3692 13 Jan 16 nicklas 567           }
3629 26 Nov 15 nicklas 568         }
2224 12 Feb 14 nicklas 569         
3565 28 Oct 15 nicklas 570         dc.commit();
2224 12 Feb 14 nicklas 571       }
2224 12 Feb 14 nicklas 572       else if ("RegisterSequencingEnded".equals(cmd))
2224 12 Feb 14 nicklas 573       {
6334 15 Jun 21 nicklas 574         dc = sc.newDbControl(":Register sequencing ended");
2224 12 Feb 14 nicklas 575
5488 12 Jun 19 nicklas 576         Pipeline pipeline = Pipeline.getByCName(req.getParameter("pipeline"));
5488 12 Jun 19 nicklas 577         ReggieRole.checkPermission(dc, "'" + cmd + "' wizard", pipeline == Pipeline.RNA_SEQ ? ReggieRole.LIBRARY_PREP : ReggieRole.MIPS_LIBRARY_PREP, ReggieRole.ADMINISTRATOR);
2197 14 Jan 14 nicklas 578
3752 17 Feb 16 nicklas 579         JSONObject jsonReq = JsonUtil.parseRequest(req);
2197 14 Jan 14 nicklas 580         JSONObject jsonSeq = (JSONObject)jsonReq.get("sequencingRun");
2225 13 Feb 14 nicklas 581         JSONObject jsonFlowCell = (JSONObject)jsonSeq.get("flowCell");
3632 30 Nov 15 nicklas 582         JSONObject jsonRunParameters = (JSONObject)jsonReq.get("runParameters");
3632 30 Nov 15 nicklas 583         JSONObject jsonSequencer = (JSONObject)jsonRunParameters.get("sequencer");
3632 30 Nov 15 nicklas 584         
2197 14 Jan 14 nicklas 585         Number seqId = (Number)jsonSeq.get("id");
2197 14 Jan 14 nicklas 586         DerivedBioAssay seqRun = DerivedBioAssay.getById(dc, seqId.intValue());
2225 13 Feb 14 nicklas 587         Number flowCellId = (Number)jsonFlowCell.get("id");
2225 13 Feb 14 nicklas 588         PhysicalBioAssay fc = PhysicalBioAssay.getById(dc, flowCellId.intValue());
3718 22 Jan 16 nicklas 589                 
3632 30 Nov 15 nicklas 590         // New information in this wizard
2197 14 Jan 14 nicklas 591         Date endDate = Reggie.CONVERTER_STRING_TO_DATETIME.convert((String)jsonSeq.get("endDate"));
2197 14 Jan 14 nicklas 592         Annotationtype.SEQUENCING_END.setAnnotationValue(dc, seqRun, endDate);
2228 14 Feb 14 nicklas 593         Annotationtype.SEQUENCING_CONFIRMED.setAnnotationValue(dc, seqRun, false);
2197 14 Jan 14 nicklas 594         seqRun.setDescription((String)jsonSeq.get("comments"));
2197 14 Jan 14 nicklas 595         
3632 30 Nov 15 nicklas 596         Date startDate = Reggie.CONVERTER_STRING_TO_DATE.convert((String)jsonRunParameters.get("SequencingStart"));
3632 30 Nov 15 nicklas 597         if (!startDate.equals(Annotationtype.SEQUENCING_START.getAnnotationValue(dc, seqRun)))
2197 14 Jan 14 nicklas 598         {
3632 30 Nov 15 nicklas 599           jsonMessages.add("Changed start date from " + 
3632 30 Nov 15 nicklas 600               Reggie.CONVERTER_DATE_TO_STRING.convert((Date)Annotationtype.SEQUENCING_START.getAnnotationValue(dc, seqRun)) + 
3632 30 Nov 15 nicklas 601               " to " + Reggie.CONVERTER_DATE_TO_STRING.convert(startDate));
3632 30 Nov 15 nicklas 602           Annotationtype.SEQUENCING_START.setAnnotationValue(dc, seqRun, startDate);
2197 14 Jan 14 nicklas 603         }
3632 30 Nov 15 nicklas 604         
3632 30 Nov 15 nicklas 605         // Possibly modified information from the RunParameters.xml file
3632 30 Nov 15 nicklas 606         String flowCellBarcode = (String)jsonRunParameters.get("FlowCellID");
3632 30 Nov 15 nicklas 607         if (!flowCellBarcode.equals(Annotationtype.FLOWCELL_ID.getAnnotationValue(dc, fc)))
2225 13 Feb 14 nicklas 608         {
3632 30 Nov 15 nicklas 609           jsonMessages.add("Changed FlowCellID from " + 
3632 30 Nov 15 nicklas 610               Annotationtype.FLOWCELL_ID.getAnnotationValue(dc, fc) + 
3632 30 Nov 15 nicklas 611               " to " + flowCellBarcode);
3632 30 Nov 15 nicklas 612           Annotationtype.FLOWCELL_ID.setAnnotationValue(dc, fc, flowCellBarcode);
2225 13 Feb 14 nicklas 613         }
3632 30 Nov 15 nicklas 614
3632 30 Nov 15 nicklas 615         String sequencingCycles = (String)jsonRunParameters.get("SequencingCycles");
3632 30 Nov 15 nicklas 616         if (!sequencingCycles.equals(Annotationtype.SEQUENCING_CYCLES.getAnnotationValue(dc, fc)))
3632 30 Nov 15 nicklas 617         {
3632 30 Nov 15 nicklas 618           jsonMessages.add("Changed SequencingCycles from " + 
3632 30 Nov 15 nicklas 619               Annotationtype.SEQUENCING_CYCLES.getAnnotationValue(dc, fc) + 
3632 30 Nov 15 nicklas 620               " to " + sequencingCycles);
3632 30 Nov 15 nicklas 621           Annotationtype.SEQUENCING_CYCLES.setAnnotationValue(dc, fc, sequencingCycles);
3632 30 Nov 15 nicklas 622         }
2197 14 Jan 14 nicklas 623         
3632 30 Nov 15 nicklas 624         String hiSeqPosition = (String)jsonRunParameters.get("HiSeqPosition");
3632 30 Nov 15 nicklas 625         if (!hiSeqPosition.equals(Annotationtype.HISEQ_POSITION.getAnnotationValue(dc, seqRun)))
3632 30 Nov 15 nicklas 626         {
3632 30 Nov 15 nicklas 627           jsonMessages.add("Changed HiSeqPosition from " + 
3632 30 Nov 15 nicklas 628               Annotationtype.HISEQ_POSITION.getAnnotationValue(dc, seqRun) + 
3632 30 Nov 15 nicklas 629               " to " + hiSeqPosition);
3632 30 Nov 15 nicklas 630           Annotationtype.HISEQ_POSITION.setAnnotationValue(dc, seqRun, hiSeqPosition);
3632 30 Nov 15 nicklas 631         }
3632 30 Nov 15 nicklas 632         
3632 30 Nov 15 nicklas 633         if (jsonSequencer != null)
3632 30 Nov 15 nicklas 634         {
3632 30 Nov 15 nicklas 635           // Update the sequencer
3632 30 Nov 15 nicklas 636           Number sequencerId = (Number)jsonSequencer.get("id");
3632 30 Nov 15 nicklas 637           seqRun.setHardware(Hardware.getById(dc, sequencerId.intValue()));
3632 30 Nov 15 nicklas 638           jsonMessages.add("Changed sequencer to " + seqRun.getHardware().getName());
3632 30 Nov 15 nicklas 639         }
3632 30 Nov 15 nicklas 640
3632 30 Nov 15 nicklas 641         Annotationtype.HISEQ_POSITION.setAnnotationValue(dc, seqRun, jsonRunParameters.get("HiSeqPosition"));
3632 30 Nov 15 nicklas 642         Annotationtype.SEQUENCING_CYCLES.setAnnotationValue(dc, seqRun, sequencingCycles);
3632 30 Nov 15 nicklas 643         Annotationtype.SEQUENCING_RUN_NUMBER.setAnnotationValue(dc, seqRun, jsonRunParameters.get("ScanNumber"));
3632 30 Nov 15 nicklas 644         Annotationtype.DATA_FILES_FOLDER.setAnnotationValue(dc, seqRun, jsonRunParameters.get("RunID"));
3632 30 Nov 15 nicklas 645       
3699 18 Jan 16 nicklas 646         // Reset annotations
3632 30 Nov 15 nicklas 647         Annotationtype.SEQUENCING_RESULT.setAnnotationValue(dc, fc, null);
3699 18 Jan 16 nicklas 648         Annotationtype.AUTO_PROCESSING.setAnnotationValue(dc, seqRun, null);
3718 22 Jan 16 nicklas 649         
3632 30 Nov 15 nicklas 650         jsonMessages.add(seqRun.getName() + " registered as ended.");
5421 13 May 19 nicklas 651         ActivityDef.SEQUENCING_ENDED.create(dc, fc.getName(),  1);
3632 30 Nov 15 nicklas 652         
3718 22 Jan 16 nicklas 653         Job autoAnalyze = seqRun.getJob();
3718 22 Jan 16 nicklas 654         if (autoAnalyze != null)
3718 22 Jan 16 nicklas 655         {
3718 22 Jan 16 nicklas 656           // Manual registration of an auto-analyze job
3718 22 Jan 16 nicklas 657           if (autoAnalyze.getStatus() != Job.Status.ERROR)
3718 22 Jan 16 nicklas 658           {
4359 15 Feb 17 nicklas 659             autoAnalyze.doneOk("Manually registered as ended");
3718 22 Jan 16 nicklas 660           }
3718 22 Jan 16 nicklas 661         }
3718 22 Jan 16 nicklas 662         
2197 14 Jan 14 nicklas 663         dc.commit();
2197 14 Jan 14 nicklas 664       }
2226 13 Feb 14 nicklas 665       else if ("ConfirmSequencingEnded".equals(cmd))
2226 13 Feb 14 nicklas 666       {
6334 15 Jun 21 nicklas 667         dc = sc.newDbControl(":Confirm sequencing completed");
2197 14 Jan 14 nicklas 668
5488 12 Jun 19 nicklas 669         Pipeline pipeline = Pipeline.getByCName(req.getParameter("pipeline"));
5488 12 Jun 19 nicklas 670         ReggieRole.checkPermission(dc, "'" + cmd + "' wizard", pipeline == Pipeline.RNA_SEQ ? ReggieRole.SECONDARY_ANALYSIS : ReggieRole.MIPS_SECONDARY_ANALYSIS, ReggieRole.ADMINISTRATOR);
2226 13 Feb 14 nicklas 671
3752 17 Feb 16 nicklas 672         JSONObject jsonReq = JsonUtil.parseRequest(req);
2226 13 Feb 14 nicklas 673         JSONObject jsonSeq = (JSONObject)jsonReq.get("sequencingRun");
2226 13 Feb 14 nicklas 674         JSONObject jsonFlowCell = (JSONObject)jsonSeq.get("flowCell");
2235 19 Feb 14 nicklas 675         boolean flagPools = Boolean.TRUE.equals(jsonReq.get("flagPools"));
2228 14 Feb 14 nicklas 676         
2226 13 Feb 14 nicklas 677         Number seqId = (Number)jsonSeq.get("id");
2226 13 Feb 14 nicklas 678         DerivedBioAssay seqRun = DerivedBioAssay.getById(dc, seqId.intValue());
2226 13 Feb 14 nicklas 679         seqRun.setDescription((String)jsonSeq.get("comments"));
2228 14 Feb 14 nicklas 680         Annotationtype.SEQUENCING_CONFIRMED.setAnnotationValue(dc, seqRun, true);
2228 14 Feb 14 nicklas 681         String outcome = (String)jsonSeq.get("SequencingResult");
2228 14 Feb 14 nicklas 682
2228 14 Feb 14 nicklas 683         Number fcId = (Number)jsonFlowCell.get("id");
2228 14 Feb 14 nicklas 684         PhysicalBioAssay flowCell = PhysicalBioAssay.getById(dc, fcId.intValue());
2228 14 Feb 14 nicklas 685
2235 19 Feb 14 nicklas 686         if (SequencingRun.SEQUENCING_FAILED.equals(outcome) && flagPools)
2226 13 Feb 14 nicklas 687         {
3247 14 Apr 15 nicklas 688           ItemList flaggedPools = null;
2228 14 Feb 14 nicklas 689           Set<Extract> pools = null;
2228 14 Feb 14 nicklas 690           int numFlagged = 0;
2228 14 Feb 14 nicklas 691           
2228 14 Feb 14 nicklas 692           // Flag pools for re-clustering
2226 13 Feb 14 nicklas 693           flaggedPools = BiomaterialList.FLAGGED_POOL.load(dc);
2226 13 Feb 14 nicklas 694           pools = new HashSet<Extract>();
2228 14 Feb 14 nicklas 695
2226 13 Feb 14 nicklas 696           // Load pool aliquots and pools for all lanes 
2226 13 Feb 14 nicklas 697           ItemQuery<Extract> aliquotQuery = flowCell.getExtracts(0);
2226 13 Feb 14 nicklas 698           aliquotQuery.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
2226 13 Feb 14 nicklas 699           List<Extract> aliquots = aliquotQuery.list(dc);
2226 13 Feb 14 nicklas 700
2226 13 Feb 14 nicklas 701           // If sequencing failed, we flag the pools and add them to the 'Flagged pools' list.
2226 13 Feb 14 nicklas 702           // Typically, most pools have enough material to try clustering again but that
2226 13 Feb 14 nicklas 703           // the responsibility of another wizard
2226 13 Feb 14 nicklas 704           for (Extract poolA : aliquots)
2226 13 Feb 14 nicklas 705           {
2226 13 Feb 14 nicklas 706             Extract pool = (Extract)poolA.getParent();
2226 13 Feb 14 nicklas 707             if (!pools.contains(pool))
2226 13 Feb 14 nicklas 708             {
2226 13 Feb 14 nicklas 709               pools.add(pool);
2226 13 Feb 14 nicklas 710               flaggedPools.add(pool);
2226 13 Feb 14 nicklas 711               numFlagged++;
2226 13 Feb 14 nicklas 712               Annotationtype.FLAG.setAnnotationValue(dc, pool, PooledLibrary.FLAG_SEQUENCING_FAILED);
2226 13 Feb 14 nicklas 713               Annotationtype.AUTO_PROCESSING.setAnnotationValue(dc, pool, "Disable");
2226 13 Feb 14 nicklas 714             }
2226 13 Feb 14 nicklas 715           }
2228 14 Feb 14 nicklas 716           
2228 14 Feb 14 nicklas 717           if (numFlagged > 0)
2228 14 Feb 14 nicklas 718           {
2228 14 Feb 14 nicklas 719             jsonMessages.add("Added " + numFlagged + " pools to '" + flaggedPools.getName() + "' list.");
2228 14 Feb 14 nicklas 720           }
2228 14 Feb 14 nicklas 721
2226 13 Feb 14 nicklas 722         }
2228 14 Feb 14 nicklas 723         else if (SequencingRun.SEQUENCING_SUCCESSFUL.equals(outcome))
2226 13 Feb 14 nicklas 724         {
2226 13 Feb 14 nicklas 725           JSONArray jsonFailedLanes = (JSONArray)jsonFlowCell.get("failedLanes");
2226 13 Feb 14 nicklas 726           Annotationtype.FAILED_LANES.setAnnotationValues(dc, flowCell, jsonFailedLanes);
2226 13 Feb 14 nicklas 727           if (jsonFailedLanes.size() > 0)
2226 13 Feb 14 nicklas 728           {
2226 13 Feb 14 nicklas 729             Object lastLane = jsonFailedLanes.get(jsonFailedLanes.size()-1);
2226 13 Feb 14 nicklas 730             String lanes;
2226 13 Feb 14 nicklas 731             if (jsonFailedLanes.size() == 1)
2226 13 Feb 14 nicklas 732             {
2226 13 Feb 14 nicklas 733               lanes = "Lane " + lastLane.toString();
2226 13 Feb 14 nicklas 734             }
2226 13 Feb 14 nicklas 735             else
2226 13 Feb 14 nicklas 736             {
2226 13 Feb 14 nicklas 737               lanes = "Lanes " + Values.getString(jsonFailedLanes.subList(0, jsonFailedLanes.size()-1), ", ", true) + " and " + lastLane;
2226 13 Feb 14 nicklas 738             }
2226 13 Feb 14 nicklas 739             jsonMessages.add(lanes + " registered as failed.");
2226 13 Feb 14 nicklas 740           }
5421 13 May 19 nicklas 741           ActivityDef.SEQUENCING_CONFIRMED.create(dc, flowCell.getName(), 1);
2226 13 Feb 14 nicklas 742         }
2226 13 Feb 14 nicklas 743         
2228 14 Feb 14 nicklas 744         Annotationtype.SEQUENCING_RESULT.setAnnotationValue(dc, seqRun, outcome);
3635 30 Nov 15 nicklas 745         Annotationtype.SEQUENCING_RESULT.setAnnotationValue(dc, flowCell, outcome);
2228 14 Feb 14 nicklas 746         jsonMessages.add(seqRun.getName() + " confirmed with status: " + outcome);
5382 24 Apr 19 nicklas 747         
2226 13 Feb 14 nicklas 748         dc.commit();
2226 13 Feb 14 nicklas 749       }
5867 18 Mar 20 nicklas 750       
5867 18 Mar 20 nicklas 751       else if ("CheckExternalSequencing".equals(cmd))
5867 18 Mar 20 nicklas 752       {
6334 15 Jun 21 nicklas 753         dc = sc.newDbControl(":Register external sequencing ");
2226 13 Feb 14 nicklas 754
5867 18 Mar 20 nicklas 755         ReggieRole.checkPermission(dc, "'" + cmd + "' wizard", ReggieRole.SECONDARY_ANALYSIS, ReggieRole.ADMINISTRATOR);
5867 18 Mar 20 nicklas 756
5867 18 Mar 20 nicklas 757         JSONObject jsonReq = JsonUtil.parseRequest(req);
5867 18 Mar 20 nicklas 758         JSONArray jsonLibs = (JSONArray)jsonReq.get("libraries");
5867 18 Mar 20 nicklas 759         
5867 18 Mar 20 nicklas 760         ItemQuery<Extract> findLib = Extract.getQuery();
5867 18 Mar 20 nicklas 761         findLib.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
5867 18 Mar 20 nicklas 762         Subtype.LIBRARY.addFilter(dc, findLib);
5889 06 Apr 20 nicklas 763         findLib.restrict(Restrictions.eq(Hql.property("id"), Expressions.parameter("libId")));
5867 18 Mar 20 nicklas 764         
5867 18 Mar 20 nicklas 765         ItemQuery<Tag> findBarcode = Tag.getQuery();
5867 18 Mar 20 nicklas 766         findBarcode.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
5867 18 Mar 20 nicklas 767         Subtype.BARCODE.addFilter(dc, findBarcode);
5867 18 Mar 20 nicklas 768         findBarcode.restrict(Restrictions.eq(Hql.property("name"), Expressions.parameter("barcode")));
5867 18 Mar 20 nicklas 769         
5867 18 Mar 20 nicklas 770         JSONArray jsonErrors = new JSONArray();
5867 18 Mar 20 nicklas 771         
5867 18 Mar 20 nicklas 772         Map<String, Number> usedItems = new HashMap<>();
5885 30 Mar 20 nicklas 773         Map<BioPlate, Integer> libPlates = new TreeMap<>(new NameableComparator<>(false));
5867 18 Mar 20 nicklas 774         Set<Integer> libsInSampleSheet = new HashSet<>();
5867 18 Mar 20 nicklas 775         for (int libNo = 0; libNo < jsonLibs.size(); libNo++)
5867 18 Mar 20 nicklas 776         {
5867 18 Mar 20 nicklas 777           JSONObject jsonLib = (JSONObject)jsonLibs.get(libNo);
5867 18 Mar 20 nicklas 778           Number lineNo = (Number)jsonLib.get("lineNo");
5909 17 Apr 20 nicklas 779           String libId = (String)jsonLib.get("sampleId");
5889 06 Apr 20 nicklas 780
5909 17 Apr 20 nicklas 781           String name = (String)jsonLib.get("sampleName");
5867 18 Mar 20 nicklas 782           String barcodeName = (String)jsonLib.get("barcode");
5867 18 Mar 20 nicklas 783           
5889 06 Apr 20 nicklas 784           if (usedItems.containsKey(name))
5867 18 Mar 20 nicklas 785           {
5889 06 Apr 20 nicklas 786             jsonErrors.add("[Error] Line " + lineNo + ": Duplicate library '" + name + "' also used on line " + usedItems.get(name));
5867 18 Mar 20 nicklas 787           }
5867 18 Mar 20 nicklas 788           else
5867 18 Mar 20 nicklas 789           {
5889 06 Apr 20 nicklas 790             usedItems.put(name, lineNo);
5889 06 Apr 20 nicklas 791             
5889 06 Apr 20 nicklas 792             int id = Values.getInt(libId);
5889 06 Apr 20 nicklas 793             if (id == 0)
5867 18 Mar 20 nicklas 794             {
5889 06 Apr 20 nicklas 795               jsonErrors.add("[Error] Line " + lineNo + ": Sample_ID is missing or not a number: " + libId);
5867 18 Mar 20 nicklas 796             }
5867 18 Mar 20 nicklas 797             else
5867 18 Mar 20 nicklas 798             {
5889 06 Apr 20 nicklas 799               findLib.setParameter("libId", id, Type.INT);
5889 06 Apr 20 nicklas 800               List<Extract> libs = findLib.list(dc);
5889 06 Apr 20 nicklas 801               if (libs.size() == 1)
5867 18 Mar 20 nicklas 802               {
5889 06 Apr 20 nicklas 803                 Extract lib = libs.get(0);
5909 17 Apr 20 nicklas 804                 jsonLib.put("libId", lib.getId());
5889 06 Apr 20 nicklas 805                 libsInSampleSheet.add(lib.getId());
5889 06 Apr 20 nicklas 806                 
5889 06 Apr 20 nicklas 807                 Date libCreatedDate = lib.getCreationEvent().getEventDate();
5889 06 Apr 20 nicklas 808                 if (libCreatedDate != null)
5889 06 Apr 20 nicklas 809                 {
5889 06 Apr 20 nicklas 810                   jsonErrors.add("[Error] Line " + lineNo + ": Library '" + lib.getName() + "' is already registered for sequencing (Created date: " + Reggie.CONVERTER_DATE_TO_STRING_WITH_SEPARATOR.convert(libCreatedDate) + ")");
5889 06 Apr 20 nicklas 811                 }
5889 06 Apr 20 nicklas 812                 
5889 06 Apr 20 nicklas 813                 if (!lib.getName().contains(name))
5889 06 Apr 20 nicklas 814                 {
5889 06 Apr 20 nicklas 815                   jsonMessages.add("[Warning] Line " + lineNo +": Sample_Name doesn't match library name: " + name + " / " + lib.getName());
5889 06 Apr 20 nicklas 816                 }
5889 06 Apr 20 nicklas 817                 
5889 06 Apr 20 nicklas 818                 BioWell well = lib.getBioWell();
5889 06 Apr 20 nicklas 819                 if (well != null) 
5889 06 Apr 20 nicklas 820                 {
5889 06 Apr 20 nicklas 821                   BioPlate plate = well.getPlate();
5889 06 Apr 20 nicklas 822                   int libsOnPlate = libPlates.containsKey(plate) ? libPlates.get(plate)+1 : 1;
5889 06 Apr 20 nicklas 823                   libPlates.put(plate, libsOnPlate);
5889 06 Apr 20 nicklas 824                   // Don't need this now, but maybe in the future
5889 06 Apr 20 nicklas 825                   //jsonLib.put("bioWell", JsonUtil.getBioWellAsJSON(well, true));
5889 06 Apr 20 nicklas 826                 }
5889 06 Apr 20 nicklas 827                 
5867 18 Mar 20 nicklas 828               }
5867 18 Mar 20 nicklas 829               else
5867 18 Mar 20 nicklas 830               {
5889 06 Apr 20 nicklas 831                 if (libs.size() == 0)
5889 06 Apr 20 nicklas 832                 {
5889 06 Apr 20 nicklas 833                   jsonErrors.add("[Error] Line " + lineNo + ": Can't find library with id=" + libId + " ('" + name + "')");
5889 06 Apr 20 nicklas 834                 }
5889 06 Apr 20 nicklas 835                 else
5889 06 Apr 20 nicklas 836                 {
5889 06 Apr 20 nicklas 837                   jsonErrors.add("[Error] Line " + lineNo + ": Found " + libs.size() + " items with name '" + name + "'");
5889 06 Apr 20 nicklas 838                 }
5867 18 Mar 20 nicklas 839               }
5867 18 Mar 20 nicklas 840             }
5867 18 Mar 20 nicklas 841           }
5867 18 Mar 20 nicklas 842           
5867 18 Mar 20 nicklas 843           if (usedItems.containsKey(barcodeName))
5867 18 Mar 20 nicklas 844           {
5867 18 Mar 20 nicklas 845             jsonErrors.add("[Error] Line " + lineNo + ": Duplicate barcode '" + barcodeName + "' also used on line " + usedItems.get(barcodeName));
5867 18 Mar 20 nicklas 846           }
5867 18 Mar 20 nicklas 847           else
5867 18 Mar 20 nicklas 848           {
5867 18 Mar 20 nicklas 849             usedItems.put(barcodeName, lineNo);
5867 18 Mar 20 nicklas 850             findBarcode.setParameter("barcode", barcodeName, Type.STRING);
5867 18 Mar 20 nicklas 851             List<Tag> barcodes = findBarcode.list(dc);
5867 18 Mar 20 nicklas 852             if (barcodes.size() == 1)
5867 18 Mar 20 nicklas 853             {
5867 18 Mar 20 nicklas 854               Tag barcode = barcodes.get(0);
5867 18 Mar 20 nicklas 855               jsonLib.put("barcodeId", barcode.getId());
5867 18 Mar 20 nicklas 856
5867 18 Mar 20 nicklas 857               String index1 = (String)jsonLib.get("index1");
5867 18 Mar 20 nicklas 858               String index2 = (String)jsonLib.get("index2");
5867 18 Mar 20 nicklas 859               String seq1 = (String)Annotationtype.BARCODE_SEQUENCE.getAnnotationValue(dc, barcode);
5867 18 Mar 20 nicklas 860               String seq2 = (String)Annotationtype.BARCODE_SEQUENCE_2.getAnnotationValue(dc, barcode);
5867 18 Mar 20 nicklas 861               if (!EqualsHelper.equals(index1, seq1))
5867 18 Mar 20 nicklas 862               {
5867 18 Mar 20 nicklas 863                 jsonErrors.add("[Error] Line " + lineNo + ": Barcode sequence mismatch for " + barcodeName + ": " + index1 + "!="+seq1);
5867 18 Mar 20 nicklas 864               }
5867 18 Mar 20 nicklas 865               if (!EqualsHelper.equals(index2, seq2))
5867 18 Mar 20 nicklas 866               {
5867 18 Mar 20 nicklas 867                 jsonErrors.add("[Error] Line " + lineNo + ": Barcode sequence mismatch for " + barcodeName + ": " + index2 + "!="+seq2);
5867 18 Mar 20 nicklas 868               }
5867 18 Mar 20 nicklas 869             }
5867 18 Mar 20 nicklas 870             else
5867 18 Mar 20 nicklas 871             {
5867 18 Mar 20 nicklas 872               if (barcodes.size() == 0)
5867 18 Mar 20 nicklas 873               {
5867 18 Mar 20 nicklas 874                 jsonErrors.add("[Error] Line " + lineNo + ": Can't find barcode '" + barcodeName + "'");
5867 18 Mar 20 nicklas 875               }
5867 18 Mar 20 nicklas 876               else
5867 18 Mar 20 nicklas 877               {
5867 18 Mar 20 nicklas 878                 jsonErrors.add("[Error] Line " + lineNo + ": Found " + barcodes.size() + " barcode with name '" + barcodeName + "'");
5867 18 Mar 20 nicklas 879               }
5867 18 Mar 20 nicklas 880             }
5867 18 Mar 20 nicklas 881           }
5867 18 Mar 20 nicklas 882         }
5867 18 Mar 20 nicklas 883         
5867 18 Mar 20 nicklas 884         json.put("libraries", jsonLibs);
5867 18 Mar 20 nicklas 885         json.put("numErrors", jsonErrors.size());
5867 18 Mar 20 nicklas 886         jsonMessages.addAll(jsonErrors);
5867 18 Mar 20 nicklas 887         if (jsonErrors.size() == 0)
5867 18 Mar 20 nicklas 888         {
5867 18 Mar 20 nicklas 889           // Check if there are remaining libraries on the used lib plates
5867 18 Mar 20 nicklas 890           if (libPlates.size() > 0)
5867 18 Mar 20 nicklas 891           {
5867 18 Mar 20 nicklas 892             ItemQuery<Extract> query = Extract.getQuery();
5867 18 Mar 20 nicklas 893             query.join(Hql.innerJoin("bioWell", "bw"));
5867 18 Mar 20 nicklas 894             query.join(Hql.innerJoin("bw", "bioPlate", "p"));
5867 18 Mar 20 nicklas 895             query.join(Hql.innerJoin("creationEvent", "ce"));
5867 18 Mar 20 nicklas 896             query.restrict(Restrictions.eq(Hql.alias("p"), Hql.entityParameter("libPlate", Item.BIOPLATE)));
5867 18 Mar 20 nicklas 897             query.restrict(Restrictions.eq(Hql.property("ce", "eventDate"), null));
5867 18 Mar 20 nicklas 898             query.restrict(Restrictions.not(
5867 18 Mar 20 nicklas 899               Restrictions.in(Hql.property("id"), Expressions.parameter("libs", libsInSampleSheet, Type.INT))
5867 18 Mar 20 nicklas 900               ));
5867 18 Mar 20 nicklas 901             
5867 18 Mar 20 nicklas 902             BioPlateType externalType = BioplateType.EXTERNAL_LIBRARY.load(dc);
5885 30 Mar 20 nicklas 903             for (BioPlate libPlate : libPlates.keySet())
5867 18 Mar 20 nicklas 904             {
5885 30 Mar 20 nicklas 905               jsonMessages.add(libPlates.get(libPlate) + " libraries on '" + libPlate.getName() + "'");
5867 18 Mar 20 nicklas 906               if (!externalType.equals(libPlate.getBioPlateType()))
5867 18 Mar 20 nicklas 907               {
5867 18 Mar 20 nicklas 908                 jsonMessages.add("[Warning] '" + libPlate.getName() + "' is not an 'External library plate'");
5867 18 Mar 20 nicklas 909               }
5867 18 Mar 20 nicklas 910               query.setEntityParameter("libPlate", libPlate);
5867 18 Mar 20 nicklas 911               long remainingLibs = query.count(dc);
5867 18 Mar 20 nicklas 912               if (remainingLibs > 0)
5867 18 Mar 20 nicklas 913               {
5867 18 Mar 20 nicklas 914                 jsonMessages.add("[Warning] On '" + libPlate.getName() + "' there are " + remainingLibs + " remaining libraries not in the sample sheet");
5867 18 Mar 20 nicklas 915               }
5867 18 Mar 20 nicklas 916             }
5867 18 Mar 20 nicklas 917           }
5867 18 Mar 20 nicklas 918         }
5867 18 Mar 20 nicklas 919       }
5867 18 Mar 20 nicklas 920       
5867 18 Mar 20 nicklas 921       else if ("RegisterExternalSequencing".equals(cmd))
5867 18 Mar 20 nicklas 922       {
6334 15 Jun 21 nicklas 923         dc = sc.newDbControl(":Register external sequencing");
5867 18 Mar 20 nicklas 924
5867 18 Mar 20 nicklas 925         ReggieRole.checkPermission(dc, "'" + cmd + "' wizard", ReggieRole.SECONDARY_ANALYSIS, ReggieRole.ADMINISTRATOR);
5867 18 Mar 20 nicklas 926
5867 18 Mar 20 nicklas 927         JSONObject jsonReq = JsonUtil.parseRequest(req);
5867 18 Mar 20 nicklas 928         JSONArray jsonLibs = (JSONArray)jsonReq.get("libraries");
5867 18 Mar 20 nicklas 929         JSONObject jsonAutoAnalyze = (JSONObject)jsonReq.get("autoAnalyze");
5867 18 Mar 20 nicklas 930         String flowCellId = (String)jsonReq.get("flowCellId");
5867 18 Mar 20 nicklas 931         String flowCellType = (String)jsonReq.get("flowCellType");
5867 18 Mar 20 nicklas 932         Date startDate = Reggie.CONVERTER_STRING_TO_DATE.convert((String)jsonReq.get("startDate"));
5867 18 Mar 20 nicklas 933         Number numLanes = (Number)jsonReq.get("numLanes");
5870 20 Mar 20 nicklas 934         String operator = (String)jsonReq.get("operator");
5886 30 Mar 20 nicklas 935         Number libProtocolId = (Number)jsonReq.get("libProtocol");
5870 20 Mar 20 nicklas 936         String comments = Values.getStringOrNull((String)jsonReq.get("comments"));
5867 18 Mar 20 nicklas 937         
5886 30 Mar 20 nicklas 938         Protocol libProtocol = libProtocolId != null ? Protocol.getById(dc, libProtocolId.intValue()) : null;
5886 30 Mar 20 nicklas 939         
5867 18 Mar 20 nicklas 940         Extract pool = Extract.getNew(dc);
5867 18 Mar 20 nicklas 941         pool.setItemSubtype(Subtype.POOLED_LIBRARY.load(dc));
5867 18 Mar 20 nicklas 942         Pipeline.RNA_SEQ.setAnnotation(dc, pool);
5867 18 Mar 20 nicklas 943         pool.setName(PooledLibrary.getNextNames(dc, 1).get(0));
5870 20 Mar 20 nicklas 944         Annotationtype.POOL_DATE.setAnnotationValue(dc, pool, startDate);
5870 20 Mar 20 nicklas 945         Annotationtype.POOL_OPERATOR.setAnnotationValue(dc, pool, operator);
5867 18 Mar 20 nicklas 946         dc.saveItem(pool);
5867 18 Mar 20 nicklas 947         jsonMessages.add("Created " + pool.getName() + " with " + jsonLibs.size() + " libraries");
5867 18 Mar 20 nicklas 948       
5867 18 Mar 20 nicklas 949         BioMaterialEvent poolEvent = pool.getCreationEvent();
5867 18 Mar 20 nicklas 950         poolEvent.setEventDate(startDate);
5867 18 Mar 20 nicklas 951         poolEvent.setProtocol(null); // To avoid that a 'project default' is used
5867 18 Mar 20 nicklas 952         poolEvent.setHardware(null);
5867 18 Mar 20 nicklas 953         
5867 18 Mar 20 nicklas 954         Set<BioPlate> libPlates = new HashSet<>();
5867 18 Mar 20 nicklas 955         for (int libNo = 0; libNo < jsonLibs.size(); libNo++)
5867 18 Mar 20 nicklas 956         {
5867 18 Mar 20 nicklas 957           JSONObject jsonLib = (JSONObject)jsonLibs.get(libNo);
5909 17 Apr 20 nicklas 958           Number libId = (Number)jsonLib.get("libId");
5867 18 Mar 20 nicklas 959           Number barcodeId = (Number)jsonLib.get("barcodeId");
5867 18 Mar 20 nicklas 960           
5870 20 Mar 20 nicklas 961           String externalPlate = (String)jsonLib.get("plate");
5870 20 Mar 20 nicklas 962           String externalWell = (String)jsonLib.get("well");
5870 20 Mar 20 nicklas 963           
5867 18 Mar 20 nicklas 964           Extract lib = Extract.getById(dc, libId.intValue());
5867 18 Mar 20 nicklas 965           Tag barcode = Tag.getById(dc, barcodeId.intValue());
5867 18 Mar 20 nicklas 966           BioWell well = lib.getBioWell();
5867 18 Mar 20 nicklas 967           if (well != null)
5867 18 Mar 20 nicklas 968           {
5867 18 Mar 20 nicklas 969             BioPlate plate = well.getPlate();
5867 18 Mar 20 nicklas 970             libPlates.add(plate);
5867 18 Mar 20 nicklas 971           }
5867 18 Mar 20 nicklas 972           
5867 18 Mar 20 nicklas 973           // Update library properties
5867 18 Mar 20 nicklas 974           lib.setTag(barcode);
5886 30 Mar 20 nicklas 975           BioMaterialEvent libCreateEvent = lib.getCreationEvent();
5886 30 Mar 20 nicklas 976           libCreateEvent.setEventDate(startDate);
5886 30 Mar 20 nicklas 977           if (libProtocol != null) libCreateEvent.setProtocol(libProtocol);
5870 20 Mar 20 nicklas 978           Annotationtype.EXTERNAL_OPERATOR.setAnnotationValue(dc, lib, operator);
5870 20 Mar 20 nicklas 979           if (externalPlate != null && externalWell != null)
5870 20 Mar 20 nicklas 980           {
5870 20 Mar 20 nicklas 981             Annotationtype.EXTERNAL_PLATE_POS.setAnnotationValue(dc, lib, externalPlate + " " + externalWell);
5870 20 Mar 20 nicklas 982           }
5867 18 Mar 20 nicklas 983           
5867 18 Mar 20 nicklas 984           // Link with pool
5867 18 Mar 20 nicklas 985           poolEvent.addSource(lib);
5867 18 Mar 20 nicklas 986         }
5867 18 Mar 20 nicklas 987         
5867 18 Mar 20 nicklas 988         // Link pool with lib plates
5867 18 Mar 20 nicklas 989         int plateNo = 0;
5867 18 Mar 20 nicklas 990         for (BioPlate plate : libPlates)
5867 18 Mar 20 nicklas 991         {
5870 20 Mar 20 nicklas 992           plate.setEventDate(startDate);
5870 20 Mar 20 nicklas 993           if (comments != null)
5870 20 Mar 20 nicklas 994           {
5870 20 Mar 20 nicklas 995             // Merge comments with existing on library plate
5870 20 Mar 20 nicklas 996             String currentComment = plate.getDescription();
5870 20 Mar 20 nicklas 997             currentComment = currentComment == null ? comments : currentComment + "\n\n" + comments;
5870 20 Mar 20 nicklas 998             plate.setDescription(comments);
5870 20 Mar 20 nicklas 999           }
5870 20 Mar 20 nicklas 1000           Annotationtype.EXTERNAL_OPERATOR.setAnnotationValue(dc, plate, operator);
5871 20 Mar 20 nicklas 1001           Annotationtype.PLATE_PROCESS_RESULT.setAnnotationValue(dc, plate, ReactionPlate.PROCESS_SUCCESSFUL);
5867 18 Mar 20 nicklas 1002           String linkSuffix = plateNo == 0 ? "" : "."+(plateNo+1);
5867 18 Mar 20 nicklas 1003           AnyToAny libPlateLink = AnyToAny.getNew(dc, pool, plate, "LibPlate"+linkSuffix, true);
5867 18 Mar 20 nicklas 1004           dc.saveItem(libPlateLink);
5867 18 Mar 20 nicklas 1005           plateNo++;
5867 18 Mar 20 nicklas 1006         }
5867 18 Mar 20 nicklas 1007         
5867 18 Mar 20 nicklas 1008         // Create FlowCell and SequencingRun
5867 18 Mar 20 nicklas 1009         PhysicalBioAssay flowCell = PhysicalBioAssay.getNew(dc);
5867 18 Mar 20 nicklas 1010         flowCell.setItemSubtype(Subtype.FLOW_CELL.load(dc));
5867 18 Mar 20 nicklas 1011         Pipeline.RNA_SEQ.setAnnotation(dc, flowCell);
5867 18 Mar 20 nicklas 1012         flowCell.setName(FlowCell.getNextNames(dc, 1).get(0));
5870 20 Mar 20 nicklas 1013         flowCell.setDescription(comments);
5867 18 Mar 20 nicklas 1014         flowCell.setSize(numLanes.intValue());
5867 18 Mar 20 nicklas 1015         Annotationtype.FLOWCELL_ID.setAnnotationValue(dc, flowCell, flowCellId);
5867 18 Mar 20 nicklas 1016         Annotationtype.FLOWCELL_TYPE.setAnnotationValue(dc, flowCell, flowCellType);
5870 20 Mar 20 nicklas 1017         Annotationtype.CLUSTER_OPERATOR.setAnnotationValue(dc, flowCell, operator);
5869 19 Mar 20 nicklas 1018         Annotationtype.PLATE_PROCESS_RESULT.setAnnotationValue(dc, flowCell, ReactionPlate.PROCESS_SUCCESSFUL);
5867 18 Mar 20 nicklas 1019         dc.saveItem(flowCell);
5867 18 Mar 20 nicklas 1020         jsonMessages.add("Created " + flowCell.getName() + " with " + numLanes + " lanes");
5867 18 Mar 20 nicklas 1021
5867 18 Mar 20 nicklas 1022         // Create pool aliquots
5867 18 Mar 20 nicklas 1023         BioMaterialEvent flowCellEvent = flowCell.getCreationEvent();
5867 18 Mar 20 nicklas 1024         flowCellEvent.setEventDate(startDate);
5867 18 Mar 20 nicklas 1025         flowCellEvent.setHardware(null); // To prevent 'project default'
5867 18 Mar 20 nicklas 1026         flowCellEvent.setProtocol(null);
5867 18 Mar 20 nicklas 1027         ItemSubtype poolAliquotType = Subtype.POOLED_LIBRARY_ALIQUOT.load(dc);
6196 31 Mar 21 nicklas 1028         String suffix = Values.getString(Subtype.POOLED_LIBRARY_ALIQUOT.getItemSuffix(), "");
5867 18 Mar 20 nicklas 1029         for (int laneNo = 1; laneNo <= flowCell.getSize(); laneNo++)
5867 18 Mar 20 nicklas 1030         {
5867 18 Mar 20 nicklas 1031           Extract poolA = Extract.getNew(dc);
5867 18 Mar 20 nicklas 1032           poolA.setItemSubtype(poolAliquotType);
6196 31 Mar 21 nicklas 1033           poolA.setName(pool.getName()+"."+suffix+laneNo);
5867 18 Mar 20 nicklas 1034           Pipeline.RNA_SEQ.setAnnotation(dc, poolA);
5867 18 Mar 20 nicklas 1035           poolA.getCreationEvent().setSource(pool);
5867 18 Mar 20 nicklas 1036           flowCellEvent.addSource(poolA).setPosition(laneNo);
5867 18 Mar 20 nicklas 1037           dc.saveItem(poolA);
5867 18 Mar 20 nicklas 1038         }
5867 18 Mar 20 nicklas 1039         
5867 18 Mar 20 nicklas 1040         Job sequencingJob = null;
5867 18 Mar 20 nicklas 1041         String seqRunName = SequencingRun.getNextName(dc);
5867 18 Mar 20 nicklas 1042
5867 18 Mar 20 nicklas 1043         if (jsonAutoAnalyze != null)
5867 18 Mar 20 nicklas 1044         {
5867 18 Mar 20 nicklas 1045           boolean debug = Boolean.TRUE.equals(jsonAutoAnalyze.get("debug"));
5867 18 Mar 20 nicklas 1046           Number priority = (Number)jsonAutoAnalyze.get("priority");
6981 17 Jan 23 nicklas 1047           String partition = Values.getStringOrNull((String)jsonAutoAnalyze.get("partition"));
5867 18 Mar 20 nicklas 1048           String clusterId = (String)jsonAutoAnalyze.get("cluster");
5867 18 Mar 20 nicklas 1049           
5867 18 Mar 20 nicklas 1050           OpenGridCluster cluster = OpenGridService.getInstance().getClusterById(dc, clusterId);
5867 18 Mar 20 nicklas 1051           if (cluster == null)
5867 18 Mar 20 nicklas 1052           {
5867 18 Mar 20 nicklas 1053             throw new ItemNotFoundException("OpenGridCluster[" + clusterId + "]");
5867 18 Mar 20 nicklas 1054           }
5867 18 Mar 20 nicklas 1055           
5867 18 Mar 20 nicklas 1056           sequencingJob = Job.getNew(dc, null, null, null);
5867 18 Mar 20 nicklas 1057           sequencingJob.setItemSubtype(Subtype.SEQUENCING_RUN_JOB.get(dc));
5867 18 Mar 20 nicklas 1058           sequencingJob.setPluginVersion("reggie-"+Reggie.VERSION);
5867 18 Mar 20 nicklas 1059           sequencingJob.setSendMessage(Values.getBoolean(sc.getUserClientSetting("plugins.sendmessage"), false));
5867 18 Mar 20 nicklas 1060           sequencingJob.setName(seqRunName + (debug ? " (debug)" : ""));
5867 18 Mar 20 nicklas 1061           if (debug)
5867 18 Mar 20 nicklas 1062           {
5867 18 Mar 20 nicklas 1063             sequencingJob.setParameterValue("debug", new BooleanParameterType(), debug);
5867 18 Mar 20 nicklas 1064           }
5867 18 Mar 20 nicklas 1065           if (priority != null)
5867 18 Mar 20 nicklas 1066           {
5867 18 Mar 20 nicklas 1067             sequencingJob.setParameterValue("priority", new IntegerParameterType(), priority.intValue());
5867 18 Mar 20 nicklas 1068           }
6981 17 Jan 23 nicklas 1069           if (partition != null)
6981 17 Jan 23 nicklas 1070           {
6981 17 Jan 23 nicklas 1071             sequencingJob.setParameterValue("partition", new StringParameterType(), partition);
6981 17 Jan 23 nicklas 1072           }
5867 18 Mar 20 nicklas 1073           sequencingJob.setScheduled(cluster.getId(), null);
5867 18 Mar 20 nicklas 1074           sequencingJob.setExternalId(flowCellId);
5867 18 Mar 20 nicklas 1075           
5867 18 Mar 20 nicklas 1076           String signalURI = ReggieSignalHandlerFactory.getSignalUri(flowCellType, flowCellId);
5867 18 Mar 20 nicklas 1077           if (signalURI != null)
5867 18 Mar 20 nicklas 1078           {
5867 18 Mar 20 nicklas 1079             sequencingJob.setSignalTransporter(ExtensionSignalTransporter.class, signalURI);
5867 18 Mar 20 nicklas 1080           }
5867 18 Mar 20 nicklas 1081           
5867 18 Mar 20 nicklas 1082           dc.saveItem(sequencingJob);
5867 18 Mar 20 nicklas 1083         }
5867 18 Mar 20 nicklas 1084         
5867 18 Mar 20 nicklas 1085         DerivedBioAssay seqRun = DerivedBioAssay.getNew(dc, flowCell, sequencingJob);
5867 18 Mar 20 nicklas 1086         seqRun.setItemSubtype(Subtype.SEQUENCING_RUN.load(dc));
5867 18 Mar 20 nicklas 1087         Pipeline.RNA_SEQ.setAnnotation(dc, seqRun);
5867 18 Mar 20 nicklas 1088         seqRun.setName(seqRunName);
5870 20 Mar 20 nicklas 1089         seqRun.setDescription(comments);
5867 18 Mar 20 nicklas 1090         Annotationtype.SEQUENCING_START.setAnnotationValue(dc, seqRun, startDate);
5870 20 Mar 20 nicklas 1091         Annotationtype.SEQUENCING_OPERATOR.setAnnotationValue(dc, seqRun, operator);
5867 18 Mar 20 nicklas 1092         seqRun.setHardware(null); // To prevent a 'project default'
5867 18 Mar 20 nicklas 1093         seqRun.setProtocol(null);
5867 18 Mar 20 nicklas 1094         dc.saveItem(seqRun);
5867 18 Mar 20 nicklas 1095         
5867 18 Mar 20 nicklas 1096         jsonMessages.add("Created " + seqRun.getName());
5869 19 Mar 20 nicklas 1097         ActivityDef.EXTERNAL_SEQUENCING_STARTED.create(dc, flowCell.getName(), 1);
5869 19 Mar 20 nicklas 1098         if (sequencingJob != null)
5869 19 Mar 20 nicklas 1099         {
5869 19 Mar 20 nicklas 1100           Annotationtype.AUTO_PROCESSING.setAnnotationValue(dc, seqRun, "AutoConfirm");
5869 19 Mar 20 nicklas 1101           jsonMessages.add("Auto-analyze enabled on " + sequencingJob.getServer());
5869 19 Mar 20 nicklas 1102         }
5869 19 Mar 20 nicklas 1103       
5867 18 Mar 20 nicklas 1104         dc.commit();
5867 18 Mar 20 nicklas 1105       }
5867 18 Mar 20 nicklas 1106
2197 14 Jan 14 nicklas 1107       json.put("messages", jsonMessages);
3059 19 Dec 14 nicklas 1108       CounterService.getInstance().setForceCount();
2197 14 Jan 14 nicklas 1109     }
2197 14 Jan 14 nicklas 1110     catch (Throwable t)
2197 14 Jan 14 nicklas 1111     {
2197 14 Jan 14 nicklas 1112       t.printStackTrace();
2197 14 Jan 14 nicklas 1113       json.clear();
2197 14 Jan 14 nicklas 1114       json.put("status", "error");
2197 14 Jan 14 nicklas 1115       json.put("message", t.getMessage());
2197 14 Jan 14 nicklas 1116       json.put("stacktrace", ThrowableUtil.stackTraceToString(t));
2197 14 Jan 14 nicklas 1117     }
2197 14 Jan 14 nicklas 1118     finally
2197 14 Jan 14 nicklas 1119     {
2197 14 Jan 14 nicklas 1120       if (dc != null) dc.close();
2197 14 Jan 14 nicklas 1121       json.writeJSONString(resp.getWriter());
2197 14 Jan 14 nicklas 1122     }
2197 14 Jan 14 nicklas 1123   }
2197 14 Jan 14 nicklas 1124   
5473 05 Jun 19 nicklas 1125   /**
5473 05 Jun 19 nicklas 1126     Load any-to-any links: LibPlate, LibPlate.2, LibPlate.3 until there are no more (max 10)
5473 05 Jun 19 nicklas 1127   */
5526 25 Jun 19 nicklas 1128   public static JSONArray loadLibPlates(DbControl dc, PooledLibrary pool)
5473 05 Jun 19 nicklas 1129   {
5473 05 Jun 19 nicklas 1130     JSONArray json = new JSONArray();
5473 05 Jun 19 nicklas 1131     int index = 1;
5473 05 Jun 19 nicklas 1132     while (index < 10)
5473 05 Jun 19 nicklas 1133     {
5473 05 Jun 19 nicklas 1134       String linkSuffix = index == 1 ? "" : "."+index;
5473 05 Jun 19 nicklas 1135       try
5473 05 Jun 19 nicklas 1136       {
5473 05 Jun 19 nicklas 1137         AnyToAny libPlateLink = AnyToAny.getByName(dc, pool.getExtract(), "LibPlate"+linkSuffix);
5473 05 Jun 19 nicklas 1138         ReactionPlate libPlate = ReactionPlate.getById(dc, libPlateLink.getToId(), BioplateType.LIBRARY);
5473 05 Jun 19 nicklas 1139         json.add(libPlate.asJSONObject());
5473 05 Jun 19 nicklas 1140       }
5473 05 Jun 19 nicklas 1141       catch (RuntimeException ex)
5473 05 Jun 19 nicklas 1142       {
5473 05 Jun 19 nicklas 1143         break;
5473 05 Jun 19 nicklas 1144       }
5473 05 Jun 19 nicklas 1145       index++;
5473 05 Jun 19 nicklas 1146     }
5473 05 Jun 19 nicklas 1147     return json;
5473 05 Jun 19 nicklas 1148   }
5473 05 Jun 19 nicklas 1149   
4306 17 Jan 17 nicklas 1150   private static CmdResult<String> getRunParametersXml(OpenGridSession session, String flowCellId)
3699 18 Jan 16 nicklas 1151   {
4306 17 Jan 17 nicklas 1152     XmlConfig cfg = Reggie.getConfig(session.getHost().getId());
4306 17 Jan 17 nicklas 1153     String runArchive = cfg.getRequiredConfig("run-archive", null);
4044 02 Aug 16 nicklas 1154     List<String> allRunArchives = new ArrayList<>();
4044 02 Aug 16 nicklas 1155     allRunArchives.add(runArchive);
4306 17 Jan 17 nicklas 1156     allRunArchives.addAll(cfg.getConfigList("run-archive", 2));
3699 18 Jan 16 nicklas 1157     
4306 17 Jan 17 nicklas 1158     ScriptBuilder script = new ScriptBuilder();
6663 01 Apr 22 nicklas 1159     script.export("AllRunArchives", Values.getString(allRunArchives, " ",  true));
6663 01 Apr 22 nicklas 1160     script.export("BARCODE", flowCellId);
6663 01 Apr 22 nicklas 1161     script.cmd(ScriptUtil.getAsString("get_run_parameters.sh"));
4306 17 Jan 17 nicklas 1162     CmdResult<String> result = session.executeCmd(script.toString(), 30);
3699 18 Jan 16 nicklas 1163     return result;
3699 18 Jan 16 nicklas 1164   }
3699 18 Jan 16 nicklas 1165   
3699 18 Jan 16 nicklas 1166   /**
6678 19 Apr 22 nicklas 1167     Run 'picard CheckIlluminaDirectory' on the specified cluster/node.
3704 19 Jan 16 nicklas 1168     @param dataFolder Data folder of the sequence data
3704 19 Jan 16 nicklas 1169     @param readString Read string that specify which cycles to check (see 
3704 19 Jan 16 nicklas 1170       {@link DemuxMergeServlet#sequencingCycles2ReadStringPicard(String, String)})
3704 19 Jan 16 nicklas 1171     @param laneNo The lane number to check (1-4 for NextSeq, 1-8 for HiSeq)
3704 19 Jan 16 nicklas 1172     @since 4.1
3704 19 Jan 16 nicklas 1173   */
6678 19 Apr 22 nicklas 1174   public static CmdResult<String> checkIlluminaDirectory(OpenGridSession session, String node, 
7030 09 Feb 23 nicklas 1175     String dataFolder, String readString, int laneNo, int timeoutInSeconds)
3704 19 Jan 16 nicklas 1176   {
3704 19 Jan 16 nicklas 1177     // Get global options
4306 17 Jan 17 nicklas 1178     XmlConfig cfg = Reggie.getConfig(session.getHost().getId());
3704 19 Jan 16 nicklas 1179     String runArchive = cfg.getRequiredConfig("run-archive", null);
4044 02 Aug 16 nicklas 1180     List<String> allRunArchives = new ArrayList<>();
4044 02 Aug 16 nicklas 1181     allRunArchives.add(runArchive);
4044 02 Aug 16 nicklas 1182     allRunArchives.addAll(cfg.getConfigList("run-archive", 2));
6665 05 Apr 22 nicklas 1183     String containerFolder = cfg.getConfig("container-folder");
3704 19 Jan 16 nicklas 1184
6693 22 Apr 22 nicklas 1185     String global_env = ScriptUtil.multilineIndent(cfg.getConfig("global-env"));
6665 05 Apr 22 nicklas 1186     String check_env = ScriptUtil.multilineIndent(cfg.getConfig("check-illumina-directory/env"));
6661 01 Apr 22 nicklas 1187     String check_execute = ScriptUtil.multilineIndent(cfg.getConfig("check-illumina-directory/execute", null, "./check-illumina-directory.sh"));
6661 01 Apr 22 nicklas 1188
4306 17 Jan 17 nicklas 1189     ScriptBuilder script = new ScriptBuilder();
6661 01 Apr 22 nicklas 1190     script.cmd("set -e");
6693 22 Apr 22 nicklas 1191     script.cmd(global_env);
6665 05 Apr 22 nicklas 1192     script.export("RunArchive", runArchive);
6661 01 Apr 22 nicklas 1193     script.export("ALL_RUN_ARCHIVES", Values.getString(allRunArchives, " ", true));
6661 01 Apr 22 nicklas 1194     script.export("DATA_FOLDER", dataFolder);
6661 01 Apr 22 nicklas 1195     script.export("LANE", Integer.toString(laneNo));
6661 01 Apr 22 nicklas 1196     script.export("READSTRING", readString);
6661 01 Apr 22 nicklas 1197     script.cmd(check_env);
6661 01 Apr 22 nicklas 1198     script.cmd(check_execute);
6661 01 Apr 22 nicklas 1199     JobDefinition job = new JobDefinition("CheckIlluminaDirectory", null);
6661 01 Apr 22 nicklas 1200     job.addFile(ScriptUtil.upload("check-illumina-directory.sh"));
6661 01 Apr 22 nicklas 1201     job.setCmd(script.toString());
6661 01 Apr 22 nicklas 1202     job.setDebug(logger.isDebugEnabled());
7030 09 Feb 23 nicklas 1203     return session.executeNow(job, node, timeoutInSeconds);
3704 19 Jan 16 nicklas 1204   }
3704 19 Jan 16 nicklas 1205   
3704 19 Jan 16 nicklas 1206   /**
3699 18 Jan 16 nicklas 1207     Job completion handler for sequencing runs. The handler downloads the
3699 18 Jan 16 nicklas 1208     'RunParameters.xml' file from the run archive ...
3699 18 Jan 16 nicklas 1209   */
3699 18 Jan 16 nicklas 1210   public static class SequencingRunJobCompletionHandler
3699 18 Jan 16 nicklas 1211     implements JobCompletionHandler
3699 18 Jan 16 nicklas 1212   {
3699 18 Jan 16 nicklas 1213     private XmlConfig cfg;
3699 18 Jan 16 nicklas 1214     
3699 18 Jan 16 nicklas 1215     public SequencingRunJobCompletionHandler()
3699 18 Jan 16 nicklas 1216     {}
3699 18 Jan 16 nicklas 1217   
3699 18 Jan 16 nicklas 1218     @Override
4306 17 Jan 17 nicklas 1219     public String jobCompleted(SessionControl sc, OpenGridSession session, Job job, JobStatus status)
3699 18 Jan 16 nicklas 1220     {
3699 18 Jan 16 nicklas 1221       String msg = null;
3699 18 Jan 16 nicklas 1222       DbControl dc = null;
3699 18 Jan 16 nicklas 1223       try
3699 18 Jan 16 nicklas 1224       {
4306 17 Jan 17 nicklas 1225         CmdResult<String> result = getRunParametersXml(session, job.getExternalId());
4311 17 Jan 17 nicklas 1226         result.throwExceptionIfNonZeroExitStatus();
3699 18 Jan 16 nicklas 1227         
3699 18 Jan 16 nicklas 1228         String stdout[] = result.getStdout().split("\n", 3);
3699 18 Jan 16 nicklas 1229
3699 18 Jan 16 nicklas 1230         Date endDateTime = Reggie.CONVERTER_STRING_TO_DATETIME.convert(Values.getStringOrNull(stdout[1]));
3699 18 Jan 16 nicklas 1231         Document dom = XmlUtil2.getXml(stdout[2], null, false);
3699 18 Jan 16 nicklas 1232         XmlConfig runParameters = new XmlConfig(dom.getRootElement(), "");
5477 10 Jun 19 nicklas 1233
6599 22 Feb 22 nicklas 1234         dc = sc.newDbControl("Reggie: Sequencing run completed handler");
3699 18 Jan 16 nicklas 1235         
3699 18 Jan 16 nicklas 1236         SequencingRun sr = SequencingRun.getByJob(dc, job);
3699 18 Jan 16 nicklas 1237         DerivedBioAssay seqRun = sr.getDerivedBioAssay();
3699 18 Jan 16 nicklas 1238         FlowCell fc = FlowCell.getBySequencingRun(dc, sr);
3699 18 Jan 16 nicklas 1239         PhysicalBioAssay flowCell = fc.getPhysicalBioAssay();
3699 18 Jan 16 nicklas 1240         
5477 10 Jun 19 nicklas 1241         String flowCelltype = (String)Annotationtype.FLOWCELL_TYPE.getAnnotationValue(dc, flowCell);
5477 10 Jun 19 nicklas 1242
5869 19 Mar 20 nicklas 1243         String sequencingCycles = null;
5869 19 Mar 20 nicklas 1244         String flowCellBarcode = null;
5477 10 Jun 19 nicklas 1245         Date startDate = null;
5477 10 Jun 19 nicklas 1246         String hiSeqPosition = "A";
5477 10 Jun 19 nicklas 1247         String dataFilesFolder = null;
5477 10 Jun 19 nicklas 1248         int runNumber = 0;
5869 19 Mar 20 nicklas 1249         String scannerId = null;
5855 09 Mar 20 nicklas 1250         if (FlowCell.FLOW_CELL_TYPE_HISEQ.equals(flowCelltype))
5477 10 Jun 19 nicklas 1251         {
5477 10 Jun 19 nicklas 1252           startDate = Reggie.CONVERTER_STRING_TO_DATE.convert("20"+runParameters.getConfig("Setup/RunStartDate"));
5477 10 Jun 19 nicklas 1253           flowCellBarcode = runParameters.getConfig("Setup/Barcode");
5855 09 Mar 20 nicklas 1254           int r1 = Values.getInt(runParameters.getConfig("Setup/Read1"));
5855 09 Mar 20 nicklas 1255           int r2 = Values.getInt(runParameters.getConfig("Setup/Read2"));
5855 09 Mar 20 nicklas 1256           int i1 = Values.getInt(runParameters.getConfig("Setup/Index1Read"));
5855 09 Mar 20 nicklas 1257           int i2 = Values.getInt(runParameters.getConfig("Setup/Index2Read"));
5855 09 Mar 20 nicklas 1258           sequencingCycles = toCycles(r1, r2, i1, i2);
5477 10 Jun 19 nicklas 1259           runNumber = Values.getInt(runParameters.getConfig("Setup/ScanNumber"));
5477 10 Jun 19 nicklas 1260           dataFilesFolder = runParameters.getConfig("Setup/RunID");
5477 10 Jun 19 nicklas 1261           hiSeqPosition = runParameters.getConfig("Setup/FCPosition");
5869 19 Mar 20 nicklas 1262           scannerId = runParameters.getConfig("Setup/ScannerID");
5477 10 Jun 19 nicklas 1263         }
5855 09 Mar 20 nicklas 1264         else if (FlowCell.FLOW_CELL_TYPE_NOVASEQ.equals(flowCelltype))
5477 10 Jun 19 nicklas 1265         {
5477 10 Jun 19 nicklas 1266           startDate = Reggie.CONVERTER_STRING_TO_DATE.convert("20"+runParameters.getConfig("RunStartDate"));
5855 09 Mar 20 nicklas 1267           flowCellBarcode = runParameters.getConfig("RfidsInfo/FlowCellSerialBarcode");
5855 09 Mar 20 nicklas 1268           int r1 = Values.getInt(runParameters.getConfig("Read1NumberOfCycles"));
5855 09 Mar 20 nicklas 1269           int r2 = Values.getInt(runParameters.getConfig("Read2NumberOfCycles"));
5855 09 Mar 20 nicklas 1270           int i1 = Values.getInt(runParameters.getConfig("IndexRead1NumberOfCycles"));
5855 09 Mar 20 nicklas 1271           int i2 = Values.getInt(runParameters.getConfig("IndexRead2NumberOfCycles"));
5855 09 Mar 20 nicklas 1272           sequencingCycles = toCycles(r1, r2, i1, i2);
5855 09 Mar 20 nicklas 1273           runNumber = Values.getInt(runParameters.getConfig("RunNumber"));
5855 09 Mar 20 nicklas 1274           dataFilesFolder = runParameters.getConfig("RunId");
5855 09 Mar 20 nicklas 1275           hiSeqPosition = runParameters.getConfig("Side");
5869 19 Mar 20 nicklas 1276           scannerId = runParameters.getConfig("InstrumentName");
5855 09 Mar 20 nicklas 1277         }
5855 09 Mar 20 nicklas 1278         else if (FlowCell.FLOW_CELL_TYPE_NEXTSEQ.equals(flowCelltype))
5855 09 Mar 20 nicklas 1279         {
5855 09 Mar 20 nicklas 1280           startDate = Reggie.CONVERTER_STRING_TO_DATE.convert("20"+runParameters.getConfig("RunStartDate"));
5477 10 Jun 19 nicklas 1281           flowCellBarcode = runParameters.getConfig("FlowCellSerial");
5855 09 Mar 20 nicklas 1282
5855 09 Mar 20 nicklas 1283           int r1 = Values.getInt(runParameters.getConfig("Setup/Read1"));
5855 09 Mar 20 nicklas 1284           int r2 = Values.getInt(runParameters.getConfig("Setup/Read2"));
5855 09 Mar 20 nicklas 1285           int i1 = Values.getInt(runParameters.getConfig("Setup/Index1Read"));
5855 09 Mar 20 nicklas 1286           int i2 = Values.getInt(runParameters.getConfig("Setup/Index2Read"));
5855 09 Mar 20 nicklas 1287           sequencingCycles = toCycles(r1, r2, i1, i2);
5477 10 Jun 19 nicklas 1288           runNumber = Values.getInt(runParameters.getConfig("RunNumber"));
5477 10 Jun 19 nicklas 1289           dataFilesFolder = runParameters.getConfig("RunID");
5869 19 Mar 20 nicklas 1290           scannerId = runParameters.getConfig("InstrumentID");
5477 10 Jun 19 nicklas 1291         }
5477 10 Jun 19 nicklas 1292         
3699 18 Jan 16 nicklas 1293         // Update flow cell
3699 18 Jan 16 nicklas 1294         Annotationtype.FLOWCELL_ID.setAnnotationValue(dc, flowCell, flowCellBarcode);
3699 18 Jan 16 nicklas 1295         Annotationtype.SEQUENCING_CYCLES.setAnnotationValue(dc, flowCell, sequencingCycles);
3699 18 Jan 16 nicklas 1296       
3699 18 Jan 16 nicklas 1297         // Update sequencing run
3699 18 Jan 16 nicklas 1298         Annotationtype.SEQUENCING_START.setAnnotationValue(dc, seqRun, startDate);
3699 18 Jan 16 nicklas 1299         Annotationtype.SEQUENCING_END.setAnnotationValue(dc, seqRun, endDateTime);
3699 18 Jan 16 nicklas 1300         Annotationtype.SEQUENCING_CONFIRMED.setAnnotationValue(dc, seqRun, false);
3699 18 Jan 16 nicklas 1301         //seqRun.setDescription((String)jsonSeq.get("comments"));
3699 18 Jan 16 nicklas 1302         Annotationtype.HISEQ_POSITION.setAnnotationValue(dc, seqRun, hiSeqPosition);
3699 18 Jan 16 nicklas 1303         Annotationtype.SEQUENCING_CYCLES.setAnnotationValue(dc, seqRun, sequencingCycles);
3699 18 Jan 16 nicklas 1304         Annotationtype.SEQUENCING_RUN_NUMBER.setAnnotationValue(dc, seqRun, runNumber);
3699 18 Jan 16 nicklas 1305         Annotationtype.DATA_FILES_FOLDER.setAnnotationValue(dc, seqRun, dataFilesFolder);
5869 19 Mar 20 nicklas 1306         if (scannerId != null)
5869 19 Mar 20 nicklas 1307         {
5869 19 Mar 20 nicklas 1308           Hardware sequencer = findSequencer(dc, scannerId);
5869 19 Mar 20 nicklas 1309           if (sequencer != null) 
5869 19 Mar 20 nicklas 1310           {
5869 19 Mar 20 nicklas 1311             seqRun.setHardware(sequencer);
5869 19 Mar 20 nicklas 1312             flowCell.getCreationEvent().setHardware(sequencer);
5869 19 Mar 20 nicklas 1313           }
5869 19 Mar 20 nicklas 1314         }
5612 18 Sep 19 nicklas 1315         ActivityDef.SEQUENCING_ENDED.create(dc, fc.getName(), 1).setUser("Auto-confirm");
3699 18 Jan 16 nicklas 1316
3699 18 Jan 16 nicklas 1317         dc.commit();
3699 18 Jan 16 nicklas 1318       }
3699 18 Jan 16 nicklas 1319       catch (IOException ex)
3699 18 Jan 16 nicklas 1320       {
3699 18 Jan 16 nicklas 1321         throw new RuntimeException(ex);
3699 18 Jan 16 nicklas 1322       }
3699 18 Jan 16 nicklas 1323       finally
3699 18 Jan 16 nicklas 1324       {
4306 17 Jan 17 nicklas 1325         if (dc != null) dc.close();
3699 18 Jan 16 nicklas 1326       }
3699 18 Jan 16 nicklas 1327       return msg;
3699 18 Jan 16 nicklas 1328     }
4306 17 Jan 17 nicklas 1329
5855 09 Mar 20 nicklas 1330     /**
5855 09 Mar 20 nicklas 1331       Convert reads to a single SequencingCycles string. R1, R2 and I1 are expected
5855 09 Mar 20 nicklas 1332       to always have value > 0. I2 may or may not.
5855 09 Mar 20 nicklas 1333     */
5855 09 Mar 20 nicklas 1334     private String toCycles(int r1, int r2, int i1, int i2)
5855 09 Mar 20 nicklas 1335     {
5855 09 Mar 20 nicklas 1336       return r1 + "-" + i1 + (i2 == 0 ? "" : "-" + i2) + "-" + r2;
5855 09 Mar 20 nicklas 1337     }
5855 09 Mar 20 nicklas 1338     
5869 19 Mar 20 nicklas 1339     private Hardware findSequencer(DbControl dc, String serialNumber)
5869 19 Mar 20 nicklas 1340     {
5869 19 Mar 20 nicklas 1341       ItemQuery<Hardware> query = Hardware.getQuery();
5869 19 Mar 20 nicklas 1342       query.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
5869 19 Mar 20 nicklas 1343       Subtype.SEQUENCER.addFilter(dc, query);
5869 19 Mar 20 nicklas 1344       query.join(Annotations.innerJoin(Annotationtype.SERIAL_NUMBER.load(dc), "sn"));
5869 19 Mar 20 nicklas 1345       query.restrict(Restrictions.eq(Hql.alias("sn"), Expressions.string(serialNumber)));
5869 19 Mar 20 nicklas 1346       List<Hardware> result = query.list(dc);
5869 19 Mar 20 nicklas 1347       return result.size() > 0 ? result.get(0) : null;
5869 19 Mar 20 nicklas 1348     }
5869 19 Mar 20 nicklas 1349     
3699 18 Jan 16 nicklas 1350   }
2197 14 Jan 14 nicklas 1351 }