Skip to content

Commit

Permalink
reuse the file logger in studio menu, and tidy up the class structure #…
Browse files Browse the repository at this point in the history
  • Loading branch information
walterxie committed Jul 18, 2023
1 parent ca2dfbd commit f40ea07
Show file tree
Hide file tree
Showing 15 changed files with 240 additions and 146 deletions.
47 changes: 25 additions & 22 deletions lphy-studio/src/main/java/lphystudio/app/LinguaPhyloStudio.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package lphystudio.app;

import lphy.core.io.UserDir;
import lphy.core.logger.LoggerUtils;
import lphy.core.logger.ValueFileLoggerListener;
import lphy.core.model.Value;
import lphy.core.parser.GraphicalLPhyParser;
import lphy.core.simulator.RandomUtils;
Expand Down Expand Up @@ -287,28 +287,31 @@ private void buildFileMenu(JMenu fileMenu) {
fileMenu.add(saveAlignmentAsMenuItem);
saveAlignmentAsMenuItem.addActionListener(e -> {
File selectedDir = Utils.getFileFromFileChooser(frame, null, JFileChooser.DIRECTORIES_ONLY, false);
// set alignment directory
if (selectedDir != null && selectedDir.isDirectory() && panel.getValuesAllRepsMap() != null) {

// TODO use ValueFileLoggerListener instead to write to a file
// TODO set dir to Preferences

Path dir = selectedDir.toPath();
UserDir.setAlignmentDir(dir.toString());
LoggerUtils.log.info("Alignments saved to: " + dir);
// save all sampled alignments
Map<Integer, List<Value>> valuesMap = panel.getValuesAllRepsMap();
AlignmentLog alignmentLogger = new AlignmentLog(parser);

alignmentLogger.setLogAlignment(true);
alignmentLogger.start(new ArrayList<>());
for (Map.Entry<Integer, List<Value>> entry : valuesMap.entrySet()) {
alignmentLogger.replicate(entry.getKey(), entry.getValue());
}
alignmentLogger.complete();

} else {
throw new IllegalArgumentException("Should select directory rather than file for saving alignments.");
if (selectedDir != null && selectedDir.isDirectory()) {

if (panel.getValuesAllRepsMap() != null) {
// retrieve all simulated alignments stored in the map
Map<Integer, List<Value>> valuesMap = panel.getValuesAllRepsMap();

ValueFileLoggerListener fileLoggerListener = new ValueFileLoggerListener();
// set alignment directory
fileLoggerListener.setOutputDir(selectedDir.getAbsolutePath());
LoggerUtils.log.info("Save the alignments to: " + selectedDir.getAbsolutePath());

// Key is the replicate index
fileLoggerListener.start(List.of(valuesMap.size(), parser.getName()));
for (Map.Entry<Integer, List<Value>> entry : valuesMap.entrySet()) {
List<Value> alignmentValuePerRep = AlignmentLog.getSimulatedAlignmentValues(entry.getValue(), parser);
//TODO could do this same to trees
fileLoggerListener.replicate(entry.getKey(), alignmentValuePerRep);
}
fileLoggerListener.complete();

} else {
JOptionPane.showMessageDialog(frame, "Cannot find the simulated alignments ! " +
"Please click Sample button, and try again. ");
}
}
});

Expand Down
3 changes: 3 additions & 0 deletions lphy-studio/src/main/java/lphystudio/app/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ public static File getFileFromFileChooser(Component parent, FileNameExtensionFil

jfc.setMultiSelectionEnabled(false);
jfc.setFileSelectionMode(fileSelectionMode);
if (JFileChooser.DIRECTORIES_ONLY == fileSelectionMode)
jfc.setDialogTitle("Select a directory");

if (filter != null) jfc.setFileFilter(filter);

int returnValue = openFile ? jfc.showOpenDialog(parent) : jfc.showSaveDialog(parent);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ private int getReps() {
return reps;
}

// Key is the replicate index, value is the result of each replicate.
Map<Integer, List<Value>> valuesAllRepsMap;

public Map<Integer, List<Value>> getValuesAllRepsMap() {
Expand Down
74 changes: 35 additions & 39 deletions lphy-studio/src/main/java/lphystudio/core/logger/AlignmentLog.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
package lphystudio.core.logger;

import lphy.base.evolution.alignment.SimpleAlignment;
import lphy.core.io.FileConfig;
import lphy.core.io.OutputSystem;
import lphy.core.logger.ValueFormatHandler;
import lphy.core.logger.ValueFormatResolver;
import lphy.core.logger.ValueFormatter;
import lphy.core.model.Value;
import lphy.core.parser.LPhyMetaParser;
import lphy.core.simulator.SimulatorListener;
import lphy.core.spi.LoaderManager;

import javax.swing.*;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

/**
Expand All @@ -27,6 +24,8 @@ public class AlignmentLog extends JTextArea implements SimulatorListener {
final LPhyMetaParser parser;

// final Preferences preferences = Preferences.userNodeForPackage(AlignmentLog.class);
// static final String ALIGNMENT_DIR = "alignment_dir";

static final String STUDIO_LOG_ALIGNMENT = "studio_log_alignment";

boolean logAlignment = false;
Expand Down Expand Up @@ -55,14 +54,6 @@ public boolean toLogAlignment() {
// return preferences.getBoolean(STUDIO_LOG_ALIGNMENT, false);
}

public void setOutputDir(String dir) {
OutputSystem.setOutputDirectory(dir);
}

public String getOutputDir() {
return OutputSystem.getOutputDirectory().getAbsolutePath();
}


@Override
public void start(List<Object> configs) {
Expand All @@ -75,7 +66,7 @@ public void start(List<Object> configs) {
public void replicate(int index, List<Value> values) {
// can be SimpleAlignment or SimpleAlignment[]
// exclude clamped alignment
List<Value> alignmentValuePerRep = getSimulatedAlignmentValues(values);
List<Value> alignmentValuePerRep = getSimulatedAlignmentValues(values, parser);

if (index == 0) {
// allAlgValues.clear();
Expand All @@ -101,9 +92,9 @@ public void replicate(int index, List<Value> values) {
for (ValueFormatter valueFormatter : valueFormatterList) {
append("\t" + valueFormatter.format(alV.value()));

if (toLogAlignment()) {
writeAlignment(index, alV);
}
// if (toLogAlignment()) {
// writeAlignment(index, alV);
// }
}
}
append("\n");
Expand All @@ -118,7 +109,7 @@ public void complete() {
}

// can be SimpleAlignment or SimpleAlignment[]
private List<Value> getSimulatedAlignmentValues(List<Value> variables) {
public static List<Value> getSimulatedAlignmentValues(List<Value> variables, final LPhyMetaParser parser) {
List<Value> values = new ArrayList<>();
for (Value<?> v : variables) {
if (v.value() instanceof SimpleAlignment || v.value() instanceof SimpleAlignment[]) {
Expand All @@ -127,35 +118,40 @@ private List<Value> getSimulatedAlignmentValues(List<Value> variables) {
values.add(v);
}
}
values.sort(Comparator.comparing(Value::getId));
return values;
}

private void writeAlignment(int index, Value<SimpleAlignment> alignmentValue) {

ValueFormatter formatter = LoaderManager.valueFormatResolver.getDefaultFormatter(alignmentValue);

if (formatter != null) {

String filePrefix = parser.getName();
String fileExtension = formatter.getExtension();
// If value is array, the id will be appended with index
String id = formatter.getValueID();

// e.g. 1 alignment per file
// if maxId > 0, add postfix, e.g. _0.nexus
String fileName = FileConfig
.getOutFileName(id, index, numReplicates, filePrefix, fileExtension);
// private void writeAlignment(int index, Value<SimpleAlignment> alignmentValue) {
//
// ValueFormatter formatter = LoaderManager.valueFormatResolver.getDefaultFormatter(alignmentValue);
//
// if (formatter != null) {
//
// String filePrefix = parser.getName();
// String fileExtension = formatter.getExtension();
// // If value is array, the id will be appended with index
// String id = formatter.getValueID();
//
// // e.g. 1 alignment per file
// // if maxId > 0, add postfix, e.g. _0.nexus
// String fileName = FileConfig
// .getOutFileName(id, index, numReplicates, filePrefix, fileExtension);
//
// ValueFormatHandler.createFile(fileName);
//
// ValueFormatHandler.ValuePerFile
// .exportValuePerFile(index, alignmentValue, formatter);
//
// } else
// JOptionPane.showMessageDialog(this,
// "Cannot find the default formatter to write alignment " + alignmentValue.getId() + " !");
//
// }

ValueFormatHandler.createFile(fileName);

ValueFormatHandler.ValuePerFile
.exportValuePerFile(index, alignmentValue, formatter);

} else
JOptionPane.showMessageDialog(this,
"Cannot find the default formatter to write alignment " + alignmentValue.getId() + " !");

}
// private void logAlignment(Value<SimpleAlignment> alignment, int rep) {
// Path dir = UserDir.getAlignmentDir();
// String fileName = alignment.getCanonicalId() + "_" + rep + ".nexus";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,6 @@ public Class<SimpleAlignment> getDataTypeClass() {
return SimpleAlignment.class;
}

@Override
public String header() {
return getValueID();
// return isClamped ? getValueID() + "-clamped" : getValueID();
}

@Override
public String getValueID() {
return valueID;
Expand All @@ -53,5 +47,4 @@ public String format(SimpleAlignment simpleAlignment) {
}



}
37 changes: 25 additions & 12 deletions lphy-studio/src/main/java/lphystudio/core/logger/TreeLog.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package lphystudio.core.logger;

import lphy.base.evolution.tree.TimeTree;
import lphy.core.logger.ValueFormatResolver;
import lphy.core.logger.ValueFormatter;
import lphy.core.model.Value;
import lphy.core.simulator.SimulatorListener;

Expand All @@ -14,6 +16,7 @@
*/
public class TreeLog extends JTextArea implements SimulatorListener {

int numReplicates = 1000;

public TreeLog() { }

Expand All @@ -25,24 +28,33 @@ public void clear() {

@Override
public void start(List<Object> configs) {

if (configs.size() > 0 && configs.get(0) instanceof Integer numReplicates)
this.numReplicates = numReplicates;
}

@Override
public void replicate(int index, List<Value> values) {
List<Value<TimeTree>> treeVariables = getTreeValues(values);
List<Value> treeValuePerRep = getTreeValues(values);

if (index == 0) {
setText("sample");
for (Value<TimeTree> tv : treeVariables) {
append("\t" + tv.getId());
for (Value treV : treeValuePerRep) {
List<ValueFormatter> valueFormatterList = ValueFormatResolver
.createFormatter(TreeTextFormatter.class, treV);
for (ValueFormatter valueFormatter : valueFormatterList) {
append("\t" + valueFormatter.header());
}
}
append("\n");
}

append(index+"");
for (Value<TimeTree> v : treeVariables) {
append("\t" + v.value().toNewick(false));
for (Value treV : treeValuePerRep) {
List<ValueFormatter> valueFormatterList = ValueFormatResolver
.createFormatter(TreeTextFormatter.class, treV);
for (ValueFormatter valueFormatter : valueFormatterList) {
append("\t" + valueFormatter.format(treV.value()));
}
}
append("\n");
}
Expand All @@ -52,15 +64,16 @@ public void complete() {

}

private List<Value<TimeTree>> getTreeValues(List<Value> variables) {
List<Value<TimeTree>> trees = new ArrayList<>();
// can be TimeTree or SimpleATimeTreelignment[]
private List<Value> getTreeValues(List<Value> variables) {
List<Value> values = new ArrayList<>();
for (Value v : variables) {
if (v.value() instanceof TimeTree) {
trees.add((Value<TimeTree>)v);
if (v.value() instanceof TimeTree || v.value() instanceof TimeTree[]) {
values.add(v);
}
}
trees.sort(Comparator.comparing(Value::getId));
return trees;
values.sort(Comparator.comparing(Value::getId));
return values;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package lphystudio.core.logger;

import lphy.base.evolution.tree.TimeTree;
import lphy.core.logger.ValueFormatter;
import lphy.core.model.Symbols;

public class TreeTextFormatter implements ValueFormatter<TimeTree> {

String valueID;
TimeTree tree;

// public NexusTreeFormatter() {
// }

public TreeTextFormatter(String valueID, TimeTree tree) {
this.valueID = Symbols.getCanonical(valueID);
this.tree = tree;
}

@Override
public String getExtension() {
return ".txt";
}

@Override
public Mode getMode() {
return Mode.VALUE_PER_LINE;
}

@Override
public Class<TimeTree> getDataTypeClass() {
return TimeTree.class;
}

@Override
public String getValueID() {
return valueID;
}

@Override
public String format(TimeTree tree) {
return tree.toNewick(false);
}

}
22 changes: 20 additions & 2 deletions lphy/src/main/java/lphy/core/io/FileConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,33 @@ public class FileConfig {

public final Long seed; // if null, then random

/**
* Complex version to keep the input lphy script file.
* @param numReplicates
* @param lphyInputFile
* @param seed
* @throws IOException
*/
public FileConfig(int numReplicates, File lphyInputFile, Long seed) throws IOException {
this.lphyInputFile = lphyInputFile;
this.numReplicates = numReplicates;
this.seed = seed;
this.filePrefix = getLPhyFilePrefix(lphyInputFile);
}

public FileConfig(int numReplicates, File lphyInputFile) throws IOException {
this(numReplicates, lphyInputFile, null);
/**
* Simple version, not retaining the input file
* @param numReplicates
* @param filePrefix
* @throws IOException
*/
public FileConfig(int numReplicates, String filePrefix) {
this.lphyInputFile = null;
this.numReplicates = numReplicates;
this.seed = null;
if (filePrefix.endsWith(LPHY_EXTETION))
filePrefix = filePrefix.substring(0, filePrefix.indexOf(LPHY_EXTETION));
this.filePrefix = filePrefix;
}


Expand Down
Loading

0 comments on commit f40ea07

Please sign in to comment.