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

Code
Comments
Other
Rev Date Author Line
4642 28 Nov 17 nicklas 1 package net.sf.basedb.reggie.servlet;
4642 28 Nov 17 nicklas 2
4642 28 Nov 17 nicklas 3 import java.io.IOException;
4642 28 Nov 17 nicklas 4 import java.io.InputStream;
4728 04 Apr 18 nicklas 5 import java.util.ArrayList;
4649 20 Dec 17 nicklas 6 import java.util.Arrays;
4648 15 Dec 17 nicklas 7 import java.util.Date;
4818 22 May 18 nicklas 8 import java.util.HashSet;
4642 28 Nov 17 nicklas 9 import java.util.List;
4648 15 Dec 17 nicklas 10 import java.util.Map;
7212 29 May 23 nicklas 11 import java.util.Queue;
4818 22 May 18 nicklas 12 import java.util.Set;
7212 29 May 23 nicklas 13 import java.util.concurrent.Callable;
7212 29 May 23 nicklas 14 import java.util.concurrent.ConcurrentLinkedQueue;
7212 29 May 23 nicklas 15 import java.util.concurrent.ExecutorCompletionService;
7212 29 May 23 nicklas 16 import java.util.concurrent.ExecutorService;
7212 29 May 23 nicklas 17 import java.util.concurrent.Executors;
7212 29 May 23 nicklas 18 import java.util.concurrent.Future;
4642 28 Nov 17 nicklas 19
4642 28 Nov 17 nicklas 20 import javax.servlet.ServletException;
4642 28 Nov 17 nicklas 21 import javax.servlet.http.HttpServlet;
4642 28 Nov 17 nicklas 22 import javax.servlet.http.HttpServletRequest;
4642 28 Nov 17 nicklas 23 import javax.servlet.http.HttpServletResponse;
4642 28 Nov 17 nicklas 24
4642 28 Nov 17 nicklas 25 import org.json.simple.JSONArray;
4642 28 Nov 17 nicklas 26 import org.json.simple.JSONObject;
4642 28 Nov 17 nicklas 27
7216 30 May 23 nicklas 28 import net.sf.basedb.core.AnnotatedItem;
4649 20 Dec 17 nicklas 29 import net.sf.basedb.core.AnnotationBatcher;
4649 20 Dec 17 nicklas 30 import net.sf.basedb.core.AnnotationType;
4648 15 Dec 17 nicklas 31 import net.sf.basedb.core.BioMaterial;
4648 15 Dec 17 nicklas 32 import net.sf.basedb.core.BioSource;
4642 28 Nov 17 nicklas 33 import net.sf.basedb.core.DbControl;
4642 28 Nov 17 nicklas 34 import net.sf.basedb.core.DerivedBioAssay;
4648 15 Dec 17 nicklas 35 import net.sf.basedb.core.Extract;
4642 28 Nov 17 nicklas 36 import net.sf.basedb.core.File;
4649 20 Dec 17 nicklas 37 import net.sf.basedb.core.Item;
4649 20 Dec 17 nicklas 38 import net.sf.basedb.core.ItemList;
4642 28 Nov 17 nicklas 39 import net.sf.basedb.core.ItemQuery;
4975 21 Sep 18 nicklas 40 import net.sf.basedb.core.ItemSubtype;
4975 21 Sep 18 nicklas 41 import net.sf.basedb.core.RawBioAssay;
4817 21 May 18 nicklas 42 import net.sf.basedb.core.Sample;
4642 28 Nov 17 nicklas 43 import net.sf.basedb.core.SessionControl;
4646 14 Dec 17 nicklas 44 import net.sf.basedb.core.SimpleProgressReporter;
4975 21 Sep 18 nicklas 45 import net.sf.basedb.core.Subtypable;
4979 24 Sep 18 nicklas 46 import net.sf.basedb.core.Type;
4649 20 Dec 17 nicklas 47 import net.sf.basedb.core.query.Annotations;
4975 21 Sep 18 nicklas 48 import net.sf.basedb.core.query.Expressions;
4642 28 Nov 17 nicklas 49 import net.sf.basedb.core.query.Hql;
4642 28 Nov 17 nicklas 50 import net.sf.basedb.core.query.Orders;
4975 21 Sep 18 nicklas 51 import net.sf.basedb.core.query.Restriction;
4975 21 Sep 18 nicklas 52 import net.sf.basedb.core.query.Restrictions;
4642 28 Nov 17 nicklas 53 import net.sf.basedb.core.snapshot.SnapshotManager;
4642 28 Nov 17 nicklas 54 import net.sf.basedb.reggie.JsonUtil;
4642 28 Nov 17 nicklas 55 import net.sf.basedb.reggie.Reggie;
7212 29 May 23 nicklas 56 import net.sf.basedb.reggie.ReggieThreadFactory;
5384 26 Apr 19 nicklas 57 import net.sf.basedb.reggie.activity.ActivityDef;
4648 15 Dec 17 nicklas 58 import net.sf.basedb.reggie.counter.CounterService;
4642 28 Nov 17 nicklas 59 import net.sf.basedb.reggie.dao.AlignedSequences;
4642 28 Nov 17 nicklas 60 import net.sf.basedb.reggie.dao.Annotationtype;
6590 21 Feb 22 nicklas 61 import net.sf.basedb.reggie.dao.BeadChip;
4649 20 Dec 17 nicklas 62 import net.sf.basedb.reggie.dao.BiomaterialList;
6590 21 Feb 22 nicklas 63 import net.sf.basedb.reggie.dao.BloodDna;
6589 21 Feb 22 nicklas 64 import net.sf.basedb.reggie.dao.GenotypeCall;
4642 28 Nov 17 nicklas 65 import net.sf.basedb.reggie.dao.Library;
4817 21 May 18 nicklas 66 import net.sf.basedb.reggie.dao.Lysate;
7209 26 May 23 nicklas 67 import net.sf.basedb.reggie.dao.Pipeline;
7209 26 May 23 nicklas 68 import net.sf.basedb.reggie.dao.ReggieItem;
4642 28 Nov 17 nicklas 69 import net.sf.basedb.reggie.dao.ReggieRole;
4642 28 Nov 17 nicklas 70 import net.sf.basedb.reggie.dao.Rna;
4818 22 May 18 nicklas 71 import net.sf.basedb.reggie.dao.SpecimenTube;
4648 15 Dec 17 nicklas 72 import net.sf.basedb.reggie.dao.Subtype;
4649 20 Dec 17 nicklas 73 import net.sf.basedb.reggie.query.AnyToAnyRestriction;
4646 14 Dec 17 nicklas 74 import net.sf.basedb.reggie.vcf.CompareData;
4646 14 Dec 17 nicklas 75 import net.sf.basedb.reggie.vcf.GenoTypeChecker;
4819 22 May 18 nicklas 76 import net.sf.basedb.reggie.vcf.GenoTypeMessage;
4646 14 Dec 17 nicklas 77 import net.sf.basedb.reggie.vcf.GenoTypePreloaderRunnable;
4642 28 Nov 17 nicklas 78 import net.sf.basedb.reggie.vcf.GtData;
4642 28 Nov 17 nicklas 79 import net.sf.basedb.reggie.vcf.SnpData;
4794 07 May 18 nicklas 80 import net.sf.basedb.reggie.vcf.SpecimenData;
4642 28 Nov 17 nicklas 81 import net.sf.basedb.reggie.vcf.VcfData;
4671 07 Feb 18 nicklas 82 import net.sf.basedb.reggie.vcf.VcfPair;
4642 28 Nov 17 nicklas 83 import net.sf.basedb.reggie.vcf.VcfParser;
4728 04 Apr 18 nicklas 84 import net.sf.basedb.reggie.vcf.VerifiedMatch;
5024 15 Oct 18 nicklas 85 import net.sf.basedb.util.EqualsHelper;
4642 28 Nov 17 nicklas 86 import net.sf.basedb.util.FileUtil;
4642 28 Nov 17 nicklas 87 import net.sf.basedb.util.Values;
4642 28 Nov 17 nicklas 88 import net.sf.basedb.util.error.ThrowableUtil;
4642 28 Nov 17 nicklas 89
4642 28 Nov 17 nicklas 90
4642 28 Nov 17 nicklas 91 public class GenotypeServlet 
4642 28 Nov 17 nicklas 92   extends HttpServlet 
4642 28 Nov 17 nicklas 93 {
4642 28 Nov 17 nicklas 94   
4642 28 Nov 17 nicklas 95   private static final long serialVersionUID = -1420144327367753332L;
4642 28 Nov 17 nicklas 96
4642 28 Nov 17 nicklas 97   public GenotypeServlet()
4642 28 Nov 17 nicklas 98   {}
4642 28 Nov 17 nicklas 99
4642 28 Nov 17 nicklas 100   @Override
4642 28 Nov 17 nicklas 101   protected void doGet(HttpServletRequest req, HttpServletResponse resp)
4642 28 Nov 17 nicklas 102     throws ServletException, IOException 
4642 28 Nov 17 nicklas 103   {
4642 28 Nov 17 nicklas 104     String cmd = req.getParameter("cmd");
4642 28 Nov 17 nicklas 105     JsonUtil.setJsonResponseHeaders(resp);
4642 28 Nov 17 nicklas 106     
4642 28 Nov 17 nicklas 107     JSONObject json = new JSONObject();
4642 28 Nov 17 nicklas 108     json.put("status", "ok");
4642 28 Nov 17 nicklas 109     
4642 28 Nov 17 nicklas 110     final SessionControl sc = Reggie.getSessionControl(req);
4642 28 Nov 17 nicklas 111     DbControl dc = null;
4642 28 Nov 17 nicklas 112     try
4642 28 Nov 17 nicklas 113     {
4642 28 Nov 17 nicklas 114       if ("GetAlignedSequencesForGenotypeQc".equals(cmd))
4642 28 Nov 17 nicklas 115       {
4649 20 Dec 17 nicklas 116         /*
4671 07 Feb 18 nicklas 117         //FOR DEBUGGING
4649 20 Dec 17 nicklas 118         dc = sc.newDbControl();
4671 07 Feb 18 nicklas 119         resetQCStatus(dc);
4649 20 Dec 17 nicklas 120         dc.commit();
4649 20 Dec 17 nicklas 121         */
4649 20 Dec 17 nicklas 122         
6335 15 Jun 21 nicklas 123         dc = sc.newDbControl(":Genotype QC wizard");
4642 28 Nov 17 nicklas 124         
5547 07 Aug 19 nicklas 125         GenoTypeChecker checker = null;
5547 07 Aug 19 nicklas 126         List<AlignedSequences> list = null;
5547 07 Aug 19 nicklas 127         String items = Values.getStringOrNull(req.getParameter("items"));
5547 07 Aug 19 nicklas 128         if (items == null)
5547 07 Aug 19 nicklas 129         {
7217 30 May 23 nicklas 130           Pipeline pipeline = Pipeline.getByName(req.getParameter("pipeline"));
7217 30 May 23 nicklas 131           if (pipeline == null) pipeline = Pipeline.RNASEQ_HISAT_STRINGTIE;
7199 25 May 23 nicklas 132           checker = new GenoTypeChecker();
7217 30 May 23 nicklas 133           if (pipeline == Pipeline.DNA_TUMOR_WGS)
7217 30 May 23 nicklas 134           {
7217 30 May 23 nicklas 135             // We skip all RNAseq comparisons
7217 30 May 23 nicklas 136             checker.setTumorPreloadFilter(Restrictions.eq(Hql.property("id"), Expressions.integer(0)));
7217 30 May 23 nicklas 137           }
5547 07 Aug 19 nicklas 138           // Start pre-load thread
6588 18 Feb 22 nicklas 139           new Thread(new GenoTypePreloaderRunnable(sc, checker, true)).start();
7211 29 May 23 nicklas 140
7211 29 May 23 nicklas 141           // Unchecked alignements of the given pipeline
7211 29 May 23 nicklas 142           ItemQuery<DerivedBioAssay> query = checker.queryBuilder(dc)
7211 29 May 23 nicklas 143             .notChecked().subtype(Subtype.ALIGNED_SEQUENCES).pipeline(pipeline)
7211 29 May 23 nicklas 144             .query();
5547 07 Aug 19 nicklas 145           // Join LibPlate for sorting
7211 29 May 23 nicklas 146           if (pipeline == Pipeline.RNASEQ_HISAT_STRINGTIE)
7211 29 May 23 nicklas 147           {
7211 29 May 23 nicklas 148             query.join(Hql.innerJoin(null, "extract", "lib", true));
7211 29 May 23 nicklas 149             query.join(Hql.innerJoin("lib", "bioWell", "bw", true));
7211 29 May 23 nicklas 150             query.join(Hql.innerJoin("bw", "bioPlate", "libPlate", true));
7211 29 May 23 nicklas 151             query.order(Orders.asc(Hql.property("libPlate", "id")));
7211 29 May 23 nicklas 152           }
5547 07 Aug 19 nicklas 153           query.order(Orders.asc(Hql.property("name")));
7219 31 May 23 nicklas 154           // When checking DNA it is better to do them all at once
7219 31 May 23 nicklas 155           if (pipeline.isRnaPipeline()) query.setMaxResults(250);
5547 07 Aug 19 nicklas 156           
5547 07 Aug 19 nicklas 157           // DEBUG!!! 
5547 07 Aug 19 nicklas 158           // query.restrict(Restrictions.eq(Hql.property("libPlate", "name"), Expressions.string("LibPlate0029")));
5547 07 Aug 19 nicklas 159           
5547 07 Aug 19 nicklas 160           list = AlignedSequences.toList(query.list(dc));
5547 07 Aug 19 nicklas 161         }
5547 07 Aug 19 nicklas 162         else
5547 07 Aug 19 nicklas 163         {
5547 07 Aug 19 nicklas 164           Integer[] ids = Values.getInt(items.split(","));
5547 07 Aug 19 nicklas 165           list = new ArrayList<AlignedSequences>();
5547 07 Aug 19 nicklas 166           for (Integer id : ids)
5547 07 Aug 19 nicklas 167           {
5547 07 Aug 19 nicklas 168             list.add(AlignedSequences.getById(dc, id));
5547 07 Aug 19 nicklas 169           }
5547 07 Aug 19 nicklas 170         }
5547 07 Aug 19 nicklas 171
4642 28 Nov 17 nicklas 172         SnapshotManager manager = new SnapshotManager();
4642 28 Nov 17 nicklas 173         JSONArray jsonAlignedSequences = new JSONArray();
4642 28 Nov 17 nicklas 174         for (AlignedSequences as : list)
4642 28 Nov 17 nicklas 175         {
7211 29 May 23 nicklas 176           Pipeline pipeline = Pipeline.getByName((String)Annotationtype.PIPELINE.getAnnotationValue(dc, as.getItem()));
7211 29 May 23 nicklas 177           as.setAnnotation("pipeline", pipeline.getName());
4642 28 Nov 17 nicklas 178           Library lib = as.getLibrary(dc);
7211 29 May 23 nicklas 179           
7211 29 May 23 nicklas 180           if (pipeline == Pipeline.DNA_NORMAL_WGS)
5547 07 Aug 19 nicklas 181           {
7211 29 May 23 nicklas 182             // NOTE! By loading the BLOOD we will get the top-most BLOOD_DNA item
7211 29 May 23 nicklas 183             Map<Subtype, BioMaterial> parents = lib.findParentBioMaterial(dc, Subtype.BLOOD_DNA, Subtype.BLOOD);
7211 29 May 23 nicklas 184             BloodDna dna = BloodDna.get((Extract)parents.get(Subtype.BLOOD_DNA));
7211 29 May 23 nicklas 185             if (dna != null)
7211 29 May 23 nicklas 186             {
7211 29 May 23 nicklas 187               as.setAnnotation("bioWell", JsonUtil.getBioWellAsJSON(dna.getItem().getBioWell(), true));
7211 29 May 23 nicklas 188               as.setAnnotation("dna", dna.asJSONObject());
7211 29 May 23 nicklas 189             }
5547 07 Aug 19 nicklas 190           }
7211 29 May 23 nicklas 191           else
7211 29 May 23 nicklas 192           {
7211 29 May 23 nicklas 193             //lib.loadBioPlateLocation();
7211 29 May 23 nicklas 194             as.setAnnotation("bioWell", JsonUtil.getBioWellAsJSON(lib.getItem().getBioWell(), true));
7211 29 May 23 nicklas 195             Rna r = lib.getRna(dc, true);
7211 29 May 23 nicklas 196             if (r != null) 
7211 29 May 23 nicklas 197             {
7211 29 May 23 nicklas 198               lib.setAnnotation("specimen", r.loadYellowLabelInfo(dc, manager));
7211 29 May 23 nicklas 199             }
7211 29 May 23 nicklas 200           }
4642 28 Nov 17 nicklas 201           as.setAnnotation("lib", lib.asJSONObject());
7211 29 May 23 nicklas 202           BioMaterial patient = lib.findSingleParent(dc, Subtype.PATIENT);
4925 13 Aug 18 nicklas 203           if (patient != null)
4925 13 Aug 18 nicklas 204           {
4925 13 Aug 18 nicklas 205             as.setAnnotation("patient", patient.getId());
4925 13 Aug 18 nicklas 206           }
4925 13 Aug 18 nicklas 207           
4642 28 Nov 17 nicklas 208           jsonAlignedSequences.add(as.asJSONObject());
4642 28 Nov 17 nicklas 209         }
4642 28 Nov 17 nicklas 210         json.put("alignedSequences", jsonAlignedSequences);
4646 14 Dec 17 nicklas 211         
5547 07 Aug 19 nicklas 212         if (checker != null)
5547 07 Aug 19 nicklas 213         {
5547 07 Aug 19 nicklas 214           checker.awaitCounts(10);
5547 07 Aug 19 nicklas 215           sc.setSessionSetting("genotypechecker", checker);
5547 07 Aug 19 nicklas 216           json.put("existingVcfCount", checker.getTotalVcfsToPreload());
7202 25 May 23 nicklas 217           json.put("existingTumorsCount", checker.getNumTumorItemsToPreload());
7202 25 May 23 nicklas 218           json.put("existingNormalsCount", checker.getNumNormalItemsToPreload());
5547 07 Aug 19 nicklas 219         }
4642 28 Nov 17 nicklas 220       }
4794 07 May 18 nicklas 221       
6442 18 Oct 21 nicklas 222       else if ("PrepareForGenotypeChecks".equals(cmd))
6442 18 Oct 21 nicklas 223       {
6442 18 Oct 21 nicklas 224         dc = sc.newDbControl(":Genotype standalone check wizard");
6442 18 Oct 21 nicklas 225         
7199 25 May 23 nicklas 226         GenoTypeChecker checker = new GenoTypeChecker();
6444 19 Oct 21 nicklas 227         checker.loadReference(Reggie.class.getResourceAsStream("/net/sf/basedb/reggie/vcf/refs/genotyping-213-snp_feb2018.vcf"), "/net/sf/basedb/reggie/vcf/refs/genotyping-213-snp_feb2018.vcf");
6442 18 Oct 21 nicklas 228         // Start pre-load thread
6588 18 Feb 22 nicklas 229         new Thread(new GenoTypePreloaderRunnable(sc, checker, true)).start();
6442 18 Oct 21 nicklas 230         
6442 18 Oct 21 nicklas 231         checker.awaitCounts(10);
6442 18 Oct 21 nicklas 232         sc.setSessionSetting("genotypechecker", checker);
6442 18 Oct 21 nicklas 233         json.put("existingVcfCount", checker.getTotalVcfsToPreload());
7202 25 May 23 nicklas 234         json.put("existingTumorsCount", checker.getNumTumorItemsToPreload());
7202 25 May 23 nicklas 235         json.put("existingNormalsCount", checker.getNumNormalItemsToPreload());
6442 18 Oct 21 nicklas 236       }
6442 18 Oct 21 nicklas 237       
4794 07 May 18 nicklas 238       else if ("GetFlaggedAlignments".equals(cmd))
4794 07 May 18 nicklas 239       {
4970 13 Sep 18 nicklas 240         
6335 15 Jun 21 nicklas 241         dc = sc.newDbControl("Flagged alignments wizard");
7209 26 May 23 nicklas 242         loadFlaggedTumorsAndRelatedNormals(dc, json, req);
4794 07 May 18 nicklas 243       }
4642 28 Nov 17 nicklas 244
4642 28 Nov 17 nicklas 245       else if ("GetVcfStatistics".equals(cmd))
4642 28 Nov 17 nicklas 246       {
6450 21 Oct 21 nicklas 247         int fileId1 = Values.getInt(req.getParameter("fileId"));
4648 15 Dec 17 nicklas 248         int fileId2 = Values.getInt(req.getParameter("fileId2"));
6450 21 Oct 21 nicklas 249         int itemId1 = Values.getInt(req.getParameter("itemId"));
4648 15 Dec 17 nicklas 250         int itemId2 = Values.getInt(req.getParameter("itemId2"));
6335 15 Jun 21 nicklas 251         dc = sc.newDbControl("Genotype QC wizard");
4642 28 Nov 17 nicklas 252         
6450 21 Oct 21 nicklas 253         AlignedSequences aligned1 = itemId1 == 0 ? null : AlignedSequences.getById(dc, itemId1);
4648 15 Dec 17 nicklas 254         AlignedSequences aligned2 = itemId2 == 0 ? null : AlignedSequences.getById(dc, itemId2);
4648 15 Dec 17 nicklas 255
6450 21 Oct 21 nicklas 256         if (aligned1 != null) 
6450 21 Oct 21 nicklas 257         {
6450 21 Oct 21 nicklas 258           loadMoreGenoTypeInfo(dc, aligned1);
6450 21 Oct 21 nicklas 259           json.put("alignment1", aligned1.asJSONObject());
6450 21 Oct 21 nicklas 260         }
6450 21 Oct 21 nicklas 261         if (aligned2 != null) 
6450 21 Oct 21 nicklas 262         {
6450 21 Oct 21 nicklas 263           loadMoreGenoTypeInfo(dc, aligned2);
6450 21 Oct 21 nicklas 264           json.put("alignment2", aligned2.asJSONObject());
6450 21 Oct 21 nicklas 265         }
4648 15 Dec 17 nicklas 266         
6450 21 Oct 21 nicklas 267         File vcf1 = fileId1 == 0 ? null : File.getById(dc, fileId1);
4648 15 Dec 17 nicklas 268         File vcf2 = fileId2 == 0 ? null : File.getById(dc, fileId2);
4648 15 Dec 17 nicklas 269         
4642 28 Nov 17 nicklas 270         InputStream vcfIn = null;
4642 28 Nov 17 nicklas 271         try
4642 28 Nov 17 nicklas 272         {
4642 28 Nov 17 nicklas 273           VcfParser parser = new VcfParser();
6450 21 Oct 21 nicklas 274           parser.parseRef(Reggie.class.getResourceAsStream("/net/sf/basedb/reggie/vcf/refs/genotyping-213-snp_feb2018.vcf"), "/net/sf/basedb/reggie/vcf/refs/genotyping-213-snp_feb2018.vcf");
4642 28 Nov 17 nicklas 275           
6450 21 Oct 21 nicklas 276           VcfData vcfData1 = null;
6450 21 Oct 21 nicklas 277           if (vcf1 != null)
6450 21 Oct 21 nicklas 278           {
6450 21 Oct 21 nicklas 279             vcfIn = vcf1.getDownloadStream(0);
6450 21 Oct 21 nicklas 280             vcfData1 = parser.parse(vcfIn, vcf1.getName());
6450 21 Oct 21 nicklas 281             FileUtil.close(vcfIn);
6450 21 Oct 21 nicklas 282             json.put("vcfData1", vcfData1.asJSONObject());
6450 21 Oct 21 nicklas 283           }
6450 21 Oct 21 nicklas 284           
4648 15 Dec 17 nicklas 285           VcfData vcfData2 = null;
4648 15 Dec 17 nicklas 286           if (vcf2 != null)
4648 15 Dec 17 nicklas 287           {
4648 15 Dec 17 nicklas 288             vcfIn = vcf2.getDownloadStream(0);
6450 21 Oct 21 nicklas 289             vcfData2 = parser.parse(vcfIn, vcf2.getName());
4648 15 Dec 17 nicklas 290             FileUtil.close(vcfIn);
6450 21 Oct 21 nicklas 291             json.put("vcfData2", vcfData2.asJSONObject());
6450 21 Oct 21 nicklas 292           }
6450 21 Oct 21 nicklas 293           
6450 21 Oct 21 nicklas 294           if (vcfData1 != null && vcfData2 != null)
6450 21 Oct 21 nicklas 295           {
6450 21 Oct 21 nicklas 296             VcfPair pair = new VcfPair(vcfData1, vcfData2);
4671 07 Feb 18 nicklas 297             json.put("compareData", pair.asJSONObject());
4648 15 Dec 17 nicklas 298           }
4648 15 Dec 17 nicklas 299           
4642 28 Nov 17 nicklas 300           List<SnpData> snpList = parser.getSnpData();
4642 28 Nov 17 nicklas 301           JSONArray jsonSnp = new JSONArray();
4642 28 Nov 17 nicklas 302           for (SnpData snp : snpList)
4642 28 Nov 17 nicklas 303           {
4648 15 Dec 17 nicklas 304             JSONObject jsonGt = new JSONObject();
4648 15 Dec 17 nicklas 305             jsonGt.put("snp", snp.asJSONObject());
4648 15 Dec 17 nicklas 306             
6450 21 Oct 21 nicklas 307             if (vcfData1 != null)
6450 21 Oct 21 nicklas 308             {
6450 21 Oct 21 nicklas 309               GtData gt1 = vcfData1.getGtData(snp.getId());
6513 07 Dec 21 nicklas 310               if (gt1 != null) jsonGt.put("gt1", gt1.asJSONObject(vcfData1.getQualityModel()));
6450 21 Oct 21 nicklas 311             }
4648 15 Dec 17 nicklas 312
4648 15 Dec 17 nicklas 313             if (vcfData2 != null)
4642 28 Nov 17 nicklas 314             {
6450 21 Oct 21 nicklas 315               GtData gt2 = vcfData2.getGtData(snp.getId());
6513 07 Dec 21 nicklas 316               if (gt2 != null) jsonGt.put("gt2", gt2.asJSONObject(vcfData2.getQualityModel()));
4642 28 Nov 17 nicklas 317             }
4642 28 Nov 17 nicklas 318             jsonSnp.add(jsonGt);
4642 28 Nov 17 nicklas 319           }
4648 15 Dec 17 nicklas 320           
4642 28 Nov 17 nicklas 321           json.put("snpData", jsonSnp);
4642 28 Nov 17 nicklas 322         }
4642 28 Nov 17 nicklas 323         finally
4642 28 Nov 17 nicklas 324         {
4642 28 Nov 17 nicklas 325           FileUtil.close(vcfIn);
4642 28 Nov 17 nicklas 326         }
4642 28 Nov 17 nicklas 327       }
4642 28 Nov 17 nicklas 328     }
4642 28 Nov 17 nicklas 329     catch (Throwable t)
4642 28 Nov 17 nicklas 330     {
4642 28 Nov 17 nicklas 331       t.printStackTrace();
4642 28 Nov 17 nicklas 332       json.clear();
4642 28 Nov 17 nicklas 333       json.put("status", "error");
4642 28 Nov 17 nicklas 334       json.put("message", t.getMessage());
4642 28 Nov 17 nicklas 335       json.put("stacktrace", ThrowableUtil.stackTraceToString(t));
4642 28 Nov 17 nicklas 336     }
4642 28 Nov 17 nicklas 337     finally
4642 28 Nov 17 nicklas 338     {
4642 28 Nov 17 nicklas 339       if (dc != null) dc.close();
4642 28 Nov 17 nicklas 340       json.writeJSONString(resp.getWriter());
4642 28 Nov 17 nicklas 341     }
4642 28 Nov 17 nicklas 342     
4642 28 Nov 17 nicklas 343   }
4642 28 Nov 17 nicklas 344
4642 28 Nov 17 nicklas 345   @SuppressWarnings("unchecked")
4642 28 Nov 17 nicklas 346   @Override
4642 28 Nov 17 nicklas 347   protected void doPost(HttpServletRequest req, HttpServletResponse resp)
4642 28 Nov 17 nicklas 348     throws ServletException, IOException 
4642 28 Nov 17 nicklas 349   {
4642 28 Nov 17 nicklas 350     String cmd = req.getParameter("cmd");
4642 28 Nov 17 nicklas 351     JsonUtil.setJsonResponseHeaders(resp);
4642 28 Nov 17 nicklas 352     
4642 28 Nov 17 nicklas 353     JSONObject json = new JSONObject();
4642 28 Nov 17 nicklas 354     json.put("status", "ok");
4642 28 Nov 17 nicklas 355     JSONArray jsonMessages = new JSONArray();
4642 28 Nov 17 nicklas 356   
4642 28 Nov 17 nicklas 357     final SessionControl sc = Reggie.getSessionControl(req);
4642 28 Nov 17 nicklas 358     DbControl dc = null;
4642 28 Nov 17 nicklas 359     try
4642 28 Nov 17 nicklas 360     {
4642 28 Nov 17 nicklas 361
4646 14 Dec 17 nicklas 362       if ("GenotypeQcCheck".equals(cmd))
4642 28 Nov 17 nicklas 363       {
6335 15 Jun 21 nicklas 364         dc = sc.newDbControl(":Genotype QC wizard");
4642 28 Nov 17 nicklas 365
4642 28 Nov 17 nicklas 366         ReggieRole.checkPermission(dc, "'" + cmd + "' wizard", ReggieRole.SECONDARY_ANALYSIS, ReggieRole.ADMINISTRATOR);
4642 28 Nov 17 nicklas 367
4646 14 Dec 17 nicklas 368         JSONObject jsonReq = JsonUtil.parseRequest(req);
4646 14 Dec 17 nicklas 369         JSONArray jsonAligned = (JSONArray)jsonReq.get("alignedSequences");
4646 14 Dec 17 nicklas 370         
4646 14 Dec 17 nicklas 371         GenoTypeChecker checker = (GenoTypeChecker)sc.getSessionSetting("genotypechecker");
4646 14 Dec 17 nicklas 372         
4646 14 Dec 17 nicklas 373         SimpleProgressReporter progress = new SimpleProgressReporter(null);
4646 14 Dec 17 nicklas 374         sc.setSessionSetting("genotypes-progress", progress);
4646 14 Dec 17 nicklas 375         progress.display(1, "Waiting for VCF pre-loading...");
4646 14 Dec 17 nicklas 376         
4646 14 Dec 17 nicklas 377         int progressOffset = 5;
4646 14 Dec 17 nicklas 378         
4925 13 Aug 18 nicklas 379         // Check if the selected alignments have patient information
4925 13 Aug 18 nicklas 380         int totalCount = jsonAligned.size();
4925 13 Aug 18 nicklas 381         for (int aNo = 0; aNo < totalCount; aNo++)
4925 13 Aug 18 nicklas 382         {
4925 13 Aug 18 nicklas 383           JSONObject jsonAl = (JSONObject)jsonAligned.get(aNo);
4925 13 Aug 18 nicklas 384           Number alignedId = (Number)jsonAl.get("id");
4925 13 Aug 18 nicklas 385           DerivedBioAssay alignment = DerivedBioAssay.getById(dc, alignedId.intValue());
4925 13 Aug 18 nicklas 386           if (checker.getSpecimenData(alignment) == null)
4925 13 Aug 18 nicklas 387           {
4925 13 Aug 18 nicklas 388             throw new RuntimeException("Alignment '" + alignment.getName() + "' has not patient information.");
4925 13 Aug 18 nicklas 389           }
4925 13 Aug 18 nicklas 390         }
4925 13 Aug 18 nicklas 391         
4646 14 Dec 17 nicklas 392         int totalVcf = checker.getTotalVcfsToPreload();
7212 29 May 23 nicklas 393         int numThreads = checker.getPreloadThreads();
4646 14 Dec 17 nicklas 394         while (!checker.preloadCompleted())
4646 14 Dec 17 nicklas 395         {
4646 14 Dec 17 nicklas 396           int loaded = checker.getCurrentVcfPreloadCount();
7212 29 May 23 nicklas 397           progress.display(50*loaded/totalVcf, "Loading existing VCF files ("+ loaded + "/"+totalVcf+"; using " + numThreads+" threads)");
4646 14 Dec 17 nicklas 398           Thread.sleep(500);
6591 21 Feb 22 nicklas 399           checker.throwIfPreloadError();
4646 14 Dec 17 nicklas 400           progressOffset = 50;
4646 14 Dec 17 nicklas 401         }
4646 14 Dec 17 nicklas 402         
4671 07 Feb 18 nicklas 403         // Preload the selected VCF files
7212 29 May 23 nicklas 404         Queue<Integer> toCompare = new ConcurrentLinkedQueue<>();
4646 14 Dec 17 nicklas 405         for (int aNo = 0; aNo < totalCount; aNo++)
4646 14 Dec 17 nicklas 406         {
4646 14 Dec 17 nicklas 407           JSONObject jsonAl = (JSONObject)jsonAligned.get(aNo);
4646 14 Dec 17 nicklas 408           Number alignedId = (Number)jsonAl.get("id");
7211 29 May 23 nicklas 409           checker.preloadItem(dc, DerivedBioAssay.getById(dc, alignedId.intValue()));
7212 29 May 23 nicklas 410           toCompare.add(alignedId.intValue());
4671 07 Feb 18 nicklas 411         }
4646 14 Dec 17 nicklas 412         
7212 29 May 23 nicklas 413         // Use multiple threads for comparison -- but not too many
7212 29 May 23 nicklas 414         numThreads = Math.min(numThreads, (int)Math.sqrt(totalCount));
7212 29 May 23 nicklas 415         ExecutorService threadPool = Executors.newFixedThreadPool(numThreads, new ReggieThreadFactory("VcfCompareThread"));
7212 29 May 23 nicklas 416         ExecutorCompletionService<List<JSONObject>> executor = new ExecutorCompletionService<>(threadPool);
7212 29 May 23 nicklas 417         for (int i = 0; i < numThreads; i++)
4671 07 Feb 18 nicklas 418         {
7212 29 May 23 nicklas 419           executor.submit(new RunnableGenotypeComparator(sc, checker, toCompare));
7212 29 May 23 nicklas 420         }
4671 07 Feb 18 nicklas 421         
7212 29 May 23 nicklas 422         // Wait for all comparisons to complete
7212 29 May 23 nicklas 423         while (toCompare.size() > 0)
7212 29 May 23 nicklas 424         {
7212 29 May 23 nicklas 425           int done = totalCount-toCompare.size();
7212 29 May 23 nicklas 426           progress.display(progressOffset+(100-progressOffset)*done/totalCount, 
7212 29 May 23 nicklas 427               "Comparing VCF files ("+done+"/"+totalCount+"; using " + numThreads+" threads)");
7212 29 May 23 nicklas 428           Thread.sleep(500);
4646 14 Dec 17 nicklas 429         }
4646 14 Dec 17 nicklas 430         
7212 29 May 23 nicklas 431         // Get the results
7212 29 May 23 nicklas 432         JSONArray jsonAlignedSequences = new JSONArray();
7212 29 May 23 nicklas 433         for (int i = 0; i < numThreads; i++)
7212 29 May 23 nicklas 434         {
7212 29 May 23 nicklas 435           Future<List<JSONObject>> result = executor.take();
7212 29 May 23 nicklas 436           jsonAlignedSequences.addAll(result.get());
7212 29 May 23 nicklas 437         }
4646 14 Dec 17 nicklas 438         progress.display(100, "Done");
4646 14 Dec 17 nicklas 439         
4648 15 Dec 17 nicklas 440         json.put("alignedSequences", jsonAlignedSequences);
4642 28 Nov 17 nicklas 441       }
6442 18 Oct 21 nicklas 442       else if ("GenotypeStandaloneFileCheck".equals(cmd))
6442 18 Oct 21 nicklas 443       {
6442 18 Oct 21 nicklas 444         dc = sc.newDbControl(":Genotype standalone check wizard");
6442 18 Oct 21 nicklas 445
6442 18 Oct 21 nicklas 446         ReggieRole.checkPermission(dc, "'" + cmd + "' wizard", ReggieRole.SECONDARY_ANALYSIS, ReggieRole.ADMINISTRATOR);
6442 18 Oct 21 nicklas 447
6442 18 Oct 21 nicklas 448         JSONObject jsonReq = JsonUtil.parseRequest(req);
6442 18 Oct 21 nicklas 449         JSONArray jsonFiles = (JSONArray)jsonReq.get("files");
6442 18 Oct 21 nicklas 450         
6442 18 Oct 21 nicklas 451         GenoTypeChecker checker = (GenoTypeChecker)sc.getSessionSetting("genotypechecker");
6442 18 Oct 21 nicklas 452         
6442 18 Oct 21 nicklas 453         SimpleProgressReporter progress = new SimpleProgressReporter(null);
6442 18 Oct 21 nicklas 454         sc.setSessionSetting("genotypes-progress", progress);
6442 18 Oct 21 nicklas 455         progress.display(1, "Waiting for VCF pre-loading...");
6442 18 Oct 21 nicklas 456         
6442 18 Oct 21 nicklas 457         int progressOffset = 5;
6442 18 Oct 21 nicklas 458         
6442 18 Oct 21 nicklas 459         int totalVcf = checker.getTotalVcfsToPreload();
6442 18 Oct 21 nicklas 460         while (!checker.preloadCompleted())
6442 18 Oct 21 nicklas 461         {
6442 18 Oct 21 nicklas 462           int loaded = checker.getCurrentVcfPreloadCount();
6442 18 Oct 21 nicklas 463           progress.display(50*loaded/totalVcf, "Loading existing VCF files ("+ loaded + "/"+totalVcf+")");
6442 18 Oct 21 nicklas 464           Thread.sleep(500);
6591 21 Feb 22 nicklas 465           checker.throwIfPreloadError();
6591 21 Feb 22 nicklas 466           progressOffset = 50;
6442 18 Oct 21 nicklas 467         }
6442 18 Oct 21 nicklas 468               
6442 18 Oct 21 nicklas 469         // Make the comparisons
6442 18 Oct 21 nicklas 470         int totalCount = jsonFiles.size();
6442 18 Oct 21 nicklas 471         for (int fNo = 0; fNo < totalCount; fNo++)
6442 18 Oct 21 nicklas 472         {
6442 18 Oct 21 nicklas 473           JSONObject jsonFile = (JSONObject)jsonFiles.get(fNo);
6442 18 Oct 21 nicklas 474           Number fileId = (Number)jsonFile.get("id");
6442 18 Oct 21 nicklas 475           File vcfFile = File.getById(dc, fileId.intValue());
6443 19 Oct 21 nicklas 476           CompareData cmp = checker.check(dc, vcfFile);
6588 18 Feb 22 nicklas 477           cmp.sortMessages(GenoTypeMessage.SORT_BY_CATEGORY_AND_ASSAY);
6442 18 Oct 21 nicklas 478           jsonFile.put("name", vcfFile.getName());
6595 22 Feb 22 nicklas 479           jsonFile.put("path", vcfFile.getPath().toString());
6443 19 Oct 21 nicklas 480           jsonFile.put("compare", cmp.asJSONObject());
6442 18 Oct 21 nicklas 481           progress.display(progressOffset+(100-progressOffset)*fNo/totalCount, "Comparing " + (fNo+1) + " of " + totalCount);
6442 18 Oct 21 nicklas 482           //Thread.sleep(100);
6442 18 Oct 21 nicklas 483         }
6442 18 Oct 21 nicklas 484         
6442 18 Oct 21 nicklas 485         progress.display(100, "Done");
6442 18 Oct 21 nicklas 486         json.put("files", jsonFiles);
6442 18 Oct 21 nicklas 487       }
4646 14 Dec 17 nicklas 488       else if ("RegisterQcCheck".equals(cmd))
4646 14 Dec 17 nicklas 489       {
6335 15 Jun 21 nicklas 490         dc = sc.newDbControl(":Genotype QC");
4646 14 Dec 17 nicklas 491
4646 14 Dec 17 nicklas 492         ReggieRole.checkPermission(dc, "'" + cmd + "' wizard", ReggieRole.SECONDARY_ANALYSIS, ReggieRole.ADMINISTRATOR);
4646 14 Dec 17 nicklas 493
4646 14 Dec 17 nicklas 494         JSONObject jsonReq = JsonUtil.parseRequest(req);
4646 14 Dec 17 nicklas 495         JSONArray jsonAligned = (JSONArray)jsonReq.get("alignedSequences");
7215 30 May 23 nicklas 496         Pipeline pipeline = Pipeline.getByName(req.getParameter("pipeline"));
7215 30 May 23 nicklas 497         if (pipeline == null) pipeline = Pipeline.RNASEQ_HISAT_STRINGTIE;
4646 14 Dec 17 nicklas 498         
4646 14 Dec 17 nicklas 499         int numChecked = 0;
4649 20 Dec 17 nicklas 500         int numFlagged = 0;
4728 04 Apr 18 nicklas 501         int numVerified = 0;
7215 30 May 23 nicklas 502         int numVerifiedByDNA = 0;
4649 20 Dec 17 nicklas 503         ItemList flagged = BiomaterialList.FLAGGED_ALIGNMENT.get(dc);
4646 14 Dec 17 nicklas 504         
4646 14 Dec 17 nicklas 505         for (int aNo = 0; aNo < jsonAligned.size(); aNo++)
4646 14 Dec 17 nicklas 506         {
4646 14 Dec 17 nicklas 507           JSONObject jsonAl = (JSONObject)jsonAligned.get(aNo);
4728 04 Apr 18 nicklas 508           Number alignedId = (Number)jsonAl.get("id");
4649 20 Dec 17 nicklas 509           JSONArray jsonFlag = (JSONArray)jsonAl.get("flag");
4728 04 Apr 18 nicklas 510           JSONArray jsonVerified = (JSONArray)jsonAl.get("verified");
4646 14 Dec 17 nicklas 511         
4646 14 Dec 17 nicklas 512           DerivedBioAssay aligned = DerivedBioAssay.getById(dc, alignedId.intValue());
4646 14 Dec 17 nicklas 513           boolean disable = Boolean.TRUE.equals(jsonAl.get("disable"));
7211 29 May 23 nicklas 514           boolean verifySelf = !Boolean.FALSE.equals(jsonAl.get("verifySelf"));
7216 30 May 23 nicklas 515           String doNotUse = (String)jsonAl.get("doNotUse");
7215 30 May 23 nicklas 516           boolean flag = jsonFlag != null && jsonFlag.size() > 0;
4646 14 Dec 17 nicklas 517           String comment = Values.getStringOrNull((String)jsonAl.get("comment"));
7216 30 May 23 nicklas 518           String doNotUseComment = Values.getString(comment, (String)jsonAl.get("doNotUseComment"));
4646 14 Dec 17 nicklas 519           
4646 14 Dec 17 nicklas 520           Annotationtype.QC_GENOTYPE_STATUS.setAnnotationValue(dc, aligned, disable ? "Disabled" : "Checked");
4648 15 Dec 17 nicklas 521           Annotationtype.QC_GENOTYPE_COMMENT.setAnnotationValue(dc, aligned, comment);
7216 30 May 23 nicklas 522           if (doNotUse != null) 
7216 30 May 23 nicklas 523           {
7216 30 May 23 nicklas 524             Annotationtype.DO_NOT_USE.setAnnotationValue(dc, aligned, doNotUse);
7216 30 May 23 nicklas 525             Annotationtype.DO_NOT_USE_COMMENT.setAnnotationValue(dc, aligned, doNotUseComment);
7216 30 May 23 nicklas 526             if (doNotUse.equals("Library"))
7216 30 May 23 nicklas 527             {
7216 30 May 23 nicklas 528               // Go up to library item and mark everything downstreams as well
7216 30 May 23 nicklas 529               Extract lib = aligned.getExtract();
7216 30 May 23 nicklas 530               List<AnnotatedItem> allChildItems = getAllChildItems(dc, lib);
7216 30 May 23 nicklas 531               for (AnnotatedItem item : allChildItems)
7216 30 May 23 nicklas 532               {
7216 30 May 23 nicklas 533                 Annotationtype.DO_NOT_USE.setAnnotationValue(dc, item, doNotUse);
7216 30 May 23 nicklas 534                 Annotationtype.DO_NOT_USE_COMMENT.setAnnotationValue(dc, item, doNotUseComment);
7216 30 May 23 nicklas 535               }
7216 30 May 23 nicklas 536             }
7216 30 May 23 nicklas 537           }
4649 20 Dec 17 nicklas 538           if (flag)
4649 20 Dec 17 nicklas 539           {
4728 04 Apr 18 nicklas 540             List<String> names = new ArrayList<>();
4649 20 Dec 17 nicklas 541             for (int fNo = 0; fNo < jsonFlag.size(); fNo++)
4649 20 Dec 17 nicklas 542             {
4649 20 Dec 17 nicklas 543               Number flagId = (Number)jsonFlag.get(fNo);
4649 20 Dec 17 nicklas 544               DerivedBioAssay toFlag = DerivedBioAssay.getById(dc, flagId.intValue());
4728 04 Apr 18 nicklas 545               if (flagged.add(toFlag)) 
4649 20 Dec 17 nicklas 546               {
4728 04 Apr 18 nicklas 547                 names.add(toFlag.getName());
4728 04 Apr 18 nicklas 548                 numFlagged++;
4649 20 Dec 17 nicklas 549               }
4649 20 Dec 17 nicklas 550             }
4728 04 Apr 18 nicklas 551             if (names.size() > 0)
4728 04 Apr 18 nicklas 552             {
4728 04 Apr 18 nicklas 553               StringBuilder allNames = new StringBuilder();
4728 04 Apr 18 nicklas 554               int last = names.size() - 1;
4728 04 Apr 18 nicklas 555               for (int i = 0; i < names.size(); i++)
4728 04 Apr 18 nicklas 556               {
4728 04 Apr 18 nicklas 557                 if (i > 0) allNames.append(i == last ? " and " : ", ");
4728 04 Apr 18 nicklas 558                 allNames.append(names.get(i));
4728 04 Apr 18 nicklas 559               }
4728 04 Apr 18 nicklas 560               jsonMessages.add(allNames + " has been flagged for extended genotype checks");
4728 04 Apr 18 nicklas 561             }
4649 20 Dec 17 nicklas 562           }
4649 20 Dec 17 nicklas 563           
4728 04 Apr 18 nicklas 564           if (jsonVerified != null && jsonVerified.size() > 0)
4728 04 Apr 18 nicklas 565           {
4728 04 Apr 18 nicklas 566             VerifiedMatch best = VerifiedMatch.getVerifiedMatch(dc, aligned);
4728 04 Apr 18 nicklas 567             for (int vNo = 0; vNo < jsonVerified.size(); vNo++)
4728 04 Apr 18 nicklas 568             {
4728 04 Apr 18 nicklas 569               JSONObject jsonV = (JSONObject)jsonVerified.get(vNo);
4728 04 Apr 18 nicklas 570               Number verifiedId = (Number)jsonV.get("id");
4728 04 Apr 18 nicklas 571               VerifiedMatch vm = VerifiedMatch.valueOf((String)jsonV.get("verifiedBy"));
4728 04 Apr 18 nicklas 572               best = VerifiedMatch.getBest(best, vm);
4728 04 Apr 18 nicklas 573               
4728 04 Apr 18 nicklas 574               // Update the other alignment if the 'vm' is better than what is already set
7201 25 May 23 nicklas 575               if ("TUMOR".equals(jsonV.get("assayType")))
4728 04 Apr 18 nicklas 576               {
7200 25 May 23 nicklas 577                 DerivedBioAssay other = DerivedBioAssay.getById(dc, verifiedId.intValue());
7200 25 May 23 nicklas 578                 if (vm.updateIfBetter(dc, other))
7200 25 May 23 nicklas 579                 {
7200 25 May 23 nicklas 580                   numVerified++;
7215 30 May 23 nicklas 581                   if (vm == VerifiedMatch.DNA) numVerifiedByDNA++;
7218 30 May 23 nicklas 582                   if (pipeline.isRnaPipeline())
7215 30 May 23 nicklas 583                   {
7215 30 May 23 nicklas 584                     jsonMessages.add(other.getName() + " is verified by "+ vm.name());
7215 30 May 23 nicklas 585                   }
7200 25 May 23 nicklas 586                 }
4728 04 Apr 18 nicklas 587               }
4728 04 Apr 18 nicklas 588             }
7211 29 May 23 nicklas 589             if (verifySelf && best.updateIfBetter(dc, aligned))
4728 04 Apr 18 nicklas 590             {
4728 04 Apr 18 nicklas 591               numVerified++;
7215 30 May 23 nicklas 592               if (best == VerifiedMatch.DNA) numVerifiedByDNA++;
7218 30 May 23 nicklas 593               if (pipeline.isRnaPipeline())
7218 30 May 23 nicklas 594               {
7218 30 May 23 nicklas 595                 jsonMessages.add(aligned.getName() + " is verified by "+ best.name());
7218 30 May 23 nicklas 596               }
4728 04 Apr 18 nicklas 597             }
4728 04 Apr 18 nicklas 598           }
4728 04 Apr 18 nicklas 599           
4646 14 Dec 17 nicklas 600           if (disable)
4646 14 Dec 17 nicklas 601           {
4646 14 Dec 17 nicklas 602             jsonMessages.add(aligned.getName() + " has been disabled for future genotype QC comparisons.");
4646 14 Dec 17 nicklas 603           }
4646 14 Dec 17 nicklas 604           else
4646 14 Dec 17 nicklas 605           {
4646 14 Dec 17 nicklas 606             numChecked++;
4646 14 Dec 17 nicklas 607           }
4646 14 Dec 17 nicklas 608         }
7218 30 May 23 nicklas 609         if (numVerifiedByDNA > 0 && pipeline.isDnaPipeline())
7215 30 May 23 nicklas 610         {
7215 30 May 23 nicklas 611           jsonMessages.add(0, countMessage(numVerifiedByDNA, "alignment has", "alignments have")+" been verified by DNA");
7215 30 May 23 nicklas 612         }
4646 14 Dec 17 nicklas 613         if (numChecked > 0)
4646 14 Dec 17 nicklas 614         {
4977 24 Sep 18 nicklas 615           jsonMessages.add(0, countMessage(numChecked, "alignment has", "alignments have") + " been checked and will be used for future genotype QC comparisons.");
4646 14 Dec 17 nicklas 616         }
5421 13 May 19 nicklas 617         ActivityDef.GENOTYPE_QC.merge(dc, jsonAligned.size());
5412 09 May 19 nicklas 618         dc.commit();
4646 14 Dec 17 nicklas 619       }
4817 21 May 18 nicklas 620       else if ("ReprocessItems".equals(cmd))
4817 21 May 18 nicklas 621       {
6335 15 Jun 21 nicklas 622         dc = sc.newDbControl(":Flagged alignment wizard");
4817 21 May 18 nicklas 623
4817 21 May 18 nicklas 624         ReggieRole.checkPermission(dc, "'" + cmd + "' wizard", ReggieRole.PREP_CURATOR, ReggieRole.ADMINISTRATOR);
4817 21 May 18 nicklas 625
4817 21 May 18 nicklas 626         JSONObject jsonReq = JsonUtil.parseRequest(req);
4817 21 May 18 nicklas 627         JSONArray jsonItems = (JSONArray)jsonReq.get("items");
4817 21 May 18 nicklas 628         
4970 13 Sep 18 nicklas 629         ItemList flagged = BiomaterialList.FLAGGED_ALIGNMENT.get(dc);
4970 13 Sep 18 nicklas 630         
4970 13 Sep 18 nicklas 631         int numReProcess = 0;
4970 13 Sep 18 nicklas 632         int numFlagged = 0;
4970 13 Sep 18 nicklas 633         int numComments = 0;
4817 21 May 18 nicklas 634         for (int itemNo = 0; itemNo < jsonItems.size(); itemNo++)
4817 21 May 18 nicklas 635         {
4817 21 May 18 nicklas 636           JSONObject jsonItem = (JSONObject)jsonItems.get(itemNo);
4970 13 Sep 18 nicklas 637           Number alignmentId = (Number)jsonItem.get("id");
4817 21 May 18 nicklas 638           
4970 13 Sep 18 nicklas 639           JSONObject jsonReProcess = (JSONObject)jsonItem.get("reprocess");
4970 13 Sep 18 nicklas 640           if (jsonReProcess != null)
4970 13 Sep 18 nicklas 641           {
4970 13 Sep 18 nicklas 642             Item itemType = Item.valueOf((String)jsonReProcess.get("type"));
4970 13 Sep 18 nicklas 643             Number itemId = (Number)jsonReProcess.get("id");
4970 13 Sep 18 nicklas 644             BioMaterial item = (BioMaterial)itemType.getById(dc, itemId.intValue());
4970 13 Sep 18 nicklas 645             boolean changed = Annotationtype.AUTO_PROCESSING.setAnnotationValue(dc, item, "ReProcess");
4970 13 Sep 18 nicklas 646             if (changed) numReProcess++;
4970 13 Sep 18 nicklas 647           }
4817 21 May 18 nicklas 648           
4970 13 Sep 18 nicklas 649           DerivedBioAssay alignment = alignmentId != null ? DerivedBioAssay.getById(dc, alignmentId.intValue()) : null;
4970 13 Sep 18 nicklas 650           if (alignment != null)
4970 13 Sep 18 nicklas 651           {
4970 13 Sep 18 nicklas 652             if (Boolean.TRUE.equals(jsonItem.get("flag")))
4970 13 Sep 18 nicklas 653             {
4970 13 Sep 18 nicklas 654               if (flagged.add(alignment)) numFlagged++;
4970 13 Sep 18 nicklas 655             }
4970 13 Sep 18 nicklas 656             if (jsonItem.containsKey("comment"))
4970 13 Sep 18 nicklas 657             {
4970 13 Sep 18 nicklas 658               String comment = (String)jsonItem.get("comment");
4970 13 Sep 18 nicklas 659               boolean changed = Annotationtype.QC_GENOTYPE_COMMENT.setAnnotationValue(dc, alignment, comment);
4970 13 Sep 18 nicklas 660               if (changed) numComments++;
4970 13 Sep 18 nicklas 661             }
4970 13 Sep 18 nicklas 662             
4970 13 Sep 18 nicklas 663           }
4817 21 May 18 nicklas 664         }
4977 24 Sep 18 nicklas 665         if (numReProcess > 0) jsonMessages.add(countMessage(numReProcess, "item has", "items have") + " been scheduled for re-processing");
4977 24 Sep 18 nicklas 666         if (numFlagged > 0) jsonMessages.add(countMessage(numFlagged, "alignment has", "alignments have") + " been flagged");
4977 24 Sep 18 nicklas 667         if (numComments > 0) jsonMessages.add(countMessage(numComments, "comment has", "comments have") + " been updated");
4817 21 May 18 nicklas 668         dc.commit();
4970 13 Sep 18 nicklas 669         
4970 13 Sep 18 nicklas 670         // Reload flagged alignments so that the browser can update the table 
6335 15 Jun 21 nicklas 671         dc = sc.newDbControl(dc.getName());
7209 26 May 23 nicklas 672         loadFlaggedTumorsAndRelatedNormals(dc, json, req);
4970 13 Sep 18 nicklas 673         dc.commit();
4817 21 May 18 nicklas 674       }
4975 21 Sep 18 nicklas 675       else if ("ResolveProblems".equals(cmd))
4975 21 Sep 18 nicklas 676       {
6335 15 Jun 21 nicklas 677         dc = sc.newDbControl(":Flagged alignment wizard");
4975 21 Sep 18 nicklas 678
4975 21 Sep 18 nicklas 679         ReggieRole.checkPermission(dc, "'" + cmd + "' wizard", ReggieRole.PREP_CURATOR, ReggieRole.ADMINISTRATOR);
4975 21 Sep 18 nicklas 680
4975 21 Sep 18 nicklas 681         JSONObject jsonReq = JsonUtil.parseRequest(req);
4975 21 Sep 18 nicklas 682         JSONArray jsonItems = (JSONArray)jsonReq.get("items");
5319 28 Feb 19 nicklas 683         Set<Number> jsonPaired = new HashSet<Number>((List<Number>)jsonReq.get("paired"));
4975 21 Sep 18 nicklas 684         
4975 21 Sep 18 nicklas 685         ItemSubtype mergedType = Subtype.MERGED_SEQUENCES.get(dc);
4975 21 Sep 18 nicklas 686         ItemSubtype alignedType = Subtype.ALIGNED_SEQUENCES.get(dc);
4977 24 Sep 18 nicklas 687         ItemSubtype specimenType = Subtype.SPECIMEN.get(dc);
4977 24 Sep 18 nicklas 688         ItemSubtype lysateType = Subtype.LYSATE.get(dc);
4977 24 Sep 18 nicklas 689         ItemSubtype rnaType = Subtype.RNA.get(dc);
4982 26 Sep 18 nicklas 690         ItemSubtype preNormalizedType = Subtype.RNA_NORMALIZED_ALIQUOT.get(dc);
4977 24 Sep 18 nicklas 691         ItemSubtype libraryType = Subtype.LIBRARY.get(dc);
4975 21 Sep 18 nicklas 692         ItemList flaggedAlignments = BiomaterialList.FLAGGED_ALIGNMENT.get(dc);
4975 21 Sep 18 nicklas 693         
4979 24 Sep 18 nicklas 694         ItemQuery<Extract> dnaFtQuery = Extract.getQuery();
4979 24 Sep 18 nicklas 695         dnaFtQuery.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
4979 24 Sep 18 nicklas 696         // We find ALL child items to a specific Lysate with the same Qiacube date and run number
4979 24 Sep 18 nicklas 697         dnaFtQuery.join(Hql.innerJoin("parent", "lys"));
4979 24 Sep 18 nicklas 698         dnaFtQuery.join(Annotations.innerJoin(Annotationtype.QIACUBE_DATE.load(dc), "qcDate"));
4979 24 Sep 18 nicklas 699         dnaFtQuery.join(Annotations.innerJoin(Annotationtype.QIACUBE_RUN_NO.load(dc), "qcRun"));
4979 24 Sep 18 nicklas 700         dnaFtQuery.restrict(Restrictions.eq(Hql.alias("lys"), Hql.entityParameter("lysate", Item.EXTRACT)));
4979 24 Sep 18 nicklas 701         dnaFtQuery.restrict(Restrictions.eq(Hql.alias("qcDate"), Expressions.parameter("qcDate", Type.DATE)));
4979 24 Sep 18 nicklas 702         dnaFtQuery.restrict(Restrictions.eq(Hql.alias("qcRun"), Expressions.parameter("qcRun", Type.INT)));
4979 24 Sep 18 nicklas 703         
7199 25 May 23 nicklas 704         GenoTypeChecker checker = new GenoTypeChecker();
7199 25 May 23 nicklas 705         checker.preloadVcfForFlaggedTumorItems(dc);
6589 21 Feb 22 nicklas 706         checker.preloadSpecimenData(dc, true);
7199 25 May 23 nicklas 707         checker.preloadRelatedNormalItems(dc, null);
4975 21 Sep 18 nicklas 708
4977 24 Sep 18 nicklas 709         // Items marked with DoNotUse - total and per item type
4975 21 Sep 18 nicklas 710         int numRootDoNotUse = 0;
4977 24 Sep 18 nicklas 711         int numSpecimen = 0;
4977 24 Sep 18 nicklas 712         int numLysate = 0;
4977 24 Sep 18 nicklas 713         int numRna = 0;
4982 26 Sep 18 nicklas 714         int numPreNormalizedRna = 0;
4977 24 Sep 18 nicklas 715         int numLibrary = 0;
4977 24 Sep 18 nicklas 716         
4975 21 Sep 18 nicklas 717         int numTotalDoNotUse = 0;
4975 21 Sep 18 nicklas 718         int numUnflagged = 0;
4975 21 Sep 18 nicklas 719         int numDisabled = 0;
4981 25 Sep 18 nicklas 720         int numFutureGt = 0;
4975 21 Sep 18 nicklas 721         int numOkToUse = 0;
4975 21 Sep 18 nicklas 722         int numAutoUnflagged = 0;
4975 21 Sep 18 nicklas 723         
4975 21 Sep 18 nicklas 724         JSONArray jsonDebug = new JSONArray();
7216 30 May 23 nicklas 725         Set<AnnotatedItem> alreadyProcessed = new HashSet<>();
4975 21 Sep 18 nicklas 726         
4975 21 Sep 18 nicklas 727         for (int itemNo = 0; itemNo < jsonItems.size(); itemNo++)
4975 21 Sep 18 nicklas 728         {
4975 21 Sep 18 nicklas 729           JSONObject jsonItem = (JSONObject)jsonItems.get(itemNo);
4975 21 Sep 18 nicklas 730           
4975 21 Sep 18 nicklas 731           Item itemType = Item.valueOf((String)jsonItem.get("type"));
4975 21 Sep 18 nicklas 732           Number itemId = (Number)jsonItem.get("id");
4975 21 Sep 18 nicklas 733           // Only one of the options below should be set
4975 21 Sep 18 nicklas 734           String doNotUse = (String)jsonItem.get("doNotUse");
4975 21 Sep 18 nicklas 735           boolean okToUse = Boolean.TRUE.equals(jsonItem.get("okToUse"));
4981 25 Sep 18 nicklas 736           boolean futureGt = Boolean.TRUE.equals(jsonItem.get("futureGt"));
4975 21 Sep 18 nicklas 737           String comment = (String)jsonItem.get("comment");
4975 21 Sep 18 nicklas 738           
4975 21 Sep 18 nicklas 739           // The root item is typically a Library, RNA, Lysate or Specimen (same as indicated by the DoNotUse value)
4975 21 Sep 18 nicklas 740           BioMaterial rootItem = (BioMaterial)itemType.getById(dc, itemId.intValue());
4975 21 Sep 18 nicklas 741           if (alreadyProcessed.contains(rootItem)) 
4975 21 Sep 18 nicklas 742           {
4975 21 Sep 18 nicklas 743             jsonDebug.add("[Debug]Already processed: "+ rootItem + " [" + doNotUse + "]");
4975 21 Sep 18 nicklas 744             continue;
4975 21 Sep 18 nicklas 745           }
5024 15 Oct 18 nicklas 746           String rootItemDoNotUse = (String)Annotationtype.DO_NOT_USE.getAnnotationValue(dc, rootItem);
4975 21 Sep 18 nicklas 747           
4975 21 Sep 18 nicklas 748           // Load all downstream items (by matching the name)
7216 30 May 23 nicklas 749           List<AnnotatedItem> allChildItems = getAllChildItems(dc, rootItem);
4979 24 Sep 18 nicklas 750           if ("RNA".equals(doNotUse))
4979 24 Sep 18 nicklas 751           {
4979 24 Sep 18 nicklas 752             Extract rna = (Extract)rootItem;
4979 24 Sep 18 nicklas 753             Extract lysate = (Extract)rna.getParent();
4979 24 Sep 18 nicklas 754             Date qcDate = (Date)Annotationtype.QIACUBE_DATE.getAnnotationValue(dc, rna);
4979 24 Sep 18 nicklas 755             Integer qcRun = (Integer)Annotationtype.QIACUBE_RUN_NO.getAnnotationValue(dc, rna);
4979 24 Sep 18 nicklas 756             // Also include DNA and FlowThrough from the same Qiacube run
4979 24 Sep 18 nicklas 757             if (lysate != null && qcDate != null && qcRun != null)
4979 24 Sep 18 nicklas 758             {
4979 24 Sep 18 nicklas 759               dnaFtQuery.setEntityParameter("lysate", lysate);
4979 24 Sep 18 nicklas 760               dnaFtQuery.setParameter("qcDate", qcDate, Type.DATE);
4979 24 Sep 18 nicklas 761               dnaFtQuery.setParameter("qcRun", qcRun, Type.INT);
4979 24 Sep 18 nicklas 762               for (Extract e : dnaFtQuery.list(dc))
4979 24 Sep 18 nicklas 763               {
4979 24 Sep 18 nicklas 764                 if (!e.equals(rootItem)) // The query return all children for the lysate but we do not need to process the RNA twice
4979 24 Sep 18 nicklas 765                 {
7216 30 May 23 nicklas 766                   List<AnnotatedItem> dnaFtItems = getAllChildItems(dc, e);
4979 24 Sep 18 nicklas 767                   allChildItems.addAll(dnaFtItems);
4979 24 Sep 18 nicklas 768                   jsonDebug.add("[Debug]Added " + dnaFtItems.size() + " items related to " + e);
4979 24 Sep 18 nicklas 769                 }
4979 24 Sep 18 nicklas 770               }
4979 24 Sep 18 nicklas 771             }
4979 24 Sep 18 nicklas 772           }
4975 21 Sep 18 nicklas 773           
7216 30 May 23 nicklas 774           for (AnnotatedItem item : allChildItems)
4975 21 Sep 18 nicklas 775           {
7216 30 May 23 nicklas 776             if (alreadyProcessed.contains(item))
4975 21 Sep 18 nicklas 777             {
7216 30 May 23 nicklas 778               jsonDebug.add("[Debug]Already processed: "+ item + " [" + doNotUse + "]");
4975 21 Sep 18 nicklas 779               continue;
4975 21 Sep 18 nicklas 780             }
7216 30 May 23 nicklas 781             alreadyProcessed.add(item);
4975 21 Sep 18 nicklas 782             
4975 21 Sep 18 nicklas 783             ItemSubtype subtype = null;
7216 30 May 23 nicklas 784             if (item instanceof Subtypable)
4975 21 Sep 18 nicklas 785             {
7216 30 May 23 nicklas 786               subtype = ((Subtypable)item).getItemSubtype();
4975 21 Sep 18 nicklas 787             }
4975 21 Sep 18 nicklas 788             
7216 30 May 23 nicklas 789             String currentDoNotUse = (String)Annotationtype.DO_NOT_USE.getAnnotationValue(dc, item);
7216 30 May 23 nicklas 790             Pipeline pipeline = Pipeline.getByName((String)Annotationtype.PIPELINE.getAnnotationValue(dc, item));
4975 21 Sep 18 nicklas 791
4975 21 Sep 18 nicklas 792             // Set the DoNotUse and DoNotUseComment annotations
4975 21 Sep 18 nicklas 793             if (doNotUse != null)
4975 21 Sep 18 nicklas 794             {
5024 15 Oct 18 nicklas 795               if (currentDoNotUse == null || EqualsHelper.equals(currentDoNotUse, rootItemDoNotUse))
4977 24 Sep 18 nicklas 796               {
7216 30 May 23 nicklas 797                 Annotationtype.DO_NOT_USE.setAnnotationValue(dc, item, doNotUse);
7216 30 May 23 nicklas 798                 Annotationtype.DO_NOT_USE_COMMENT.setAnnotationValue(dc, item, comment);
7216 30 May 23 nicklas 799                 jsonDebug.add("[Debug]Do not use: " + item + " ["+doNotUse+"]");
5024 15 Oct 18 nicklas 800                 numTotalDoNotUse++;
7216 30 May 23 nicklas 801                 if (item == rootItem) 
5024 15 Oct 18 nicklas 802                 {
5024 15 Oct 18 nicklas 803                   numRootDoNotUse++;
5024 15 Oct 18 nicklas 804                   if (specimenType.equals(subtype)) numSpecimen++;
5024 15 Oct 18 nicklas 805                   else if (lysateType.equals(subtype)) numLysate++;
5024 15 Oct 18 nicklas 806                   else if (rnaType.equals(subtype)) numRna++;
5024 15 Oct 18 nicklas 807                   else if (preNormalizedType.equals(subtype)) numPreNormalizedRna++;
5024 15 Oct 18 nicklas 808                   else if (libraryType.equals(subtype)) numLibrary++;
5024 15 Oct 18 nicklas 809                 }
4977 24 Sep 18 nicklas 810               }
5024 15 Oct 18 nicklas 811               else
5024 15 Oct 18 nicklas 812               {
7216 30 May 23 nicklas 813                 jsonDebug.add("[Debug]Not updated: " + item + " ["+currentDoNotUse+"]");
5024 15 Oct 18 nicklas 814               }
4975 21 Sep 18 nicklas 815             }
4975 21 Sep 18 nicklas 816             
4975 21 Sep 18 nicklas 817             // Alignments need special handling
7209 26 May 23 nicklas 818             if (alignedType.equals(subtype) && pipeline == Pipeline.RNASEQ_HISAT_STRINGTIE)
4975 21 Sep 18 nicklas 819             {
7216 30 May 23 nicklas 820               DerivedBioAssay dba = (DerivedBioAssay)item;
4975 21 Sep 18 nicklas 821
4975 21 Sep 18 nicklas 822               // If there is no current status it is probably an alignment that have no GT data (eg. legacy pipeline)
7216 30 May 23 nicklas 823               String currentQcStatus = (String)Annotationtype.QC_GENOTYPE_STATUS.getAnnotationValue(dc, item);
4975 21 Sep 18 nicklas 824
4975 21 Sep 18 nicklas 825               // Remove it from the flagged alignments list 
5364 16 Apr 19 nicklas 826               boolean removed = flaggedAlignments.removeItem(dba);
5364 16 Apr 19 nicklas 827               if (removed)
4975 21 Sep 18 nicklas 828               {
5364 16 Apr 19 nicklas 829                 jsonDebug.add("[Debug]Unflagged: " + dba);
4975 21 Sep 18 nicklas 830                 numUnflagged++;
4975 21 Sep 18 nicklas 831               }
4975 21 Sep 18 nicklas 832               
4975 21 Sep 18 nicklas 833               // Remove it from the GenotypeChecker to make the auto-unflag functionality work
4975 21 Sep 18 nicklas 834               if (checker.remove(dba))
4975 21 Sep 18 nicklas 835               {
4975 21 Sep 18 nicklas 836                 jsonDebug.add("[Debug]Removed: "+ dba);
4975 21 Sep 18 nicklas 837               }
4975 21 Sep 18 nicklas 838               
4975 21 Sep 18 nicklas 839               if (currentQcStatus != null)
4975 21 Sep 18 nicklas 840               {
4975 21 Sep 18 nicklas 841                 // Disable alignment from future GT checks
4975 21 Sep 18 nicklas 842                 if (doNotUse != null)
4975 21 Sep 18 nicklas 843                 {
4981 25 Sep 18 nicklas 844                   if (futureGt)
4981 25 Sep 18 nicklas 845                   {
4981 25 Sep 18 nicklas 846                     Annotationtype.QC_GENOTYPE_STATUS.setAnnotationValue(dc, dba, "Checked");
7216 30 May 23 nicklas 847                     jsonDebug.add("[Debug]FutureGT: " + item);
4981 25 Sep 18 nicklas 848                     numFutureGt++;
4981 25 Sep 18 nicklas 849                   }
4981 25 Sep 18 nicklas 850                   else
4981 25 Sep 18 nicklas 851                   {
4981 25 Sep 18 nicklas 852                     Annotationtype.QC_GENOTYPE_STATUS.setAnnotationValue(dc, dba, "Disabled");
7216 30 May 23 nicklas 853                     jsonDebug.add("[Debug]Disabled: " + item);
4981 25 Sep 18 nicklas 854                     numDisabled++;
4981 25 Sep 18 nicklas 855                   }
4975 21 Sep 18 nicklas 856                 }
4975 21 Sep 18 nicklas 857                 else if (okToUse)
4975 21 Sep 18 nicklas 858                 {
4975 21 Sep 18 nicklas 859                   Annotationtype.QC_GENOTYPE_STATUS.setAnnotationValue(dc, dba, "Checked");
4975 21 Sep 18 nicklas 860                   if (comment != null) Annotationtype.QC_GENOTYPE_COMMENT.setAnnotationValue(dc, dba, comment);
7216 30 May 23 nicklas 861                   jsonDebug.add("[Debug]OkToUse: " + item + " [" + comment + "]");
4975 21 Sep 18 nicklas 862                   numOkToUse++;
4975 21 Sep 18 nicklas 863                 }
4975 21 Sep 18 nicklas 864               }
4975 21 Sep 18 nicklas 865             }
4975 21 Sep 18 nicklas 866           }
4975 21 Sep 18 nicklas 867         }
4975 21 Sep 18 nicklas 868         
4975 21 Sep 18 nicklas 869         // Handles related (flagged alignments) that may no longer see any genotype errors after
4975 21 Sep 18 nicklas 870         // removing the DoNotUse/OkToUse alignments from the flagged alignments list
4975 21 Sep 18 nicklas 871         for (Number id : jsonPaired)
4975 21 Sep 18 nicklas 872         {
4975 21 Sep 18 nicklas 873           //Number id = (Number)jsonPaired.get(itemNo);
4975 21 Sep 18 nicklas 874           DerivedBioAssay dba = DerivedBioAssay.getById(dc, id.intValue());
4975 21 Sep 18 nicklas 875           if (checker.isFlagged(dba))
4975 21 Sep 18 nicklas 876           {
4975 21 Sep 18 nicklas 877             CompareData cmp = checker.check(dc, dba);
4975 21 Sep 18 nicklas 878             if (!cmp.getRecommendFlag())
4975 21 Sep 18 nicklas 879             {
5364 16 Apr 19 nicklas 880               flaggedAlignments.removeItem(dba);
4975 21 Sep 18 nicklas 881               jsonDebug.add("[Debug]Auto-unflag:" + dba);
4975 21 Sep 18 nicklas 882               numAutoUnflagged++;
4975 21 Sep 18 nicklas 883             }
4975 21 Sep 18 nicklas 884             else
4975 21 Sep 18 nicklas 885             {
4975 21 Sep 18 nicklas 886               jsonDebug.add("[Debug]Still flagged: "+ dba);
4975 21 Sep 18 nicklas 887             }
4975 21 Sep 18 nicklas 888           }
4975 21 Sep 18 nicklas 889           else
4975 21 Sep 18 nicklas 890           {
4975 21 Sep 18 nicklas 891             jsonDebug.add("[Debug]Not flagged: " + dba);
4975 21 Sep 18 nicklas 892           }
4975 21 Sep 18 nicklas 893         }
4975 21 Sep 18 nicklas 894
4975 21 Sep 18 nicklas 895         if (numRootDoNotUse > 0)
4975 21 Sep 18 nicklas 896         {
4977 24 Sep 18 nicklas 897           StringBuilder msg = new StringBuilder();
4977 24 Sep 18 nicklas 898           if (numSpecimen > 0)
4977 24 Sep 18 nicklas 899           {
4977 24 Sep 18 nicklas 900             msg.append(countMessage(numSpecimen, "specimen", "specimens"));
4977 24 Sep 18 nicklas 901           }
4977 24 Sep 18 nicklas 902           if (numLysate > 0)
4977 24 Sep 18 nicklas 903           {
4977 24 Sep 18 nicklas 904             if (msg.length() > 0) msg.append(", ");
4977 24 Sep 18 nicklas 905             msg.append(countMessage(numLysate, "lysate", "lysates"));
4977 24 Sep 18 nicklas 906           }
4977 24 Sep 18 nicklas 907           if (numRna > 0)
4977 24 Sep 18 nicklas 908           {
4977 24 Sep 18 nicklas 909             if (msg.length() > 0) msg.append(", ");
4977 24 Sep 18 nicklas 910             msg.append(countMessage(numRna, "RNA", "RNA"));
4977 24 Sep 18 nicklas 911           }
4982 26 Sep 18 nicklas 912           if (numPreNormalizedRna > 0)
4982 26 Sep 18 nicklas 913           {
4982 26 Sep 18 nicklas 914             if (msg.length() > 0) msg.append(", ");
4982 26 Sep 18 nicklas 915             msg.append(countMessage(numPreNormalizedRna, "pre-normalized RNA", "pre-normalized RNA"));
4982 26 Sep 18 nicklas 916           }
4977 24 Sep 18 nicklas 917           if (numLibrary > 0)
4977 24 Sep 18 nicklas 918           {
4977 24 Sep 18 nicklas 919             if (msg.length() > 0) msg.append(", ");
4977 24 Sep 18 nicklas 920             msg.append(countMessage(numLibrary, "library", "libraries"));
4977 24 Sep 18 nicklas 921           }
4977 24 Sep 18 nicklas 922           jsonMessages.add(msg + " and " + countMessage(numTotalDoNotUse-numRootDoNotUse, "related item", "related items") + " marked as DoNotUse.");
4975 21 Sep 18 nicklas 923         }
4975 21 Sep 18 nicklas 924         
4981 25 Sep 18 nicklas 925         if (numDisabled > 0 || numFutureGt > 0)
4975 21 Sep 18 nicklas 926         {
4981 25 Sep 18 nicklas 927           StringBuilder msg = new StringBuilder();
4981 25 Sep 18 nicklas 928           if (numDisabled > 0)
4981 25 Sep 18 nicklas 929           {
4981 25 Sep 18 nicklas 930             msg.append(countMessage(numDisabled, "alignment has", "alignments have")).append(" been disabled");
4981 25 Sep 18 nicklas 931           }
4981 25 Sep 18 nicklas 932           if (numFutureGt > 0)
4981 25 Sep 18 nicklas 933           {
4981 25 Sep 18 nicklas 934             if (msg.length() > 0) msg.append(" and ");
4981 25 Sep 18 nicklas 935             msg.append(countMessage(numFutureGt, "alignment has", "alignments have")).append(" been retained");
4981 25 Sep 18 nicklas 936           }
4981 25 Sep 18 nicklas 937           msg.append(" for future genotype checks.");
4981 25 Sep 18 nicklas 938           jsonMessages.add(msg.toString());
4975 21 Sep 18 nicklas 939         }
4975 21 Sep 18 nicklas 940
4975 21 Sep 18 nicklas 941         if (numOkToUse > 0)
4975 21 Sep 18 nicklas 942         {
4977 24 Sep 18 nicklas 943           jsonMessages.add(countMessage(numOkToUse, "alignment is", "alignments are") + " ok to use.");
4975 21 Sep 18 nicklas 944         }
4975 21 Sep 18 nicklas 945         
4975 21 Sep 18 nicklas 946         if (numAutoUnflagged > 0)
4975 21 Sep 18 nicklas 947         {
4977 24 Sep 18 nicklas 948           jsonMessages.add(countMessage(numAutoUnflagged, "related alignment has", "related alignments have") + " been automatically unflagged.");
4975 21 Sep 18 nicklas 949         }
4975 21 Sep 18 nicklas 950         
6589 21 Feb 22 nicklas 951         jsonMessages.addAll(jsonDebug);
4975 21 Sep 18 nicklas 952         
6591 21 Feb 22 nicklas 953         dc.commit();
6589 21 Feb 22 nicklas 954         dc.close();
4975 21 Sep 18 nicklas 955         
4975 21 Sep 18 nicklas 956         // Reload flagged alignments so that the browser can update the table 
6335 15 Jun 21 nicklas 957         dc = sc.newDbControl(dc.getName());
7209 26 May 23 nicklas 958         loadFlaggedTumorsAndRelatedNormals(dc, json, req);
4975 21 Sep 18 nicklas 959         dc.commit();
4975 21 Sep 18 nicklas 960       }
4642 28 Nov 17 nicklas 961       
4642 28 Nov 17 nicklas 962       json.put("messages", jsonMessages);
4648 15 Dec 17 nicklas 963       CounterService.getInstance().setForceCount();
4642 28 Nov 17 nicklas 964     }
4642 28 Nov 17 nicklas 965     catch (Throwable t)
4642 28 Nov 17 nicklas 966     {
4642 28 Nov 17 nicklas 967       t.printStackTrace();
4642 28 Nov 17 nicklas 968       json.clear();
4642 28 Nov 17 nicklas 969       json.put("status", "error");
4642 28 Nov 17 nicklas 970       json.put("message", t.getMessage());
4642 28 Nov 17 nicklas 971       json.put("stacktrace", ThrowableUtil.stackTraceToString(t));
4642 28 Nov 17 nicklas 972     }
4642 28 Nov 17 nicklas 973     finally
4642 28 Nov 17 nicklas 974     {
4642 28 Nov 17 nicklas 975       if (dc != null) dc.close();
4642 28 Nov 17 nicklas 976       json.writeJSONString(resp.getWriter());
4642 28 Nov 17 nicklas 977     }
4642 28 Nov 17 nicklas 978     
4642 28 Nov 17 nicklas 979   }
4642 28 Nov 17 nicklas 980   
4642 28 Nov 17 nicklas 981   
4648 15 Dec 17 nicklas 982   private void loadMoreGenoTypeInfo(DbControl dc, AlignedSequences aligned)
4648 15 Dec 17 nicklas 983   {
7203 25 May 23 nicklas 984     aligned.loadAnnotations(dc, "PIPELINE", Annotationtype.PIPELINE, null);
4648 15 Dec 17 nicklas 985     aligned.loadAnnotations(dc, "ALIGNED_PAIRS", Annotationtype.ALIGNED_PAIRS, null);
4649 20 Dec 17 nicklas 986     aligned.loadAnnotations(dc, "FRACTION_DUPLICATION", Annotationtype.FRACTION_DUPLICATION, null);
4713 22 Mar 18 nicklas 987     aligned.loadAnnotations(dc, "QC_GENOTYPE_VERIFIED", Annotationtype.QC_GENOTYPE_VERIFIED, null);
4713 22 Mar 18 nicklas 988     aligned.loadAnnotations(dc, "QC_GENOTYPE_COMMENT", Annotationtype.QC_GENOTYPE_COMMENT, null);
4648 15 Dec 17 nicklas 989     Library lib = aligned.getLibrary(dc);
4648 15 Dec 17 nicklas 990     lib.loadBioPlateLocation();
4648 15 Dec 17 nicklas 991     aligned.setAnnotation("lib", lib.asJSONObject());
4648 15 Dec 17 nicklas 992     
4648 15 Dec 17 nicklas 993     Map<Subtype, BioMaterial> parents = lib.findParentBioMaterial(dc, Subtype.RNA, Subtype.LYSATE, Subtype.PATIENT);
4648 15 Dec 17 nicklas 994     
4648 15 Dec 17 nicklas 995     Extract rna = (Extract)parents.get(Subtype.RNA);
4648 15 Dec 17 nicklas 996     Extract lysate = (Extract)parents.get(Subtype.LYSATE);
4648 15 Dec 17 nicklas 997     BioSource pat = (BioSource)parents.get(Subtype.PATIENT);
4648 15 Dec 17 nicklas 998     
4648 15 Dec 17 nicklas 999     if (rna != null) 
4648 15 Dec 17 nicklas 1000     {
4648 15 Dec 17 nicklas 1001       aligned.setAnnotation("QIACUBE_DATE", Reggie.CONVERTER_DATE_TO_STRING.convert((Date)Annotationtype.QIACUBE_DATE.getAnnotationValue(dc, rna)));
4648 15 Dec 17 nicklas 1002       aligned.setAnnotation("QIACUBE_RUN_NO", Annotationtype.QIACUBE_RUN_NO.getAnnotationValue(dc, rna));
4648 15 Dec 17 nicklas 1003       aligned.setAnnotation("QIACUBE_POSITION", Annotationtype.QIACUBE_POSITION.getAnnotationValue(dc, rna));
4648 15 Dec 17 nicklas 1004     }
4648 15 Dec 17 nicklas 1005     
4648 15 Dec 17 nicklas 1006     if (lysate != null)
4648 15 Dec 17 nicklas 1007     {
4648 15 Dec 17 nicklas 1008       aligned.setAnnotation("PARTITION_DATE", Reggie.CONVERTER_DATE_TO_STRING.convert((Date)Annotationtype.PARTITION_DATE.getAnnotationValue(dc, lysate)));
4648 15 Dec 17 nicklas 1009     }
4648 15 Dec 17 nicklas 1010     
4648 15 Dec 17 nicklas 1011     if (pat != null)
4648 15 Dec 17 nicklas 1012     {
4648 15 Dec 17 nicklas 1013       aligned.setAnnotation("patientName", pat.getName());
4648 15 Dec 17 nicklas 1014     }
4648 15 Dec 17 nicklas 1015     
4648 15 Dec 17 nicklas 1016     
4648 15 Dec 17 nicklas 1017   }
4649 20 Dec 17 nicklas 1018   
4649 20 Dec 17 nicklas 1019   /**
4649 20 Dec 17 nicklas 1020     Reset and clear all QC_GENOTYPE_STATUS annotations.
4649 20 Dec 17 nicklas 1021     FOR DEBUGGING!!!
4649 20 Dec 17 nicklas 1022   */
4671 07 Feb 18 nicklas 1023   private void resetQCStatus(DbControl dc)
4649 20 Dec 17 nicklas 1024   {
4649 20 Dec 17 nicklas 1025     ItemQuery<DerivedBioAssay> query = DerivedBioAssay.getQuery();
4649 20 Dec 17 nicklas 1026     Subtype.ALIGNED_SEQUENCES.addFilter(dc, query);
4649 20 Dec 17 nicklas 1027     query.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
4649 20 Dec 17 nicklas 1028     
4649 20 Dec 17 nicklas 1029     // Must have 'qc_genotype.vcf' FILE already
4649 20 Dec 17 nicklas 1030     query.restrict(AnyToAnyRestriction.exists("qc_genotype.vcf", Item.FILE));
4649 20 Dec 17 nicklas 1031
4649 20 Dec 17 nicklas 1032     // Must have a QC_GENOTYPE_STATUS annotation
4649 20 Dec 17 nicklas 1033     query.join(Annotations.innerJoin(null, Annotationtype.QC_GENOTYPE_STATUS.load(dc), "qc"));
4649 20 Dec 17 nicklas 1034
4649 20 Dec 17 nicklas 1035     AnnotationType qcStatus = Annotationtype.QC_GENOTYPE_STATUS.get(dc);
4649 20 Dec 17 nicklas 1036     AnnotationBatcher batcher = new AnnotationBatcher(dc, Item.DERIVEDBIOASSAY);
4649 20 Dec 17 nicklas 1037     batcher.addAnnotationTypes(Arrays.asList(qcStatus));
4649 20 Dec 17 nicklas 1038     
4649 20 Dec 17 nicklas 1039     for (DerivedBioAssay aligned : query.list(dc))
4649 20 Dec 17 nicklas 1040     {
4649 20 Dec 17 nicklas 1041       batcher.setCurrentItem(aligned);
4649 20 Dec 17 nicklas 1042       batcher.setValue(qcStatus, null, null, false);
4649 20 Dec 17 nicklas 1043     }
4649 20 Dec 17 nicklas 1044
4671 07 Feb 18 nicklas 1045     // Remove all items from the Flagged alignment list
4671 07 Feb 18 nicklas 1046     ItemList flagged = BiomaterialList.FLAGGED_ALIGNMENT.get(dc);
4671 07 Feb 18 nicklas 1047     flagged.removeAll(flagged);
4649 20 Dec 17 nicklas 1048   }
4649 20 Dec 17 nicklas 1049   
4671 07 Feb 18 nicklas 1050
4980 25 Sep 18 nicklas 1051   private void loadLibraryAnnotations(DbControl dc, SnapshotManager manager, Library lib)
4980 25 Sep 18 nicklas 1052   {
4980 25 Sep 18 nicklas 1053     if (lib == null) return;
4980 25 Sep 18 nicklas 1054     Extract libExtract = lib.getExtract();
4980 25 Sep 18 nicklas 1055     lib.loadBioPlateLocation();
5024 15 Oct 18 nicklas 1056     lib.loadDoNotUseAnnotations(dc, manager);
4980 25 Sep 18 nicklas 1057   }
4980 25 Sep 18 nicklas 1058   
4818 22 May 18 nicklas 1059   private void loadRnaAnnotations(DbControl dc, SnapshotManager manager, Rna rna)
4818 22 May 18 nicklas 1060   {
4818 22 May 18 nicklas 1061     if (rna == null) return;
4818 22 May 18 nicklas 1062     Extract rnaExtract = rna.getExtract();
4818 22 May 18 nicklas 1063     rna.loadAnnotations(dc, manager, "QIACUBE_DATE", Annotationtype.QIACUBE_DATE, Reggie.CONVERTER_DATE_TO_STRING);
4818 22 May 18 nicklas 1064     rna.loadAnnotations(dc, manager, "QIACUBE_RUN_NO", Annotationtype.QIACUBE_RUN_NO, null);
4818 22 May 18 nicklas 1065     rna.loadAnnotations(dc, manager, "QIACUBE_POSITION", Annotationtype.QIACUBE_POSITION, null);
4818 22 May 18 nicklas 1066     rna.loadAnnotations(dc, manager, "AutoProcessing", Annotationtype.AUTO_PROCESSING, null);
5024 15 Oct 18 nicklas 1067     rna.loadDoNotUseAnnotations(dc, manager);
4818 22 May 18 nicklas 1068     rna.setAnnotation("remainingQuantity", rnaExtract.getRemainingQuantity());
4818 22 May 18 nicklas 1069     rna.setAnnotation("originalQuantity", rnaExtract.getOriginalQuantity());
4818 22 May 18 nicklas 1070   }
4818 22 May 18 nicklas 1071   
4818 22 May 18 nicklas 1072   private void loadLysateAnnotations(DbControl dc, SnapshotManager manager, Lysate lys)
4818 22 May 18 nicklas 1073   {
4818 22 May 18 nicklas 1074     if (lys == null) return;
4818 22 May 18 nicklas 1075     Extract lysExtract = lys.getExtract();
4818 22 May 18 nicklas 1076     lys.loadAnnotations(dc, manager, "AutoProcessing", Annotationtype.AUTO_PROCESSING, null);
4818 22 May 18 nicklas 1077     lys.setAnnotation("remainingQuantity", lysExtract.getRemainingQuantity());
5024 15 Oct 18 nicklas 1078     lys.loadDoNotUseAnnotations(dc, manager);
4818 22 May 18 nicklas 1079   }
4818 22 May 18 nicklas 1080   
4818 22 May 18 nicklas 1081   private void loadSpecimenAnnotations(DbControl dc, SnapshotManager manager, SpecimenTube sp)
4818 22 May 18 nicklas 1082   {
4818 22 May 18 nicklas 1083     if (sp == null) return;
4818 22 May 18 nicklas 1084     Sample specimenSample = sp.getSample();
4818 22 May 18 nicklas 1085     sp.loadAnnotations(dc, manager, "AutoProcessing", Annotationtype.AUTO_PROCESSING, null);
4818 22 May 18 nicklas 1086     sp.setAnnotation("remainingQuantity", specimenSample.getRemainingQuantity());
5024 15 Oct 18 nicklas 1087     sp.loadDoNotUseAnnotations(dc, manager);
4818 22 May 18 nicklas 1088   }
4818 22 May 18 nicklas 1089
7209 26 May 23 nicklas 1090   private void loadFlaggedTumorsAndRelatedNormals(DbControl dc, JSONObject json, HttpServletRequest req)
4970 13 Sep 18 nicklas 1091   {
4970 13 Sep 18 nicklas 1092     String libPlateFilter = req.getParameter("libPlateFilter");
4970 13 Sep 18 nicklas 1093     String qiaCubeFilter = req.getParameter("qiaCubeFilter");
4970 13 Sep 18 nicklas 1094     boolean highHetFilter = Values.getBoolean(req.getParameter("highHetFilter"));
4970 13 Sep 18 nicklas 1095     
7199 25 May 23 nicklas 1096     GenoTypeChecker checker = new GenoTypeChecker();
7199 25 May 23 nicklas 1097     checker.preloadVcfForFlaggedTumorItems(dc);
6589 21 Feb 22 nicklas 1098     checker.preloadSpecimenData(dc, true);
4970 13 Sep 18 nicklas 1099     
7199 25 May 23 nicklas 1100     ItemQuery<DerivedBioAssay> query = checker.getFlaggedTumorItems(dc);
4970 13 Sep 18 nicklas 1101     // When we have a filter we want to load information about all items on the 
4970 13 Sep 18 nicklas 1102     // given QiaCube/LibPlate. We fill this Set with all RNA/Library items and then 
4970 13 Sep 18 nicklas 1103     // remove them as we find alignments. Remaining items in this Set have no alignment (that we can use)
4970 13 Sep 18 nicklas 1104     Set<Extract> itemsWithoutAlignment = null; 
4970 13 Sep 18 nicklas 1105     if (qiaCubeFilter != null)
4970 13 Sep 18 nicklas 1106     {
4970 13 Sep 18 nicklas 1107       Date qcDate = Reggie.CONVERTER_STRING_TO_DATE.convert(qiaCubeFilter.substring(0, 8));
4970 13 Sep 18 nicklas 1108       int runNo = Values.getInt(qiaCubeFilter.substring(9));
4970 13 Sep 18 nicklas 1109       
4970 13 Sep 18 nicklas 1110       ItemQuery<Extract> rnaQuery = checker.getRnaRelatedToQiacube(dc, qcDate, runNo);
4970 13 Sep 18 nicklas 1111       itemsWithoutAlignment = new HashSet<>(rnaQuery.list(dc));
7199 25 May 23 nicklas 1112       query = checker.getTumorItemsRelatedTo(dc, itemsWithoutAlignment, true, true);
4970 13 Sep 18 nicklas 1113     }
4970 13 Sep 18 nicklas 1114     else if (libPlateFilter != null)
4970 13 Sep 18 nicklas 1115     {
4970 13 Sep 18 nicklas 1116       ItemQuery<Extract> libQuery = checker.getLibrariesRelatedToLibPlate(dc, libPlateFilter);
4970 13 Sep 18 nicklas 1117       itemsWithoutAlignment = new HashSet<>(libQuery.list(dc));
7199 25 May 23 nicklas 1118       query = checker.getTumorItemsRelatedTo(dc, itemsWithoutAlignment, true, true);
4970 13 Sep 18 nicklas 1119     }
4970 13 Sep 18 nicklas 1120     else if (highHetFilter)
4970 13 Sep 18 nicklas 1121     {
7199 25 May 23 nicklas 1122       query = checker.getTumorItemsWithHighHet(dc, true);
4970 13 Sep 18 nicklas 1123     }
4970 13 Sep 18 nicklas 1124     query.order(Orders.asc(Hql.property("name")));
4970 13 Sep 18 nicklas 1125     
7209 26 May 23 nicklas 1126     List<AlignedSequences> tumors = AlignedSequences.toList(query.list(dc));
4970 13 Sep 18 nicklas 1127     SnapshotManager manager = new SnapshotManager();
4970 13 Sep 18 nicklas 1128
4970 13 Sep 18 nicklas 1129     if (qiaCubeFilter != null || libPlateFilter != null || highHetFilter)
4970 13 Sep 18 nicklas 1130     {
7209 26 May 23 nicklas 1131       for (AlignedSequences as : tumors)
4970 13 Sep 18 nicklas 1132       {
4970 13 Sep 18 nicklas 1133         DerivedBioAssay alignment = as.getDerivedBioAssay();
4970 13 Sep 18 nicklas 1134         String qcStatus = (String)Annotationtype.QC_GENOTYPE_STATUS.getAnnotationValue(dc, manager, alignment);
4970 13 Sep 18 nicklas 1135         if ("Checked".equals(qcStatus))
4970 13 Sep 18 nicklas 1136         {
4970 13 Sep 18 nicklas 1137           // Only include "Checked" alignments in genotyping
7211 29 May 23 nicklas 1138           checker.preloadItem(dc, as.getDerivedBioAssay());
4970 13 Sep 18 nicklas 1139         }
4970 13 Sep 18 nicklas 1140       }
4970 13 Sep 18 nicklas 1141     }
4970 13 Sep 18 nicklas 1142     
7209 26 May 23 nicklas 1143     JSONArray jsonTumors = new JSONArray();
6589 21 Feb 22 nicklas 1144     Set<Integer> patients = new HashSet<>();
6589 21 Feb 22 nicklas 1145     List<AlignedSequences> toCheck = new ArrayList<>();
7209 26 May 23 nicklas 1146     for (AlignedSequences as : tumors)
4970 13 Sep 18 nicklas 1147     {
4970 13 Sep 18 nicklas 1148       String qcStatus = (String)Annotationtype.QC_GENOTYPE_STATUS.getAnnotationValue(dc, manager, as.getItem());
7209 26 May 23 nicklas 1149       as.loadAnnotations(dc, manager, "PIPELINE", Annotationtype.PIPELINE, null);
4970 13 Sep 18 nicklas 1150       as.loadAnnotations(dc, manager, "QC_GENOTYPE_HET_PCT", Annotationtype.QC_GENOTYPE_HET_PCT, null);
4970 13 Sep 18 nicklas 1151       as.loadAnnotations(dc, manager, "QC_GENOTYPE_VERIFIED", Annotationtype.QC_GENOTYPE_VERIFIED, null);
4970 13 Sep 18 nicklas 1152       as.loadAnnotations(dc, manager, "QC_GENOTYPE_COMMENT", Annotationtype.QC_GENOTYPE_COMMENT, null);
5024 15 Oct 18 nicklas 1153       as.loadDoNotUseAnnotations(dc, manager);
4970 13 Sep 18 nicklas 1154       as.setAnnotation("QC_GENOTYPE_STATUS", qcStatus);
4975 21 Sep 18 nicklas 1155       as.setAnnotation("flagged", checker.isFlagged(as.getItem()));
4970 13 Sep 18 nicklas 1156       Library lib = as.getLibrary(dc);
4982 26 Sep 18 nicklas 1157       Rna rna = lib.getRna(dc, true);
4982 26 Sep 18 nicklas 1158       Rna prenormalizedRna = null;
4982 26 Sep 18 nicklas 1159       if (rna != null && rna.isPreNormalized(dc))
4982 26 Sep 18 nicklas 1160       {
4982 26 Sep 18 nicklas 1161         prenormalizedRna = rna;
4982 26 Sep 18 nicklas 1162         rna = Rna.get((Extract)rna.getExtract().getParent());
4982 26 Sep 18 nicklas 1163       }
4970 13 Sep 18 nicklas 1164       Lysate lys = rna != null ? rna.getLysate() : null;
4970 13 Sep 18 nicklas 1165       SpecimenTube sp = lys != null ? lys.getSpecimen() : null;
4970 13 Sep 18 nicklas 1166       
4980 25 Sep 18 nicklas 1167       loadLibraryAnnotations(dc, manager, lib);
4970 13 Sep 18 nicklas 1168       loadRnaAnnotations(dc, manager, rna);
4970 13 Sep 18 nicklas 1169       loadLysateAnnotations(dc, manager, lys);
4970 13 Sep 18 nicklas 1170       loadSpecimenAnnotations(dc, manager, sp);
4970 13 Sep 18 nicklas 1171       SpecimenData pat = checker.getSpecimenData(as.getItem());
4970 13 Sep 18 nicklas 1172       if (pat != null) // Can be null if the item is an external library
4970 13 Sep 18 nicklas 1173       {
4970 13 Sep 18 nicklas 1174         sp.setAnnotation("patientName", pat.getPatientName());
6589 21 Feb 22 nicklas 1175         patients.add(pat.getPatientId());
4970 13 Sep 18 nicklas 1176       }
4970 13 Sep 18 nicklas 1177       
4970 13 Sep 18 nicklas 1178       if (itemsWithoutAlignment != null) 
4970 13 Sep 18 nicklas 1179       {
4970 13 Sep 18 nicklas 1180         // Important that we remove the RNA/Library that we have found and alignment for 
4970 13 Sep 18 nicklas 1181         if (qiaCubeFilter != null) itemsWithoutAlignment.remove(rna.getExtract());
4970 13 Sep 18 nicklas 1182         if (libPlateFilter != null) itemsWithoutAlignment.remove(lib.getExtract());
4970 13 Sep 18 nicklas 1183       }
4970 13 Sep 18 nicklas 1184       
4970 13 Sep 18 nicklas 1185       if (lib != null) as.setAnnotation("lib", lib.asJSONObject());
5024 15 Oct 18 nicklas 1186       if (prenormalizedRna != null) 
5024 15 Oct 18 nicklas 1187       {
5024 15 Oct 18 nicklas 1188         prenormalizedRna.loadDoNotUseAnnotations(dc, manager);
5024 15 Oct 18 nicklas 1189         as.setAnnotation("preNormalizedRna", prenormalizedRna.asJSONObject());
5024 15 Oct 18 nicklas 1190       }
4970 13 Sep 18 nicklas 1191       if (rna != null) as.setAnnotation("rna", rna.asJSONObject());
4970 13 Sep 18 nicklas 1192       if (lys != null) as.setAnnotation("lysate", lys.asJSONObject());
4970 13 Sep 18 nicklas 1193       if (sp != null) as.setAnnotation("specimen", sp.asJSONObject());
4970 13 Sep 18 nicklas 1194       if ("Checked".equals(qcStatus))
4970 13 Sep 18 nicklas 1195       {
4970 13 Sep 18 nicklas 1196         // Only include "Checked" alignments in genotyping
6589 21 Feb 22 nicklas 1197         // But the check need to wait until we have loaded genotype calls
6589 21 Feb 22 nicklas 1198         toCheck.add(as);
4970 13 Sep 18 nicklas 1199       }
7209 26 May 23 nicklas 1200       jsonTumors.add(as.asJSONObject());
4970 13 Sep 18 nicklas 1201     }
4970 13 Sep 18 nicklas 1202     
4970 13 Sep 18 nicklas 1203     if (itemsWithoutAlignment != null && itemsWithoutAlignment.size() > 0)
4970 13 Sep 18 nicklas 1204     {
4970 13 Sep 18 nicklas 1205       for (Extract e : itemsWithoutAlignment)
4970 13 Sep 18 nicklas 1206       {
4970 13 Sep 18 nicklas 1207         Library lib = null;
4970 13 Sep 18 nicklas 1208         Rna rna = null;
4970 13 Sep 18 nicklas 1209         Lysate lys = null;
4970 13 Sep 18 nicklas 1210         SpecimenTube sp = null;
4970 13 Sep 18 nicklas 1211         
4970 13 Sep 18 nicklas 1212         // The item is eiter an RNA or a Library
4970 13 Sep 18 nicklas 1213         if (qiaCubeFilter != null)
4970 13 Sep 18 nicklas 1214         {
4970 13 Sep 18 nicklas 1215           rna = Rna.get(e);
4970 13 Sep 18 nicklas 1216           lys = rna.getLysate();
4970 13 Sep 18 nicklas 1217           sp = lys.getSpecimen();
4970 13 Sep 18 nicklas 1218         }
4970 13 Sep 18 nicklas 1219         else if (libPlateFilter != null)
4970 13 Sep 18 nicklas 1220         {
4970 13 Sep 18 nicklas 1221           lib = Library.get(e);
4970 13 Sep 18 nicklas 1222           rna = lib.getRna(dc, false);
4970 13 Sep 18 nicklas 1223           // Can be null here if the library is external
4970 13 Sep 18 nicklas 1224           if (rna != null) lys = rna.getLysate();
4970 13 Sep 18 nicklas 1225           if (lys != null) sp = lys.getSpecimen();
4970 13 Sep 18 nicklas 1226         }
4970 13 Sep 18 nicklas 1227         
4980 25 Sep 18 nicklas 1228         loadLibraryAnnotations(dc, manager, lib);
4970 13 Sep 18 nicklas 1229         loadRnaAnnotations(dc, manager, rna);
4970 13 Sep 18 nicklas 1230         loadLysateAnnotations(dc, manager, lys);
4970 13 Sep 18 nicklas 1231         loadSpecimenAnnotations(dc, manager, sp);
4970 13 Sep 18 nicklas 1232         SpecimenData pat = checker.getSpecimenData(e);
4970 13 Sep 18 nicklas 1233         if (pat != null) // Can be null if the item is an external library
4970 13 Sep 18 nicklas 1234         {
4970 13 Sep 18 nicklas 1235           sp.setAnnotation("patientName", pat.getPatientName());
6589 21 Feb 22 nicklas 1236           patients.add(pat.getPatientId());
4970 13 Sep 18 nicklas 1237         }
4970 13 Sep 18 nicklas 1238
4970 13 Sep 18 nicklas 1239         JSONObject jsonItemWithoutAlignment = new JSONObject();
4970 13 Sep 18 nicklas 1240         if (lib != null) jsonItemWithoutAlignment.put("lib", lib.asJSONObject());
4970 13 Sep 18 nicklas 1241         if (rna != null) jsonItemWithoutAlignment.put("rna", rna.asJSONObject());
4970 13 Sep 18 nicklas 1242         if (lys != null) jsonItemWithoutAlignment.put("lysate", lys.asJSONObject());
4970 13 Sep 18 nicklas 1243         if (sp != null) jsonItemWithoutAlignment.put("specimen", sp.asJSONObject());
7209 26 May 23 nicklas 1244         jsonTumors.add(jsonItemWithoutAlignment);
4970 13 Sep 18 nicklas 1245       }
4970 13 Sep 18 nicklas 1246     }
4970 13 Sep 18 nicklas 1247     
6589 21 Feb 22 nicklas 1248     // Load genotype calls that are related to the same patients as the alignments that
6589 21 Feb 22 nicklas 1249     // are already loaded
7209 26 May 23 nicklas 1250     JSONArray jsonNormals = new JSONArray();
7209 26 May 23 nicklas 1251     List<DerivedBioAssay> normals = checker.preloadRelatedNormalItems(dc, patients);
7209 26 May 23 nicklas 1252     for (DerivedBioAssay dba : normals)
6589 21 Feb 22 nicklas 1253     {
7209 26 May 23 nicklas 1254       Pipeline pipeline = Pipeline.getByName((String)Annotationtype.PIPELINE.getAnnotationValue(dc, dba));
7209 26 May 23 nicklas 1255       GenotypeCall gtc = null;
7209 26 May 23 nicklas 1256       AlignedSequences aligned = null;
7209 26 May 23 nicklas 1257       ReggieItem<?> normal = null;
7209 26 May 23 nicklas 1258       if (pipeline == Pipeline.DNA_GENOTYPING)
6590 21 Feb 22 nicklas 1259       {
7209 26 May 23 nicklas 1260         gtc = GenotypeCall.get(dba);
7209 26 May 23 nicklas 1261         BeadChip chip = gtc.getBeadChip(dc);
7209 26 May 23 nicklas 1262         BloodDna dna = gtc.getBloodDna(dc);
7209 26 May 23 nicklas 1263         if (chip != null)
7209 26 May 23 nicklas 1264         {
7209 26 May 23 nicklas 1265           chip.loadAnnotations(dc, manager, "BeadChipID", Annotationtype.BEADCHIP_ID, null);
7209 26 May 23 nicklas 1266           gtc.setAnnotation("chip", chip.asJSONObject());
7209 26 May 23 nicklas 1267         }
7209 26 May 23 nicklas 1268         if (dna != null)
7209 26 May 23 nicklas 1269         {
7209 26 May 23 nicklas 1270           dna.loadAnnotations(dc, manager, "BeadChipPosition", Annotationtype.BEADCHIP_POSITION, null);
7209 26 May 23 nicklas 1271           gtc.setAnnotation("dna", dna.asJSONObject());
7209 26 May 23 nicklas 1272         }
7209 26 May 23 nicklas 1273         normal = gtc;
6590 21 Feb 22 nicklas 1274       }
7209 26 May 23 nicklas 1275       else if (pipeline == Pipeline.DNA_NORMAL_WGS)
6590 21 Feb 22 nicklas 1276       {
7209 26 May 23 nicklas 1277         aligned = AlignedSequences.get(dba);
7209 26 May 23 nicklas 1278         Library lib = aligned.getLibrary(dc);
7209 26 May 23 nicklas 1279         if (lib != null)
7209 26 May 23 nicklas 1280         {
7209 26 May 23 nicklas 1281           // NOTE! By loading the BLOOD we will get the top-most BLOOD_DNA item
7209 26 May 23 nicklas 1282           Map<Subtype, BioMaterial> parents = lib.findParentBioMaterial(dc, Subtype.BLOOD_DNA, Subtype.BLOOD);
7209 26 May 23 nicklas 1283           BloodDna dna = BloodDna.get((Extract)parents.get(Subtype.BLOOD_DNA));
7209 26 May 23 nicklas 1284           if (dna != null)
7209 26 May 23 nicklas 1285           {
7209 26 May 23 nicklas 1286             dna.loadBioPlateLocation();
7209 26 May 23 nicklas 1287             aligned.setAnnotation("dna", dna.asJSONObject());
7209 26 May 23 nicklas 1288           }
7209 26 May 23 nicklas 1289         }
7209 26 May 23 nicklas 1290         
7209 26 May 23 nicklas 1291         normal = aligned;
6590 21 Feb 22 nicklas 1292       }
7209 26 May 23 nicklas 1293       normal.loadAnnotations(dc, manager, "PIPELINE", Annotationtype.PIPELINE, null);
7209 26 May 23 nicklas 1294       normal.loadAnnotations(dc, manager, "QC_GENOTYPE_STATUS", Annotationtype.QC_GENOTYPE_STATUS, null);
7209 26 May 23 nicklas 1295       normal.loadAnnotations(dc, manager, "QC_GENOTYPE_HET_PCT", Annotationtype.QC_GENOTYPE_HET_PCT, null);
7209 26 May 23 nicklas 1296       normal.loadAnnotations(dc, manager, "QC_GENOTYPE_VERIFIED", Annotationtype.QC_GENOTYPE_VERIFIED, null);
7209 26 May 23 nicklas 1297       normal.loadAnnotations(dc, manager, "QC_GENOTYPE_COMMENT", Annotationtype.QC_GENOTYPE_COMMENT, null);
7209 26 May 23 nicklas 1298       normal.loadDoNotUseAnnotations(dc, manager);
6590 21 Feb 22 nicklas 1299       
7209 26 May 23 nicklas 1300       SpecimenData pat = checker.getSpecimenData(normal.getItem());
6589 21 Feb 22 nicklas 1301       if (pat != null) // Can be null if the item is an external library
6589 21 Feb 22 nicklas 1302       {
7209 26 May 23 nicklas 1303         normal.setAnnotation("specimen", pat.asJSONObject());
6589 21 Feb 22 nicklas 1304       }
7209 26 May 23 nicklas 1305       jsonNormals.add(normal.asJSONObject());
6589 21 Feb 22 nicklas 1306     }
6589 21 Feb 22 nicklas 1307     
6589 21 Feb 22 nicklas 1308     // Check the alignments agains all pre-loaded genotypes
6589 21 Feb 22 nicklas 1309     for (AlignedSequences as : toCheck)
6589 21 Feb 22 nicklas 1310     {
6589 21 Feb 22 nicklas 1311       CompareData cmp = checker.check(dc, as.getItem());
6589 21 Feb 22 nicklas 1312       cmp.sortMessages(GenoTypeMessage.SORT_BY_CATEGORY_AND_ASSAY);
6589 21 Feb 22 nicklas 1313       JSONObject jsonCompare = cmp.asJSONObject();
6589 21 Feb 22 nicklas 1314       as.setAnnotation("compare", jsonCompare);
6589 21 Feb 22 nicklas 1315     }
6589 21 Feb 22 nicklas 1316     
7209 26 May 23 nicklas 1317     json.put("tumors", jsonTumors);
7209 26 May 23 nicklas 1318     json.put("normals", jsonNormals);
4970 13 Sep 18 nicklas 1319   }
4970 13 Sep 18 nicklas 1320   
7216 30 May 23 nicklas 1321   private List<AnnotatedItem> getAllChildItems(DbControl dc, BioMaterial item)
4975 21 Sep 18 nicklas 1322   {
7216 30 May 23 nicklas 1323     List<AnnotatedItem> allItems = new ArrayList<>();
4975 21 Sep 18 nicklas 1324     allItems.add(item);
4975 21 Sep 18 nicklas 1325     
4975 21 Sep 18 nicklas 1326     Restriction byName = Restrictions.like(Hql.property("name"), Expressions.string(item.getName()+".%"));
4975 21 Sep 18 nicklas 1327     
5003 04 Oct 18 nicklas 1328     // Find child samples if the item is a sample (eg. specimen)
5003 04 Oct 18 nicklas 1329     if (item.getType() == Item.SAMPLE)
5003 04 Oct 18 nicklas 1330     {
5003 04 Oct 18 nicklas 1331       ItemQuery<Sample> sampleQuery = Sample.getQuery();
5003 04 Oct 18 nicklas 1332       sampleQuery.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
5003 04 Oct 18 nicklas 1333       sampleQuery.restrict(byName);
5003 04 Oct 18 nicklas 1334       allItems.addAll(sampleQuery.list(dc));
5003 04 Oct 18 nicklas 1335     }
5003 04 Oct 18 nicklas 1336     
4975 21 Sep 18 nicklas 1337     // Find child extracts
4975 21 Sep 18 nicklas 1338     ItemQuery<Extract> extractQuery = Extract.getQuery();
4975 21 Sep 18 nicklas 1339     extractQuery.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
4975 21 Sep 18 nicklas 1340     extractQuery.restrict(byName);
4975 21 Sep 18 nicklas 1341     allItems.addAll(extractQuery.list(dc));
4975 21 Sep 18 nicklas 1342     
4975 21 Sep 18 nicklas 1343     // Find child derived bioassays
4975 21 Sep 18 nicklas 1344     ItemQuery<DerivedBioAssay> dbaQuery = DerivedBioAssay.getQuery();
4975 21 Sep 18 nicklas 1345     dbaQuery.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
4975 21 Sep 18 nicklas 1346     dbaQuery.restrict(byName);
4975 21 Sep 18 nicklas 1347     allItems.addAll(dbaQuery.list(dc));
4975 21 Sep 18 nicklas 1348     
4975 21 Sep 18 nicklas 1349     // Find child raw bioassays
4975 21 Sep 18 nicklas 1350     ItemQuery<RawBioAssay> rawQuery = RawBioAssay.getQuery();
4975 21 Sep 18 nicklas 1351     rawQuery.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT);
4975 21 Sep 18 nicklas 1352     rawQuery.restrict(byName);
4975 21 Sep 18 nicklas 1353     allItems.addAll(rawQuery.list(dc));
4975 21 Sep 18 nicklas 1354     
4975 21 Sep 18 nicklas 1355     return allItems;
4975 21 Sep 18 nicklas 1356   }
4975 21 Sep 18 nicklas 1357
4977 24 Sep 18 nicklas 1358   private String countMessage(int count, String one, String more)
4977 24 Sep 18 nicklas 1359   {
4977 24 Sep 18 nicklas 1360     return count + " " + (count > 1 ? more : one);
4977 24 Sep 18 nicklas 1361   }
4977 24 Sep 18 nicklas 1362   
7212 29 May 23 nicklas 1363   /**
7212 29 May 23 nicklas 1364     Implementation for comparing genotypes between a given list of
7212 29 May 23 nicklas 1365     alignments and the preloaded set. Multiple threads may be started
7212 29 May 23 nicklas 1366     using the same genotype checker and queue of items. The implementation
7212 29 May 23 nicklas 1367     will continue until the queue is empty.
7212 29 May 23 nicklas 1368   */
7212 29 May 23 nicklas 1369   static class RunnableGenotypeComparator
7212 29 May 23 nicklas 1370     implements Callable<List<JSONObject>>
7212 29 May 23 nicklas 1371   {
7212 29 May 23 nicklas 1372     
7212 29 May 23 nicklas 1373     private final SessionControl sc;
7212 29 May 23 nicklas 1374     private final GenoTypeChecker checker;
7212 29 May 23 nicklas 1375     private final Queue<Integer> toProcess;
7212 29 May 23 nicklas 1376     
7212 29 May 23 nicklas 1377     RunnableGenotypeComparator(SessionControl sc, GenoTypeChecker checker, Queue<Integer> toProcess)
7212 29 May 23 nicklas 1378     {
7212 29 May 23 nicklas 1379       this.sc = sc;
7212 29 May 23 nicklas 1380       this.checker = checker;
7212 29 May 23 nicklas 1381       this.toProcess = toProcess;
7212 29 May 23 nicklas 1382     }
7212 29 May 23 nicklas 1383
7212 29 May 23 nicklas 1384     @Override
7212 29 May 23 nicklas 1385     public List<JSONObject> call() 
7212 29 May 23 nicklas 1386       throws Exception
7212 29 May 23 nicklas 1387     {
7212 29 May 23 nicklas 1388       DbControl dc = null;
7212 29 May 23 nicklas 1389       List<JSONObject> json = new ArrayList<>();
7212 29 May 23 nicklas 1390       try
7212 29 May 23 nicklas 1391       {
7212 29 May 23 nicklas 1392         dc = sc.newDbControl();
7212 29 May 23 nicklas 1393         while (true)
7212 29 May 23 nicklas 1394         {
7212 29 May 23 nicklas 1395           Integer alignId = toProcess.poll();
7212 29 May 23 nicklas 1396           if (alignId == null) break; // No more items to process
7212 29 May 23 nicklas 1397
7212 29 May 23 nicklas 1398           AlignedSequences aligned = AlignedSequences.getById(dc, alignId.intValue());          
7212 29 May 23 nicklas 1399           Pipeline pipeline = Pipeline.getByName((String)Annotationtype.PIPELINE.getAnnotationValue(dc, aligned.getItem()));
7212 29 May 23 nicklas 1400           aligned.setAnnotation("pipeline", pipeline.getName());
7212 29 May 23 nicklas 1401           aligned.loadAnnotations(dc, "ALIGNED_PAIRS", Annotationtype.ALIGNED_PAIRS, null);
7212 29 May 23 nicklas 1402           aligned.loadAnnotations(dc, "FRACTION_DUPLICATION", Annotationtype.FRACTION_DUPLICATION, null);
7212 29 May 23 nicklas 1403           aligned.loadAnnotations(dc, "QC_GENOTYPE_COMMENT", Annotationtype.QC_GENOTYPE_COMMENT, null);
7212 29 May 23 nicklas 1404           Library lib = aligned.getLibrary(dc);
7212 29 May 23 nicklas 1405           if (pipeline == Pipeline.DNA_NORMAL_WGS)
7212 29 May 23 nicklas 1406           {
7212 29 May 23 nicklas 1407             // NOTE! By loading the BLOOD we will get the top-most BLOOD_DNA item
7212 29 May 23 nicklas 1408             Map<Subtype, BioMaterial> parents = lib.findParentBioMaterial(dc, Subtype.BLOOD_DNA, Subtype.BLOOD);
7212 29 May 23 nicklas 1409             BloodDna dna = BloodDna.get((Extract)parents.get(Subtype.BLOOD_DNA));
7212 29 May 23 nicklas 1410             if (dna != null)
7212 29 May 23 nicklas 1411             {
7212 29 May 23 nicklas 1412               aligned.setAnnotation("bioWell", JsonUtil.getBioWellAsJSON(dna.getItem().getBioWell(), true));
7212 29 May 23 nicklas 1413               aligned.setAnnotation("dna", dna.asJSONObject());
7212 29 May 23 nicklas 1414             }
7212 29 May 23 nicklas 1415           }
7212 29 May 23 nicklas 1416           else
7212 29 May 23 nicklas 1417           {
7212 29 May 23 nicklas 1418             aligned.setAnnotation("bioWell", JsonUtil.getBioWellAsJSON(lib.getItem().getBioWell(), true));
7212 29 May 23 nicklas 1419           }
7212 29 May 23 nicklas 1420           aligned.setAnnotation("lib", lib.asJSONObject());
7212 29 May 23 nicklas 1421           
7212 29 May 23 nicklas 1422           CompareData cmp = checker.check(dc, aligned.getItem());
7212 29 May 23 nicklas 1423           cmp.sortMessages(GenoTypeMessage.SORT_BY_CATEGORY_AND_ASSAY);
7212 29 May 23 nicklas 1424           aligned.setAnnotation("compare", cmp.asJSONObject());
7212 29 May 23 nicklas 1425           json.add(aligned.asJSONObject());
7212 29 May 23 nicklas 1426         }
7212 29 May 23 nicklas 1427       }
7212 29 May 23 nicklas 1428       catch (RuntimeException ex)
7212 29 May 23 nicklas 1429       {
7212 29 May 23 nicklas 1430         // Force all other threads to quit if there is an exception
7212 29 May 23 nicklas 1431         toProcess.clear();
7212 29 May 23 nicklas 1432         throw ex;
7212 29 May 23 nicklas 1433       }
7212 29 May 23 nicklas 1434       finally
7212 29 May 23 nicklas 1435       {
7212 29 May 23 nicklas 1436         if (dc != null) dc.close();
7212 29 May 23 nicklas 1437       }
7212 29 May 23 nicklas 1438       return json;
7212 29 May 23 nicklas 1439     }
7212 29 May 23 nicklas 1440     
7212 29 May 23 nicklas 1441   }
7212 29 May 23 nicklas 1442   
4642 28 Nov 17 nicklas 1443 }