3700 |
18 Jan 16 |
nicklas |
1 |
package net.sf.basedb.reggie.autoconfirm; |
3700 |
18 Jan 16 |
nicklas |
2 |
|
3715 |
21 Jan 16 |
nicklas |
3 |
import java.util.Arrays; |
3715 |
21 Jan 16 |
nicklas |
4 |
import java.util.List; |
3715 |
21 Jan 16 |
nicklas |
5 |
|
3700 |
18 Jan 16 |
nicklas |
6 |
import org.slf4j.LoggerFactory; |
3700 |
18 Jan 16 |
nicklas |
7 |
|
6213 |
15 Apr 21 |
nicklas |
8 |
import net.sf.basedb.core.Annotatable; |
3700 |
18 Jan 16 |
nicklas |
9 |
import net.sf.basedb.core.DbControl; |
3700 |
18 Jan 16 |
nicklas |
10 |
import net.sf.basedb.core.DerivedBioAssay; |
3700 |
18 Jan 16 |
nicklas |
11 |
import net.sf.basedb.core.Job; |
3700 |
18 Jan 16 |
nicklas |
12 |
import net.sf.basedb.core.PhysicalBioAssay; |
3715 |
21 Jan 16 |
nicklas |
13 |
import net.sf.basedb.core.Protocol; |
3700 |
18 Jan 16 |
nicklas |
14 |
import net.sf.basedb.core.SessionControl; |
3715 |
21 Jan 16 |
nicklas |
15 |
import net.sf.basedb.core.Software; |
4306 |
17 Jan 17 |
nicklas |
16 |
import net.sf.basedb.opengrid.CmdResult; |
4306 |
17 Jan 17 |
nicklas |
17 |
import net.sf.basedb.opengrid.OpenGrid; |
4306 |
17 Jan 17 |
nicklas |
18 |
import net.sf.basedb.opengrid.OpenGridCluster; |
4306 |
17 Jan 17 |
nicklas |
19 |
import net.sf.basedb.opengrid.OpenGridSession; |
4306 |
17 Jan 17 |
nicklas |
20 |
import net.sf.basedb.opengrid.config.NodeConfig; |
4306 |
17 Jan 17 |
nicklas |
21 |
import net.sf.basedb.opengrid.service.OpenGridService; |
5384 |
26 Apr 19 |
nicklas |
22 |
import net.sf.basedb.reggie.activity.ActivityDef; |
3700 |
18 Jan 16 |
nicklas |
23 |
import net.sf.basedb.reggie.dao.Annotationtype; |
3700 |
18 Jan 16 |
nicklas |
24 |
import net.sf.basedb.reggie.dao.FlowCell; |
5491 |
13 Jun 19 |
nicklas |
25 |
import net.sf.basedb.reggie.dao.Pipeline; |
3700 |
18 Jan 16 |
nicklas |
26 |
import net.sf.basedb.reggie.dao.SequencingRun; |
3715 |
21 Jan 16 |
nicklas |
27 |
import net.sf.basedb.reggie.dao.Subtype; |
4306 |
17 Jan 17 |
nicklas |
28 |
import net.sf.basedb.reggie.grid.DemuxJobCreator; |
4306 |
17 Jan 17 |
nicklas |
29 |
import net.sf.basedb.reggie.grid.ScriptUtil; |
4306 |
17 Jan 17 |
nicklas |
30 |
import net.sf.basedb.reggie.grid.DemuxJobCreator.DemuxDefinition; |
5491 |
13 Jun 19 |
nicklas |
31 |
import net.sf.basedb.reggie.grid.MipsDemuxJobCreator; |
5486 |
12 Jun 19 |
nicklas |
32 |
import net.sf.basedb.reggie.grid.RnaSeqDemuxJobCreator; |
3704 |
19 Jan 16 |
nicklas |
33 |
import net.sf.basedb.reggie.servlet.DemuxMergeServlet; |
3704 |
19 Jan 16 |
nicklas |
34 |
import net.sf.basedb.reggie.servlet.SequencingRunServlet; |
7077 |
27 Mar 23 |
nicklas |
35 |
import net.sf.basedb.util.extensions.logging.ExtensionsLog; |
7077 |
27 Mar 23 |
nicklas |
36 |
import net.sf.basedb.util.extensions.logging.ExtensionsLogger; |
6213 |
15 Apr 21 |
nicklas |
37 |
import net.sf.basedb.util.filter.AllOfFilter; |
6213 |
15 Apr 21 |
nicklas |
38 |
import net.sf.basedb.util.filter.Filter; |
3700 |
18 Jan 16 |
nicklas |
39 |
|
3700 |
18 Jan 16 |
nicklas |
40 |
/** |
3700 |
18 Jan 16 |
nicklas |
Auto-confirm implementation for sequencing runs. |
3700 |
18 Jan 16 |
nicklas |
The rules are: |
3700 |
18 Jan 16 |
nicklas |
43 |
|
3700 |
18 Jan 16 |
nicklas |
* {@link DerivedBioAssay#getJob()} job status must be {@link net.sf.basedb.core.Job.Status#DONE}. |
3700 |
18 Jan 16 |
nicklas |
* picard CheckIlluminaFiles must not return an error for any lane/tile |
3700 |
18 Jan 16 |
nicklas |
46 |
|
3700 |
18 Jan 16 |
nicklas |
If the rules are met, the auto-confirmation will continue by sending a demux job |
4306 |
17 Jan 17 |
nicklas |
to the cluster otheriwse the sequencing run ends up for manual confirmation in the |
3700 |
18 Jan 16 |
nicklas |
"Confirm sequencing ended" wizard. |
3700 |
18 Jan 16 |
nicklas |
50 |
|
3700 |
18 Jan 16 |
nicklas |
@author nicklas |
3700 |
18 Jan 16 |
nicklas |
@since 4.1 |
3700 |
18 Jan 16 |
nicklas |
53 |
*/ |
3700 |
18 Jan 16 |
nicklas |
54 |
public class SequencingRunAutoConfirmer |
3700 |
18 Jan 16 |
nicklas |
55 |
extends AutoConfirmer<DerivedBioAssay> |
3700 |
18 Jan 16 |
nicklas |
56 |
{ |
3700 |
18 Jan 16 |
nicklas |
57 |
|
7077 |
27 Mar 23 |
nicklas |
58 |
private static final ExtensionsLogger logger = |
7077 |
27 Mar 23 |
nicklas |
59 |
ExtensionsLog.getLogger(AutoConfirmService.ID, true).wrap(LoggerFactory.getLogger(SequencingRunAutoConfirmer.class)); |
3700 |
18 Jan 16 |
nicklas |
60 |
|
3700 |
18 Jan 16 |
nicklas |
61 |
public SequencingRunAutoConfirmer(DerivedBioAssay seqRun) |
3700 |
18 Jan 16 |
nicklas |
62 |
{ |
3700 |
18 Jan 16 |
nicklas |
63 |
super(seqRun, seqRun.getJob()); |
3700 |
18 Jan 16 |
nicklas |
64 |
} |
3700 |
18 Jan 16 |
nicklas |
65 |
|
3700 |
18 Jan 16 |
nicklas |
66 |
/** |
3700 |
18 Jan 16 |
nicklas |
Passes if the job ended successfully and picard CheckIlluminaDirectory |
3700 |
18 Jan 16 |
nicklas |
returns without error for all lanes. |
3700 |
18 Jan 16 |
nicklas |
69 |
*/ |
3700 |
18 Jan 16 |
nicklas |
70 |
@Override |
3700 |
18 Jan 16 |
nicklas |
71 |
public boolean checkRules(DbControl dc, AutoConfirmManager manager) |
3700 |
18 Jan 16 |
nicklas |
72 |
{ |
3700 |
18 Jan 16 |
nicklas |
73 |
DerivedBioAssay seqRun = item(dc); |
3715 |
21 Jan 16 |
nicklas |
74 |
Job job = job(dc); |
3700 |
18 Jan 16 |
nicklas |
// Job must be ended |
3700 |
18 Jan 16 |
nicklas |
76 |
if (job.getStatus() != Job.Status.DONE) return false; |
3704 |
19 Jan 16 |
nicklas |
77 |
|
3704 |
19 Jan 16 |
nicklas |
78 |
String clusterId = job.getServer(); |
4306 |
17 Jan 17 |
nicklas |
79 |
OpenGridCluster cluster = OpenGridService.getInstance().getClusterById(dc, clusterId); |
6661 |
01 Apr 22 |
nicklas |
80 |
OpenGridCluster checkCluster = ScriptUtil.autoSelectClusterWithConfig(dc, "check-illumina-directory", cluster); |
3704 |
19 Jan 16 |
nicklas |
// Get the first node or null if no node is configured |
6661 |
01 Apr 22 |
nicklas |
82 |
List<NodeConfig> nodes = checkCluster.getConfig().getNodes(); |
4306 |
17 Jan 17 |
nicklas |
83 |
String node = nodes.size() > 0 ? nodes.get(0).getName() : null; |
3700 |
18 Jan 16 |
nicklas |
84 |
|
3704 |
19 Jan 16 |
nicklas |
// Get the data we need |
3704 |
19 Jan 16 |
nicklas |
86 |
FlowCell fc = FlowCell.getBySequencingRun(dc, SequencingRun.getById(dc, seqRun.getId())); |
3704 |
19 Jan 16 |
nicklas |
87 |
PhysicalBioAssay flowCell = fc.getPhysicalBioAssay(); |
4306 |
17 Jan 17 |
nicklas |
88 |
String dataFolder = ScriptUtil.checkValidScriptParameter((String)Annotationtype.DATA_FILES_FOLDER.getAnnotationValue(dc, seqRun)); |
3704 |
19 Jan 16 |
nicklas |
89 |
int numLanes = flowCell.getSize(); |
3704 |
19 Jan 16 |
nicklas |
90 |
String flowCellType = (String)Annotationtype.FLOWCELL_TYPE.getAnnotationValue(dc, flowCell); |
3704 |
19 Jan 16 |
nicklas |
91 |
String seqCycles = (String)Annotationtype.SEQUENCING_CYCLES.getAnnotationValue(dc, seqRun); |
5545 |
06 Aug 19 |
nicklas |
92 |
Pipeline pipeline = Pipeline.getByName((String)Annotationtype.PIPELINE.getAnnotationValue(dc, seqRun)); |
5545 |
06 Aug 19 |
nicklas |
93 |
String readString = DemuxMergeServlet.sequencingCycles2ReadStringPicard(seqCycles, pipeline, flowCellType); |
3700 |
18 Jan 16 |
nicklas |
94 |
|
3704 |
19 Jan 16 |
nicklas |
// Run Picard CheckIlluminaDirectory for each lane |
4306 |
17 Jan 17 |
nicklas |
96 |
OpenGridSession session = null; |
3704 |
19 Jan 16 |
nicklas |
97 |
try |
3704 |
19 Jan 16 |
nicklas |
98 |
{ |
6661 |
01 Apr 22 |
nicklas |
99 |
session = checkCluster.connect(5); |
3704 |
19 Jan 16 |
nicklas |
100 |
for (int laneNo = 1; laneNo <= numLanes; laneNo++) |
3704 |
19 Jan 16 |
nicklas |
101 |
{ |
7030 |
09 Feb 23 |
nicklas |
102 |
CmdResult<String> result = SequencingRunServlet.checkIlluminaDirectory(session, node, dataFolder, readString, laneNo, 120); |
3704 |
19 Jan 16 |
nicklas |
103 |
if (result.getExitStatus() != 0) |
3704 |
19 Jan 16 |
nicklas |
104 |
{ |
3704 |
19 Jan 16 |
nicklas |
105 |
logger.error("Failed when checking CheckIlluminaDirectory: " + result.getStderr(), result.getException()); |
3704 |
19 Jan 16 |
nicklas |
106 |
return false; |
3704 |
19 Jan 16 |
nicklas |
107 |
} |
3704 |
19 Jan 16 |
nicklas |
108 |
} |
3704 |
19 Jan 16 |
nicklas |
109 |
} |
3704 |
19 Jan 16 |
nicklas |
110 |
finally |
3704 |
19 Jan 16 |
nicklas |
111 |
{ |
4306 |
17 Jan 17 |
nicklas |
112 |
OpenGrid.close(session); |
3704 |
19 Jan 16 |
nicklas |
113 |
} |
3704 |
19 Jan 16 |
nicklas |
114 |
|
3700 |
18 Jan 16 |
nicklas |
115 |
return true; |
3700 |
18 Jan 16 |
nicklas |
116 |
} |
3700 |
18 Jan 16 |
nicklas |
117 |
|
3700 |
18 Jan 16 |
nicklas |
118 |
/** |
3700 |
18 Jan 16 |
nicklas |
Set "SequencingResult" flag to successful and confirm the sequencing run. |
3700 |
18 Jan 16 |
nicklas |
120 |
*/ |
3700 |
18 Jan 16 |
nicklas |
121 |
@Override |
3700 |
18 Jan 16 |
nicklas |
122 |
public boolean autoConfirm(DbControl dc, AutoConfirmManager manager) |
3700 |
18 Jan 16 |
nicklas |
123 |
{ |
3700 |
18 Jan 16 |
nicklas |
124 |
DerivedBioAssay seqRun = item(dc); |
3700 |
18 Jan 16 |
nicklas |
125 |
FlowCell fc = FlowCell.getBySequencingRun(dc, SequencingRun.getById(dc, seqRun.getId())); |
3700 |
18 Jan 16 |
nicklas |
126 |
PhysicalBioAssay flowCell = fc.getPhysicalBioAssay(); |
3700 |
18 Jan 16 |
nicklas |
127 |
|
3700 |
18 Jan 16 |
nicklas |
// Reset auto-processing so that it shows up in the manual wizard if |
3700 |
18 Jan 16 |
nicklas |
// starting the next step fails |
3700 |
18 Jan 16 |
nicklas |
130 |
Annotationtype.AUTO_PROCESSING.setAnnotationValue(dc, seqRun, null); |
3700 |
18 Jan 16 |
nicklas |
131 |
|
3700 |
18 Jan 16 |
nicklas |
132 |
Annotationtype.SEQUENCING_CONFIRMED.setAnnotationValue(dc, seqRun, true); |
3700 |
18 Jan 16 |
nicklas |
133 |
Annotationtype.SEQUENCING_RESULT.setAnnotationValue(dc, seqRun, SequencingRun.SEQUENCING_SUCCESSFUL); |
3700 |
18 Jan 16 |
nicklas |
134 |
Annotationtype.SEQUENCING_RESULT.setAnnotationValue(dc, flowCell, SequencingRun.SEQUENCING_SUCCESSFUL); |
3700 |
18 Jan 16 |
nicklas |
135 |
|
5421 |
13 May 19 |
nicklas |
136 |
ActivityDef.SEQUENCING_AUTOCONFIRMED.create(dc, flowCell.getName(), 1).setUser("Auto-confirm"); |
5382 |
24 Apr 19 |
nicklas |
137 |
|
3700 |
18 Jan 16 |
nicklas |
138 |
return true; |
3700 |
18 Jan 16 |
nicklas |
139 |
} |
3700 |
18 Jan 16 |
nicklas |
140 |
|
3700 |
18 Jan 16 |
nicklas |
141 |
/** |
3700 |
18 Jan 16 |
nicklas |
Schedule a demux run on the cluster. |
3700 |
18 Jan 16 |
nicklas |
143 |
*/ |
3700 |
18 Jan 16 |
nicklas |
144 |
@Override |
3700 |
18 Jan 16 |
nicklas |
145 |
public boolean startNextStep(SessionControl sc, AutoConfirmManager manager) |
3700 |
18 Jan 16 |
nicklas |
146 |
{ |
3715 |
21 Jan 16 |
nicklas |
147 |
DbControl dc = null; |
3715 |
21 Jan 16 |
nicklas |
148 |
try |
3715 |
21 Jan 16 |
nicklas |
149 |
{ |
6599 |
22 Feb 22 |
nicklas |
150 |
dc = sc.newDbControl("Reggie: Auto-confirm sequencing - start demux"); |
3715 |
21 Jan 16 |
nicklas |
151 |
|
3715 |
21 Jan 16 |
nicklas |
// Load items |
3715 |
21 Jan 16 |
nicklas |
153 |
Job job = job(dc); |
3715 |
21 Jan 16 |
nicklas |
154 |
DerivedBioAssay seqRun = item(dc); |
5491 |
13 Jun 19 |
nicklas |
155 |
String pipelineName = (String)Annotationtype.PIPELINE.getAnnotationValue(dc, seqRun); |
5491 |
13 Jun 19 |
nicklas |
156 |
Pipeline pipeline = Pipeline.getByName(pipelineName); |
5494 |
14 Jun 19 |
nicklas |
157 |
|
3715 |
21 Jan 16 |
nicklas |
158 |
SequencingRun sr = SequencingRun.getById(dc, seqRun.getId()); |
3715 |
21 Jan 16 |
nicklas |
159 |
FlowCell fc = FlowCell.getBySequencingRun(dc, sr); |
3715 |
21 Jan 16 |
nicklas |
160 |
PhysicalBioAssay flowCell = fc.getPhysicalBioAssay(); |
3715 |
21 Jan 16 |
nicklas |
161 |
|
3715 |
21 Jan 16 |
nicklas |
162 |
boolean debug = Boolean.TRUE.equals(job.getParameterValue("debug")); |
3715 |
21 Jan 16 |
nicklas |
163 |
Integer priority = (Integer)job.getParameterValue("priority"); |
6982 |
17 Jan 23 |
nicklas |
164 |
String partition = job.getParameterValue("partition"); |
3715 |
21 Jan 16 |
nicklas |
165 |
|
6213 |
15 Apr 21 |
nicklas |
166 |
Filter<Annotatable> pipelineFilter = Annotationtype.PIPELINE.createFilter(pipelineName); |
6213 |
15 Apr 21 |
nicklas |
167 |
Filter<Annotatable> demuxFilter = new AllOfFilter<>(Arrays.asList(pipelineFilter, Annotationtype.DEMUX_TYPE.createFilter("Picard"))); |
6213 |
15 Apr 21 |
nicklas |
168 |
Filter<Annotatable> mergeFilter = new AllOfFilter<>(Arrays.asList(pipelineFilter, Annotationtype.MERGE_TYPE.createFilter("Default"))); |
6213 |
15 Apr 21 |
nicklas |
169 |
Protocol demuxProtocol = (Protocol)Subtype.DEMUX_PROTOCOL.getLatestProjectDefault(dc, demuxFilter); |
6213 |
15 Apr 21 |
nicklas |
170 |
Software demuxSoftware = (Software)Subtype.DEMUX_SOFTWARE.getLatestProjectDefault(dc, demuxFilter); |
6213 |
15 Apr 21 |
nicklas |
171 |
Protocol mergeProtocol = (Protocol)Subtype.MERGE_PROTOCOL.getLatestProjectDefault(dc, mergeFilter); |
6213 |
15 Apr 21 |
nicklas |
172 |
Software mergeSoftware = (Software)Subtype.MERGE_SOFTWARE.getLatestProjectDefault(dc, mergeFilter); |
3715 |
21 Jan 16 |
nicklas |
173 |
|
3715 |
21 Jan 16 |
nicklas |
174 |
String flowCellType = (String)Annotationtype.FLOWCELL_TYPE.getAnnotationValue(dc, flowCell); |
3715 |
21 Jan 16 |
nicklas |
175 |
String seqCycles = (String)Annotationtype.SEQUENCING_CYCLES.getAnnotationValue(dc, seqRun); |
5545 |
06 Aug 19 |
nicklas |
176 |
String readString = DemuxMergeServlet.sequencingCycles2ReadStringPicard(seqCycles, pipeline, flowCellType); |
4306 |
17 Jan 17 |
nicklas |
177 |
|
4306 |
17 Jan 17 |
nicklas |
178 |
String clusterId = job.getServer(); |
4306 |
17 Jan 17 |
nicklas |
179 |
OpenGridCluster cluster = OpenGridService.getInstance().getClusterById(dc, clusterId); |
3715 |
21 Jan 16 |
nicklas |
180 |
|
3715 |
21 Jan 16 |
nicklas |
181 |
if (logger.isDebugEnabled()) |
3715 |
21 Jan 16 |
nicklas |
182 |
{ |
3715 |
21 Jan 16 |
nicklas |
183 |
logger.debug("Starting demux job on cluster: " + clusterId); |
3715 |
21 Jan 16 |
nicklas |
184 |
logger.debug("Demux software/protocol: " + demuxSoftware + "/" + demuxProtocol); |
3715 |
21 Jan 16 |
nicklas |
185 |
logger.debug("Merge software/protocol: " + mergeSoftware + "/" + mergeProtocol); |
3715 |
21 Jan 16 |
nicklas |
186 |
} |
3715 |
21 Jan 16 |
nicklas |
187 |
|
3715 |
21 Jan 16 |
nicklas |
188 |
if (cluster == null) |
3715 |
21 Jan 16 |
nicklas |
189 |
{ |
3715 |
21 Jan 16 |
nicklas |
// If we don't have required items, abort and revert to manual start |
3715 |
21 Jan 16 |
nicklas |
191 |
return false; |
3715 |
21 Jan 16 |
nicklas |
192 |
} |
6982 |
17 Jan 23 |
nicklas |
193 |
OpenGridCluster demuxCluster = ScriptUtil.autoSelectClusterWithConfig(dc, pipeline == Pipeline.MIPS ? "demux-mips" : "demux", cluster); |
3715 |
21 Jan 16 |
nicklas |
194 |
|
5491 |
13 Jun 19 |
nicklas |
195 |
DemuxJobCreator jobCreator = pipeline == Pipeline.MIPS ? new MipsDemuxJobCreator() : new RnaSeqDemuxJobCreator(); |
5491 |
13 Jun 19 |
nicklas |
196 |
|
3715 |
21 Jan 16 |
nicklas |
197 |
jobCreator.setDemuxProtocol(demuxProtocol); |
3715 |
21 Jan 16 |
nicklas |
198 |
jobCreator.setDemuxSoftware(demuxSoftware); |
3715 |
21 Jan 16 |
nicklas |
199 |
jobCreator.setMergeProtocol(mergeProtocol); |
3715 |
21 Jan 16 |
nicklas |
200 |
jobCreator.setMergeSoftware(mergeSoftware); |
3715 |
21 Jan 16 |
nicklas |
201 |
jobCreator.setAutoConfirm(true); |
3715 |
21 Jan 16 |
nicklas |
202 |
jobCreator.setDebug(debug); |
6982 |
17 Jan 23 |
nicklas |
203 |
if (cluster == demuxCluster) jobCreator.setPartition(partition); |
6982 |
17 Jan 23 |
nicklas |
204 |
jobCreator.setPartition(partition); |
3715 |
21 Jan 16 |
nicklas |
205 |
|
6280 |
09 Jun 21 |
nicklas |
206 |
DemuxDefinition demuxDef = new DemuxDefinition(sr, readString, null, null, false); |
6982 |
17 Jan 23 |
nicklas |
207 |
Job demuxJob = jobCreator.createDemuxJob(dc, demuxCluster, Arrays.asList(demuxDef), null); |
3715 |
21 Jan 16 |
nicklas |
208 |
dc.commit(); |
3715 |
21 Jan 16 |
nicklas |
209 |
|
3715 |
21 Jan 16 |
nicklas |
210 |
if (logger.isDebugEnabled()) |
3715 |
21 Jan 16 |
nicklas |
211 |
{ |
6982 |
17 Jan 23 |
nicklas |
212 |
logger.debug("Submitted demux job to " + demuxCluster.getConnectionInfo().getName() + " with id " + demuxJob.getExternalId()); |
3715 |
21 Jan 16 |
nicklas |
213 |
} |
3715 |
21 Jan 16 |
nicklas |
214 |
} |
3715 |
21 Jan 16 |
nicklas |
215 |
finally |
3715 |
21 Jan 16 |
nicklas |
216 |
{ |
3715 |
21 Jan 16 |
nicklas |
217 |
if (dc != null) dc.close(); |
3715 |
21 Jan 16 |
nicklas |
218 |
} |
3715 |
21 Jan 16 |
nicklas |
219 |
|
3715 |
21 Jan 16 |
nicklas |
220 |
return true; |
3700 |
18 Jan 16 |
nicklas |
221 |
} |
3700 |
18 Jan 16 |
nicklas |
222 |
|
3700 |
18 Jan 16 |
nicklas |
223 |
} |