package reaction;
import java.awt.Desktop;
import java.io.File;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.Vector;
import logs.Logs;
import miscellaneous.DirectoryManager;
import miscellaneous.JEXCSVWriter;
import miscellaneous.LSVList;
import recorders.Recorder;
import weka.core.converters.JEXTableWriter;
public class Simulator {
Vector<Reaction> rxns = new Vector<Reaction>();
File outputFolder = null;
double duration = 0, dt = 0, dtRecorder = 0;
public Simulator()
{
this.outputFolder = new File(DirectoryManager.getUniqueAbsoluteTempPath(JEXTableWriter.ARFF_FILE));
}
public Simulator(String outputFolderPath)
{
this.outputFolder = new File(outputFolderPath);
DirectoryManager.setHostDirectory(this.outputFolder.getAbsolutePath());
}
public static void main(String[] args)
{
Simulator sim = new Simulator("/Users/jaywarrick/Desktop/TestSimulator");
sim.setParams(6 * 60 * 60, 1.0, 15 * 60); // sets the simulation parameters (runs for 6 hours, with a simulation time step of 1 second, and records data every 15 minutes)
// Create a pool and add items (i.e. molecules, proteins, transcripts, genomes, etc.) to it.
Pool pool = new Pool("Main Pool");
pool.initialize(new Item("Gen", 1.0, 0.0)); // new Item("Name", amount, delayTime)
pool.initialize(new Item("Pol", 50.0, 0.0));
pool.initialize(new Item("AntiGen", 0.0, 0.0));
pool.initialize(new Item("Rib", 5e6, 0.0));
pool.initialize(new Item("Protein", 0, 0.0));
// Transcription - Pol + Gen -> Transcript + Pol + Gen
Reaction r1 = new Reaction();
r1.setk(1e-3);
r1.addReactant(pool, "Pol", 1.0, 1.0);
r1.addReactant(pool, "Gen", 1, 1);
r1.addProduct(pool, "Transcript", 1, 1);
r1.addProduct(pool, "Pol", 1, 1);
r1.addProduct(pool, "Gen", 1, 0.0);
// Make AntiGen - Pol + Gen -> AntiGen + Gen + Pol
Reaction r2 = new Reaction();
r2.setk(1e-6);
r2.addReactant(pool, "Pol", 1, 1);
r2.addReactant(pool, "Gen", 1, 1);
r2.addProduct(pool, "AntiGen", 1, 5000);
r2.addProduct(pool, "Gen", 1, 0);
r2.addProduct(pool, "Pol", 1, 5000);
// Make Gen - Pol + AntiGen -> Gen + Pol + AntiGen
Reaction r3 = new Reaction();
r3.setk(1e-6);
r3.addReactant(pool, "Pol", 1, 1);
r3.addReactant(pool, "AntiGen", 1, 1);
r3.addProduct(pool, "Gen", 1, 5000);
r3.addProduct(pool, "Pol", 1, 5000);
r3.addProduct(pool, "AntiGen", 1, 0.0);
// Make Protein - Rib + Transcript -> Protein + Rib + Transcript
Reaction r4 = new Reaction();
r4.setk(1e-6);
r4.addReactant(pool, "Rib", 1, 1);
r4.addReactant(pool, "Transcript", 1, 1);
r4.addProduct(pool, "Protein", 3, 300);
r4.addProduct(pool, "Rib", 1, 300.0);
r4.addProduct(pool, "Transcript", 1, 0.0);
// Make Pol - Protein -> Pol
Reaction r5 = new Reaction();
r5.setk(1e-9);
r5.addReactant(pool, "Protein", 2, 1);
r5.addProduct(pool, "Pol", 1, 0);
sim.rxns.add(r1);
sim.rxns.add(r2);
sim.rxns.add(r3);
sim.rxns.add(r4);
sim.rxns.add(r5);
Logs.log("%%%%%%%%%% Model Reactions %%%%%%%%%", Simulator.class);
for (Reaction r : sim.rxns)
{
Logs.log(r.toString(), Simulator.class);
}
Logs.log("\n\n", Simulator.class);
// Simulation
double t = 0;
JEXCSVWriter writer = new JEXCSVWriter(DirectoryManager.getHostDirectory() + File.separator + "Results.csv"); // Set up a file writer to write data as we go.
try
// set up a try loop so we can catch errors and close the writer if something bad happens
{
writer.write(new String[] { "Time", "Gen", "Pol", "AntiGen", "Rib", "Transcript" }); // List of strings with a comma between them (i.e. a row in the table, in this case, the header of the table)
DecimalFormat format = new DecimalFormat("0.00");
double lastRecordedTime = 0;
String[] itemsToRecord = new String[] { "Gen", "Pol", "AntiGen", "Rib", "Transcript" };
Vector<String> data = new Vector<String>();
while (t < sim.duration)
{
// Add matured items to the pool
pool.mature(t);
// records the amounts of items in the pool at given time in the results table
if(t - lastRecordedTime >= sim.dtRecorder) // If enough time has elapsed since our last recording, record the status of the pool at this time step
{
data.add("" + t); // Time
for (String itemName : itemsToRecord)
{
double amount = pool.amounts.getCount(itemName);
data.add(format.format(amount));
}
writer.write(data);
Logs.log(data.toString(), Simulator.class);
data.clear();
lastRecordedTime = t;
}
// increment time here
// This way, time 0 is recorded initially but time is incremented
// dt for integrating and finding the next solution.
t = t + sim.dt;
// calculate rates based on each reaction in the simulation
for (Reaction rxn : sim.rxns)
{
rxn.calculateBaseRate();
rxn.applyStoichAndRate();
}
// Use the new calculated base rates (dA/dt, dB/dt, etc) to calculate the amount to adjust each amount for the given time-step
pool.simpleLinearIntegrate(sim.dt, t, 1.0); // 1.0 is an attenuation factor (1.0 means no attenuation of all the reactions, 0.0 means all the reactions are stopped. Used to apply things like cell death)
}
}
finally
{
if(writer != null)
{
writer.close();
try
// try to open the folder with the results
{
Desktop.getDesktop().open(sim.outputFolder);
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
public void setParams(double duration, double dt, double dtRecorder)
{
this.duration = duration;
this.dt = dt;
this.dtRecorder = dtRecorder;
// Print the reactions used
LSVList reactions = new LSVList();
reactions.add(" ");
for (Reaction r : this.rxns)
{
reactions.add(r.toString());
}
Recorder.log(reactions.toString(), this);
}
}