package statalign.postprocess; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import statalign.base.MainManager; import statalign.base.Mcmc; import statalign.base.McmcStep; import statalign.base.State; import statalign.base.Utils; import statalign.mcmc.McmcModule; import statalign.model.ext.ModelExtManager; import statalign.ui.ErrorMessage; /** * This class manages the postprocesses. * * @author miklos, novak * */ public class PostprocessManager { /** * The recognized plugins are in this array */ private List<Postprocess> plugins; /** * This is the Mcmc that is analyzed */ public Mcmc mcmc; /** * This is the log-file writer */ public FileWriter logFile = null; /** * This is the Main manager that manages the MCMC run. */ public MainManager mainManager; /** * */ public static boolean rnaMode = false; /** * Static object holding parameters, which are visible to all plugins. */ public static PluginParameters pluginParameters = new PluginParameters(); /** The base filename where output is to be sent. Each plugin appends a suffix to this. */ private String baseFileName; public String getBaseFileName() { return baseFileName; } public void setBaseFileName(String s) { baseFileName = s; } /** * This constructor recognizes the plugins * @param mainManager The MainManager that manages the MCMC run. */ public PostprocessManager(MainManager mainManager) { this.mainManager = mainManager; List<String> pluginNames = Utils.classesInPackage(Postprocess.class.getPackage().getName()+".plugins"); HashMap<String,Integer> nameMap = new HashMap<String,Integer>(); HashMap<Postprocess,Boolean> selectedMap = new HashMap<Postprocess, Boolean>(); plugins = new ArrayList<Postprocess>(pluginNames.size()); for(int i = 0; i < pluginNames.size(); i++) plugins.add(null); for(int i = 0; i < pluginNames.size(); i++) { nameMap.put(pluginNames.get(i), i); try { Class<?> cl = Class.forName(pluginNames.get(i)); if(!Postprocess.class.isAssignableFrom(cl)) continue; Postprocess plugin = (Postprocess)cl.newInstance(); selectedMap.put(plugin, plugin.selected); plugin.selected = plugin.active = true; plugins.set(i, plugin); } catch (Exception e) { e.printStackTrace(); } } ArrayList<Postprocess> workingPlugins = new ArrayList<Postprocess>(); for(Postprocess plugin : plugins) dependProb(plugin, nameMap, workingPlugins); plugins = workingPlugins; boolean show = mainManager.frame != null; for(Postprocess plugin : plugins){ plugin.selected = selectedMap.get(plugin); if(plugin.screenable) { plugin.show = show; } // plugin.init(); } } public List<Postprocess> getPlugins() { return Collections.unmodifiableList(plugins); } public void createPluginFiles() { try{ for (Postprocess p : plugins) { if (p.postprocessWrite) { String name = baseFileName + p.getFileExtension(); System.out.println("Output file for " + p.getTabName() + ": " + name); p.outputFile = new FileWriter(name); if (p.createsMultipleOutputFiles()) { for (String extension : p.getAdditionalFileExtensions()) { name = baseFileName + extension; } System.out.println("Additional output file for " + p.getTabName() + ": " + name); p.additionalOutputFiles = new ArrayList<FileWriter>(); p.additionalOutputFiles.add(new FileWriter(name)); } } } } catch (IOException e) { e.printStackTrace(); } } /** * Finds dependency problems. Adds working plugins in dependency order to workingPlugins. */ private boolean dependProb(Postprocess plugin, HashMap<String,Integer> nameMap, ArrayList<Postprocess> workingPlugins) { if(plugin == null) return true; if(!plugin.selected) return plugin.active; plugin.selected = false; String[] deps = plugin.getDependencies(); Postprocess[] refs = null; if(deps != null) { refs = new Postprocess[deps.length]; for(int i = 0; i < deps.length; i++) { Integer ind = nameMap.get(deps[i]); if(ind == null || dependProb(plugins.get(ind), nameMap, workingPlugins)) return true; refs[i] = plugins.get(ind); } } plugin.refToDependencies(refs); plugin.active = false; workingPlugins.add(plugin); return false; } public void init(ModelExtManager modelExtMan) { for(Postprocess plugin : plugins){ plugin.postprocessManager = this; plugin.init(modelExtMan); } } /** * This function invoked before the first sample. * It opens information chanels towards postrocessing plug-ins. */ public void beforeFirstSample() { if(rnaMode) { for(Postprocess plugin : plugins){ plugin.mcmc = mcmc; plugin.file = logFile; plugin.alignmentType = MainManager.alignmentTypes[mainManager.inputData.currentAlignmentType]; plugin.beforeFirstSample(mainManager.inputData); } } else { for(Postprocess plugin : plugins) { if(!plugin.rnaAssociated) { plugin.mcmc = mcmc; plugin.file = logFile; plugin.alignmentType = MainManager.alignmentTypes[mainManager.inputData.currentAlignmentType]; plugin.beforeFirstSample(mainManager.inputData); } } } } /** * Calls the plug-ins at a new sample. * @param no The number of the current sample * @param total The total number of samples. */ public void newSample(McmcModule coreModel, State state, int no, int total) { if(rnaMode) { for(Postprocess plugin : plugins) { plugin.newSample(coreModel,state, no, total); } } else { for(Postprocess plugin : plugins) { if(!plugin.rnaAssociated) { plugin.newSample(coreModel,state, no, total); } } } } /** * Calls the plug-ins after an MCMC step. */ public void newStep(McmcStep step) { if(rnaMode) { for(Postprocess plugin : plugins){ //if(plugin.selected){ plugin.newStep(step); //} } } else { for(Postprocess plugin : plugins){ if(!plugin.rnaAssociated){ plugin.newStep(step); } } } } public void flushAll() { if(rnaMode) { for(Postprocess plugin : plugins){ if(plugin.selected && plugin.postprocessWrite){ try { plugin.outputFile.flush(); } catch (IOException ioex) { ioex.printStackTrace(); } } } } else { for(Postprocess plugin : plugins){ if(plugin.selected && plugin.postprocessWrite && !plugin.rnaAssociated){ try { plugin.outputFile.flush(); } catch (IOException ioex) { ioex.printStackTrace(); } } } } } /** * Calls the plug-ins after an MCMC step. */ public void newPeek() { State state = mcmc.getState(); if(rnaMode) { for(Postprocess plugin : plugins){ //if(plugin.selected){ plugin.newPeek(state); //} } } else { for(Postprocess plugin : plugins){ if(!plugin.rnaAssociated){ plugin.newPeek(state); } } } } /** * It is called after the last sample of MCMC. * It calls plug-ins to finalize their postprocessing activities. */ public void afterLastSample() { if(rnaMode) { for(Postprocess plugin : plugins) { plugin.afterLastSample(); } } else { for(Postprocess plugin : plugins) { if(!plugin.rnaAssociated) { plugin.afterLastSample(); } } } try { logFile.close(); } catch (IOException e) { new ErrorMessage(mainManager.frame, " "+e.getLocalizedMessage(), true); } } public void updateSelectedList() { if(mainManager.frame != null) mainManager.frame.updateTabs(); } }