1326 |
29 Mar 11 |
nicklas |
1 |
package net.sf.basedb.reggie.dao; |
1326 |
29 Mar 11 |
nicklas |
2 |
|
1326 |
29 Mar 11 |
nicklas |
3 |
import java.util.ArrayList; |
3779 |
10 Mar 16 |
nicklas |
4 |
import java.util.Collection; |
2840 |
20 Oct 14 |
nicklas |
5 |
import java.util.HashMap; |
1326 |
29 Mar 11 |
nicklas |
6 |
import java.util.List; |
2840 |
20 Oct 14 |
nicklas |
7 |
import java.util.Map; |
1326 |
29 Mar 11 |
nicklas |
8 |
|
4482 |
05 May 17 |
nicklas |
9 |
import net.sf.basedb.core.AnnotationRestriction; |
3247 |
14 Apr 15 |
nicklas |
10 |
import net.sf.basedb.core.AnnotationSimpleRestriction; |
4964 |
03 Sep 18 |
nicklas |
11 |
import net.sf.basedb.core.AnnotationType; |
1379 |
27 Jun 11 |
martin |
12 |
import net.sf.basedb.core.BioWell; |
1326 |
29 Mar 11 |
nicklas |
13 |
import net.sf.basedb.core.DbControl; |
3146 |
25 Feb 15 |
nicklas |
14 |
import net.sf.basedb.core.Extract; |
1326 |
29 Mar 11 |
nicklas |
15 |
import net.sf.basedb.core.Include; |
1372 |
23 May 11 |
martin |
16 |
import net.sf.basedb.core.InvalidDataException; |
1326 |
29 Mar 11 |
nicklas |
17 |
import net.sf.basedb.core.ItemQuery; |
1492 |
02 Dec 11 |
nicklas |
18 |
import net.sf.basedb.core.MeasuredBioMaterial; |
3247 |
14 Apr 15 |
nicklas |
19 |
import net.sf.basedb.core.Operator; |
1326 |
29 Mar 11 |
nicklas |
20 |
import net.sf.basedb.core.Sample; |
1326 |
29 Mar 11 |
nicklas |
21 |
import net.sf.basedb.core.Type; |
1623 |
26 Apr 12 |
nicklas |
22 |
import net.sf.basedb.core.query.Annotations; |
1326 |
29 Mar 11 |
nicklas |
23 |
import net.sf.basedb.core.query.Expressions; |
1326 |
29 Mar 11 |
nicklas |
24 |
import net.sf.basedb.core.query.Hql; |
1326 |
29 Mar 11 |
nicklas |
25 |
import net.sf.basedb.core.query.Orders; |
3145 |
25 Feb 15 |
nicklas |
26 |
import net.sf.basedb.core.query.Restriction; |
1326 |
29 Mar 11 |
nicklas |
27 |
import net.sf.basedb.core.query.Restrictions; |
1826 |
07 Feb 13 |
nicklas |
28 |
import net.sf.basedb.reggie.JsonUtil; |
1678 |
31 May 12 |
nicklas |
29 |
import net.sf.basedb.reggie.Reggie; |
1326 |
29 Mar 11 |
nicklas |
30 |
|
1406 |
17 Oct 11 |
martin |
31 |
import org.json.simple.JSONObject; |
1406 |
17 Oct 11 |
martin |
32 |
|
1326 |
29 Mar 11 |
nicklas |
33 |
/** |
1326 |
29 Mar 11 |
nicklas |
Class for loading information that is related to specimen tubes. |
1326 |
29 Mar 11 |
nicklas |
35 |
|
1326 |
29 Mar 11 |
nicklas |
@author nicklas |
1326 |
29 Mar 11 |
nicklas |
@since 1.2 |
1326 |
29 Mar 11 |
nicklas |
38 |
*/ |
1326 |
29 Mar 11 |
nicklas |
39 |
public class SpecimenTube |
1326 |
29 Mar 11 |
nicklas |
40 |
extends ReggieItem<Sample> |
1326 |
29 Mar 11 |
nicklas |
41 |
{ |
1326 |
29 Mar 11 |
nicklas |
42 |
|
7186 |
22 May 23 |
nicklas |
43 |
/** |
7186 |
22 May 23 |
nicklas |
@since 4.47 |
7186 |
22 May 23 |
nicklas |
45 |
*/ |
7186 |
22 May 23 |
nicklas |
46 |
public static final String FLAG_MISSING_IN_TRANSPORT_BOX = "MissingInTransportBox"; |
7186 |
22 May 23 |
nicklas |
47 |
|
2840 |
20 Oct 14 |
nicklas |
48 |
public static final Map<String, String> suffix2BiopsyType = new HashMap<String, String>(); |
2840 |
20 Oct 14 |
nicklas |
49 |
|
2840 |
20 Oct 14 |
nicklas |
50 |
static |
2840 |
20 Oct 14 |
nicklas |
51 |
{ |
2840 |
20 Oct 14 |
nicklas |
52 |
suffix2BiopsyType.put("C", "SpecimenCoreBiopsy"); |
2840 |
20 Oct 14 |
nicklas |
53 |
suffix2BiopsyType.put("D", "SpecimenCoreBiopsy2nd"); |
2840 |
20 Oct 14 |
nicklas |
54 |
} |
2840 |
20 Oct 14 |
nicklas |
55 |
|
1326 |
29 Mar 11 |
nicklas |
56 |
/** |
1326 |
29 Mar 11 |
nicklas |
Find all specimen tubes associated with a given case. This method can either |
1326 |
29 Mar 11 |
nicklas |
load all (including merged) specimen tubes, or only specimen tubes that |
1326 |
29 Mar 11 |
nicklas |
are really part of the original case. |
1623 |
26 Apr 12 |
nicklas |
<p> |
1623 |
26 Apr 12 |
nicklas |
If useBiopsyTypeAnnotation is set the lookup will use the 'BiopsyType' annotation |
2840 |
20 Oct 14 |
nicklas |
when searching for samples. If the case name has a C or D suffix only samples annotated |
2840 |
20 Oct 14 |
nicklas |
with BiopsyType=SpecimenCoreBiopsy/SpecimenCoreBiopsy2nd are considered. If no suffix is |
2840 |
20 Oct 14 |
nicklas |
specified SpecimenCoreBiopsy* samples are ignored. |
1326 |
29 Mar 11 |
nicklas |
65 |
*/ |
1623 |
26 Apr 12 |
nicklas |
66 |
public static List<SpecimenTube> findByCase(DbControl dc, Case theCase, String originalCaseName, boolean useBiopsyTypeAnnotation) |
1326 |
29 Mar 11 |
nicklas |
67 |
{ |
1326 |
29 Mar 11 |
nicklas |
68 |
ItemQuery<Sample> specimenQuery = theCase.getSample().getChildSamples(); |
1503 |
18 Jan 12 |
nicklas |
69 |
Subtype.SPECIMEN.addFilter(dc, specimenQuery); |
1623 |
26 Apr 12 |
nicklas |
70 |
if (originalCaseName != null) |
1326 |
29 Mar 11 |
nicklas |
71 |
{ |
2840 |
20 Oct 14 |
nicklas |
72 |
String suffix = null; |
2840 |
20 Oct 14 |
nicklas |
73 |
if (originalCaseName.length() > 7) |
2840 |
20 Oct 14 |
nicklas |
74 |
{ |
2840 |
20 Oct 14 |
nicklas |
75 |
suffix = originalCaseName.substring(7, 8); |
2840 |
20 Oct 14 |
nicklas |
76 |
originalCaseName = originalCaseName.substring(0, 7); |
2840 |
20 Oct 14 |
nicklas |
77 |
} |
1623 |
26 Apr 12 |
nicklas |
78 |
specimenQuery.restrict(Restrictions.like(Hql.property("name"), Expressions.parameter("name", originalCaseName + ".%", Type.STRING))); |
1623 |
26 Apr 12 |
nicklas |
79 |
if (useBiopsyTypeAnnotation) |
1623 |
26 Apr 12 |
nicklas |
80 |
{ |
2840 |
20 Oct 14 |
nicklas |
81 |
SpecimenTube.addBiopsyTypeFilter(dc, specimenQuery, suffix); |
1623 |
26 Apr 12 |
nicklas |
82 |
} |
1326 |
29 Mar 11 |
nicklas |
83 |
} |
1326 |
29 Mar 11 |
nicklas |
84 |
specimenQuery.order(Orders.asc(Hql.property("name"))); |
1326 |
29 Mar 11 |
nicklas |
85 |
specimenQuery.include(Include.ALL); |
1326 |
29 Mar 11 |
nicklas |
86 |
List<SpecimenTube> tubes = new ArrayList<SpecimenTube>(); |
1326 |
29 Mar 11 |
nicklas |
87 |
for (Sample s : specimenQuery.list(dc)) |
1326 |
29 Mar 11 |
nicklas |
88 |
{ |
1326 |
29 Mar 11 |
nicklas |
89 |
tubes.add(new SpecimenTube(s)); |
1326 |
29 Mar 11 |
nicklas |
90 |
} |
1326 |
29 Mar 11 |
nicklas |
91 |
return tubes; |
1326 |
29 Mar 11 |
nicklas |
92 |
} |
1326 |
29 Mar 11 |
nicklas |
93 |
|
1326 |
29 Mar 11 |
nicklas |
94 |
/** |
1326 |
29 Mar 11 |
nicklas |
Find all specimen tubes that are linked by name to a given case name. The assumption |
1326 |
29 Mar 11 |
nicklas |
is that the case has not yet been registered and we are trying to find all specimen |
1326 |
29 Mar 11 |
nicklas |
tubes that are associated with it. The specimen tubes start with the same name as the |
1326 |
29 Mar 11 |
nicklas |
case and then have a suffix with a dot plus a running number. Eg. xxx.1, xxx.2, etc. |
1623 |
26 Apr 12 |
nicklas |
<p> |
1623 |
26 Apr 12 |
nicklas |
If useBiopsyTypeAnnotation is set the lookup will use the 'BiopsyType' annotation |
1623 |
26 Apr 12 |
nicklas |
when searching for samples. If the case name has a suffix 'C' only samples annotated |
1623 |
26 Apr 12 |
nicklas |
with BiopsyType=SpecimenCoreBiopsy are considered. If no suffix is specified SpecimenCoreBiopsy |
1623 |
26 Apr 12 |
nicklas |
samples are ignored. |
1326 |
29 Mar 11 |
nicklas |
104 |
*/ |
1623 |
26 Apr 12 |
nicklas |
105 |
public static List<SpecimenTube> findByCaseName(DbControl dc, String name, boolean useBiopsyTypeAnnotation) |
1326 |
29 Mar 11 |
nicklas |
106 |
{ |
2840 |
20 Oct 14 |
nicklas |
107 |
String suffix = null; |
2840 |
20 Oct 14 |
nicklas |
108 |
if (name.length() > 7) |
2840 |
20 Oct 14 |
nicklas |
109 |
{ |
2840 |
20 Oct 14 |
nicklas |
110 |
suffix = name.substring(7, 8); |
2840 |
20 Oct 14 |
nicklas |
111 |
name = name.substring(0, 7); |
2840 |
20 Oct 14 |
nicklas |
112 |
} |
1623 |
26 Apr 12 |
nicklas |
113 |
|
1326 |
29 Mar 11 |
nicklas |
114 |
ItemQuery<Sample> specimenQuery = Sample.getQuery(); |
1503 |
18 Jan 12 |
nicklas |
115 |
Subtype.SPECIMEN.addFilter(dc, specimenQuery); |
1492 |
02 Dec 11 |
nicklas |
116 |
specimenQuery.restrict(Restrictions.like(Hql.property("name"), Expressions.parameter("name", name + ".%", Type.STRING))); |
1326 |
29 Mar 11 |
nicklas |
117 |
specimenQuery.order(Orders.asc(Hql.property("name"))); |
2917 |
11 Nov 14 |
nicklas |
118 |
specimenQuery.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT); |
1326 |
29 Mar 11 |
nicklas |
119 |
|
1623 |
26 Apr 12 |
nicklas |
120 |
if (useBiopsyTypeAnnotation) |
1623 |
26 Apr 12 |
nicklas |
121 |
{ |
2840 |
20 Oct 14 |
nicklas |
122 |
SpecimenTube.addBiopsyTypeFilter(dc, specimenQuery, suffix); |
1623 |
26 Apr 12 |
nicklas |
123 |
} |
1623 |
26 Apr 12 |
nicklas |
124 |
|
1326 |
29 Mar 11 |
nicklas |
125 |
List<SpecimenTube> tubes = new ArrayList<SpecimenTube>(); |
1326 |
29 Mar 11 |
nicklas |
126 |
for (Sample s : specimenQuery.list(dc)) |
1379 |
27 Jun 11 |
martin |
127 |
{ |
1326 |
29 Mar 11 |
nicklas |
128 |
tubes.add(new SpecimenTube(s)); |
1326 |
29 Mar 11 |
nicklas |
129 |
} |
1326 |
29 Mar 11 |
nicklas |
130 |
return tubes; |
1326 |
29 Mar 11 |
nicklas |
131 |
} |
1326 |
29 Mar 11 |
nicklas |
132 |
|
1492 |
02 Dec 11 |
nicklas |
133 |
/** |
1492 |
02 Dec 11 |
nicklas |
Find a specimen tube with the given name. |
1492 |
02 Dec 11 |
nicklas |
@return A specimen tube, or null if not found |
1492 |
02 Dec 11 |
nicklas |
136 |
*/ |
1372 |
23 May 11 |
martin |
137 |
public static SpecimenTube findByTubeName(DbControl dc, String tubeName) |
1372 |
23 May 11 |
martin |
138 |
{ |
1372 |
23 May 11 |
martin |
139 |
SpecimenTube tube = null; |
1372 |
23 May 11 |
martin |
140 |
|
1372 |
23 May 11 |
martin |
141 |
ItemQuery<Sample> tubeQuery = Sample.getQuery(); |
1503 |
18 Jan 12 |
nicklas |
142 |
Subtype.SPECIMEN.addFilter(dc, tubeQuery); |
1372 |
23 May 11 |
martin |
143 |
tubeQuery.restrict(Restrictions.like(Hql.property("name"), Expressions.string(tubeName))); |
4031 |
26 Jul 16 |
nicklas |
144 |
tubeQuery.order(Orders.desc(Hql.property("name"))); |
4031 |
26 Jul 16 |
nicklas |
145 |
tubeQuery.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT); |
1372 |
23 May 11 |
martin |
146 |
|
1372 |
23 May 11 |
martin |
147 |
List<Sample> tubes = tubeQuery.list(dc); |
1372 |
23 May 11 |
martin |
148 |
if (tubes.size() > 1) |
1372 |
23 May 11 |
martin |
149 |
{ |
1372 |
23 May 11 |
martin |
150 |
throw new InvalidDataException( |
1372 |
23 May 11 |
martin |
151 |
"More than one specimen tube with the name " + tubeName + " was found. " + |
1372 |
23 May 11 |
martin |
152 |
"This wizard can't be used until that is corrected."); |
1372 |
23 May 11 |
martin |
153 |
} |
1372 |
23 May 11 |
martin |
154 |
if (tubes.size() == 1) |
1372 |
23 May 11 |
martin |
155 |
{ |
1372 |
23 May 11 |
martin |
156 |
tube = new SpecimenTube(tubes.get(0)); |
1372 |
23 May 11 |
martin |
157 |
} |
1372 |
23 May 11 |
martin |
158 |
return tube; |
1372 |
23 May 11 |
martin |
159 |
} |
1372 |
23 May 11 |
martin |
160 |
|
1419 |
28 Oct 11 |
martin |
161 |
/** |
4075 |
05 Sep 16 |
nicklas |
Find a specimen tube with the given external ID. |
4075 |
05 Sep 16 |
nicklas |
@return A specimen tube, or null if not found |
4075 |
05 Sep 16 |
nicklas |
@since 4.7 |
4075 |
05 Sep 16 |
nicklas |
165 |
*/ |
4075 |
05 Sep 16 |
nicklas |
166 |
public static SpecimenTube findByExternalId(DbControl dc, String externalId) |
4075 |
05 Sep 16 |
nicklas |
167 |
{ |
4075 |
05 Sep 16 |
nicklas |
168 |
SpecimenTube tube = null; |
4075 |
05 Sep 16 |
nicklas |
169 |
|
4075 |
05 Sep 16 |
nicklas |
170 |
ItemQuery<Sample> tubeQuery = Sample.getQuery(); |
4075 |
05 Sep 16 |
nicklas |
171 |
Subtype.SPECIMEN.addFilter(dc, tubeQuery); |
4075 |
05 Sep 16 |
nicklas |
172 |
tubeQuery.restrict(Restrictions.eq(Hql.property("externalId"), Expressions.string(externalId))); |
4075 |
05 Sep 16 |
nicklas |
173 |
tubeQuery.order(Orders.desc(Hql.property("name"))); |
4075 |
05 Sep 16 |
nicklas |
174 |
tubeQuery.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT); |
4075 |
05 Sep 16 |
nicklas |
175 |
|
4075 |
05 Sep 16 |
nicklas |
176 |
List<Sample> tubes = tubeQuery.list(dc); |
4075 |
05 Sep 16 |
nicklas |
177 |
if (tubes.size() > 1) |
4075 |
05 Sep 16 |
nicklas |
178 |
{ |
4075 |
05 Sep 16 |
nicklas |
179 |
throw new InvalidDataException( |
4075 |
05 Sep 16 |
nicklas |
180 |
"More than one specimen tube with the external id '" + externalId + "' was found. " + |
4075 |
05 Sep 16 |
nicklas |
181 |
"This wizard can't be used until that is corrected."); |
4075 |
05 Sep 16 |
nicklas |
182 |
} |
4075 |
05 Sep 16 |
nicklas |
183 |
if (tubes.size() == 1) |
4075 |
05 Sep 16 |
nicklas |
184 |
{ |
4075 |
05 Sep 16 |
nicklas |
185 |
tube = new SpecimenTube(tubes.get(0)); |
4075 |
05 Sep 16 |
nicklas |
186 |
} |
4075 |
05 Sep 16 |
nicklas |
187 |
return tube; |
4075 |
05 Sep 16 |
nicklas |
188 |
} |
4075 |
05 Sep 16 |
nicklas |
189 |
|
4075 |
05 Sep 16 |
nicklas |
190 |
/** |
4964 |
03 Sep 18 |
nicklas |
Find a specimen tubes by PAD. Not that multiple tubes |
4964 |
03 Sep 18 |
nicklas |
may be registered with the same PAD. Note that if the logged |
4964 |
03 Sep 18 |
nicklas |
in user doesn't have permission to access PAD information |
4964 |
03 Sep 18 |
nicklas |
this method will throw a PermissionDeniedException. |
4964 |
03 Sep 18 |
nicklas |
195 |
|
4964 |
03 Sep 18 |
nicklas |
@param dc DbControl The DbControl to use. |
4964 |
03 Sep 18 |
nicklas |
@param pad The PAD to look for |
4964 |
03 Sep 18 |
nicklas |
@since 4.19.1 |
4964 |
03 Sep 18 |
nicklas |
199 |
*/ |
4964 |
03 Sep 18 |
nicklas |
200 |
public static List<SpecimenTube> findByPAD(DbControl dc, String pad) |
4964 |
03 Sep 18 |
nicklas |
201 |
{ |
4964 |
03 Sep 18 |
nicklas |
202 |
AnnotationType padType = Annotationtype.PAD.load(dc); |
4964 |
03 Sep 18 |
nicklas |
203 |
|
4964 |
03 Sep 18 |
nicklas |
204 |
ItemQuery<Sample> tubeQuery = Sample.getQuery(); |
4964 |
03 Sep 18 |
nicklas |
205 |
Subtype.SPECIMEN.addFilter(dc, tubeQuery); |
4964 |
03 Sep 18 |
nicklas |
206 |
tubeQuery.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT); |
4964 |
03 Sep 18 |
nicklas |
207 |
tubeQuery.restrict(new AnnotationSimpleRestriction(null, padType, Operator.EQ, pad, new AnnotationRestriction.Options())); |
4964 |
03 Sep 18 |
nicklas |
208 |
List<Sample> tubes = tubeQuery.list(dc); |
4964 |
03 Sep 18 |
nicklas |
209 |
|
4964 |
03 Sep 18 |
nicklas |
210 |
return toList(tubes); |
4964 |
03 Sep 18 |
nicklas |
211 |
} |
4964 |
03 Sep 18 |
nicklas |
212 |
|
7150 |
09 May 23 |
nicklas |
213 |
/** |
7150 |
09 May 23 |
nicklas |
Find a specimen tubes by ExternalRef. Typically only |
7150 |
09 May 23 |
nicklas |
a single specimen should be registered with the same ExternalRef, |
7150 |
09 May 23 |
nicklas |
but we return a list that may have more hits and delegate the |
7150 |
09 May 23 |
nicklas |
calling to code to handle multiple hits. |
7150 |
09 May 23 |
nicklas |
218 |
|
7150 |
09 May 23 |
nicklas |
@param dc DbControl The DbControl to use. |
7150 |
09 May 23 |
nicklas |
@param ref The ExternalRef to look for |
7150 |
09 May 23 |
nicklas |
@since 4.47 |
7150 |
09 May 23 |
nicklas |
222 |
*/ |
7150 |
09 May 23 |
nicklas |
223 |
public static List<SpecimenTube> findByExternalRef(DbControl dc, String ref) |
7150 |
09 May 23 |
nicklas |
224 |
{ |
7150 |
09 May 23 |
nicklas |
225 |
AnnotationType eRefType = Annotationtype.EXTERNAL_REF.load(dc); |
4964 |
03 Sep 18 |
nicklas |
226 |
|
7150 |
09 May 23 |
nicklas |
227 |
ItemQuery<Sample> tubeQuery = Sample.getQuery(); |
7150 |
09 May 23 |
nicklas |
228 |
Subtype.SPECIMEN.addFilter(dc, tubeQuery); |
7150 |
09 May 23 |
nicklas |
229 |
tubeQuery.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT); |
7150 |
09 May 23 |
nicklas |
230 |
tubeQuery.restrict(new AnnotationSimpleRestriction(null, eRefType, Operator.LIKE, "%"+ref, new AnnotationRestriction.Options())); |
7150 |
09 May 23 |
nicklas |
231 |
List<Sample> tubes = tubeQuery.list(dc); |
7150 |
09 May 23 |
nicklas |
232 |
|
7150 |
09 May 23 |
nicklas |
233 |
return toList(tubes); |
7150 |
09 May 23 |
nicklas |
234 |
} |
7150 |
09 May 23 |
nicklas |
235 |
|
4964 |
03 Sep 18 |
nicklas |
236 |
/** |
1492 |
02 Dec 11 |
nicklas |
Find unpartitioned specimen tubes. A specimen tube that has not been partitioned |
1492 |
02 Dec 11 |
nicklas |
have a 'null' {@link MeasuredBioMaterial#getOriginalQuantity()}. |
1419 |
28 Oct 11 |
martin |
@since 1.6 |
1492 |
02 Dec 11 |
nicklas |
240 |
*/ |
3145 |
25 Feb 15 |
nicklas |
241 |
public static List<SpecimenTube> findUnPartitionedTubes(DbControl dc, boolean includeReProcess) |
1419 |
28 Oct 11 |
martin |
242 |
{ |
1419 |
28 Oct 11 |
martin |
243 |
List<SpecimenTube> unPartitionedTubes = new ArrayList<SpecimenTube>(); |
1419 |
28 Oct 11 |
martin |
244 |
|
1419 |
28 Oct 11 |
martin |
245 |
ItemQuery<Sample> tubeQuery = Sample.getQuery(); |
3145 |
25 Feb 15 |
nicklas |
246 |
tubeQuery.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT); |
1503 |
18 Jan 12 |
nicklas |
247 |
Subtype.SPECIMEN.addFilter(dc, tubeQuery); |
3145 |
25 Feb 15 |
nicklas |
// Default criteria is to only include items with originalQuantity=null |
3145 |
25 Feb 15 |
nicklas |
249 |
Restriction criteria = Restrictions.eq(Hql.property("originalQuantity"), null); |
3145 |
25 Feb 15 |
nicklas |
250 |
|
3145 |
25 Feb 15 |
nicklas |
251 |
if (includeReProcess) |
3145 |
25 Feb 15 |
nicklas |
252 |
{ |
3145 |
25 Feb 15 |
nicklas |
253 |
tubeQuery.join(Annotations.leftJoin(null, Annotationtype.AUTO_PROCESSING.load(dc), "ap")); |
3145 |
25 Feb 15 |
nicklas |
// Also include items with AutoProcessing=ReProcess |
3145 |
25 Feb 15 |
nicklas |
255 |
criteria = Restrictions.or( |
3145 |
25 Feb 15 |
nicklas |
256 |
criteria, |
3145 |
25 Feb 15 |
nicklas |
257 |
Restrictions.eq(Hql.alias("ap"), Expressions.string("ReProcess")) |
3145 |
25 Feb 15 |
nicklas |
258 |
); |
3145 |
25 Feb 15 |
nicklas |
259 |
} |
3145 |
25 Feb 15 |
nicklas |
260 |
tubeQuery.restrict(criteria); |
3145 |
25 Feb 15 |
nicklas |
261 |
|
1449 |
02 Nov 11 |
martin |
262 |
tubeQuery.order(Orders.desc(Hql.property("id"))); |
1419 |
28 Oct 11 |
martin |
263 |
List<Sample> tubes = tubeQuery.list(dc); |
1419 |
28 Oct 11 |
martin |
264 |
for (Sample tube : tubes) |
1419 |
28 Oct 11 |
martin |
265 |
{ |
1456 |
09 Nov 11 |
martin |
266 |
BioWell well = tube.getBioWell(); |
1456 |
09 Nov 11 |
martin |
267 |
String boxNamePrefix = null; |
1503 |
18 Jan 12 |
nicklas |
268 |
|
3145 |
25 Feb 15 |
nicklas |
269 |
String autoProcessing = (String)Annotationtype.AUTO_PROCESSING.getAnnotationValue(dc, tube); |
1456 |
09 Nov 11 |
martin |
270 |
if (well != null) |
1449 |
02 Nov 11 |
martin |
271 |
{ |
1456 |
09 Nov 11 |
martin |
272 |
boxNamePrefix = well.getPlate().getName().substring(0,2); |
1456 |
09 Nov 11 |
martin |
273 |
} |
3145 |
25 Feb 15 |
nicklas |
274 |
if ("ReProcess".equals(autoProcessing) || (tube.countExtracts() == 0 && "Sp".equals(boxNamePrefix))) |
1456 |
09 Nov 11 |
martin |
275 |
{ |
1449 |
02 Nov 11 |
martin |
276 |
unPartitionedTubes.add(new SpecimenTube(tube)); |
1449 |
02 Nov 11 |
martin |
277 |
} |
1419 |
28 Oct 11 |
martin |
278 |
} |
1419 |
28 Oct 11 |
martin |
279 |
return unPartitionedTubes; |
1419 |
28 Oct 11 |
martin |
280 |
} |
1419 |
28 Oct 11 |
martin |
281 |
|
4898 |
10 Jul 18 |
nicklas |
282 |
|
4898 |
10 Jul 18 |
nicklas |
283 |
/** |
4898 |
10 Jul 18 |
nicklas |
Find the next name to give a "Specimen" or "NoSpecimen" item. This assumes that |
4898 |
10 Jul 18 |
nicklas |
all items are using the naming convention: foo.1, foo.2, and |
4898 |
10 Jul 18 |
nicklas |
so on. |
4898 |
10 Jul 18 |
nicklas |
@return The next unused name |
4898 |
10 Jul 18 |
nicklas |
@since 4.19 |
4898 |
10 Jul 18 |
nicklas |
289 |
*/ |
7000 |
20 Jan 23 |
nicklas |
290 |
public static String getNextSpecimenName(DbControl dc, String caseName, boolean releaseIfTransactionFails) |
4898 |
10 Jul 18 |
nicklas |
291 |
{ |
4964 |
03 Sep 18 |
nicklas |
292 |
if (caseName.length() > 7) |
4964 |
03 Sep 18 |
nicklas |
293 |
{ |
4964 |
03 Sep 18 |
nicklas |
294 |
caseName = caseName.substring(0, 7); |
4964 |
03 Sep 18 |
nicklas |
295 |
} |
4964 |
03 Sep 18 |
nicklas |
296 |
|
4898 |
10 Jul 18 |
nicklas |
297 |
ItemQuery<Sample> query = Sample.getQuery(); |
4898 |
10 Jul 18 |
nicklas |
298 |
query.setIncludes(Include.ALL); |
4898 |
10 Jul 18 |
nicklas |
299 |
query.restrict(Restrictions.or( |
4898 |
10 Jul 18 |
nicklas |
300 |
Subtype.SPECIMEN.restriction(dc, null), |
6510 |
03 Dec 21 |
nicklas |
301 |
Subtype.NO_SPECIMEN.restriction(dc, null) |
4898 |
10 Jul 18 |
nicklas |
302 |
)); |
4898 |
10 Jul 18 |
nicklas |
303 |
query.restrict(Restrictions.like(Hql.property("name"), Expressions.string(caseName + ".%"))); |
7000 |
20 Jan 23 |
nicklas |
304 |
return ReggieItem.getNextChildItemName(dc, caseName, query, "", releaseIfTransactionFails); |
4898 |
10 Jul 18 |
nicklas |
305 |
} |
4898 |
10 Jul 18 |
nicklas |
306 |
|
4071 |
02 Sep 16 |
nicklas |
307 |
/** |
4071 |
02 Sep 16 |
nicklas |
Generate the next auto-generated external ID. This method will search all specimen/nospecimen |
4071 |
02 Sep 16 |
nicklas |
starting with the given prefix and find the one with the highest numeric suffix. |
4902 |
10 Jul 18 |
nicklas |
The returned string is the found item + 1. |
4902 |
10 Jul 18 |
nicklas |
@since 4.19 |
4071 |
02 Sep 16 |
nicklas |
312 |
*/ |
5088 |
13 Nov 18 |
nicklas |
313 |
public static String getNextExternalId(DbControl dc, Subtype subtype) |
4071 |
02 Sep 16 |
nicklas |
314 |
{ |
4071 |
02 Sep 16 |
nicklas |
315 |
ItemQuery<Sample> spQuery = Sample.getQuery(); |
5088 |
13 Nov 18 |
nicklas |
316 |
return ReggieItem.getNextExternalId(dc, spQuery, subtype.getExternalIdPrefix()); |
4071 |
02 Sep 16 |
nicklas |
317 |
} |
4071 |
02 Sep 16 |
nicklas |
318 |
|
4071 |
02 Sep 16 |
nicklas |
319 |
|
2840 |
20 Oct 14 |
nicklas |
320 |
public static void addBiopsyTypeFilter(DbControl dc, ItemQuery<Sample> query, String suffix) |
2840 |
20 Oct 14 |
nicklas |
321 |
{ |
2840 |
20 Oct 14 |
nicklas |
322 |
if (suffix != null) |
2840 |
20 Oct 14 |
nicklas |
323 |
{ |
2840 |
20 Oct 14 |
nicklas |
// Only look for samples specific annotation BiopsyType (C=SpecimenCoreBiopsy, D=SpecimenCoreBiopsy2nd) |
4482 |
05 May 17 |
nicklas |
325 |
query.restrict(new AnnotationSimpleRestriction(null, Annotationtype.BIOPSY_TYPE.load(dc), Operator.EQ, suffix2BiopsyType.get(suffix), new AnnotationRestriction.Options())); |
2840 |
20 Oct 14 |
nicklas |
326 |
} |
2840 |
20 Oct 14 |
nicklas |
327 |
else |
2840 |
20 Oct 14 |
nicklas |
328 |
{ |
2840 |
20 Oct 14 |
nicklas |
// Ignore samples with BiopsyType = any that require suffix |
2840 |
20 Oct 14 |
nicklas |
330 |
query.join(Annotations.leftJoin(Annotationtype.BIOPSY_TYPE.load(dc), "bt")); |
2840 |
20 Oct 14 |
nicklas |
331 |
query.restrict( |
2840 |
20 Oct 14 |
nicklas |
332 |
Restrictions.or( |
2840 |
20 Oct 14 |
nicklas |
333 |
Restrictions.not(Restrictions.in(Hql.alias("bt"), Expressions.parameter("btValues"))), |
2840 |
20 Oct 14 |
nicklas |
334 |
Restrictions.eq(Hql.alias("bt"), null) |
2840 |
20 Oct 14 |
nicklas |
335 |
)); |
2840 |
20 Oct 14 |
nicklas |
336 |
query.setParameter("btValues", suffix2BiopsyType.values(), Type.STRING); |
2840 |
20 Oct 14 |
nicklas |
337 |
} |
2840 |
20 Oct 14 |
nicklas |
338 |
} |
3146 |
25 Feb 15 |
nicklas |
339 |
|
3146 |
25 Feb 15 |
nicklas |
340 |
/** |
5333 |
28 Mar 19 |
nicklas |
Get the specimen that was the last one to be placed in a storage box with the |
5333 |
28 Mar 19 |
nicklas |
given prefix. Eg. 'Sp' for regular storage boxes or 'PSp' for paused storage |
7140 |
28 Apr 23 |
nicklas |
boxes. If a subtype is specified only consider items of the specified type. |
7140 |
28 Apr 23 |
nicklas |
@since 4.47 |
5333 |
28 Mar 19 |
nicklas |
345 |
*/ |
7140 |
28 Apr 23 |
nicklas |
346 |
public static SpecimenTube getLastPlacedSpecimen(DbControl dc, Subtype subtype, String boxPrefix) |
5333 |
28 Mar 19 |
nicklas |
347 |
{ |
5333 |
28 Mar 19 |
nicklas |
348 |
ItemQuery<Sample> spQuery = Sample.getQuery(); |
5333 |
28 Mar 19 |
nicklas |
349 |
spQuery.setIncludes(Reggie.INCLUDE_IN_CURRENT_PROJECT); |
7140 |
28 Apr 23 |
nicklas |
350 |
if (subtype != null) subtype.addFilter(dc, spQuery); |
5333 |
28 Mar 19 |
nicklas |
351 |
spQuery.join(Hql.innerJoin("bioWell", "bw")); |
5333 |
28 Mar 19 |
nicklas |
352 |
spQuery.join(Hql.innerJoin("bw", "bioPlate", "bp")); |
5333 |
28 Mar 19 |
nicklas |
353 |
spQuery.restrict(Restrictions.like(Hql.property("bp", "name"), Expressions.string(boxPrefix+"%"))); |
5333 |
28 Mar 19 |
nicklas |
354 |
spQuery.order(Orders.desc(Hql.property("bp", "name"))); |
5333 |
28 Mar 19 |
nicklas |
355 |
spQuery.order(Orders.desc(Hql.property("bw", "row"))); |
5333 |
28 Mar 19 |
nicklas |
356 |
spQuery.order(Orders.desc(Hql.property("bw", "column"))); |
5333 |
28 Mar 19 |
nicklas |
357 |
spQuery.setMaxResults(1); |
5333 |
28 Mar 19 |
nicklas |
358 |
List<Sample> lastPlacedSpecimen = spQuery.list(dc); |
5333 |
28 Mar 19 |
nicklas |
359 |
return lastPlacedSpecimen.size() > 0 ? new SpecimenTube(lastPlacedSpecimen.get(0)) : null; |
5333 |
28 Mar 19 |
nicklas |
360 |
} |
5333 |
28 Mar 19 |
nicklas |
361 |
|
5333 |
28 Mar 19 |
nicklas |
362 |
/** |
3146 |
25 Feb 15 |
nicklas |
Get a Specimen item when the id is known. |
3146 |
25 Feb 15 |
nicklas |
@since 3.2 |
3146 |
25 Feb 15 |
nicklas |
365 |
*/ |
3146 |
25 Feb 15 |
nicklas |
366 |
public static SpecimenTube getById(DbControl dc, int id) |
3146 |
25 Feb 15 |
nicklas |
367 |
{ |
3146 |
25 Feb 15 |
nicklas |
368 |
return new SpecimenTube(Sample.getById(dc, id)); |
3146 |
25 Feb 15 |
nicklas |
369 |
} |
2840 |
20 Oct 14 |
nicklas |
370 |
|
3166 |
05 Mar 15 |
nicklas |
371 |
/** |
3166 |
05 Mar 15 |
nicklas |
@since 3.2 |
3166 |
05 Mar 15 |
nicklas |
373 |
*/ |
3166 |
05 Mar 15 |
nicklas |
374 |
public static SpecimenTube get(Sample sample) |
3166 |
05 Mar 15 |
nicklas |
375 |
{ |
3166 |
05 Mar 15 |
nicklas |
376 |
return new SpecimenTube(sample); |
3166 |
05 Mar 15 |
nicklas |
377 |
} |
3166 |
05 Mar 15 |
nicklas |
378 |
|
3779 |
10 Mar 16 |
nicklas |
379 |
/** |
3779 |
10 Mar 16 |
nicklas |
@since 4.3 |
3779 |
10 Mar 16 |
nicklas |
381 |
*/ |
3779 |
10 Mar 16 |
nicklas |
382 |
public static List<SpecimenTube> toList(Collection<Sample> samples) |
3779 |
10 Mar 16 |
nicklas |
383 |
{ |
3779 |
10 Mar 16 |
nicklas |
384 |
List<SpecimenTube> tubes = new ArrayList<SpecimenTube>(samples.size()); |
3779 |
10 Mar 16 |
nicklas |
385 |
for (Sample s : samples) |
3779 |
10 Mar 16 |
nicklas |
386 |
{ |
3779 |
10 Mar 16 |
nicklas |
387 |
tubes.add(new SpecimenTube(s)); |
3779 |
10 Mar 16 |
nicklas |
388 |
} |
3779 |
10 Mar 16 |
nicklas |
389 |
return tubes; |
3779 |
10 Mar 16 |
nicklas |
390 |
} |
2840 |
20 Oct 14 |
nicklas |
391 |
|
1821 |
06 Feb 13 |
nicklas |
392 |
private JSONObject jsonWell; |
1379 |
27 Jun 11 |
martin |
393 |
|
1326 |
29 Mar 11 |
nicklas |
394 |
private SpecimenTube(Sample sample) |
1326 |
29 Mar 11 |
nicklas |
395 |
{ |
1326 |
29 Mar 11 |
nicklas |
396 |
super(sample); |
1379 |
27 Jun 11 |
martin |
397 |
} |
1326 |
29 Mar 11 |
nicklas |
398 |
|
1379 |
27 Jun 11 |
martin |
399 |
|
1326 |
29 Mar 11 |
nicklas |
400 |
/** |
1326 |
29 Mar 11 |
nicklas |
Get the real sample that represents this speciment tube in BASE. |
1326 |
29 Mar 11 |
nicklas |
402 |
*/ |
1326 |
29 Mar 11 |
nicklas |
403 |
public Sample getSample() |
1326 |
29 Mar 11 |
nicklas |
404 |
{ |
1326 |
29 Mar 11 |
nicklas |
405 |
return getItem(); |
1326 |
29 Mar 11 |
nicklas |
406 |
} |
1326 |
29 Mar 11 |
nicklas |
407 |
|
1821 |
06 Feb 13 |
nicklas |
408 |
@Override |
1821 |
06 Feb 13 |
nicklas |
409 |
protected void initJSON(JSONObject json) |
1379 |
27 Jun 11 |
martin |
410 |
{ |
1821 |
06 Feb 13 |
nicklas |
411 |
super.initJSON(json); |
1821 |
06 Feb 13 |
nicklas |
412 |
if (jsonWell != null) json.put("bioWell", jsonWell); |
1379 |
27 Jun 11 |
martin |
413 |
} |
1821 |
06 Feb 13 |
nicklas |
414 |
|
1379 |
27 Jun 11 |
martin |
415 |
/** |
1821 |
06 Feb 13 |
nicklas |
Load information about the plate and location the current RNA |
1821 |
06 Feb 13 |
nicklas |
is located on. |
1379 |
27 Jun 11 |
martin |
418 |
*/ |
1821 |
06 Feb 13 |
nicklas |
419 |
public JSONObject loadBioPlateLocation() |
1379 |
27 Jun 11 |
martin |
420 |
{ |
1826 |
07 Feb 13 |
nicklas |
421 |
if (jsonWell == null) |
1821 |
06 Feb 13 |
nicklas |
422 |
{ |
2134 |
11 Nov 13 |
nicklas |
423 |
jsonWell = JsonUtil.getBioWellAsJSON(getItem().getBioWell(), true); |
1821 |
06 Feb 13 |
nicklas |
424 |
} |
1821 |
06 Feb 13 |
nicklas |
425 |
return jsonWell; |
1379 |
27 Jun 11 |
martin |
426 |
} |
3146 |
25 Feb 15 |
nicklas |
427 |
|
3146 |
25 Feb 15 |
nicklas |
428 |
/** |
3146 |
25 Feb 15 |
nicklas |
Find the next name to give a Lysate child item. This assumes that |
3146 |
25 Feb 15 |
nicklas |
all child items are using the naming convention. foo.l, foo.l2, and |
3146 |
25 Feb 15 |
nicklas |
so on. NOTE! The first child item have no number! |
3146 |
25 Feb 15 |
nicklas |
@return The next unused name |
3146 |
25 Feb 15 |
nicklas |
@since 3.2 |
3146 |
25 Feb 15 |
nicklas |
434 |
*/ |
3146 |
25 Feb 15 |
nicklas |
435 |
public String getNextLysateName(DbControl dc) |
3146 |
25 Feb 15 |
nicklas |
436 |
{ |
3146 |
25 Feb 15 |
nicklas |
437 |
Sample sp = getItem(); |
6193 |
30 Mar 21 |
nicklas |
438 |
ItemQuery<Extract> query = null; |
6193 |
30 Mar 21 |
nicklas |
439 |
if (sp.isInDatabase()) |
6193 |
30 Mar 21 |
nicklas |
440 |
{ |
6193 |
30 Mar 21 |
nicklas |
441 |
query = sp.getExtracts(); |
6193 |
30 Mar 21 |
nicklas |
442 |
Subtype.LYSATE.addFilter(dc, query); |
6193 |
30 Mar 21 |
nicklas |
443 |
query.setIncludes(Include.ALL); |
6193 |
30 Mar 21 |
nicklas |
444 |
} |
4896 |
09 Jul 18 |
nicklas |
445 |
return getNextChildItemName(dc, query, Subtype.LYSATE.getItemSuffix(), true); |
3146 |
25 Feb 15 |
nicklas |
446 |
} |
1379 |
27 Jun 11 |
martin |
447 |
|
3146 |
25 Feb 15 |
nicklas |
448 |
/** |
3146 |
25 Feb 15 |
nicklas |
Find the next name to give a Histology child item. This assumes that |
3146 |
25 Feb 15 |
nicklas |
all child items are using the naming convention. foo.his, foo.his2, and |
3146 |
25 Feb 15 |
nicklas |
so on. NOTE! The first child item have no number! |
3146 |
25 Feb 15 |
nicklas |
@return The next unused name |
3146 |
25 Feb 15 |
nicklas |
@since 3.2 |
3146 |
25 Feb 15 |
nicklas |
454 |
*/ |
3146 |
25 Feb 15 |
nicklas |
455 |
public String getNextHistologyName(DbControl dc) |
3146 |
25 Feb 15 |
nicklas |
456 |
{ |
3146 |
25 Feb 15 |
nicklas |
457 |
Sample sp = getItem(); |
6193 |
30 Mar 21 |
nicklas |
458 |
ItemQuery<Sample> query = null; |
6193 |
30 Mar 21 |
nicklas |
459 |
if (sp.isInDatabase()) |
6193 |
30 Mar 21 |
nicklas |
460 |
{ |
6193 |
30 Mar 21 |
nicklas |
461 |
query = sp.getChildSamples(); |
6193 |
30 Mar 21 |
nicklas |
462 |
Subtype.HISTOLOGY.addFilter(dc, query); |
6193 |
30 Mar 21 |
nicklas |
463 |
query.setIncludes(Include.ALL); |
6193 |
30 Mar 21 |
nicklas |
464 |
} |
4896 |
09 Jul 18 |
nicklas |
465 |
return getNextChildItemName(dc, query, Subtype.HISTOLOGY.getItemSuffix(), true); |
3146 |
25 Feb 15 |
nicklas |
466 |
} |
3940 |
16 May 16 |
nicklas |
467 |
|
3940 |
16 May 16 |
nicklas |
468 |
/** |
3940 |
16 May 16 |
nicklas |
Get the parent case. |
3940 |
16 May 16 |
nicklas |
@since 4.5 |
3940 |
16 May 16 |
nicklas |
471 |
*/ |
3940 |
16 May 16 |
nicklas |
472 |
public Case getCase() |
3940 |
16 May 16 |
nicklas |
473 |
{ |
3940 |
16 May 16 |
nicklas |
474 |
Sample specimen = getItem(); |
3940 |
16 May 16 |
nicklas |
475 |
Sample theCase = (Sample)specimen.getParent(); |
3940 |
16 May 16 |
nicklas |
476 |
return Case.get(theCase); |
3940 |
16 May 16 |
nicklas |
477 |
} |
3146 |
25 Feb 15 |
nicklas |
478 |
|
1326 |
29 Mar 11 |
nicklas |
479 |
} |