String peeksFileName = factor + ".peak.bin";
File peeksFile = new File(outputDir, peeksFileName);
BufferedReader[] readers = new BufferedReader[bedFiles.size()];
LittleEndianOutputStream peakWriter = null;
long indexPosition = 0l;
try {
for (int i = 0; i < bedFiles.size(); i++) {
readers[i] = new BufferedReader(new FileReader(bedFiles.get(i)));
}
peakWriter = new LittleEndianOutputStream(new BufferedOutputStream(new FileOutputStream(peeksFile)));
LinkedHashMap<String, Long> chrIndex = new LinkedHashMap<String, Long>();
String[] line = new String[readers.length];
// Placeholder for index position
peakWriter.writeLong(0l);
// Track line
peakWriter.writeString("track name=" + factor + " sample=" + factor + " viewLimits=0:100 useScore=1 color=" + c);
// Time values
int nTimePoints = times.size();
peakWriter.writeInt(nTimePoints);
for (int i = 0; i < times.size(); i++) {
peakWriter.writeInt(times.get(i));
}
// Path to associated signal ("tdf") files
String tdf = root + "/tdf/compressed/" + factor + ".merged.bam.tdf";
peakWriter.writeString(tdf);
for (int t : times) {
peakWriter.writeString(root + "/tdf/timecourses/" + factor + "_" + t + "/" + factor + "_" + t + ".merged.bam.tdf");
}
// Process bed records
String currentChr = "";
List<PeakRecord> records = new ArrayList(20000);
while (true) {
for (int i = 0; i < readers.length; i++) {
line[i] = readers[i].readLine();
if (line[i] == null) {
// EOF, we're done
if (records.size() > 0) {
writeChromosomeData(peakWriter, chrIndex, currentChr, records);
}
break;
}
}
if (line[0].startsWith("#") || line[0].startsWith("track")) {
continue; // Skip these lines. Note we should actually check all files
}
// Take locus from first file
String[] tokens = line[0].split("\t");
String chr = tokens[0];
if (!chr.equals(currentChr) && records.size() > 0) {
// End of data for current chromosome.
// Record position of start of this chromosome block for index
writeChromosomeData(peakWriter, chrIndex, currentChr, records);
}
if (chr == null) {
break;
}
currentChr = chr;
int start = Integer.parseInt(tokens[1]);
int end = Integer.parseInt(tokens[2]);
float score = Float.parseFloat(tokens[4]);
float[] timeScores = new float[nTimePoints];
for (int i = 0; i < nTimePoints; i++) {
tokens = line[i + 1].split("\t");
if (!(tokens[0].equals(chr) &&
Integer.parseInt(tokens[1]) == start &&
Integer.parseInt(tokens[2]) == end)) {
throw new RuntimeException("Unordered files");
}
timeScores[i] = Float.parseFloat(tokens[4]);
}
records.add(new PeakRecord(start, end, score, timeScores));
}
// Write out index
indexPosition = peakWriter.getWrittenCount();
peakWriter.writeInt(chrIndex.size());
for (Map.Entry<String, Long> entry : chrIndex.entrySet()) {
peakWriter.writeString(entry.getKey());
peakWriter.writeLong(entry.getValue());
}
} finally {
if (peakWriter != null) {
peakWriter.close();
writeIndexPosition(peeksFile, indexPosition);
}
for (BufferedReader reader : readers) {
reader.close();
}