/*---------------------------- Ingeneue source code ?Copyright 2000 by George von Dassow, Eli Meir, Edwin Munro, and Garrett Odell. Permission is granted for use by private individuals and by individuals and groups at all non-profit institutions, as long as those using the software or examining the code do not intend to make a profit from its use, and subject to all other conditions given on the website www.ingenenue.org. www.ingeneue.org contact@ingeneue.org ----------------------------*/ /** The top level class for Ingeneue. Contains main(). Deals with top level actions, such as opening network and iterator files, starting runs, and so on. Does not do any user interface stuff (it doesn't know whether inputs come from command line or from menus). */ package main; import java.awt.event.*; import java.io.*; import iterators.ModelIterator; import iterators.Function; import stoppers.SimpleStop; import mygraphs.CamGraph; import stat.Stat; import parameters.ParameterSetArray; import parameters.ParameterSet; import affectors.Affector; import genegui.*; import main.event.NetworkEvent; import main.event.NetworkEventListener; /** GeneNet.java The MainClass. */ public class GeneNet extends Object implements GuiInterface, Runnable { private static final int NOTHING_RUNNING = 0; private static final int MODEL_RUNNING = 1; private static final int ITERATOR_RUNNING = 2; private static final int SEARCHER_RUNNING = 3; /** The iterator if any for this model */ public ModelIterator ItsIterator = null; /** */ private long RunTime=0; /** */ public static GeneNet TheGeneNet; /** The main Graphical User Interface */ public static MainGui TheMainGui; /** */ public static Model TheModel = null; /** */ public Model model = null; /** */ private SimpleStop itsStopper = new SimpleStop(Globals.getRunTime()); /** */ private Stat itsStatistic = null; /** The object that stores the text for the currently loaded model */ private NetworkFile netFile; /** */ private ModelRunner runner = null; /** */ private Experiment experiment = null; /** */ private ScriptRunner script = null; /** */ private int runType = NOTHING_RUNNING; static private String[] rgs={""}; /** GeneNetInterface is the central class used to keep track of all the various windows available for looking at and modifying the loaded model. */ private GeneNetInterface geneNetInterface = null; /** */ public SymAction actor = new SymAction(); static public void main(String args[]) { TheGeneNet = new GeneNet(args); } public GeneNet() { netFile = new NetworkFile(); TheMainGui = new MainGui(this); // TheMainGui.addActionListener(actor); geneNetInterface = new GeneNetInterface(); geneNetInterface.addActionListener(actor); Globals.setMainProgram(this); } /* public GeneNet(String arg){ Globals.setUsingGUI(false); int i = 0; // java inputs start at position 0 actor.actionPerformed(new ActionEvent(this, GeneNetInterface.LOAD_MODEL, arg)); if(model == null && script == null) { // There was a problem, so quit System.out.println("Problem loading models - quitting"); System.exit(10); } if (script != null) ; // Script already started on load else if(ItsIterator != null) actor.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, GeneNetInterface.RUN_ITERATOR_TEXT)); else if(itsStatistic != null) { try { if(Globals.getCurParamSetArray() == null) { System.out.println("Could not run statistic because there is no cam file loaded"); System.exit(10); } itsStatistic.init(Globals.getCurParamSetArray()); itsStatistic.setOutputFile("statistic_out.txt"); itsStatistic.calculateStat(); } catch(IOException e) { System.out.println("Exception while calculating statistic: " + e.toString()); } System.exit(10); } else actor.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, GeneNetInterface.RUN_MODEL_TEXT)); Globals.setMainProgram(this); }*/ private GeneNet(String [] args) { netFile = new NetworkFile(); if(args.length >= 1) { Globals.setUsingGUI(false); int i = 0; // java inputs start at position 0 while(i < args.length) { actor.actionPerformed(new ActionEvent(this, GeneNetInterface.LOAD_MODEL, args[i])); i++; } if(model == null && script == null) { // There was a problem, so quit System.out.println("Problem loading models - quitting"); System.exit(10); } if (script != null) ; // Script already started on load else if(ItsIterator != null) actor.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, GeneNetInterface.RUN_ITERATOR_TEXT)); else if(itsStatistic != null) { try { if(Globals.getCurParamSetArray() == null) { System.out.println("Could not run statistic because there is no cam file loaded"); System.exit(10); } itsStatistic.init(Globals.getCurParamSetArray()); itsStatistic.setOutputFile("statistic_out.txt"); itsStatistic.calculateStat(); } catch(IOException e) { System.out.println("Exception while calculating statistic: " + e.toString()); } System.exit(10); } else actor.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, GeneNetInterface.RUN_MODEL_TEXT)); } else { TheMainGui = new MainGui(this); // TheMainGui.addActionListener(actor); geneNetInterface = new GeneNetInterface(); geneNetInterface.addActionListener(actor); } Globals.setMainProgram(this); } // TODO - Destroy this! class SymAction implements java.awt.event.ActionListener { public void actionPerformed(java.awt.event.ActionEvent event) { switch(event.getID()) { case ActionEvent.ACTION_PERFORMED: { String command = event.getActionCommand(); if (command.equals(GeneNetInterface.QUIT_TEXT)) { System.exit(0); // exit } else if(command.equals(GeneNetInterface.REMOVE_EXPERIMENT_TEXT)) { if(experiment != null) { experiment.endExperiment(); if(ItsIterator != null) ItsIterator.resetStopper(); experiment = null; } } else if(command.equals(GeneNetInterface.RUN_MODEL_TEXT)) { if(model == null) return; stop(); runner = getModelRunner(); runner.setRunMode(Globals.getIntegrationAlgorithm()); runner.startRun(); runType = MODEL_RUNNING; start(); } else if(command.equals(GeneNetInterface.STEP_MODEL_TEXT)) { if(model == null) return; stop(); runner = getModelRunner(); runner.setRunMode(Globals.getIntegrationAlgorithm()); try { runner.doStep(); } catch(Exception e) { System.out.println(e.toString()); } } else if(command.equals(GeneNetInterface.RESET_MODEL_TEXT)) { if(model == null) return; stop(); runner = getModelRunner(); runner.setRunMode(Globals.getIntegrationAlgorithm()); runner.doReset(); } /* else if(command.equals(GeneNetInterface.RUN_FIXED_POINT_TEXT)) { if(model == null) return; stop(); // Need to bring up a dlog here asking where to run model to. runner = getModelRunner(); runner.setRunMode(ModelRunner.FIXEDPOINT); runner.startRun(); runType = MODEL_RUNNING; start(); } */ else if(command.equals(GeneNetInterface.RUN_ITERATOR_TEXT)) { if (ItsIterator == null) { System.out.println("No iterator loaded"); return; } stop(); ItsIterator.setPrint(true); // print out summaries ItsIterator.startRun(); //iteratorThread = new Thread(itsIterator); //iteratorThread.start(); runType = ITERATOR_RUNNING; start(); } else if(command.equals(GeneNetInterface.STOP_TEXT)) { stop(); } else return; } break; case GeneNetInterface.LOAD_MODEL: // Open file and figure out what first tag in file is try { FileInputStream fs = new FileInputStream(event.getActionCommand()); BetterTokenizer tokenizer = new BetterTokenizer(fs); GeneralInput.setupTokenizer(tokenizer); String info = GeneralInput.findNextIDToken(tokenizer).toUpperCase(); if(info.equals("MODEL")) { fs.close(); fs = new FileInputStream(event.getActionCommand()); loadModel(event.getActionCommand(), fs); fs.close(); } else if(info.equals("SCRIPT")) { loadScript(tokenizer); } else { // For everything else, need model loaded first if(model == null) { System.out.println("You must load a model before loading anything else"); fs.close(); return; } if(info.equals("ITERATOR")) loadIterator(tokenizer); else if(info.equals("STOPPER")) loadStopper(tokenizer); else if(info.equals("CAM")) loadCamFile(tokenizer, event.getActionCommand()); else if(info.equals("STATISTIC")) loadStatisticFile(tokenizer); else System.out.println("Unrecognized first tag in file <" + info + "> - nothing loaded"); fs.close(); } } catch(Exception e) { System.out.println("Error in loading file " + event.getActionCommand() + ": " + e.toString()); } break; case GeneNetInterface.SAVE_MODEL: if(model == null) return; try { FileOutputStream fs = new FileOutputStream(event.getActionCommand()); PrintWriter pw = new PrintWriter(fs, true); model.saveNetworkFile(pw); pw.close(); System.out.println("Saved network into file " + event.getActionCommand()); //fs.close(); } catch(Exception e) { System.out.println("Error while saving network file : " + e.toString()); } break; case GeneNetInterface.LOAD_EXPERIMENT: experiment = new Experiment(model, event.getActionCommand()); experiment.startExperiment(); if(ItsIterator != null && experiment.stopper != null) ItsIterator.setStopper(experiment.stopper); System.out.println("Experiment loaded"); break; case GeneNetInterface.LOAD_CAM_FILE: try { FileInputStream stream = new FileInputStream(event.getActionCommand()); BetterTokenizer tokenizer = new BetterTokenizer(stream); GeneralInput.setupTokenizer(tokenizer); loadCamFile(tokenizer, event.getActionCommand()); } catch(Exception e) { System.out.println("Error opening cam file " + event.getActionCommand() + " : " + e.toString()); } break; case GeneNetInterface.INTERFACE_ACTION: if(event.getActionCommand().equals(GeneNetInterface.UPDATE_MODEL)) { loadModel(netFile); } break; } } } /******************* START OF IN USE SECTION ********************/ /** Do a tidy shutdown of the program @author WJS */ public static void close() { // TODO - Other tidey type things System.exit(0); } /** Returns the ModelIterator. @result ModelIterator. @author WJS */ public ModelIterator getIterator() { return(ItsIterator); } /** Returns the Model loaded in this GeneNet. @result Model @author WJS */ public Model getModel() { return(TheModel); } /** Returns the Network for the Model loaded in this GeneNet. @result Network @author WJS */ public Network getNetwork() { return(TheModel.getNetwork()); } /** @author WJS */ public NetworkFile getNetworkFile() { return(netFile); } /** @author WJS */ public boolean isIteratorRunning() { return(runType==ITERATOR_RUNNING); } /** @author WJS */ private boolean isModelFile(File file) { // Open file and figure out what first tag in file is try { FileInputStream fs = new FileInputStream(file); BetterTokenizer tokenizer = new BetterTokenizer(fs); GeneralInput.setupTokenizer(tokenizer); String info = GeneralInput.findNextIDToken(tokenizer).toUpperCase(); if (info.equals("MODEL")) { fs.close(); return(true); } else return(false); } catch(Exception e) { System.out.println("Error in loading file " + file.getAbsolutePath() + ": " + e.toString()); return(false); } } /** @author WJS */ private boolean isIteratorFile(File file) { // Open file and figure out what first tag in file is try { FileInputStream fs = new FileInputStream(file); BetterTokenizer tokenizer = new BetterTokenizer(fs); GeneralInput.setupTokenizer(tokenizer); String info = GeneralInput.findNextIDToken(tokenizer).toUpperCase(); if (info.equals("ITERATOR")) { fs.close(); return(true); } else return(false); } catch(Exception e) { System.out.println("Error in loading file " + file.getAbsolutePath() + ": " + e.toString()); return(false); } } /** @author WJS */ public boolean isModelRunning() { return(runType==MODEL_RUNNING); } // I put this in so that the surface inspector can also use it. I should probably // beef it up a little - maybe stop old models running here, for instance private ModelRunner getModelRunner() { if(experiment != null) runner = new ModelRunner(model, experiment.stopper); else { if(itsStopper == null) { itsStopper = new SimpleStop(Globals.getRunTime()); itsStopper.init(model); } runner = new ModelRunner(model,itsStopper); } return(runner); } /** */ private void loadCamFile(BetterTokenizer tokenizer, String filename) { ParameterSetArray psa = loadParamsFromOutfile(tokenizer, filename); if(psa != null) { Globals.addParamSetArray(psa); Globals.setCurParamSetArray(psa); if(Globals.getUsingGUI()) { CamGraph cg = new CamGraph(); cg.setParamSets(psa); } } } /** @author WJS */ private boolean loadFile(File file) { boolean result = true; // Open file and figure out what first tag in file is try { FileInputStream fs = new FileInputStream(file); BetterTokenizer tokenizer = new BetterTokenizer(fs); GeneralInput.setupTokenizer(tokenizer); String info = GeneralInput.findNextIDToken(tokenizer).toUpperCase(); if (info.equals("MODEL")) { fs.close(); fs = new FileInputStream(file); result = loadModel(file.getAbsolutePath(), fs); fs.close(); } else if (info.equals("SCRIPT")) { loadScript(tokenizer); result = true; } else { // For everything else, need model loaded first if (model == null) { System.out.println("You must load a model before loading anything else"); fs.close(); return(false); } if (info.equals("ITERATOR")) loadIterator(tokenizer); else if (info.equals("STOPPER")) loadStopper(tokenizer); else if (info.equals("CAM")) loadCamFile(tokenizer, file.getAbsolutePath()); else if (info.equals("STATISTIC")) loadStatisticFile(tokenizer); else { System.out.println("GeneNet.loadFile - Unrecognized first tag in file <" + info + "> - nothing loaded"); result = false; } fs.close(); } } catch(Exception e) { System.out.println("GeneNet.loadFile - Error in loading file " + file.getAbsolutePath() + ": " + e.toString()); } return(result); } /** */ private boolean loadModel(String filename, FileInputStream fs) throws Exception { netFile.readText(fs); boolean result = loadModel(netFile); //What the hell???? File file = new File(filename); Globals.setModelFile(file.getName(), file.lastModified()); return(result); } /** */ private boolean loadModel(NetworkFile net_file) { try { // First stop the model if it's running and clean thing up stop(); if(model != null) model.cleanUp(); Affector.clearStatic(); model = net_file.createModel(); TheModel = model; runner = null; experiment = null; ItsIterator = null; if (model == null) { if(geneNetInterface != null) { geneNetInterface.setModel(null); geneNetInterface.setNetwork(null); } GlobalIO.printlnGeneral("Problem loading model"); sendNetworkEvent(new NetworkEvent(null, NetworkEvent.NEW_NETWORK, 0)); } else { if (itsStopper != null) itsStopper.init(model); if (geneNetInterface != null) { geneNetInterface.setModel(model); geneNetInterface.setNetwork(model.net); } // Announce success GlobalIO.printlnGeneral("Model loaded"); sendNetworkEvent(new NetworkEvent(model.net, NetworkEvent.NEW_NETWORK, 0)); } } catch (Exception ex) { System.out.println("GeneNet.loadFile - Error loading file "+ex); return(false); } return(true); } /** */ private void loadIterator(BetterTokenizer tokenizer) throws Exception { GeneralInput.nextToken(tokenizer); String iter_name = tokenizer.sval; Class c = Class.forName("iterators." + iter_name); ItsIterator = (ModelIterator)c.newInstance(); ItsIterator.init(model.net, model); ItsIterator.loadParameters(tokenizer); if(experiment != null && experiment.stopper != null) ItsIterator.setStopper(experiment.stopper); GlobalIO.printlnGeneral("Iterator loaded"); } /** Use this function to read in the sets of parameters from an output file. This function looks for the first ParamsToVary tag that's outside of anything else, and assumes that defines what parameters are important in the params that follow. All other parameters are ignored - this could be dangerous if the net file that was used while creating the output file is different than the one currently being used, so probably I should redo this somehow to keep track of both the varying and the unvarying parameters. @return Returns a ParameterSetArray which has all the parameter sets from the output file, including their group numbers and id tags. @see ParameterSetArray */ private ParameterSetArray loadParamsFromOutfile(BetterTokenizer tokenizer, String filename) { try { // First look for the first ParamsToVary that we find which is outside of any evaluator // which will give params that were varied, and therefore the params that we care about loading in String info = GeneralInput.findNextIDToken(tokenizer); ParameterSet prototype = new ParameterSet(); while(! info.equals("endHeader")) { if(info.equals("ModelFile")) { GeneralInput.nextToken(tokenizer); if(!tokenizer.sval.equals(Globals.modelFilename)) System.out.println("WARNING - This output file wasn't made using the model that you currently have loaded"); GeneralInput.nextToken(tokenizer); if((long)tokenizer.nval != Globals.modelChangeTime) System.out.println("WARNING - This output file was made with a model that has a different date than the currently loaded model"); } else if(info.equals("Evaluators")) { // Look for endEvaluators while(!info.equals("endEvaluators")) info = GeneralInput.findNextIDToken(tokenizer); } else if(info.equals("ParamsToVary")) { prototype.loadParameterValues(tokenizer, false); } else if(info.equals("VaryAllParams")) { ParameterSet new_prototype = model.getModelParameterSet().copy(); new_prototype.copyValueFieldNames(prototype); prototype = new_prototype; } else if(info.equals("ValueFieldNames")) { prototype.loadValueFieldNames(tokenizer); } info = GeneralInput.findNextIDToken(tokenizer); } System.out.println("Loading parameters"); // Now just call the ParameterSetArray load, which will look for the first par flag and be off and running ParameterSetArray psa = new ParameterSetArray(prototype); psa.loadParameters(tokenizer); psa.setFilename((new File(filename)).getName()); System.out.println("Done loading parameters"); return psa; } catch(Exception e) { System.out.println("Error reading from file: " + e.toString()); return null; } } /** */ private void loadStopper(BetterTokenizer tokenizer) throws Exception { GeneralInput.nextToken(tokenizer); String stop_name = tokenizer.sval; Class c = Class.forName("stoppers." + stop_name); itsStopper = (SimpleStop)c.newInstance(); itsStopper.init(model); itsStopper.loadParameters(tokenizer); if(runner != null) runner.setStopper(itsStopper); GlobalIO.printlnGeneral("Stopper loaded"); } /** */ private void loadScript(BetterTokenizer tokenizer) { script = new ScriptRunner(tokenizer, this); Thread thread = new Thread(script); thread.start(); } /** */ private void loadStatisticFile(BetterTokenizer tokenizer) throws Exception { GeneralInput.nextToken(tokenizer); String stat_name = tokenizer.sval; Class c = Class.forName("stat." + stat_name); itsStatistic = (Stat)c.newInstance(); GlobalIO.printlnGeneral("Statistic loaded"); } /** @author WJS */ private void resetIterator() { // TODO - Reset iterator itself if needed. May be useful for iterators that // start at a certain point. if (ItsIterator!=null) { ItsIterator.reset(); } // Reset the model too. resetModel(); } /** @author WJS */ private void resetModel() { if(model == null) return; stop(); runner = getModelRunner(); runner.setRunMode(Globals.getIntegrationAlgorithm()); runner.doReset(); } /** @author WJS */ public void run() { try { if(runType == MODEL_RUNNING) { while(runner.running) { Thread.sleep(500); } } else if(runType == ITERATOR_RUNNING) { while(ItsIterator.isRunning() ) {//&& iteratorThread != null && iteratorThread.isAlive()) { Thread.sleep(500); } } } catch(InterruptedException e) { System.out.println("Running interrupted: " + e.toString()); } stop(); } /** Initiates an iterator run if an iterator is loaded. @author WJS */ private void runIterator() { if (ItsIterator==null) { if (TheMainGui!=null) ErrorPopUp.nonFatalError("No iterator loaded"); System.out.println("No iterator loaded"); } else { stop(); ItsIterator.setPrint(true); ItsIterator.startRun(); runType = ITERATOR_RUNNING; start(); } } /** @author WJS */ private void runModel() { if(model == null) return; stop(); runner = getModelRunner(); runner.setRunMode(Globals.getIntegrationAlgorithm()); runner.startRun(); runType = MODEL_RUNNING; start(); } /** */ private void saveModel(File file) { if (model==null) { System.out.println("Nothing to save - Model is empty."); return; } try { FileOutputStream fs = new FileOutputStream(file); PrintWriter pw = new PrintWriter(fs, true); model.saveNetworkFile(pw); pw.close(); System.out.println("Saved network into file " + file.getPath()); } catch(Exception e) { System.out.println("GeneNet.saveModel - Error while saving file : " + e.toString()); } } /** @author WJS */ private void start() { Thread runThread = new Thread(this); runThread.start(); System.out.println("Start"); RunTime = System.currentTimeMillis(); } /** @author WJS */ private void stepModel() { if(model == null) return; stop(); runner = getModelRunner(); runner.setRunMode(Globals.getIntegrationAlgorithm()); try { runner.doStep(); } catch(Exception e) { System.out.println(e.toString()); } } /** @author WJS */ private void stop() { if(runType == NOTHING_RUNNING) return; // Otherwise we could call this twice if(runType == MODEL_RUNNING && runner.running) { runner.stopRun(); try { runner.runThread.join(); } catch(Exception e) {} } else if(runType == ITERATOR_RUNNING && ItsIterator.isRunning()) { ItsIterator.stopRun(); } if(runType == MODEL_RUNNING) { // Print out the value of the stopper if(itsStopper.didPass()) System.out.println("Stopper value = " + itsStopper.getScore() + " passed"); else System.out.println("Stopper value = " + itsStopper.getScore() + " didn't pass"); } runType = NOTHING_RUNNING; System.out.println("Done running"); RunTime = System.currentTimeMillis()-RunTime; System.out.println("RunTime="+RunTime); if(!Globals.getUsingGUI()) System.exit(1); } /** @author WJS */ private void stopModel() { stop(); } public void addNetworkListener(NetworkEventListener listener) { } public void removeNetworkListener(NetworkEventListener listener) { } private void sendNetworkEvent(NetworkEvent evt) { } /******************** GUItoNet Interface implementation *********************/ /** Called when a change is made to the passed AffectorTemplate @param int operation @param AffectorTemplate affectorTemplate @param GuiInterface source - Originator of this interface change. @author WJS */ public void affectorTemplateChanged(int operation, AffectorTemplate affectorTemplate, GuiInterface source) { } /** Method for invoking general network IO operations. @param int operation - The network IO operation code. @param File file - The file if needed, else don't care. @author WJS */ public boolean networkIO(int operation, File file) { boolean result = true; switch (operation) { case GuiInterface.CLOSE: break; case GuiInterface.EXIT: close(); break; case GuiInterface.IS_MODEL: result = isModelFile(file); break; case GuiInterface.IS_ITERATOR: result = isIteratorFile(file); break; case GuiInterface.NEW: break; case GuiInterface.OPEN: result = loadFile(file); break; case GuiInterface.SAVE: saveModel(file); break; default: System.out.println("GeneNet.networkIO - unknown operation"); break; } return(result); } /** Called when a change is made to the passed NodeTemplate @param int operation @param NodeTemplate nodeTemplate @param GuiInterface source - Originator of this interface change. @author WJS */ public void nodeTemplateChanged(int operation, NodeTemplate nodeTemplate, GuiInterface source) { // Notify other listeners. } /** Called when a change is made to a parameter or the whole parameter set @param int operation @param int parameterNumber @param GuiInterface source - Originator of this interface change. @author WJS */ public void parameterSetChanged(int operation, int parameterNumber, GuiInterface source) { } /** Method for controling model/iterator runs. @param int operation - Run control code. @author WJS */ public void runControl(int operation) { switch (operation) { case RUN_MODEL: runModel(); break; case STEP_MODEL: stepModel(); break; case RESET_MODEL: resetModel(); break; case RUN_ITERATOR: runIterator(); break; case STEP_ITERATOR: break; case STOP_ITERATOR: stopModel(); break; case RESET_ITERATOR: resetIterator(); break; default: System.out.println("GeneNet.runControl - unknown operation"); break; } } /** Method for reporting status of the model/iterator runs @param int operation - Run status code. @author WJS */ public void runStatus(int operation) { } }