5627 |
24 Sep 19 |
nicklas |
1 |
package net.sf.basedb.reggie.ssp; |
5627 |
24 Sep 19 |
nicklas |
2 |
|
5627 |
24 Sep 19 |
nicklas |
3 |
import java.io.IOException; |
5668 |
15 Oct 19 |
nicklas |
4 |
import java.util.ArrayList; |
5627 |
24 Sep 19 |
nicklas |
5 |
import java.util.Date; |
5627 |
24 Sep 19 |
nicklas |
6 |
import java.util.List; |
5962 |
03 Jun 20 |
nicklas |
7 |
import java.util.Map; |
5627 |
24 Sep 19 |
nicklas |
8 |
|
5627 |
24 Sep 19 |
nicklas |
9 |
import net.sf.basedb.core.DbControl; |
5627 |
24 Sep 19 |
nicklas |
10 |
import net.sf.basedb.core.File; |
5627 |
24 Sep 19 |
nicklas |
11 |
import net.sf.basedb.core.ItemNotFoundException; |
5627 |
24 Sep 19 |
nicklas |
12 |
import net.sf.basedb.reggie.Reggie; |
5627 |
24 Sep 19 |
nicklas |
13 |
import net.sf.basedb.reggie.XmlConfig; |
5627 |
24 Sep 19 |
nicklas |
14 |
import net.sf.basedb.reggie.dao.Datafiletype; |
5627 |
24 Sep 19 |
nicklas |
15 |
import net.sf.basedb.reggie.dao.Rawbioassay; |
6035 |
29 Oct 20 |
nicklas |
16 |
import net.sf.basedb.reggie.script.RFunction; |
6036 |
02 Nov 20 |
nicklas |
17 |
import net.sf.basedb.reggie.script.ScriptResult; |
6035 |
29 Oct 20 |
nicklas |
18 |
import net.sf.basedb.reggie.script.RScriptDefinition; |
6035 |
29 Oct 20 |
nicklas |
19 |
import net.sf.basedb.reggie.script.TemporaryWorkDir; |
5627 |
24 Sep 19 |
nicklas |
20 |
import net.sf.basedb.util.Values; |
5627 |
24 Sep 19 |
nicklas |
21 |
import net.sf.basedb.util.formatter.Formatter; |
5627 |
24 Sep 19 |
nicklas |
22 |
|
5627 |
24 Sep 19 |
nicklas |
23 |
|
5627 |
24 Sep 19 |
nicklas |
24 |
/** |
5627 |
24 Sep 19 |
nicklas |
Wrapper class for calling the R script(s) used for the Single Sample Predictor. |
5627 |
24 Sep 19 |
nicklas |
The wrapper has been designed to run multiple SSP models for a single rawbioassay |
5627 |
24 Sep 19 |
nicklas |
in one go, and a single instance can then be used to run multiple raw bioassays |
5627 |
24 Sep 19 |
nicklas |
after each other. See {@link #run(DbControl, Rawbioassay, List)}. |
5627 |
24 Sep 19 |
nicklas |
29 |
|
5627 |
24 Sep 19 |
nicklas |
Data files will be copied to a temporary working directory as needed. It |
5627 |
24 Sep 19 |
nicklas |
is recommended that the {@link #removeWorkDir()} method is called as soon |
5627 |
24 Sep 19 |
nicklas |
as the analysis is complete. After that, the instance cannot be used any more. |
5627 |
24 Sep 19 |
nicklas |
33 |
|
5627 |
24 Sep 19 |
nicklas |
Configuration options are taken from reggie-config.xml/reggie/rscript/ssp. |
5627 |
24 Sep 19 |
nicklas |
35 |
|
5627 |
24 Sep 19 |
nicklas |
@since 4.24 |
5627 |
24 Sep 19 |
nicklas |
37 |
*/ |
5627 |
24 Sep 19 |
nicklas |
38 |
public class SspAnalysis |
5627 |
24 Sep 19 |
nicklas |
39 |
extends RScriptDefinition |
5627 |
24 Sep 19 |
nicklas |
40 |
{ |
5627 |
24 Sep 19 |
nicklas |
41 |
|
5627 |
24 Sep 19 |
nicklas |
42 |
private final RFunction ssp; |
5962 |
03 Jun 20 |
nicklas |
43 |
private final RFunction info; |
5627 |
24 Sep 19 |
nicklas |
44 |
private final String sourceDir; |
5627 |
24 Sep 19 |
nicklas |
45 |
private final String modelsDir; |
5627 |
24 Sep 19 |
nicklas |
46 |
private final TemporaryWorkDir tmp; |
5627 |
24 Sep 19 |
nicklas |
47 |
|
5627 |
24 Sep 19 |
nicklas |
48 |
public SspAnalysis() |
5627 |
24 Sep 19 |
nicklas |
49 |
throws IOException |
5627 |
24 Sep 19 |
nicklas |
50 |
{ |
5627 |
24 Sep 19 |
nicklas |
51 |
XmlConfig config = Reggie.getConfig(); |
5627 |
24 Sep 19 |
nicklas |
// Check that files and directories exists |
5627 |
24 Sep 19 |
nicklas |
53 |
sourceDir = config.getRequiredConfig("rscript/ssp/path", null); |
5627 |
24 Sep 19 |
nicklas |
54 |
Reggie.checkFile(sourceDir, true); |
5627 |
24 Sep 19 |
nicklas |
55 |
modelsDir = config.getConfig("rscript/ssp/models-dir", null, sourceDir + "/models"); |
5627 |
24 Sep 19 |
nicklas |
56 |
Reggie.checkFile(modelsDir, true); |
5627 |
24 Sep 19 |
nicklas |
57 |
|
5627 |
24 Sep 19 |
nicklas |
// Create a temporary working directory |
5627 |
24 Sep 19 |
nicklas |
59 |
this.tmp = TemporaryWorkDir.create("SSP", Reggie.CONVERTER_DATE_TO_STRING.convert(new Date()), this); |
5627 |
24 Sep 19 |
nicklas |
60 |
setWorkDir(tmp.getWorkDir().getAbsolutePath()); |
5627 |
24 Sep 19 |
nicklas |
61 |
|
5627 |
24 Sep 19 |
nicklas |
// The wrapper script will be saved to the working diretory |
5627 |
24 Sep 19 |
nicklas |
63 |
setScript("./runSSP.R"); |
5627 |
24 Sep 19 |
nicklas |
64 |
|
5627 |
24 Sep 19 |
nicklas |
65 |
ssp = addFunction("runSSP"); |
5627 |
24 Sep 19 |
nicklas |
66 |
ssp.setParameter("sourceDir", "'" + sourceDir + "'"); |
5627 |
24 Sep 19 |
nicklas |
67 |
ssp.setParameter("modelsDir", "'" + modelsDir + "'"); |
5962 |
03 Jun 20 |
nicklas |
68 |
|
5962 |
03 Jun 20 |
nicklas |
69 |
info = addFunction("getInfo"); |
5962 |
03 Jun 20 |
nicklas |
70 |
info.setParameter("sourceDir", "'" + sourceDir + "'"); |
5962 |
03 Jun 20 |
nicklas |
71 |
info.setParameter("modelsDir", "'" + modelsDir + "'"); |
5627 |
24 Sep 19 |
nicklas |
72 |
} |
5627 |
24 Sep 19 |
nicklas |
73 |
|
5627 |
24 Sep 19 |
nicklas |
74 |
/** |
5627 |
24 Sep 19 |
nicklas |
Run one or more SSP models for the given raw bioassay. |
5627 |
24 Sep 19 |
nicklas |
76 |
*/ |
5627 |
24 Sep 19 |
nicklas |
77 |
public Result run(DbControl dc, Rawbioassay raw, List<SspModel> models) |
5627 |
24 Sep 19 |
nicklas |
78 |
{ |
5627 |
24 Sep 19 |
nicklas |
79 |
File tsvFile = raw.getFile(dc, Datafiletype.GENERIC_RAWDATA); |
5627 |
24 Sep 19 |
nicklas |
80 |
if (tsvFile == null) |
5627 |
24 Sep 19 |
nicklas |
81 |
{ |
5627 |
24 Sep 19 |
nicklas |
82 |
throw new ItemNotFoundException(Datafiletype.GENERIC_RAWDATA.getName() + " for raw bioassay " + raw.getName()); |
5627 |
24 Sep 19 |
nicklas |
83 |
} |
5627 |
24 Sep 19 |
nicklas |
84 |
|
5627 |
24 Sep 19 |
nicklas |
85 |
ssp.setParameter("tsvFile", "'./"+raw.getName()+"_"+tsvFile.getName()+"'"); |
5627 |
24 Sep 19 |
nicklas |
86 |
|
5962 |
03 Jun 20 |
nicklas |
87 |
String modelsParam = Values.getString(models, ",", true, new ModelParameterFormatter()); |
5627 |
24 Sep 19 |
nicklas |
88 |
ssp.setParameter("models", "c("+modelsParam+")"); |
5627 |
24 Sep 19 |
nicklas |
89 |
|
5962 |
03 Jun 20 |
nicklas |
90 |
Result result = run(new Result(raw, tsvFile, models), ssp); |
5627 |
24 Sep 19 |
nicklas |
91 |
return result; |
5627 |
24 Sep 19 |
nicklas |
92 |
} |
5627 |
24 Sep 19 |
nicklas |
93 |
|
5627 |
24 Sep 19 |
nicklas |
94 |
/** |
5962 |
03 Jun 20 |
nicklas |
Get information about the given SSP models. |
5962 |
03 Jun 20 |
nicklas |
96 |
*/ |
5962 |
03 Jun 20 |
nicklas |
97 |
public Info info(DbControl dc, List<SspModel> models) |
5962 |
03 Jun 20 |
nicklas |
98 |
{ |
5962 |
03 Jun 20 |
nicklas |
99 |
String modelsParam = Values.getString(models, ",", true, new ModelParameterFormatter()); |
5962 |
03 Jun 20 |
nicklas |
100 |
info.setParameter("models", "c("+modelsParam+")"); |
5962 |
03 Jun 20 |
nicklas |
101 |
|
5962 |
03 Jun 20 |
nicklas |
102 |
Info result = run(new Info(models), info); |
5962 |
03 Jun 20 |
nicklas |
103 |
return result; |
5962 |
03 Jun 20 |
nicklas |
104 |
} |
5962 |
03 Jun 20 |
nicklas |
105 |
|
5962 |
03 Jun 20 |
nicklas |
106 |
/** |
5627 |
24 Sep 19 |
nicklas |
Cleanup the temporary workdir |
5627 |
24 Sep 19 |
nicklas |
108 |
*/ |
5627 |
24 Sep 19 |
nicklas |
109 |
@Override |
5627 |
24 Sep 19 |
nicklas |
110 |
public void removeWorkDir() |
5627 |
24 Sep 19 |
nicklas |
111 |
{ |
5627 |
24 Sep 19 |
nicklas |
112 |
tmp.close(); |
5627 |
24 Sep 19 |
nicklas |
113 |
setWorkDir(null); |
5627 |
24 Sep 19 |
nicklas |
114 |
} |
5627 |
24 Sep 19 |
nicklas |
115 |
|
5627 |
24 Sep 19 |
nicklas |
116 |
|
5627 |
24 Sep 19 |
nicklas |
117 |
public class Result |
6036 |
02 Nov 20 |
nicklas |
118 |
extends ScriptResult |
5627 |
24 Sep 19 |
nicklas |
119 |
{ |
5627 |
24 Sep 19 |
nicklas |
120 |
public final Rawbioassay raw; |
5627 |
24 Sep 19 |
nicklas |
121 |
public final File tsvFile; |
5668 |
15 Oct 19 |
nicklas |
122 |
private final List<SspModel> models; |
5627 |
24 Sep 19 |
nicklas |
123 |
|
5627 |
24 Sep 19 |
nicklas |
124 |
/** |
5627 |
24 Sep 19 |
nicklas |
Creates a new result object for the given raw bioassay. |
5627 |
24 Sep 19 |
nicklas |
126 |
*/ |
5668 |
15 Oct 19 |
nicklas |
127 |
public Result(Rawbioassay raw, File tsvFile, List<SspModel> models) |
5627 |
24 Sep 19 |
nicklas |
128 |
{ |
5627 |
24 Sep 19 |
nicklas |
129 |
super(); |
5627 |
24 Sep 19 |
nicklas |
130 |
this.raw = raw; |
5627 |
24 Sep 19 |
nicklas |
131 |
this.tsvFile = tsvFile; |
5668 |
15 Oct 19 |
nicklas |
132 |
this.models = models; |
5627 |
24 Sep 19 |
nicklas |
133 |
} |
5627 |
24 Sep 19 |
nicklas |
134 |
|
5668 |
15 Oct 19 |
nicklas |
135 |
/** |
5668 |
15 Oct 19 |
nicklas |
Get the result for each of the specified models. |
5668 |
15 Oct 19 |
nicklas |
137 |
*/ |
5668 |
15 Oct 19 |
nicklas |
138 |
public List<SspModelResult> getModelResults() |
5668 |
15 Oct 19 |
nicklas |
139 |
{ |
5668 |
15 Oct 19 |
nicklas |
140 |
List<SspModelResult> modelResults = new ArrayList<>(models.size()); |
5668 |
15 Oct 19 |
nicklas |
// Split result into lines, Note that output may contain other information |
5668 |
15 Oct 19 |
nicklas |
// and the only lines we are interested in should start/end with '<' and '>' (eg. <Basal>) |
5668 |
15 Oct 19 |
nicklas |
143 |
String[] lines = getStdout().split("[\n\r]+"); |
5668 |
15 Oct 19 |
nicklas |
144 |
int modelNo = 0; |
5668 |
15 Oct 19 |
nicklas |
145 |
for (String line : lines) |
5668 |
15 Oct 19 |
nicklas |
146 |
{ |
5668 |
15 Oct 19 |
nicklas |
147 |
if (!line.startsWith("<") || !line.endsWith(">")) continue; // with the next line |
5668 |
15 Oct 19 |
nicklas |
148 |
String result = line.substring(1, line.length()-1); |
5668 |
15 Oct 19 |
nicklas |
149 |
modelResults.add(new SspModelResult(raw, models.get(modelNo), result)); |
5668 |
15 Oct 19 |
nicklas |
150 |
modelNo++; |
5668 |
15 Oct 19 |
nicklas |
151 |
} |
5668 |
15 Oct 19 |
nicklas |
152 |
return modelResults; |
5668 |
15 Oct 19 |
nicklas |
153 |
} |
5668 |
15 Oct 19 |
nicklas |
154 |
|
5627 |
24 Sep 19 |
nicklas |
155 |
@Override |
5627 |
24 Sep 19 |
nicklas |
156 |
protected void loadFilesToWorkDir() |
5627 |
24 Sep 19 |
nicklas |
157 |
throws IOException |
5627 |
24 Sep 19 |
nicklas |
158 |
{ |
5627 |
24 Sep 19 |
nicklas |
159 |
createWorkFile("runSSP.R", false, SspAnalysis.class.getResourceAsStream("/net/sf/basedb/reggie/ssp/runSSP.R"), true); |
5627 |
24 Sep 19 |
nicklas |
160 |
createWorkFile(raw.getName()+"_"+tsvFile.getName(), false, tsvFile.getDownloadStream(0), true); |
5627 |
24 Sep 19 |
nicklas |
161 |
} |
5962 |
03 Jun 20 |
nicklas |
162 |
|
5962 |
03 Jun 20 |
nicklas |
163 |
@Override |
5962 |
03 Jun 20 |
nicklas |
164 |
protected void cleanupWorkDir() |
5962 |
03 Jun 20 |
nicklas |
165 |
{ |
5962 |
03 Jun 20 |
nicklas |
166 |
removeWorkFile(raw.getName()+"_"+tsvFile.getName()); |
5962 |
03 Jun 20 |
nicklas |
167 |
} |
5627 |
24 Sep 19 |
nicklas |
168 |
|
5627 |
24 Sep 19 |
nicklas |
169 |
} |
5627 |
24 Sep 19 |
nicklas |
170 |
|
5962 |
03 Jun 20 |
nicklas |
171 |
public class Info |
6036 |
02 Nov 20 |
nicklas |
172 |
extends ScriptResult |
5962 |
03 Jun 20 |
nicklas |
173 |
{ |
5962 |
03 Jun 20 |
nicklas |
174 |
private final List<SspModel> models; |
5962 |
03 Jun 20 |
nicklas |
175 |
/** |
5962 |
03 Jun 20 |
nicklas |
Creates a new result object for the given models. |
5962 |
03 Jun 20 |
nicklas |
177 |
*/ |
5962 |
03 Jun 20 |
nicklas |
178 |
public Info(List<SspModel> models) |
5962 |
03 Jun 20 |
nicklas |
179 |
{ |
5962 |
03 Jun 20 |
nicklas |
180 |
super(); |
5962 |
03 Jun 20 |
nicklas |
181 |
this.models = models; |
5962 |
03 Jun 20 |
nicklas |
182 |
} |
5962 |
03 Jun 20 |
nicklas |
183 |
|
5962 |
03 Jun 20 |
nicklas |
184 |
/** |
5962 |
03 Jun 20 |
nicklas |
Get the result for each of the specified models. |
5962 |
03 Jun 20 |
nicklas |
186 |
*/ |
5962 |
03 Jun 20 |
nicklas |
187 |
public List<SspInfoResult> getInfoResults() |
5962 |
03 Jun 20 |
nicklas |
188 |
{ |
5962 |
03 Jun 20 |
nicklas |
189 |
List<SspInfoResult> modelResults = new ArrayList<>(models.size()); |
5962 |
03 Jun 20 |
nicklas |
// Split result into lines, Note that output may contain other information |
5962 |
03 Jun 20 |
nicklas |
// and the only lines we are interested in should start/end with '<' and '>' (eg. <Basal>) |
5962 |
03 Jun 20 |
nicklas |
192 |
String[] lines = getStdout().split("[\n\r]+"); |
5962 |
03 Jun 20 |
nicklas |
193 |
int modelNo = 0; |
5962 |
03 Jun 20 |
nicklas |
194 |
Map<String, String> translations = SspModel.getTranslations(); |
5962 |
03 Jun 20 |
nicklas |
195 |
for (String line : lines) |
5962 |
03 Jun 20 |
nicklas |
196 |
{ |
5962 |
03 Jun 20 |
nicklas |
197 |
if (!line.startsWith("<") || !line.endsWith(">")) continue; // with the next line |
5962 |
03 Jun 20 |
nicklas |
198 |
String result = line.substring(1, line.length()-1); |
5962 |
03 Jun 20 |
nicklas |
199 |
modelResults.add(new SspInfoResult(models.get(modelNo), result, translations)); |
5962 |
03 Jun 20 |
nicklas |
200 |
modelNo++; |
5962 |
03 Jun 20 |
nicklas |
201 |
} |
5962 |
03 Jun 20 |
nicklas |
202 |
return modelResults; |
5962 |
03 Jun 20 |
nicklas |
203 |
} |
5962 |
03 Jun 20 |
nicklas |
204 |
|
5962 |
03 Jun 20 |
nicklas |
205 |
@Override |
5962 |
03 Jun 20 |
nicklas |
206 |
protected void loadFilesToWorkDir() |
5962 |
03 Jun 20 |
nicklas |
207 |
throws IOException |
5962 |
03 Jun 20 |
nicklas |
208 |
{ |
5962 |
03 Jun 20 |
nicklas |
209 |
createWorkFile("runSSP.R", false, SspAnalysis.class.getResourceAsStream("/net/sf/basedb/reggie/ssp/runSSP.R"), true); |
5962 |
03 Jun 20 |
nicklas |
210 |
} |
5962 |
03 Jun 20 |
nicklas |
211 |
|
5962 |
03 Jun 20 |
nicklas |
212 |
} |
5962 |
03 Jun 20 |
nicklas |
213 |
|
5962 |
03 Jun 20 |
nicklas |
214 |
public static class ModelParameterFormatter |
5962 |
03 Jun 20 |
nicklas |
215 |
implements Formatter<SspModel> |
5962 |
03 Jun 20 |
nicklas |
216 |
{ |
5962 |
03 Jun 20 |
nicklas |
217 |
@Override |
5962 |
03 Jun 20 |
nicklas |
218 |
public String format(SspModel m) |
5962 |
03 Jun 20 |
nicklas |
219 |
{ |
5962 |
03 Jun 20 |
nicklas |
220 |
return "'" + m.getModelData() + "'"; |
5962 |
03 Jun 20 |
nicklas |
221 |
} |
5962 |
03 Jun 20 |
nicklas |
222 |
|
5962 |
03 Jun 20 |
nicklas |
223 |
@Override |
5962 |
03 Jun 20 |
nicklas |
224 |
public SspModel parseString(String arg0) |
5962 |
03 Jun 20 |
nicklas |
225 |
{ |
5962 |
03 Jun 20 |
nicklas |
226 |
return null; |
5962 |
03 Jun 20 |
nicklas |
227 |
} |
5962 |
03 Jun 20 |
nicklas |
228 |
} |
5627 |
24 Sep 19 |
nicklas |
229 |
} |