
import java.awt.geom.Point2D;
import java.io.File;
import java.util.Arrays;

import jimena.binaryrn.RegulatoryNetwork;
import jimena.libs.StringLib;
import jimena.perturbation.OnOffPerturbation;
import jimena.simulation.ProgressWindow;
import jimena.simulationmethods.NormalizedHillCubeInterpolationMethod;
import jimena.ssssearcher.RandomSearcher;

/**
 * A collection of typical example which show how to use the simulation package as a library.
 * 
 * @author Stefan Karl, Department of Bioinformatics, University of Würzburg, stefan[dot]karl[at]stud-mail[dot]uni-wuerzburg[dot]de
 * 
 */
public class JIMENAExample {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // Create a new GRN
        RegulatoryNetwork network = new RegulatoryNetwork();

        // Load a yED GraphML file into the network
        try {
            network.loadYEdFile(new File("H:\\Th Model.graphml")); // ENTER THE PATH TO THE EXAMPLE HERE
        } catch (Exception e) {
            e.printStackTrace();
        }

        // List network nodes
        System.out.println(Arrays.toString(network.getNodeNames()));
        System.out.print("\n");

        // Set the SQUAD decay parameter for the third node
        network.getNetworkNodes()[2].setSQUADDecay(2D);

        // Set value of the first node
        network.getNetworkNodes()[0].setValue(1D);

        /*
         * Simulate the network using the Odefy model with normalized HillCubes, an differential equation solving step of 0.001 for 10
         * second (network time). Simulate as fast as possible (maxSpeed = Double.POSITIVE_INFINITY) and create a log entry every ~1.0
         * seconds. Since the network has no registered observers we can set the GUI refreshing intervall to infinity. No calculation
         * controller is given (null).
         */
        network.simulate(new NormalizedHillCubeInterpolationMethod(), 0.001D, 10D, Double.POSITIVE_INFINITY, 1.0, Double.POSITIVE_INFINITY,
                null);

        // The time index of network is different now
        System.out.println(network.getTimeIndex() + "\n");

        // Print the log entries of the first node:
        for (Point2D.Double logEntry : network.getNetworkNodes()[0].getLog()) {
            System.out.println(logEntry.getX() + ": " + logEntry.getY());
        }
        System.out.print("\n");

        // Reset the network (Resets all values to the initial values, resets the logs and sets the time index to 0.)
        // Does not reset the simulation parameters or perturbations
        network.reset();

        // Fix the first node to the value 1 between the time indices 0 and 5 by adding a perturbation to the node
        network.getNetworkNodes()[0].getPerturbations().add(new OnOffPerturbation(0, 500000, 1));

        // Simulate the network again. This time with a calculation controller: A progress window.
        network.simulate(new NormalizedHillCubeInterpolationMethod(), 0.0001D, 10D, Double.POSITIVE_INFINITY, 1.0, 0.5,
                new ProgressWindow());

        // Print the log entries of the first node:
        for (Point2D.Double logEntry : network.getNetworkNodes()[0].getLog()) {
            System.out.println(logEntry.getX() + ": " + logEntry.getY());
        }
        System.out.print("\n");

        // Remove all perturbations before we calculate stable steady states
        // Otherwise they will be included in the calculation as assumptions
        network.removeAllPerturbations();

        /*
         * Note that all methods of RegulatoryNetwork block the current thread (even if they are threaded internally). You should not call
         * them in the default Swing GUI thread or the GUI will freeze.
         */

        /*
         * Calculate the stable steady state reached from the current values. A state is considered to be stable after all of its values
         * stay in an environment of 2*0.001 for 5 seconds. The search is conducted for no more than 1000 seconds (simulation time).
         */
        System.out.println(Arrays.toString(network.stableSteadyState(network.getValues(), 0.001, 5,
                new NormalizedHillCubeInterpolationMethod(), 0.001, 1000, null)));
        System.out.print("\n");

        /*
         * Calculate ALL stable steady state reached from the current values. A state is considered to be stable after all of its values
         * stay in an environment of 2*0.001 for 5 seconds. The search is conducted for no more than 1000 seconds per random start vector in
         * simulation time and 5000 ms real calculation time. 2 threads and a random searcher are used for the search.
         */
        StringLib.printDoubleVectorList(network.stableSteadyStates(0.001, 5, new NormalizedHillCubeInterpolationMethod(), 0.01, 50, 0.001,
                5000, new ProgressWindow(), 2, new RandomSearcher()));
        System.out.print("\n");

        // Determine the stable steady states for a discrete model using BDDs
        StringLib.printByteVectorList(network.discreteStableSteadyStates());

        // Stop all GUI activities.
        System.exit(0);
    }
}
