/*
* Copyright (c) 2012 Diamond Light Source Ltd.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package uk.ac.diamond.scisoft.analysis.io;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import org.eclipse.dawnsci.analysis.api.io.IDataHolder;
import org.eclipse.dawnsci.analysis.api.io.ScanFileHolderException;
import org.eclipse.january.IMonitor;
/**
* Should act like the SRSLoader, but for Xas format ascii files. This is because the associated editor subclasses the
* SRSEditor.
*/
public class XasAsciiLoader extends SRSLoader {
private static final String COMMENT_PREFIX = "#";
public XasAsciiLoader(String fileName) {
setFile(fileName);
}
@Override
public DataHolder loadFile(IMonitor mon) throws ScanFileHolderException {
// then try to read the file given
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(fileName));
String dataStr;
String previousHeaderLine = "";
boolean readingHeader = true;
boolean readingFooter = false;
List<?>[] columnData = null;
int count = 0;
while ((dataStr = reader.readLine()) != null) {
// ignore blank
if (dataStr.isEmpty()) {
continue;
}
// first block of commented out lines are the header
if (dataStr.startsWith(COMMENT_PREFIX) && readingHeader) {
readHeaderLine(dataStr);
previousHeaderLine = dataStr;
continue;
}
readingHeader = false;
// next block of commented out lines after any break in comments will be the footer
if (dataStr.startsWith(COMMENT_PREFIX) && !readingHeader) {
readingFooter = true;
readFooterLine(dataStr);
continue;
}
// if get here then its data
if (readingFooter) {
// should not get here after reading a block of commented out lines for a second time: invalid
// format
throw new ScanFileHolderException("Cannot read file");
}
// the first time we get here, the previous line should have been the header
if (columnData == null && datasetNames.size() == 0) {
columnData = parseHeaderString(previousHeaderLine);
}
if (columnData != null) {
if (!loadLazily)
parseColumns(splitLine(dataStr.trim()), columnData);
count++;
} else {
logger.warn("Dropped possible data owing to lack of column headers: {}", dataStr);
}
}
DataHolder result = new DataHolder();
if (loadLazily) {
for (String n : datasetNames) {
result.addDataset(n, createLazyDataset(n, -1, new int[] {count}, new XasAsciiLoader(fileName)));
}
} else {
try {
convertToDatasets(result, datasetNames, columnData, isStoreStringValues(), isUseImageLoaderForStrings(), (new File(this.fileName)).getParent());
} catch (Exception e) {
logger.warn(e.getMessage());
}
}
if (loadMetadata) {
createMetadata();
result.setMetadata(metadata);
}
return result;
} catch (Exception e) {
throw new ScanFileHolderException("XasAsciiLoader.loadFile exception loading " + fileName, e);
} finally {
try {
if (reader != null)
reader.close();
} catch (IOException e) {
throw new ScanFileHolderException("Cannot read file", e);
}
}
}
private List<?>[] parseHeaderString(String previousHeaderLine) {
// remove leading hash
previousHeaderLine = previousHeaderLine.substring(1).trim();
String parts[] = splitLine(previousHeaderLine);
datasetNames.clear();
datasetNames.addAll(Arrays.asList(parts));
return new List<?>[parts.length];
}
private String[] splitLine(String line) {
return line.split("[\t ]+");
}
private void readFooterLine(String dataStr) {
// do not differentiate for the moment
readHeaderLine(dataStr);
}
private void readHeaderLine(String dataStr) {
// remove leading hash
dataStr = dataStr.trim().substring(1);
int colonLoc = dataStr.indexOf(":");
if (colonLoc == -1) {
// must be a comment without any metadata
return;
}
// split by colon
String key = dataStr.substring(0, colonLoc);
String value = dataStr.substring(colonLoc+1);
textMetadata.put(key.trim(), value.trim());
}
@Override
protected void writeHeader(BufferedWriter out, IDataHolder dh) throws IOException {
// now write out the data names
out.write(COMMENT_PREFIX);
int imax = dh.size();
for (int i = 0; i < imax; i++) {
out.write(dh.getName(i) + "\t");
}
out.write("\n");
}
}