package org.signalml.domain.signal.export.ascii; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.text.DecimalFormat; import org.signalml.app.model.signal.SignalExportDescriptor; import org.signalml.app.view.signal.SampleSourceUtils; import org.signalml.domain.signal.SignalWriterMonitor; import org.signalml.domain.signal.export.ISignalWriter; import org.signalml.domain.signal.samplesource.MultichannelSampleSource; /** * Exports signal to ASCII format. * * @author Paweł Kordowski, Piotr Szachewicz */ public class ASCIISignalWriter implements ISignalWriter { /** * Maximum size of buffer used to write the signal to file. */ private static final int BUFFER_SIZE = 8192; /** * Formatter used to format sample values. */ private DecimalFormat formatter = new DecimalFormat("#####0.0##############"); /** * Number of channels that will be written to the file. */ private int channelCount; /** * Writes the signal to a file in ASCII format. * * @param outputPath * output file path * @throws IOException * when the file cannot be written */ @Override public void writeSignal(File outputFile, MultichannelSampleSource sampleSource, SignalExportDescriptor descriptor, SignalWriterMonitor monitor) throws IOException { FileWriter fileWriter = new FileWriter(outputFile); this.channelCount = sampleSource.getChannelCount(); for (int channelNumber = 0; channelNumber < channelCount; channelNumber++) { if(!writeSingleChannel(fileWriter, sampleSource, descriptor, monitor, channelNumber)) return; if (channelNumber < sampleSource.getChannelCount()-1) fileWriter.write("\n"); } fileWriter.close(); } /** * Exports signal from a single channel to file. * @param channelNumber number of channel to be exported. * @return false if writing data was cancelled, true if continuing is ok. * @throws IOException */ protected boolean writeSingleChannel( FileWriter output, MultichannelSampleSource sampleSource, SignalExportDescriptor descriptor, SignalWriterMonitor monitor, int channelNumber) throws IOException { int sampleCount = SampleSourceUtils.getMinSampleCount(sampleSource); int numberOfSamplesToGet = 0; for (int sampleNumber = 0; sampleNumber < sampleCount; sampleNumber += numberOfSamplesToGet) { numberOfSamplesToGet = Math.min(sampleCount - sampleNumber, BUFFER_SIZE); double[] data = new double[numberOfSamplesToGet]; sampleSource.getSamples(channelNumber, data, sampleNumber, numberOfSamplesToGet, 0); for (double sample: data) { output.write(formatter.format(sample) + descriptor.getSeparator()); } if (monitor != null && monitor.isRequestingAbort()) { return false; } if (monitor != null) { double processedSampleCount = channelNumber * sampleCount + sampleNumber + numberOfSamplesToGet; processedSampleCount = Math.ceil(processedSampleCount / channelCount); monitor.setProcessedSampleCount((int) processedSampleCount); } } return true; } }