-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathIOMethods.pde
More file actions
302 lines (262 loc) · 12.8 KB
/
IOMethods.pde
File metadata and controls
302 lines (262 loc) · 12.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
/*
* Copyright (c) 2010 The Jackson Laboratory
*
* This software was developed by Matt Hibbs' Lab at The Jackson
* Laboratory (see http://cbfg.jax.org/).
*
* This is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* This method prompts the user to select a file for loading.
*
* The openFile method _only_ prompts the user for a file, it does not handle any I/O. This is done by the loadFile method.
* It is also important to note that due to some issues with Processing, neither selectInput nor selectFolder work on all setups. My AWT solution should work.
*/
void openFile() {
String path;
FileDialog fd = new FileDialog((Frame)null, "Select .lod.csv file...", FileDialog.LOAD); // annoying work-around; selectInput was hanging
fd.setVisible(true); // http://code.google.com/p/processing/issues/detail?id=445
path = fd.getDirectory() + fd.getFile();
if (fd.getDirectory() != null && fd.getFile() != null) {// ^^ details
loadFile(path);
}
}
/**
* This method loads the given file, parses it and any associated files, and prepares the UI for display.
*
* loadFile may load twice as many additional files as the number of phenotypes represented by the main table. It can be called by either openFile or loadFolder.
*
* @param path a String representing the path of the main LOD data file
*/
void loadFile(String path) {
if (path.split("/").length < 1) {
return;
}
String pathName = path.split("/")[path.split("/").length - 1];
String modifiedPath = getModifiedPath(path);
fileTree.add(new UITreeNode(pathName, true));
Parent_File parent = new Parent_File(pathName);
float autoLower = 1.5, autoUpper = 3.0;
try {
autoLower = float(((UITextInput)texts.get(0)).getText());
autoUpper = float(((UITextInput)texts.get(1)).getText());
} catch (Exception error) {
error.printStackTrace();
}
try {
FileReader fr = new FileReader(path);
String[][] data = readCSV(fr);
fr.close();
String[] names = new String[0];
HashMap<String, float[][]> chrData = new HashMap<String, float[][]>();
ArrayList<HashMap<String, float[]>> thresholdData = new ArrayList<HashMap<String, float[]>>();
String[][] csvPeaks = new String[0][0], csvThresh = new String[0][0];
int alphaCol = -1;
if (new File(modifiedPath + ".peaks.txt").exists()) {
FileReader peaksFileReader = new FileReader(modifiedPath + ".peaks.txt");
chrData = readPeaks(peaksFileReader);
peaksFileReader.close();
Iterator it = chrData.keySet().iterator();
while (it.hasNext ()) {
names = (String[])append(names, it.next());
}
} else if (new File(modifiedPath + ".peaks.csv").exists()) {
InputStreamReader csvFile = new InputStreamReader(new FileInputStream(modifiedPath + ".peaks.csv"));
csvPeaks = readCSV(csvFile);
csvFile.close();
}
if (new File(modifiedPath + ".thresh.txt").exists()) {
FileReader threshFileReader = new FileReader(modifiedPath + ".thresh.txt");
thresholdData = getThresholdData(threshFileReader, names, parent);
threshFileReader.close();
} else if (new File(modifiedPath + ".thresh.csv").exists()) {
FileReader threshCSVReader = new FileReader(modifiedPath + ".thresh.csv");
int[] alphaArray = new int[1];
csvThresh = getThresholdData(threshCSVReader, parent, names, alphaArray);
alphaCol = alphaArray[0];
threshCSVReader.close();
}
if (names.length == 0 && new File(modifiedPath + ".thresh.txt").exists()) {
for (int i = 3; i < data[0].length; i++) {
names = (String[])append(names, data[0][i].trim());
}
FileReader threshFileReader = new FileReader(modifiedPath + ".thresh.txt");
thresholdData = getThresholdData(threshFileReader, names, parent);
threshFileReader.close();
}
for (int i = 3; i < data[0].length; i++) {
((UITreeNode)fileTree.last()).add(new UITreeNode(data[0][i].trim()));
Phenotype currentPhenotype = new Phenotype(data[0][i]);
boolean useBP = false;
if (float(data[1][2]) > unitThreshold) { // cM should be less than this, bP _should_ be more
useBP = true;
}
// load LOD scores
for (int j = 1; j < data.length; j++) {
if (data[j].length-1 >= i) {
currentPhenotype.lodscores = append(currentPhenotype.lodscores, float(data[j][i]));
int posChr = getChr(data[j][1]);
if (useBP) {
currentPhenotype.position = append(currentPhenotype.position, (float)unitConverter.basePairsToCentimorgans(posChr, (long)Double.parseDouble(data[j][2])));
} else {
currentPhenotype.position = append(currentPhenotype.position, float(data[j][2]));
}
currentPhenotype.chromosome = append(currentPhenotype.chromosome, posChr);
}
}
// load threshold information
if (new File(modifiedPath + ".thresh.txt").exists() && !parent.useModelThresholds) {
if (! addThresholdData(currentPhenotype, thresholdData)) {
currentPhenotype.thresholds = new float[][] { { autoLower, autoUpper } };
currentPhenotype.useDefaults = true;
currentPhenotype.useXDefaults = true;
}
} else if (new File(modifiedPath + ".thresh.csv").exists() && !parent.useModelThresholds) {
if (! addThresholdData(currentPhenotype, csvThresh, alphaCol)) {
currentPhenotype.thresholds = new float[][] {
{
autoLower, autoUpper
}
};
currentPhenotype.useDefaults = true;
currentPhenotype.useXDefaults = true;
}
} else if (new File(modifiedPath + "_" + currentPhenotype.name + ".sum.csv").exists()) {
FileReader sumFile = new FileReader(modifiedPath + "_" + currentPhenotype.name + ".sum.csv");
if (! addThreshCSVFile(currentPhenotype, sumFile)) {
currentPhenotype.thresholds = new float[][] { { autoLower, autoUpper } };
currentPhenotype.useDefaults = true;
currentPhenotype.useXDefaults = true;
}
sumFile.close();
}
// load peak information
if (new File(modifiedPath + ".peaks.txt").exists()) {
addPeakData(currentPhenotype, chrData.get(currentPhenotype.name));
} else if (new File(modifiedPath + ".peaks.csv").exists()) {
addPeakData(currentPhenotype, csvPeaks);
} else if (new File(modifiedPath + "_" + currentPhenotype.name + ".chr.csv").exists()) {
FileReader peakCSVReader = new FileReader(modifiedPath + "_" + currentPhenotype.name + ".chr.csv");
addPeakCSVFile(currentPhenotype, peakCSVReader);
peakCSVReader.close();
}
parent.add(currentPhenotype);
}
parentFiles.add(parent);
} catch (Exception error) {
fileTree.remove(fileTree.size() - 1);
error.printStackTrace();
}
parent.update();
}
/**
* This method prompts the user to select a folder for loading.
*
* Besides prompting for a folder, this method looks for LOD files in the folder root and executes loadFile on each one.
* It is also important to note that due to some issues with Processing, neither selectInput nor selectFolder work on all setups. My AWT solution should work.
*/
void loadFolder() {
// selectFolder has same issue as with selectInput
FileDialog folderPrompt = new FileDialog((Frame)null, "Select folder...", FileDialog.LOAD);
System.setProperty("apple.awt.fileDialogForDirectories", "true"); // how would anyone ever know to do this??
folderPrompt.setVisible(true);
System.setProperty("apple.awt.fileDialogForDirectories", "false");
if (folderPrompt.getDirectory() != null && folderPrompt.getFile() != null && new File(folderPrompt.getDirectory() + folderPrompt.getFile()).isDirectory()) {
for (String path : new File(folderPrompt.getDirectory() + folderPrompt.getFile()).list()) {
if (path.toLowerCase().endsWith(".lod.csv") && !(new File(folderPrompt.getDirectory() + folderPrompt.getFile() + "/" + path).isDirectory())) {
loadFile(folderPrompt.getDirectory() + folderPrompt.getFile() + "/" + path);
}
}
}
}
/**
* This method loads a configuration file in the Java Properties (java.util.Properties) format.
* The key "chromosome_list" contains a comma-separated list of chromosome numbers
* The other keys are:
* chromosome_c -- name
* chromosome_c_length -- length in cM or bp
* chromosome_c_centromere -- position of the centromere in cM or bp
* where c is a chromosome number
*/
void loadConfig() {
FileDialog fd = new FileDialog((Frame)null, "Select config file...", FileDialog.LOAD);
fd.setVisible(true);
if (fd.getDirectory() != null && fd.getFile() != null) {
try {
FileInputStream inputConfig = new FileInputStream(fd.getDirectory() + fd.getFile());
Properties configFile = new Properties();
configFile.load(inputConfig);
String[] chrNumbers = ((String)configFile.get("chromosome_list")).split(",");
// prepare arrays to be loaded with new data
chrLengths = new float[0];
chrNames = new String[0];
chrMarkerpos = new float[0];
chrOffsets = new float[0];
chrTotal = 0.0;
// update the arrays
for (String number : chrNumbers) {
chrNames = append(chrNames, (String)configFile.get("chromosome_" + number.trim()));
String newLength = (String)configFile.get("chromosome_" + number.trim() + "_length");
String newPos = (String)configFile.get("chromosome_" + number.trim() + "_centromere");
if (float(newLength) > unitThreshold) {
chrLengths = append(chrLengths, (float)unitConverter.basePairsToCentimorgans(int(number.trim()), Long.parseLong(newLength)));
} else {
chrLengths = append(chrLengths, float(newLength));
}
if (float(newPos) > unitThreshold) {
chrMarkerpos = append(chrMarkerpos, (float)unitConverter.basePairsToCentimorgans(int(number.trim()), Long.parseLong(newPos)));
} else {
chrMarkerpos = append(chrMarkerpos, float(newPos));
}
}
chrOffsets = new float[chrLengths.length];
chrTotal = chrLengths[0];
// recalculate the offsets and total length (see initConstants in the InitUI module)
for (int i = 1; i < chrLengths.length; i++) {
chrOffsets[i] = chrOffsets[i-1] + chrLengths[i-1];
chrTotal += chrLengths[i];
}
inputConfig.close();
} catch (Exception error) {
initConstants(); // reload the old settings if the above fails
error.printStackTrace();
}
}
}
/**
* This method is used to get a chromosome's order given its human-readable form.
*
* Consider the following example (for a mouse chromosome): getChr("X") == 20
*
* @param stringChr the human-readable name for a chromosome
* @return the order of the chromosome
*/
int getChr(String stringChr) {
int chr = 21;
String nString = new String(stringChr).trim();
if (nString.startsWith("chr")) {
nString = nString.substring(3);
}
try {
chr = Integer.parseInt(nString);
} catch (NumberFormatException error) {
for (int i = 0; i < chrNames.length; i++) {
if (chrNames[i].equals(nString)) {
chr = i + 1;
break;
}
}
}
return chr;
}