/* MP5LocalProcessExecutor.java created 2008-02-08
*
*/
package org.signalml.method.mp5;
import static org.signalml.app.util.i18n.SvarogI18n._;
import java.io.File;
import java.io.IOException;
import java.util.Formatter;
import java.util.UUID;
import org.apache.log4j.Logger;
import org.signalml.app.model.signal.SignalExportDescriptor;
import org.signalml.domain.signal.raw.RawSignalByteOrder;
import org.signalml.domain.signal.raw.RawSignalSampleType;
import org.signalml.domain.signal.raw.RawSignalWriter;
import org.signalml.domain.signal.samplesource.MultichannelSegmentedSampleSource;
import org.signalml.method.ComputationException;
import org.signalml.method.MethodExecutionTracker;
import com.thoughtworks.xstream.annotations.XStreamAlias;
/** MP5LocalProcessExecutor
*
*
* @author Michal Dobaczewski © 2007-2008 CC Otwarte Systemy Komputerowe Sp. z o.o.
*/
@XStreamAlias("mp5localexecutor")
public class MP5LocalProcessExecutor implements MP5Executor {
protected static final Logger logger = Logger.getLogger(MP5LocalProcessExecutor.class);
private static final String[] CODES = new String[] { "mp5Method.executor.localProcess" };
private String uid;
private String name;
private String mp5ExecutablePath;
private transient MP5ConfigCreator configCreator = new MP5ConfigCreator();
private transient RawSignalWriter rawSignalWriter = new RawSignalWriter();
private transient MP5LocalProcessController processController = new MP5LocalProcessController();
public MP5LocalProcessExecutor() {
uid = UUID.randomUUID().toString();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String getUID() {
return uid;
}
public String getMp5ExecutablePath() {
return mp5ExecutablePath;
}
public void setMp5ExecutablePath(String mp5ExecutablePath) {
this.mp5ExecutablePath = mp5ExecutablePath;
}
@Override
public boolean execute(MP5Data data, int segment, File resultFile, MethodExecutionTracker tracker) throws ComputationException {
File workingDirectory = data.getWorkingDirectory();
MP5Parameters parameters = data.getParameters();
MultichannelSegmentedSampleSource sampleSource = data.getSampleSource();
File configFile = new File(workingDirectory, "mp5.cfg");
File signalFile = new File(workingDirectory, "signal.bin");
MP5RuntimeParameters runtimeParameters = new MP5RuntimeParameters();
runtimeParameters.setChannelCount(sampleSource.getChannelCount());
runtimeParameters.setSegementSize(sampleSource.getSegmentLengthInSamples());
runtimeParameters.setChosenChannels(null);
runtimeParameters.setOutputDirectory(null);
runtimeParameters.setPointsPerMicrovolt(1F);
runtimeParameters.setSamplingFrequency(sampleSource.getSamplingFrequency());
runtimeParameters.setSignalFile(signalFile);
runtimeParameters.setWritingMode(MP5WritingModeType.CREATE);
SignalExportDescriptor signalExportDescriptor = new SignalExportDescriptor();
signalExportDescriptor.setSampleType(RawSignalSampleType.FLOAT);
signalExportDescriptor.setByteOrder(RawSignalByteOrder.LITTLE_ENDIAN);
signalExportDescriptor.setNormalize(false);
Formatter configFormatter = configCreator.createConfigFormatter();
String rawConfig = parameters.getRawConfigText();
if (rawConfig == null) {
configCreator.writeRuntimeInvariantConfig(parameters, configFormatter);
} else {
configCreator.writeRawConfig(rawConfig, configFormatter);
}
configCreator.writeRuntimeConfig(runtimeParameters, configFormatter);
// write config
try {
configCreator.writeMp5Config(configFormatter, configFile);
} catch (IOException ex) {
logger.error("Failed to create config file", ex);
throw new ComputationException(ex);
}
tracker.setMessage(_("Writing signal file"));
// write data file
try {
rawSignalWriter.writeSignal(signalFile, sampleSource, signalExportDescriptor, segment, null);
} catch (IOException ex) {
logger.error("Failed to create data file", ex);
throw new ComputationException(ex);
}
// delete results in the way
File generatedBookFile;
if (parameters.getAlgorithm() == MP5Algorithm.SMP) {
generatedBookFile = new File(workingDirectory, "signal_smp.b");
} else {
generatedBookFile = new File(workingDirectory, "signal_mmp.b");
}
if (generatedBookFile.exists()) {
generatedBookFile.delete();
}
tracker.setMessage(_("Starting executable"));
boolean executionOk = processController.executeProcess(workingDirectory, mp5ExecutablePath, configFile, tracker);
if (!executionOk) {
return false;
}
if (!generatedBookFile.exists()) {
logger.error("MP5 process didn't produce expected result file [" + generatedBookFile.getAbsolutePath() + "]");
throw new ComputationException("error.mp5.exitedWithNoResult");
}
boolean renameOk = generatedBookFile.renameTo(resultFile);
if (!renameOk) {
logger.error("Failed to rename [" + generatedBookFile.getAbsolutePath() + "] to [" + resultFile.getAbsolutePath() + "]");
throw new ComputationException("error.mp5.resultRenameFailed");
}
return true;
}
@Override
public Object[] getArguments() {
return new Object[] { name };
}
@Override
public String[] getCodes() {
return CODES;
}
@Override
public String getDefaultMessage() {
return "MP5LocalProcessExecutor [" + name + "]";
}
@Override
public String toString() {
return getDefaultMessage();
}
public static MP5LocalProcessExecutor pathExecutor() {
MP5LocalProcessExecutor ex = new MP5LocalProcessExecutor();
ex.setName("execute from $PATH");
ex.setMp5ExecutablePath("mp5");
return ex;
}
}