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

Code
Comments
Other
Rev Date Author Line
7387 31 Oct 23 nicklas 1 package net.sf.basedb.reggie.servlet;
7387 31 Oct 23 nicklas 2
7387 31 Oct 23 nicklas 3 import java.io.IOException;
7423 14 Nov 23 nicklas 4 import java.io.InputStream;
7387 31 Oct 23 nicklas 5 import java.util.ArrayList;
7423 14 Nov 23 nicklas 6 import java.util.Arrays;
7387 31 Oct 23 nicklas 7 import java.util.Collections;
7387 31 Oct 23 nicklas 8 import java.util.List;
7423 14 Nov 23 nicklas 9 import java.util.zip.GZIPInputStream;
7387 31 Oct 23 nicklas 10
7387 31 Oct 23 nicklas 11 import javax.servlet.ServletException;
7387 31 Oct 23 nicklas 12 import javax.servlet.http.HttpServlet;
7387 31 Oct 23 nicklas 13 import javax.servlet.http.HttpServletRequest;
7387 31 Oct 23 nicklas 14 import javax.servlet.http.HttpServletResponse;
7387 31 Oct 23 nicklas 15
7387 31 Oct 23 nicklas 16 import org.json.simple.JSONArray;
7387 31 Oct 23 nicklas 17 import org.json.simple.JSONObject;
7387 31 Oct 23 nicklas 18
7439 16 Nov 23 nicklas 19 import net.sf.basedb.core.AnnotationType;
7394 06 Nov 23 nicklas 20 import net.sf.basedb.core.BasicItem;
7400 07 Nov 23 nicklas 21 import net.sf.basedb.core.BioSource;
7387 31 Oct 23 nicklas 22 import net.sf.basedb.core.DbControl;
7388 31 Oct 23 nicklas 23 import net.sf.basedb.core.DerivedBioAssay;
7442 17 Nov 23 nicklas 24 import net.sf.basedb.core.Extract;
7423 14 Nov 23 nicklas 25 import net.sf.basedb.core.File;
7395 06 Nov 23 nicklas 26 import net.sf.basedb.core.Include;
7395 06 Nov 23 nicklas 27 import net.sf.basedb.core.Item;
7395 06 Nov 23 nicklas 28 import net.sf.basedb.core.ItemList;
7388 31 Oct 23 nicklas 29 import net.sf.basedb.core.ItemNotFoundException;
7392 03 Nov 23 nicklas 30 import net.sf.basedb.core.ItemQuery;
7388 31 Oct 23 nicklas 31 import net.sf.basedb.core.Job;
7436 15 Nov 23 nicklas 32 import net.sf.basedb.core.RawBioAssay;
7387 31 Oct 23 nicklas 33 import net.sf.basedb.core.SessionControl;
7396 06 Nov 23 nicklas 34 import net.sf.basedb.core.Software;
7394 06 Nov 23 nicklas 35 import net.sf.basedb.core.Trashcan;
7392 03 Nov 23 nicklas 36 import net.sf.basedb.core.query.Annotations;
7392 03 Nov 23 nicklas 37 import net.sf.basedb.core.query.Expressions;
7392 03 Nov 23 nicklas 38 import net.sf.basedb.core.query.Hql;
7392 03 Nov 23 nicklas 39 import net.sf.basedb.core.query.Orders;
7392 03 Nov 23 nicklas 40 import net.sf.basedb.core.query.Restrictions;
7387 31 Oct 23 nicklas 41 import net.sf.basedb.core.snapshot.SnapshotManager;
7388 31 Oct 23 nicklas 42 import net.sf.basedb.opengrid.JobDefinition;
7388 31 Oct 23 nicklas 43 import net.sf.basedb.opengrid.OpenGridCluster;
7406 08 Nov 23 nicklas 44 import net.sf.basedb.opengrid.config.BatchConfig;
7388 31 Oct 23 nicklas 45 import net.sf.basedb.opengrid.service.OpenGridService;
7387 31 Oct 23 nicklas 46 import net.sf.basedb.reggie.JsonUtil;
7387 31 Oct 23 nicklas 47 import net.sf.basedb.reggie.Reggie;
7437 15 Nov 23 nicklas 48 import net.sf.basedb.reggie.activity.ActivityDef;
7387 31 Oct 23 nicklas 49 import net.sf.basedb.reggie.counter.CounterService;
7387 31 Oct 23 nicklas 50 import net.sf.basedb.reggie.dao.AlignedSequences;
7387 31 Oct 23 nicklas 51 import net.sf.basedb.reggie.dao.Annotationtype;
7400 07 Nov 23 nicklas 52 import net.sf.basedb.reggie.dao.BiomaterialList;
7436 15 Nov 23 nicklas 53 import net.sf.basedb.reggie.dao.Datafiletype;
7387 31 Oct 23 nicklas 54 import net.sf.basedb.reggie.dao.Library;
7392 03 Nov 23 nicklas 55 import net.sf.basedb.reggie.dao.PanelOfNormal;
7400 07 Nov 23 nicklas 56 import net.sf.basedb.reggie.dao.Patient;
7400 07 Nov 23 nicklas 57 import net.sf.basedb.reggie.dao.Pipeline;
7423 14 Nov 23 nicklas 58 import net.sf.basedb.reggie.dao.Rawbioassay;
7436 15 Nov 23 nicklas 59 import net.sf.basedb.reggie.dao.Rawdatatype;
7387 31 Oct 23 nicklas 60 import net.sf.basedb.reggie.dao.ReggieRole;
7392 03 Nov 23 nicklas 61 import net.sf.basedb.reggie.dao.Subtype;
7406 08 Nov 23 nicklas 62 import net.sf.basedb.reggie.dao.TumorNormalPair;
7388 31 Oct 23 nicklas 63 import net.sf.basedb.reggie.grid.ScriptUtil;
7388 31 Oct 23 nicklas 64 import net.sf.basedb.reggie.grid.WgsVariantCallJobCreator;
7423 14 Nov 23 nicklas 65 import net.sf.basedb.reggie.vcf.GtData;
7423 14 Nov 23 nicklas 66 import net.sf.basedb.reggie.vcf.PassFilterFilter;
7423 14 Nov 23 nicklas 67 import net.sf.basedb.reggie.vcf.SnpData;
7423 14 Nov 23 nicklas 68 import net.sf.basedb.reggie.vcf.VariantCallingInfoFactory;
7423 14 Nov 23 nicklas 69 import net.sf.basedb.reggie.vcf.VcfData;
7423 14 Nov 23 nicklas 70 import net.sf.basedb.reggie.vcf.VcfParser;
7423 14 Nov 23 nicklas 71 import net.sf.basedb.util.FileUtil;
7387 31 Oct 23 nicklas 72 import net.sf.basedb.util.Values;
7387 31 Oct 23 nicklas 73 import net.sf.basedb.util.error.ThrowableUtil;
7387 31 Oct 23 nicklas 74
7387 31 Oct 23 nicklas 75
7387 31 Oct 23 nicklas 76 public class WgsVariantCallingServlet 
7387 31 Oct 23 nicklas 77   extends HttpServlet 
7387 31 Oct 23 nicklas 78 {
7387 31 Oct 23 nicklas 79
7387 31 Oct 23 nicklas 80   private static final long serialVersionUID = -5853842236693335827L;
7387 31 Oct 23 nicklas 81
7406 08 Nov 23 nicklas 82   /**
7406 08 Nov 23 nicklas 83     Variable for storing the earliest allowed start time for the next variant calling job.
7406 08 Nov 23 nicklas 84     We do not want to start too many variant calling jobs at the same time since copying
7406 08 Nov 23 nicklas 85     the BAM files to the local node will overload the server were they are stored.
7406 08 Nov 23 nicklas 86   */
7406 08 Nov 23 nicklas 87   private static long NEXT_START_TIME = 0;
7406 08 Nov 23 nicklas 88
7387 31 Oct 23 nicklas 89   public WgsVariantCallingServlet()
7387 31 Oct 23 nicklas 90   {}
7387 31 Oct 23 nicklas 91
7387 31 Oct 23 nicklas 92   @Override
7387 31 Oct 23 nicklas 93   protected void doGet(HttpServletRequest req, HttpServletResponse resp)
7387 31 Oct 23 nicklas 94     throws ServletException, IOException 
7387 31 Oct 23 nicklas 95   {
7387 31 Oct 23 nicklas 96     String cmd = req.getParameter("cmd");
7387 31 Oct 23 nicklas 97     JsonUtil.setJsonResponseHeaders(resp);
7387 31 Oct 23 nicklas 98     
7387 31 Oct 23 nicklas 99     JSONObject json = new JSONObject();
7387 31 Oct 23 nicklas 100     json.put("status", "ok");
7387 31 Oct 23 nicklas 101     
7387 31 Oct 23 nicklas 102     final SessionControl sc = Reggie.getSessionControl(req);
7387 31 Oct 23 nicklas 103     DbControl dc = null;
7387 31 Oct 23 nicklas 104     try
7387 31 Oct 23 nicklas 105     {
7387 31 Oct 23 nicklas 106       if ("GetAlignedSequencesForPonVariantCalling".equals(cmd))
7387 31 Oct 23 nicklas 107       {
7387 31 Oct 23 nicklas 108         dc = sc.newDbControl(":Start panel-of-normals variant calling");
7387 31 Oct 23 nicklas 109         
7387 31 Oct 23 nicklas 110         List<AlignedSequences> list = null;
7387 31 Oct 23 nicklas 111         String items = Values.getStringOrNull(req.getParameter("items"));
7387 31 Oct 23 nicklas 112         if (items == null)
7387 31 Oct 23 nicklas 113         {
7387 31 Oct 23 nicklas 114           list = Collections.emptyList();
7387 31 Oct 23 nicklas 115         }
7387 31 Oct 23 nicklas 116         else
7387 31 Oct 23 nicklas 117         {
7387 31 Oct 23 nicklas 118           Integer[] ids = Values.getInt(items.split(","));
7387 31 Oct 23 nicklas 119           list = new ArrayList<AlignedSequences>();
7387 31 Oct 23 nicklas 120           for (Integer id : ids)
7387 31 Oct 23 nicklas 121           {
7387 31 Oct 23 nicklas 122             list.add(AlignedSequences.getById(dc, id));
7387 31 Oct 23 nicklas 123           }
7387 31 Oct 23 nicklas 124         }
7387 31 Oct 23 nicklas 125         SnapshotManager manager = new SnapshotManager();
7387 31 Oct 23 nicklas 126         JSONArray jsonAlignedSequences = new JSONArray();
7387 31 Oct 23 nicklas 127         for (AlignedSequences as : list)
7387 31 Oct 23 nicklas 128         {
7387 31 Oct 23 nicklas 129           as.loadAnnotations(dc, "pipeline", Annotationtype.PIPELINE, null);
7387 31 Oct 23 nicklas 130           as.loadAnnotations(dc, "MeanCoverage", Annotationtype.MEAN_COVERAGE, null);
7387 31 Oct 23 nicklas 131           Library lib = as.getLibrary(dc);
7387 31 Oct 23 nicklas 132           lib.loadAnnotations(dc, "ExternalOperator", Annotationtype.EXTERNAL_OPERATOR, null);
7387 31 Oct 23 nicklas 133           as.setAnnotation("lib", lib.asJSONObject());
7387 31 Oct 23 nicklas 134           
7387 31 Oct 23 nicklas 135           as.loadAnnotations(dc, manager, "AutoProcess", Annotationtype.AUTO_PROCESSING, null);
7387 31 Oct 23 nicklas 136           as.loadDoNotUseAnnotations(dc, manager);
7387 31 Oct 23 nicklas 137           jsonAlignedSequences.add(as.asJSONObject());
7387 31 Oct 23 nicklas 138         }
7387 31 Oct 23 nicklas 139         json.put("alignedSequences", jsonAlignedSequences);
7387 31 Oct 23 nicklas 140       }
7392 03 Nov 23 nicklas 141       else if ("GetUnconfirmedPanelOfNormals".equals(cmd))
7392 03 Nov 23 nicklas 142       {
7392 03 Nov 23 nicklas 143         dc = sc.newDbControl(":Confirm panel-of-normals variant calling");
7392 03 Nov 23 nicklas 144         ItemQuery<DerivedBioAssay> query = DerivedBioAssay.getQuery();
7392 03 Nov 23 nicklas 145         query.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
7392 03 Nov 23 nicklas 146         Subtype.PANEL_OF_NORMAL.addFilter(dc, query);
7392 03 Nov 23 nicklas 147         // The job must be a VariantCalling job and it must be ended
7392 03 Nov 23 nicklas 148         query.join(Hql.innerJoin("job", "jb"));
7392 03 Nov 23 nicklas 149         Subtype.VARIANT_CALLING_JOB.addFilter(dc, query, "jb");
7392 03 Nov 23 nicklas 150         query.restrict(Restrictions.neq(Hql.property("jb", "ended"), null));
7392 03 Nov 23 nicklas 151         // Must NOT have a ANALYSIS_RESULT annotation
7392 03 Nov 23 nicklas 152         query.join(Annotations.leftJoin(null, Annotationtype.ANALYSIS_RESULT.load(dc), "ar"));
7392 03 Nov 23 nicklas 153         query.restrict(Restrictions.eq(Hql.alias("ar"), null));
7392 03 Nov 23 nicklas 154         // Ignore if AutoProcess==AutoConfirm
7392 03 Nov 23 nicklas 155         query.join(Annotations.leftJoin(null, Annotationtype.AUTO_PROCESSING.load(dc), "ap"));
7392 03 Nov 23 nicklas 156         query.restrict(
7392 03 Nov 23 nicklas 157             Restrictions.or(
7392 03 Nov 23 nicklas 158               Restrictions.neq(Hql.alias("ap"), Expressions.string("AutoConfirm")),
7392 03 Nov 23 nicklas 159               Restrictions.eq(Hql.alias("ap"), null)
7392 03 Nov 23 nicklas 160             ));
7392 03 Nov 23 nicklas 161         query.order(Orders.asc(Hql.property("name")));
7392 03 Nov 23 nicklas 162         query.setMaxResults(250);
7392 03 Nov 23 nicklas 163         
7392 03 Nov 23 nicklas 164         SnapshotManager manager = new SnapshotManager();
7392 03 Nov 23 nicklas 165         JSONArray jsonPon = new JSONArray();
7392 03 Nov 23 nicklas 166         List<PanelOfNormal> list = PanelOfNormal.toList(query.list(dc));
7392 03 Nov 23 nicklas 167         for (PanelOfNormal pon : list)
7392 03 Nov 23 nicklas 168         {
7392 03 Nov 23 nicklas 169           pon.loadAnnotations(dc, manager, "PIPELINE", Annotationtype.PIPELINE, null);
7392 03 Nov 23 nicklas 170           pon.loadAnnotations(dc, manager, "VARIANTS_RAW", Annotationtype.VARIANTS_RAW, null);
7397 06 Nov 23 nicklas 171           pon.loadAnnotations(dc, manager, "CALLABLE_BASES", Annotationtype.CALLABLE_BASES, null);
7392 03 Nov 23 nicklas 172           
7392 03 Nov 23 nicklas 173           AlignedSequences aligned = pon.getNormalAlignment(dc);
7392 03 Nov 23 nicklas 174           aligned.loadAnnotations(dc, manager, "ALIGNED_PAIRS", Annotationtype.ALIGNED_PAIRS, null);
7392 03 Nov 23 nicklas 175           aligned.loadAnnotations(dc, manager, "FRACTION_DUPLICATION", Annotationtype.FRACTION_DUPLICATION, null);
7392 03 Nov 23 nicklas 176           aligned.loadAnnotations(dc, manager, "MEAN_COVERAGE", Annotationtype.MEAN_COVERAGE, null);
7392 03 Nov 23 nicklas 177           pon.setAnnotation("aligned", aligned.asJSONObject());
7392 03 Nov 23 nicklas 178           
7392 03 Nov 23 nicklas 179           // Load job information
7392 03 Nov 23 nicklas 180           Job job = pon.getItem().getJob();
7392 03 Nov 23 nicklas 181           JSONObject jsonJob = JsonUtil.getJobAsJSON(job);
7392 03 Nov 23 nicklas 182           pon.setAnnotation("job", jsonJob);
7392 03 Nov 23 nicklas 183           boolean debug = Boolean.TRUE.equals(job.getParameterValue("debug"));
7392 03 Nov 23 nicklas 184           jsonJob.put("debug", debug);    
7392 03 Nov 23 nicklas 185           
7392 03 Nov 23 nicklas 186           jsonPon.add(pon.asJSONObject());
7392 03 Nov 23 nicklas 187         }
7392 03 Nov 23 nicklas 188         
7392 03 Nov 23 nicklas 189         json.put("panelOfNormals", jsonPon);
7392 03 Nov 23 nicklas 190       }
7395 06 Nov 23 nicklas 191       else if ("PreValidateItemListForPanelOfNormals".equals(cmd))
7395 06 Nov 23 nicklas 192       {
7395 06 Nov 23 nicklas 193         int listId = Values.getInt(req.getParameter("listId"));
7395 06 Nov 23 nicklas 194         dc = sc.newDbControl(":Build panel-of-normal");
7395 06 Nov 23 nicklas 195         
7395 06 Nov 23 nicklas 196         ItemList list = ItemList.getById(dc, listId);
7395 06 Nov 23 nicklas 197         if (list.getMemberType() != Item.DERIVEDBIOASSAY)
7395 06 Nov 23 nicklas 198         {
7442 17 Nov 23 nicklas 199           json.put("errorMessage", "A list with DERIVEDBIOASSAY items is required");
7395 06 Nov 23 nicklas 200         }
7395 06 Nov 23 nicklas 201         else if (list.getSize() == 0)
7395 06 Nov 23 nicklas 202         {
7442 17 Nov 23 nicklas 203           json.put("errorMessage", "The list is empty");
7395 06 Nov 23 nicklas 204         }
7395 06 Nov 23 nicklas 205         else
7395 06 Nov 23 nicklas 206         {
7395 06 Nov 23 nicklas 207           ItemQuery<DerivedBioAssay> query = list.getMembers();
7395 06 Nov 23 nicklas 208           query.include(Include.ALL);
7395 06 Nov 23 nicklas 209           Subtype.PANEL_OF_NORMAL.addFilter(dc, query);
7395 06 Nov 23 nicklas 210           long count = query.count(dc);
7395 06 Nov 23 nicklas 211           if (count != list.getSize())
7395 06 Nov 23 nicklas 212           {
7442 17 Nov 23 nicklas 213             json.put("errorMessage", "All items in the list must be PanelOfNormal items.");
7395 06 Nov 23 nicklas 214           }
7395 06 Nov 23 nicklas 215           else
7395 06 Nov 23 nicklas 216           {
7395 06 Nov 23 nicklas 217             // Must have a ANALYSIS_RESULT=Successful annotation
7395 06 Nov 23 nicklas 218             query.reset();
7395 06 Nov 23 nicklas 219             query.join(Annotations.leftJoin(null, Annotationtype.ANALYSIS_RESULT.load(dc), "ar"));
7395 06 Nov 23 nicklas 220             query.restrict(Restrictions.eq(Hql.alias("ar"), Expressions.string("Successful")));
7442 17 Nov 23 nicklas 221             count = query.count(dc);
7395 06 Nov 23 nicklas 222             
7442 17 Nov 23 nicklas 223             // Check if all parent Libraries have the same ExternalOperator
7442 17 Nov 23 nicklas 224             List<PanelOfNormal> pons = PanelOfNormal.toList(query.list(dc));
7442 17 Nov 23 nicklas 225             String operator = null;
7442 17 Nov 23 nicklas 226             int numWithMissingLibOrOperator = 0;
7442 17 Nov 23 nicklas 227             int numWithOtherOperator = 0;
7442 17 Nov 23 nicklas 228             for (PanelOfNormal pon : pons)
7442 17 Nov 23 nicklas 229             {
7442 17 Nov 23 nicklas 230               Extract lib = pon.getItem().getExtract();
7442 17 Nov 23 nicklas 231               String op = (String)Annotationtype.EXTERNAL_OPERATOR.getAnnotationValue(dc, lib);
7442 17 Nov 23 nicklas 232               if (op == null)
7442 17 Nov 23 nicklas 233               {
7442 17 Nov 23 nicklas 234                 numWithMissingLibOrOperator++;
7442 17 Nov 23 nicklas 235               }
7442 17 Nov 23 nicklas 236               else
7442 17 Nov 23 nicklas 237               {
7442 17 Nov 23 nicklas 238                 if (operator == null)
7442 17 Nov 23 nicklas 239                 {
7442 17 Nov 23 nicklas 240                   operator = op;
7442 17 Nov 23 nicklas 241                 }
7442 17 Nov 23 nicklas 242                 else if (!op.equals(operator))
7442 17 Nov 23 nicklas 243                 {
7442 17 Nov 23 nicklas 244                   numWithOtherOperator++;
7442 17 Nov 23 nicklas 245                 }
7442 17 Nov 23 nicklas 246               }
7442 17 Nov 23 nicklas 247             }
7442 17 Nov 23 nicklas 248             json.put("ExternalOperator", operator);
7395 06 Nov 23 nicklas 249             if (count != list.getSize())
7395 06 Nov 23 nicklas 250             {
7442 17 Nov 23 nicklas 251               json.put("errorMessage", "Only " + count + " of " + list.getSize() + 
7395 06 Nov 23 nicklas 252                 " members in the list have been confirmed (AnalysisResult=Successful)");
7395 06 Nov 23 nicklas 253             }
7442 17 Nov 23 nicklas 254             else if (numWithMissingLibOrOperator > 0)
7442 17 Nov 23 nicklas 255             {
7442 17 Nov 23 nicklas 256               json.put("warningMessage", numWithMissingLibOrOperator+" of "+count+
7442 17 Nov 23 nicklas 257                 " members in the list is missing a parent Library.ExternalOperator");
7442 17 Nov 23 nicklas 258             }
7442 17 Nov 23 nicklas 259             else if (numWithOtherOperator > 0)
7442 17 Nov 23 nicklas 260             {
7442 17 Nov 23 nicklas 261               json.put("warningMessage", numWithOtherOperator+" of "+count+
7442 17 Nov 23 nicklas 262                 " members in the list have an ExternalOperator<>"+operator);
7442 17 Nov 23 nicklas 263             }
7442 17 Nov 23 nicklas 264             
7395 06 Nov 23 nicklas 265           }
7395 06 Nov 23 nicklas 266         }
7395 06 Nov 23 nicklas 267       }
7400 07 Nov 23 nicklas 268       else if ("GetAlignedSequencesForVariantCalling".equals(cmd))
7400 07 Nov 23 nicklas 269       {
7400 07 Nov 23 nicklas 270         dc = sc.newDbControl(":Start WGS variant calling");
7400 07 Nov 23 nicklas 271         
7400 07 Nov 23 nicklas 272         List<AlignedSequences> list = null;
7400 07 Nov 23 nicklas 273         String items = Values.getStringOrNull(req.getParameter("items"));
7400 07 Nov 23 nicklas 274         if (items == null)
7400 07 Nov 23 nicklas 275         {
7400 07 Nov 23 nicklas 276           ItemList vcallPipeline = BiomaterialList.WGS_VARIANT_CALLING_PIPELINE.load(dc);
7400 07 Nov 23 nicklas 277           ItemQuery<DerivedBioAssay> query = vcallPipeline.getMembers();
7400 07 Nov 23 nicklas 278           query.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
7400 07 Nov 23 nicklas 279           Subtype.ALIGNED_SEQUENCES.addFilter(dc, query);
7400 07 Nov 23 nicklas 280           query.order(Orders.asc(Hql.property("name")));
7400 07 Nov 23 nicklas 281           query.setMaxResults(50);
7400 07 Nov 23 nicklas 282           list = AlignedSequences.toList(query.list(dc));
7400 07 Nov 23 nicklas 283         }
7400 07 Nov 23 nicklas 284         else
7400 07 Nov 23 nicklas 285         {
7400 07 Nov 23 nicklas 286           Integer[] ids = Values.getInt(items.split(","));
7400 07 Nov 23 nicklas 287           list = new ArrayList<AlignedSequences>();
7400 07 Nov 23 nicklas 288           for (Integer id : ids)
7400 07 Nov 23 nicklas 289           {
7400 07 Nov 23 nicklas 290             list.add(AlignedSequences.getById(dc, id));
7400 07 Nov 23 nicklas 291           }
7400 07 Nov 23 nicklas 292         }
7400 07 Nov 23 nicklas 293         SnapshotManager manager = new SnapshotManager();
7400 07 Nov 23 nicklas 294         JSONArray jsonAlignedSequences = new JSONArray();
7400 07 Nov 23 nicklas 295         for (AlignedSequences as : list)
7400 07 Nov 23 nicklas 296         {
7400 07 Nov 23 nicklas 297           as.loadAnnotations(dc, manager, "pipeline", Annotationtype.PIPELINE, null);
7400 07 Nov 23 nicklas 298           as.loadAnnotations(dc, manager, "MeanCoverage", Annotationtype.MEAN_COVERAGE, null);
7400 07 Nov 23 nicklas 299           as.loadAnnotations(dc, manager, "AutoProcess", Annotationtype.AUTO_PROCESSING, null);
7400 07 Nov 23 nicklas 300           as.loadDoNotUseAnnotations(dc, manager);
7400 07 Nov 23 nicklas 301           
7400 07 Nov 23 nicklas 302           Library lib = as.getLibrary(dc);
7400 07 Nov 23 nicklas 303           lib.loadAnnotations(dc, manager, "ExternalOperator", Annotationtype.EXTERNAL_OPERATOR, null);
7400 07 Nov 23 nicklas 304           as.setAnnotation("lib", lib.asJSONObject());
7400 07 Nov 23 nicklas 305           
7400 07 Nov 23 nicklas 306           // Find matching normal alignment(s)
7400 07 Nov 23 nicklas 307           Patient patient = Patient.get((BioSource)as.findSingleParent(dc, Subtype.PATIENT));
7400 07 Nov 23 nicklas 308           as.setAnnotation("patient", patient.asJSONObject());
7400 07 Nov 23 nicklas 309           
7400 07 Nov 23 nicklas 310           JSONArray jsonNormals = new JSONArray();
7400 07 Nov 23 nicklas 311           ItemQuery<DerivedBioAssay> query = patient.findChildItems(dc, Subtype.ALIGNED_SEQUENCES);
7400 07 Nov 23 nicklas 312           Pipeline.DNA_NORMAL_WGS.addFilter(dc, query);
7400 07 Nov 23 nicklas 313           query.restrict(Restrictions.neq(Hql.property("id"), Expressions.integer(as.getId())));
7400 07 Nov 23 nicklas 314           query.order(Orders.asc(Hql.property("name")));
7400 07 Nov 23 nicklas 315           for (DerivedBioAssay ch : query.list(dc))
7400 07 Nov 23 nicklas 316           {
7400 07 Nov 23 nicklas 317             AlignedSequences normal = AlignedSequences.get(ch);
7400 07 Nov 23 nicklas 318             normal.loadDoNotUseAnnotations(dc, manager);
7400 07 Nov 23 nicklas 319             jsonNormals.add(normal.asJSONObject());
7400 07 Nov 23 nicklas 320           }
7400 07 Nov 23 nicklas 321           as.setAnnotation("normals", jsonNormals);
7400 07 Nov 23 nicklas 322           
7400 07 Nov 23 nicklas 323           jsonAlignedSequences.add(as.asJSONObject());
7400 07 Nov 23 nicklas 324         }
7400 07 Nov 23 nicklas 325         json.put("alignedSequences", jsonAlignedSequences);
7439 16 Nov 23 nicklas 326         
7439 16 Nov 23 nicklas 327         // We may also need the current values for the PanelOfNormals annotation
7439 16 Nov 23 nicklas 328         AnnotationType ponType = Annotationtype.PANEL_OF_NORMALS.get(dc);
7439 16 Nov 23 nicklas 329         if (ponType != null)
7439 16 Nov 23 nicklas 330         {
7439 16 Nov 23 nicklas 331           json.put("panelOfNormals", ponType.getValues());
7439 16 Nov 23 nicklas 332         }
7400 07 Nov 23 nicklas 333       }
7436 15 Nov 23 nicklas 334       else if ("GetUnconfirmed".equals(cmd))
7436 15 Nov 23 nicklas 335       {
7436 15 Nov 23 nicklas 336         dc = sc.newDbControl(":Confirm WGS variant calling");
7436 15 Nov 23 nicklas 337         ItemQuery<RawBioAssay> query = RawBioAssay.getQuery();
7436 15 Nov 23 nicklas 338         query.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
7436 15 Nov 23 nicklas 339         Rawdatatype.VARIANT_CALL.addFilter(dc, query);
7436 15 Nov 23 nicklas 340         Pipeline.DNA_PAIRED_VARIANTCALL.addFilter(dc, query);
7436 15 Nov 23 nicklas 341         
7436 15 Nov 23 nicklas 342         // The job must be ended
7436 15 Nov 23 nicklas 343         query.join(Hql.innerJoin("job", "jb"));
7436 15 Nov 23 nicklas 344         query.restrict(Restrictions.neq(Hql.property("jb", "ended"), null));
7436 15 Nov 23 nicklas 345         // Must NOT have a ANALYSIS_RESULT annotation
7436 15 Nov 23 nicklas 346         query.join(Annotations.leftJoin(null, Annotationtype.ANALYSIS_RESULT.load(dc), "ar"));
7436 15 Nov 23 nicklas 347         query.restrict(Restrictions.eq(Hql.alias("ar"), null));
7436 15 Nov 23 nicklas 348         // Ignore if AutoProcess==AutoConfirm
7436 15 Nov 23 nicklas 349         query.join(Annotations.leftJoin(null, Annotationtype.AUTO_PROCESSING.load(dc), "ap"));
7436 15 Nov 23 nicklas 350         query.restrict(
7436 15 Nov 23 nicklas 351             Restrictions.or(
7436 15 Nov 23 nicklas 352               Restrictions.neq(Hql.alias("ap"), Expressions.string("AutoConfirm")),
7436 15 Nov 23 nicklas 353               Restrictions.eq(Hql.alias("ap"), null)
7436 15 Nov 23 nicklas 354             ));
7436 15 Nov 23 nicklas 355         query.order(Orders.asc(Hql.property("name")));
7436 15 Nov 23 nicklas 356         query.setMaxResults(250);
7436 15 Nov 23 nicklas 357         
7436 15 Nov 23 nicklas 358         SnapshotManager manager = new SnapshotManager();
7436 15 Nov 23 nicklas 359         List<Rawbioassay> list = Rawbioassay.toList(query.list(dc));
7436 15 Nov 23 nicklas 360         JSONArray jsonRawBioAssays = new JSONArray();
7436 15 Nov 23 nicklas 361         for (Rawbioassay raw : list)
7436 15 Nov 23 nicklas 362         {
7436 15 Nov 23 nicklas 363           RawBioAssay rba = raw.getItem();
7436 15 Nov 23 nicklas 364           raw.loadAnnotations(dc, manager, "DataFilesFolder", Annotationtype.DATA_FILES_FOLDER, null);
7436 15 Nov 23 nicklas 365           raw.loadAnnotations(dc, manager, "VariantsPassedFilter", Annotationtype.VARIANTS_PASSED_FILTER, null);
7436 15 Nov 23 nicklas 366           raw.loadAnnotations(dc, manager, "CallableBases", Annotationtype.CALLABLE_BASES, null);
7436 15 Nov 23 nicklas 367           raw.loadAnnotations(dc, manager, "VariantsRaw", Annotationtype.VARIANTS_RAW, null);
7440 16 Nov 23 nicklas 368           raw.loadAnnotations(dc, manager, "PanelOfNormals", Annotationtype.PANEL_OF_NORMALS, null);
7436 15 Nov 23 nicklas 369           
7436 15 Nov 23 nicklas 370           // Normal alignment
7436 15 Nov 23 nicklas 371           AlignedSequences normal = AlignedSequences.get(raw.getLinkedItem(dc, "Normal"));
7436 15 Nov 23 nicklas 372           if (normal != null)
7436 15 Nov 23 nicklas 373           {
7436 15 Nov 23 nicklas 374             raw.setAnnotation("normal", normal.asJSONObject());
7436 15 Nov 23 nicklas 375           }
7436 15 Nov 23 nicklas 376           
7436 15 Nov 23 nicklas 377           File vcf = raw.getFile(dc, Datafiletype.VCF);
7436 15 Nov 23 nicklas 378           if (vcf != null) raw.setAnnotation("vcfFile", JsonUtil.getFileAsJSON(vcf));
7436 15 Nov 23 nicklas 379           
7436 15 Nov 23 nicklas 380           // Load job information
7436 15 Nov 23 nicklas 381           Job job = rba.getJob();
7436 15 Nov 23 nicklas 382           JSONObject jsonJob = JsonUtil.getJobAsJSON(job);
7436 15 Nov 23 nicklas 383           raw.setAnnotation("vcallJob", jsonJob);
7436 15 Nov 23 nicklas 384           
7436 15 Nov 23 nicklas 385           jsonRawBioAssays.add(raw.asJSONObject());
7436 15 Nov 23 nicklas 386         }
7436 15 Nov 23 nicklas 387         
7436 15 Nov 23 nicklas 388         json.put("rawBioAssays", jsonRawBioAssays);
7436 15 Nov 23 nicklas 389       }
7423 14 Nov 23 nicklas 390       else if ("GetVcfStatistics".equals(cmd))
7423 14 Nov 23 nicklas 391       {
7423 14 Nov 23 nicklas 392         int fileId = Values.getInt(req.getParameter("fileId"));
7423 14 Nov 23 nicklas 393         int itemId = Values.getInt(req.getParameter("itemId"));
7423 14 Nov 23 nicklas 394         dc = sc.newDbControl(":View variants");
7423 14 Nov 23 nicklas 395         
7423 14 Nov 23 nicklas 396         Rawbioassay vcall = Rawbioassay.getById(dc, itemId);
7423 14 Nov 23 nicklas 397         vcall.setAnnotation("VariantsRaw", Annotationtype.VARIANTS_RAW.getAnnotationValue(dc, vcall.getItem()));
7423 14 Nov 23 nicklas 398
7423 14 Nov 23 nicklas 399         File vcf = File.getById(dc, fileId);
7423 14 Nov 23 nicklas 400         InputStream vcfIn = null;
7423 14 Nov 23 nicklas 401         try
7423 14 Nov 23 nicklas 402         {
7423 14 Nov 23 nicklas 403           VcfParser parser = new VcfParser();
7423 14 Nov 23 nicklas 404           parser.setUseLineNoAsId(true);
7423 14 Nov 23 nicklas 405           parser.setInfoFactory(new VariantCallingInfoFactory(
7426 14 Nov 23 nicklas 406               Arrays.asList("TYPE", "ncbiRefSeq", "cosmic_AA", "cosmic_CDS", "cosmic_ID", "cosmic_nc_ID", "dbsnp_ID"),
7423 14 Nov 23 nicklas 407               Arrays.asList("HGVS.c", "HGVS.p")
7423 14 Nov 23 nicklas 408               ));
7423 14 Nov 23 nicklas 409           vcfIn = vcf.getDownloadStream(0);
7423 14 Nov 23 nicklas 410           if (vcf.getName().endsWith(".gz")) vcfIn = new GZIPInputStream(vcfIn);
7423 14 Nov 23 nicklas 411           VcfData vcfData = parser.parse(vcfIn, vcf.getName(), new PassFilterFilter());
7423 14 Nov 23 nicklas 412           FileUtil.close(vcfIn);
7423 14 Nov 23 nicklas 413           
7423 14 Nov 23 nicklas 414           List<SnpData> snpList = parser.getSnpData();
7423 14 Nov 23 nicklas 415           JSONArray jsonSnp = new JSONArray();
7423 14 Nov 23 nicklas 416           for (SnpData snp : snpList)
7423 14 Nov 23 nicklas 417           {
7423 14 Nov 23 nicklas 418             JSONObject jsonGt = new JSONObject();
7423 14 Nov 23 nicklas 419             jsonGt.put("snp", snp.asJSONObject());
7423 14 Nov 23 nicklas 420             
7423 14 Nov 23 nicklas 421             GtData gtTumor = vcfData.getGtData(snp.getId());
7423 14 Nov 23 nicklas 422             GtData gtNormal = vcfData.getNormalGtData(snp.getId());
7423 14 Nov 23 nicklas 423             if (gtTumor != null) jsonGt.put("gtTumor", gtTumor.asJSONObject(vcfData.getQualityModel())); 
7423 14 Nov 23 nicklas 424             if (gtNormal != null) jsonGt.put("gtNormal", gtNormal.asJSONObject(vcfData.getQualityModel())); 
7423 14 Nov 23 nicklas 425
7423 14 Nov 23 nicklas 426             jsonSnp.add(jsonGt);
7423 14 Nov 23 nicklas 427           }
7423 14 Nov 23 nicklas 428           
7423 14 Nov 23 nicklas 429           json.put("rawbioassay", vcall.asJSONObject());
7423 14 Nov 23 nicklas 430           json.put("vcfSummary", vcfData.asJSONObject());
7423 14 Nov 23 nicklas 431           json.put("snpData", jsonSnp);
7423 14 Nov 23 nicklas 432         }
7423 14 Nov 23 nicklas 433         finally
7423 14 Nov 23 nicklas 434         {
7423 14 Nov 23 nicklas 435           FileUtil.close(vcfIn);
7423 14 Nov 23 nicklas 436         }
7423 14 Nov 23 nicklas 437       }
7387 31 Oct 23 nicklas 438     }
7387 31 Oct 23 nicklas 439     catch (Throwable t)
7387 31 Oct 23 nicklas 440     {
7387 31 Oct 23 nicklas 441       t.printStackTrace();
7387 31 Oct 23 nicklas 442       json.clear();
7387 31 Oct 23 nicklas 443       json.put("status", "error");
7387 31 Oct 23 nicklas 444       json.put("message", t.getMessage());
7387 31 Oct 23 nicklas 445       json.put("stacktrace", ThrowableUtil.stackTraceToString(t));
7387 31 Oct 23 nicklas 446     }
7387 31 Oct 23 nicklas 447     finally
7387 31 Oct 23 nicklas 448     {
7387 31 Oct 23 nicklas 449       if (dc != null) dc.close();
7387 31 Oct 23 nicklas 450       json.writeJSONString(resp.getWriter());
7387 31 Oct 23 nicklas 451     }
7387 31 Oct 23 nicklas 452     
7387 31 Oct 23 nicklas 453   }
7387 31 Oct 23 nicklas 454
7387 31 Oct 23 nicklas 455   @Override
7387 31 Oct 23 nicklas 456   protected void doPost(HttpServletRequest req, HttpServletResponse resp)
7387 31 Oct 23 nicklas 457     throws ServletException, IOException 
7387 31 Oct 23 nicklas 458   {
7387 31 Oct 23 nicklas 459     String cmd = req.getParameter("cmd");
7387 31 Oct 23 nicklas 460     JsonUtil.setJsonResponseHeaders(resp);
7387 31 Oct 23 nicklas 461     
7387 31 Oct 23 nicklas 462     JSONObject json = new JSONObject();
7387 31 Oct 23 nicklas 463     json.put("status", "ok");
7387 31 Oct 23 nicklas 464     JSONArray jsonMessages = new JSONArray();
7387 31 Oct 23 nicklas 465   
7387 31 Oct 23 nicklas 466     final SessionControl sc = Reggie.getSessionControl(req);
7387 31 Oct 23 nicklas 467     DbControl dc = null;
7387 31 Oct 23 nicklas 468     try
7387 31 Oct 23 nicklas 469     {
7387 31 Oct 23 nicklas 470
7387 31 Oct 23 nicklas 471       if ("StartPonVariantCalling".equals(cmd))
7387 31 Oct 23 nicklas 472       {
7387 31 Oct 23 nicklas 473         dc = sc.newDbControl(":Start panel-of-normals variant calling");
7387 31 Oct 23 nicklas 474
7388 31 Oct 23 nicklas 475         ReggieRole.checkPermission(dc, "'" + cmd + "' wizard", ReggieRole.ADMINISTRATOR);
7387 31 Oct 23 nicklas 476
7387 31 Oct 23 nicklas 477         JSONObject jsonReq = JsonUtil.parseRequest(req);
7387 31 Oct 23 nicklas 478         JSONArray jsonAligned = (JSONArray)jsonReq.get("alignedSequences");
7387 31 Oct 23 nicklas 479       
7396 06 Nov 23 nicklas 480         Number vcallSoftwareId = (Number)jsonReq.get("vcallSoftware");
7388 31 Oct 23 nicklas 481         String clusterId = (String)jsonReq.get("cluster");
7388 31 Oct 23 nicklas 482         boolean debug = Boolean.TRUE.equals(jsonReq.get("debug"));
7388 31 Oct 23 nicklas 483         boolean autoConfirm = Boolean.TRUE.equals(jsonReq.get("autoConfirm"));
7388 31 Oct 23 nicklas 484         Number priority = (Number)jsonReq.get("priority");
7388 31 Oct 23 nicklas 485         String partition = Values.getStringOrNull((String)jsonReq.get("partition"));
7388 31 Oct 23 nicklas 486         String submitOptions = Values.getStringOrNull((String)jsonReq.get("submitOptionsOverride"));
7388 31 Oct 23 nicklas 487
7388 31 Oct 23 nicklas 488         OpenGridCluster cluster = OpenGridService.getInstance().getClusterById(dc, clusterId);
7388 31 Oct 23 nicklas 489         if (cluster == null)
7388 31 Oct 23 nicklas 490         {
7388 31 Oct 23 nicklas 491           throw new ItemNotFoundException("OpenGridCluster[" + clusterId + "]");
7388 31 Oct 23 nicklas 492         }
7406 08 Nov 23 nicklas 493         
7406 08 Nov 23 nicklas 494         // Configure delay between jobs
7406 08 Nov 23 nicklas 495         BatchConfig batch = new BatchConfig();
7406 08 Nov 23 nicklas 496         batch.setDelayInterval(120); // 2 minutes delay
7406 08 Nov 23 nicklas 497         long initialDelay = NEXT_START_TIME-System.currentTimeMillis();
7406 08 Nov 23 nicklas 498         if (initialDelay > 0)
7406 08 Nov 23 nicklas 499         {
7406 08 Nov 23 nicklas 500           // We have to wait a bit also for the first job
7406 08 Nov 23 nicklas 501           batch.setInitialDelay((int)initialDelay/1000);
7406 08 Nov 23 nicklas 502         }
7406 08 Nov 23 nicklas 503         batch.lock();
7388 31 Oct 23 nicklas 504
7388 31 Oct 23 nicklas 505         // VariantCall job creator implementation
7388 31 Oct 23 nicklas 506         WgsVariantCallJobCreator jobCreator = new WgsVariantCallJobCreator();
7406 08 Nov 23 nicklas 507         jobCreator.setBatchConfig(batch);
7388 31 Oct 23 nicklas 508         jobCreator.setAutoConfirm(autoConfirm);
7388 31 Oct 23 nicklas 509         jobCreator.setDebug(debug);
7388 31 Oct 23 nicklas 510         jobCreator.setPriority(priority == null ? null : priority.intValue());
7388 31 Oct 23 nicklas 511         jobCreator.setPartition(partition);
7388 31 Oct 23 nicklas 512         jobCreator.setSubmitOptionsOverride(submitOptions);
7396 06 Nov 23 nicklas 513         if (vcallSoftwareId != null)
7396 06 Nov 23 nicklas 514         {
7396 06 Nov 23 nicklas 515           jobCreator.setSoftware(Software.getById(dc, vcallSoftwareId.intValue()));
7396 06 Nov 23 nicklas 516         }
7387 31 Oct 23 nicklas 517         
7388 31 Oct 23 nicklas 518         List<AlignedSequences> alignedSequences = new ArrayList<AlignedSequences>();
7388 31 Oct 23 nicklas 519         for (int alNo = 0; alNo < jsonAligned.size(); alNo++)
7388 31 Oct 23 nicklas 520         {
7388 31 Oct 23 nicklas 521           JSONObject jsonAl = (JSONObject)jsonAligned.get(alNo);
7388 31 Oct 23 nicklas 522           Number alignedId = (Number)jsonAl.get("id");
7387 31 Oct 23 nicklas 523         
7388 31 Oct 23 nicklas 524           AlignedSequences as = AlignedSequences.getById(dc, alignedId.intValue());
7388 31 Oct 23 nicklas 525           alignedSequences.add(as);
7388 31 Oct 23 nicklas 526
7388 31 Oct 23 nicklas 527           // Reset AUTO_PROCESSING annotation
7388 31 Oct 23 nicklas 528           DerivedBioAssay aligned = as.getDerivedBioAssay();
7388 31 Oct 23 nicklas 529           Annotationtype.AUTO_PROCESSING.setAnnotationValue(dc, aligned, null);
7388 31 Oct 23 nicklas 530         }
7388 31 Oct 23 nicklas 531
7388 31 Oct 23 nicklas 532         List<JobDefinition> jobDefs = jobCreator.createPonVariantCallingJobs(dc, cluster, alignedSequences);
7388 31 Oct 23 nicklas 533         List<Job> jobs = ScriptUtil.submitJobs(dc, cluster, jobDefs);
7406 08 Nov 23 nicklas 534         // Remember this time so that a new batch is also delayed
7406 08 Nov 23 nicklas 535         NEXT_START_TIME = batch.getNextStartTime();
7388 31 Oct 23 nicklas 536         
7388 31 Oct 23 nicklas 537         for (Job job : jobs)
7388 31 Oct 23 nicklas 538         {
7388 31 Oct 23 nicklas 539           if (job.getStatus() == Job.Status.ERROR)
7388 31 Oct 23 nicklas 540           {
7388 31 Oct 23 nicklas 541             jsonMessages.add("[Error]Job submission for '" + job.getName() + "' failed: " + job.getStatusMessage());
7388 31 Oct 23 nicklas 542           }
7388 31 Oct 23 nicklas 543           else
7388 31 Oct 23 nicklas 544           {
7388 31 Oct 23 nicklas 545             jsonMessages.add("Submitted Panel-of-normal variant calling job to " + cluster.getConnectionInfo().getName() + " with id " + job.getExternalId());
7388 31 Oct 23 nicklas 546           }
7388 31 Oct 23 nicklas 547         }
7388 31 Oct 23 nicklas 548         
7387 31 Oct 23 nicklas 549         dc.commit();
7387 31 Oct 23 nicklas 550       }
7394 06 Nov 23 nicklas 551       else if ("RegisterPanelOfNormals".equals(cmd))
7394 06 Nov 23 nicklas 552       {
7394 06 Nov 23 nicklas 553         dc = sc.newDbControl(":Confirm panel-of-normals variant calling");
7387 31 Oct 23 nicklas 554
7394 06 Nov 23 nicklas 555         ReggieRole.checkPermission(dc, "'" + cmd + "' wizard", ReggieRole.ADMINISTRATOR);
7394 06 Nov 23 nicklas 556
7394 06 Nov 23 nicklas 557         JSONObject jsonReq = JsonUtil.parseRequest(req);
7394 06 Nov 23 nicklas 558         JSONArray jsonPonItems = (JSONArray)jsonReq.get("panelOfNormals");
7394 06 Nov 23 nicklas 559
7394 06 Nov 23 nicklas 560         int numConfirmed = 0;
7394 06 Nov 23 nicklas 561         int numDeleted = 0;
7394 06 Nov 23 nicklas 562         int numUndecided = 0;
7394 06 Nov 23 nicklas 563         
7394 06 Nov 23 nicklas 564         List<BasicItem> toDelete = new ArrayList<BasicItem>();
7394 06 Nov 23 nicklas 565         
7394 06 Nov 23 nicklas 566         for (int ponNo = 0; ponNo < jsonPonItems.size(); ++ponNo)
7394 06 Nov 23 nicklas 567         {
7394 06 Nov 23 nicklas 568           JSONObject jsonPon = (JSONObject)jsonPonItems.get(ponNo);
7394 06 Nov 23 nicklas 569           Number ponId = (Number)jsonPon.get("id");
7394 06 Nov 23 nicklas 570           boolean confirm = Boolean.TRUE.equals(jsonPon.get("confirm"));
7394 06 Nov 23 nicklas 571           boolean delete = Boolean.TRUE.equals(jsonPon.get("delete"));
7394 06 Nov 23 nicklas 572           
7394 06 Nov 23 nicklas 573           DerivedBioAssay pon = DerivedBioAssay.getById(dc, ponId.intValue());
7394 06 Nov 23 nicklas 574           if (delete)
7394 06 Nov 23 nicklas 575           {
7394 06 Nov 23 nicklas 576             pon.setRemoved(true);
7394 06 Nov 23 nicklas 577             toDelete.add(pon);
7394 06 Nov 23 nicklas 578             toDelete.addAll(Reggie.removeAttachedFiles(dc, pon));
7394 06 Nov 23 nicklas 579             numDeleted++;
7394 06 Nov 23 nicklas 580           }
7394 06 Nov 23 nicklas 581           else
7394 06 Nov 23 nicklas 582           {          
7394 06 Nov 23 nicklas 583             String comment = Values.getStringOrNull((String)jsonPon.get("comment"));
7394 06 Nov 23 nicklas 584             pon.setDescription(comment);            
7394 06 Nov 23 nicklas 585             if (confirm)
7394 06 Nov 23 nicklas 586             {
7394 06 Nov 23 nicklas 587               Job job = pon.getJob();
7394 06 Nov 23 nicklas 588               if (job.getStatus() == Job.Status.ERROR)
7394 06 Nov 23 nicklas 589               {
7394 06 Nov 23 nicklas 590                 Annotationtype.ANALYSIS_RESULT.setAnnotationValue(dc, pon, "Failed");
7394 06 Nov 23 nicklas 591               }
7394 06 Nov 23 nicklas 592               else
7394 06 Nov 23 nicklas 593               {
7394 06 Nov 23 nicklas 594                 Annotationtype.ANALYSIS_RESULT.setAnnotationValue(dc, pon, "Successful");
7394 06 Nov 23 nicklas 595               }
7394 06 Nov 23 nicklas 596               numConfirmed++;
7394 06 Nov 23 nicklas 597             }
7394 06 Nov 23 nicklas 598             else
7394 06 Nov 23 nicklas 599             {
7394 06 Nov 23 nicklas 600               numUndecided++;
7394 06 Nov 23 nicklas 601             }
7394 06 Nov 23 nicklas 602           }
7394 06 Nov 23 nicklas 603         }
7394 06 Nov 23 nicklas 604         
7394 06 Nov 23 nicklas 605         if (numConfirmed > 0)
7394 06 Nov 23 nicklas 606         {
7394 06 Nov 23 nicklas 607           jsonMessages.add(numConfirmed + " panel-of-normals confirmed");
7394 06 Nov 23 nicklas 608         }
7394 06 Nov 23 nicklas 609         if (numDeleted > 0)
7394 06 Nov 23 nicklas 610         {
7394 06 Nov 23 nicklas 611           jsonMessages.add(numDeleted + " panel-of-normals deleted");
7394 06 Nov 23 nicklas 612         }
7394 06 Nov 23 nicklas 613         if (numUndecided > 0)
7394 06 Nov 23 nicklas 614         {
7394 06 Nov 23 nicklas 615           jsonMessages.add(numUndecided + " panel-of-normals remain undecided");
7394 06 Nov 23 nicklas 616         }
7394 06 Nov 23 nicklas 617         dc.commit();
7394 06 Nov 23 nicklas 618         if (toDelete.size() > 0)
7394 06 Nov 23 nicklas 619         {
7394 06 Nov 23 nicklas 620           try
7394 06 Nov 23 nicklas 621           {
7394 06 Nov 23 nicklas 622             Trashcan.delete(sc, toDelete, false, null);
7394 06 Nov 23 nicklas 623           }
7394 06 Nov 23 nicklas 624           catch (RuntimeException ex)
7394 06 Nov 23 nicklas 625           {
7394 06 Nov 23 nicklas 626             ex.printStackTrace();
7394 06 Nov 23 nicklas 627             jsonMessages.add("[Error]Could not delete all items created by failed jobs: " + ex.getMessage());
7394 06 Nov 23 nicklas 628           }
7394 06 Nov 23 nicklas 629         }
7394 06 Nov 23 nicklas 630       }
7395 06 Nov 23 nicklas 631       else if ("BuildPanelOfNormals".equals(cmd))
7395 06 Nov 23 nicklas 632       {
7395 06 Nov 23 nicklas 633         dc = sc.newDbControl(":Build panel-of-normals");
7395 06 Nov 23 nicklas 634
7395 06 Nov 23 nicklas 635         ReggieRole.checkPermission(dc, "'" + cmd + "' wizard", ReggieRole.ADMINISTRATOR);
7395 06 Nov 23 nicklas 636
7395 06 Nov 23 nicklas 637         JSONObject jsonReq = JsonUtil.parseRequest(req);
7395 06 Nov 23 nicklas 638       
7395 06 Nov 23 nicklas 639         Number listId = (Number)jsonReq.get("itemList");
7395 06 Nov 23 nicklas 640         String clusterId = (String)jsonReq.get("cluster");
7395 06 Nov 23 nicklas 641         boolean debug = Boolean.TRUE.equals(jsonReq.get("debug"));
7395 06 Nov 23 nicklas 642         Number priority = (Number)jsonReq.get("priority");
7395 06 Nov 23 nicklas 643         String partition = Values.getStringOrNull((String)jsonReq.get("partition"));
7395 06 Nov 23 nicklas 644
7395 06 Nov 23 nicklas 645         OpenGridCluster cluster = OpenGridService.getInstance().getClusterById(dc, clusterId);
7395 06 Nov 23 nicklas 646         if (cluster == null)
7395 06 Nov 23 nicklas 647         {
7395 06 Nov 23 nicklas 648           throw new ItemNotFoundException("OpenGridCluster[" + clusterId + "]");
7395 06 Nov 23 nicklas 649         }
7395 06 Nov 23 nicklas 650                 
7395 06 Nov 23 nicklas 651         ItemList list = ItemList.getById(dc, listId.intValue());
7395 06 Nov 23 nicklas 652         
7395 06 Nov 23 nicklas 653         WgsVariantCallJobCreator jobCreator = new WgsVariantCallJobCreator();
7395 06 Nov 23 nicklas 654         jobCreator.setDebug(debug);
7395 06 Nov 23 nicklas 655         jobCreator.setPriority(priority == null ? null : priority.intValue());
7395 06 Nov 23 nicklas 656         jobCreator.setPartition(partition);
7395 06 Nov 23 nicklas 657
7395 06 Nov 23 nicklas 658         Job ponJob = jobCreator.buildPanelOfNormals(dc, cluster, list);
7395 06 Nov 23 nicklas 659         if (ponJob.getStatus() == Job.Status.ERROR)
7395 06 Nov 23 nicklas 660         {
7395 06 Nov 23 nicklas 661           jsonMessages.add("[Error]Job submission for '" + ponJob.getName() + "' failed: " + ponJob.getStatusMessage());
7395 06 Nov 23 nicklas 662         }
7395 06 Nov 23 nicklas 663         else
7395 06 Nov 23 nicklas 664         {
7395 06 Nov 23 nicklas 665           jsonMessages.add("Submitted panel-of-normal job to " + cluster.getConnectionInfo().getName() + " with id " + ponJob.getExternalId());
7395 06 Nov 23 nicklas 666         }
7395 06 Nov 23 nicklas 667         dc.commit();
7395 06 Nov 23 nicklas 668       }
7406 08 Nov 23 nicklas 669       else if ("StartVariantCalling".equals(cmd))
7406 08 Nov 23 nicklas 670       {
7406 08 Nov 23 nicklas 671         dc = sc.newDbControl(":Start WGS variant calling");
7406 08 Nov 23 nicklas 672
7406 08 Nov 23 nicklas 673         ReggieRole.checkPermission(dc, "'" + cmd + "' wizard", ReggieRole.SECONDARY_ANALYSIS, ReggieRole.ADMINISTRATOR);
7406 08 Nov 23 nicklas 674
7406 08 Nov 23 nicklas 675         JSONObject jsonReq = JsonUtil.parseRequest(req);
7406 08 Nov 23 nicklas 676         JSONArray jsonAligned = (JSONArray)jsonReq.get("alignedSequences");
7406 08 Nov 23 nicklas 677       
7439 16 Nov 23 nicklas 678         String panelOfNormals = Values.getStringOrNull((String)jsonReq.get("panelOfNormals"));
7406 08 Nov 23 nicklas 679         Number vcallSoftwareId = (Number)jsonReq.get("vcallSoftware");
7406 08 Nov 23 nicklas 680         String clusterId = (String)jsonReq.get("cluster");
7406 08 Nov 23 nicklas 681         boolean debug = Boolean.TRUE.equals(jsonReq.get("debug"));
7406 08 Nov 23 nicklas 682         boolean autoConfirm = Boolean.TRUE.equals(jsonReq.get("autoConfirm"));
7406 08 Nov 23 nicklas 683         Number priority = (Number)jsonReq.get("priority");
7406 08 Nov 23 nicklas 684         String partition = Values.getStringOrNull((String)jsonReq.get("partition"));
7406 08 Nov 23 nicklas 685         String submitOptions = Values.getStringOrNull((String)jsonReq.get("submitOptionsOverride"));
7406 08 Nov 23 nicklas 686
7406 08 Nov 23 nicklas 687         OpenGridCluster cluster = OpenGridService.getInstance().getClusterById(dc, clusterId);
7406 08 Nov 23 nicklas 688         if (cluster == null)
7406 08 Nov 23 nicklas 689         {
7406 08 Nov 23 nicklas 690           throw new ItemNotFoundException("OpenGridCluster[" + clusterId + "]");
7406 08 Nov 23 nicklas 691         }
7406 08 Nov 23 nicklas 692
7406 08 Nov 23 nicklas 693         // Configure delay between jobs
7406 08 Nov 23 nicklas 694         BatchConfig batch = new BatchConfig();
7406 08 Nov 23 nicklas 695         batch.setDelayInterval(120); // 2 minutes delay
7406 08 Nov 23 nicklas 696         long initialDelay = NEXT_START_TIME-System.currentTimeMillis();
7406 08 Nov 23 nicklas 697         if (initialDelay > 0)
7406 08 Nov 23 nicklas 698         {
7406 08 Nov 23 nicklas 699           // We have to wait a bit also for the first job
7406 08 Nov 23 nicklas 700           batch.setInitialDelay((int)initialDelay/1000);
7406 08 Nov 23 nicklas 701         }
7406 08 Nov 23 nicklas 702         batch.lock();
7406 08 Nov 23 nicklas 703
7406 08 Nov 23 nicklas 704         // VariantCall job creator implementation
7406 08 Nov 23 nicklas 705         WgsVariantCallJobCreator jobCreator = new WgsVariantCallJobCreator();
7406 08 Nov 23 nicklas 706         jobCreator.setBatchConfig(batch);
7406 08 Nov 23 nicklas 707         jobCreator.setAutoConfirm(autoConfirm);
7406 08 Nov 23 nicklas 708         jobCreator.setDebug(debug);
7406 08 Nov 23 nicklas 709         jobCreator.setPriority(priority == null ? null : priority.intValue());
7406 08 Nov 23 nicklas 710         jobCreator.setPartition(partition);
7406 08 Nov 23 nicklas 711         jobCreator.setSubmitOptionsOverride(submitOptions);
7439 16 Nov 23 nicklas 712         jobCreator.setPanelOfNormals(panelOfNormals);
7406 08 Nov 23 nicklas 713         if (vcallSoftwareId != null)
7406 08 Nov 23 nicklas 714         {
7406 08 Nov 23 nicklas 715           jobCreator.setSoftware(Software.getById(dc, vcallSoftwareId.intValue()));
7406 08 Nov 23 nicklas 716         }
7406 08 Nov 23 nicklas 717         
7406 08 Nov 23 nicklas 718         List<TumorNormalPair> pairs = new ArrayList<TumorNormalPair>();
7406 08 Nov 23 nicklas 719         for (int alNo = 0; alNo < jsonAligned.size(); alNo++)
7406 08 Nov 23 nicklas 720         {
7406 08 Nov 23 nicklas 721           JSONObject jsonAl = (JSONObject)jsonAligned.get(alNo);
7406 08 Nov 23 nicklas 722           Number tumorId = (Number)jsonAl.get("tumorId");
7406 08 Nov 23 nicklas 723           Number normalId = (Number)jsonAl.get("normalId");
7406 08 Nov 23 nicklas 724         
7406 08 Nov 23 nicklas 725           TumorNormalPair pair = new TumorNormalPair(
7406 08 Nov 23 nicklas 726             AlignedSequences.getById(dc, tumorId.intValue()), 
7406 08 Nov 23 nicklas 727             AlignedSequences.getById(dc, normalId.intValue()));
7406 08 Nov 23 nicklas 728           pairs.add(pair);
7406 08 Nov 23 nicklas 729
7406 08 Nov 23 nicklas 730           // Reset AUTO_PROCESSING annotation
7406 08 Nov 23 nicklas 731           Annotationtype.AUTO_PROCESSING.setAnnotationValue(dc, pair.tumor.getDerivedBioAssay(), null);
7406 08 Nov 23 nicklas 732         }
7406 08 Nov 23 nicklas 733
7411 10 Nov 23 nicklas 734         List<JobDefinition> jobDefs = jobCreator.createPairedVariantCallingJobs(dc, cluster, pairs);
7406 08 Nov 23 nicklas 735         List<Job> jobs = ScriptUtil.submitJobs(dc, cluster, jobDefs);
7406 08 Nov 23 nicklas 736         // Remember this time so that a new batch is also delayed
7406 08 Nov 23 nicklas 737         NEXT_START_TIME = batch.getNextStartTime();
7406 08 Nov 23 nicklas 738         
7406 08 Nov 23 nicklas 739         for (Job job : jobs)
7406 08 Nov 23 nicklas 740         {
7406 08 Nov 23 nicklas 741           if (job.getStatus() == Job.Status.ERROR)
7406 08 Nov 23 nicklas 742           {
7406 08 Nov 23 nicklas 743             jsonMessages.add("[Error]Job submission for '" + job.getName() + "' failed: " + job.getStatusMessage());
7406 08 Nov 23 nicklas 744           }
7406 08 Nov 23 nicklas 745           else
7406 08 Nov 23 nicklas 746           {
7406 08 Nov 23 nicklas 747             jsonMessages.add("Submitted WGS variant calling job to " + cluster.getConnectionInfo().getName() + " with id " + job.getExternalId());
7406 08 Nov 23 nicklas 748           }
7406 08 Nov 23 nicklas 749         }
7406 08 Nov 23 nicklas 750         
7406 08 Nov 23 nicklas 751         dc.commit();
7406 08 Nov 23 nicklas 752       }
7437 15 Nov 23 nicklas 753       else if ("ConfirmVariantCalling".equals(cmd))
7437 15 Nov 23 nicklas 754       {
7437 15 Nov 23 nicklas 755         dc = sc.newDbControl(":Confirm WGS variant calling");
7437 15 Nov 23 nicklas 756
7437 15 Nov 23 nicklas 757         ReggieRole.checkPermission(dc, "'" + cmd + "' wizard", ReggieRole.SECONDARY_ANALYSIS, ReggieRole.ADMINISTRATOR);
7437 15 Nov 23 nicklas 758
7437 15 Nov 23 nicklas 759         JSONObject jsonReq = JsonUtil.parseRequest(req);
7437 15 Nov 23 nicklas 760         JSONArray jsonRawBioAssays = (JSONArray)jsonReq.get("rawBioAssays");
7437 15 Nov 23 nicklas 761
7437 15 Nov 23 nicklas 762         int numConfirmed = 0;
7437 15 Nov 23 nicklas 763         int numUnconfirmed = 0;
7437 15 Nov 23 nicklas 764         int numReRun = 0;
7437 15 Nov 23 nicklas 765         int numDeleted = 0;
7437 15 Nov 23 nicklas 766         
7437 15 Nov 23 nicklas 767         ItemList vcallPipeline = BiomaterialList.WGS_VARIANT_CALLING_PIPELINE.load(dc);
7437 15 Nov 23 nicklas 768         
7437 15 Nov 23 nicklas 769         boolean deleteItemsCreatedByFailedJobs = Boolean.TRUE.equals(jsonReq.get("deleteItemsCreatedByFailedJobs"));
7437 15 Nov 23 nicklas 770         List<BasicItem> toDelete = new ArrayList<BasicItem>();
7437 15 Nov 23 nicklas 771         
7437 15 Nov 23 nicklas 772         for (int rawNo = 0; rawNo < jsonRawBioAssays.size(); ++rawNo)
7437 15 Nov 23 nicklas 773         {
7437 15 Nov 23 nicklas 774           JSONObject jsonRaw = (JSONObject)jsonRawBioAssays.get(rawNo);
7437 15 Nov 23 nicklas 775           Number rawdId = (Number)jsonRaw.get("id");
7437 15 Nov 23 nicklas 776           
7437 15 Nov 23 nicklas 777           Rawbioassay raw = Rawbioassay.getById(dc, rawdId.intValue());
7437 15 Nov 23 nicklas 778           AlignedSequences aligned = raw.getAlignedSequences(dc);
7437 15 Nov 23 nicklas 779           
7437 15 Nov 23 nicklas 780           DerivedBioAssay alignedDBA = aligned.getDerivedBioAssay();
7437 15 Nov 23 nicklas 781           RawBioAssay rba = raw.getRawBioAssay();
7437 15 Nov 23 nicklas 782           Job job = rba.getJob();
7437 15 Nov 23 nicklas 783           Annotationtype.AUTO_PROCESSING.setAnnotationValue(dc, rba, null);
7437 15 Nov 23 nicklas 784                   
7437 15 Nov 23 nicklas 785           String comment = Values.getStringOrNull((String)jsonRaw.get("comment"));
7437 15 Nov 23 nicklas 786           rba.setDescription(comment);
7437 15 Nov 23 nicklas 787           
7437 15 Nov 23 nicklas 788           boolean reRun = Boolean.TRUE.equals(jsonRaw.get("rerun"));
7437 15 Nov 23 nicklas 789           boolean confirm = Boolean.TRUE.equals(jsonRaw.get("confirm"));
7437 15 Nov 23 nicklas 790           boolean deleted = false;
7437 15 Nov 23 nicklas 791
7437 15 Nov 23 nicklas 792           if (reRun)
7437 15 Nov 23 nicklas 793           {
7437 15 Nov 23 nicklas 794             // Set ReProcess annotation on aligned sequences item
7437 15 Nov 23 nicklas 795             Annotationtype.AUTO_PROCESSING.setAnnotationValue(dc, aligned.getItem(), "ReProcess");
7437 15 Nov 23 nicklas 796             vcallPipeline.add(aligned.getItem());
7437 15 Nov 23 nicklas 797             numReRun++;
7437 15 Nov 23 nicklas 798             
7437 15 Nov 23 nicklas 799             if (deleteItemsCreatedByFailedJobs && !confirm)
7437 15 Nov 23 nicklas 800             {
7437 15 Nov 23 nicklas 801               // Delete rawbioassay and related items
7437 15 Nov 23 nicklas 802               rba.setRemoved(true);
7437 15 Nov 23 nicklas 803               toDelete.add(rba);
7437 15 Nov 23 nicklas 804               toDelete.addAll(Reggie.removeAttachedFiles(dc, rba));
7437 15 Nov 23 nicklas 805               deleted = true;
7437 15 Nov 23 nicklas 806               numDeleted++;
7437 15 Nov 23 nicklas 807             }
7437 15 Nov 23 nicklas 808           }
7437 15 Nov 23 nicklas 809           
7437 15 Nov 23 nicklas 810           if (!deleted)
7437 15 Nov 23 nicklas 811           {
7437 15 Nov 23 nicklas 812             if (confirm)
7437 15 Nov 23 nicklas 813             {
7437 15 Nov 23 nicklas 814               Annotationtype.ANALYSIS_RESULT.setAnnotationValue(dc, rba, Rawbioassay.FEATURE_EXTRACTION_SUCCESSFUL);
7437 15 Nov 23 nicklas 815               numConfirmed++;
7437 15 Nov 23 nicklas 816             }
7437 15 Nov 23 nicklas 817             else if (reRun)
7437 15 Nov 23 nicklas 818             {
7437 15 Nov 23 nicklas 819               Annotationtype.ANALYSIS_RESULT.setAnnotationValue(dc, rba, Rawbioassay.FEATURE_EXTRACTION_FAILED);
7437 15 Nov 23 nicklas 820             }
7437 15 Nov 23 nicklas 821             else
7437 15 Nov 23 nicklas 822             {
7437 15 Nov 23 nicklas 823               numUnconfirmed++;
7437 15 Nov 23 nicklas 824             }
7437 15 Nov 23 nicklas 825           }
7437 15 Nov 23 nicklas 826         }
7437 15 Nov 23 nicklas 827         
7437 15 Nov 23 nicklas 828         if (numConfirmed > 0)
7437 15 Nov 23 nicklas 829         {
7437 15 Nov 23 nicklas 830           jsonMessages.add("Variant calling confirmed for " + numConfirmed + " alignments");
7437 15 Nov 23 nicklas 831           ActivityDef.WGS_VARIANT_CALLING_CONFIRMED.merge(dc, numConfirmed);
7437 15 Nov 23 nicklas 832         }
7437 15 Nov 23 nicklas 833         else
7437 15 Nov 23 nicklas 834         {
7437 15 Nov 23 nicklas 835           jsonMessages.add("No variant callings confirmed");
7437 15 Nov 23 nicklas 836         }
7437 15 Nov 23 nicklas 837         
7437 15 Nov 23 nicklas 838         if (numReRun > 0)
7437 15 Nov 23 nicklas 839         {
7437 15 Nov 23 nicklas 840           jsonMessages.add(numReRun + " alignments flagged for new variant calling");
7437 15 Nov 23 nicklas 841         }
7437 15 Nov 23 nicklas 842         
7437 15 Nov 23 nicklas 843         if (numDeleted > 0)
7437 15 Nov 23 nicklas 844         {
7437 15 Nov 23 nicklas 845           jsonMessages.add(numDeleted + " variant callings deleted due to failure");
7437 15 Nov 23 nicklas 846           if (toDelete.size() > numDeleted)
7437 15 Nov 23 nicklas 847           {
7437 15 Nov 23 nicklas 848             jsonMessages.add((toDelete.size() - numDeleted) + " linked items (eg. parent items and files) deleted");
7437 15 Nov 23 nicklas 849           }
7437 15 Nov 23 nicklas 850         }
7437 15 Nov 23 nicklas 851
7437 15 Nov 23 nicklas 852         if (numUnconfirmed > 0)
7437 15 Nov 23 nicklas 853         {
7437 15 Nov 23 nicklas 854           jsonMessages.add(numUnconfirmed + " variant callings remain unconfirmed");
7437 15 Nov 23 nicklas 855         }
7437 15 Nov 23 nicklas 856         dc.commit();
7437 15 Nov 23 nicklas 857         if (toDelete.size() > 0)
7437 15 Nov 23 nicklas 858         {
7437 15 Nov 23 nicklas 859           try
7437 15 Nov 23 nicklas 860           {
7437 15 Nov 23 nicklas 861             Trashcan.delete(sc, toDelete, false, null);
7437 15 Nov 23 nicklas 862           }
7437 15 Nov 23 nicklas 863           catch (RuntimeException ex)
7437 15 Nov 23 nicklas 864           {
7437 15 Nov 23 nicklas 865             ex.printStackTrace();
7437 15 Nov 23 nicklas 866             jsonMessages.add("[Error]Could not delete all items created by failed jobs: " + ex.getMessage());
7437 15 Nov 23 nicklas 867           }
7437 15 Nov 23 nicklas 868         }
7437 15 Nov 23 nicklas 869       }
7387 31 Oct 23 nicklas 870       json.put("messages", jsonMessages);
7387 31 Oct 23 nicklas 871       CounterService.getInstance().setForceCount();
7387 31 Oct 23 nicklas 872     }
7387 31 Oct 23 nicklas 873     catch (Throwable t)
7387 31 Oct 23 nicklas 874     {
7387 31 Oct 23 nicklas 875       t.printStackTrace();
7387 31 Oct 23 nicklas 876       json.clear();
7387 31 Oct 23 nicklas 877       json.put("status", "error");
7387 31 Oct 23 nicklas 878       json.put("message", t.getMessage());
7387 31 Oct 23 nicklas 879       json.put("stacktrace", ThrowableUtil.stackTraceToString(t));
7387 31 Oct 23 nicklas 880     }
7387 31 Oct 23 nicklas 881     finally
7387 31 Oct 23 nicklas 882     {
7387 31 Oct 23 nicklas 883       if (dc != null) dc.close();
7387 31 Oct 23 nicklas 884       json.writeJSONString(resp.getWriter());
7387 31 Oct 23 nicklas 885     }
7387 31 Oct 23 nicklas 886     
7387 31 Oct 23 nicklas 887   }
7387 31 Oct 23 nicklas 888   
7387 31 Oct 23 nicklas 889   
7387 31 Oct 23 nicklas 890 }