1 /*** VictorTextFileDataSetLoader.java - part of the MirkE (say murky) application for colormetric analysis emphesizing
2 kinetics.
3
4 Created by: Scott Menor on 21 July, 2004.
5
6 Copyright (c) 2004 Arizona State University - Cancer Research Institute. All rights reserved.
7
8 MirkE is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 MirkE is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with MirkE; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 US
21 */
22
23 package edu.asu.cri.MirkE.io;
24
25 import java.io.BufferedReader;
26 import java.io.File;
27 import java.io.FileReader;
28 import java.io.IOException;
29 import java.util.Arrays;
30 import java.util.GregorianCalendar;
31 import java.util.HashMap;
32 import java.util.Iterator;
33 import java.util.LinkedHashMap;
34 import java.util.LinkedHashSet;
35 import java.util.List;
36 import java.util.Map;
37 import java.util.TreeSet;
38 import java.util.Vector;
39
40 import net.sf.hibernate.Session;
41 import net.sf.hibernate.Transaction;
42 import edu.asu.cri.MirkE.dataStructures.DataSet;
43 import edu.asu.cri.MirkE.dataStructures.PlateDescription;
44 import edu.asu.cri.MirkE.dataStructures.PlateWellDataPoint;
45 import edu.asu.cri.MirkE.dataStructures.PlateWellDescriptor;
46 import edu.asu.cri.MirkE.exceptions.MirkEApplicationException;
47 import edu.asu.cri.MirkE.exceptions.MirkESystemException;
48
49 /*** Reads a text file generated by Victor's software (TODO - find its name) and returns a DataSet
50
51 */
52 public class VictorTextFileDataSetLoader {
53
54 private final static int COLUMN_FORMATTED_DATA = 0;
55 private final static int PLATE_LAYOUT_DATA = 1;
56 private final static int PROTOCOL_DESCRIPTION = 2;
57 private final static int PLATE_MAP = 3;
58 private final static int IGNORE = 4;
59
60 /*** load a DataSet from a Victor text dump
61 *
62 * @param filename
63 *
64 * @return dataSet
65 * @throws IOException
66 * @throws MirkEApplicationException
67 * @throws MirkESystemException
68 */
69 public static DataSet load(String filename)
70 throws IOException, MirkEApplicationException, MirkESystemException{
71 File file = new File(filename);
72 DataSet ds = load(file);
73 return ds;
74 }
75
76 /*** load a DataSet from a Victor text dump
77
78 @param files
79
80 @return dataSet
81 * @throws IOException
82 * @throws MirkEApplicationException
83 * @throws MirkESystemException
84 */
85 public static DataSet load(File[] files)
86 throws IOException, MirkEApplicationException, MirkESystemException
87 {
88 DataSet dataSet = new DataSet();
89
90 for (int fileNumber=0;fileNumber<files.length;fileNumber++) {
91 dataSet = load(files[fileNumber],
92 dataSet);
93 }
94
95 return dataSet;
96 }
97
98 /*** load a DataSet from a Victor text dump
99
100 @param file
101
102 @return dataSet
103 * @throws IOException
104 * @throws MirkEApplicationException
105 * @throws MirkESystemException
106 */
107 public static DataSet load(File file) throws IOException, MirkEApplicationException, MirkESystemException {
108 DataSet dataSet = new DataSet();
109 return load(file, dataSet);
110 }
111
112 /*** load a DataSet from a Victor text dump
113
114 @param file
115 @param dataSet <code>DataSet</code> to import <code>DataPoint</code>s into
116
117 @return dataSet
118 * @throws IOException
119 * @throws MirkEApplicationException
120 */
121 public static DataSet load(File file,
122 DataSet dataSet) throws IOException, MirkEApplicationException {
123
124 BufferedReader bufferedReader = null;
125
126
127 bufferedReader = new BufferedReader(new FileReader(file));
128
129
130
131
132
133 bufferedReader = new BufferedReader(new FileReader(file));
134
135
136
137 String plateIdentifier;
138 Map protocolDescriptionMap = new HashMap();
139
140 TreeSet plateRowsTreeSet;
141 TreeSet plateColumnsTreeSet;
142
143 LinkedHashSet observables = new LinkedHashSet();
144
145
146 Vector columnIndices = new Vector(Arrays.asList(bufferedReader.readLine().split("//t")));
147 Map indexToObservableColumnMap = new LinkedHashMap();
148 int timeIndexColumnNumber = 0;
149 int largestObservableColumnNumber = 0;
150
151 while (timeIndexColumnNumber >= 0) {
152 timeIndexColumnNumber = columnIndices.indexOf("Time", timeIndexColumnNumber + 1);
153
154 if (timeIndexColumnNumber >= 0) {
155 indexToObservableColumnMap.put(columnIndices.elementAt(timeIndexColumnNumber + 1), new Integer(timeIndexColumnNumber));
156 if (timeIndexColumnNumber > largestObservableColumnNumber) {
157 largestObservableColumnNumber = timeIndexColumnNumber + 1;
158 }
159 }
160 }
161
162 plateIdentifier = file.getName();
163
164
165 plateRowsTreeSet = new TreeSet();
166 plateColumnsTreeSet = new TreeSet();
167
168 String well = null;
169 String plateRow = null;
170 Integer plateColumn = null;
171
172
173 String previousWellColumnElement = "";
174
175
176 int victorTextFileSubsection = COLUMN_FORMATTED_DATA;
177
178 while (bufferedReader.ready()) {
179 String rawLine = bufferedReader.readLine();
180 String line = rawLine.trim();
181
182 switch (victorTextFileSubsection) {
183 case COLUMN_FORMATTED_DATA: {
184 Vector lineTokens = new Vector(Arrays.asList(line.split("//t")));
185
186 if (lineTokens.contains("Plate")) {
187 victorTextFileSubsection = PLATE_LAYOUT_DATA;
188 } else {
189
190 String wellColumnElement = previousWellColumnElement;
191
192 if (columnIndices.size() == lineTokens.size()) {
193
194 wellColumnElement = (String)lineTokens.elementAt(columnIndices.indexOf("Well"));
195 previousWellColumnElement = wellColumnElement;
196
197 } else {
198
199
200 }
201
202
203
204 if (wellColumnElement.equals("")) {
205
206 } else {
207 well = wellColumnElement;
208 plateRow = well.substring(0, 1);
209 plateRowsTreeSet.add(plateRow);
210
211 plateColumn = Integer.valueOf(well.substring(1));
212 plateColumnsTreeSet.add(plateColumn);
213 }
214
215 Iterator observableIterator = indexToObservableColumnMap.entrySet().iterator();
216 while (observableIterator.hasNext()) {
217 Map.Entry entry = (Map.Entry)observableIterator.next();
218
219 int observableTimeIndexColumnNumber = ((Integer)entry.getValue()).intValue();
220
221 if (columnIndices.size() == lineTokens.size()) {
222
223 } else {
224 observableTimeIndexColumnNumber += -(columnIndices.size() - lineTokens.size());
225 }
226
227 String observableName = (String)entry.getKey();
228
229 if (lineTokens.size() >= observableTimeIndexColumnNumber + 2) {
230 String time = (String)lineTokens.elementAt(observableTimeIndexColumnNumber);
231 String observationValue = (String)lineTokens.elementAt(observableTimeIndexColumnNumber + 1);
232
233 if (observationValue != null) {
234 if (!(observationValue.equals("")||observationValue.equals("N/A"))) {
235 PlateWellDataPoint plateWellDataPoint = new PlateWellDataPoint();
236 plateWellDataPoint.setTimestamp(toTimestamp(time));
237 plateWellDataPoint.setPlateIdentifier(plateIdentifier);
238 plateWellDataPoint.setPlateRow(plateRow.trim());
239 plateWellDataPoint.setPlateColumn(plateColumn.toString());
240
241 plateWellDataPoint.setObservableName(observableName.trim());
242 observables.add(observableName.trim());
243
244 plateWellDataPoint.setObservedValue(Double.parseDouble(observationValue.trim()));
245
246 dataSet.save(plateWellDataPoint);
247 }
248 }
249 }
250 }
251 }
252
253 } break;
254
255 case PLATE_LAYOUT_DATA: {
256
257 if (line.equals("Protocol description")) {
258 victorTextFileSubsection = PROTOCOL_DESCRIPTION;
259 }
260 } break;
261
262 case PROTOCOL_DESCRIPTION: {
263
264
265
266 protocolDescriptionMap.put("plateIdentifier", plateIdentifier);
267 protocolDescriptionMap.put("dataPointType", "protocolDescription");
268
269 if (line.startsWith("Plate map of")) {
270 victorTextFileSubsection = PLATE_MAP;
271 } else {
272 String[] protocolDescriptionKeyValuePair = line.split("[//.]{2,}");
273
274 if (protocolDescriptionKeyValuePair.length>1) {
275
276 protocolDescriptionMap.put(protocolDescriptionKeyValuePair[0].trim(),
277 protocolDescriptionKeyValuePair[1].trim());
278 }
279 }
280
281
282
283 } break;
284
285 case PLATE_MAP: {
286 if (line.length() == 0) {
287 victorTextFileSubsection = PROTOCOL_DESCRIPTION;
288 } else {
289 String[] splitLine = line.split("//|");
290
291 if (splitLine.length==2) {
292 String plateMapRow = splitLine[0].trim();
293
294 plateRowsTreeSet.add(plateMapRow);
295
296 Vector plateMapRowVector = new Vector(Arrays.asList(splitLine[1].split("[//s]+")));
297
298 for (int columnNumber=1;columnNumber<plateMapRowVector.size();columnNumber++) {
299 Integer columnNumberInteger = new Integer(columnNumber);
300
301 PlateWellDescriptor plateWellDescriptor = new PlateWellDescriptor();
302 plateWellDescriptor.setPlateIdentifier(plateIdentifier);
303 plateWellDescriptor.setPlateRow(plateMapRow);
304 plateWellDescriptor.setPlateColumn(columnNumberInteger.toString());
305 plateWellDescriptor.setPlateWellType(plateMapRowVector.elementAt(columnNumber).toString());
306 dataSet.save(plateWellDescriptor);
307
308 plateColumnsTreeSet.add(columnNumberInteger);
309 }
310
311 } else {
312
313 }
314 }
315 } break;
316
317 case IGNORE: {
318
319 } break;
320 }
321
322 }
323
324
325
326
327
328
329
330
331
332 PlateDescription plateDescription = new PlateDescription();
333 plateDescription.setPlateIdentifier(plateIdentifier);
334 plateDescription.setNumberOfRows(plateRowsTreeSet.size());
335 plateDescription.setNumberOfColumns(plateColumnsTreeSet.size());
336
337 plateDescription.setTimestamp(toTimestamp(protocolDescriptionMap.get("Measured on").toString()));
338
339 dataSet.save(plateDescription);
340
341 processAndGuessLabelWavelengths(dataSet,
342 new Vector(observables),
343 protocolDescriptionMap);
344
345 return dataSet;
346 }
347
348 /***
349
350 @param time
351
352 @return timestamp
353 */
354 public static java.sql.Timestamp toTimestamp(String time) {
355 java.sql.Timestamp timestamp = null;
356
357 if (time != null) {
358 if (time.split("/").length > 1) {
359 String[] whitespaceSplitDate = time.split("//s");
360 String[] dateComponents = whitespaceSplitDate[0].split("/");
361
362 int month = Integer.valueOf(dateComponents[0]).intValue();
363 int day = Integer.valueOf(dateComponents[1]).intValue();
364 int year = Integer.valueOf(dateComponents[2]).intValue();
365
366 String[] hourMinuteSecond = whitespaceSplitDate[1].split(":");
367
368 int hour = Integer.valueOf(hourMinuteSecond[0]).intValue();
369 int minute = Integer.valueOf(hourMinuteSecond[1]).intValue();
370 double second = Double.valueOf(hourMinuteSecond[2]).doubleValue();
371
372 if (whitespaceSplitDate[2].equals("PM")) {
373 hour += 12;
374 }
375
376 GregorianCalendar gregorianCalendar = new GregorianCalendar(year,
377 month,
378 day,
379 hour,
380 minute,
381 (int)Math.round(second));
382
383 timestamp = new java.sql.Timestamp(gregorianCalendar.getTime().getTime());
384
385 } else {
386 String[] hourMinuteSecond = time.split(":");
387
388 int hour = Integer.valueOf(hourMinuteSecond[0]).intValue();
389 int minute = Integer.valueOf(hourMinuteSecond[1]).intValue();
390 double second = Double.valueOf(hourMinuteSecond[2]).doubleValue();
391
392 GregorianCalendar gregorianCalendar = new GregorianCalendar(1970,
393 1,
394 1,
395 hour,
396 minute,
397 (int)Math.round(second));
398
399 timestamp = new java.sql.Timestamp(gregorianCalendar.getTime().getTime());
400 }
401 }
402
403 return timestamp;
404 }
405
406
407 /***
408 * @param dataSet
409 * @param observables
410 * @param protocolDescriptionMap
411 * @throws MirkEApplicationException
412 */
413 public static void processAndGuessLabelWavelengths(DataSet dataSet,
414 Vector observables,
415 Map protocolDescriptionMap) throws MirkEApplicationException{
416
417 String labelTechnology = protocolDescriptionMap.get("Label technology").toString();
418
419 Map observableToWavelengthAndTypeMap = new HashMap();
420
421
422
423 if (labelTechnology.equals("Prompt fluorometry")) {
424
425
426 String cwEmissionFilterName = protocolDescriptionMap.get("Emission filter name").toString();
427 if (cwEmissionFilterName != null) {
428 String firstEmissionMeasurementWavelengthAndType = parseObservableWavelengthAndType(cwEmissionFilterName.toString());
429 observableToWavelengthAndTypeMap.put(observables.elementAt(0),
430 firstEmissionMeasurementWavelengthAndType);
431 }
432
433 Object secondCWEmissionFilterName = protocolDescriptionMap.get("Second meas. emission filter name");
434 if (secondCWEmissionFilterName != null) {
435 String secondEmissionMeasurementWavelengthAndType = parseObservableWavelengthAndType(secondCWEmissionFilterName.toString());
436 observableToWavelengthAndTypeMap.put(observables.elementAt(1),
437 secondEmissionMeasurementWavelengthAndType);
438 }
439 }
440
441 if (labelTechnology.equals("Photometry")) {
442 Object cwLampFilterName = protocolDescriptionMap.get("CW-lamp filter name");
443 if (cwLampFilterName != null) {
444 String firstAbsorbanceMeasurementWavelengthAndType = parseObservableWavelengthAndType(cwLampFilterName.toString());
445 observableToWavelengthAndTypeMap.put(observables.elementAt(0),
446 firstAbsorbanceMeasurementWavelengthAndType);
447 }
448
449 Object secondCWLampFilterName = protocolDescriptionMap.get("Second meas. CW-lamp filter name");
450 if (secondCWLampFilterName != null) {
451 String secondAbsorbanceMeasurementWavelengthAndType = parseObservableWavelengthAndType(secondCWLampFilterName.toString());
452 observableToWavelengthAndTypeMap.put(observables.elementAt(1),
453 secondAbsorbanceMeasurementWavelengthAndType);
454 }
455 }
456
457 try{
458
459 Session session = dataSet.getSession();
460
461 Transaction transaction = session.beginTransaction();
462
463 List dataPointsList = session.find("from PlateWellDataPoint p");
464
465 Iterator dataPointsListIterator = dataPointsList.iterator();
466 while (dataPointsListIterator.hasNext()) {
467 PlateWellDataPoint plateWellDataPoint = (PlateWellDataPoint)dataPointsListIterator.next();
468
469 if (observableToWavelengthAndTypeMap.containsKey(plateWellDataPoint.getObservableName())) {
470 plateWellDataPoint.setObservableName(observableToWavelengthAndTypeMap.get(plateWellDataPoint.getObservableName()).toString());
471
472 }
473 }
474
475 transaction.commit();
476 session.close();
477 } catch(net.sf.hibernate.HibernateException hibernateException){
478 new MirkEApplicationException("from PlateWellDataPoint p -- dataPointsListIterator", hibernateException);
479 }
480 }
481
482 /***
483
484 @param victorDatasetObservableName
485
486 @return formattedObservable
487 */
488 public static String parseObservableWavelengthAndType(String victorDatasetObservableName) {
489 String wavelength = victorDatasetObservableName.substring(1);
490
491 String observableType = victorDatasetObservableName.substring(0,
492 1);
493
494 String type;
495
496 if (observableType.equals("P")) {
497 type = "A";
498
499 } else if (observableType.equals("E")) {
500 type = "E";
501
502 } else if (observableType.equals("F")) {
503 type = "E";
504
505 } else {
506 type = "";
507
508 }
509
510 String formattedObservable = type + " " + wavelength.trim() + "nm";
511
512 return formattedObservable;
513 }
514 }