5199 |
15 Dec 09 |
nicklas |
1 |
/** |
5199 |
15 Dec 09 |
nicklas |
$Id$ |
5199 |
15 Dec 09 |
nicklas |
3 |
|
5199 |
15 Dec 09 |
nicklas |
Copyright (C) 2009 Nicklas Nordborg |
5199 |
15 Dec 09 |
nicklas |
5 |
|
5199 |
15 Dec 09 |
nicklas |
This file is part of BASE - BioArray Software Environment. |
5199 |
15 Dec 09 |
nicklas |
Available at http://base.thep.lu.se/ |
5199 |
15 Dec 09 |
nicklas |
8 |
|
5199 |
15 Dec 09 |
nicklas |
BASE is free software; you can redistribute it and/or |
5199 |
15 Dec 09 |
nicklas |
modify it under the terms of the GNU General Public License |
5199 |
15 Dec 09 |
nicklas |
as published by the Free Software Foundation; either version 3 |
5199 |
15 Dec 09 |
nicklas |
of the License, or (at your option) any later version. |
5199 |
15 Dec 09 |
nicklas |
13 |
|
5199 |
15 Dec 09 |
nicklas |
BASE is distributed in the hope that it will be useful, |
5199 |
15 Dec 09 |
nicklas |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
5199 |
15 Dec 09 |
nicklas |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
5199 |
15 Dec 09 |
nicklas |
GNU General Public License for more details. |
5199 |
15 Dec 09 |
nicklas |
18 |
|
5199 |
15 Dec 09 |
nicklas |
You should have received a copy of the GNU General Public License |
5199 |
15 Dec 09 |
nicklas |
along with BASE. If not, see <http://www.gnu.org/licenses/>. |
5199 |
15 Dec 09 |
nicklas |
21 |
*/ |
5199 |
15 Dec 09 |
nicklas |
22 |
package net.sf.basedb.util.export.spotdata; |
5199 |
15 Dec 09 |
nicklas |
23 |
|
5199 |
15 Dec 09 |
nicklas |
24 |
import java.io.IOException; |
5199 |
15 Dec 09 |
nicklas |
25 |
import java.sql.SQLException; |
5199 |
15 Dec 09 |
nicklas |
26 |
import java.util.ArrayList; |
5199 |
15 Dec 09 |
nicklas |
27 |
import java.util.Arrays; |
5199 |
15 Dec 09 |
nicklas |
28 |
import java.util.Collection; |
5199 |
15 Dec 09 |
nicklas |
29 |
import java.util.Collections; |
5199 |
15 Dec 09 |
nicklas |
30 |
import java.util.HashSet; |
5199 |
15 Dec 09 |
nicklas |
31 |
import java.util.LinkedHashMap; |
5199 |
15 Dec 09 |
nicklas |
32 |
import java.util.List; |
5199 |
15 Dec 09 |
nicklas |
33 |
import java.util.Map; |
5199 |
15 Dec 09 |
nicklas |
34 |
import java.util.Set; |
5199 |
15 Dec 09 |
nicklas |
35 |
|
5199 |
15 Dec 09 |
nicklas |
36 |
import net.sf.basedb.core.BioAssay; |
5199 |
15 Dec 09 |
nicklas |
37 |
import net.sf.basedb.core.DatabaseException; |
5199 |
15 Dec 09 |
nicklas |
38 |
import net.sf.basedb.core.DbControl; |
5199 |
15 Dec 09 |
nicklas |
39 |
import net.sf.basedb.core.DynamicPositionQuery; |
5199 |
15 Dec 09 |
nicklas |
40 |
import net.sf.basedb.core.DynamicResultIterator; |
5199 |
15 Dec 09 |
nicklas |
41 |
import net.sf.basedb.core.DynamicSpotQuery; |
5199 |
15 Dec 09 |
nicklas |
42 |
import net.sf.basedb.core.ProgressReporter; |
5199 |
15 Dec 09 |
nicklas |
43 |
import net.sf.basedb.core.Type; |
5199 |
15 Dec 09 |
nicklas |
44 |
import net.sf.basedb.core.query.SqlResult; |
5405 |
10 Sep 10 |
nicklas |
45 |
import net.sf.basedb.core.signal.ThreadSignalHandler; |
5199 |
15 Dec 09 |
nicklas |
46 |
import net.sf.basedb.util.ChainedProgressReporter; |
5199 |
15 Dec 09 |
nicklas |
47 |
import net.sf.basedb.util.Values; |
5199 |
15 Dec 09 |
nicklas |
48 |
import net.sf.basedb.util.bfs.AnnotationWriter; |
5199 |
15 Dec 09 |
nicklas |
49 |
import net.sf.basedb.util.bfs.DataWriter; |
5199 |
15 Dec 09 |
nicklas |
50 |
import net.sf.basedb.util.bfs.DataWriterFactory; |
5199 |
15 Dec 09 |
nicklas |
51 |
import net.sf.basedb.util.bfs.MetadataWriter; |
5199 |
15 Dec 09 |
nicklas |
52 |
import net.sf.basedb.util.bfs.MetadataModel.SectionEntry; |
5199 |
15 Dec 09 |
nicklas |
53 |
import net.sf.basedb.util.formatter.Formatter; |
5199 |
15 Dec 09 |
nicklas |
54 |
import net.sf.basedb.util.formatter.ToStringFormatter; |
5199 |
15 Dec 09 |
nicklas |
55 |
|
5199 |
15 Dec 09 |
nicklas |
56 |
/** |
5199 |
15 Dec 09 |
nicklas |
Base class for exporting spotdata to BFS format. This class will |
5199 |
15 Dec 09 |
nicklas |
do most of the hard work. A subclass is required to: |
5199 |
15 Dec 09 |
nicklas |
<ul> |
5199 |
15 Dec 09 |
nicklas |
<li> |
5199 |
15 Dec 09 |
nicklas |
<li>create a list of data writers that will output the actual |
5199 |
15 Dec 09 |
nicklas |
spot data (see {@link #createDataWriters()}). |
5199 |
15 Dec 09 |
nicklas |
<li>rearrange the data that is loaded by the query to the |
5199 |
15 Dec 09 |
nicklas |
correct data writer (see {@link #arrangeData(int, short, Object[][], Object[])}). |
5199 |
15 Dec 09 |
nicklas |
</ul> |
5199 |
15 Dec 09 |
nicklas |
66 |
|
5199 |
15 Dec 09 |
nicklas |
<p> |
5199 |
15 Dec 09 |
nicklas |
Before the exporter can be used it must be configured. The most important options are: |
5199 |
15 Dec 09 |
nicklas |
<ul> |
5199 |
15 Dec 09 |
nicklas |
<li>{@link #setDbControl(DbControl)} (required): Sets the DbControl that is used for database access. |
5199 |
15 Dec 09 |
nicklas |
<li>{@link #setSource(net.sf.basedb.core.BioAssaySet)} (required): Sets the bioassay set that data should |
5199 |
15 Dec 09 |
nicklas |
be exported from. |
5199 |
15 Dec 09 |
nicklas |
<li>{@link #setMetadataWriter(MetadataWriter)} (required): Sets the writer stream were BFS metadata is |
5199 |
15 Dec 09 |
nicklas |
written. |
5199 |
15 Dec 09 |
nicklas |
<li>{@link #setReporterAnnotationsWriter(AnnotationWriter)} and {@link #addReporterField(DynamicField)} |
5199 |
15 Dec 09 |
nicklas |
(optional): Sets the writer stream were reporter annoatations are written and selects which |
5199 |
15 Dec 09 |
nicklas |
reporter annotations to export. If no writer is specified the reporter annotations file is not |
5199 |
15 Dec 09 |
nicklas |
created. |
5199 |
15 Dec 09 |
nicklas |
<li>{@link #setAssayAnnotationsWriter(AnnotationWriter)} and {@link #addAssayField(AssayField)} |
5199 |
15 Dec 09 |
nicklas |
(optional): Sets the writer stream were assay annotations is written and selects which |
5199 |
15 Dec 09 |
nicklas |
assay annotations to export. If no writer is specified the assay annotations file is not |
5199 |
15 Dec 09 |
nicklas |
created. |
5319 |
20 Apr 10 |
nicklas |
<li>{@link #setDataWriterFactory(DataWriterFactory)} and {@link #addSpotField(DynamicField)} |
5199 |
15 Dec 09 |
nicklas |
(optional): Sets the factory that should be used to create output files and selects which |
5199 |
15 Dec 09 |
nicklas |
spot data to export. The number of files and the data arrangement depends on the subtype. |
5199 |
15 Dec 09 |
nicklas |
<li>{@link #setParameter(String, String...)} (optional): Additional parameters that are needed |
5199 |
15 Dec 09 |
nicklas |
by, for example, a plug-in that is about to process the exported data files. |
5199 |
15 Dec 09 |
nicklas |
</ul> |
5199 |
15 Dec 09 |
nicklas |
89 |
|
5199 |
15 Dec 09 |
nicklas |
90 |
|
5199 |
15 Dec 09 |
nicklas |
@author Nicklas |
5199 |
15 Dec 09 |
nicklas |
@version 2.15 |
5199 |
15 Dec 09 |
nicklas |
@base.modified $Date$ |
5199 |
15 Dec 09 |
nicklas |
94 |
*/ |
5199 |
15 Dec 09 |
nicklas |
95 |
public abstract class BfsExporter |
5199 |
15 Dec 09 |
nicklas |
96 |
extends AbstractBioAssaySetExporter |
5199 |
15 Dec 09 |
nicklas |
97 |
{ |
5199 |
15 Dec 09 |
nicklas |
98 |
|
5319 |
20 Apr 10 |
nicklas |
99 |
private boolean autoCloseWriters; |
6875 |
20 Apr 15 |
nicklas |
100 |
@SuppressWarnings("rawtypes") |
5199 |
15 Dec 09 |
nicklas |
101 |
private DataWriterFactory dataWriterFactory; |
5199 |
15 Dec 09 |
nicklas |
102 |
private Map<String, String[]> parameters; |
5199 |
15 Dec 09 |
nicklas |
103 |
private MetadataWriter metadataWriter; |
5199 |
15 Dec 09 |
nicklas |
104 |
private AnnotationWriter reporterWriter; |
5199 |
15 Dec 09 |
nicklas |
105 |
private AnnotationWriter assayWriter; |
5199 |
15 Dec 09 |
nicklas |
106 |
private List<DataWriter> dataWriters; |
5199 |
15 Dec 09 |
nicklas |
107 |
private List<SectionEntry> extraFiles; |
5199 |
15 Dec 09 |
nicklas |
108 |
private ChainedProgressReporter chainedProgress; |
5199 |
15 Dec 09 |
nicklas |
109 |
private long spotCount; |
5199 |
15 Dec 09 |
nicklas |
110 |
private Set<Integer> exportedPositions; |
5199 |
15 Dec 09 |
nicklas |
111 |
|
5199 |
15 Dec 09 |
nicklas |
112 |
protected BfsExporter() |
5199 |
15 Dec 09 |
nicklas |
113 |
{ |
5199 |
15 Dec 09 |
nicklas |
114 |
this.parameters = new LinkedHashMap<String, String[]>(); |
5199 |
15 Dec 09 |
nicklas |
115 |
this.extraFiles = new ArrayList<SectionEntry>(); |
5319 |
20 Apr 10 |
nicklas |
116 |
this.autoCloseWriters = true; |
5199 |
15 Dec 09 |
nicklas |
117 |
} |
5199 |
15 Dec 09 |
nicklas |
118 |
|
5199 |
15 Dec 09 |
nicklas |
119 |
/* |
5199 |
15 Dec 09 |
nicklas |
Configuration properties |
5199 |
15 Dec 09 |
nicklas |
121 |
------------------------ |
5199 |
15 Dec 09 |
nicklas |
122 |
*/ |
5199 |
15 Dec 09 |
nicklas |
123 |
/** |
5319 |
20 Apr 10 |
nicklas |
If this option is set then all writers are automatically closed |
5319 |
20 Apr 10 |
nicklas |
when all data has been writted to them. This setting is enabled by default. |
5319 |
20 Apr 10 |
nicklas |
126 |
*/ |
5319 |
20 Apr 10 |
nicklas |
127 |
public void setAutoCloseWriters(boolean autoClose) |
5319 |
20 Apr 10 |
nicklas |
128 |
{ |
5319 |
20 Apr 10 |
nicklas |
129 |
this.autoCloseWriters = autoClose; |
5319 |
20 Apr 10 |
nicklas |
130 |
} |
5319 |
20 Apr 10 |
nicklas |
131 |
|
5319 |
20 Apr 10 |
nicklas |
132 |
/** |
5199 |
15 Dec 09 |
nicklas |
Set the stream were the metadata should be written. This |
5199 |
15 Dec 09 |
nicklas |
stream is required before it is possible to start the |
5199 |
15 Dec 09 |
nicklas |
export. It is expected that the given writer is a fresh writer |
5199 |
15 Dec 09 |
nicklas |
and that no data has been written to it yet. |
5199 |
15 Dec 09 |
nicklas |
137 |
*/ |
5199 |
15 Dec 09 |
nicklas |
138 |
public void setMetadataWriter(MetadataWriter metadataWriter) |
5199 |
15 Dec 09 |
nicklas |
139 |
{ |
5199 |
15 Dec 09 |
nicklas |
140 |
this.metadataWriter = metadataWriter; |
5199 |
15 Dec 09 |
nicklas |
141 |
} |
5199 |
15 Dec 09 |
nicklas |
142 |
|
5199 |
15 Dec 09 |
nicklas |
143 |
/** |
5199 |
15 Dec 09 |
nicklas |
Set the stream were reporter annotations should be written. This is optional |
5199 |
15 Dec 09 |
nicklas |
and if not given, no reporter annotations file is generated. The |
5199 |
15 Dec 09 |
nicklas |
writer must return a filename from {@link AnnotationWriter#getFilename()} |
5199 |
15 Dec 09 |
nicklas |
since this is required in the metadata file. |
5199 |
15 Dec 09 |
nicklas |
<p> |
5199 |
15 Dec 09 |
nicklas |
Use {@link #addReporterField(DynamicField)} to register reporter |
5199 |
15 Dec 09 |
nicklas |
fields to export. The position number is always exported. |
5199 |
15 Dec 09 |
nicklas |
151 |
|
5199 |
15 Dec 09 |
nicklas |
@param reporterWriter An annotation writer, or null if no reporter |
5199 |
15 Dec 09 |
nicklas |
annotation file should be created |
5199 |
15 Dec 09 |
nicklas |
154 |
*/ |
5199 |
15 Dec 09 |
nicklas |
155 |
public void setReporterAnnotationsWriter(AnnotationWriter reporterWriter) |
5199 |
15 Dec 09 |
nicklas |
156 |
{ |
5199 |
15 Dec 09 |
nicklas |
157 |
this.reporterWriter = reporterWriter; |
5199 |
15 Dec 09 |
nicklas |
158 |
} |
5199 |
15 Dec 09 |
nicklas |
159 |
|
5199 |
15 Dec 09 |
nicklas |
160 |
/** |
5199 |
15 Dec 09 |
nicklas |
Set the stream were assay annotations should be written. This is optional |
5199 |
15 Dec 09 |
nicklas |
and if not given, no assay annotations file is generated. The |
5199 |
15 Dec 09 |
nicklas |
writer must return a filename from {@link AnnotationWriter#getFilename()} |
5199 |
15 Dec 09 |
nicklas |
since this is required in the metadata file. |
5199 |
15 Dec 09 |
nicklas |
<p> |
5199 |
15 Dec 09 |
nicklas |
Use {@link #addAssayField(AssayField)} to register fields to export. |
5199 |
15 Dec 09 |
nicklas |
The assay id is always exported. |
5199 |
15 Dec 09 |
nicklas |
168 |
|
5199 |
15 Dec 09 |
nicklas |
@param assayWriter An annotation writer, or null if no assay |
5199 |
15 Dec 09 |
nicklas |
annotations file should be created |
5199 |
15 Dec 09 |
nicklas |
171 |
*/ |
5199 |
15 Dec 09 |
nicklas |
172 |
public void setAssayAnnotationsWriter(AnnotationWriter assayWriter) |
5199 |
15 Dec 09 |
nicklas |
173 |
{ |
5199 |
15 Dec 09 |
nicklas |
174 |
this.assayWriter = assayWriter; |
5199 |
15 Dec 09 |
nicklas |
175 |
} |
5199 |
15 Dec 09 |
nicklas |
176 |
|
5199 |
15 Dec 09 |
nicklas |
177 |
/** |
5199 |
15 Dec 09 |
nicklas |
Set the data writer factory to use for generating spot data files. |
5199 |
15 Dec 09 |
nicklas |
What files that are required depends on the BFS subtype. Eg. |
5199 |
15 Dec 09 |
nicklas |
the serial format uses a file per assay and the matrix format |
5199 |
15 Dec 09 |
nicklas |
uses a file per spot field. A data writer factory is optional |
5199 |
15 Dec 09 |
nicklas |
and if not given, no spot data is exported. |
5199 |
15 Dec 09 |
nicklas |
183 |
|
5199 |
15 Dec 09 |
nicklas |
@param dataWriterFactory A data writer factory, or null if no spot |
5199 |
15 Dec 09 |
nicklas |
data files should be created |
5199 |
15 Dec 09 |
nicklas |
186 |
*/ |
5199 |
15 Dec 09 |
nicklas |
187 |
public void setDataWriterFactory(DataWriterFactory<?> dataWriterFactory) |
5199 |
15 Dec 09 |
nicklas |
188 |
{ |
5199 |
15 Dec 09 |
nicklas |
189 |
this.dataWriterFactory = dataWriterFactory; |
5199 |
15 Dec 09 |
nicklas |
190 |
} |
5199 |
15 Dec 09 |
nicklas |
191 |
|
5199 |
15 Dec 09 |
nicklas |
192 |
/** |
5199 |
15 Dec 09 |
nicklas |
Add a parameter that is exported in the [parameters] section. |
5199 |
15 Dec 09 |
nicklas |
There can be one or more values for a given key, which are then |
5199 |
15 Dec 09 |
nicklas |
separated by tab characters. The parameters are written to the file |
5199 |
15 Dec 09 |
nicklas |
in the order they are registered by this method. |
5199 |
15 Dec 09 |
nicklas |
<p> |
5199 |
15 Dec 09 |
nicklas |
NOTE! Calling this method twice with the same key, overwrites the |
5199 |
15 Dec 09 |
nicklas |
existing parameters, but doesn't change the order they are written |
5199 |
15 Dec 09 |
nicklas |
to the file. |
5199 |
15 Dec 09 |
nicklas |
201 |
|
5199 |
15 Dec 09 |
nicklas |
@param key The parameter key (if null this method call is ignored) |
5199 |
15 Dec 09 |
nicklas |
@param values The parameter value (may be null) |
5199 |
15 Dec 09 |
nicklas |
204 |
*/ |
5199 |
15 Dec 09 |
nicklas |
205 |
public void setParameter(String key, String... values) |
5199 |
15 Dec 09 |
nicklas |
206 |
{ |
5199 |
15 Dec 09 |
nicklas |
207 |
if (key == null) return; |
5199 |
15 Dec 09 |
nicklas |
208 |
parameters.put(key, values); |
5199 |
15 Dec 09 |
nicklas |
209 |
} |
5199 |
15 Dec 09 |
nicklas |
210 |
|
5199 |
15 Dec 09 |
nicklas |
211 |
/** |
5199 |
15 Dec 09 |
nicklas |
Get the current value of a parameter. |
5199 |
15 Dec 09 |
nicklas |
@param key The parameter key |
5199 |
15 Dec 09 |
nicklas |
@return The value, or null if no values has been registered for |
5199 |
15 Dec 09 |
nicklas |
the key (or if the registered value is null) |
5199 |
15 Dec 09 |
nicklas |
216 |
*/ |
5199 |
15 Dec 09 |
nicklas |
217 |
public String[] getParameter(String key) |
5199 |
15 Dec 09 |
nicklas |
218 |
{ |
5199 |
15 Dec 09 |
nicklas |
219 |
return parameters.get(key); |
5199 |
15 Dec 09 |
nicklas |
220 |
} |
5199 |
15 Dec 09 |
nicklas |
221 |
|
5199 |
15 Dec 09 |
nicklas |
222 |
|
5199 |
15 Dec 09 |
nicklas |
223 |
@Override |
5199 |
15 Dec 09 |
nicklas |
224 |
public void addReporterField(DynamicField field) |
5199 |
15 Dec 09 |
nicklas |
225 |
{ |
5199 |
15 Dec 09 |
nicklas |
226 |
super.addReporterField(field); |
5199 |
15 Dec 09 |
nicklas |
227 |
} |
5199 |
15 Dec 09 |
nicklas |
228 |
|
5199 |
15 Dec 09 |
nicklas |
229 |
/** |
5199 |
15 Dec 09 |
nicklas |
Add multiple reporter fields in one go. A null collection is ignored and |
5199 |
15 Dec 09 |
nicklas |
so are null values in the collection. |
5199 |
15 Dec 09 |
nicklas |
@param fields A collection with the fields that should be added |
5199 |
15 Dec 09 |
nicklas |
233 |
*/ |
5199 |
15 Dec 09 |
nicklas |
234 |
public void addReporterFields(Collection<? extends DynamicField> fields) |
5199 |
15 Dec 09 |
nicklas |
235 |
{ |
5199 |
15 Dec 09 |
nicklas |
236 |
if (fields == null) return; |
5199 |
15 Dec 09 |
nicklas |
237 |
for (DynamicField f : fields) |
5199 |
15 Dec 09 |
nicklas |
238 |
{ |
5199 |
15 Dec 09 |
nicklas |
239 |
addReporterField(f); |
5199 |
15 Dec 09 |
nicklas |
240 |
} |
5199 |
15 Dec 09 |
nicklas |
241 |
} |
5199 |
15 Dec 09 |
nicklas |
242 |
|
5199 |
15 Dec 09 |
nicklas |
243 |
@Override |
5199 |
15 Dec 09 |
nicklas |
244 |
public List<DynamicField> getReporterFields() |
5199 |
15 Dec 09 |
nicklas |
245 |
{ |
5199 |
15 Dec 09 |
nicklas |
246 |
return super.getReporterFields(); |
5199 |
15 Dec 09 |
nicklas |
247 |
} |
5199 |
15 Dec 09 |
nicklas |
248 |
|
5199 |
15 Dec 09 |
nicklas |
249 |
@Override |
5199 |
15 Dec 09 |
nicklas |
250 |
public void addAssayField(AssayField field) |
5199 |
15 Dec 09 |
nicklas |
251 |
{ |
5199 |
15 Dec 09 |
nicklas |
252 |
super.addAssayField(field); |
5199 |
15 Dec 09 |
nicklas |
253 |
} |
5199 |
15 Dec 09 |
nicklas |
254 |
|
5199 |
15 Dec 09 |
nicklas |
255 |
/** |
5199 |
15 Dec 09 |
nicklas |
Add multiple assay fields in one go. A null collection is ignored and |
5199 |
15 Dec 09 |
nicklas |
so are null values in the collection. |
5199 |
15 Dec 09 |
nicklas |
@param fields A collection with the fields that should be added |
5199 |
15 Dec 09 |
nicklas |
259 |
*/ |
5199 |
15 Dec 09 |
nicklas |
260 |
public void addAssayFields(Collection<? extends AssayField> fields) |
5199 |
15 Dec 09 |
nicklas |
261 |
{ |
5199 |
15 Dec 09 |
nicklas |
262 |
if (fields == null) return; |
5199 |
15 Dec 09 |
nicklas |
263 |
for (AssayField f : fields) |
5199 |
15 Dec 09 |
nicklas |
264 |
{ |
5199 |
15 Dec 09 |
nicklas |
265 |
addAssayField(f); |
5199 |
15 Dec 09 |
nicklas |
266 |
} |
5199 |
15 Dec 09 |
nicklas |
267 |
} |
5199 |
15 Dec 09 |
nicklas |
268 |
|
5199 |
15 Dec 09 |
nicklas |
269 |
@Override |
5199 |
15 Dec 09 |
nicklas |
270 |
public List<AssayField> getAssayFields() |
5199 |
15 Dec 09 |
nicklas |
271 |
{ |
5199 |
15 Dec 09 |
nicklas |
272 |
return super.getAssayFields(); |
5199 |
15 Dec 09 |
nicklas |
273 |
} |
5199 |
15 Dec 09 |
nicklas |
274 |
|
5199 |
15 Dec 09 |
nicklas |
275 |
/** |
5199 |
15 Dec 09 |
nicklas |
Add information about a spot field that should be exported. |
5199 |
15 Dec 09 |
nicklas |
@param spotField The spot field information |
5199 |
15 Dec 09 |
nicklas |
278 |
*/ |
5319 |
20 Apr 10 |
nicklas |
279 |
@Override |
5319 |
20 Apr 10 |
nicklas |
280 |
public void addSpotField(DynamicField spotField) |
5199 |
15 Dec 09 |
nicklas |
281 |
{ |
5199 |
15 Dec 09 |
nicklas |
282 |
super.addSpotField(spotField); |
5199 |
15 Dec 09 |
nicklas |
283 |
} |
5319 |
20 Apr 10 |
nicklas |
284 |
|
5199 |
15 Dec 09 |
nicklas |
285 |
/** |
5319 |
20 Apr 10 |
nicklas |
Add multiple spot fields in one go. A null collection is ignored and |
5319 |
20 Apr 10 |
nicklas |
so are null values in the collection. |
5319 |
20 Apr 10 |
nicklas |
@param fields A collection with the fields that should be added |
5319 |
20 Apr 10 |
nicklas |
289 |
*/ |
5319 |
20 Apr 10 |
nicklas |
290 |
public void addSpotFields(Collection<? extends DynamicField> fields) |
5319 |
20 Apr 10 |
nicklas |
291 |
{ |
5319 |
20 Apr 10 |
nicklas |
292 |
if (fields == null) return; |
5319 |
20 Apr 10 |
nicklas |
293 |
for (DynamicField f : fields) |
5319 |
20 Apr 10 |
nicklas |
294 |
{ |
5319 |
20 Apr 10 |
nicklas |
295 |
addSpotField(f); |
5319 |
20 Apr 10 |
nicklas |
296 |
} |
5319 |
20 Apr 10 |
nicklas |
297 |
} |
5319 |
20 Apr 10 |
nicklas |
298 |
|
5319 |
20 Apr 10 |
nicklas |
299 |
@Override |
5319 |
20 Apr 10 |
nicklas |
300 |
public List<DynamicField> getSpotFields() |
5319 |
20 Apr 10 |
nicklas |
301 |
{ |
5319 |
20 Apr 10 |
nicklas |
302 |
return super.getSpotFields(); |
5319 |
20 Apr 10 |
nicklas |
303 |
} |
5319 |
20 Apr 10 |
nicklas |
304 |
|
5319 |
20 Apr 10 |
nicklas |
305 |
/** |
5199 |
15 Dec 09 |
nicklas |
Add information about an extra data file that is included |
5199 |
15 Dec 09 |
nicklas |
as part of the BFS. This exporter will register this information |
5199 |
15 Dec 09 |
nicklas |
as an entry in the [files] section in the metadata file. |
5199 |
15 Dec 09 |
nicklas |
It will not check that the file actually exists or do any |
5199 |
15 Dec 09 |
nicklas |
other action with the file. |
5199 |
15 Dec 09 |
nicklas |
<p> |
5199 |
15 Dec 09 |
nicklas |
File entries are written in the order they are registered by |
5199 |
15 Dec 09 |
nicklas |
this method. Multiple entries with the same key are allowed |
5199 |
15 Dec 09 |
nicklas |
(eg. the previous entry is not replaced). |
5199 |
15 Dec 09 |
nicklas |
<p> |
5199 |
15 Dec 09 |
nicklas |
316 |
|
5199 |
15 Dec 09 |
nicklas |
@param key The key for the file |
5199 |
15 Dec 09 |
nicklas |
@param filename The name of the file |
5199 |
15 Dec 09 |
nicklas |
319 |
*/ |
5199 |
15 Dec 09 |
nicklas |
320 |
public void addExtraFile(String key, String filename) |
5199 |
15 Dec 09 |
nicklas |
321 |
{ |
5199 |
15 Dec 09 |
nicklas |
322 |
extraFiles.add(new SectionEntry(key, filename)); |
5199 |
15 Dec 09 |
nicklas |
323 |
} |
5199 |
15 Dec 09 |
nicklas |
324 |
|
5199 |
15 Dec 09 |
nicklas |
325 |
// -------------------------------------- |
5199 |
15 Dec 09 |
nicklas |
326 |
|
5199 |
15 Dec 09 |
nicklas |
327 |
/* |
5199 |
15 Dec 09 |
nicklas |
From the AbstractBioAssaySetExporter class |
5199 |
15 Dec 09 |
nicklas |
329 |
------------------------------------------ |
5199 |
15 Dec 09 |
nicklas |
330 |
*/ |
5199 |
15 Dec 09 |
nicklas |
331 |
@Override |
5199 |
15 Dec 09 |
nicklas |
332 |
protected void validate() |
5199 |
15 Dec 09 |
nicklas |
333 |
{ |
5199 |
15 Dec 09 |
nicklas |
334 |
super.validate(); |
5199 |
15 Dec 09 |
nicklas |
335 |
if (getMetadataWriter() == null) throw new NullPointerException("getMetadataWriter()"); |
5199 |
15 Dec 09 |
nicklas |
336 |
AnnotationWriter aw = getReporterAnnotationsWriter(); |
5199 |
15 Dec 09 |
nicklas |
337 |
if (aw != null && aw.getFilename() == null) |
5199 |
15 Dec 09 |
nicklas |
338 |
{ |
5199 |
15 Dec 09 |
nicklas |
339 |
throw new NullPointerException("getReporterAnnotationsWriter().getFilename()"); |
5199 |
15 Dec 09 |
nicklas |
340 |
} |
5199 |
15 Dec 09 |
nicklas |
341 |
aw = getAssayAnnotationsWriter(); |
5199 |
15 Dec 09 |
nicklas |
342 |
if (aw != null && aw.getFilename() == null) |
5199 |
15 Dec 09 |
nicklas |
343 |
{ |
5199 |
15 Dec 09 |
nicklas |
344 |
throw new NullPointerException("getAssayAnnotationsWriter().getFilename()"); |
5199 |
15 Dec 09 |
nicklas |
345 |
} |
5199 |
15 Dec 09 |
nicklas |
346 |
} |
5199 |
15 Dec 09 |
nicklas |
347 |
|
5199 |
15 Dec 09 |
nicklas |
348 |
/** |
5199 |
15 Dec 09 |
nicklas |
Validates that all required properties has been set and |
5199 |
15 Dec 09 |
nicklas |
initialises other things that are needed. |
5199 |
15 Dec 09 |
nicklas |
351 |
*/ |
5199 |
15 Dec 09 |
nicklas |
352 |
@Override |
5199 |
15 Dec 09 |
nicklas |
353 |
protected void beginExport() |
5199 |
15 Dec 09 |
nicklas |
354 |
{ |
5199 |
15 Dec 09 |
nicklas |
355 |
super.beginExport(); |
5199 |
15 Dec 09 |
nicklas |
356 |
setProgress(0, "Initializing..."); |
5199 |
15 Dec 09 |
nicklas |
357 |
ProgressReporter p = getProgressReporter(); |
5199 |
15 Dec 09 |
nicklas |
358 |
if (p != null) chainedProgress = new ChainedProgressReporter(p); |
5199 |
15 Dec 09 |
nicklas |
359 |
try |
5199 |
15 Dec 09 |
nicklas |
360 |
{ |
5199 |
15 Dec 09 |
nicklas |
361 |
if (getDataWriterFactory() != null) dataWriters = createDataWriters(); |
5213 |
12 Jan 10 |
nicklas |
362 |
if (dataWriters == null) dataWriters = Collections.emptyList(); |
5199 |
15 Dec 09 |
nicklas |
363 |
} |
5199 |
15 Dec 09 |
nicklas |
364 |
catch (IOException ex) |
5199 |
15 Dec 09 |
nicklas |
365 |
{ |
5199 |
15 Dec 09 |
nicklas |
366 |
throw new RuntimeException(ex); |
5199 |
15 Dec 09 |
nicklas |
367 |
} |
5199 |
15 Dec 09 |
nicklas |
368 |
} |
5199 |
15 Dec 09 |
nicklas |
369 |
|
5199 |
15 Dec 09 |
nicklas |
370 |
/** |
5199 |
15 Dec 09 |
nicklas |
Export the metadata and assay annotations. |
5199 |
15 Dec 09 |
nicklas |
372 |
*/ |
5199 |
15 Dec 09 |
nicklas |
373 |
@Override |
5199 |
15 Dec 09 |
nicklas |
374 |
protected boolean exportGlobalHeader() |
5199 |
15 Dec 09 |
nicklas |
375 |
{ |
5199 |
15 Dec 09 |
nicklas |
376 |
exportMetadata(); |
5199 |
15 Dec 09 |
nicklas |
377 |
exportAssayAnnotations(); |
5199 |
15 Dec 09 |
nicklas |
378 |
return true; |
5199 |
15 Dec 09 |
nicklas |
379 |
} |
5199 |
15 Dec 09 |
nicklas |
380 |
|
5199 |
15 Dec 09 |
nicklas |
381 |
/** |
5199 |
15 Dec 09 |
nicklas |
Export all spot data. |
5199 |
15 Dec 09 |
nicklas |
383 |
*/ |
5199 |
15 Dec 09 |
nicklas |
384 |
@Override |
5199 |
15 Dec 09 |
nicklas |
385 |
protected void exportSectionData() |
5199 |
15 Dec 09 |
nicklas |
386 |
{ |
5199 |
15 Dec 09 |
nicklas |
387 |
if (chainedProgress != null) chainedProgress.setRange(15, 80); |
5199 |
15 Dec 09 |
nicklas |
388 |
spotCount = exportSpotData(chainedProgress, getSource().getNumSpots()); |
5199 |
15 Dec 09 |
nicklas |
389 |
} |
5199 |
15 Dec 09 |
nicklas |
390 |
|
5199 |
15 Dec 09 |
nicklas |
391 |
/** |
5199 |
15 Dec 09 |
nicklas |
Exports reporter annotations. |
5199 |
15 Dec 09 |
nicklas |
393 |
*/ |
5199 |
15 Dec 09 |
nicklas |
394 |
@Override |
5199 |
15 Dec 09 |
nicklas |
395 |
protected void exportGlobalFooter() |
5199 |
15 Dec 09 |
nicklas |
396 |
{ |
5199 |
15 Dec 09 |
nicklas |
397 |
if (chainedProgress != null) chainedProgress.setRange(80, 95); |
5199 |
15 Dec 09 |
nicklas |
398 |
exportReporterAnnotations(chainedProgress, exportedPositions.size()); |
5199 |
15 Dec 09 |
nicklas |
399 |
} |
5199 |
15 Dec 09 |
nicklas |
400 |
|
5199 |
15 Dec 09 |
nicklas |
401 |
/** |
5199 |
15 Dec 09 |
nicklas |
Clean up. |
5199 |
15 Dec 09 |
nicklas |
403 |
*/ |
5199 |
15 Dec 09 |
nicklas |
404 |
@Override |
5199 |
15 Dec 09 |
nicklas |
405 |
protected void endExport(RuntimeException e) |
5199 |
15 Dec 09 |
nicklas |
406 |
{ |
5199 |
15 Dec 09 |
nicklas |
407 |
if (e == null) setProgress(100, "Export complete. " + spotCount + " spots done"); |
5199 |
15 Dec 09 |
nicklas |
408 |
if (exportedPositions != null) exportedPositions.clear(); |
5199 |
15 Dec 09 |
nicklas |
409 |
exportedPositions = null; |
5199 |
15 Dec 09 |
nicklas |
410 |
super.endExport(e); |
5199 |
15 Dec 09 |
nicklas |
411 |
} |
5199 |
15 Dec 09 |
nicklas |
412 |
// ------------------------------------------- |
5199 |
15 Dec 09 |
nicklas |
413 |
|
5199 |
15 Dec 09 |
nicklas |
414 |
/** |
5199 |
15 Dec 09 |
nicklas |
Get the BFS subtype. This method may be overridden by subclasses. |
5199 |
15 Dec 09 |
nicklas |
The default implementation returns null. The subtype is written to |
5199 |
15 Dec 09 |
nicklas |
the metadata file: {@link MetadataWriter#setSubtype(String)}. |
5199 |
15 Dec 09 |
nicklas |
418 |
*/ |
5199 |
15 Dec 09 |
nicklas |
419 |
public String getBFSSubtype() |
5199 |
15 Dec 09 |
nicklas |
420 |
{ |
5199 |
15 Dec 09 |
nicklas |
421 |
return null; |
5199 |
15 Dec 09 |
nicklas |
422 |
} |
5199 |
15 Dec 09 |
nicklas |
423 |
|
5199 |
15 Dec 09 |
nicklas |
424 |
/** |
5199 |
15 Dec 09 |
nicklas |
Get the writer were metadata should be printed. |
5199 |
15 Dec 09 |
nicklas |
426 |
*/ |
5199 |
15 Dec 09 |
nicklas |
427 |
protected MetadataWriter getMetadataWriter() |
5199 |
15 Dec 09 |
nicklas |
428 |
{ |
5199 |
15 Dec 09 |
nicklas |
429 |
return metadataWriter; |
5199 |
15 Dec 09 |
nicklas |
430 |
} |
5199 |
15 Dec 09 |
nicklas |
431 |
|
5199 |
15 Dec 09 |
nicklas |
432 |
/** |
5199 |
15 Dec 09 |
nicklas |
Get the writer were reporter annotations should be printed. |
5199 |
15 Dec 09 |
nicklas |
Can be null. |
5199 |
15 Dec 09 |
nicklas |
435 |
*/ |
5199 |
15 Dec 09 |
nicklas |
436 |
protected AnnotationWriter getReporterAnnotationsWriter() |
5199 |
15 Dec 09 |
nicklas |
437 |
{ |
5199 |
15 Dec 09 |
nicklas |
438 |
return reporterWriter; |
5199 |
15 Dec 09 |
nicklas |
439 |
} |
5199 |
15 Dec 09 |
nicklas |
440 |
|
5199 |
15 Dec 09 |
nicklas |
441 |
/** |
5199 |
15 Dec 09 |
nicklas |
Get the writer were assay annotations should be printed. |
5199 |
15 Dec 09 |
nicklas |
Can be null. |
5199 |
15 Dec 09 |
nicklas |
444 |
*/ |
5199 |
15 Dec 09 |
nicklas |
445 |
protected AnnotationWriter getAssayAnnotationsWriter() |
5199 |
15 Dec 09 |
nicklas |
446 |
{ |
5199 |
15 Dec 09 |
nicklas |
447 |
return assayWriter; |
5199 |
15 Dec 09 |
nicklas |
448 |
} |
5199 |
15 Dec 09 |
nicklas |
449 |
|
5199 |
15 Dec 09 |
nicklas |
450 |
/** |
5199 |
15 Dec 09 |
nicklas |
Get the factory that creates data writers. |
5199 |
15 Dec 09 |
nicklas |
Can be null. |
5199 |
15 Dec 09 |
nicklas |
453 |
*/ |
6875 |
20 Apr 15 |
nicklas |
454 |
@SuppressWarnings("rawtypes") |
5199 |
15 Dec 09 |
nicklas |
455 |
protected DataWriterFactory getDataWriterFactory() |
5199 |
15 Dec 09 |
nicklas |
456 |
{ |
5199 |
15 Dec 09 |
nicklas |
457 |
return dataWriterFactory; |
5199 |
15 Dec 09 |
nicklas |
458 |
} |
5199 |
15 Dec 09 |
nicklas |
459 |
|
5199 |
15 Dec 09 |
nicklas |
460 |
/** |
5199 |
15 Dec 09 |
nicklas |
Export the metadata file which contains information about the |
5199 |
15 Dec 09 |
nicklas |
other files (reporter annotations, assay annotations and spot data), |
5199 |
15 Dec 09 |
nicklas |
plug-in parameters, etc. Plug-in parameters are registered with |
5199 |
15 Dec 09 |
nicklas |
{@link #setParameter(String, String[])} and are written to |
5199 |
15 Dec 09 |
nicklas |
the [parameters] section. If no parameters has been registered this |
5199 |
15 Dec 09 |
nicklas |
section is skipped. |
5199 |
15 Dec 09 |
nicklas |
467 |
*/ |
5199 |
15 Dec 09 |
nicklas |
468 |
protected void exportMetadata() |
5199 |
15 Dec 09 |
nicklas |
469 |
{ |
5199 |
15 Dec 09 |
nicklas |
470 |
setProgress(5, "Exporting metadata..."); |
5199 |
15 Dec 09 |
nicklas |
471 |
MetadataWriter out = getMetadataWriter(); |
5199 |
15 Dec 09 |
nicklas |
472 |
out.setSubtype(getBFSSubtype()); |
5199 |
15 Dec 09 |
nicklas |
473 |
|
5199 |
15 Dec 09 |
nicklas |
474 |
|
5199 |
15 Dec 09 |
nicklas |
// [files] |
5199 |
15 Dec 09 |
nicklas |
476 |
out.bfsPrintSection("files", true, true); |
5199 |
15 Dec 09 |
nicklas |
// Reporter and assay annotation files |
5199 |
15 Dec 09 |
nicklas |
478 |
AnnotationWriter aw = getReporterAnnotationsWriter(); |
5199 |
15 Dec 09 |
nicklas |
479 |
if (aw != null) out.bfsPrintValue("rdata", aw.getFilename()); |
5199 |
15 Dec 09 |
nicklas |
480 |
aw = getAssayAnnotationsWriter(); |
5199 |
15 Dec 09 |
nicklas |
481 |
if (aw != null) out.bfsPrintValue("pdata", aw.getFilename()); |
5199 |
15 Dec 09 |
nicklas |
// Spot data files are labeled 'sdataN' with N = 1, 2, ... |
5199 |
15 Dec 09 |
nicklas |
483 |
int index = 1; |
5199 |
15 Dec 09 |
nicklas |
484 |
for (DataWriter dataWriter : dataWriters) |
5199 |
15 Dec 09 |
nicklas |
485 |
{ |
5199 |
15 Dec 09 |
nicklas |
486 |
out.bfsPrintValue("sdata" + index, dataWriter.getFilename()); |
5199 |
15 Dec 09 |
nicklas |
487 |
index++; |
5199 |
15 Dec 09 |
nicklas |
488 |
} |
5199 |
15 Dec 09 |
nicklas |
// Custom extra data files |
5199 |
15 Dec 09 |
nicklas |
490 |
for (SectionEntry extraFile : extraFiles) |
5199 |
15 Dec 09 |
nicklas |
491 |
{ |
5199 |
15 Dec 09 |
nicklas |
492 |
out.bfsPrintValue(extraFile.getKey(), extraFile.getValues()); |
5199 |
15 Dec 09 |
nicklas |
493 |
} |
5199 |
15 Dec 09 |
nicklas |
494 |
|
5199 |
15 Dec 09 |
nicklas |
// [parameters] |
5199 |
15 Dec 09 |
nicklas |
496 |
if (parameters.size() > 0) |
5199 |
15 Dec 09 |
nicklas |
497 |
{ |
5199 |
15 Dec 09 |
nicklas |
498 |
out.bfsPrintSection("parameters", true, true); |
5199 |
15 Dec 09 |
nicklas |
499 |
for (Map.Entry<String, String[]> entry : parameters.entrySet()) |
5199 |
15 Dec 09 |
nicklas |
500 |
{ |
5199 |
15 Dec 09 |
nicklas |
501 |
String key = entry.getKey(); |
5199 |
15 Dec 09 |
nicklas |
502 |
String[] values = entry.getValue(); |
5199 |
15 Dec 09 |
nicklas |
503 |
out.bfsPrintValue(key, values); |
5199 |
15 Dec 09 |
nicklas |
504 |
} |
5199 |
15 Dec 09 |
nicklas |
505 |
} |
5199 |
15 Dec 09 |
nicklas |
506 |
|
5199 |
15 Dec 09 |
nicklas |
// [sdata] |
5199 |
15 Dec 09 |
nicklas |
508 |
List<DynamicField> spotFields = getSpotFields(); |
5199 |
15 Dec 09 |
nicklas |
509 |
if (spotFields.size() > 0) |
5199 |
15 Dec 09 |
nicklas |
510 |
{ |
5199 |
15 Dec 09 |
nicklas |
511 |
out.bfsPrintSection("sdata", true, true); |
5199 |
15 Dec 09 |
nicklas |
512 |
for (DynamicField spotField : spotFields) |
5199 |
15 Dec 09 |
nicklas |
513 |
{ |
5319 |
20 Apr 10 |
nicklas |
514 |
Type spotType = spotField.getType(); |
5319 |
20 Apr 10 |
nicklas |
515 |
out.bfsPrintValue(spotField.getTitle(), spotType == null ? "" : spotType.getStringValue()); |
5199 |
15 Dec 09 |
nicklas |
516 |
} |
5199 |
15 Dec 09 |
nicklas |
517 |
} |
5199 |
15 Dec 09 |
nicklas |
518 |
out.flush(); |
5319 |
20 Apr 10 |
nicklas |
519 |
if (autoCloseWriters) out.close(); |
5199 |
15 Dec 09 |
nicklas |
520 |
} |
5199 |
15 Dec 09 |
nicklas |
521 |
|
5199 |
15 Dec 09 |
nicklas |
522 |
/** |
5199 |
15 Dec 09 |
nicklas |
Export the reporter annotations. This method is ignored if |
5199 |
15 Dec 09 |
nicklas |
{@link #getReporterAnnotationsWriter()} returns null. The |
5199 |
15 Dec 09 |
nicklas |
position is used as the value for the id column. Other columns |
5199 |
15 Dec 09 |
nicklas |
are exported as given by {@link #getReporterFields()}. |
5199 |
15 Dec 09 |
nicklas |
<p> |
5199 |
15 Dec 09 |
nicklas |
If a progress reporter is given, progress is updated between |
5199 |
15 Dec 09 |
nicklas |
0 and 100%. |
5199 |
15 Dec 09 |
nicklas |
<p> |
5199 |
15 Dec 09 |
nicklas |
This method needs to be executed after {@link #exportSpotData(ProgressReporter, long)} |
5199 |
15 Dec 09 |
nicklas |
since we need to know which positions that was exported. |
5199 |
15 Dec 09 |
nicklas |
533 |
|
5199 |
15 Dec 09 |
nicklas |
@param progress An optional progress reporter |
5199 |
15 Dec 09 |
nicklas |
@param count The total number of reporters, or 0 if not known |
5199 |
15 Dec 09 |
nicklas |
536 |
*/ |
6875 |
20 Apr 15 |
nicklas |
537 |
@SuppressWarnings({ "unchecked", "rawtypes" }) |
5199 |
15 Dec 09 |
nicklas |
538 |
protected void exportReporterAnnotations(ProgressReporter progress, long count) |
5199 |
15 Dec 09 |
nicklas |
539 |
{ |
5199 |
15 Dec 09 |
nicklas |
540 |
AnnotationWriter out = getReporterAnnotationsWriter(); |
5199 |
15 Dec 09 |
nicklas |
541 |
if (out == null) return; |
5199 |
15 Dec 09 |
nicklas |
542 |
|
5199 |
15 Dec 09 |
nicklas |
543 |
List<DynamicField> fields = getReporterFields(); |
5199 |
15 Dec 09 |
nicklas |
544 |
int numReporterFields = fields.size(); |
5199 |
15 Dec 09 |
nicklas |
545 |
DbControl dc = getDbControl(); |
5199 |
15 Dec 09 |
nicklas |
546 |
int posIndex = numReporterFields + 1; |
5199 |
15 Dec 09 |
nicklas |
547 |
|
5199 |
15 Dec 09 |
nicklas |
// Initialize headers and formatters |
5199 |
15 Dec 09 |
nicklas |
549 |
String[] headers = new String[numReporterFields]; |
5199 |
15 Dec 09 |
nicklas |
550 |
Formatter[] formatters = new Formatter[numReporterFields]; |
5199 |
15 Dec 09 |
nicklas |
551 |
int index = 0; |
5199 |
15 Dec 09 |
nicklas |
552 |
for (DynamicField df : fields) |
5199 |
15 Dec 09 |
nicklas |
553 |
{ |
5199 |
15 Dec 09 |
nicklas |
554 |
headers[index] = df.getTitle(); |
5199 |
15 Dec 09 |
nicklas |
555 |
Formatter f = df.getFormatter(); |
5199 |
15 Dec 09 |
nicklas |
556 |
if (f == null) f = new ToStringFormatter(); |
5199 |
15 Dec 09 |
nicklas |
557 |
formatters[index] = f; |
5199 |
15 Dec 09 |
nicklas |
558 |
index++; |
5199 |
15 Dec 09 |
nicklas |
559 |
} |
5199 |
15 Dec 09 |
nicklas |
560 |
out.bfsPrintHeaders(headers); |
5199 |
15 Dec 09 |
nicklas |
561 |
|
5199 |
15 Dec 09 |
nicklas |
562 |
if (progress != null) progress.display(0, "Loading reporter annotations..."); |
5199 |
15 Dec 09 |
nicklas |
563 |
DynamicPositionQuery query = getReporterQuery(); |
5199 |
15 Dec 09 |
nicklas |
564 |
DynamicResultIterator it = query.iterate(dc); |
5199 |
15 Dec 09 |
nicklas |
565 |
Object[] data = new Object[numReporterFields]; |
5199 |
15 Dec 09 |
nicklas |
566 |
try |
5199 |
15 Dec 09 |
nicklas |
567 |
{ |
5199 |
15 Dec 09 |
nicklas |
568 |
long numDone = 0; |
5319 |
20 Apr 10 |
nicklas |
569 |
long progressInterval = Math.max(count > 0 ? 1 + count / 100 : 100, 100); |
5199 |
15 Dec 09 |
nicklas |
570 |
while (it.hasNext()) |
5199 |
15 Dec 09 |
nicklas |
571 |
{ |
5405 |
10 Sep 10 |
nicklas |
572 |
ThreadSignalHandler.checkInterrupted(); |
5199 |
15 Dec 09 |
nicklas |
573 |
SqlResult result = it.next(); |
5199 |
15 Dec 09 |
nicklas |
574 |
|
5199 |
15 Dec 09 |
nicklas |
575 |
int position = result.getInt(posIndex); |
5199 |
15 Dec 09 |
nicklas |
576 |
if (exportedPositions.contains(position)) |
5199 |
15 Dec 09 |
nicklas |
577 |
{ |
5199 |
15 Dec 09 |
nicklas |
578 |
index = 0; |
5199 |
15 Dec 09 |
nicklas |
579 |
for (int i = 1; i <= numReporterFields; ++i) |
5199 |
15 Dec 09 |
nicklas |
580 |
{ |
5199 |
15 Dec 09 |
nicklas |
581 |
data[index] = formatters[index].format(result.getObject(i)); |
5199 |
15 Dec 09 |
nicklas |
582 |
++index; |
5199 |
15 Dec 09 |
nicklas |
583 |
} |
5199 |
15 Dec 09 |
nicklas |
584 |
out.bfsPrintData(position, data); |
5199 |
15 Dec 09 |
nicklas |
585 |
++numDone; |
5319 |
20 Apr 10 |
nicklas |
586 |
if (progress != null && numDone % progressInterval == 0) |
5199 |
15 Dec 09 |
nicklas |
587 |
{ |
5199 |
15 Dec 09 |
nicklas |
588 |
int percent = count == 0 ? 0 : 10+(int)((90L * numDone) / count); |
5199 |
15 Dec 09 |
nicklas |
589 |
progress.display(percent, "Exporting reporter annotations: " + |
5199 |
15 Dec 09 |
nicklas |
590 |
numDone + " of " + (count == 0 ? "unknown" : count) + " done"); |
5199 |
15 Dec 09 |
nicklas |
591 |
} |
5199 |
15 Dec 09 |
nicklas |
592 |
} |
5199 |
15 Dec 09 |
nicklas |
593 |
} |
5199 |
15 Dec 09 |
nicklas |
594 |
out.flush(); |
5199 |
15 Dec 09 |
nicklas |
595 |
if (progress != null) |
5199 |
15 Dec 09 |
nicklas |
596 |
{ |
5199 |
15 Dec 09 |
nicklas |
597 |
progress.display(100, numDone + " reporter annotations exported."); |
5199 |
15 Dec 09 |
nicklas |
598 |
} |
5199 |
15 Dec 09 |
nicklas |
599 |
} |
5199 |
15 Dec 09 |
nicklas |
600 |
catch (SQLException e) |
5199 |
15 Dec 09 |
nicklas |
601 |
{ |
5199 |
15 Dec 09 |
nicklas |
602 |
throw new DatabaseException(e); |
5199 |
15 Dec 09 |
nicklas |
603 |
} |
5199 |
15 Dec 09 |
nicklas |
604 |
finally |
5199 |
15 Dec 09 |
nicklas |
605 |
{ |
5199 |
15 Dec 09 |
nicklas |
606 |
if (it != null) it.close(); |
5319 |
20 Apr 10 |
nicklas |
607 |
if (out != null && autoCloseWriters) out.close(); |
5199 |
15 Dec 09 |
nicklas |
608 |
} |
5199 |
15 Dec 09 |
nicklas |
609 |
} |
5199 |
15 Dec 09 |
nicklas |
610 |
|
5199 |
15 Dec 09 |
nicklas |
611 |
|
5199 |
15 Dec 09 |
nicklas |
612 |
/** |
5199 |
15 Dec 09 |
nicklas |
Export the assay annotations. This method is ignored if |
5199 |
15 Dec 09 |
nicklas |
{@link #getAssayAnnotationsWriter()} returns null. The |
5199 |
15 Dec 09 |
nicklas |
assay ID is used as the value for the id column. Other columns |
5199 |
15 Dec 09 |
nicklas |
are exported as given by {@link #getAssayFields()}. |
5199 |
15 Dec 09 |
nicklas |
617 |
*/ |
6875 |
20 Apr 15 |
nicklas |
618 |
@SuppressWarnings({ "unchecked", "rawtypes" }) |
5199 |
15 Dec 09 |
nicklas |
619 |
protected void exportAssayAnnotations() |
5199 |
15 Dec 09 |
nicklas |
620 |
{ |
5199 |
15 Dec 09 |
nicklas |
621 |
AnnotationWriter out = getAssayAnnotationsWriter(); |
5199 |
15 Dec 09 |
nicklas |
622 |
if (out == null) return; |
5199 |
15 Dec 09 |
nicklas |
623 |
|
5199 |
15 Dec 09 |
nicklas |
624 |
setProgress(10, "Exporting assay annotations..."); |
5199 |
15 Dec 09 |
nicklas |
625 |
List<AssayField> fields = getAssayFields(); |
5199 |
15 Dec 09 |
nicklas |
626 |
int numFields = fields.size(); |
5199 |
15 Dec 09 |
nicklas |
627 |
DbControl dc = getDbControl(); |
5199 |
15 Dec 09 |
nicklas |
628 |
|
5199 |
15 Dec 09 |
nicklas |
629 |
String[] headers = new String[numFields]; |
5199 |
15 Dec 09 |
nicklas |
630 |
Formatter[] formatters = new Formatter[numFields]; |
5199 |
15 Dec 09 |
nicklas |
631 |
|
5199 |
15 Dec 09 |
nicklas |
632 |
int index = 0; |
5199 |
15 Dec 09 |
nicklas |
633 |
for (AssayField df : fields) |
5199 |
15 Dec 09 |
nicklas |
634 |
{ |
5199 |
15 Dec 09 |
nicklas |
635 |
headers[index] = df.getTitle(); |
5199 |
15 Dec 09 |
nicklas |
636 |
Formatter f = df.getFormatter(); |
5199 |
15 Dec 09 |
nicklas |
637 |
if (f == null) f = new ToStringFormatter(); |
5199 |
15 Dec 09 |
nicklas |
638 |
formatters[index] = f; |
5199 |
15 Dec 09 |
nicklas |
639 |
index++; |
5199 |
15 Dec 09 |
nicklas |
640 |
} |
5199 |
15 Dec 09 |
nicklas |
641 |
out.bfsPrintHeaders(headers); |
5199 |
15 Dec 09 |
nicklas |
642 |
|
5199 |
15 Dec 09 |
nicklas |
643 |
List<BioAssay> assays = getBioAssays(); |
5199 |
15 Dec 09 |
nicklas |
644 |
Object[] data = new Object[numFields]; |
5199 |
15 Dec 09 |
nicklas |
645 |
|
5199 |
15 Dec 09 |
nicklas |
646 |
for (BioAssay ba : assays) |
5199 |
15 Dec 09 |
nicklas |
647 |
{ |
5405 |
10 Sep 10 |
nicklas |
648 |
ThreadSignalHandler.checkInterrupted(); |
5199 |
15 Dec 09 |
nicklas |
649 |
index = 0; |
5199 |
15 Dec 09 |
nicklas |
650 |
for (int i = 1; i <= numFields; ++i) |
5199 |
15 Dec 09 |
nicklas |
651 |
{ |
5199 |
15 Dec 09 |
nicklas |
652 |
Collection<?> values = fields.get(index).getAssayValue(dc, ba); |
5199 |
15 Dec 09 |
nicklas |
653 |
data[index] = values == null || values.size() == 0 ? |
5199 |
15 Dec 09 |
nicklas |
654 |
null : Values.getString(values, ", ", true, formatters[index]); |
5199 |
15 Dec 09 |
nicklas |
655 |
++index; |
5199 |
15 Dec 09 |
nicklas |
656 |
} |
5199 |
15 Dec 09 |
nicklas |
657 |
out.bfsPrintData(ba.getId(), data); |
5199 |
15 Dec 09 |
nicklas |
658 |
} |
5199 |
15 Dec 09 |
nicklas |
659 |
out.flush(); |
5319 |
20 Apr 10 |
nicklas |
660 |
if (autoCloseWriters) out.close(); |
5199 |
15 Dec 09 |
nicklas |
661 |
} |
5199 |
15 Dec 09 |
nicklas |
662 |
|
5199 |
15 Dec 09 |
nicklas |
663 |
/** |
5199 |
15 Dec 09 |
nicklas |
Export spot data. This method needs to be executed even if no spot |
5199 |
15 Dec 09 |
nicklas |
fields has been selected. The reason is that we need to find out |
5199 |
15 Dec 09 |
nicklas |
the positions that are used in the bioassay set when exporting |
5199 |
15 Dec 09 |
nicklas |
reporter annotations. The only exception is if also no reporter |
5199 |
15 Dec 09 |
nicklas |
annotations are exported. |
5199 |
15 Dec 09 |
nicklas |
669 |
|
5199 |
15 Dec 09 |
nicklas |
@param progress An optional progress reporter |
5199 |
15 Dec 09 |
nicklas |
@param count The expected number of spots or 0 if not known |
5199 |
15 Dec 09 |
nicklas |
@return The number of spots processed |
5199 |
15 Dec 09 |
nicklas |
673 |
*/ |
6875 |
20 Apr 15 |
nicklas |
674 |
@SuppressWarnings({ "unchecked", "rawtypes" }) |
5199 |
15 Dec 09 |
nicklas |
675 |
protected long exportSpotData(ProgressReporter progress, long count) |
5199 |
15 Dec 09 |
nicklas |
676 |
{ |
5199 |
15 Dec 09 |
nicklas |
677 |
exportedPositions = new HashSet<Integer>(); |
5199 |
15 Dec 09 |
nicklas |
678 |
DbControl dc = getDbControl(); |
5199 |
15 Dec 09 |
nicklas |
679 |
List<DynamicField> spotFields = getSpotFields(); |
5199 |
15 Dec 09 |
nicklas |
680 |
int numSpotFields = spotFields.size(); |
5199 |
15 Dec 09 |
nicklas |
681 |
if (numSpotFields == 0 && getReporterFields().size() == 0) return 0; |
5199 |
15 Dec 09 |
nicklas |
682 |
|
5199 |
15 Dec 09 |
nicklas |
683 |
Formatter[] formatters = new Formatter[numSpotFields]; |
5199 |
15 Dec 09 |
nicklas |
684 |
Object[] spotData = new Object[numSpotFields]; |
5199 |
15 Dec 09 |
nicklas |
685 |
for (int i = 0; i < numSpotFields; ++i) |
5199 |
15 Dec 09 |
nicklas |
686 |
{ |
5199 |
15 Dec 09 |
nicklas |
687 |
Formatter f = spotFields.get(i).getFormatter(); |
5199 |
15 Dec 09 |
nicklas |
688 |
if (f == null) f = new ToStringFormatter(); |
5199 |
15 Dec 09 |
nicklas |
689 |
formatters[i] = f; |
5199 |
15 Dec 09 |
nicklas |
690 |
} |
5199 |
15 Dec 09 |
nicklas |
691 |
|
5199 |
15 Dec 09 |
nicklas |
692 |
Object[][] data = new Object[dataWriters.size()][]; |
5199 |
15 Dec 09 |
nicklas |
693 |
int index = 0; |
5199 |
15 Dec 09 |
nicklas |
694 |
for (DataWriter dw : dataWriters) |
5199 |
15 Dec 09 |
nicklas |
695 |
{ |
5199 |
15 Dec 09 |
nicklas |
696 |
data[index] = new Object[dw.getColumnCount()]; |
5199 |
15 Dec 09 |
nicklas |
697 |
++index; |
5199 |
15 Dec 09 |
nicklas |
698 |
} |
5199 |
15 Dec 09 |
nicklas |
699 |
|
5199 |
15 Dec 09 |
nicklas |
700 |
int posIndex = numSpotFields + 1; |
5199 |
15 Dec 09 |
nicklas |
701 |
int colIndex = numSpotFields + 2; |
5199 |
15 Dec 09 |
nicklas |
702 |
int currentPosition = -1; |
5199 |
15 Dec 09 |
nicklas |
703 |
|
5199 |
15 Dec 09 |
nicklas |
// Execute the query |
5199 |
15 Dec 09 |
nicklas |
705 |
if (progress != null) progress.display(0, "Loading spot data..."); |
5199 |
15 Dec 09 |
nicklas |
706 |
DynamicSpotQuery spotQuery = getSpotQuery(false); |
5199 |
15 Dec 09 |
nicklas |
707 |
DynamicResultIterator it = spotQuery.iterate(dc); |
5199 |
15 Dec 09 |
nicklas |
708 |
long numDone = 0; |
5199 |
15 Dec 09 |
nicklas |
709 |
try |
5199 |
15 Dec 09 |
nicklas |
710 |
{ |
5319 |
20 Apr 10 |
nicklas |
711 |
long progressInterval = Math.max(count > 0 ? 1 + count / 100 : 100, 100); |
5199 |
15 Dec 09 |
nicklas |
712 |
while (it.hasNext()) |
5199 |
15 Dec 09 |
nicklas |
713 |
{ |
5405 |
10 Sep 10 |
nicklas |
714 |
ThreadSignalHandler.checkInterrupted(); |
5199 |
15 Dec 09 |
nicklas |
715 |
SqlResult result = it.next(); |
5199 |
15 Dec 09 |
nicklas |
716 |
|
5199 |
15 Dec 09 |
nicklas |
717 |
int position = result.getInt(posIndex); |
5199 |
15 Dec 09 |
nicklas |
718 |
short column = result.getShort(colIndex); |
5199 |
15 Dec 09 |
nicklas |
719 |
if (position != currentPosition) |
5199 |
15 Dec 09 |
nicklas |
720 |
{ |
5199 |
15 Dec 09 |
nicklas |
721 |
if (currentPosition != -1) |
5199 |
15 Dec 09 |
nicklas |
722 |
{ |
5199 |
15 Dec 09 |
nicklas |
// print out data for the old position |
5199 |
15 Dec 09 |
nicklas |
724 |
index = 0; |
5199 |
15 Dec 09 |
nicklas |
725 |
for (DataWriter writer : dataWriters) |
5199 |
15 Dec 09 |
nicklas |
726 |
{ |
5199 |
15 Dec 09 |
nicklas |
727 |
writer.bfsPrintData(data[index]); |
5199 |
15 Dec 09 |
nicklas |
728 |
Arrays.fill(data[index], null); |
5199 |
15 Dec 09 |
nicklas |
729 |
index++; |
5199 |
15 Dec 09 |
nicklas |
730 |
} |
5223 |
26 Jan 10 |
nicklas |
731 |
exportedPositions.add(currentPosition); |
5199 |
15 Dec 09 |
nicklas |
732 |
} |
5199 |
15 Dec 09 |
nicklas |
733 |
currentPosition = position; |
5199 |
15 Dec 09 |
nicklas |
734 |
} |
5199 |
15 Dec 09 |
nicklas |
735 |
|
5199 |
15 Dec 09 |
nicklas |
// Copy formatted spot field values into the spotData array... |
5199 |
15 Dec 09 |
nicklas |
737 |
for (int i = 0; i < spotData.length; ++i) |
5199 |
15 Dec 09 |
nicklas |
738 |
{ |
5199 |
15 Dec 09 |
nicklas |
739 |
spotData[i] = formatters[i].format(result.getObject(i+1)); |
5199 |
15 Dec 09 |
nicklas |
740 |
} |
5199 |
15 Dec 09 |
nicklas |
// ... and let the subclass arrange the data into the output array |
5213 |
12 Jan 10 |
nicklas |
742 |
if (numSpotFields > 0) arrangeData(position, column, data, spotData); |
5199 |
15 Dec 09 |
nicklas |
743 |
|
5199 |
15 Dec 09 |
nicklas |
744 |
++numDone; |
5319 |
20 Apr 10 |
nicklas |
745 |
if (progress != null && numDone % progressInterval == 0) |
5199 |
15 Dec 09 |
nicklas |
746 |
{ |
5199 |
15 Dec 09 |
nicklas |
747 |
int percent = count == 0 ? 0 : 10+(int)((90L * numDone) / count); |
5199 |
15 Dec 09 |
nicklas |
748 |
progress.display(percent, "Exporting spot data: " + |
5199 |
15 Dec 09 |
nicklas |
749 |
numDone + " of " + (count == 0 ? "unknown" : count) + " done"); |
5199 |
15 Dec 09 |
nicklas |
750 |
} |
5199 |
15 Dec 09 |
nicklas |
751 |
} |
5199 |
15 Dec 09 |
nicklas |
752 |
|
5199 |
15 Dec 09 |
nicklas |
// Print out the final data line |
5199 |
15 Dec 09 |
nicklas |
754 |
exportedPositions.add(currentPosition); |
5199 |
15 Dec 09 |
nicklas |
755 |
index = 0; |
5199 |
15 Dec 09 |
nicklas |
756 |
for (DataWriter writer : dataWriters) |
5199 |
15 Dec 09 |
nicklas |
757 |
{ |
5199 |
15 Dec 09 |
nicklas |
758 |
writer.bfsPrintData(data[index]); |
5199 |
15 Dec 09 |
nicklas |
759 |
writer.flush(); |
5319 |
20 Apr 10 |
nicklas |
760 |
if (autoCloseWriters) writer.close(); |
5199 |
15 Dec 09 |
nicklas |
761 |
index++; |
5199 |
15 Dec 09 |
nicklas |
762 |
} |
5199 |
15 Dec 09 |
nicklas |
763 |
} |
5199 |
15 Dec 09 |
nicklas |
764 |
catch (SQLException ex) |
5199 |
15 Dec 09 |
nicklas |
765 |
{ |
5199 |
15 Dec 09 |
nicklas |
766 |
throw new DatabaseException(ex); |
5199 |
15 Dec 09 |
nicklas |
767 |
} |
5199 |
15 Dec 09 |
nicklas |
768 |
finally |
5199 |
15 Dec 09 |
nicklas |
769 |
{ |
5199 |
15 Dec 09 |
nicklas |
770 |
if (it != null) it.close(); |
5199 |
15 Dec 09 |
nicklas |
771 |
} |
5199 |
15 Dec 09 |
nicklas |
772 |
if (progress != null) progress.display(100, "Exported spot data: " + numDone + " spots"); |
5199 |
15 Dec 09 |
nicklas |
773 |
return numDone; |
5199 |
15 Dec 09 |
nicklas |
774 |
} |
5199 |
15 Dec 09 |
nicklas |
775 |
|
5199 |
15 Dec 09 |
nicklas |
776 |
/** |
5199 |
15 Dec 09 |
nicklas |
Utility method for calling creating a data writer. Calls |
5199 |
15 Dec 09 |
nicklas |
{@link DataWriterFactory#createDataWriter(Object, String)}. |
5199 |
15 Dec 09 |
nicklas |
@return A data writer, or null if no factory has been specified |
5199 |
15 Dec 09 |
nicklas |
780 |
*/ |
5199 |
15 Dec 09 |
nicklas |
781 |
@SuppressWarnings("unchecked") |
5199 |
15 Dec 09 |
nicklas |
782 |
protected DataWriter createDataWriter(Object owner, String suggestedFilename) |
5199 |
15 Dec 09 |
nicklas |
783 |
throws IOException |
5199 |
15 Dec 09 |
nicklas |
784 |
{ |
5199 |
15 Dec 09 |
nicklas |
785 |
DataWriter writer = null; |
5199 |
15 Dec 09 |
nicklas |
786 |
if (dataWriterFactory != null) |
5199 |
15 Dec 09 |
nicklas |
787 |
{ |
5199 |
15 Dec 09 |
nicklas |
788 |
writer = dataWriterFactory.createDataWriter(owner, suggestedFilename); |
5199 |
15 Dec 09 |
nicklas |
789 |
} |
5199 |
15 Dec 09 |
nicklas |
790 |
return writer; |
5199 |
15 Dec 09 |
nicklas |
791 |
} |
5199 |
15 Dec 09 |
nicklas |
792 |
|
5199 |
15 Dec 09 |
nicklas |
793 |
/** |
5199 |
15 Dec 09 |
nicklas |
Create the exact number of data writers that is needed to export the |
5199 |
15 Dec 09 |
nicklas |
desired data. Each data writer needs to specify a filename |
5199 |
15 Dec 09 |
nicklas |
({@link DataWriter#getFilename()} and the number of data columns |
5199 |
15 Dec 09 |
nicklas |
({@link DataWriter#getColumnCount()}) it is going to write. |
5199 |
15 Dec 09 |
nicklas |
<p> |
5199 |
15 Dec 09 |
nicklas |
799 |
|
5199 |
15 Dec 09 |
nicklas |
This method must be implemented by a subclass and is called once from |
5199 |
15 Dec 09 |
nicklas |
the {@link #beginExport()} method unless no data writer factory has been |
5199 |
15 Dec 09 |
nicklas |
set up. |
5199 |
15 Dec 09 |
nicklas |
803 |
|
5199 |
15 Dec 09 |
nicklas |
@return A list with data writers |
5199 |
15 Dec 09 |
nicklas |
@throws IOException If there is a problem with creating the writers |
5199 |
15 Dec 09 |
nicklas |
806 |
*/ |
5199 |
15 Dec 09 |
nicklas |
807 |
protected abstract List<DataWriter> createDataWriters() |
5199 |
15 Dec 09 |
nicklas |
808 |
throws IOException; |
5199 |
15 Dec 09 |
nicklas |
809 |
|
5199 |
15 Dec 09 |
nicklas |
810 |
/** |
5199 |
15 Dec 09 |
nicklas |
Arrange the data that was returned by the query into the data writers |
5199 |
15 Dec 09 |
nicklas |
array. The data array is a two-demensional array. The first index |
5199 |
15 Dec 09 |
nicklas |
represents a datawriter and goes from 0 to the one below the number |
5199 |
15 Dec 09 |
nicklas |
of data writers returned by {@link #createDataWriters()}. The size of |
5199 |
15 Dec 09 |
nicklas |
the second index is determined by the number of columns for the |
5199 |
15 Dec 09 |
nicklas |
data writer (eg. {@link DataWriter#getColumnCount()}. |
5199 |
15 Dec 09 |
nicklas |
<p> |
5199 |
15 Dec 09 |
nicklas |
818 |
|
5199 |
15 Dec 09 |
nicklas |
This method must be implemented by a subclass which should copy |
5199 |
15 Dec 09 |
nicklas |
data from the spotdata array into the data array. The data array |
5199 |
15 Dec 09 |
nicklas |
is flushed to the data writers every time the position coordinate |
5199 |
15 Dec 09 |
nicklas |
changes. Thus, this method can be called multiple times with |
5199 |
15 Dec 09 |
nicklas |
different column (=assay) coordinates. |
5199 |
15 Dec 09 |
nicklas |
824 |
|
5199 |
15 Dec 09 |
nicklas |
@param position The current position of the spot data |
5199 |
15 Dec 09 |
nicklas |
@param column The current column of the spot data |
5199 |
15 Dec 09 |
nicklas |
@param data The data array to copy the data to |
5199 |
15 Dec 09 |
nicklas |
@param spotData The current row of spot data, in the same order |
5199 |
15 Dec 09 |
nicklas |
as {@link #getSpotFields()} |
5199 |
15 Dec 09 |
nicklas |
830 |
*/ |
5199 |
15 Dec 09 |
nicklas |
831 |
protected abstract void arrangeData(int position, short column, |
5199 |
15 Dec 09 |
nicklas |
832 |
Object[][] data, Object[] spotData); |
5199 |
15 Dec 09 |
nicklas |
833 |
|
5199 |
15 Dec 09 |
nicklas |
834 |
} |