package statalign.postprocess;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.List;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JPanel;
import java.awt.Color;
import org.apache.commons.math3.util.Pair;
import statalign.base.InputData;
import statalign.base.Mcmc;
import statalign.base.McmcStep;
import statalign.base.State;
import statalign.mcmc.McmcModule;
import statalign.model.ext.ModelExtManager;
import statalign.model.ext.ModelExtension;
/**
* Common ancestor for post-processing plugin classes.
*
* Comments for plugin developers:
* <ul><li> Implement the abstract class. You can use the boolean variables
* to tell the main program what your plugin is supposed to do.
* <li> Via the mcmc variable, you can reach the tree and eventually all
* its public variables, so you can collect information about the current state
* of the Markov chain
* <li> If you would like to make a GUI for this postprocess plugin, return with its
* JPanel in the getJPanel() function
* <li> The implemented subclass must handle the information gathered and needed
* for the postprocessing. Neither the Mcmc class, nor the PostprocessManager class
* collects information about the state of the Markov chain!
* </ul>
*
*/
public abstract class Postprocess {
/** TODO: REMOVE!!!!!!!!!! */
public Mcmc mcmc;
PostprocessManager postprocessManager;
/**
* True, if the plugin implements the {@link Postprocess#getToolBarItems()} function.
* Defaults to false.
*/
public boolean hasToolBar = false;
/**
* True if plugin is selected in the menu (and thus a tab is created for the plugin in
* the main window that can be used to allow the user to change settings before MCMC
* start and to show runtime information afterwards)
*/
public boolean selected = true;
/**
* True if it <u>can</u> generate a GUI. Not used in the current version, it is
* for further development if one wants to switch on and off the GUIs.
*/
public boolean screenable = false;
/**
* True if a GUI must be shown to the user.
*/
public boolean show = true;
/**
* True if plugin is active (must produce its output) either because other plugins depend
* on it or because it is selected
*/
public boolean active = false;
/**
* True if this class <u>can</u> generate an output
*/
public boolean outputable = false;
/**
* True if this class <u>can</u> generate a postprocess file
*/
public boolean postprocessable = false;
/**
* True if it writes into the log file
*/
public boolean sampling;
/**
* True if it writes a postprocess file
*/
public boolean postprocessWrite;
/**
* True if it should show only when running an RNA/DNA file
*/
public boolean rnaAssociated;
protected ArrayList<Track> tracks = new ArrayList<Track>();
/** The extra tracks to be plotted */
public ArrayList<Track> getTracks() { return tracks; }
/**
* NB because the track is added as a Pair, it will be passed by reference,
* which allows it to be modified from the place where it was added, i.e.
* the desired behaviour.
* @param track
*/
public void addTrack(Track track) { tracks.add(track); }
/**
* This string tells the alignment type in which alignment must be presented
*/
public String alignmentType;
/**
* This is the logfile writer that is written during the running and gets information from
* all postprocesses.
*/
public FileWriter file;
/**
* This is the output file writer, that is written by a specific postprocess.
*/
public FileWriter outputFile;
/**
* Optional array for additional output files.
*/
public ArrayList<FileWriter> additionalOutputFiles;
/**
* Called by {@link PostprocessManager} after setting the {@link #show} field to allow initialisation,
* possibly involving GUI (toolbar etc.)
*/
// public void init() {
// }
public void init(ModelExtManager modelExtMan) {
}
/**
*
* @return Returns with the name that will appear on the label of the tabulated panel.
*/
public abstract String getTabName();
/**
*
* @return Returns with the icon that will appear on the label of the tabulated panel.
*/
public abstract Icon getIcon();
/**
*
* @return Returns with the panel of the GUI
*/
public abstract JPanel getJPanel();
//public abstract Component getComponent();
/**
* Reinitializes panel to accommodate a new GUI
*/
public void reloadPanel() {
}
/**
* Returns with the tip information (shown when the mouse cursor is moved over the
* label of the tabulated panel)
*/
public abstract String getTip();
/**
* Specifies the order of the tab for this plugin in the GUI.
* <p>
* E.g. we probably always want the "sequence input"-tab to appear first and
* therefore it returns a 1.0d here. The "current alignment"-tab returns 2.0d here
* and so if we want to make a tab get ordered between the "sequence input" and the
* "current alignment"-tabs we just make that plugin return 1.5d or something similar
* here. By default tabs get ordered last.
* @return the tab order of the tab associated with this plugin, if running in a GUI.
*/
public double getTabOrder() {
return Double.MAX_VALUE;
}
/**
* Returns default file extension that is to appended to the input
* file name to get the file this plugin is writing into.
*/
public String getFileExtension() {
return null;
}
/**
* Returns addotopma; file extensions to appendeto the input
* file name to get the additional filenames this plugin is writing to.
*/
public ArrayList<String> getAdditionalFileExtensions() {
return null;
}
/**
* Override this and return an array of full-qualified class names of the plugins
* this plugin depends on.
*/
public String[] getDependencies() {
return null;
}
/**
* Override this to get access to instances of the plugins your plugin depends on.
*
* This function will be called by the PostprocessManager during its initialisation.
*
* @param plugins reference to Postprocess objects in the order they are specified
* in getDependences() or null if it returns null
*/
public void refToDependencies(Postprocess[] plugins) {
}
/**
* Called before MCMC start. This is the first time you can use PostprocessManager.mcmc
* to access internal data structure
*/
public void beforeFirstSample(InputData inputData) {
}
/**
* Called after a new step is made. A typical run of MCMC takes hundred thousands of
* steps, override this function only if it takes a negligible amount of time and does not
* use too much memory. We use, for example, in drawing the loglikelihood trace.
*/
public void newStep(McmcStep mcmcStep) {
}
/**
* Allows peeking into the Markov chain before actual sampling begins. Frequency is
* determined by the MCMC sampling parameter set by the user, just like for
* {@link #newSample(State, int, int)}. Unlike that method, this one is called both
* during and after the burn-in period.
*
* @param state A {@link State} object representing the current state of the chain
*/
public void newPeek(State state) {
}
/**
*
* This function is called when we sample from the Markov chain. Frequency is determined
* by the MCMC sampling parameter set by the user. Unlike {@link #newPeek(State state)},
* this method is only called after the burn-in period.
*
* @param state A {@link State} object representing the current state of the chain
* @param no The number of the current sample
* @param total The number of the total samples
*/
public void newSample(State state, int no, int total) {
}
public void newSample(McmcModule coreModel, State state, int no, int total) {
newSample(state,no,total);
}
/**
* This function switches on or off the sampling mode.
* @param enabled Set it true if you need samples.
*/
public abstract void setSampling(boolean enabled);
/**
* This function is called after the MCMC runs.
*/
public void afterLastSample() {
}
/**
* Returns the toolbar that this plugin uses.
*/
public ArrayList<JComponent> getToolBarItems() {
return null;
}
public List<ModelExtension> getModExtPlugins() {
return mcmc.modelExtMan.getPluginList();
}
public void setSelected(boolean selected) {
this.selected = selected;
postprocessManager.updateSelectedList();
}
protected String getBaseFileName() {
return postprocessManager.getBaseFileName();
}
public boolean createsMultipleOutputFiles() {
return false;
}
}