4477 |
03 May 17 |
nicklas |
1 |
package net.sf.basedb.reggie.servlet; |
4477 |
03 May 17 |
nicklas |
2 |
|
4477 |
03 May 17 |
nicklas |
3 |
import java.io.IOException; |
6098 |
11 Jan 21 |
nicklas |
4 |
import java.time.Instant; |
6098 |
11 Jan 21 |
nicklas |
5 |
import java.time.LocalDateTime; |
6098 |
11 Jan 21 |
nicklas |
6 |
import java.time.ZoneId; |
6098 |
11 Jan 21 |
nicklas |
7 |
import java.time.temporal.ChronoUnit; |
4477 |
03 May 17 |
nicklas |
8 |
import java.util.Date; |
4477 |
03 May 17 |
nicklas |
9 |
import java.util.HashMap; |
4701 |
16 Mar 18 |
nicklas |
10 |
import java.util.HashSet; |
4477 |
03 May 17 |
nicklas |
11 |
import java.util.Iterator; |
4477 |
03 May 17 |
nicklas |
12 |
import java.util.Map; |
4701 |
16 Mar 18 |
nicklas |
13 |
import java.util.Set; |
4477 |
03 May 17 |
nicklas |
14 |
|
4477 |
03 May 17 |
nicklas |
15 |
import javax.servlet.ServletException; |
4477 |
03 May 17 |
nicklas |
16 |
import javax.servlet.http.HttpServlet; |
4477 |
03 May 17 |
nicklas |
17 |
import javax.servlet.http.HttpServletRequest; |
4477 |
03 May 17 |
nicklas |
18 |
import javax.servlet.http.HttpServletResponse; |
4477 |
03 May 17 |
nicklas |
19 |
|
4477 |
03 May 17 |
nicklas |
20 |
import org.json.simple.JSONArray; |
4477 |
03 May 17 |
nicklas |
21 |
import org.json.simple.JSONObject; |
4477 |
03 May 17 |
nicklas |
22 |
|
6098 |
11 Jan 21 |
nicklas |
23 |
import net.sf.basedb.core.BioSource; |
4477 |
03 May 17 |
nicklas |
24 |
import net.sf.basedb.core.DbControl; |
4477 |
03 May 17 |
nicklas |
25 |
import net.sf.basedb.core.Item; |
4477 |
03 May 17 |
nicklas |
26 |
import net.sf.basedb.core.ItemQuery; |
4477 |
03 May 17 |
nicklas |
27 |
import net.sf.basedb.core.Sample; |
4477 |
03 May 17 |
nicklas |
28 |
import net.sf.basedb.core.SessionControl; |
4477 |
03 May 17 |
nicklas |
29 |
import net.sf.basedb.core.SimpleProgressReporter; |
4701 |
16 Mar 18 |
nicklas |
30 |
import net.sf.basedb.core.query.Annotations; |
4701 |
16 Mar 18 |
nicklas |
31 |
import net.sf.basedb.core.query.Expressions; |
4477 |
03 May 17 |
nicklas |
32 |
import net.sf.basedb.core.query.Hql; |
4477 |
03 May 17 |
nicklas |
33 |
import net.sf.basedb.core.query.Orders; |
4477 |
03 May 17 |
nicklas |
34 |
import net.sf.basedb.core.query.Restrictions; |
4477 |
03 May 17 |
nicklas |
35 |
import net.sf.basedb.core.snapshot.SnapshotManager; |
4477 |
03 May 17 |
nicklas |
36 |
import net.sf.basedb.reggie.JsonUtil; |
4477 |
03 May 17 |
nicklas |
37 |
import net.sf.basedb.reggie.Reggie; |
4477 |
03 May 17 |
nicklas |
38 |
import net.sf.basedb.reggie.counter.CounterService; |
4477 |
03 May 17 |
nicklas |
39 |
import net.sf.basedb.reggie.dao.Annotationtype; |
4477 |
03 May 17 |
nicklas |
40 |
import net.sf.basedb.reggie.dao.ReferenceDateSource; |
4477 |
03 May 17 |
nicklas |
41 |
import net.sf.basedb.reggie.dao.ReferenceDateWithSource; |
4477 |
03 May 17 |
nicklas |
42 |
import net.sf.basedb.reggie.dao.ReggieRole; |
4477 |
03 May 17 |
nicklas |
43 |
import net.sf.basedb.reggie.dao.Subtype; |
4477 |
03 May 17 |
nicklas |
44 |
import net.sf.basedb.util.error.ThrowableUtil; |
4477 |
03 May 17 |
nicklas |
45 |
|
4477 |
03 May 17 |
nicklas |
46 |
|
4477 |
03 May 17 |
nicklas |
47 |
public class ReferenceDateServlet |
4477 |
03 May 17 |
nicklas |
48 |
extends HttpServlet |
4477 |
03 May 17 |
nicklas |
49 |
{ |
4477 |
03 May 17 |
nicklas |
50 |
|
4477 |
03 May 17 |
nicklas |
51 |
private static final long serialVersionUID = 8047423138847961359L; |
4477 |
03 May 17 |
nicklas |
52 |
|
4477 |
03 May 17 |
nicklas |
53 |
public ReferenceDateServlet() |
4477 |
03 May 17 |
nicklas |
54 |
{} |
4477 |
03 May 17 |
nicklas |
55 |
|
4477 |
03 May 17 |
nicklas |
56 |
@Override |
4477 |
03 May 17 |
nicklas |
57 |
protected void doGet(HttpServletRequest req, HttpServletResponse resp) |
4477 |
03 May 17 |
nicklas |
58 |
throws ServletException, IOException |
4477 |
03 May 17 |
nicklas |
59 |
{ |
4477 |
03 May 17 |
nicklas |
60 |
String cmd = req.getParameter("cmd"); |
4477 |
03 May 17 |
nicklas |
61 |
JsonUtil.setJsonResponseHeaders(resp); |
4477 |
03 May 17 |
nicklas |
62 |
|
4477 |
03 May 17 |
nicklas |
63 |
JSONObject json = new JSONObject(); |
4477 |
03 May 17 |
nicklas |
64 |
json.put("status", "ok"); |
4477 |
03 May 17 |
nicklas |
65 |
|
4477 |
03 May 17 |
nicklas |
66 |
final SessionControl sc = Reggie.getSessionControl(req); |
4477 |
03 May 17 |
nicklas |
67 |
DbControl dc = null; |
4477 |
03 May 17 |
nicklas |
68 |
try |
4477 |
03 May 17 |
nicklas |
69 |
{ |
4477 |
03 May 17 |
nicklas |
70 |
|
4477 |
03 May 17 |
nicklas |
71 |
} |
4477 |
03 May 17 |
nicklas |
72 |
catch (Throwable t) |
4477 |
03 May 17 |
nicklas |
73 |
{ |
4477 |
03 May 17 |
nicklas |
74 |
t.printStackTrace(); |
4477 |
03 May 17 |
nicklas |
75 |
json.clear(); |
4477 |
03 May 17 |
nicklas |
76 |
json.put("status", "error"); |
4477 |
03 May 17 |
nicklas |
77 |
json.put("message", t.getMessage()); |
4477 |
03 May 17 |
nicklas |
78 |
json.put("stacktrace", ThrowableUtil.stackTraceToString(t)); |
4477 |
03 May 17 |
nicklas |
79 |
} |
4477 |
03 May 17 |
nicklas |
80 |
finally |
4477 |
03 May 17 |
nicklas |
81 |
{ |
4477 |
03 May 17 |
nicklas |
82 |
if (dc != null) dc.close(); |
4477 |
03 May 17 |
nicklas |
83 |
json.writeJSONString(resp.getWriter()); |
4477 |
03 May 17 |
nicklas |
84 |
} |
4477 |
03 May 17 |
nicklas |
85 |
|
4477 |
03 May 17 |
nicklas |
86 |
|
4477 |
03 May 17 |
nicklas |
87 |
} |
4477 |
03 May 17 |
nicklas |
88 |
|
4477 |
03 May 17 |
nicklas |
89 |
@Override |
4477 |
03 May 17 |
nicklas |
90 |
protected void doPost(HttpServletRequest req, HttpServletResponse resp) |
4477 |
03 May 17 |
nicklas |
91 |
throws ServletException, IOException |
4477 |
03 May 17 |
nicklas |
92 |
{ |
4477 |
03 May 17 |
nicklas |
93 |
String cmd = req.getParameter("cmd"); |
4477 |
03 May 17 |
nicklas |
94 |
JsonUtil.setJsonResponseHeaders(resp); |
4477 |
03 May 17 |
nicklas |
95 |
|
4477 |
03 May 17 |
nicklas |
96 |
JSONObject json = new JSONObject(); |
4477 |
03 May 17 |
nicklas |
97 |
json.put("status", "ok"); |
4477 |
03 May 17 |
nicklas |
98 |
|
4477 |
03 May 17 |
nicklas |
99 |
JSONArray jsonMessages = new JSONArray(); |
4477 |
03 May 17 |
nicklas |
100 |
|
4477 |
03 May 17 |
nicklas |
101 |
final SessionControl sc = Reggie.getSessionControl(req); |
4477 |
03 May 17 |
nicklas |
102 |
DbControl dc = null; |
4477 |
03 May 17 |
nicklas |
103 |
try |
4477 |
03 May 17 |
nicklas |
104 |
{ |
4477 |
03 May 17 |
nicklas |
105 |
if ("UpdateAllReferenceDateAnnotations".equals(cmd)) |
4477 |
03 May 17 |
nicklas |
106 |
{ |
6336 |
16 Jun 21 |
nicklas |
107 |
dc = sc.newDbControl(":Reference date wizard"); |
4477 |
03 May 17 |
nicklas |
108 |
|
4477 |
03 May 17 |
nicklas |
109 |
ReggieRole.checkPermission(dc, "'" + cmd + "' wizard", ReggieRole.PREP_CURATOR, ReggieRole.ADMINISTRATOR); |
4477 |
03 May 17 |
nicklas |
110 |
|
4477 |
03 May 17 |
nicklas |
111 |
SimpleProgressReporter progress = new SimpleProgressReporter(null); |
4477 |
03 May 17 |
nicklas |
112 |
sc.setSessionSetting("ref-date-progress", progress); |
4477 |
03 May 17 |
nicklas |
113 |
progress.display(1, "Loading cases..."); |
4477 |
03 May 17 |
nicklas |
114 |
|
4477 |
03 May 17 |
nicklas |
115 |
SnapshotManager snapshot = new SnapshotManager(); |
4477 |
03 May 17 |
nicklas |
116 |
|
4477 |
03 May 17 |
nicklas |
// Initialize counters |
4477 |
03 May 17 |
nicklas |
118 |
int numUpdated = 0; |
4701 |
16 Mar 18 |
nicklas |
119 |
int numSkipped = 0; |
6098 |
11 Jan 21 |
nicklas |
120 |
int numLinkedCasesUpdated = 0; |
4477 |
03 May 17 |
nicklas |
121 |
Map<ReferenceDateSource, Counter> counters = new HashMap<ReferenceDateSource, Counter>(); |
4701 |
16 Mar 18 |
nicklas |
122 |
Counter incaDiagnosisDateCounter = new Counter(ReferenceDateSource.INCA_DIAGNOSIS_DATE); |
4477 |
03 May 17 |
nicklas |
123 |
counters.put(null, new Counter(null)); |
4701 |
16 Mar 18 |
nicklas |
124 |
counters.put(ReferenceDateSource.INCA_DIAGNOSIS_DATE, incaDiagnosisDateCounter); |
4701 |
16 Mar 18 |
nicklas |
125 |
counters.put(ReferenceDateSource.SAMPLING_DATE, new Counter(ReferenceDateSource.SAMPLING_DATE)); |
4701 |
16 Mar 18 |
nicklas |
126 |
counters.put(ReferenceDateSource.CONSENT_DATE, new Counter(ReferenceDateSource.CONSENT_DATE)); |
4701 |
16 Mar 18 |
nicklas |
127 |
counters.put(ReferenceDateSource.REGISTRATION_DATE, new Counter(ReferenceDateSource.REGISTRATION_DATE)); |
4477 |
03 May 17 |
nicklas |
128 |
|
4701 |
16 Mar 18 |
nicklas |
// Query to load all cases with ReferenceDateSource=IncaDiagnosisDate AND RefererenceDate=INCA2_a_diag_dat |
4701 |
16 Mar 18 |
nicklas |
// They are already correct and will not have to be checked furthur which should speed up the update process |
4701 |
16 Mar 18 |
nicklas |
131 |
ItemQuery<Sample> ccQuery = Sample.getQuery(); |
4701 |
16 Mar 18 |
nicklas |
132 |
ccQuery.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT); |
4701 |
16 Mar 18 |
nicklas |
133 |
Subtype.CASE.addFilter(dc, ccQuery); |
4701 |
16 Mar 18 |
nicklas |
134 |
ccQuery.join(Annotations.innerJoin(Annotationtype.REFERENCE_DATE_SOURCE.load(dc), "refs")); |
4701 |
16 Mar 18 |
nicklas |
135 |
ccQuery.join(Annotations.innerJoin(Annotationtype.INCA2_a_diag_dat.load(dc), "idat")); |
4701 |
16 Mar 18 |
nicklas |
136 |
ccQuery.join(Annotations.innerJoin(Annotationtype.REFERENCE_DATE.load(dc), "rdat")); |
4701 |
16 Mar 18 |
nicklas |
137 |
ccQuery.restrict(Restrictions.eq(Hql.alias("refs"), Expressions.string(ReferenceDateSource.INCA_DIAGNOSIS_DATE.getTitle()))); |
4701 |
16 Mar 18 |
nicklas |
138 |
ccQuery.restrict(Restrictions.eq(Hql.alias("idat"), Hql.alias("rdat"))); |
4701 |
16 Mar 18 |
nicklas |
139 |
|
4701 |
16 Mar 18 |
nicklas |
140 |
Set<Integer> okCases = new HashSet<>(ccQuery.idList(dc)); |
4701 |
16 Mar 18 |
nicklas |
141 |
|
4477 |
03 May 17 |
nicklas |
// Load all cases |
4477 |
03 May 17 |
nicklas |
143 |
ItemQuery<Sample> caseQuery = Sample.getQuery(); |
4477 |
03 May 17 |
nicklas |
144 |
caseQuery.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT); |
4477 |
03 May 17 |
nicklas |
145 |
Subtype.CASE.addFilter(dc, caseQuery); |
6098 |
11 Jan 21 |
nicklas |
// IMPORTANT!! Sort by patient so that we can calculate LinkedCase annotation easy |
6098 |
11 Jan 21 |
nicklas |
147 |
caseQuery.order(Orders.asc(Hql.property("parent.id"))); |
4477 |
03 May 17 |
nicklas |
148 |
|
6510 |
03 Dec 21 |
nicklas |
// Load all child Specimen/NoSpecimen with a known creation date |
4477 |
03 May 17 |
nicklas |
// IMPORTANT!! Sort by oldest first |
4477 |
03 May 17 |
nicklas |
151 |
ItemQuery<Sample> specimenQuery = Sample.getQuery(); |
4477 |
03 May 17 |
nicklas |
152 |
specimenQuery.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT); |
4477 |
03 May 17 |
nicklas |
153 |
specimenQuery.restrict( |
4477 |
03 May 17 |
nicklas |
154 |
Restrictions.or( |
4477 |
03 May 17 |
nicklas |
155 |
Subtype.SPECIMEN.restriction(dc, null), |
6510 |
03 Dec 21 |
nicklas |
156 |
Subtype.NO_SPECIMEN.restriction(dc, null) |
4477 |
03 May 17 |
nicklas |
157 |
)); |
4477 |
03 May 17 |
nicklas |
158 |
specimenQuery.join(Hql.innerJoin(null, "parent", "c", null, true)); |
4477 |
03 May 17 |
nicklas |
159 |
specimenQuery.join(Hql.innerJoin(null, "creationEvent", "ce", null, true)); |
4477 |
03 May 17 |
nicklas |
160 |
|
4477 |
03 May 17 |
nicklas |
161 |
specimenQuery.restrict(Restrictions.eq(Hql.alias("c"), Hql.entityParameter("c", Item.SAMPLE))); |
4477 |
03 May 17 |
nicklas |
162 |
|
4477 |
03 May 17 |
nicklas |
163 |
specimenQuery.restrict(Restrictions.neq(Hql.property("ce", "eventDate"), null)); |
4477 |
03 May 17 |
nicklas |
164 |
specimenQuery.order(Orders.asc(Hql.property("ce", "eventDate"))); |
4477 |
03 May 17 |
nicklas |
165 |
|
6098 |
11 Jan 21 |
nicklas |
// Keep track of last case and patient |
6098 |
11 Jan 21 |
nicklas |
167 |
Sample lastCase = null; |
6098 |
11 Jan 21 |
nicklas |
168 |
BioSource lastPatient = null; |
6440 |
11 Oct 21 |
nicklas |
169 |
ReferenceDateWithSource lastRefAfter = null; |
4477 |
03 May 17 |
nicklas |
170 |
long totalCount = caseQuery.count(dc); |
4477 |
03 May 17 |
nicklas |
171 |
long count = 0; |
4477 |
03 May 17 |
nicklas |
172 |
Iterator<Sample> it = caseQuery.iterate(dc); |
4477 |
03 May 17 |
nicklas |
173 |
while (it.hasNext()) |
4477 |
03 May 17 |
nicklas |
174 |
{ |
4477 |
03 May 17 |
nicklas |
175 |
if (count % 100 == 0) |
4477 |
03 May 17 |
nicklas |
176 |
{ |
6098 |
11 Jan 21 |
nicklas |
177 |
progress.display(5 + (int)((90 * count) / totalCount), count + " of " + totalCount + |
6098 |
11 Jan 21 |
nicklas |
178 |
" done (" + numUpdated + " reference dates and " + numLinkedCasesUpdated + " linked cases updated)"); |
4477 |
03 May 17 |
nicklas |
179 |
} |
4477 |
03 May 17 |
nicklas |
180 |
count++; |
4477 |
03 May 17 |
nicklas |
181 |
|
4477 |
03 May 17 |
nicklas |
182 |
Sample theCase = it.next(); |
6440 |
11 Oct 21 |
nicklas |
183 |
ReferenceDateWithSource refAfter = null; |
4701 |
16 Mar 18 |
nicklas |
184 |
if (okCases.contains(theCase.getId())) |
4477 |
03 May 17 |
nicklas |
185 |
{ |
4701 |
16 Mar 18 |
nicklas |
186 |
incaDiagnosisDateCounter.numBefore++; |
4701 |
16 Mar 18 |
nicklas |
187 |
incaDiagnosisDateCounter.numAfter++; |
4701 |
16 Mar 18 |
nicklas |
188 |
numSkipped++; |
4477 |
03 May 17 |
nicklas |
189 |
} |
4701 |
16 Mar 18 |
nicklas |
190 |
else |
4477 |
03 May 17 |
nicklas |
191 |
{ |
4477 |
03 May 17 |
nicklas |
192 |
|
4701 |
16 Mar 18 |
nicklas |
// Load the information that we already have |
4701 |
16 Mar 18 |
nicklas |
194 |
Date dateBefore = (Date)Annotationtype.REFERENCE_DATE.getAnnotationValue(dc, snapshot, theCase); |
4701 |
16 Mar 18 |
nicklas |
195 |
String sourceBefore = (String)Annotationtype.REFERENCE_DATE_SOURCE.getAnnotationValue(dc, snapshot, theCase); |
4701 |
16 Mar 18 |
nicklas |
196 |
ReferenceDateWithSource refBefore = null; |
4701 |
16 Mar 18 |
nicklas |
197 |
if (dateBefore != null && sourceBefore != null) |
4477 |
03 May 17 |
nicklas |
198 |
{ |
4701 |
16 Mar 18 |
nicklas |
199 |
refBefore = new ReferenceDateWithSource(dateBefore, ReferenceDateSource.fromTitle(sourceBefore)); |
4477 |
03 May 17 |
nicklas |
200 |
} |
4701 |
16 Mar 18 |
nicklas |
201 |
|
4701 |
16 Mar 18 |
nicklas |
// Check for INCA diagnosis date |
4701 |
16 Mar 18 |
nicklas |
203 |
Date incaDiaDate = (Date)Annotationtype.INCA2_a_diag_dat.getAnnotationValue(dc, snapshot, theCase); |
4701 |
16 Mar 18 |
nicklas |
204 |
if (incaDiaDate != null) |
4477 |
03 May 17 |
nicklas |
205 |
{ |
4701 |
16 Mar 18 |
nicklas |
206 |
refAfter = new ReferenceDateWithSource(incaDiaDate, ReferenceDateSource.INCA_DIAGNOSIS_DATE); |
4477 |
03 May 17 |
nicklas |
207 |
} |
4701 |
16 Mar 18 |
nicklas |
208 |
|
4701 |
16 Mar 18 |
nicklas |
// Check for sampling date of Specimen/NoSpecimen |
4701 |
16 Mar 18 |
nicklas |
210 |
if (refAfter == null) |
4701 |
16 Mar 18 |
nicklas |
211 |
{ |
4701 |
16 Mar 18 |
nicklas |
212 |
specimenQuery.setEntityParameter("c", theCase); |
4701 |
16 Mar 18 |
nicklas |
213 |
Iterator<Sample> it2 = specimenQuery.iterate(dc); |
4701 |
16 Mar 18 |
nicklas |
214 |
if (it2.hasNext()) |
4701 |
16 Mar 18 |
nicklas |
215 |
{ |
4701 |
16 Mar 18 |
nicklas |
216 |
Sample specimen = it2.next(); |
4701 |
16 Mar 18 |
nicklas |
217 |
refAfter = new ReferenceDateWithSource(specimen.getCreationEvent().getEventDate(), ReferenceDateSource.SAMPLING_DATE); |
4701 |
16 Mar 18 |
nicklas |
218 |
} |
4701 |
16 Mar 18 |
nicklas |
219 |
} |
4701 |
16 Mar 18 |
nicklas |
220 |
|
4701 |
16 Mar 18 |
nicklas |
// Check for consent date |
4701 |
16 Mar 18 |
nicklas |
222 |
if (refAfter == null) |
4701 |
16 Mar 18 |
nicklas |
223 |
{ |
4701 |
16 Mar 18 |
nicklas |
224 |
Date consentDate = (Date)Annotationtype.CONSENT_DATE.getAnnotationValue(dc, snapshot, theCase); |
4701 |
16 Mar 18 |
nicklas |
225 |
if (consentDate != null) |
4701 |
16 Mar 18 |
nicklas |
226 |
{ |
4701 |
16 Mar 18 |
nicklas |
227 |
refAfter = new ReferenceDateWithSource(consentDate, ReferenceDateSource.CONSENT_DATE); |
4701 |
16 Mar 18 |
nicklas |
228 |
} |
4701 |
16 Mar 18 |
nicklas |
229 |
} |
4701 |
16 Mar 18 |
nicklas |
230 |
|
4701 |
16 Mar 18 |
nicklas |
// We always have a registration date |
4701 |
16 Mar 18 |
nicklas |
232 |
if (refAfter == null) |
4701 |
16 Mar 18 |
nicklas |
233 |
{ |
4701 |
16 Mar 18 |
nicklas |
234 |
refAfter = new ReferenceDateWithSource(theCase.getEntryDate(), ReferenceDateSource.REGISTRATION_DATE); |
4701 |
16 Mar 18 |
nicklas |
235 |
} |
4701 |
16 Mar 18 |
nicklas |
236 |
|
4701 |
16 Mar 18 |
nicklas |
// Update counter and the annotation if needed |
4701 |
16 Mar 18 |
nicklas |
238 |
Counter counter = counters.get(refBefore == null ? null : refBefore.getSource()); |
4701 |
16 Mar 18 |
nicklas |
239 |
if (counter != null) counter.numBefore++; |
4477 |
03 May 17 |
nicklas |
240 |
|
4701 |
16 Mar 18 |
nicklas |
241 |
counter = counters.get(refAfter.getSource()); |
4701 |
16 Mar 18 |
nicklas |
242 |
if (counter != null) counter.numAfter++; |
4701 |
16 Mar 18 |
nicklas |
243 |
if (!refAfter.equals(refBefore)) |
4701 |
16 Mar 18 |
nicklas |
244 |
{ |
4701 |
16 Mar 18 |
nicklas |
245 |
refAfter.updateAnnotations(dc, theCase); |
4701 |
16 Mar 18 |
nicklas |
246 |
numUpdated++; |
4701 |
16 Mar 18 |
nicklas |
247 |
} |
4477 |
03 May 17 |
nicklas |
248 |
} |
6098 |
11 Jan 21 |
nicklas |
249 |
|
6098 |
11 Jan 21 |
nicklas |
// Update LinkedCase if there is a second case for the same patient |
6098 |
11 Jan 21 |
nicklas |
251 |
BioSource patient = (BioSource)theCase.getParent(); |
6440 |
11 Oct 21 |
nicklas |
252 |
if (patient != null && patient.equals(lastPatient)) |
6098 |
11 Jan 21 |
nicklas |
253 |
{ |
6098 |
11 Jan 21 |
nicklas |
// We have a patient with two case -- calculate and update LinkedSpecimen |
6440 |
11 Oct 21 |
nicklas |
255 |
Date thisDate = refAfter == null ? (Date)Annotationtype.REFERENCE_DATE.getAnnotationValue(dc, snapshot, theCase) : refAfter.getDate(); |
6440 |
11 Oct 21 |
nicklas |
256 |
Date otherDate = lastRefAfter == null ? (Date)Annotationtype.REFERENCE_DATE.getAnnotationValue(dc, snapshot, lastCase) : lastRefAfter.getDate(); |
6098 |
11 Jan 21 |
nicklas |
257 |
|
6440 |
11 Oct 21 |
nicklas |
// The dates SHOULD never be null, but just in case... |
6440 |
11 Oct 21 |
nicklas |
259 |
if (thisDate != null && otherDate != null) |
6440 |
11 Oct 21 |
nicklas |
260 |
{ |
6440 |
11 Oct 21 |
nicklas |
261 |
LocalDateTime thisDay = LocalDateTime.ofInstant(Instant.ofEpochMilli(thisDate.getTime()), ZoneId.systemDefault()); |
6440 |
11 Oct 21 |
nicklas |
262 |
LocalDateTime otherDay = LocalDateTime.ofInstant(Instant.ofEpochMilli(otherDate.getTime()), ZoneId.systemDefault()); |
6440 |
11 Oct 21 |
nicklas |
263 |
|
6440 |
11 Oct 21 |
nicklas |
264 |
int daysBetween = (int)ChronoUnit.DAYS.between(thisDay, otherDay); |
6440 |
11 Oct 21 |
nicklas |
265 |
if (Annotationtype.LINKED_CASE.setAnnotationValue(dc, theCase, daysBetween)) numLinkedCasesUpdated++; |
6440 |
11 Oct 21 |
nicklas |
266 |
if (Annotationtype.LINKED_CASE.setAnnotationValue(dc, lastCase, -daysBetween)) numLinkedCasesUpdated++; |
6440 |
11 Oct 21 |
nicklas |
267 |
} |
6098 |
11 Jan 21 |
nicklas |
268 |
lastCase = null; |
6098 |
11 Jan 21 |
nicklas |
269 |
lastPatient = null; |
6440 |
11 Oct 21 |
nicklas |
270 |
lastRefAfter = null; |
6098 |
11 Jan 21 |
nicklas |
271 |
} |
6098 |
11 Jan 21 |
nicklas |
272 |
else |
6098 |
11 Jan 21 |
nicklas |
273 |
{ |
6098 |
11 Jan 21 |
nicklas |
// The last case was a patient with a single case -- clear the LinkedSpecimen annotation |
6440 |
11 Oct 21 |
nicklas |
275 |
if (lastCase != null) |
6440 |
11 Oct 21 |
nicklas |
276 |
{ |
6440 |
11 Oct 21 |
nicklas |
277 |
if (Annotationtype.LINKED_CASE.setAnnotationValue(dc, lastCase, null)) numLinkedCasesUpdated++; |
6440 |
11 Oct 21 |
nicklas |
278 |
} |
6098 |
11 Jan 21 |
nicklas |
279 |
lastCase = theCase; |
6098 |
11 Jan 21 |
nicklas |
280 |
lastPatient = patient; |
6440 |
11 Oct 21 |
nicklas |
281 |
lastRefAfter = refAfter; |
6098 |
11 Jan 21 |
nicklas |
282 |
} |
4477 |
03 May 17 |
nicklas |
283 |
} |
4477 |
03 May 17 |
nicklas |
284 |
|
6098 |
11 Jan 21 |
nicklas |
285 |
if (lastCase != null) |
6098 |
11 Jan 21 |
nicklas |
286 |
{ |
6098 |
11 Jan 21 |
nicklas |
// The last case was a patient with a single case -- clear the LinkedSpecimen annotation |
6098 |
11 Jan 21 |
nicklas |
288 |
if (Annotationtype.LINKED_CASE.setAnnotationValue(dc, lastCase, null)) numLinkedCasesUpdated++; |
6098 |
11 Jan 21 |
nicklas |
289 |
} |
6098 |
11 Jan 21 |
nicklas |
290 |
|
6098 |
11 Jan 21 |
nicklas |
291 |
progress.display(98, count + " of " + totalCount + " done (" + numUpdated + " reference dates and " + |
6098 |
11 Jan 21 |
nicklas |
292 |
numLinkedCasesUpdated + " linked cases updated). Saving to database..."); |
4477 |
03 May 17 |
nicklas |
293 |
|
4477 |
03 May 17 |
nicklas |
294 |
JSONArray jsonCounters = new JSONArray(); |
4477 |
03 May 17 |
nicklas |
295 |
for (Counter c : counters.values()) |
4477 |
03 May 17 |
nicklas |
296 |
{ |
4477 |
03 May 17 |
nicklas |
297 |
JSONObject jsonCount = new JSONObject(); |
4701 |
16 Mar 18 |
nicklas |
298 |
jsonCount.put("name", c.refSource == null ? null : c.refSource.getTitle()); |
4477 |
03 May 17 |
nicklas |
299 |
jsonCount.put("before", c.numBefore); |
4477 |
03 May 17 |
nicklas |
300 |
jsonCount.put("after", c.numAfter); |
4477 |
03 May 17 |
nicklas |
301 |
jsonCounters.add(jsonCount); |
4477 |
03 May 17 |
nicklas |
302 |
} |
4477 |
03 May 17 |
nicklas |
303 |
json.put("counters", jsonCounters); |
6098 |
11 Jan 21 |
nicklas |
304 |
jsonMessages.add("Number of updated reference dates: " + numUpdated); |
6098 |
11 Jan 21 |
nicklas |
305 |
jsonMessages.add("Number of updated linked cases: " + numLinkedCasesUpdated); |
4477 |
03 May 17 |
nicklas |
306 |
json.put("numUpdated", numUpdated); |
6098 |
11 Jan 21 |
nicklas |
307 |
json.put("numLinkedCasesUpdated", numLinkedCasesUpdated); |
4477 |
03 May 17 |
nicklas |
308 |
|
4477 |
03 May 17 |
nicklas |
309 |
dc.commit(); |
4477 |
03 May 17 |
nicklas |
310 |
json.put("messages", jsonMessages); |
4477 |
03 May 17 |
nicklas |
311 |
} |
4477 |
03 May 17 |
nicklas |
312 |
|
4477 |
03 May 17 |
nicklas |
313 |
|
4477 |
03 May 17 |
nicklas |
314 |
CounterService.getInstance().setForceCount(); |
4477 |
03 May 17 |
nicklas |
315 |
} |
4477 |
03 May 17 |
nicklas |
316 |
catch (Throwable t) |
4477 |
03 May 17 |
nicklas |
317 |
{ |
4477 |
03 May 17 |
nicklas |
318 |
t.printStackTrace(); |
4477 |
03 May 17 |
nicklas |
319 |
json.clear(); |
4477 |
03 May 17 |
nicklas |
320 |
json.put("status", "error"); |
4477 |
03 May 17 |
nicklas |
321 |
json.put("message", t.getMessage()); |
4477 |
03 May 17 |
nicklas |
322 |
json.put("stacktrace", ThrowableUtil.stackTraceToString(t)); |
4477 |
03 May 17 |
nicklas |
323 |
} |
4477 |
03 May 17 |
nicklas |
324 |
finally |
4477 |
03 May 17 |
nicklas |
325 |
{ |
4477 |
03 May 17 |
nicklas |
326 |
if (dc != null) dc.close(); |
4477 |
03 May 17 |
nicklas |
327 |
if (sc != null) sc.setSessionSetting("linked-specimen-progress", null); |
4477 |
03 May 17 |
nicklas |
328 |
json.writeJSONString(resp.getWriter()); |
4477 |
03 May 17 |
nicklas |
329 |
} |
4477 |
03 May 17 |
nicklas |
330 |
|
4477 |
03 May 17 |
nicklas |
331 |
} |
4477 |
03 May 17 |
nicklas |
332 |
|
4477 |
03 May 17 |
nicklas |
333 |
|
4477 |
03 May 17 |
nicklas |
334 |
static class Counter |
4477 |
03 May 17 |
nicklas |
335 |
{ |
4477 |
03 May 17 |
nicklas |
336 |
|
4701 |
16 Mar 18 |
nicklas |
337 |
final ReferenceDateSource refSource; |
4477 |
03 May 17 |
nicklas |
338 |
|
4701 |
16 Mar 18 |
nicklas |
339 |
Counter(ReferenceDateSource refSource) |
4477 |
03 May 17 |
nicklas |
340 |
{ |
4701 |
16 Mar 18 |
nicklas |
341 |
this.refSource = refSource; |
4477 |
03 May 17 |
nicklas |
342 |
} |
4477 |
03 May 17 |
nicklas |
343 |
|
4477 |
03 May 17 |
nicklas |
344 |
int numBefore = 0; |
4477 |
03 May 17 |
nicklas |
345 |
int numAfter = 0; |
4477 |
03 May 17 |
nicklas |
346 |
} |
4477 |
03 May 17 |
nicklas |
347 |
|
4477 |
03 May 17 |
nicklas |
348 |
} |