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 |
//FOR DEBUGGING |
4649 |
20 Dec 17 |
nicklas |
dc = sc.newDbControl(); |
4671 |
07 Feb 18 |
nicklas |
resetQCStatus(dc); |
4649 |
20 Dec 17 |
nicklas |
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 |
// 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 |
// 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 |
// 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 |
// 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 |
// 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 |
// DEBUG!!! |
5547 |
07 Aug 19 |
nicklas |
// 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 |
// 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 |
//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 |
// 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 |
// 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 |
// 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 |
// 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 |
// 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 |
// 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 |
// 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 |
//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 |
// 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 |
// 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 |
// 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 |
// 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 |
// 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 |
// 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 |
// 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 |
// 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 |
// 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 |
// 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 |
// 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 |
// 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 |
// 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 |
// 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 |
// 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 |
// Handles related (flagged alignments) that may no longer see any genotype errors after |
4975 |
21 Sep 18 |
nicklas |
// 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 |
//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 |
// 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 |
Reset and clear all QC_GENOTYPE_STATUS annotations. |
4649 |
20 Dec 17 |
nicklas |
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 |
// 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 |
// 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 |
// 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 |
// When we have a filter we want to load information about all items on the |
4970 |
13 Sep 18 |
nicklas |
// given QiaCube/LibPlate. We fill this Set with all RNA/Library items and then |
4970 |
13 Sep 18 |
nicklas |
// 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 |
// 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 |
// 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 |
// Only include "Checked" alignments in genotyping |
6589 |
21 Feb 22 |
nicklas |
// 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 |
// 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 |
// 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 |
// Load genotype calls that are related to the same patients as the alignments that |
6589 |
21 Feb 22 |
nicklas |
// 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 |
// 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 |
// 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 |
// 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 |
// 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 |
// 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 |
// 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 |
Implementation for comparing genotypes between a given list of |
7212 |
29 May 23 |
nicklas |
alignments and the preloaded set. Multiple threads may be started |
7212 |
29 May 23 |
nicklas |
using the same genotype checker and queue of items. The implementation |
7212 |
29 May 23 |
nicklas |
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 |
// 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 |
// 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 |
} |