diff --git a/java/source/infodynamics/demos/autoanalysis/AutoAnalyser.java b/java/source/infodynamics/demos/autoanalysis/AutoAnalyser.java index 077b3cf..22f22d4 100644 --- a/java/source/infodynamics/demos/autoanalysis/AutoAnalyser.java +++ b/java/source/infodynamics/demos/autoanalysis/AutoAnalyser.java @@ -28,6 +28,7 @@ import infodynamics.utils.EmpiricalNullDistributionComputer; import infodynamics.utils.MatrixUtils; import javax.swing.BorderFactory; +import javax.swing.DefaultCellEditor; import javax.swing.ImageIcon; import javax.swing.JComponent; import javax.swing.JFrame; @@ -49,6 +50,7 @@ import javax.swing.event.ChangeListener; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.table.AbstractTableModel; +import javax.swing.table.TableCellEditor; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; @@ -108,11 +110,13 @@ public abstract class AutoAnalyser extends JFrame protected String[] discreteProperties; // Children to initialise protected String[] discretePropertyDefaultValues; // Children to initialise protected String[] discretePropertyDescriptions; // Children to initialise + protected String[][] discretePropertyValueChoices; // Children to initialise // Common property names for all continuous calculators: protected String[] commonContPropertyNames; protected String[] commonContPropertiesFieldNames; protected String[] commonContPropertyDescriptions; + protected String[][] commonContPropertyValueChoices; // Children can define properties for specific continuous // calculators @@ -179,6 +183,8 @@ public abstract class AutoAnalyser extends JFrame protected int numPermutationsToCheck = 100; // Table for the properties protected JTable propertiesTable; + // Default editor for the property values + protected TableCellEditor propertiesDefaultEditor; // Table model (local class) for the table protected PropertiesTableModel propertiesTableModel; // Names of the properties @@ -187,6 +193,8 @@ public abstract class AutoAnalyser extends JFrame protected Vector propertyFieldNames; // Descriptions of the fields for the properties protected Vector propertyDescriptions; + // Lists of drop-down options for the properties + protected Vector propertyValueChoices; // Values of the properties protected HashMap propertyValues; // CheckBox for "Compute result?" @@ -213,7 +221,7 @@ public abstract class AutoAnalyser extends JFrame protected String pathToAutoAnalyserDir = ""; // Main JIDT git/distribution folder, inferred from pathToAutoAnalyserDir protected String jidtFolder = ""; - + public class TextAreaWithImage extends JTextArea { /** @@ -294,7 +302,7 @@ public abstract class AutoAnalyser extends JFrame Image watermarkImage = (new ImageIcon(pathToAutoAnalyserDir + "JIDT-logo-watermark.png")).getImage(); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - setSize(1100,670); + setSize(1100,680); setTitle(appletTitle); // Centre in the middle of the screen setLocationRelativeTo(null); @@ -366,13 +374,17 @@ public abstract class AutoAnalyser extends JFrame putCalcPropertiesInTable(); propertiesTableModel = new PropertiesTableModel(); propertiesTable = new TableWithToolTip(propertiesTableModel); + // Get the default editor for the properties values: + propertiesDefaultEditor = propertiesTable.getDefaultEditor( + propertiesTable.getColumnClass(1)); + System.out.println("Default properties editor is " + propertiesDefaultEditor.getClass().getName()); // Make sure any properties are saved when the compute button is clicked propertiesTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE); Font headerFont = propertiesTable.getTableHeader().getFont(); propertiesTable.getTableHeader().setFont(headerFont.deriveFont(Font.BOLD)); TableColumn valueColumn = propertiesTable.getColumn("Property value"); - valueColumn.setMinWidth(130); - valueColumn.setMaxWidth(130); + valueColumn.setMinWidth(170); + valueColumn.setMaxWidth(170); JScrollPane propsTableScrollPane = new JScrollPane(propertiesTable); // Set up for ~18 rows maximum (the +6 is exact to fit all props // for Kraskov TE in without scrollbar) @@ -383,7 +395,7 @@ public abstract class AutoAnalyser extends JFrame propsTableScrollPane.setMinimumSize( new Dimension(d.width,rowHeight*17+6)); System.out.println("Row height was " + rowHeight); - + // Checkbox for compute result computeResultCheckBox = new JCheckBox("Compute result?"); computeResultCheckBox.setToolTipText("Compute result or only generate code?"); @@ -418,7 +430,7 @@ public abstract class AutoAnalyser extends JFrame javaAreaScrollPane.setHorizontalScrollBarPolicy( JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); int codeTextAreaWidth = 560; - int codeTextAreaHeight = 480; + int codeTextAreaHeight = 530; Dimension codeTextAreaDimension = new Dimension(codeTextAreaWidth, codeTextAreaHeight); javaAreaScrollPane.setPreferredSize(codeTextAreaDimension); @@ -653,8 +665,8 @@ public abstract class AutoAnalyser extends JFrame } protected void loadData(boolean isInts) { - ArrayFileReader afr = new ArrayFileReader(dataFile); try { + ArrayFileReader afr = new ArrayFileReader(dataFile); if (isInts) { dataDiscrete = afr.getInt2DMatrix(); dataRows = dataDiscrete.length; @@ -1558,6 +1570,70 @@ public abstract class AutoAnalyser extends JFrame } } */ + + /** + * Use this method to set combo box options for editing cells + */ + @Override + public TableCellEditor getCellEditor(int row, int column) { + if ((propertyValueChoices.get(row) != null) && (column == 1)) { + // We need to construct a combo box for the selection for this property: + try { + JComboBox paramChoiceComboBox = new JComboBox(); + // Set font to not bold and one size less than the default (to fit better) + Font font = paramChoiceComboBox.getFont(); + paramChoiceComboBox.setFont(font.deriveFont(Font.PLAIN, font.getSize()-1)); + String[] choices = propertyValueChoices.get(row); + for (int c = 0; c < choices.length; c++) { + paramChoiceComboBox.addItem(choices[c]); + } + return new DefaultCellEditor(paramChoiceComboBox); + } catch (Exception e) { + e.printStackTrace(); + // But now allow this to be handled by the default cell editor + } + } + // I think the following would do the default behaviour: + // return this.getDefaultEditor(this.getColumnClass(column)); + // however it should be safer to just allow the parent to handle: + return super.getCellEditor(row, column); + } + + /** + * This method allows us to keep a combo box visible when + * the property value is no longer selected. + * Adapted from answer at https://stackoverflow.com/questions/30744524/how-to-make-the-jcombobox-dropdown-always-visible-in-a-jtable + */ + @Override + public TableCellRenderer getCellRenderer(int row, int column) { + if ((propertyValueChoices.get(row) != null) && (column == 1)) { + try { + return new TableCellRenderer() { + JComboBox box = new JComboBox(); + int defaultFontSize = box.getFont().getSize(); + + @Override + public Component getTableCellRendererComponent(JTable table, + Object value, boolean isSelected, boolean hasFocus, int row, + int column) { + // Set font to not bold and one size less than the default (to fit better) + Font font = box.getFont(); + box.setFont(font.deriveFont(Font.PLAIN, defaultFontSize-1)); + // Now empty all items out and just put the value we currently have. + // (This is only for displaying, the editor will override with available values if + // user wants to edit). + box.removeAllItems(); + box.addItem(value.toString()); + return box; + } + }; + } catch (Exception e) { + e.printStackTrace(); + // But now allow this to be handled by the default cell renderer + } + } + return super.getCellRenderer(row, column); + } } protected class PropertiesTableModel extends AbstractTableModel { @@ -1645,6 +1721,8 @@ public abstract class AutoAnalyser extends JFrame calcProperties.classSpecificPropertiesFieldNames; String[] classSpecificPropertyDescriptions = calcProperties.classSpecificPropertyDescriptions; + String[][] classSpecificPropertyValueChoices = + calcProperties.classSpecificPropertyValueChoices; calcClass = calcProperties.calcClass; Object calc = calcProperties.calc; @@ -1652,6 +1730,7 @@ public abstract class AutoAnalyser extends JFrame propertyNames = new Vector(); propertyFieldNames = new Vector(); propertyDescriptions = new Vector(); + propertyValueChoices = new Vector(); if (selectedCalcType.equalsIgnoreCase(CALC_TYPE_DISCRETE) || selectedCalcType.equalsIgnoreCase(CALC_TYPE_BINNED)) { @@ -1662,10 +1741,12 @@ public abstract class AutoAnalyser extends JFrame for (String propName : discreteProperties) { String propertyDescription = discretePropertyDescriptions[i]; String defaultPropertyValue = discretePropertyDefaultValues[i]; + String[] propertyValueChoiceSet = discretePropertyValueChoices[i]; i++; propertyNames.add(propName); propertyDescriptions.add(propertyDescription); propertyValues.put(propName, defaultPropertyValue); + propertyValueChoices.add(propertyValueChoiceSet); System.out.println("Adding property name " + propName); } } else { @@ -1674,6 +1755,7 @@ public abstract class AutoAnalyser extends JFrame for (String fieldName : commonContPropertiesFieldNames) { String propName = commonContPropertyNames[i]; String propertyDescription = commonContPropertyDescriptions[i]; + String[] propertyValueChoiceSet = commonContPropertyValueChoices[i]; i++; System.out.println("Adding property name " + abstractContinuousClass.getSimpleName() + "." + fieldName + @@ -1681,6 +1763,7 @@ public abstract class AutoAnalyser extends JFrame propertyFieldNames.add(abstractContinuousClass.getSimpleName() + "." + fieldName); propertyNames.add(propName); propertyDescriptions.add(propertyDescription); + propertyValueChoices.add(propertyValueChoiceSet); } // Then for the specific estimator types @@ -1688,9 +1771,11 @@ public abstract class AutoAnalyser extends JFrame for (String fieldName : classSpecificPropertiesFieldNames) { String propName = classSpecificPropertyNames[i]; String propertyDescription = classSpecificPropertyDescriptions[i]; + String[] propertyValueChoiceSet = classSpecificPropertyValueChoices[i]; i++; propertyNames.add(propName); propertyDescriptions.add(propertyDescription); + propertyValueChoices.add(propertyValueChoiceSet); if (fieldName.contains(".")) { System.out.println("Adding property name " + fieldName + " = \"" + propName + "\""); @@ -1736,6 +1821,7 @@ public abstract class AutoAnalyser extends JFrame String[] classSpecificPropertyNames; String[] classSpecificPropertiesFieldNames; String[] classSpecificPropertyDescriptions; + String[][] classSpecificPropertyValueChoices; } /** @@ -1758,6 +1844,7 @@ public abstract class AutoAnalyser extends JFrame calcProperties.classSpecificPropertyNames = discreteProperties; calcProperties.classSpecificPropertiesFieldNames = null; // Not used calcProperties.classSpecificPropertyDescriptions = discretePropertyDescriptions; + calcProperties.classSpecificPropertyValueChoices = discretePropertyValueChoices; // TODO Later can add binning method to the properties for // binned calculator here. return calcProperties; diff --git a/java/source/infodynamics/demos/autoanalysis/AutoAnalyserAIS.java b/java/source/infodynamics/demos/autoanalysis/AutoAnalyserAIS.java index b21521d..cd0dc09 100644 --- a/java/source/infodynamics/demos/autoanalysis/AutoAnalyserAIS.java +++ b/java/source/infodynamics/demos/autoanalysis/AutoAnalyserAIS.java @@ -55,12 +55,15 @@ public class AutoAnalyserAIS extends AutoAnalyser { protected String[] gaussianProperties; protected String[] gaussianPropertiesFieldNames; protected String[] gaussianPropertyDescriptions; + protected String[][] gaussianPropertyValueChoices; protected String[] kernelProperties; protected String[] kernelPropertiesFieldNames; protected String[] kernelPropertyDescriptions; + protected String[][] kernelPropertyValueChoices; protected String[] kraskovProperties; protected String[] kraskovPropertiesFieldNames; protected String[] kraskovPropertyDescriptions; + protected String[][] kraskovPropertyValueChoices; public AutoAnalyserAIS() { super(); @@ -106,6 +109,10 @@ public class AutoAnalyserAIS extends AutoAnalyser { "Number of discrete states available for each variable (i.e. 2 for binary)", "History embedding length (k_HISTORY)" }; + discretePropertyValueChoices = new String[][] { + null, + null + }; // Continuous: abstractContinuousClass = ActiveInfoStorageCalculator.class; @@ -122,6 +129,10 @@ public class AutoAnalyserAIS extends AutoAnalyser { "History embedding length (k_HISTORY)", "History embedding delay (k_TAU)" }; + commonContPropertyValueChoices = new String[][] { + null, + null + }; // Gaussian properties: gaussianProperties = new String[] { }; @@ -129,6 +140,8 @@ public class AutoAnalyserAIS extends AutoAnalyser { }; gaussianPropertyDescriptions = new String[] { }; + gaussianPropertyValueChoices = new String[][] { + }; // Kernel: kernelProperties = new String[] { MutualInfoCalculatorMultiVariateKernel.KERNEL_WIDTH_PROP_NAME, @@ -147,7 +160,12 @@ public class AutoAnalyserAIS extends AutoAnalyser { "otherwise it is an absolute value.", "Dynamic correlation exclusion time or
Theiler window (see Kantz and Schreiber); " + "0 (default) means no dynamic exclusion window", - "(boolean) whether to normalise
each incoming time-series to mean 0, standard deviation 1, or not (recommended)", + "(boolean) whether to normalise
each incoming time-series to mean 0, standard deviation 1, or not (default true, recommended)", + }; + kernelPropertyValueChoices = new String[][] { + null, + null, + {"true", "false"} }; // KSG (Kraskov): kraskovProperties = new String[] { @@ -201,6 +219,20 @@ public class AutoAnalyserAIS extends AutoAnalyser { "Max. embedding delay to search to
if auto embedding (as determined by " + ActiveInfoStorageCalculatorKraskov.PROP_AUTO_EMBED_METHOD + ")", "Number of k nearest neighbours for
Ragwitz auto embedding (if used; defaults to match property \"k\")" }; + kraskovPropertyValueChoices = new String[][] { + {"true", "false"}, + null, + null, + null, + {"MAX_NORM", "EUCLIDEAN", "EUCLIDEAN_SQUARED"}, + null, + {"true", "false"}, + {ActiveInfoStorageCalculatorKraskov.AUTO_EMBED_METHOD_NONE, ActiveInfoStorageCalculatorKraskov.AUTO_EMBED_METHOD_RAGWITZ, + ActiveInfoStorageCalculatorKraskov.AUTO_EMBED_METHOD_MAX_CORR_AIS}, + null, + null, + null, + }; } @Override @@ -307,14 +339,17 @@ public class AutoAnalyserAIS extends AutoAnalyser { calcProperties.classSpecificPropertyNames = gaussianProperties; calcProperties.classSpecificPropertiesFieldNames = gaussianPropertiesFieldNames; calcProperties.classSpecificPropertyDescriptions = gaussianPropertyDescriptions; + calcProperties.classSpecificPropertyValueChoices = gaussianPropertyValueChoices; } else if (selectedCalcType.equalsIgnoreCase(CALC_TYPE_KRASKOV)) { calcProperties.classSpecificPropertyNames = kraskovProperties; calcProperties.classSpecificPropertiesFieldNames = kraskovPropertiesFieldNames; calcProperties.classSpecificPropertyDescriptions = kraskovPropertyDescriptions; + calcProperties.classSpecificPropertyValueChoices = kraskovPropertyValueChoices; } else if (selectedCalcType.equalsIgnoreCase(CALC_TYPE_KERNEL)) { calcProperties.classSpecificPropertyNames = kernelProperties; calcProperties.classSpecificPropertiesFieldNames = kernelPropertiesFieldNames; calcProperties.classSpecificPropertyDescriptions = kernelPropertyDescriptions; + calcProperties.classSpecificPropertyValueChoices = kernelPropertyValueChoices; } else { calcProperties = null; throw new Exception("No recognised calculator selected: " + diff --git a/java/source/infodynamics/demos/autoanalysis/AutoAnalyserCMI.java b/java/source/infodynamics/demos/autoanalysis/AutoAnalyserCMI.java index 56c7515..542328a 100644 --- a/java/source/infodynamics/demos/autoanalysis/AutoAnalyserCMI.java +++ b/java/source/infodynamics/demos/autoanalysis/AutoAnalyserCMI.java @@ -56,9 +56,11 @@ public class AutoAnalyserCMI extends AutoAnalyser protected String[] gaussianProperties; protected String[] gaussianPropertiesFieldNames; protected String[] gaussianPropertyDescriptions; + protected String[][] gaussianPropertyValueChoices; protected String[] kraskovProperties; protected String[] kraskovPropertiesFieldNames; protected String[] kraskovPropertyDescriptions; + protected String[][] kraskovPropertyValueChoices; protected static final String CALC_TYPE_KRASKOV_ALG1 = CALC_TYPE_KRASKOV + " alg. 1"; protected static final String CALC_TYPE_KRASKOV_ALG2 = CALC_TYPE_KRASKOV + " alg. 2"; @@ -107,6 +109,9 @@ public class AutoAnalyserCMI extends AutoAnalyser "Number of discrete states available for each variable (i.e. 2 for binary).
" + "Can be set individually for each variable -- see code." }; + discretePropertyValueChoices = new String[][] { + null + }; // Continuous: abstractContinuousClass = ConditionalMutualInfoCalculatorMultiVariate.class; @@ -120,6 +125,9 @@ public class AutoAnalyserCMI extends AutoAnalyser commonContPropertyDescriptions = new String[] { // None }; + commonContPropertyValueChoices = new String[][] { + // None + }; // Gaussian properties: gaussianProperties = new String[] { }; @@ -127,6 +135,8 @@ public class AutoAnalyserCMI extends AutoAnalyser }; gaussianPropertyDescriptions = new String[] { }; + gaussianPropertyValueChoices = new String[][] { + }; // KSG (Kraskov): kraskovProperties = new String[] { ConditionalMutualInfoMultiVariateCommon.PROP_NORMALISE, @@ -160,7 +170,15 @@ public class AutoAnalyserCMI extends AutoAnalyser "(default, to indicate to use all available processors)", "Whether to enable the GPU module (number of threads then has no bearing); boolean, default false" }; - + kraskovPropertyValueChoices = new String[][] { + {"true", "false"}, + null, + null, + null, + {"MAX_NORM", "EUCLIDEAN", "EUCLIDEAN_SQUARED"}, + null, + {"true", "false"} + }; } @Override @@ -313,11 +331,13 @@ public class AutoAnalyserCMI extends AutoAnalyser calcProperties.classSpecificPropertyNames = gaussianProperties; calcProperties.classSpecificPropertiesFieldNames = gaussianPropertiesFieldNames; calcProperties.classSpecificPropertyDescriptions = gaussianPropertyDescriptions; + calcProperties.classSpecificPropertyValueChoices = gaussianPropertyValueChoices; } else if (selectedCalcType.startsWith(CALC_TYPE_KRASKOV)) { // The if statement will work for both MI Kraskov calculators calcProperties.classSpecificPropertyNames = kraskovProperties; calcProperties.classSpecificPropertiesFieldNames = kraskovPropertiesFieldNames; calcProperties.classSpecificPropertyDescriptions = kraskovPropertyDescriptions; + calcProperties.classSpecificPropertyValueChoices = kraskovPropertyValueChoices; } else { calcProperties = null; throw new Exception("No recognised calculator selected: " + diff --git a/java/source/infodynamics/demos/autoanalysis/AutoAnalyserCTE.java b/java/source/infodynamics/demos/autoanalysis/AutoAnalyserCTE.java index de6fc37..e12b51c 100644 --- a/java/source/infodynamics/demos/autoanalysis/AutoAnalyserCTE.java +++ b/java/source/infodynamics/demos/autoanalysis/AutoAnalyserCTE.java @@ -57,9 +57,11 @@ public class AutoAnalyserCTE extends AutoAnalyser protected String[] gaussianProperties; protected String[] gaussianPropertiesFieldNames; protected String[] gaussianPropertyDescriptions; + protected String[][] gaussianPropertyValueChoices; protected String[] kraskovProperties; protected String[] kraskovPropertiesFieldNames; protected String[] kraskovPropertyDescriptions; + protected String[][] kraskovPropertyValueChoices; public AutoAnalyserCTE() { super(); @@ -108,6 +110,10 @@ public class AutoAnalyserCTE extends AutoAnalyser "Can be set individually for each variable -- see code.", "Destination history embedding length (k_HISTORY)", }; + discretePropertyValueChoices = new String[][] { + null, + null + }; // Continuous: abstractContinuousClass = ConditionalTransferEntropyCalculator.class; @@ -142,6 +148,16 @@ public class AutoAnalyserCTE extends AutoAnalyser "Conditional history embeding delay", "Delay from conditional to destination (in time steps)" }; + commonContPropertyValueChoices = new String[][] { + null, + null, + null, + null, + null, + null, + null, + null + }; // Gaussian properties: gaussianProperties = new String[] { }; @@ -149,6 +165,8 @@ public class AutoAnalyserCTE extends AutoAnalyser }; gaussianPropertyDescriptions = new String[] { }; + gaussianPropertyValueChoices = new String[][] { + }; // KSG (Kraskov): kraskovProperties = new String[] { ConditionalMutualInfoMultiVariateCommon.PROP_NORMALISE, @@ -185,7 +203,16 @@ public class AutoAnalyserCTE extends AutoAnalyser "Whether to enable the GPU module (number of threads then has no bearing); boolean, default false", "Which KSG algorithm to use (1 or 2)", }; - + kraskovPropertyValueChoices = new String[][] { + {"true", "false"}, + null, + null, + null, + {"MAX_NORM", "EUCLIDEAN", "EUCLIDEAN_SQUARED"}, + null, + {"true", "false"}, + {"1", "2"} + }; } @Override @@ -338,11 +365,13 @@ public class AutoAnalyserCTE extends AutoAnalyser calcProperties.classSpecificPropertyNames = gaussianProperties; calcProperties.classSpecificPropertiesFieldNames = gaussianPropertiesFieldNames; calcProperties.classSpecificPropertyDescriptions = gaussianPropertyDescriptions; + calcProperties.classSpecificPropertyValueChoices = gaussianPropertyValueChoices; } else if (selectedCalcType.startsWith(CALC_TYPE_KRASKOV)) { // The if statement will work for both MI Kraskov calculators calcProperties.classSpecificPropertyNames = kraskovProperties; calcProperties.classSpecificPropertiesFieldNames = kraskovPropertiesFieldNames; calcProperties.classSpecificPropertyDescriptions = kraskovPropertyDescriptions; + calcProperties.classSpecificPropertyValueChoices = kraskovPropertyValueChoices; } else { calcProperties = null; throw new Exception("No recognised calculator selected: " + diff --git a/java/source/infodynamics/demos/autoanalysis/AutoAnalyserChannelCalculator.java b/java/source/infodynamics/demos/autoanalysis/AutoAnalyserChannelCalculator.java index 1398a5f..af03f1a 100644 --- a/java/source/infodynamics/demos/autoanalysis/AutoAnalyserChannelCalculator.java +++ b/java/source/infodynamics/demos/autoanalysis/AutoAnalyserChannelCalculator.java @@ -47,13 +47,16 @@ public abstract class AutoAnalyserChannelCalculator extends AutoAnalyser { protected String[] gaussianProperties; protected String[] gaussianPropertiesFieldNames; protected String[] gaussianPropertyDescriptions; + protected String[][] gaussianPropertyValueChoices; protected String[] kernelProperties; protected String[] kernelPropertiesFieldNames; protected String[] kernelPropertyDescriptions; + protected String[][] kernelPropertyValueChoices; protected String[] kraskovProperties; protected String[] kraskovPropertiesFieldNames; protected String[] kraskovPropertyDescriptions; - + protected String[][] kraskovPropertyValueChoices; + public AutoAnalyserChannelCalculator() { super(); @@ -207,15 +210,18 @@ public abstract class AutoAnalyserChannelCalculator extends AutoAnalyser { calcProperties.classSpecificPropertyNames = gaussianProperties; calcProperties.classSpecificPropertiesFieldNames = gaussianPropertiesFieldNames; calcProperties.classSpecificPropertyDescriptions = gaussianPropertyDescriptions; + calcProperties.classSpecificPropertyValueChoices = gaussianPropertyValueChoices; } else if (selectedCalcType.startsWith(CALC_TYPE_KRASKOV)) { // The if statement will work for both MI Kraskov calculators calcProperties.classSpecificPropertyNames = kraskovProperties; calcProperties.classSpecificPropertiesFieldNames = kraskovPropertiesFieldNames; calcProperties.classSpecificPropertyDescriptions = kraskovPropertyDescriptions; + calcProperties.classSpecificPropertyValueChoices = kraskovPropertyValueChoices; } else if (selectedCalcType.equalsIgnoreCase(CALC_TYPE_KERNEL)) { calcProperties.classSpecificPropertyNames = kernelProperties; calcProperties.classSpecificPropertiesFieldNames = kernelPropertiesFieldNames; calcProperties.classSpecificPropertyDescriptions = kernelPropertyDescriptions; + calcProperties.classSpecificPropertyValueChoices = kernelPropertyValueChoices; } else { calcProperties = null; throw new Exception("No recognised calculator selected: " + diff --git a/java/source/infodynamics/demos/autoanalysis/AutoAnalyserEntropy.java b/java/source/infodynamics/demos/autoanalysis/AutoAnalyserEntropy.java index b5e902a..34ad05f 100644 --- a/java/source/infodynamics/demos/autoanalysis/AutoAnalyserEntropy.java +++ b/java/source/infodynamics/demos/autoanalysis/AutoAnalyserEntropy.java @@ -52,12 +52,15 @@ public class AutoAnalyserEntropy extends AutoAnalyser { protected String[] gaussianProperties; protected String[] gaussianPropertiesFieldNames; protected String[] gaussianPropertyDescriptions; + protected String[][] gaussianPropertyValueChoices; protected String[] kernelProperties; protected String[] kernelPropertiesFieldNames; protected String[] kernelPropertyDescriptions; + protected String[][] kernelPropertyValueChoices; protected String[] klProperties; protected String[] klPropertiesFieldNames; protected String[] klPropertyDescriptions; + protected String[][] klPropertyValueChoices; public AutoAnalyserEntropy() { super(); @@ -100,6 +103,9 @@ public class AutoAnalyserEntropy extends AutoAnalyser { discretePropertyDescriptions = new String[] { "Number of discrete states available for each variable (i.e. 2 for binary)" }; + discretePropertyValueChoices = new String[][] { + null + }; // Continuous: abstractContinuousClass = EntropyCalculator.class; @@ -113,6 +119,9 @@ public class AutoAnalyserEntropy extends AutoAnalyser { commonContPropertyDescriptions = new String[] { // None }; + commonContPropertyValueChoices = new String[][] { + // None + }; // Gaussian properties: gaussianProperties = new String[] { }; @@ -120,6 +129,8 @@ public class AutoAnalyserEntropy extends AutoAnalyser { }; gaussianPropertyDescriptions = new String[] { }; + gaussianPropertyValueChoices = new String[][] { + }; // Kernel: kernelProperties = new String[] { EntropyCalculatorKernel.KERNEL_WIDTH_PROP_NAME, @@ -134,7 +145,11 @@ public class AutoAnalyserEntropy extends AutoAnalyser { EntropyCalculatorKernel.NORMALISE_PROP_NAME + " is set, then this is a number of standard deviations; " + "otherwise it is an absolute value.", - "(boolean) whether to normalise
the incoming time-series to mean 0, standard deviation 1, or not (recommended)", + "(boolean) whether to normalise
the incoming time-series to mean 0, standard deviation 1, or not (default true, recommended)", + }; + kernelPropertyValueChoices = new String[][] { + null, + {"true", "false"} }; // KSG (Kraskov): klProperties = new String[] { @@ -145,6 +160,8 @@ public class AutoAnalyserEntropy extends AutoAnalyser { }; klPropertyDescriptions = new String[] { }; + klPropertyValueChoices = new String[][] { + }; } @Override @@ -251,14 +268,17 @@ public class AutoAnalyserEntropy extends AutoAnalyser { calcProperties.classSpecificPropertyNames = gaussianProperties; calcProperties.classSpecificPropertiesFieldNames = gaussianPropertiesFieldNames; calcProperties.classSpecificPropertyDescriptions = gaussianPropertyDescriptions; + calcProperties.classSpecificPropertyValueChoices = gaussianPropertyValueChoices; } else if (selectedCalcType.equalsIgnoreCase(CALC_TYPE_KOZ_LEO)) { calcProperties.classSpecificPropertyNames = klProperties; calcProperties.classSpecificPropertiesFieldNames = klPropertiesFieldNames; calcProperties.classSpecificPropertyDescriptions = klPropertyDescriptions; + calcProperties.classSpecificPropertyValueChoices = klPropertyValueChoices; } else if (selectedCalcType.equalsIgnoreCase(CALC_TYPE_KERNEL)) { calcProperties.classSpecificPropertyNames = kernelProperties; calcProperties.classSpecificPropertiesFieldNames = kernelPropertiesFieldNames; calcProperties.classSpecificPropertyDescriptions = kernelPropertyDescriptions; + calcProperties.classSpecificPropertyValueChoices = kernelPropertyValueChoices; } else { calcProperties = null; throw new Exception("No recognised calculator selected: " + diff --git a/java/source/infodynamics/demos/autoanalysis/AutoAnalyserMI.java b/java/source/infodynamics/demos/autoanalysis/AutoAnalyserMI.java index 0d386e1..d95d423 100644 --- a/java/source/infodynamics/demos/autoanalysis/AutoAnalyserMI.java +++ b/java/source/infodynamics/demos/autoanalysis/AutoAnalyserMI.java @@ -92,6 +92,10 @@ public class AutoAnalyserMI extends AutoAnalyserChannelCalculator "Number of discrete states available for each variable (i.e. 2 for binary)", "Time-lag from source to dest to consider MI across; must be >= 0 (0 for standard MI)", }; + discretePropertyValueChoices = new String[][] { + null, + null + }; // Continuous: abstractContinuousClass = MutualInfoCalculatorMultiVariate.class; @@ -105,6 +109,9 @@ public class AutoAnalyserMI extends AutoAnalyserChannelCalculator commonContPropertyDescriptions = new String[] { "Time-lag from source to dest to consider MI across; must be >= 0 (0 for standard MI)" }; + commonContPropertyValueChoices = new String[][] { + null + }; // Gaussian properties: gaussianProperties = new String[] { }; @@ -112,6 +119,8 @@ public class AutoAnalyserMI extends AutoAnalyserChannelCalculator }; gaussianPropertyDescriptions = new String[] { }; + gaussianPropertyValueChoices = new String[][] { + }; // Kernel: kernelProperties = new String[] { MutualInfoCalculatorMultiVariateKernel.KERNEL_WIDTH_PROP_NAME, @@ -132,6 +141,11 @@ public class AutoAnalyserMI extends AutoAnalyserChannelCalculator "0 (default) means no dynamic exclusion window", "(boolean) whether to normalise
each incoming time-series to mean 0, standard deviation 1, or not (recommended)", }; + kernelPropertyValueChoices = new String[][] { + null, + null, + {"true", "false"} + }; // KSG (Kraskov): kraskovProperties = new String[] { MutualInfoCalculatorMultiVariateKraskov.PROP_NORMALISE, @@ -165,7 +179,15 @@ public class AutoAnalyserMI extends AutoAnalyserChannelCalculator "(default, to indicate to use all available processors)", "Whether to enable the GPU module (number of threads then has no bearing); boolean, default false" }; - + kraskovPropertyValueChoices = new String[][] { + {"true", "false"}, + null, + null, + null, + {"MAX_NORM", "EUCLIDEAN", "EUCLIDEAN_SQUARED"}, + null, + {"true", "false"}, + }; } /** diff --git a/java/source/infodynamics/demos/autoanalysis/AutoAnalyserTE.java b/java/source/infodynamics/demos/autoanalysis/AutoAnalyserTE.java index e9f06b3..bd12e8e 100644 --- a/java/source/infodynamics/demos/autoanalysis/AutoAnalyserTE.java +++ b/java/source/infodynamics/demos/autoanalysis/AutoAnalyserTE.java @@ -104,7 +104,15 @@ public class AutoAnalyserTE extends AutoAnalyserChannelCalculator "Source history embeding delay (l_TAU)", "Delay from source to destination (in time steps)", }; - + discretePropertyValueChoices = new String[][] { + null, + null, + null, + null, + null, + null + }; + // Continuous: abstractContinuousClass = TransferEntropyCalculator.class; // Common properties for all continuous calcs: @@ -117,6 +125,9 @@ public class AutoAnalyserTE extends AutoAnalyserChannelCalculator commonContPropertyDescriptions = new String[] { "Destination history embedding length (k_HISTORY)" }; + commonContPropertyValueChoices = new String[][] { + null + }; // Gaussian properties: gaussianProperties = new String[] { TransferEntropyCalculator.K_TAU_PROP_NAME, // Not common to Kernel @@ -136,6 +147,12 @@ public class AutoAnalyserTE extends AutoAnalyserChannelCalculator "Source history embeding delay (l_TAU)", "Delay from source to destination (in time steps)" }; + gaussianPropertyValueChoices = new String[][] { + null, + null, + null, + null, + }; // Kernel: kernelProperties = new String[] { TransferEntropyCalculatorKernel.KERNEL_WIDTH_PROP_NAME, @@ -154,7 +171,12 @@ public class AutoAnalyserTE extends AutoAnalyserChannelCalculator "otherwise it is an absolute value.", "Dynamic correlation exclusion time or
Theiler window (see Kantz and Schreiber); " + "0 (default) means no dynamic exclusion window", - "(boolean) whether to normalise
each incoming time-series to mean 0, standard deviation 1, or not (recommended)", + "(boolean) whether to normalise
each incoming time-series to mean 0, standard deviation 1, or not (default true, recommended)", + }; + kernelPropertyValueChoices = new String[][] { + null, + null, + {"true", "false"} }; // KSG (Kraskov): kraskovProperties = new String[] { @@ -198,7 +220,7 @@ public class AutoAnalyserTE extends AutoAnalyserChannelCalculator "Source history embedding length (l)", "Source history embeding delay (l_TAU)", "Delay from source to destination (in time steps)", - "(boolean) whether to normalise
each incoming time-series to mean 0, standard deviation 1, or not (recommended)", + "(boolean) whether to normalise
each incoming time-series to mean 0, standard deviation 1, or not (default true, recommended)", "Number of k nearest neighbours to use
in the full joint kernel space in the KSG algorithm", "Standard deviation for an amount
of random Gaussian noise to add to each variable, " + "to avoid having neighbourhoods with artificially large counts.
" + @@ -225,7 +247,28 @@ public class AutoAnalyserTE extends AutoAnalyserChannelCalculator "Max. embedding delay to search to
if auto embedding (as determined by " + TransferEntropyCalculatorKraskov.PROP_AUTO_EMBED_METHOD + ")", "Number of k nearest neighbours for
Ragwitz auto embedding (if used; defaults to match property \"k\")" }; - + kraskovPropertyValueChoices = new String[][] { + null, + null, + null, + null, + {"true", "false"}, + null, + null, + null, + {"MAX_NORM", "EUCLIDEAN", "EUCLIDEAN_SQUARED"}, + null, + {"true", "false"}, + {"1", "2"}, + {TransferEntropyCalculatorKraskov.AUTO_EMBED_METHOD_NONE, + TransferEntropyCalculatorKraskov.AUTO_EMBED_METHOD_RAGWITZ, + TransferEntropyCalculatorKraskov.AUTO_EMBED_METHOD_RAGWITZ_DEST_ONLY, + TransferEntropyCalculatorKraskov.AUTO_EMBED_METHOD_MAX_CORR_AIS, + TransferEntropyCalculatorKraskov.AUTO_EMBED_METHOD_MAX_CORR_AIS_DEST_ONLY}, + null, + null, + null, + }; } /**