package uk.ac.ed.inf.biopepa.ui.wizards.timeseries; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.*; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.*; import uk.ac.ed.csbe.sbsivisual.sbsiDataFormat.*; import uk.ac.ed.inf.biopepa.core.BasicResult; import uk.ac.ed.inf.biopepa.core.interfaces.Result; import uk.ac.ed.inf.biopepa.core.sba.Parameters; import au.com.bytecode.opencsv.CSVReader; public class ImportDataPage extends WizardPage { private int labelStyle = SWT.SINGLE | SWT.LEFT; protected ImportDataPage(String pageName) { super(pageName); this.setTitle("Import external data for comparison"); this.setDescription("Import data from a csv file or SBSI format" + " to plot alongside data from BioPEPA analysis"); } private FileOpener csvFileOpener; private FileOpener sbsiResultParser; public void createControl(Composite parent) { Composite composite = new Composite(parent, SWT.NONE); composite.setLayout(new GridLayout()); setControl(composite); Composite fileSetterComposite = new Composite (composite, SWT.NONE); GridLayout filesCompLayout = new GridLayout(3, false); fileSetterComposite.setLayout(filesCompLayout); GridData fileSetterGridData = new GridData(); fileSetterGridData.grabExcessHorizontalSpace = true; fileSetterGridData.horizontalAlignment = GridData.FILL; fileSetterComposite.setLayoutData(fileSetterGridData); fileSetterGridData.minimumWidth = 100; csvFileOpener = new FileOpener (fileSetterComposite, "Open csv data", new CsvResultParser ()); sbsiResultParser = new FileOpener (fileSetterComposite, "Open sbsi data", new SBSIResultParser()); } private interface ResultFileParser { public void parseFile (String filename); public String[] getFileExtensions(); } private class CsvResultParser implements ResultFileParser { public void parseFile (String filename){ readCsvFile(filename); } public String[] getFileExtensions (){ String [] result = { "*.csv", "*" }; return result; } } private class SBSIResultParser implements ResultFileParser { public void parseFile (String filename){ readSBSIFile(filename); } public String[] getFileExtensions (){ String [] result = { "*.dat", "*" }; return result; } } private class FileOpener { private Label cfLabel; private Button cfButton; private ResultFileParser resultFileParser; String selectedFile; public void unSetSelectedFile(){ cfLabel.setText("no file"); cfButton.setText("set file"); } FileOpener (Composite parent, String exportName, ResultFileParser resultFileParser){ Label exportLabel = new Label (parent, labelStyle); exportLabel.setText(exportName); GridData buttonGridData = new GridData (); buttonGridData.horizontalAlignment = GridData.FILL; buttonGridData.minimumWidth = 5; buttonGridData.grabExcessHorizontalSpace = true; cfButton = new Button (parent, SWT.PUSH); cfButton.setText("set file"); cfButton.setLayoutData(buttonGridData); String[] extensions = resultFileParser.getFileExtensions(); cfButton.addSelectionListener(new Open(extensions)); cfLabel = new Label (parent, labelStyle); cfLabel.setText("no file"); GridData labelGridData = new GridData(); labelGridData.grabExcessHorizontalSpace = true; labelGridData.horizontalAlignment = GridData.FILL; cfLabel.setLayoutData(labelGridData); this.resultFileParser = resultFileParser; } class Open implements SelectionListener { private String[] extensions; Open(String[] extensions){ this.extensions = extensions; } public void widgetSelected(SelectionEvent event) { FileDialog fd = new FileDialog(getShell(), SWT.OPEN); fd.setText("Open"); fd.setFilterPath("C:/"); fd.setFilterExtensions(this.extensions); String selected = fd.open(); IPath selectedPath = Path.fromOSString(selected); String labelString = selectedPath.lastSegment(); if (labelString.length() > 30){ labelString = labelString.substring(0, 30) + "..."; } selectedFile = selected; // cfLabel.setText(selectedFile); cfLabel.setText(labelString); cfButton.setText("Change"); resultFileParser.parseFile(selectedFile); } public void widgetDefaultSelected(SelectionEvent event) { } } } public Result getPlottableResult(){ return this.plottableResult; } private Result plottableResult; private void csvParseError(String errMsg){ this.csvFileOpener.unSetSelectedFile(); this.setErrorMessage(errMsg); } private void readCsvFile (String filename){ if (filename == null) { // csvReadError = "Filename null"; return ; } try { FileReader freader = new FileReader(filename); CSVReader reader = new CSVReader(freader); // Read the top line which should give us the // component and rate names String[] nextLine; nextLine = reader.readNext(); if (nextLine == null) { return; } // The first line specifies the names, we assume that // the first name is time. String[] names = new String[nextLine.length - 1]; for (int i = 1; i < nextLine.length; i++) { names[i - 1] = nextLine[i].trim(); } LinkedList<Number>timesList = new LinkedList<Number>(); // For each time point this will hold the value of each // component's name. Note that this is kind of the other // way around from how a 'Result' is held. LinkedList<double[]>resultsList = new LinkedList<double[]>(); while ((nextLine = reader.readNext()) != null) { timesList.add(Double.parseDouble(nextLine[0].trim())); double [] resultLine = new double [names.length]; for (int column = 0; column < names.length; column++){ if (column > nextLine.length){ resultLine[column] = 0; } else { double value = Double.parseDouble(nextLine[column + 1].trim()); resultLine[column] = value; } } resultsList.addLast(resultLine); } double [] times = new double[timesList.size()]; for (int index = 0; index < times.length; index++){ times[index] = timesList.get(index).doubleValue(); } // For each component name create a results array the same // length as the time points array double [][] results = new double[names.length][]; for (int i = 0; i < names.length; i++){ results[i] = new double[times.length]; } for (int timeIndex = 0; timeIndex < times.length; timeIndex++){ double[] resultLine = resultsList.get(timeIndex); for (int index = 0; index < results.length; index++){ results[index][timeIndex] = resultLine[index]; } } Parameters params = new Parameters(); HashMap<String, Number> modelParams = new HashMap<String, Number>(); BasicResult thisResult = new BasicResult(params, modelParams); thisResult.setComponentNames(names); thisResult.setResults(results); thisResult.setTimePoints(times); this.setErrorMessage(null); plottableResult = thisResult; } catch (FileNotFoundException e) { this.csvParseError("csv file not found"); e.printStackTrace(); } catch (IOException e) { this.csvParseError("csv file / io error " + e.getMessage()); e.printStackTrace(); } catch (Exception e){ this.csvParseError("csv file error " + e.getMessage()); e.printStackTrace(); } } private void sbsiParseError(String errMsg){ this.sbsiResultParser.unSetSelectedFile(); this.setErrorMessage(errMsg); } private void readSBSIFile (String filename){ if (filename == null) { // System.out.println("Filename is null"); return ; } try { SBSIResourceFactory sbsiResFact = SBSIResourceFactory.getInstance(); SBSIDataDocument sbsiDoc = sbsiResFact.readSBSIDataFile(filename); ISBSIData sbsiData = sbsiDoc.getSBSIData(); String [] names = sbsiData.getHeaders(); double [][] results = new double[names.length][]; for (int index = 0; index < names.length; index++){ results[index] = sbsiData.getColumnData(index); } double [] times = results[0]; Parameters params = new Parameters(); HashMap<String, Number> modelParams = new HashMap<String, Number>(); BasicResult thisResult = new BasicResult(params, modelParams); thisResult.setComponentNames(names); thisResult.setResults(results); thisResult.setTimePoints(times); this.setErrorMessage(null); plottableResult = thisResult; } catch (IllegalStateException e){ // We assume this means it can't parse the file. this.sbsiParseError("Cannot parse sbsi data file " + e.getMessage()); } catch (Exception e){ this.sbsiParseError("Error opening sbsi data file " + e.getMessage()); e.printStackTrace(); } } }