/* MP5MethodDialog.java created 2007-10-28 * */ package org.signalml.app.method.mp5; import static org.signalml.app.util.i18n.SvarogI18n._; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.io.File; import java.io.IOException; import java.net.URL; import java.text.DecimalFormat; import java.text.NumberFormat; import java.util.Formatter; import java.util.concurrent.ExecutionException; import javax.swing.AbstractAction; import javax.swing.Box; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JSpinner; import javax.swing.JTabbedPane; import javax.swing.ListSelectionModel; import javax.swing.border.EmptyBorder; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import org.signalml.app.config.preset.Preset; import org.signalml.app.config.preset.PresetManager; import org.signalml.app.document.FileBackedDocument; import org.signalml.app.document.TagDocument; import org.signalml.app.document.signal.SignalDocument; import org.signalml.app.method.ApplicationMethodManager; import org.signalml.app.method.InitializingMethodConfigurer; import org.signalml.app.method.MethodPresetManager; import org.signalml.app.method.PresetEquippedMethodConfigurer; import org.signalml.app.model.components.validation.ValidationErrors; import org.signalml.app.model.signal.SignalExportDescriptor; import org.signalml.app.util.IconUtils; import org.signalml.app.view.common.dialogs.AbstractSignalSpaceAwarePresetDialog; import org.signalml.app.view.common.dialogs.OptionPane; import org.signalml.app.view.common.dialogs.PleaseWaitDialog; import org.signalml.app.view.common.dialogs.errors.Dialogs; import org.signalml.app.view.signal.PositionedTag; import org.signalml.app.view.signal.SampleSourceUtils; import org.signalml.app.view.signal.SignalPlot; import org.signalml.app.view.signal.SignalView; import org.signalml.app.view.signal.signalselection.SignalSpacePanel; import org.signalml.app.view.workspace.ViewerFileChooser; import org.signalml.app.worker.document.ExportSignalWorker; import org.signalml.domain.signal.SignalProcessingChain; 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.domain.signal.space.SegmentedSampleSourceFactory; import org.signalml.domain.signal.space.SignalSpace; import org.signalml.domain.signal.space.SignalSpaceConstraints; import org.signalml.exception.SanityCheckException; import org.signalml.method.Method; import org.signalml.method.mp5.MP5Algorithm; import org.signalml.method.mp5.MP5ConfigCreator; import org.signalml.method.mp5.MP5Data; import org.signalml.method.mp5.MP5DictionaryType; import org.signalml.method.mp5.MP5Parameters; import org.signalml.method.mp5.MP5RuntimeParameters; import org.signalml.method.mp5.MP5WritingModeType; import org.signalml.plugin.export.SignalMLException; import org.signalml.plugin.export.signal.SignalSelection; import org.signalml.plugin.export.signal.Tag; import org.signalml.util.Util; import org.springframework.core.io.ClassPathResource; /** MP5MethodDialog * * * @author Michal Dobaczewski © 2007-2008 CC Otwarte Systemy Komputerowe Sp. z o.o. */ public class MP5MethodDialog extends AbstractSignalSpaceAwarePresetDialog implements InitializingMethodConfigurer, PresetEquippedMethodConfigurer { private static final long serialVersionUID = 1L; public static final Dimension FIELD_SIZE = new Dimension(400,25); private static final long MEMORY_MB = 1024L*1024L; private static final long MEMORY_GB = 1024L*1024L*1024L; private static final long MEMORY_TB = 1024L*1024L*1024L*1024L; // public static final String HELP_ALGORITHM = "org/signalml/help/decompMP5.html#algorithm"; // public static final String HELP_BOOK_COMMENT = "org/signalml/help/decompMP5.html#bookComment"; // public static final String HELP_MAX_ITERATION_COUNT = "org/signalml/help/decompMP5.html#maxIterationCount"; // public static final String HELP_ENERGY_PERCENT = "org/signalml/help/decompMP5.html#energyPercent"; // public static final String HELP_ENERGY_ERROR = "org/signalml/help/decompMP5.html#energyError"; // public static final String HELP_ATOM_COUNT = "org/signalml/help/decompMP5.html#atomCount"; // public static final String HELP_RAM_USAGE = "org/signalml/help/decompMP5.html#ramUsage"; // public static final String HELP_DICTIONARY_TYPE = "org/signalml/help/decompMP5.html#dictionaryType"; // public static final String HELP_DICTIONARY_REINIT_TYPE = "org/signalml/help/decompMP5.html#dictionaryReinitType"; // public static final String HELP_SCALE_TO_PERIOD_FACTOR = "org/signalml/help/decompMP5.html#scaleToPeriodFactor"; // public static final String HELP_BOOK_WITH_SIGNAL = "org/signalml/help/decompMP5.html#bookWithSignal"; // public static final String HELP_ADDITIONAL_CONFIG = "org/signalml/help/decompMP5.html#additionalConfig"; // public static final String HELP_RAW_CONFIG = "org/signalml/help/decompMP5.html#rawConfig"; private PleaseWaitDialog pleaseWaitDialog; private MP5ExecutorManager executorManager; private MP5LocalExecutorDialog localExecutorDialog; private MP5ToolConfigDialog configDialog; private SignalSpacePanel signalSpacePanel; private MP5DictionaryConfigPanel dictionaryConfigPanel; private MP5DecompositionConfigPanel decompositionConfigPanel; private MP5ExpertConfigPanel expertConfigPanel; private MP5RawConfigPanel rawConfigPanel; private JTabbedPane tabbedPane; private boolean rawMode = false; private SwitchEditModeAction switchEditModeAction; private MP5ConfigCreator mp5ConfigCreator = null; private RawSignalWriter rawSignalWriter = null; private MP5Data currentData; private MP5Parameters currentParameters; private MP5SaveForLaterUseDialog mP5SaveForLaterUseDialog; private URL contextHelpURL = null; private int currentPageLength; private int currentSelectedChannelCount; private NumberFormat memoryFormat = new DecimalFormat("0.00"); private NumberFormat atomCountFormat = DecimalFormat.getIntegerInstance(); private Window dialogParent; public MP5MethodDialog(MethodPresetManager methodPresetManager, Window w) { super(methodPresetManager, w, true); } @Override protected JPanel createButtonPane() { JPanel buttonPane = super.createButtonPane(); buttonPane.add(Box.createHorizontalStrut(10), 1); buttonPane.add(new JButton(new SaveConfigAction()), 1); buttonPane.add(Box.createHorizontalStrut(3), 1); buttonPane.add(new JButton(getSwitchEditModeAction()), 1); return buttonPane; } @Override public void initialize(ApplicationMethodManager manager) { setFileChooser(manager.getFileChooser()); executorManager = manager.getMp5ExecutorManager(); dialogParent = manager.getDialogParent(); } @Override protected void initialize() { setTitle(_("MP Decomposition configuration")); setIconImage(IconUtils.loadClassPathImage(MP5MethodDescriptor.ICON_PATH)); setResizable(false); super.initialize(); } public MP5ToolConfigDialog getConfigDialog() { if (configDialog == null) { configDialog = new MP5ToolConfigDialog(dialogParent,true); configDialog.setExecutorManager(executorManager); configDialog.setLocalExecutorDialog(getLocalExecutorDialog()); } return configDialog; } @Override protected URL getContextHelpURL() { if (contextHelpURL == null) { try { contextHelpURL = (new ClassPathResource("org/signalml/help/decompMP5.html")).getURL(); } catch (IOException ex) { logger.error("Failed to get help URL", ex); } } return contextHelpURL; } @Override public JComponent createInterface() { JPanel interfacePanel = new JPanel(); interfacePanel.setLayout(new BorderLayout()); interfacePanel.setBorder(new EmptyBorder(3,3,3,3)); interfacePanel.add(getTabbedPane()); getSignalSpacePanel().getChannelSpacePanel().getChannelList().getSelectionModel().addListSelectionListener(new ListSelectionListener() { @Override public void valueChanged(ListSelectionEvent e) { JList list = getSignalSpacePanel().getChannelSpacePanel().getChannelList(); int size = list.getModel().getSize(); ListSelectionModel selecton = list.getSelectionModel(); int selCount = 0; for (int i=0; i<size; i++) { if (selecton.isSelectedIndex(i)) { selCount++; } } boolean mmpEnabled = (selCount > 1); getDecompositionConfigPanel().getAlgorithmConfigPanel().setMMPEnabled(mmpEnabled); currentSelectedChannelCount = selCount; updateInfoFields(); } }); final JSpinner energyErrorPercentageSpinner = getDictionaryConfigPanel().getDictionaryDensityConfigPanel().getEnergyErrorPercentageSpinner(); final JComboBox dictionaryTypeComboBox = getDictionaryConfigPanel().getAdvancedDecompositionConfigPanel().getDictionaryTypeComboBox(); dictionaryTypeComboBox.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { if (e.getStateChange() == ItemEvent.SELECTED) { energyErrorPercentageSpinner.setEnabled(e.getItem() == MP5DictionaryType.OCTAVE_STOCH); } } }); ChangeListener changeListener = new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { updateInfoFields(); } }; ItemListener itemListener = new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { if (e.getStateChange() == ItemEvent.SELECTED) { updateInfoFields(); } } }; getDictionaryConfigPanel().getDictionaryDensityConfigPanel().getEnergyErrorSpinner().addChangeListener(changeListener); energyErrorPercentageSpinner.addChangeListener(changeListener); getDecompositionConfigPanel().getAlgorithmConfigPanel().getAlgorithmComboBox().addItemListener(itemListener); getDictionaryConfigPanel().getAdvancedDecompositionConfigPanel().getDictionaryTypeComboBox().addItemListener(itemListener); dictionaryTypeComboBox.addItemListener(itemListener); return interfacePanel; } public SignalSpacePanel getSignalSpacePanel() { if (signalSpacePanel == null) { signalSpacePanel = new SignalSpacePanel(); signalSpacePanel.getChannelSpacePanel().getChannelList().setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION); } return signalSpacePanel; } public MP5DictionaryConfigPanel getDictionaryConfigPanel() { if (dictionaryConfigPanel == null) { dictionaryConfigPanel = new MP5DictionaryConfigPanel(this); } return dictionaryConfigPanel; } public MP5DecompositionConfigPanel getDecompositionConfigPanel() { if (decompositionConfigPanel == null) { decompositionConfigPanel = new MP5DecompositionConfigPanel(this); } return decompositionConfigPanel; } public MP5ExpertConfigPanel getExpertConfigPanel() { if (expertConfigPanel == null) { expertConfigPanel = new MP5ExpertConfigPanel(executorManager,this); } return expertConfigPanel; } public MP5RawConfigPanel getRawConfigPanel() { if (rawConfigPanel == null) { rawConfigPanel = new MP5RawConfigPanel(executorManager,this); } return rawConfigPanel; } public JTabbedPane getTabbedPane() { if (tabbedPane == null) { tabbedPane = new JTabbedPane(JTabbedPane.TOP, JTabbedPane.SCROLL_TAB_LAYOUT); configureTabbedPaneForRawMode(rawMode); } return tabbedPane; } private void configureTabbedPaneForRawMode(boolean rawMode) { JTabbedPane pane = getTabbedPane(); pane.removeAll(); pane.addTab(_("Signal selection"), getSignalSpacePanel()); if (rawMode) { pane.addTab(_("Edit raw config"), getRawConfigPanel()); } else { pane.addTab(_("Dictionary"), getDictionaryConfigPanel()); pane.addTab(_("Decomposition"), getDecompositionConfigPanel()); pane.addTab(_("Advanced/setup"), getExpertConfigPanel()); } } public SwitchEditModeAction getSwitchEditModeAction() { if (switchEditModeAction == null) { switchEditModeAction = new SwitchEditModeAction(); } return switchEditModeAction; } public boolean setRawMode(boolean rawMode) { if (this.rawMode != rawMode) { SwitchEditModeAction modeAction = getSwitchEditModeAction(); if (rawMode) { // enter raw mode modeAction.putValue(AbstractAction.NAME, _("To friendly mode")); modeAction.putValue(AbstractAction.SHORT_DESCRIPTION,_("Edit MP5 configuration with a user friendly editor")); } else { // exit raw mode if (getRawConfigPanel().isConfigChanged()) { int ans = OptionPane.showRawConfigWillBeLost(this); if (ans != OptionPane.OK_OPTION) { return false; } } modeAction.putValue(AbstractAction.NAME, _("To raw mode")); modeAction.putValue(AbstractAction.SHORT_DESCRIPTION,_("Edit MP5 configuration as text")); } this.rawMode = rawMode; configureTabbedPaneForRawMode(rawMode); getTabbedPane().setSelectedIndex(1); return true; } else { return true; } } @Override public void fillDialogFromModel(Object model) throws SignalMLException { MP5ApplicationData data = (MP5ApplicationData) model; currentData = data; SignalDocument signalDocument = data.getSignalDocument(); SignalView signalView = (SignalView) signalDocument.getDocumentView(); SignalPlot masterPlot = signalView.getMasterPlot(); SignalSpaceConstraints signalSpaceConstraints = signalView.createSignalSpaceConstraints(); TagDocument tagDocument = signalDocument.getActiveTag(); if (tagDocument != null) { tagDocument.updateSignalSpaceConstraints(signalSpaceConstraints); } getSignalSpacePanel().setConstraints(signalSpaceConstraints); currentPageLength = (int)(signalSpaceConstraints.getPageSize() * signalSpaceConstraints.getSamplingFrequency()); MP5Parameters parameters = (MP5Parameters) getPresetManager().getDefaultPreset(); if (parameters == null) { parameters = data.getParameters(); } SignalSelection signalSelection = signalView.getSignalSelection(masterPlot); Tag tag = null; if (tagDocument != null) { PositionedTag tagSelection = signalView.getTagSelection(masterPlot); if (tagSelection != null) { if (tagSelection.getTagPositionIndex() == signalDocument.getTagDocuments().indexOf(tagDocument)) { tag = tagSelection.getTag(); } } } parameters.getSignalSpace().configureFromSelections(signalSelection, tag); fillDialogFromParameters(parameters, true); if (parameters.getRawConfigText() == null) { getExpertConfigPanel().getExecutorPanel().fillPanelFromModel(data); } else { getRawConfigPanel().getExecutorPanel().fillPanelFromModel(data); } getRawConfigPanel().setConfigChanged(true); } private void fillDialogFromParameters(MP5Parameters parameters, boolean includeSpace) { currentParameters = parameters; if (includeSpace) { getSignalSpacePanel().fillPanelFromModel(parameters.getSignalSpace()); } MP5RawConfigPanel rawConfig = getRawConfigPanel(); if (parameters.getRawConfigText() == null) { rawConfig.setConfigChanged(false); setRawMode(false); getDictionaryConfigPanel().fillPanelFromParameters(parameters); getDecompositionConfigPanel().fillPanelFromParameters(parameters); getExpertConfigPanel().fillPanelFromParameters(parameters); } else { rawConfig.setConfigChanged(false); setRawMode(true); rawConfig.fillPanelFromParameters(parameters); } } @Override public void fillModelFromDialog(Object model) throws SignalMLException { MP5ApplicationData data = (MP5ApplicationData) model; fillParametersFromDialog(data.getParameters()); if (data.getParameters().getRawConfigText() == null) { getExpertConfigPanel().getExecutorPanel().fillModelFromPanel(data); } else { getRawConfigPanel().getExecutorPanel().fillModelFromPanel(data); } data.calculate(); } private void fillParametersFromDialog(MP5Parameters parameters) { getSignalSpacePanel().fillModelFromPanel(parameters.getSignalSpace()); if (rawMode) { getRawConfigPanel().fillParametersFromPanel(parameters); } else { getDictionaryConfigPanel().fillParametersFromPanel(parameters); getDecompositionConfigPanel().fillParametersFromPanel(parameters); getExpertConfigPanel().fillParametersFromPanel(parameters); parameters.setRawConfigText(null); } } @Override public Preset getPreset() throws SignalMLException { MP5Parameters parameters = new MP5Parameters(); fillParametersFromDialog(parameters); return parameters; } @Override public void setPreset(Preset preset, boolean includeSpace) throws SignalMLException { MP5Parameters parameters = (MP5Parameters) preset; fillDialogFromParameters(parameters, includeSpace); getRawConfigPanel().setConfigChanged(true); } @Override public void validateDialog(Object model, ValidationErrors errors) throws SignalMLException { getSignalSpacePanel().validatePanel(errors); if (rawMode) { getRawConfigPanel().validatePanel(errors); } else { getDictionaryConfigPanel().validatePanel(errors); getDecompositionConfigPanel().validatePanel(errors); getExpertConfigPanel().validatePanel(errors); } if (rawMode) { getRawConfigPanel().getExecutorPanel().validatePanel(errors); } else { getExpertConfigPanel().getExecutorPanel().validatePanel(errors); } } public void updateInfoFields() { MP5DictionaryConfigPanel panel = getDictionaryConfigPanel(); MP5DictionaryDensityConfigPanel densityConfigPanel = panel.getDictionaryDensityConfigPanel(); MP5AdvancedDecompositionConfigPanel advancedPanel = panel.getAdvancedDecompositionConfigPanel(); double eps2 = ((Number) densityConfigPanel.getEnergyErrorSpinner().getValue()).doubleValue(); double eps = Math.sqrt(eps2); double a = (1 + eps*Math.sqrt((2.0-eps2)*(eps2*eps2-2.0*eps2+2.0))) / ((1.0-eps2)*(1.0-eps2)); double percentageChosen = ((Number) densityConfigPanel.getEnergyErrorPercentageSpinner().getValue()).doubleValue(); // R = 0.5pi * N * ln(N)/ln(a) / ln(1-eps2) double approxAtomCount = Math.ceil(0.5 * Math.PI * currentPageLength * Math.log(currentPageLength)/Math.log(a) / Math.abs(Math.log(1.0-eps2)) ); if (advancedPanel.getDictionaryTypeComboBox().getSelectedItem() == MP5DictionaryType.OCTAVE_STOCH) { approxAtomCount *= (percentageChosen / 100.0F); } MP5Algorithm algorithm = (MP5Algorithm) getDecompositionConfigPanel().getAlgorithmConfigPanel().getAlgorithmComboBox().getSelectedItem(); int k; switch (algorithm) { case SMP : case MMP2 : k = 1; break; case MMP1 : case MMP3 : k = currentSelectedChannelCount; break; default : throw new SanityCheckException("Unsupported algorithm [" + algorithm + "]"); } // 2*sizeof(unsigned short int) + sizeof(unsigned int) + 3*sizeof(float) + 3*K*sizeof(float) + szieof(unsigned char) int atomSize = 2*2 + 4 + 3*4 + 3*k*4 + 1; double dictionarySize = approxAtomCount * atomSize; double unitedSize; String units; if (dictionarySize < MEMORY_GB) { unitedSize = ((double) dictionarySize) / MEMORY_MB; units = "MB"; } else if (dictionarySize < MEMORY_TB) { unitedSize = ((double) dictionarySize) / MEMORY_GB; units = "GB"; } else { unitedSize = ((double) dictionarySize) / MEMORY_TB; units = "TB"; } String memoryUsageString = memoryFormat.format(unitedSize) + " " + units; String approxAtomCountString = atomCountFormat.format(approxAtomCount); densityConfigPanel.getAtomCountTextField().setText(approxAtomCountString); densityConfigPanel.getRamUsageTextField().setText(memoryUsageString); } @Override protected void onDialogClose() { try { Preset preset = getPreset(); getPresetManager().setDefaultPreset(preset); } catch (Exception ex) { logger.debug("Failed to get preset", ex); } currentParameters = null; } @Override public boolean configure(Method method, Object methodDataObj) throws SignalMLException { if (executorManager.getExecutorCount() == 0) { boolean configureOk = getConfigDialog().showDialog(null, true); if (!configureOk) { return false; } } return showDialog(methodDataObj, true); } @Override public void setPresetManager(PresetManager presetManager) { } public MP5ConfigCreator getMp5ConfigCreator() { if (mp5ConfigCreator == null) { mp5ConfigCreator = new MP5ConfigCreator(); } return mp5ConfigCreator; } protected MP5LocalExecutorDialog getLocalExecutorDialog() { if (localExecutorDialog == null) { localExecutorDialog = new MP5LocalExecutorDialog(this,true); localExecutorDialog.setFileChooser(getFileChooser()); } return localExecutorDialog; } protected PleaseWaitDialog getPleaseWaitDialog() { if (pleaseWaitDialog == null) { pleaseWaitDialog = new PleaseWaitDialog(this); pleaseWaitDialog.initializeNow(); } return pleaseWaitDialog; } @Override public boolean supportsModelClass(Class<?> clazz) { return MP5ApplicationData.class.isAssignableFrom(clazz); } protected class SwitchEditModeAction extends AbstractAction { private static final long serialVersionUID = 1L; public SwitchEditModeAction() { super(_("To raw mode")); putValue(AbstractAction.SMALL_ICON, IconUtils.loadClassPathIcon("org/signalml/app/icon/switcheditmode.png")); putValue(AbstractAction.SHORT_DESCRIPTION,_("Edit MP5 configuration as text")); } public void actionPerformed(ActionEvent ev) { if (currentParameters == null) { return; } if (rawMode) { // switch from raw mode fillParametersFromDialog(currentParameters); getRawConfigPanel().getExecutorPanel().fillModelFromPanel(currentData); boolean ok = setRawMode(false); if (!ok) { return; } currentParameters.setRawConfigText(null); fillDialogFromParameters(currentParameters, false); getExpertConfigPanel().getExecutorPanel().fillPanelFromModel(currentData); } else { // switch to raw mode fillParametersFromDialog(currentParameters); getExpertConfigPanel().getExecutorPanel().fillModelFromPanel(currentData); boolean ok = setRawMode(true); if (!ok) { return; } MP5ConfigCreator mp5ConfigCreator = getMp5ConfigCreator(); Formatter configFormatter = mp5ConfigCreator.createConfigFormatter(false); mp5ConfigCreator.writeRuntimeInvariantConfig(currentParameters, configFormatter); currentParameters.setRawConfigText(configFormatter.toString()); fillDialogFromParameters(currentParameters, false); getRawConfigPanel().getExecutorPanel().fillPanelFromModel(currentData); getRawConfigPanel().setConfigChanged(false); } } } protected class SaveConfigAction extends AbstractAction { private static final long serialVersionUID = 1L; public SaveConfigAction() { super(_("Save for later use")); putValue(AbstractAction.SMALL_ICON, IconUtils.loadClassPathIcon("org/signalml/app/icon/saveconfig.png")); putValue(AbstractAction.SHORT_DESCRIPTION,_("Save for later use")); } public void actionPerformed(ActionEvent ev) { Object currentModel = getCurrentModel(); if (currentModel != null) { ValidationErrors errors = new ValidationErrors(); try { validateDialog(currentModel,errors); } catch (SignalMLException ex) { logger.error("Dialog validation threw an exception", ex); Dialogs.showExceptionDialog(MP5MethodDialog.this, ex); return; } if (errors.hasErrors()) { showValidationErrors(errors); return; } } MP5Parameters parameters = new MP5Parameters(); fillParametersFromDialog(parameters); MP5SaveForLaterUseDescriptor mP5SaveForLaterUseDescriptor = new MP5SaveForLaterUseDescriptor(); mP5SaveForLaterUseDescriptor.setSaveSignal(true); mP5SaveForLaterUseDescriptor.setSaveConfig(true); if (mP5SaveForLaterUseDialog == null) { mP5SaveForLaterUseDialog = new MP5SaveForLaterUseDialog(MP5MethodDialog.this, true); } boolean ok = mP5SaveForLaterUseDialog.showDialog(mP5SaveForLaterUseDescriptor, true); if (!ok) { return; } if (!mP5SaveForLaterUseDescriptor.isSaveConfig() && !mP5SaveForLaterUseDescriptor.isSaveSignal()) { return; } MP5ApplicationData currentData = (MP5ApplicationData) currentModel;; SignalDocument signalDocument = currentData.getSignalDocument(); boolean hasFile = false; File configFile = null; File signalFile = null; if (mP5SaveForLaterUseDescriptor.isSaveConfig()) { File file = null; do { file = ((ViewerFileChooser) getFileChooser()).chooseSaveMP5ConfigFile(MP5MethodDialog.this); //TODO remove cast if (file == null) { return; } hasFile = true; if (file.exists()) { int res = OptionPane.showFileAlreadyExists(MP5MethodDialog.this); if (res != OptionPane.OK_OPTION) { hasFile = false; } } } while (!hasFile); configFile = file; signalFile = Util.changeOrAddFileExtension(file, "bin"); if (configFile.equals(signalFile)) { signalFile = new File(file.getParent(), "_" + file.getName()); } } else { if (signalDocument instanceof FileBackedDocument) { File backingFile = ((FileBackedDocument) signalDocument).getBackingFile(); if (backingFile != null) { signalFile = new File(backingFile.getName()); String extension = Util.getFileExtension(signalFile, false); if (extension == null || ! "bin".equals(extension)) { signalFile = Util.changeOrAddFileExtension(signalFile, "bin"); } } } } if (mP5SaveForLaterUseDescriptor.isSaveSignal()) { File file = null; do { file = getFileChooser().chooseExportSignalFile(MP5MethodDialog.this, signalFile); if (file == null) { return; } hasFile = true; if (file.exists() || (configFile != null && file.equals(configFile))) { int res = OptionPane.showFileAlreadyExists(MP5MethodDialog.this); if (res != OptionPane.OK_OPTION) { hasFile = false; } } } while (!hasFile); signalFile = file; } SignalView signalView = (SignalView) signalDocument.getDocumentView(); SignalPlot plot = signalView.getMasterPlot(); SignalProcessingChain signalChain = plot.getSignalChain(); SignalSpace signalSpace = parameters.getSignalSpace(); SignalProcessingChain copyChain; try { copyChain = signalChain.createLevelCopyChain(signalSpace.getSignalSourceLevel()); } catch (SignalMLException ex) { logger.error("Failed to create signal chain", ex); Dialogs.showExceptionDialog((Window) null, ex); return; } TagDocument tagDocument = signalDocument.getActiveTag(); SegmentedSampleSourceFactory factory = SegmentedSampleSourceFactory.getSharedInstance(); MultichannelSegmentedSampleSource sampleSource = factory.getSegmentedSampleSource(copyChain, signalSpace, tagDocument != null ? tagDocument.getTagSet() : null, plot.getPageSize(), plot.getBlockSize()); int minSampleCount = SampleSourceUtils.getMinSampleCount(sampleSource); if (mP5SaveForLaterUseDescriptor.isSaveSignal()) { if (rawSignalWriter == null) { rawSignalWriter = new RawSignalWriter(); } SignalExportDescriptor signalExportDescriptor = new SignalExportDescriptor(); signalExportDescriptor.setSampleType(RawSignalSampleType.FLOAT); signalExportDescriptor.setByteOrder(RawSignalByteOrder.LITTLE_ENDIAN); signalExportDescriptor.setNormalize(false); ExportSignalWorker worker = new ExportSignalWorker(sampleSource, signalFile, signalExportDescriptor, getPleaseWaitDialog()); worker.execute(); PleaseWaitDialog waitDialog = getPleaseWaitDialog(); waitDialog.setActivity(_("exporting signal")); waitDialog.configureForDeterminate(0, minSampleCount, 0); waitDialog.waitAndShowDialogIn(MP5MethodDialog.this.getRootPane(), 500, worker); try { worker.get(); } catch (InterruptedException ex) { // ignore } catch (ExecutionException ex) { logger.error("Worker failed to save signal", ex.getCause()); Dialogs.showExceptionDialog((Window) null, ex.getCause()); return; } } if (mP5SaveForLaterUseDescriptor.isSaveConfig()) { MP5ConfigCreator mp5ConfigCreator = getMp5ConfigCreator(); 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); runtimeParameters.setMinOffset(1); runtimeParameters.setMaxOffset(((int) Math.floor(minSampleCount / sampleSource.getSegmentLengthInSamples()))); Formatter configFormatter = mp5ConfigCreator.createConfigFormatter(); String rawConfig = parameters.getRawConfigText(); if (rawConfig == null) { mp5ConfigCreator.writeRuntimeInvariantConfig(parameters, configFormatter); } else { mp5ConfigCreator.writeRawConfig(rawConfig, configFormatter); } mp5ConfigCreator.writeRuntimeConfig(runtimeParameters, configFormatter); // write config try { mp5ConfigCreator.writeMp5Config(configFormatter, configFile); } catch (IOException ex) { logger.error("Failed to save config", ex); Dialogs.showExceptionDialog((Window) null, ex); return; } } } } }