private static void Execute_Worker(bool doParse, bool doAST, bool doScope, bool autoContinue, bool chartOutput) { KGui.gui.GuiBeginningExecution(); lastExecution = null; KGui.gui.GuiSaveInput(); KGui.gui.GuiOutputClear(); DateTime startTime = DateTime.Now; if (TheParser.Parser().Parse(KGui.gui.GuiInputGetText(), out IReduction root)) { if (doParse) { root.DrawReductionTree(); } else { Netlist netlist = new Netlist(autoContinue); try { Statements statements = Parser.ParseTop(root); if (doAST) { KGui.gui.GuiOutputAppendText(statements.Format()); } else { SampleValue vessel = Vessel(KControls.SelectNoiseSelectedItem != Noise.None); Env initialEnv = new ValueEnv("vessel", Type.Sample, vessel, new BuiltinEnv(new NullEnv())); Scope initialScope = initialEnv.ToScope(); Scope scope = statements.Scope(initialScope); if (doScope) { KGui.gui.GuiOutputAppendText(scope.Format()); } else { Style style = new Style(varchar: scopeVariants ? defaultVarchar : null, new SwapMap(), map: remapVariants ? new AlphaMap() : null, numberFormat: "G4", dataFormat: "full", // we want it full for samples, but maybe only headers for functions/networks? exportTarget: ExportTarget.Standard, traceFull: false, chartOutput: chartOutput); KChartHandler.ChartClear("", "s", "M", style); KChartHandler.LegendUpdate(style); KScoreHandler.ScoreClear(); KControls.ParametersClear(style); KDeviceHandler.Clear(style); KDeviceHandler.Sample(vessel, style); netlist.Emit(new SampleEntry(vessel)); DateTime evalTime = DateTime.Now; lastExecution = new ExecutionInstance(vessel, netlist, style, startTime, evalTime); lastExecution.environment = statements.EvalReject(initialEnv, netlist, style, 0); if (lastExecution.environment == null) { throw new Error("Top level reject"); } lastExecution.EndTime(); if (style.chartOutput) { foreach (ParameterEntry parameter in netlist.Parameters()) { KControls.AddParameter(parameter.symbol.Format(style), (parameter.value as NumberValue).value, parameter.distribution, style); } KGui.gui.GuiParametersUpdate(); // calls back KControls.ParametersUpdate, but only on Win/Mac } KGui.gui.GuiProcessOutput(); } } } catch (ExecutionEnded) { lastExecution.EndTime(); KGui.gui.GuiOutputAppendText(lastExecution.ElapsedTime()); } catch (ConstantEvaluation ex) { string cat = "Does not have a value: "; netlist.Emit(new CommentEntry(cat + ": " + ex.Message)); KGui.gui.GuiInputSetErrorSelection(-1, -1, 0, cat, ex.Message); } catch (Error ex) { netlist.Emit(new CommentEntry(ex.Message)); KGui.gui.GuiInputSetErrorSelection(-1, -1, 0, "Error", ex.Message); try { KGui.gui.GuiProcessOutput(); } catch { }; } catch (StackOverflowException ex) { netlist.Emit(new CommentEntry(ex.Message)); KGui.gui.GuiInputSetErrorSelection(-1, -1, 0, "Stack Overflow", ex.Message); } catch (Exception ex) { string cat = "Something happened"; netlist.Emit(new CommentEntry(cat + ": " + ex.Message)); KGui.gui.GuiInputSetErrorSelection(-1, -1, 0, cat, ex.Message); } } } else { KGui.gui.GuiInputSetErrorSelection(TheParser.Parser().FailLineNumber(), TheParser.Parser().FailColumnNumber(), TheParser.Parser().FailLength(), TheParser.Parser().FailCategory(), TheParser.Parser().FailMessage()); } EndingExecution(); }
public static SampleValue Equilibrate(Env env, Symbol outSymbol, SampleValue inSample, Noise noise, double fortime, Netlist netlist, Style style) { inSample.CheckConsumed(style); // we will consume it later, but we need to check now double initialTime = 0.0; double finalTime = fortime; string sampleName = (outSymbol.Raw() == "vessel") ? "" : "Sample " + inSample.FormatSymbol(style); KChartHandler.ChartClear(sampleName, "s", "M", style); List <SpeciesValue> inSpecies = inSample.stateMap.species; State initialState = inSample.stateMap.state; if ((noise == Noise.None) && initialState.lna) { initialState = new State(initialState.size, lna: false).InitMeans(initialState.MeanVector()); } if ((noise != Noise.None) && !initialState.lna) { initialState = new State(initialState.size, lna: true).InitMeans(initialState.MeanVector()); } List <ReactionValue> reactions = inSample.RelevantReactions(netlist, style); CRN crn = new CRN(inSample, reactions, precomputeLNA: (noise != Noise.None) && KControls.precomputeLNA); KChartHandler.SetMeanFlowDictionary(crn.MeanFlowDictionary(), style); // List<ReportEntry> reports = netlist.Reports(inSpecies); List <ReportEntry> reports = inSample.RelevantReports(style); Exec.lastExecution.lastCRN = crn; KGui.gui.GuiOutputSetText(crn.FormatNice(style)); Exec.lastExecution.ResetGraphCache(); Func <double, double, Vector, Func <double, Vector, Vector>, IEnumerable <SolPoint> > Solver; if (KControls.solver == "GearBDF") { Solver = Ode.GearBDF; } else if (KControls.solver == "RK547M") { Solver = Ode.RK547M; } else { throw new Error("No solver"); } Func <double, Vector, Vector> Flux; if (noise != Noise.None) { Flux = (t, x) => crn.LNAFlux(t, x, style); } else { Flux = (t, x) => crn.Flux(t, x, style); } bool nonTrivialSolution = (inSpecies.Count > 0) && // we don't want to run on the empty species list: Oslo crashes (!crn.Trivial(style)) && // we don't want to run trivial ODEs: some Oslo solvers hang on very small stepping finalTime > 0; // we don't want to run when fortime==0 // INTEGRATE (double lastTime, State lastState) = Integrate(Solver, initialState, initialTime, finalTime, Flux, inSample, reports, noise, nonTrivialSolution, style); if (lastState == null) { lastState = initialState.Clone(); } lastState = lastState.Positive(); List <SpeciesValue> outSpecies = new List <SpeciesValue> { }; foreach (SpeciesValue sp in inSpecies) { outSpecies.Add(sp); // the species list may be destructively modified (added to) later in the new sample } SampleValue outSample = new SampleValue(outSymbol, new StateMap(outSymbol, outSpecies, lastState), new NumberValue(inSample.Volume()), new NumberValue(inSample.Temperature()), produced: true); outSample.AddReports(inSample.RelevantReports(style)); foreach (ReportEntry report in reports) { // an equilibrate may pick up the reports of a previous equilibrate, so we reassign the report even if it has already been assigned // this does not really affect lexical binding because a second report with the same name will get a new symbol // P.S. this was changed so that an equilibrate no longer picks up reports of previous equilibrate, so the issue should not arise if (report.timecourse != null) { env.AssignValue(report.timecourse, KChartHandler.ToTimecourse(report.timecourse, report.flow, style), reassign: true); } } inSample.Consume(reactions, lastTime, lastState, netlist, style); return(outSample); }