diff --git a/ClassicGEC/ClassicGECBrowserIntegrationTests/ClassicGECBrowserIntegrationTests.fsproj b/ClassicGEC/ClassicGECBrowserIntegrationTests/ClassicGECBrowserIntegrationTests.fsproj new file mode 100644 index 0000000..ac6c2fe --- /dev/null +++ b/ClassicGEC/ClassicGECBrowserIntegrationTests/ClassicGECBrowserIntegrationTests.fsproj @@ -0,0 +1,24 @@ + + + + + netcoreapp3.1 + Exe + x64 + x64 + true + + + + + + + + + + + + + + + diff --git a/ClassicGEC/ClassicGECBrowserIntegrationTests/Program.fs b/ClassicGEC/ClassicGECBrowserIntegrationTests/Program.fs new file mode 100644 index 0000000..1651322 --- /dev/null +++ b/ClassicGEC/ClassicGECBrowserIntegrationTests/Program.fs @@ -0,0 +1,35 @@ +module Program + +open System +open System.Diagnostics +open Expecto +open canopy +open canopy.types +open canopy.classic +open Microsoft.Research.CRNIntegrationTestLib + +[] +let main args = + let (dir,groups,timeout,args) = Program.separateArgsDist args + + // Start a web server + printfn "Starting 'dotnet serve' on %s" dir + let serverProcess = Process.Start("dotnet", sprintf "serve -d %s" dir) + printfn "'dotnet serve' started, PID = %d" serverProcess.Id + + let result = + try + let url = "http://localhost:8080" + BrowserSetup.configureCanopy timeout + let tests = Tests.tests groups Tests.Worker url + Program.run args tests + finally + printfn "Shutting down 'dotnet serve'..." + try serverProcess.Kill() with _ -> () + canopy.classic.quit() + + if System.Diagnostics.Debugger.IsAttached then + printf "Press any key to exit" + System.Console.ReadKey() |> ignore + + result \ No newline at end of file diff --git a/ClassicGEC/ClassicGECBrowserIntegrationTests/paket.references b/ClassicGEC/ClassicGECBrowserIntegrationTests/paket.references new file mode 100644 index 0000000..0d34aef --- /dev/null +++ b/ClassicGEC/ClassicGECBrowserIntegrationTests/paket.references @@ -0,0 +1,9 @@ +group DOTNETCORE + +Canopy +Expecto +FSharp.Core +Selenium.WebDriver +Selenium.WebDriver.ChromeDriver +Selenium.WebDriver.GeckoDriver.Win64 +Selenium.WebDriver.MicrosoftWebDriver \ No newline at end of file diff --git a/ClassicGEC/ClassicGECCLI/App.config b/ClassicGEC/ClassicGECCLI/App.config new file mode 100644 index 0000000..5481afc --- /dev/null +++ b/ClassicGEC/ClassicGECCLI/App.config @@ -0,0 +1,103 @@ + + + + + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + \ No newline at end of file diff --git a/ClassicGEC/ClassicGECCLI/AssemblyInfo.fs b/ClassicGEC/ClassicGECCLI/AssemblyInfo.fs new file mode 100644 index 0000000..9eca9d1 --- /dev/null +++ b/ClassicGEC/ClassicGECCLI/AssemblyInfo.fs @@ -0,0 +1,41 @@ +namespace ClassicGECCLI.AssemblyInfo + +open System.Reflection +open System.Runtime.CompilerServices +open System.Runtime.InteropServices + +// Le informazioni generali relative a un assembly sono controllate dal seguente +// set di attributi. Modificare i valori di questi attributi per modificare le informazioni +// associate a un assembly. +[] +[] +[] +[] +[] +[] +[] +[] + +// Se si imposta ComVisible su false, i tipi in questo assembly non saranno visibili +// ai componenti COM. Se è necessario accedere a un tipo in questo assembly da +// COM, impostare su true l'attributo ComVisible per tale tipo. +[] + +// Se il progetto viene esposto a COM, il seguente GUID verrà utilizzato come ID della libreria dei tipi +[] + +// Le informazioni sulla versione di un assembly sono costituite dai quattro valori seguenti: +// +// Versione principale +// Versione secondaria +// Numero di build +// Revisione +// +// È possibile specificare tutti i valori oppure impostare valori predefiniti per i numeri relativi alla revisione e alla build +// utilizzando l'asterisco (*) come illustrato di seguito: +// [] +[] +[] + +do + () \ No newline at end of file diff --git a/ClassicGEC/ClassicGECCLI/ClassicGECCLI.fsproj b/ClassicGEC/ClassicGECCLI/ClassicGECCLI.fsproj new file mode 100644 index 0000000..30bbf0b --- /dev/null +++ b/ClassicGEC/ClassicGECCLI/ClassicGECCLI.fsproj @@ -0,0 +1,37 @@ + + + + netcoreapp3.1 + Exe + x64 + True + true + ClassicGEC + + + + + + + + + + + + + + ..\..\Lib\Oslo.FSharp\Oslo.FSharp.dll + + + + x64 + + + x64 + + + + + + + \ No newline at end of file diff --git a/ClassicGEC/ClassicGECCLI/Program.fs b/ClassicGEC/ClassicGECCLI/Program.fs new file mode 100644 index 0000000..ff96f20 --- /dev/null +++ b/ClassicGEC/ClassicGECCLI/Program.fs @@ -0,0 +1,145 @@ +module Microsoft.Research.GEC.Classic + +open Microsoft.Research.CliLibrary +open Microsoft.Research.CRNEngine +open Argu + +type GECArgs = + | Parts of string + | Reactions of string + | DE + | MG of int + | CE + +with + interface IArgParserTemplate with + member s.Usage = + match s with + | Parts _ -> "Parts database" + | Reactions _ -> "Reactions database" + | DE -> "Enumerate possible constructs from the given parts and constraints." + | MG _ -> "Generate CRN model for the nth device enumerated by GEC." + | CE -> "Export the generated CRN model into an SVG image." + + +let printSVG crn = + printf """ + + + """ + + crn + |> Crn.reactions_to_svg + |> Svg.to_element_string + |> printfn "%s" + + printfn "" + crn.all_species () + |> List.iter (fun s -> match crn.attributes.TryFind s.name with + | None -> () + | Some a -> printfn "%s = %s" a.name (System.Web.HttpUtility.HtmlEncode a.structure |> String.filter(fun c -> c <> '\"'))) + printfn "" + printfn "" + + +[] +let main args = + // Enforce invariant culture (prevents issues with decimal separators on international systems). + System.Threading.Thread.CurrentThread.CurrentCulture <- System.Globalization.CultureInfo.InvariantCulture + + // Start by extracting the parts and reactions databases from the argument list + let gec_parser = ArgumentParser.Create(programName = "ClassicGEC") + let gec_results = gec_parser.Parse(args, ignoreUnrecognized=true) + let dbParts = + match gec_results.TryGetResult Parts with + | Some f -> System.IO.File.ReadAllText f + | None -> Databases.defaultParts + let dbReactions = + match gec_results.TryGetResult Reactions with + | Some f -> System.IO.File.ReadAllText f + | None -> Databases.defaultReactions + + // Here we assume that we are only interested in the first solution, equivalent to how the GUI handles inference from a GEC program + let parser code = + match Main.parse code with + | Program.t.ClassicGec _ -> + let solveResult = GECEngine.solveGEC (ref false) code dbParts dbReactions + let firstSolution = GECEngine.getCrnAssignment solveResult.graph solveResult.solution 0 + firstSolution.model + | Program.t.LogicGec bundle -> + let cle = LogicGEC.cle + if gec_results.Contains DE + // generate all models + then + LogicGEC.enumerateDevices cle bundle.rules bundle.program + |> List.map (fun p -> p |> List.map (LogicGEC.Instruction.ToString cle) |> String.concat " | ") + |> List.iteri (fun i s -> printfn "Solution %i: %s" i s) + + // return empty graph + { task = None + nodes = Map.empty + edges = Map.empty + expanded =false } + + elif gec_results.Contains MG + then + let i = gec_results.GetResult MG + + // get ith model + let solutions = LogicGEC.enumerateDevices cle bundle.rules bundle.program + let max = solutions.Length + if 0 <= i && i < max + then + // generate ith model + let sol = solutions.Item i + let crn = LogicGEC.generateCRN cle bundle.rules sol + + // return IGraph with a single node + let crnSettings = Crn_settings.defaults.from_default_directive_list bundle.settings.directives + + if gec_results.Contains CE + then printSVG crn + else + printf "%s" (crn.to_string ()) + printfn "\n" + crn.all_species () + |> List.iter (fun s -> match crn.attributes.TryFind s.name with + | None -> () + | Some a -> printfn "%s = %s" a.name (a.structure |> String.filter (fun c -> c <> '"'))) + { task = None + nodes = Map.ofList [sprintf "Model_%i" i, Model.create crnSettings [crn]] + edges = Map.empty + expanded =false } + else failwithf "Input index %i is out of bound, the total number of solutions found is %i" i max + else failwith "Please specify whether to do construct assembly or model generation for the given Logic GEC program." + // Call generic CLI program + try + let ret = Program.main parser args + ret + with e -> + match e with + | :? Parser.Exception as e -> match e.Errors with + | [| {row=r; column=c; text=t} |] -> printfn "Parsing error at %i, %i: expecting %s" r c t + -1 + | _ -> raise e + | _ -> raise e \ No newline at end of file diff --git a/ClassicGEC/ClassicGECCLI/paket.references b/ClassicGEC/ClassicGECCLI/paket.references new file mode 100644 index 0000000..7decf61 --- /dev/null +++ b/ClassicGEC/ClassicGECCLI/paket.references @@ -0,0 +1,8 @@ +group DOTNETCORE + +#FsCheck +#FsUnit.xUnit +#xunit.core +#xunit.runner.console +#xunit.runner.visualstudio +FSharp.Core \ No newline at end of file diff --git a/ClassicGEC/ClassicGECCli.sln b/ClassicGEC/ClassicGECCli.sln new file mode 100644 index 0000000..ed030f5 --- /dev/null +++ b/ClassicGEC/ClassicGECCli.sln @@ -0,0 +1,118 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30225.117 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "CRNEngineDotNet", "..\CRNEngine\CRNEngineDotNet\CRNEngineDotNet.fsproj", "{AE45211A-A65D-4827-A1F9-07A20EB0F154}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "Filzbach.FSharp.Portable", "..\Filzbach.FSharp\Filzbach.FSharp.Portable.fsproj", "{2849368F-AC32-4D1E-B6D6-9C52261A5F2D}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "ParserCombinators", "..\ParserCombinators\ParserCombinators\ParserCombinators.fsproj", "{DD8FEC26-6D1D-4642-A706-04070B6D5494}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SundialsSolver15", "..\SundialsSolver\SundialsSolver15\SundialsSolver15.vcxproj", "{866880DC-BF1E-4C12-8238-72E7EFF44AFB}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "ReactionDiffusion", "..\PDESolvers\ReactionDiffusion\ReactionDiffusion.fsproj", "{529BEDB7-C73A-4A77-BFD9-1628D75C321B}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "CRNEngineTests", "..\CRNEngine\CRNEngineTests\CRNEngineTests.fsproj", "{8E0427CB-DD8F-46BE-A5BC-C02CF55F152D}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "CliLibrary", "..\CRNEngine\CliLibrary\CliLibrary.fsproj", "{EEF843A3-43F8-4E6B-AB7F-9ADE3A5AF022}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "ClassicGECDotNet", "ClassicGECDotNet\ClassicGECDotNet.fsproj", "{74DDCD31-9968-4B9B-8E5D-F07EDB7CE332}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "ClassicGECCLI", "ClassicGECCLI\ClassicGECCLI.fsproj", "{7B81A30F-F8A4-435D-A53A-9634C7A82686}" + ProjectSection(ProjectDependencies) = postProject + {866880DC-BF1E-4C12-8238-72E7EFF44AFB} = {866880DC-BF1E-4C12-8238-72E7EFF44AFB} + EndProjectSection +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "ClassicGECDotNetTests", "ClassicGECDotNetTests\ClassicGECDotNetTests.fsproj", "{EEBFA61A-4235-4C7C-B801-D44958F9D21C}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSBOLWrapper", "..\FSBOLWrapper\FSBOLWrapper\FSBOLWrapper.fsproj", "{7D875457-2116-4222-89E0-A048792E1213}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "MomentClosure", "..\MomentClosure\MomentClosure\MomentClosure.fsproj", "{40A82B6F-9447-4767-BD5B-8D870D3FACFF}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "CRNEngineCloudLib", "..\CRNEngine\CRNEngineCloudLib\CRNEngineCloudLib.fsproj", "{B0C5BB1E-CC0C-4D9E-A56A-82891A09653E}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "ClassicGECRunAllExamples", "ClassicGECRunAllExamples\ClassicGECRunAllExamples.fsproj", "{B9B04586-11D5-466C-8288-1BC62FC3C382}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "ClassicGECTests", "ClassicGECTests\ClassicGECTests.fsproj", "{5B3B81C7-5B7C-460D-B109-5E063133C0AD}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "RulesDSD", "..\RulesDSD\RulesDSD\RulesDSD.fsproj", "{22DF9340-8F96-4FBE-8001-675E2E55CB54}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {AE45211A-A65D-4827-A1F9-07A20EB0F154}.Debug|x64.ActiveCfg = Debug|Any CPU + {AE45211A-A65D-4827-A1F9-07A20EB0F154}.Debug|x64.Build.0 = Debug|Any CPU + {AE45211A-A65D-4827-A1F9-07A20EB0F154}.Release|x64.ActiveCfg = Release|Any CPU + {AE45211A-A65D-4827-A1F9-07A20EB0F154}.Release|x64.Build.0 = Release|Any CPU + {2849368F-AC32-4D1E-B6D6-9C52261A5F2D}.Debug|x64.ActiveCfg = Debug|x64 + {2849368F-AC32-4D1E-B6D6-9C52261A5F2D}.Debug|x64.Build.0 = Debug|x64 + {2849368F-AC32-4D1E-B6D6-9C52261A5F2D}.Release|x64.ActiveCfg = Release|x64 + {2849368F-AC32-4D1E-B6D6-9C52261A5F2D}.Release|x64.Build.0 = Release|x64 + {DD8FEC26-6D1D-4642-A706-04070B6D5494}.Debug|x64.ActiveCfg = Debug|Any CPU + {DD8FEC26-6D1D-4642-A706-04070B6D5494}.Debug|x64.Build.0 = Debug|Any CPU + {DD8FEC26-6D1D-4642-A706-04070B6D5494}.Release|x64.ActiveCfg = Release|Any CPU + {DD8FEC26-6D1D-4642-A706-04070B6D5494}.Release|x64.Build.0 = Release|Any CPU + {866880DC-BF1E-4C12-8238-72E7EFF44AFB}.Debug|x64.ActiveCfg = Debug|x64 + {866880DC-BF1E-4C12-8238-72E7EFF44AFB}.Debug|x64.Build.0 = Debug|x64 + {866880DC-BF1E-4C12-8238-72E7EFF44AFB}.Release|x64.ActiveCfg = Release|x64 + {866880DC-BF1E-4C12-8238-72E7EFF44AFB}.Release|x64.Build.0 = Release|x64 + {529BEDB7-C73A-4A77-BFD9-1628D75C321B}.Debug|x64.ActiveCfg = Debug|Any CPU + {529BEDB7-C73A-4A77-BFD9-1628D75C321B}.Debug|x64.Build.0 = Debug|Any CPU + {529BEDB7-C73A-4A77-BFD9-1628D75C321B}.Release|x64.ActiveCfg = Release|Any CPU + {529BEDB7-C73A-4A77-BFD9-1628D75C321B}.Release|x64.Build.0 = Release|Any CPU + {8E0427CB-DD8F-46BE-A5BC-C02CF55F152D}.Debug|x64.ActiveCfg = Debug|Any CPU + {8E0427CB-DD8F-46BE-A5BC-C02CF55F152D}.Debug|x64.Build.0 = Debug|Any CPU + {8E0427CB-DD8F-46BE-A5BC-C02CF55F152D}.Release|x64.ActiveCfg = Release|Any CPU + {8E0427CB-DD8F-46BE-A5BC-C02CF55F152D}.Release|x64.Build.0 = Release|Any CPU + {EEF843A3-43F8-4E6B-AB7F-9ADE3A5AF022}.Debug|x64.ActiveCfg = Debug|Any CPU + {EEF843A3-43F8-4E6B-AB7F-9ADE3A5AF022}.Debug|x64.Build.0 = Debug|Any CPU + {EEF843A3-43F8-4E6B-AB7F-9ADE3A5AF022}.Release|x64.ActiveCfg = Release|Any CPU + {EEF843A3-43F8-4E6B-AB7F-9ADE3A5AF022}.Release|x64.Build.0 = Release|Any CPU + {74DDCD31-9968-4B9B-8E5D-F07EDB7CE332}.Debug|x64.ActiveCfg = Debug|Any CPU + {74DDCD31-9968-4B9B-8E5D-F07EDB7CE332}.Debug|x64.Build.0 = Debug|Any CPU + {74DDCD31-9968-4B9B-8E5D-F07EDB7CE332}.Release|x64.ActiveCfg = Release|Any CPU + {74DDCD31-9968-4B9B-8E5D-F07EDB7CE332}.Release|x64.Build.0 = Release|Any CPU + {7B81A30F-F8A4-435D-A53A-9634C7A82686}.Debug|x64.ActiveCfg = Debug|x64 + {7B81A30F-F8A4-435D-A53A-9634C7A82686}.Debug|x64.Build.0 = Debug|x64 + {7B81A30F-F8A4-435D-A53A-9634C7A82686}.Release|x64.ActiveCfg = Release|x64 + {7B81A30F-F8A4-435D-A53A-9634C7A82686}.Release|x64.Build.0 = Release|x64 + {EEBFA61A-4235-4C7C-B801-D44958F9D21C}.Debug|x64.ActiveCfg = Debug|Any CPU + {EEBFA61A-4235-4C7C-B801-D44958F9D21C}.Debug|x64.Build.0 = Debug|Any CPU + {EEBFA61A-4235-4C7C-B801-D44958F9D21C}.Release|x64.ActiveCfg = Release|Any CPU + {EEBFA61A-4235-4C7C-B801-D44958F9D21C}.Release|x64.Build.0 = Release|Any CPU + {7D875457-2116-4222-89E0-A048792E1213}.Debug|x64.ActiveCfg = Debug|Any CPU + {7D875457-2116-4222-89E0-A048792E1213}.Debug|x64.Build.0 = Debug|Any CPU + {7D875457-2116-4222-89E0-A048792E1213}.Release|x64.ActiveCfg = Release|Any CPU + {7D875457-2116-4222-89E0-A048792E1213}.Release|x64.Build.0 = Release|Any CPU + {40A82B6F-9447-4767-BD5B-8D870D3FACFF}.Debug|x64.ActiveCfg = Debug|Any CPU + {40A82B6F-9447-4767-BD5B-8D870D3FACFF}.Debug|x64.Build.0 = Debug|Any CPU + {40A82B6F-9447-4767-BD5B-8D870D3FACFF}.Release|x64.ActiveCfg = Release|Any CPU + {40A82B6F-9447-4767-BD5B-8D870D3FACFF}.Release|x64.Build.0 = Release|Any CPU + {B0C5BB1E-CC0C-4D9E-A56A-82891A09653E}.Debug|x64.ActiveCfg = Debug|Any CPU + {B0C5BB1E-CC0C-4D9E-A56A-82891A09653E}.Debug|x64.Build.0 = Debug|Any CPU + {B0C5BB1E-CC0C-4D9E-A56A-82891A09653E}.Release|x64.ActiveCfg = Release|Any CPU + {B0C5BB1E-CC0C-4D9E-A56A-82891A09653E}.Release|x64.Build.0 = Release|Any CPU + {B9B04586-11D5-466C-8288-1BC62FC3C382}.Debug|x64.ActiveCfg = Debug|x64 + {B9B04586-11D5-466C-8288-1BC62FC3C382}.Debug|x64.Build.0 = Debug|x64 + {B9B04586-11D5-466C-8288-1BC62FC3C382}.Release|x64.ActiveCfg = Release|x64 + {B9B04586-11D5-466C-8288-1BC62FC3C382}.Release|x64.Build.0 = Release|x64 + {5B3B81C7-5B7C-460D-B109-5E063133C0AD}.Debug|x64.ActiveCfg = Debug|Any CPU + {5B3B81C7-5B7C-460D-B109-5E063133C0AD}.Debug|x64.Build.0 = Debug|Any CPU + {5B3B81C7-5B7C-460D-B109-5E063133C0AD}.Release|x64.ActiveCfg = Release|Any CPU + {5B3B81C7-5B7C-460D-B109-5E063133C0AD}.Release|x64.Build.0 = Release|Any CPU + {22DF9340-8F96-4FBE-8001-675E2E55CB54}.Debug|x64.ActiveCfg = Debug|x64 + {22DF9340-8F96-4FBE-8001-675E2E55CB54}.Debug|x64.Build.0 = Debug|x64 + {22DF9340-8F96-4FBE-8001-675E2E55CB54}.Release|x64.ActiveCfg = Release|x64 + {22DF9340-8F96-4FBE-8001-675E2E55CB54}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {CD1A1B77-DF19-4175-9D30-1B36C117F584} + EndGlobalSection +EndGlobal diff --git a/ClassicGEC/ClassicGECDotNet/AssemblyInfo.fs b/ClassicGEC/ClassicGECDotNet/AssemblyInfo.fs new file mode 100644 index 0000000..165ede8 --- /dev/null +++ b/ClassicGEC/ClassicGECDotNet/AssemblyInfo.fs @@ -0,0 +1,41 @@ +namespace ClassicGECDotNet.AssemblyInfo + +open System.Reflection +open System.Runtime.CompilerServices +open System.Runtime.InteropServices + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[] +[] +[] +[] +[] +[] +[] +[] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [] +[] +[] + +do + () \ No newline at end of file diff --git a/ClassicGEC/ClassicGECDotNet/ClassicGECDotNet.fsproj b/ClassicGEC/ClassicGECDotNet/ClassicGECDotNet.fsproj new file mode 100644 index 0000000..2872911 --- /dev/null +++ b/ClassicGEC/ClassicGECDotNet/ClassicGECDotNet.fsproj @@ -0,0 +1,54 @@ + + + + netstandard2.0 + x64 + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ..\..\Lib\Oslo.FSharp\Oslo.FSharp.dll + + + + \ No newline at end of file diff --git a/ClassicGEC/ClassicGECDotNet/Databases.fs b/ClassicGEC/ClassicGECDotNet/Databases.fs new file mode 100644 index 0000000..a7f5efd --- /dev/null +++ b/ClassicGEC/ClassicGECDotNet/Databases.fs @@ -0,0 +1,64 @@ +module Microsoft.Research.GEC.Databases + +let defaultParts = "i723017,pcr,codes(xylR;0.001) +i723024, pcr, codes(phzM;0.001) +e0040, pcr, codes(gfp;0.01) +c0099, pcr, codes(cviR;0.01) +i723025, pcr, codes(phzS;0.001) +i723028, pcr, codes(pca;0.001) +c0051, pcr, codes(cI;0.01) +c0040, pcr, codes(tetR;0.01) +c0080, pcr, codes(araC;0.01) +c0012, pcr, codes(lacI;0.01) +cunknown2, pcr, codes(unknown2;0.001) +c0061, pcr, codes(luxI;0.01) +c0062, pcr, codes(luxR;0.01) +c0079, pcr, codes(lasR;0.01) +c0078, pcr, codes(lasI;0.01) +cunknown3, pcr, codes(ccdB;0.005) +cunknown4, pcr, codes(ccdA;0.1) +i723020, prom, pos(toluene::xylR;0.001; 0.001; 1.0); con(0.0001) +r0051, prom, neg(cI; 1.0; 0.5; 0.00005); con(0.12) +r0040, prom, neg(tetR; 1.0; 0.5; 0.00005); con(0.09) +runknown1, prom, neg(unknown1; 1.0; 0.005; 0.001); con(0.04) +r0080, prom, neg(araC; 1.0; 0.000001; 0.0001); pos(araC::arabinose; 0.001; 0.001; 1.0); con(0.1) +r0011, prom, neg(lacI; 1.0; 0.5; 0.00005); con(0.1) +r0062, prom, pos(lasR::m3OC12HSL; 1.0; 0.8; 0.1); pos(luxR::m3OC6HSL; 1.0; 0.8; 0.1); con(0.01) +r0090, prom, pos(lasR::m3OC12HSL; 1.0; 0.8; 0.1); con(0.01) +r0099, prom, pos(cviR::m3OC6HSL; 1.0; 0.8; 0.1); con(0.01) +b0034, rbs, rate(0.1) +b0015, ter +cunknown5, pcr, codes(ccdA2; 10.0) +runknown5, prom, con(10.0) +j06504, pcr, codes(mCherry; 0.1) +prpr, device, components[pr; rbs34; eyfp; ter1; pr; rbs34; ecfp; ter1] +drPcat, device, components[pCat; rbs34; luxR; rbs34; lasR; ter1; pLas81; rbs34; eyfp; ter1; plux76; rbs34; ecfp; ter1] +drRS100S32, device, components[pTet; rbss100; luxR; ter1; pLac; rbs32; lasR; ter1; pLas81; rbs34; eyfp; ter1; plux76; rbs34; ecfp; ter1] +drR33S32, device, components[pTet; rbs33; luxR; ter1; pLac; rbs32; lasR; ter1; pLas81; rbs34; eyfp; ter1; plux76; rbs34; ecfp; ter1] +drR33S175, device, components[pTet; rbs33; luxR; ter1; pLac; rbsS175; lasR; ter1; pLas81; rbs34; eyfp; ter1; plux76; rbs34; ecfp; ter1] +relayP76LasI, device, components[pLux76; rbs900; lasI; l3s2p21] +relayP81LuxI, device, components[pLas81; rbs32; luxI; l3s2p21] +pBadYFP, device, components[pBad; rbs34; eyfp; l3s2p21] +lactonase, device, components[pBad; rbs34; aiia; l3s2p21]" + +let defaultReactions = "toluene + xylR ->{1.0} toluene::xylR +phzM ~ pca ->{1.0} metPCA +phzS ~ metPCA ->{1.0} pyo +luxR + m3OC6HSL ->{0.5} luxR::m3OC6HSL +lasR + m3OC12HSL ->{0.5} lasR::m3OC12HSL +cviR + m3OC6HSL ->{0.5} cviR::m3OC6HSL +cviR + m3OC12HSL ->{0.5} cviR::m3OC12HSL +luxI ~ ->{1.0} m3OC6HSL +lasI ~ ->{1.0} m3OC12HSL +ccdA ~ ccdB ->{1.0} +c[m3OC6HSL] ->{0.5} m3OC6HSL +m3OC6HSL ->{0.5} c[m3OC6HSL] +c[m3OC12HSL] ->{0.5} m3OC12HSL +m3OC12HSL ->{0.5} c[m3OC12HSL] +luxR::m3OC6HSL ->{1.0} luxR + m3OC6HSL +cviR::m3OC6HSL ->{1.0} cviR + m3OC6HSL +cviR::m3OC12HSL ->{1.0} cviR + m3OC12HSL +lasR::m3OC12HSL ->{1.0} lasR + m3OC12HSL +ccdA2 ~ ccdB ->{0.00001} +lacI + iptg ->{1.0} lacI::iptg +tetR + aTc ->{1.0} tetR::aTc" \ No newline at end of file diff --git a/ClassicGEC/ClassicGECDotNet/NumUtil.fs b/ClassicGEC/ClassicGECDotNet/NumUtil.fs new file mode 100644 index 0000000..04b60db --- /dev/null +++ b/ClassicGEC/ClassicGECDotNet/NumUtil.fs @@ -0,0 +1,24 @@ +module Microsoft.Research.GEC.NumUtil + +#if JavaScript + +open WebSharper +[] +#endif +let isNum s = let d = ref 0.0 in (System.Double.TryParse(s, d)) + +#if JavaScript +[] +#endif +let parse_double s = + let d = ref 0.0 in + if System.Double.TryParse(s, d) + then !d + else System.Double.NaN + +[] +let case_double f v s = + let d = parse_double s in + if System.Double.IsNaN d + then v + else f d \ No newline at end of file diff --git a/ClassicGEC/ClassicGECDotNet/TransCrn.fs b/ClassicGEC/ClassicGECDotNet/TransCrn.fs new file mode 100644 index 0000000..12e0a03 --- /dev/null +++ b/ClassicGEC/ClassicGECDotNet/TransCrn.fs @@ -0,0 +1,186 @@ +[] +module Microsoft.Research.GEC.TransCrn + +open Microsoft.Research.GEC.Trans +open Microsoft.Research.CRNEngine +open Api + +open Parser + +let separator = "_" + +let spReplace (str:string) = + str.Replace("::","_") + +let private newStr = // ref (fun () -> "Fixme") + let count = ref 0 + (fun () -> count := !count + 1; string !count) + +let rec newVar = + "sp" + newStr() + "_" + +let indexInitial (initial:Initial>) (str:string)= + //let newSpeciesName = newVar + ((spReplace initial.species.name) + separator + (spReplace str)) + let newSpeciesName = ((spReplace initial.species.name) + separator + (spReplace str)) + let newSpecies = Species.create(newSpeciesName) + let newInitial = {initial with species = newSpecies} + newInitial + +let indexReaction (reaction:Reaction) (str:string)= + let ncatalysts = reaction.catalysts |> Mset.map (fun (x) -> + //let newSpName = newVar + ((spReplace x.name) + separator + (spReplace str)) + let newSpName = ((spReplace x.name) + separator + (spReplace str)) + Species.create(newSpName)) + let nreactants = reaction.reactants |> Mset.map (fun (x) -> + //let newSpName = newVar + ((spReplace x.name) + separator + (spReplace str)) + let newSpName = ((spReplace x.name) + separator + (spReplace str)) + Species.create(newSpName)) + let nproducts = reaction.products |> Mset.map (fun (x) -> + //let newSpName = newVar + ((spReplace x.name) + separator + (spReplace str)) + let newSpName = ((spReplace x.name) + separator + (spReplace str)) + Species.create(newSpName)) + let nreaction = {reaction with catalysts = ncatalysts; reactants = nreactants; products=nproducts} + nreaction + +let compInitial (initial:Initial>) (str:string) = + //let newSpName = newVar + ((spReplace str) + separator + (spReplace initial.species.name)) + let newSpName = ((spReplace str) + separator + (spReplace initial.species.name)) + let newSpecies = Species.create(newSpName) + let newInitial = {initial with species = newSpecies} + newInitial + +let compReaction (reaction:Reaction) (str:string)= + let ncatalysts = reaction.catalysts |> Mset.map (fun (x) -> + //let newSpName = newVar + ((spReplace str) + separator + (spReplace x.name)) + let newSpName = ((spReplace str) + separator + (spReplace x.name)) + Species.create(newSpName)) + let nreactants = reaction.reactants |> Mset.map (fun (x) -> + //let newSpName = newVar + ((spReplace str) + separator + (spReplace x.name)) + let newSpName = ((spReplace str) + separator + (spReplace x.name)) + Species.create(newSpName)) + let nproducts = reaction.products |> Mset.map (fun (x) -> + //let newSpName = newVar + ((spReplace str) + separator + (spReplace x.name)) + let newSpName = ((spReplace str) + separator + (spReplace x.name)) + Species.create(newSpName)) + + let nreaction = {reaction with catalysts = ncatalysts; reactants = nreactants; products=nproducts} + nreaction + + + + +let createComplexSpecies (sp:string list) = + if sp.IsEmpty then + Species.create("") + else + //let species = sp |> List.reduce (fun a b -> (a + "-" + b)) |> Species.create + let species = sp |> List.reduce (fun a b -> + //newVar + ((spReplace a) + separator + (spReplace b))) |> Species.create + ((spReplace a) + separator + (spReplace b))) |> Species.create + species + +let createComplexSpeciesWithEmptyCheck (sp:string list) = + if sp.IsEmpty then + None + else + //let species = sp |> List.reduce (fun a b -> (newVar + ((spReplace a) + separator + (spReplace b)))) |> Species.create + let species = sp |> List.reduce (fun a b -> (((spReplace a) + separator + (spReplace b)))) |> Species.create + Some(species) + +let createComplexSpeciesList (sp:string list list) = + if sp.IsEmpty then + [] + else + sp + |> List.map (fun(x) -> createComplexSpeciesWithEmptyCheck(x)) + |> List.filter (fun x -> + match x with + | None -> false + | Some(_) -> true) + |> List.map (fun x -> x.Value) + +let createComplexCompSpecies (sp:string list) (comp:string)= + //let spName = sp |> List.reduce (fun a b -> (a + "-" + b)) + let spName = sp |> List.reduce (fun a b -> ((spReplace a) + separator + (spReplace b))) + //let species = Species.create(comp + "[" + spName + "]") + //let newSpName = newVar + ((spReplace comp) + separator + spName) + let newSpName = ((spReplace comp) + separator + spName) + let species = Species.create(newSpName) + species + +let rec createCrnReactions (lbsProg:tLBSProg) (reactions:Reaction<_,_,_> list) (initials:Initial<_,_> list) = + match lbsProg with + | LBSPar(prog1,prog2) -> + let (reactions1,initials1) = createCrnReactions prog1 [] [] + let (reactions2,initials2) = createCrnReactions prog2 [] [] + ((reactions1@reactions2@reactions),(initials1@initials2@initials)) + | LBSInitPop(initVal,value) -> + //let species = initVal |> List.reduce (fun a b -> (newVar + (spReplace a) + separator + (spReplace b))) |> Species.create + let species = initVal |> List.reduce (fun a b -> ((spReplace a) + separator + (spReplace b))) |> Species.create + let initial = Initial.create(false, (Expression.Float value), species, None, None) + (reactions,initial::initials) + | LBSCopy(index,prog) -> + let (reactions1,initials1) = createCrnReactions prog [] [] + let rinitials = initials1 |> List.map (fun(x) -> indexInitial x (index.ToString())) + let rreactions = reactions1 |> List.map (fun(x) -> indexReaction x (index.ToString())) + (rreactions@reactions,rinitials@initials) + | LBSComp(comp,prog) -> + let (reactions1,initials1) = createCrnReactions prog [] [] + let rinitials = initials1 |> List.map (fun(x) -> compInitial x comp) + let rreactions = reactions1 |> List.map (fun(x) -> compReaction x comp) + (rreactions@reactions,rinitials@initials) + | LBSCompDec(comp,prog) -> + let (reactions1,initials1) = createCrnReactions prog [] [] + let rinitials = initials1 |> List.map (fun(x) -> compInitial x comp) + let rreactions = reactions1 |> List.map (fun(x) -> compReaction x comp) + (rreactions@reactions,rinitials@initials) + | LBSReac(enzymes,reactants,products,rate,massAction) -> + let rreactants = createComplexSpeciesList(reactants) //|> Mset.from_list + let renzymes = createComplexSpeciesList(enzymes) //|> Mset.from_list + let rproducts = createComplexSpeciesList(products) //|> Mset.from_list + if massAction then + //check if anything is empty + let reaction = Reaction.create(renzymes, rreactants, !-> (Expression.Key rate ), rproducts) + (reaction:: reactions,initials) + else + (*let baseIdParserNoSpaces = (Parser.many1Satisfy Parser.isLetter .>>. Parser.manySatisfy (fun c -> Parser.isLetter c || Parser.isDigit c || c = '_'|| c = '-' || c = '\'') |>> fun (a,b) -> a + b) "an identifier" + let baseIdParser = baseIdParserNoSpaces .>> Parser.spaces + let speciesparser = baseIdParser |>> fun (x) -> (Species.create(x)) + let speciesExpParser = Expression.parse speciesparser + let exp_from_string (s:string) = Parser.from_string speciesExpParser s + let exp = exp_from_string rate + let reaction = Reaction.create_functional renzymes rreactants exp None rproducts + (reaction:: reactions,initials)*) + (reactions,initials) + | LBSDegReac(reactants,rate) -> + let rreactants = createComplexSpeciesList(reactants) + let reaction = Reaction.create([], rreactants, !-> (Expression.Key rate), []) + (reaction::reactions,initials) + | LBSTrans(complex1,complex2,compartment,rate,direction) -> + if direction = Ast.In then + let reaction = Reaction.create([], [(createComplexSpecies complex1)], !-> (Expression.Key rate), [(createComplexCompSpecies complex2 compartment)]) + (reaction::reactions,initials) + else + let reaction = Reaction.create([], [(createComplexCompSpecies complex1 compartment)], !-> (Expression.Key rate), [(createComplexSpecies complex2)]) + (reaction::reactions,initials) + | LBSReacAbstraction((enzymes,reactants,products,rate,massAction),prog1) -> + let rreactants = createComplexSpeciesList(reactants) //|> Mset.from_list + let renzymes = createComplexSpeciesList(enzymes) //|> Mset.from_list + let rproducts = createComplexSpeciesList(products) //|> Mset.from_list + let (reactions1,initials1) = createCrnReactions prog1 [] [] + if massAction then + let reaction = Reaction.create(renzymes, rreactants, !-> (Expression.Key rate), rproducts) + ((reaction::reactions1)@reactions,initials1@initials) + else + (reactions1@reactions,initials1@initials) + + | _ -> ([],[]) //This is basically LBSNil, + + + + +let create (lbsProg:tLBSProg) = + let (reactions,initials) = createCrnReactions lbsProg List.empty List.empty + let (crn:Crn) = {Crn.empty with reactions = reactions; initials = initials} + let gcrn = Crn.group_reactions crn + gcrn diff --git a/ClassicGEC/ClassicGECDotNet/app.config b/ClassicGEC/ClassicGECDotNet/app.config new file mode 100644 index 0000000..2bc077c --- /dev/null +++ b/ClassicGEC/ClassicGECDotNet/app.config @@ -0,0 +1,13 @@ + + + + + + + + + True + + + + \ No newline at end of file diff --git a/ClassicGEC/ClassicGECDotNet/ast.fs b/ClassicGEC/ClassicGECDotNet/ast.fs new file mode 100644 index 0000000..244c19c --- /dev/null +++ b/ClassicGEC/ClassicGECDotNet/ast.fs @@ -0,0 +1,158 @@ +(* +Defines the abstract syntax tree data types for GEC. +Also defines compiler exceptions. + +Author: Michael Pedersen. +Copyright Microsoft Research, 2009. +*) + +[] +module Microsoft.Research.GEC.Ast +//open Microsoft.Research.ModellingEngine +open Microsoft.Research.CRNEngine + +// exceptions for compilation errors. +//type pos = {l1 : int; c1 : int; l2 : int; c2 : int} +//exception CompilerEx of string +//exception CompilerExPos of string * pos + +// values can be names or variables (collectively identifiers), floats or wild cards; +// or more recently, algebraic expressions for functional rate expressions in promoter properties. +type value = + | IdVal of string + | FloatVal of float + | WildCardVal + | AlgebraicExp of aexp + +// in order to parse actual parameter lists without conflicts, we allow "abstract complexes" +// to contain any value, including floats, and rely on a type system to filter out bad uses. +and abstractComplex = value list + +// properties: +and prop = string * abstractComplex list + +// arithmetic expressions (very basic for now): +and aexp = //| ValAExp of value + | FloatAExp of float + | IdAExp of string + | PlusAExp of aexp * aexp + | MinusAExp of aexp * aexp + | MulAExp of aexp * aexp + | DivAExp of aexp * aexp + | PowAExp of aexp * aexp + +// direction for transport reactions (in or out of compartment): +type direction = In | Out + +// predicate operators for quantitative constraints: +type op = Gt | Lt | Eq + +// programmes: +type prog = + | Nil + | Brick of value * string * prop list + | Device of string + | Reac of abstractComplex list * abstractComplex list * abstractComplex list * value * bool + | Trans of abstractComplex * abstractComplex * string * value * bool * direction + | TemplateInv of string * abstractComplex list + | Seq of prog * prog + | Par of prog * prog + | Comp of string * prog + | New of string * prog + | TemplateDef of string * string list * prog * prog + | Constraint of aexp * op * aexp + | Rate of value * float + | InitPop of abstractComplex * float + | Copy of int * prog * bool * bool // first bool indicates par/seq, second bool indicates simonly + +// directives: +type gecSimpleSpecies = CompartmentSpecies of string * abstractComplex + | SimpleSpecies of abstractComplex +type gecSpecies = gecSimpleSpecies list +type gecNumPoints = Default | IntPoints of int | AllPoints +type kinetics = + | Contextual_kinetics + | Stochastic_kinetics + | Deterministic_kinetics +let string_of_kinetics = function + | Contextual_kinetics -> "contextual" + | Stochastic_kinetics -> "stochastic" + | Deterministic_kinetics -> "deterministic" +type directive = + | SAMPLE of float * gecNumPoints + | TIME of Time + | CONCENTRATION of Concentration + | ABSTOLERANCE of float + | RELTOLERANCE of float + | SCALE of float + | PLOT of gecSimpleSpecies Key Expression.t list + | KINETICS of kinetics + +(* ************************************************************************************************************ *) + +(* String representation of a species complex. *) +let complexString xs = Lib.string_of_list Lib.id "::" xs + +(* String representation of a species in a compartment. *) +let compartmentString c x = c + Lib.brack x + +(* String representation of an operator. *) +let stringOfOp = function + | Gt -> ">" + | Lt -> "<" + | Eq -> "=" + +(* String representation of an expression. *) +let rec stringOfAExp = function + | FloatAExp f -> Lib.display_float f + | IdAExp id -> id + | PlusAExp (e1,e2) -> (stringOfAExp e1) + "+" + (stringOfAExp e2) + | MinusAExp (e1,e2) -> (stringOfAExp e1) + "-" + (stringOfAExp e2) + | MulAExp (e1,e2) -> (stringOfAExp e1) + "*" + (stringOfAExp e2) + | DivAExp (e1,e2) -> (stringOfAExp e1) + "/" + (stringOfAExp e2) + | PowAExp (e1,e2) -> (stringOfAExp e1) + "^" + (stringOfAExp e2) + + +(* String representation of an expression. *) +let rec lbsStringOfAExp = function + | FloatAExp f -> Lib.display_float f + | IdAExp id -> id + | PlusAExp (e1,e2) -> "(" + (lbsStringOfAExp e1) + "+" + (lbsStringOfAExp e2) + ")" + | MinusAExp (e1,e2) -> "(" + (lbsStringOfAExp e1) + "--" + (lbsStringOfAExp e2) + ")" + | MulAExp (e1,e2) -> (lbsStringOfAExp e1) + "*" + (lbsStringOfAExp e2) + | DivAExp (e1,e2) -> (lbsStringOfAExp e1) + "/" + (lbsStringOfAExp e2) + | PowAExp (e1,e2) -> (lbsStringOfAExp e1) + "^" + (lbsStringOfAExp e2) + +(* String representation of a value. *) +let stringOfValue = function + | IdVal x -> x + | FloatVal f -> Lib.display_float f + | WildCardVal -> "_" + | AlgebraicExp aexp -> stringOfAExp aexp + +(* String representation of an abstract complex. *) +let abstractComplexString vs = Lib.string_of_list stringOfValue "::" vs + +(* Are two complexes equal? *) +let complexesEqual (xs:string list) (ys:string list) = Lib.is_permutation (=) xs ys + +(* Produce a string representation of a "gecSpecies". *) +let stringOfGecSimpleSpecies (g:gecSimpleSpecies) : string = + (* Produce a string representation of a "gecSimpleSpecies". *) + let stringOfGecSimpleSpecies (g:gecSimpleSpecies) : string = + match g with + | SimpleSpecies ac -> abstractComplexString ac + | CompartmentSpecies (c,ac) -> compartmentString c (abstractComplexString ac) + stringOfGecSimpleSpecies g + +(* Produce the source code representation of a directive. *) +let stringOfDirective (d:directive) : string = + match d with + | SAMPLE(f,io) -> "directive sample " + (Lib.display_float f) + (match io with Default -> "" | IntPoints i -> " " + (string i) | AllPoints -> " all") + | TIME u -> "directive time " + u.to_string + | CONCENTRATION u -> "directive concentration " + u.to_string + | ABSTOLERANCE f -> "directive abstolerance " + (Lib.display_float f) + | RELTOLERANCE f -> "directive reltolerance " + (Lib.display_float f) + | SCALE f -> "directive scale " + (Lib.display_float f) + | PLOT ps -> "directive plot " + (Lib.string_of_list (Expression.to_string (Key.to_string stringOfGecSimpleSpecies)) "; " ps) + | KINETICS k -> "directive kinetics " + string_of_kinetics k diff --git a/ClassicGEC/ClassicGECDotNet/characterization.fs b/ClassicGEC/ClassicGECDotNet/characterization.fs new file mode 100644 index 0000000..5cca4c8 --- /dev/null +++ b/ClassicGEC/ClassicGECDotNet/characterization.fs @@ -0,0 +1,1455 @@ +module GEC.Characterization + +open Microsoft.Research.Filzbach //MCMC inference +open System.Collections.Generic +open System +open System.Text +open System.Text.RegularExpressions + + + +type GrowthModels = Gompertz = 0 | Richards = 1 | Logistic = 2 +type GrowthModelType = { + mu: float; + lag: float; + tm: float; + K: float; + res: int; + model: (int * float -> float); +} +type NoiseModel = Linear=0| Squared=1 + +type DataTypes = Data | Gain | Blank | Negative +type Well = { + Row: char; + Col: int; + Content: string; + Colony: string; + DataType: DataTypes; + Condition: Map; + + Signals: double[][]; + SignalNames: string[]; + T: double[]; + + GrowthModel: GrowthModelType option; + Filter: int -> bool; //given an signal array index, is this part of the selection + SteadyStates: Map<(string*string),(double*double)>; + Activity: Map<(string*string),double>; +} +type Plate = { + Name: string; + Data: seq; + Blanks: Map; + + Conditions: Map; + Cname: string; + C: double[]; //conditions + Properties: double[][][]; //computed or measured properties + PropertyNames: string[]; //name of properties + + Gain: Map; + log:string; +} + +let EmptyPlate = {Name=""; Data = Seq.empty; Blanks = Map.empty; Conditions = Map.empty; C = [||];Properties=[||]; PropertyNames=[||]; Cname=""; Gain = Map.empty; log=""} +let EmptyWell = { + Row = ' '; + Col = -1; + Content = ""; + Colony = ""; + DataType = DataTypes.Blank; + Condition = Map.empty; + Signals = Array.empty; + SignalNames = Array.empty; + T = Array.empty; + GrowthModel = None; + Filter = (fun x -> true); + SteadyStates = Map.empty; + Activity = Map.empty; +} +type Parameter = { + pname: string; + value: double; + dist: double[]; + log: bool; +} +type ModelTypes = + | Constitutive = 0 + | Linear = 1 + | Michaelis_Menten_Activation = 2 + | Michaelis_Menten_Repression = 3 + | Michaelis_Menten_General = 4 + | Dimer_Activation = 5 + | Dimer_Repression = 6 + | Dimer_General = 7 + | Hill_Activation = 8 + | Hill_Repression = 9 + | Hill_General = 10 + | Sequential_Binding = 11 + +type ResponseTypes = + | EYFP_ECFP = 0 + | EYFP_OD = 1 + | ECFP_OD = 2 + | mu = 3 + | K = 4 + | lag = 5 + | EYFP_mRFP1 = 6 + | ECFP_mRFP1 = 7 + | mRFP1_OD = 8 + +type Model = { + modelType: ModelTypes; + AIC: double; + BIC: double; + CIC: double; //rename this information criterion to the right abbreviation + model: int * double -> double; + res: int; + parameters: Parameter[]; + X: double[]; + bayestable: List; +} + + +let string_of_response response = match response with + | ResponseTypes.EYFP_ECFP -> "EYFP/ECFP" + | ResponseTypes.EYFP_OD -> "EYFP/OD" + | ResponseTypes.ECFP_OD -> "ECFP/OD" + | ResponseTypes.mu -> "mu" + | ResponseTypes.K -> "K" + | ResponseTypes.lag -> "lag" + | ResponseTypes.EYFP_mRFP1 -> "EYFP/mRFP1" + | ResponseTypes.ECFP_mRFP1 -> "ECFP/mRFP1" + | ResponseTypes.mRFP1_OD -> "mRFP1/OD" + + + +let Interp (X:double[]) (Y:double[]) (Z:double[]) = + let InterpVal xt = + match Array.tryFindIndex(fun x -> x=xt) X with + | Some n -> Y.[n] //exact match -> return the value + | None -> //no exact match, interpolate + let (P,N) = Array.fold2(fun (P,N) x y -> + let dx = x-xt in + if dx>0.0 then ((dx,y)::P,N) + else (P,(dx,y)::N)) ([],[]) X Y in + let (x1,y1) = Seq.maxBy(fun (x,y) -> x) N in //largest negative element (on the left of target) + let (x2,y2) = Seq.minBy(fun (x,y) -> x) P in //smallest positive element (on the right of target) + + let (x1,x2) = (x1+xt, x2+xt) in //expresss xt as a linear combination + let a = (xt - x2)/(x1-x2) in + let y = a*y1 + (1.0-a)*y2 in + y + in + Array.map(fun x -> InterpVal x) Z + + + +let LoadPlate (data:string) = + let ParseLine (str: string list) = + let fields = str.Head.Split([|','|]) |> Array.toList + (fields, str.Tail) + + let rec Skip n l = + match (n, l) with + | 0, _ -> l + | _, [] -> [] + | n, _ :: ls -> Skip (n-1) ls + in + + //load the time and ids information from the header files; returns (signal name * id * time in min) + let ParseHeaders (hdr:string list) = + let regex = new Regex(@"\((?.*)\)\s*(?\d+)\s*-\s*(?\d+)\s*h\s*((?\d+)\s*min)?", RegexOptions.IgnoreCase) in + Seq.map(fun x-> let mc = regex.Match(x) + let signal = mc.Groups.Item("signal").ToString() + let id = (int)(mc.Groups.Item("id").ToString()) + let h = (double)(mc.Groups.Item("h").ToString()) + let m = let ms = mc.Groups.Item("m").ToString() + if (ms <> "") then (double)ms else 0.0 + signal,id , h * 60.0 + m) (Skip 5 hdr) //The number of skips has to match the meta-data columns of the file + + + let data = data.Replace('\r',' ') in + let lines = data.Split([|'\n'|]) |> Array.toList in + let (headers, lines) = ParseLine(lines) in //read in the headers line + let headers = ParseHeaders(headers) in //parse the headers and extract time and samples information + let lines = Skip 1 lines in //get rid of averages line + let lines = Seq.fold(fun acc (x:string) -> if x.Replace(',',' ').Trim()="" then acc else acc@[x]) [] lines in //remove empty lines + //parse the wells and data + let data = Seq.map(fun (line:string) -> + let fields = line.Split(',') |> List.ofArray in //String.split([',']) line in + match fields with + | content::colony::col::row::cond::data -> + let signals = Seq.map2(fun (s,_,t) v -> (s,t,(double)v)) headers data + |> Seq.groupBy(fun (s,t,v) -> s) + |> Seq.map(fun (k,x) -> (k,Seq.map(fun (s,t,v) -> t,v) x |> Seq.sortBy(fun (t,v) -> t))) + |> Seq.map(fun (k,x) -> (k,Seq.map(fun (t,_) -> t) x |> Array.ofSeq , Seq.map(fun (_,y) -> y) x |> Array.ofSeq)) in + let (_,T,OD) = Seq.find(fun (s:string,_,_) -> s.ToLower()="od") signals in + let signals = Seq.map(fun (s,Tc,S) -> if Tc=T then (s,S) + else (s, Interp Tc S T) + ) signals in //TODO: THROW A WARNING WHEN INTERPOLATING + let condition = Seq.fold(fun acc (x:string) -> + if (x.Length>0) then + let y = x.Split '=' in + (y.[0],Double.Parse(y.[1]))::acc + else + acc + ) [] (cond.Split(';')) + |> Map.ofSeq in + let dT = if content.ToLower().Contains("gain") then Gain + else if content.ToLower().Contains("blank") then Blank + else if content.ToLower().Contains("negative") then Negative + else Data in + + let names = Seq.map(fun (n,_) ->n) signals |> Array.ofSeq in + let signals = Seq.map(fun (_,s) ->s) signals |> Array.ofSeq in + let row = row.Trim().[0] in + let col = Convert.ToInt32(col) in + { + EmptyWell with + Row = row; + Col = col; + Content = content; + Colony = colony; + DataType = dT; + Condition = condition; + Signals = signals; + SignalNames = names; + T = T; + } + //| _ -> failwith "Headers in the wrong format." + ) lines in + let conditions = Seq.fold (fun ag well -> Seq.append(ag) (well.Condition|>Map.toSeq)) Seq.empty data + |> Seq.groupBy fst + |> Seq.map(fun (c,vals) -> c, Seq.map snd vals |> Seq.distinct |> Array.ofSeq) + |> Map.ofSeq in + + {EmptyPlate with Data=data; Conditions=conditions} + + +let getSignal(well:Well, str:string) = + match Array.tryFindIndex(fun x -> x=str) well.SignalNames with + |Some n -> (well.T,well.Signals.[n]) + |None -> (Array.empty, Array.empty) +let getSignals(well:Well, s1:string, s2:string) = + match (getSignal(well,s1), getSignal(well,s2)) with + |((X1,Y1), (X2,Y2)) when not (Array.isEmpty(Y1)) && not (Array.isEmpty(Y2)) -> (Y1,Y2) + |_ -> (Array.empty, Array.empty) + + + +let getFluorescence (well:Well) = + let namedSignals = Array.map2(fun name signal -> (name,signal)) well.SignalNames well.Signals + |> Seq.filter(fun (name,signal) -> not (name="OD")) in //ignore the growth signal + (well.T,namedSignals) + + +let getFOd (well:Well) = + let namedSignals = Array.map2(fun name signal -> (name,signal)) well.SignalNames well.Signals in + let F = Seq.filter(fun (n,_) -> not (n = "OD")) namedSignals in + let OD = snd (Seq.find(fun (n,_) -> n="OD") namedSignals) in + (OD,F) + +let getFF (well:Well, chan:string) = + let namedSignals = Array.map2(fun name signal -> (name,signal)) well.SignalNames well.Signals in + let F = Seq.filter(fun (n,_) -> not (n = chan || n="OD")) namedSignals in + let X = snd (Seq.find(fun (n,_) -> n=chan) namedSignals) in + (X,F) + + + +let MergePlates (plate1:Plate, plate2:Plate) = + let name = "Merged " + plate1.Name + " and " + plate2.Name in + let data = Seq.append plate1.Data plate2.Data in + let conditions = Map.fold (fun s k v -> + match Map.tryFind k s with + | Some v' -> Map.add k (Array.ofSeq (Seq.distinct (Seq.append (Seq.ofArray v) (Seq.ofArray v')))) s + | None -> Map.add k v s) plate1.Conditions plate2.Conditions in + { EmptyPlate with Name = name; Data = data; Conditions = conditions } + +let Median (vals:seq) = + let sorted = Seq.sort vals |> List.ofSeq in + let n = Seq.length sorted in + if n % 2 =0 then + sorted.[n/2] + else + let mp = Convert.ToDouble(n)/2.0 in + let l = Convert.ToInt32(floor(mp/2.0)) in + let h = Convert.ToInt32(ceil(mp/2.0)) in + (sorted.[l] + sorted.[h]) /2.0 + + + +(* Linear least squares *) +let LsqLin (Xi:double[]) (Yi:double[]) = + let sum X = Array.fold(fun s x -> s + x) 0.0 X + let ave X = (sum X)/((float)(Array.length X)) + let mx = ave Xi + let my = ave Yi + let S1 = Array.map2(fun x y -> (x-mx)*(y-my)) Xi Yi |> sum + let S2 = Array.map(fun x-> Math.Pow((x-mx),2.0)) Xi |> sum + let a = if S2 = 0.0 then failwith "Linear regression failed because of divide by zero." else S1/S2 + let b = my - a * mx + (a,b) + + +let CorrectBlanks (plate:Plate) = + let ComputeBlanks (plate:Plate) = + let blanks = Seq.filter(fun x -> x.DataType = DataTypes.Blank) plate.Data in + let signals = Seq.fold(fun acc well -> Array.map2(fun name signal -> (name,signal)) well.SignalNames well.Signals |> Seq.append(acc)) Seq.empty blanks + |> Seq.groupBy(fun (s,x) ->s) + |> Seq.map(fun (s,x) -> (s, Seq.fold(fun acc (_,v) -> Seq.append(acc) v) Seq.empty x|> Median)) //compute the median of the background + //|> Seq.map(fun (s,x) -> (s, Seq.fold(fun acc (_,v) -> Seq.append(acc) v) Seq.empty x|> Seq.average)) //compute the average of the background + //|> Seq.filter(fun (s,_) -> not (s = "OD")) //use this to avoid the correction of OD data + //|> Seq.filter(fun (s,_) -> (s = "OD")) //use this to only allow the correction of OD data + |> Map.ofSeq in + {plate with Blanks=signals} //Check this? + in + let BlankCorrect (blanks:Map) (well:Well) = + {well with Signals = Array.map2(fun name signal -> if blanks.ContainsKey(name) then + let df = blanks.Item(name) in + Array.map(fun x -> x - df) signal + else + signal + ) well.SignalNames well.Signals} + in + let plate = ComputeBlanks plate in + let bc = BlankCorrect plate.Blanks in + let newData = Seq.map(fun w -> bc w) plate.Data |> Seq.cache in + {plate with Data = newData;} + + + +// let CorrectBlanksAndGain (plate:Plate) = +// let ComputeBlanks (plate:Plate) = +// let blanks = Seq.filter(fun x -> x.DataType = DataTypes.Blank) plate.Data in +// let signals = Seq.fold(fun acc well -> Array.map2(fun name signal -> (name,signal)) well.SignalNames well.Signals|> Seq.append(acc)) Seq.empty blanks +// |> Seq.groupBy(fun (s,x) ->s) +// |> Seq.map(fun (s,x) -> (s, Seq.fold(fun acc (_,v) -> Seq.append(acc) v) Seq.empty x|> Median)) +// //|> Seq.filter(fun (s,_) -> not (s = "OD")) //use this to avoid the correction of OD data +// |> Map.ofSeq in +// {plate with Blanks=signals} +// in +// let BlankCorrect (blanks:Map) (well:Well) = +// {well with Signals = Array.map2(fun name signal -> if blanks.ContainsKey(name) then +// let df = blanks.Item(name) in +// if name="OD" then +// Array.map(fun x -> x - df) signal //use the original (subtraction) for OD [no gain] +// else +// Array.map(fun x -> x/df-1.0) signal //use the modified procedures for all other (fluorescent) channels +// else +// signal) well.SignalNames well.Signals} +// in +// let plate = ComputeBlanks plate in +// let bc = BlankCorrect plate.Blanks in +// let newData = Seq.map(fun w -> bc w) plate.Data |> Seq.cache in +// {plate with Data = newData;} + + + + + +let Add (s1:double[]) (s2:double[]) = Array.map2(fun x y -> x+y) s1 s2 +let Div (s:double[]) (n:double) = Array.map(fun x -> x/n) s + +let CorrectAutofluorescence (plate:Plate) = + let negatives = Seq.filter(fun x -> x.DataType = DataTypes.Negative) plate.Data |> Seq.map(fun w -> w) in + + if Seq.isEmpty negatives then //no autofluorescence information was found, proceed without correcting but raise a message + //TO DO: Include a delegate for displaying information to the user + {plate with log=plate.log + "\n No autofluorescence callibration was performed!\n";} + else +// let T = (Seq.head negatives).T in +// let autofl = Seq.fold(fun acc well -> let ns = (Seq.map2(fun name signal -> (name,Interp well.T signal T)) well.SignalNames well.Signals) in Seq.concat([acc; ns])) Seq.empty negatives +// |> Seq.groupBy(fun (s,x) ->s) +// |> Seq.map(fun (s,x) -> (s,Seq.map(fun (_,y) -> y) x)) +// |> Seq.map(fun (s,x) -> +// let n = Convert.ToDouble(Seq.length x) in +// (s,Seq.fold(fun acc y -> Add acc (Div y n)) (Div (Seq.head x) n) (Seq.skip 1 x))) +// |> Map.ofSeq +// in +// let AutoCorrect (well:Well) = +// {well with Signals = Array.map2(fun name signal -> if not (name="OD") then +// let Df = Interp T (autofl.Item(name)) well.T in +// Array.map2(fun x df -> x - df) signal Df +// else +// signal) well.SignalNames well.Signals} +// in +// let newData = Seq.map(fun w -> AutoCorrect w) plate.Data |> Seq.cache in +// {plate with Data = newData} +// + let autofl = Seq.map(fun w -> let od= getSignal(w,"OD") |> snd |> Seq.mapi(fun i x -> (i,x)) |> Seq.filter(fun (i,x) -> w.Filter(i)) |> Seq.map(fun (i,x) -> x) |> Array.ofSeq in + Seq.map2(fun name signal -> if not (name="OD") then + let signal = signal |> Seq.mapi(fun i x -> (i,x)) |> Seq.filter(fun (i,x) -> w.Filter(i)) |> Seq.map(fun (i,x) -> x) |> Array.ofSeq in + (name,od,signal) + else + ("",[||],[||]) + ) w.SignalNames w.Signals + |> Seq.filter(fun (n,_,_) -> not (n="")) + ) negatives + |> Seq.fold(fun acc s -> Seq.append(acc) s) Seq.empty + |> Seq.groupBy(fun (s,_,_) ->s) + |> Seq.map(fun (s,x) -> (s,Seq.fold(fun (OD,F) (_,od,f) -> (Seq.append(OD) od,Seq.append(F) f)) (Seq.empty,Seq.empty) x)) + |> Seq.map(fun (s,(OD,F)) -> (s,LsqLin (OD |> Array.ofSeq) (F |> Array.ofSeq))) + |> Map.ofSeq + in + let AutoCorrect (well:Well) = + {well with Signals = let od = getSignal(well,"OD") |> snd in + Array.map2(fun name signal -> + if not (name="OD") then + let (a,b) = autofl.Item(name) in + Array.mapi(fun i x -> x - a*od.[i]+b) signal + else + signal) well.SignalNames well.Signals} + in + let newData = Seq.map(fun w -> AutoCorrect w) plate.Data |> Seq.cache in + {plate with Data = newData} + + + + + + + + + + + + + + + + //model parameters, Filzbach parameters, likelihood (param->double) +//Replace this with the built-in Filzbach scriptable +type Filzbach(mparam,likefn) = + class + inherit ModelBase(new System.Random()) + override this.setup_data() = () + override this.setup_parameters() = + Seq.iter(fun (name,lb,ub,v,t) -> this.parameter_create(name,lb,ub,v,t,0,0)) mparam; + override this.likelihood() = + let cv = Seq.map(fun (name,_,_,_,_) -> this.cv(name)) mparam + |> Seq.cache in + let log_like = likefn cv in + this.set_metr_ltotnew(log_like); + this.inc_metr_number_ok(1.0); + member this.ltotmax = 0.0; + member this.Run(fparam) = + this.setup_data(); + this.setup_parameters(); + let burnin,eststeps,burnin2,mleexp = fparam in + this.runmcmc(burnin,eststeps,burnin2,mleexp, null, null, null,null); + this.params_set_to_MLE(); //or set_to_posterior_mean? + Seq.map(fun (name,_,_,_,_) -> this.cv(name)) mparam + |> Seq.cache + member this.GetParamHist() = this.bayestable + end + + + + + + +//growth models, inverse and derivatives +(* +Gompertz model is reparametrized as in: +Zwietering MH, Jongenburger I, Rombouts FM, Van’t Riet K (1990) +Modelling of the bacterial growth curve. +Appl Environ Microbiol 56:1875–1881 +*) +let Gompertz(mu, K, lag) t = K*exp(-exp((lag-t)*(mu*exp(1.0)/K)+1.0)) //Gompertz growth model. +//let GompInv(mu, K, lag) od = lag-(log(-log(od/K))-1.0)*K/(mu*exp(1.0)) //Inverse Gompertz function +//let GompDer(mu, K, lag) t = mu*exp(exp(1.0)*mu*(lag-t)/K-exp(exp(1.0)*mu*(lag-t)/K+1.0)+2.0) //Gompertz derivative function +let Richards(mu,K,lag,v) t = + // let A = Math.Pow(mu/K*(1.0+v),(1.0+1.0/v))*(lag-t) in + let A = mu/K*Math.Pow((1.0+v),(1.0+1.0/v))*(lag-t) in + let B = 1.0+v*exp(1.0+v)*exp(A) in + K*Math.Pow(B,-1.0/v) +let Logistic(mu,K,lag) t = + K * exp(-exp(mu*exp(1.0)/K*(lag-t)+1.0)) + + +//runs Filzbach using a selected growth model and returns the identified parameters (mu,K,lag) + +let FitGrowthModel (modelType) (plate:Plate) = + let FitGrowthModelOD(ODi, model) = + + + //od fit + //let od0 = Seq.map(fun (t, od) -> od) ODi |> Seq.min in //use smallest OD measurement to avoid negative value +// let od0 = snd (Seq.nth 0 ODi) in //use the first OD value +// let OD = Seq.map(fun (t,od) -> (t, od/od0)) ODi |> Seq.cache in + + //window slope calculation procedure for growth +// let od0 = ODi |> Seq.map(fun (_,x) -> x) |> Seq.min in +// let OD = Seq.map(fun (t,od) -> (t,od - od0) ) ODi in +// let OD = Seq.map(fun (t,od) -> (t, log(od))) OD |> Seq.cache in +// let mus = new List() in +// let ws = 50 in //window size +// for i in ws..((Seq.length OD)-ws) do +// let a = OD|> Seq.skip(i) |> Seq.take(5) |> Seq.fold(fun (acc1, acc2) (x,y) -> (List.concat([acc1; [x]]), List.concat([acc2;[y]]))) ([],[]) in +// let (A,B) = (fst a |> Array.ofSeq, snd a |> Array.ofSeq) in +// mus.Add(fst (LsqLin A B)); +// done; +// let mx = mus |> Seq.filter(fun x-> not (Double.IsNaN(x) || Double.IsInfinity(x))) |> Seq.max in + + let OD = Seq.map(fun (t,od) -> (t,if od<=0.0 then 1.0e-2 else od)) ODi |> Seq.cache in //negative values are bad when using log fits + //let OD = Seq.filter(fun (t,od) -> od>0.0) ODi |> Seq.cache in //negative values are bad when using log fits + let od0 = snd (Seq.nth 0 OD) in //use the first OD value + let OD = Seq.map(fun (t,od) -> (t, log (od/od0))) OD |> Seq.cache in + + match model with + | GrowthModels.Logistic -> + let fparam = 2000, 2000, 500, 500 in + let mparam = Seq.ofList[("mu", 0.0, 1.0, 0.25, 0); + ("K", 0.0, 10.0, 1.0, 0); + ("lag",-500.0, 500.0, 100.0, 0); + ("s", 1e-8, 1e2, 1e-8, 1)] in + let likefn param = let (mu,K,lag,s) = Seq.nth 0 param,Seq.nth 1 param,Seq.nth 2 param,Seq.nth 3 param in + Seq.fold (fun sum (x,y) -> + let obs = Logistic(mu, K, lag) x in + let noise = s in + sum + log(ModelBase.normal_density(y,obs,noise))) 0.0 OD in + let FilzGrowth = Filzbach(mparam,likefn) in + let param = FilzGrowth.Run(fparam) in + let mu = Seq.nth 0 param in + let K = Seq.nth 1 param in + let lag = Seq.nth 2 param in + let e = Math.Exp(1.0) in + let maturation_offset = 50.0 in + let tm = lag + K/(2.0*mu) + maturation_offset in + let ParamHist = FilzGrowth.GetParamHist() in + let res = ParamHist.Count in + let RandLogistic(id, x) = + let param = ParamHist.[id] in //random parameter from posterior + let (mu,K,lag) = param.[2], param.[3],param.[4] in + let y = Logistic(mu,K,lag) x in + od0 * Math.Exp(y) + //y + + in + mu, lag, tm, K,res, RandLogistic, OD + + + | GrowthModels.Gompertz -> + let fparam = 2000, 2000, 500, 500 in + let mparam = Seq.ofList[("mu", 0.0, 1.0, 0.25, 0); + ("K", 0.0, 10.0, 1.0, 0); + ("lag",-500.0, 500.0, 100.0, 0); + ("s", 1e-8, 1e3, 1e-8, 1)] in + let likefn param = let (mu,K,lag,s) = Seq.nth 0 param,Seq.nth 1 param,Seq.nth 2 param,Seq.nth 3 param in + Seq.fold (fun sum (x, y) -> + let obs = Gompertz(mu, K, lag) x in + let noise = s in + sum + log(ModelBase.normal_density(y,obs,noise))) 0.0 OD in + let FilzGrowth = Filzbach(mparam,likefn) in + let param = FilzGrowth.Run(fparam) in + let mu = Seq.nth 0 param in + let K = Seq.nth 1 param in + let lag = Seq.nth 2 param in + let e = Math.Exp(1.0) in + let maturation_offset = 50.0 in + let tm = (K + e*lag*mu)/(e*mu) + maturation_offset in + let ParamHist = FilzGrowth.GetParamHist() in + let res = ParamHist.Count in + let RandGompertz(id, x) = + let param = ParamHist.[id] in //random parameter from posterior + let (mu,K,lag) = param.[2], param.[3],param.[4] in + let y = Gompertz(mu,K,lag) x in + od0*Math.Exp(y) + //y + in + mu, lag, tm, K,res, RandGompertz, OD + // mx, lag, tm, K,res, RandGompertz, OD + + + | GrowthModels.Richards -> + //let fparam = 2000, 2000, 500, 500 in + let fparam = 2000, 2000, 500, 500 in + let mparam = Seq.ofList[("mu", 0.0, 1.0, 0.25, 0); + ("K", 0.0, 10.0, 1.0, 0); + ("lag",-500.0, 500.0, 100.0, 0); + ("v",0.0, 1.0, 0.01, 0); + ("s", 1e-8, 1e2, 1e-8, 1)] in + let likefn param = let (mu,K,lag,v,s) = Seq.nth 0 param,Seq.nth 1 param,Seq.nth 2 param,Seq.nth 3 param, Seq.nth 4 param in + Seq.fold(fun sum (x, y) -> + let obs = Richards(mu, K, lag,v) x in + let noise = s in + sum + log(ModelBase.normal_density(y,obs,noise))) 0.0 OD in + let FilzGrowth = Filzbach(mparam,likefn) in + let param = FilzGrowth.Run(fparam) in + let mu = Seq.nth 0 param in + let K = Seq.nth 1 param in + let lag = Seq.nth 2 param in + let e = Math.Exp(1.0) in + let maturation_offset = 50.0 in + let tm = (K + e*lag*mu)/(e*mu) + maturation_offset in + //construct a random growth sampling function + let ParamHist = FilzGrowth.GetParamHist() in + let res = ParamHist.Count in + let RandRichards(id, x) = + let param = ParamHist.[id] in //random parameter from posterior + let (mu,K,lag,v) = param.[2], param.[3],param.[4],param.[5] in + let y = Richards(mu,K,lag,v) x in + od0 * Math.Exp(y) + //y + in + //return results + mu, lag, tm, K,res, RandRichards , OD + in + let FitGrowthModelWell (modelType) (well:Well) = + let (T,OD) = getSignal(well, "OD") in + let OD = Seq.map2(fun t od -> (t,od)) T OD in + let rec runner OD modelType = + let (mu,lag,tm,K,res,md,nOD) = FitGrowthModelOD(OD,modelType) in + if (tm < 0.0) + then runner OD modelType + else (mu,lag,tm,K,res,md,nOD) in + let (mu,lag,tm,K,res,md,nOD) = runner OD modelType in + let nOD = Seq.map(fun (t,od) -> od) nOD |> Array.ofSeq in + let model = {mu=mu;lag=lag;tm=tm;K=K; res=res;model=md} in + //let newSignals = Array.mapi(fun i s -> if well.SignalNames.[i]="OD" then nOD else s) well.Signals in + //{well with Signals = newSignals; GrowthModel = Some model;} + {well with GrowthModel = Some model;} + in + let newData = Seq.map(fun w -> FitGrowthModelWell modelType w ) plate.Data |> Seq.cache in + {plate with Data = newData;} + + +//physical properties of commonly used fluorescent proteins +//assume all FPs have the same degradation and translation rates - specific values from (Elowitz and Leibler, Nature, 2000) are used. +//CFP, YFP maturation rates are taken from (J. Brown, 2011) which refers to (Gordon et. al., Nat. Meth 2007) +type ReporterPropertiesType = {name:string; degradation:double; maturation:double; translation: double; mRNAdeg:double} + +//let degradationRate = 0.0693 +let degradationRate = 0.0005 + +let ReporterProperties (name:string) = + let reporter = name.ToLower() in + match reporter with + | "gfpmut3" -> Some {name="GFPmut3"; degradation=degradationRate; maturation=0.0277; translation=0.1443; mRNAdeg=0.001;} + | "mcherry" -> Some {name="mCherry"; degradation=degradationRate; maturation=0.0186; translation=0.1443; mRNAdeg=0.001;} + | "ecfp" -> Some {name="ECFP"; degradation=degradationRate; maturation=0.0139; translation=0.1443; mRNAdeg=0.001;} + | "eyfp" -> Some {name="EYFP"; degradation=degradationRate; maturation=0.0173; translation=0.1443; mRNAdeg=0.001;} + | "mrfp1" -> Some {name="mRFP1"; degradation=degradationRate; maturation=0.0173; translation=0.1443; mRNAdeg=0.001;} + | _ -> None + +//construct a filter function for each well to capture the exponential phase based on the inferred growth curve. +let SetFilters plate = + let newData = Seq.map(fun w -> + let newFilter = + match w.GrowthModel with + | Some model -> + let filter id = + let t = w.T.[id] in + t > model.lag && t < 2.0*model.tm-model.lag in + filter + | None -> w.Filter + in + { w with Filter = newFilter } + ) plate.Data |> Seq.cache in + {plate with Data = newData;} + + +let FindSteadyStates plate = + let filteri filter X = + let mapped = Array.mapi (fun i x -> (i,x)) X in + let filtered = Array.filter (fun (i,x) -> filter i) mapped in + Array.map (fun (i,x) -> x) filtered + in + let FindSS well = + let Filter = filteri well.Filter in + let Signals = Array.map(fun s -> Filter s) well.Signals in //filter signals + Array.fold2(fun (map:Map<(string*string),(double*double)>) name signal -> //for each pair of signals, compute the cross slope + Array.fold2(fun map2 name2 signal2 -> + let fit = LsqLin signal2 signal in //signal2 is the X, signal is Y; + map2.Add((name,name2),fit)) map well.SignalNames Signals) + Map.empty well.SignalNames Signals + in + let newData = Seq.map(fun w -> {w with SteadyStates = FindSS w;}) plate.Data |> Seq.cache in + {plate with Data=newData;} + +let FindActivities (plate:Plate) = + let copies = 1.0 in //single copy number assumption + let FindActivity (well:Well) = + Map.toSeq well.SteadyStates + |> Seq.fold(fun (map:Map<(string*string),double>) ((s1,s2), (a,_)) -> + if not (s1="OD") && s2="OD" then + let propOpt = ReporterProperties s1 in + match propOpt with + | Some prop -> + let Pdeg = prop.degradation in + let Pmat = prop.maturation in + let Ptrans = prop.translation in + let mRNAdeg = prop.mRNAdeg in + let mu = well.GrowthModel.Value.mu in + let factor = mRNAdeg * (Pdeg + mu)*(Pdeg + mu + Pmat)/(Pmat*Ptrans*copies) in + map.Add((s1,s2),factor*a) + | None -> map + else if not (s1="OD") && not (s2="OD") && not(s1=s2) then + let prop1 = ReporterProperties s1 in + let prop2 = ReporterProperties s2 in + match (prop1,prop2) with + | (Some p1, Some p2) -> + let Pdeg1 = p1.degradation in + let Pmat1 = p1.maturation in + let Ptrans1 = p1.translation in + let mRNAdeg1 = p1.mRNAdeg in + + let Pdeg2 = p2.degradation in + let Pmat2 = p2.maturation in + let Ptrans2 = p2.translation in + let mRNAdeg2 = p2.mRNAdeg in + + let mu = well.GrowthModel.Value.mu in + + let F1 = mRNAdeg1 * (Pdeg1 + mu)*(Pdeg1 + mu + Pmat1)/(Pmat1*Ptrans1) in + let F2 = mRNAdeg2 * (Pdeg2 + mu)*(Pdeg2 + mu + Pmat2)/(Pmat2*Ptrans2) in + + map.Add((s1,s2),(F1/F2)*a) + | _ -> map + else + map + ) Map.empty + in + let newData = Seq.map(fun w -> {w with Activity = FindActivity w;}) plate.Data |> Seq.cache in + {plate with Data=newData;} + + +let ComputeProperties condition default_values (plate:Plate) = + let devices = Seq.groupBy(fun w -> w.Content) plate.Data //group wells by device + |> Seq.filter(fun (s:string,w) -> //remove controls + let name = s.ToLower() in + not (name.Contains("blank") || + name.Contains("negative") || + name.Contains("gain"))) in + let device = snd (Seq.head devices) in //select the first devices (TODO: generalize for multiple devices) + //let d0 = Seq.head device in //select the first well to explore the available conditions + + //TODO: FIX EMPTY CONDITION + + // Filter the wells for matched conditions and their values + let get_condition well key = if well.Condition.ContainsKey key then well.Condition.[key] else 0.0 in + + let device = + let filtered_values = Seq.filter (fun (cnd,_) -> not (cnd=condition)) default_values in + Seq.filter (fun w -> Seq.fold (fun res (c,v) -> res && (get_condition w c = v)) true filtered_values) device in + + let measurements = Seq.groupBy(fun w -> get_condition w condition) device + |> Seq.map(fun (c, wells) -> (c,Seq.map(fun w -> + let activities = Map.toSeq w.Activity |> Seq.map(fun ((s1,s2),v) -> (s1 + "/" + s2, v)) in + let growth = [("mu", w.GrowthModel.Value.mu); ("lag", w.GrowthModel.Value.lag);("K", w.GrowthModel.Value.K);] |> Seq.ofList in + Seq.concat([activities; growth]) + |> Map.ofSeq) wells)) + in + let propertyNames = Seq.head measurements |> snd |> Seq.head |> Map.toSeq |> Seq.map(fun (s,_) -> s) |> Array.ofSeq in + let C = Seq.map(fun (s,_) -> s) measurements |> Array.ofSeq in + + let mMap = measurements |> Map.ofSeq in + let properties = Seq.map(fun c -> //for each condition + let d = mMap.[c] in + Seq.map(fun n -> Seq.map(fun (s:Map) -> s.[n]) d |> Array.ofSeq) propertyNames //for each property + |> Array.ofSeq) C |> Array.ofSeq in + {plate with C=C; Properties=properties; PropertyNames=propertyNames; Cname=condition;} + +let FilterByDevice plate device = + let data = Seq.filter (fun w -> w.Content = device) plate.Data in + { plate with Data = data } + + +let AdjustGain(plate:Plate) = + let ComputeGain(plate:Plate) = + let gain = Seq.filter(fun w -> w.DataType=DataTypes.Gain) plate.Data //filter only the "Gain" wells + |> Seq.map(fun w -> w.Activity |> Map.toSeq) //take the calculated activity values and represent as sequences + |> Seq.fold(fun acc s -> Seq.append(acc) s) Seq.empty //append all replicates + |> Seq.groupBy(fun (s,_) -> s) //group by the signal type + |> Seq.map(fun (s,x) -> //compute the average gain of each channel + let ave = Seq.map(fun (_,X) -> X) x |> Seq.average in + (s,ave)) + |> Seq.filter(fun ((s1,s2),_) -> not (s1="OD" || s2="OD")) //leave only fluorescent channels + |> Map.ofSeq in + {plate with Gain=gain} + in + let AdjustSignals(plate:Plate) = + let newData = Seq.map(fun w -> + if w.DataType = DataTypes.Data then + let activity = w.Activity |> Map.toSeq in + let newActivity = Seq.map(fun (key,value) -> + let newValue = if plate.Gain.ContainsKey(key) then value/(plate.Gain.[key]) else value in + (key,newValue)) activity + |> Map.ofSeq in + {w with Activity=newActivity} + else + w + ) plate.Data in + {plate with Data = newData;} + in + plate + |> ComputeGain + |> AdjustSignals + + + + +let Characterize(plate:Plate, growthModel) = + let def_cond = plate.Conditions |> Map.toSeq |> Seq.head |> fst in + let def_cond_vals = plate.Conditions |> Map.toSeq |> Seq.map(fun (c,_) -> c, 0.0) in + plate + |> CorrectBlanks //compute and subtract background signals from blank media + |> FitGrowthModel growthModel //fit the parameters of a growth curve to each werll + |> SetFilters //use the growth curve to select a range of data + |> CorrectAutofluorescence //compute and subtract the background fluorescence of nonfluorescent cells (autofluorescence) + |> FindSteadyStates //compute the steady states of each reporter (individually) + |> FindActivities //compute the promoter activities from the fluorescence + |> AdjustGain //compute the average gain adjustment and modify the signals accordingly + |> ComputeProperties def_cond def_cond_vals //collect a represenation of the different properties (activities, growht, etc) as a function of condition + + + + + + + +let getKeys map = Seq.map(fun (k,_) -> k) (Map.toSeq map) + +let getProperties (plate:Plate, property:string) = + let id = Array.findIndex(fun x -> x = property) plate.PropertyNames in + Seq.map2(fun x (y:double[][]) -> (x,y.[id])) plate.C plate.Properties + + + +let DataOutput(plate:Plate) = + let result = "" in + + let conditions = Seq.fold(fun acc w -> Seq.append(acc) (w.Condition |> Map.toSeq |> Seq.map(fun (s,_) -> s))) Seq.empty plate.Data |> Set.ofSeq in + let result = Seq.fold(fun acc c -> acc + c + ",") result conditions in + let signals = (Seq.head plate.Data).SignalNames in + let has_rfp = Array.contains "mRFP1" signals in + let result = result + + "F(EYFP/OD),F(ECFP/OD)," + + (if has_rfp then "F(mRFP1/OD)," else "") + + "F(EYFP/ECFP)," + + (if has_rfp then "F(EYFP/mRFP1),F(ECFP/mRFP1)," else "") + + "P(EYFP/OD),P(ECFP/OD)," + + (if has_rfp then "P(mRFP1/OD)," else "") + + "P(EYFP/ECFP)," + + (if has_rfp then "P(EYFP/mRFP1),P(ECFP/mRFP1)," else "") + + "mu,K,lag\n" in + let result = Seq.fold(fun acc well -> + //let acc = acc + well.Row.ToString() + "," + well.Col.ToString() + "," + well.DataType.ToString() + "," in + //let acc = acc + well.Condition.Aggregate("", (acc, y) => acc + y.Key + "=" + y.Value + ";") + "," in + let acc = Seq.fold(fun acc c -> acc + (if well.Condition.ContainsKey(c) then well.Condition.[c].ToString() else "0.0") + ",") acc conditions in + let acc = acc + + (fst well.SteadyStates.[("EYFP", "OD")]).ToString() + "," + + (fst well.SteadyStates.[("ECFP", "OD")]).ToString() + "," + + (if has_rfp then (fst well.SteadyStates.[("mRFP1", "OD")]).ToString() + "," else "") + + (fst well.SteadyStates.[("EYFP", "ECFP")]).ToString() + "," + + (if has_rfp then (fst well.SteadyStates.[("EYFP", "mRFP1")]).ToString() + "," + + (fst well.SteadyStates.[("ECFP", "mRFP1")]).ToString() + "," else "") in + + let acc = acc + + well.Activity.[("EYFP", "OD")].ToString() + "," + + well.Activity.[("ECFP", "OD")].ToString() + "," + + (if has_rfp then well.Activity.[("mRFP1", "OD")].ToString() + "," else "") + + well.Activity.[("EYFP", "ECFP")].ToString() + "," + + (if has_rfp then well.Activity.[("EYFP", "mRFP1")].ToString() + "," + + well.Activity.[("ECFP", "mRFP1")].ToString() + "," else "") in + + let acc = acc + well.GrowthModel.Value.mu.ToString() + "," in + let acc = acc + well.GrowthModel.Value.K.ToString() + "," in + let acc = acc + well.GrowthModel.Value.lag.ToString() + "\n" in + acc + ) result (Seq.filter( fun w -> w.DataType=DataTypes.Data) plate.Data) in + result + + +//-------------------------------------------------------------------------- +//The following block of code deals with different regulation models +// +//This is a VERY preliminary prototype! These procedures should be generalized +// in order to avoid code duplication +//-------------------------------------------------------------------------- + +let Hill(a,b,K,n) x = (a*x**n + b*K**n)/(x**n+K**n) + +let Hill_General(B)= + let fparam = (50000, 50000, 2000, 2000) in + //let fparam = (500000, 500000, 20000, 20000) in + let mparam = Seq.ofList[("a", 0.0, 5000.0, 5.0, 0); + ("b", 0.0, 200.0, 0.0, 0); + ("K", 1e-15, 1e15, 1e-8, 1); + ("n", 0.0, 5.0, 1.0, 0); + ("s", 1e-5, 10.0, 1.0, 1)] in + +// //use these settings for the growth model fits -> smaller ranges for a,b parameters +// let mparam = Seq.ofList[("a", 0.0, 0.05, 5.0, 0); +// ("b", 0.0, 0.05, 0.0, 0); +// ("K", 1e-15, 1e15, 1e-8, 1); +// ("n", 0.0, 5.0, 1.0, 0); +// ("s", 1e-5, 10.0, 1.0, 1)] in + + let ltotmax = ref Double.MinValue in + let likefn param = let (a,b,K,n,s) = Seq.nth 0 param,Seq.nth 1 param,Seq.nth 2 param,Seq.nth 3 param,Seq.nth 4 param in + let logLk = Seq.fold (fun s1 (conc,vals) -> + let obs = Hill(a,b,K,n) conc in + Seq.fold(fun s2 y -> + let noise = if (y<0.0) then 0.0 else Math.Sqrt(obs)*s in + let v = ModelBase.normal_density(y,obs,noise) in + let v = if v<=0.0 || Double.IsInfinity(v) then 0.0 else log(v) in + s2 + v) s1 vals) 0.0 B in + ltotmax:= if (!ltotmax + let dist = Seq.map(fun (y:float[]) -> y.[i+2]) ParamHist + |> Array.ofSeq in + (n,log,dist)) [("a",false);("b",false);("K",true);("n",false); ("s",true)] in + let parameters = List.mapi(fun i (name,log,dist) -> {pname=name; value= Seq.nth i param; log=log; dist=dist;}) paramDist |> Array.ofList in + let (AIC,BIC,CIC) = ICs in + let X = Seq.map(fun (x,_) -> x) B |> Array.ofSeq in + { + modelType = ModelTypes.Linear; + AIC = AIC; + BIC = BIC; + CIC = CIC; + model = RandFunc; + res = res; + parameters = parameters; + X = X; + bayestable = ParamHist; + } + +let Hill_Activation(B)= + let fparam = (50000, 50000, 2000, 2000) in + let mparam = Seq.ofList[("a", 0.0, 200.0, 5.0, 0); + ("K", 1e-15, 1e15, 1e-8, 1); + ("n", 0.0, 5.0, 1.0, 0); + ("s", 1e-5, 10.0, 1.0, 1)] in + let ltotmax = ref Double.MinValue in + let likefn param = + let (a,K,n,s) = Seq.nth 0 param,Seq.nth 1 param,Seq.nth 2 param,Seq.nth 3 param in + let logLk = Seq.fold (fun s1 (conc,vals) -> + let obs = Hill(a,0.0,K,n) conc in + Seq.fold(fun s2 y -> + let noise = if (y<0.0) then 0.0 else Math.Sqrt(obs)*s in + let v = ModelBase.normal_density(y,obs,noise) in + let v = if v<=0.0 || Double.IsInfinity(v) then 0.0 else log(v) in + s2 + v) s1 vals) 0.0 B in + ltotmax:= if (!ltotmax + let dist = Seq.map(fun (y:float[]) -> y.[i+2]) ParamHist + |> Array.ofSeq in + (n,log,dist)) [("a",false);("K",true);("n",false); ("s",true)] in + let parameters = List.mapi(fun i (name,log,dist) -> {pname=name; value= Seq.nth i param; log=log; dist=dist;}) paramDist |> Array.ofList in + let (AIC,BIC,CIC) = ICs in + let X = Seq.map(fun (x,_) -> x) B |> Array.ofSeq in + { + modelType = ModelTypes.Linear; + AIC = AIC; + BIC = BIC; + CIC = CIC; + model = RandFunc; + res = res; + parameters = parameters; + X = X; + bayestable = ParamHist; + } + + +let Hill_Repression(B)= + let fparam = (50000, 50000, 2000, 2000) in + let mparam = Seq.ofList[("b", 0.0, 200.0, 5.0, 0); + ("K", 1e-15, 1e15, 1e-8, 1); + ("n", 0.0, 5.0, 1.0, 0); + ("s", 1e-5, 10.0, 1.0, 1)] in + let ltotmax = ref Double.MinValue in + let likefn param = + let (b,K,n,s) = Seq.nth 0 param,Seq.nth 1 param,Seq.nth 2 param,Seq.nth 3 param in + let logLk = Seq.fold (fun s1 (conc,vals) -> + let obs = Hill(0.0,b,K,n) conc in + Seq.fold(fun s2 y -> + let noise = if (y<0.0) then 0.0 else Math.Sqrt(obs)*s in + let v = ModelBase.normal_density(y,obs,noise) in + let v = if v<=0.0 || Double.IsInfinity(v) then 0.0 else log(v) in + s2 + v) s1 vals) 0.0 B in + ltotmax:= if (!ltotmax + let dist = Seq.map(fun (y:float[]) -> y.[i+2]) ParamHist |> Array.ofSeq in + (n,log,dist)) [("b",false);("K",true);("n",false); ("s",true)] + in + let parameters = List.mapi(fun i (name,log,dist) -> {pname=name; value= Seq.nth i param; log=log; dist=dist;}) paramDist |> Array.ofList in + let (AIC,BIC,CIC) = ICs in + let X = Seq.map(fun (x,_) -> x) B |> Array.ofSeq in + { + modelType = ModelTypes.Linear; + AIC = AIC; + BIC = BIC; + CIC = CIC; + model = RandFunc; + res = res; + parameters = parameters; + X = X; + bayestable = ParamHist; + } + + +let MM_General(B)= + let fparam = (50000, 50000, 2000, 2000) in + let mparam = Seq.ofList[("a", 0.0, 5000.0, 5.0, 0); + ("b", 0.0, 200.0, 0.0, 0); + ("K", 1e-15, 1e15, 1e-8, 1); + ("s", 1e-5, 10.0, 1.0, 1)] in + let ltotmax = ref Double.MinValue in + let likefn param = + let (a,b,K,s) = Seq.nth 0 param,Seq.nth 1 param,Seq.nth 2 param,Seq.nth 3 param in + let logLk = Seq.fold (fun s1 (conc,vals) -> + let obs = Hill(a,b,K,1.0) conc in + Seq.fold(fun s2 y -> + let noise = if (y<0.0) then 0.0 else Math.Sqrt(obs)*s in + let v = ModelBase.normal_density(y,obs,noise) in + let v = if v<=0.0 || Double.IsInfinity(v) then 0.0 else log(v) in + s2 + v) s1 vals) 0.0 B in + ltotmax:= if (!ltotmax + let dist = Seq.map(fun (y:float[]) -> y.[i+2]) ParamHist + |> Array.ofSeq in + (n,log,dist)) [("a",false);("b",false);("K",true);("s",true)] in + let parameters = List.mapi(fun i (name,log,dist) -> {pname=name; value= Seq.nth i param; log=log; dist=dist;}) paramDist |> Array.ofList in + let (AIC,BIC,CIC) = ICs in + let X = Seq.map(fun (x,_) -> x) B |> Array.ofSeq in + { + modelType = ModelTypes.Linear; + AIC = AIC; + BIC = BIC; + CIC = CIC; + model = RandFunc; + res = res; + parameters = parameters; + X = X; + bayestable = ParamHist; + } + +let MM_Repression(B)= + let fparam = (50000, 50000, 2000, 2000) in + let mparam = Seq.ofList[("b", 0.0, 200.0, 5.0, 0); + ("K", 1e-15, 1e15, 1e-8, 1); + ("s", 1e-5, 10.0, 1.0, 1)] in + let ltotmax = ref Double.MinValue in + let likefn param = let (b,K,s) = Seq.nth 0 param,Seq.nth 1 param,Seq.nth 2 param in + let logLk = Seq.fold (fun s1 (conc,vals) -> + let obs = Hill(0.0,b,K,1.0) conc in + Seq.fold(fun s2 y -> + let noise = if (y<0.0) then 0.0 else Math.Sqrt(obs)*s in + let v = ModelBase.normal_density(y,obs,noise) in + let v = if v<=0.0 || Double.IsInfinity(v) then + 0.0 + else + log(v) + in + s2 + v) s1 vals) 0.0 B in + ltotmax:= if (!ltotmax + let dist = Seq.map(fun (y:float[]) -> y.[i+2]) ParamHist + |> Array.ofSeq in + (n,log,dist)) [("b",false);("K",true);("s",true)] in + let parameters = List.mapi(fun i (name,log,dist) -> {pname=name; value= Seq.nth i param; log=log; dist=dist;}) paramDist |> Array.ofList in + let (AIC,BIC,CIC) = ICs in + let X = Seq.map(fun (x,_) -> x) B |> Array.ofSeq in + { + modelType = ModelTypes.Linear; + AIC = AIC; + BIC = BIC; + CIC = CIC; + model = RandFunc; + res = res; + parameters = parameters; + X = X; + bayestable = ParamHist; + } + + +let MM_Activation(B)= + let fparam = (50000, 50000, 2000, 2000) in + let mparam = Seq.ofList[("a", 0.0, 200.0, 5.0, 0); + ("K", 1e-15, 1e15, 1e-8, 1); + ("s", 1e-5, 10.0, 1.0, 1)] in + let ltotmax = ref Double.MinValue in + let likefn param = let (a,K,s) = Seq.nth 0 param,Seq.nth 1 param,Seq.nth 2 param in + let logLk = Seq.fold (fun s1 (conc,vals) -> + let obs = Hill(a,0.0,K,1.0) conc in + Seq.fold(fun s2 y -> + let noise = if (y<0.0) then 0.0 else Math.Sqrt(obs)*s in + let v = ModelBase.normal_density(y,obs,noise) in + let v = if v<=0.0 || Double.IsInfinity(v) then 0.0 else log(v) in + s2 + v) s1 vals) 0.0 B in + ltotmax:= if (!ltotmax + let dist = Seq.map(fun (y:float[]) -> y.[i+2]) ParamHist + |> Array.ofSeq in + (n,log,dist)) [("a",false);("K",true);("s",true)] in + let parameters = List.mapi(fun i (name,log,dist) -> {pname=name; value= Seq.nth i param; log=log; dist=dist;}) paramDist |> Array.ofList in + let (AIC,BIC,CIC) = ICs in + let X = Seq.map(fun (x,_) -> x) B |> Array.ofSeq in + { + modelType = ModelTypes.Linear; + AIC = AIC; + BIC = BIC; + CIC = CIC; + model = RandFunc; + res = res; + parameters = parameters; + X = X; + bayestable = ParamHist; + } + + + +let Dimer_General(B)= + let fparam = (50000, 50000, 2000, 2000) in + let mparam = Seq.ofList[("a", 0.0, 200.0, 5.0, 0); + ("b", 0.0, 200.0, 0.0, 0); + ("K", 1e-15, 1e15, 1e-8, 1); + ("s", 1e-5, 10.0, 1.0, 1)] in + let ltotmax = ref Double.MinValue in + let likefn param = let (a,b,K,s) = Seq.nth 0 param,Seq.nth 1 param,Seq.nth 2 param,Seq.nth 3 param in + let logLk = Seq.fold (fun s1 (conc,vals) -> + let obs = Hill(a,b,K,2.0) conc in + Seq.fold(fun s2 y -> + let noise = if (y<0.0) then 0.0 else Math.Sqrt(obs)*s in + let v = ModelBase.normal_density(y,obs,noise) in + let v = if v<=0.0 || Double.IsInfinity(v) then 0.0 else log(v) in + s2 + v) s1 vals) 0.0 B in + ltotmax:= if (!ltotmax + let dist = Seq.map(fun (y:float[]) -> y.[i+2]) ParamHist + |> Array.ofSeq in + (n,log,dist)) [("a",false);("b",false);("K",true);("s",true)] in + let parameters = List.mapi(fun i (name,log,dist) -> {pname=name; value= Seq.nth i param; log=log; dist=dist;}) paramDist |> Array.ofList in + let (AIC,BIC,CIC) = ICs in + let X = Seq.map(fun (x,_) -> x) B |> Array.ofSeq in + { + modelType = ModelTypes.Linear; + AIC = AIC; + BIC = BIC; + CIC = CIC; + model = RandFunc; + res = res; + parameters = parameters; + X = X; + bayestable = ParamHist; + } + + +let Dimer_Repression(B)= + let fparam = (50000, 50000, 2000, 2000) in + let mparam = Seq.ofList[("b", 0.0, 200.0, 5.0, 0); + ("K", 1e-15, 1e15, 1e-8, 1); + ("s", 1e-5, 10.0, 1.0, 1)] in + let ltotmax = ref Double.MinValue in + let likefn param = let (b,K,s) = Seq.nth 0 param,Seq.nth 1 param,Seq.nth 2 param in + let logLk = Seq.fold (fun s1 (conc,vals) -> + let obs = Hill(0.0,b,K,2.0) conc in + Seq.fold(fun s2 y -> + let noise = if (y<0.0) then 0.0 else Math.Sqrt(obs)*s in + let v = ModelBase.normal_density(y,obs,noise) in + let v = if v<=0.0 || Double.IsInfinity(v) then 0.0 else log(v) in + s2 + v) s1 vals) 0.0 B in + ltotmax:= if (!ltotmax + let dist = Seq.map(fun (y:float[]) -> y.[i+2]) ParamHist + |> Array.ofSeq in + (n,log,dist)) [("b",false);("K",true);("s",true)] in + let parameters = List.mapi(fun i (name,log,dist) -> {pname=name; value= Seq.nth i param; log=log; dist=dist;}) paramDist |> Array.ofList in + let (AIC,BIC,CIC) = ICs in + let X = Seq.map(fun (x,_) -> x) B |> Array.ofSeq in + { + modelType = ModelTypes.Linear; + AIC = AIC; + BIC = BIC; + CIC = CIC; + model = RandFunc; + res = res; + parameters = parameters; + X = X; + bayestable = ParamHist; + } + +let Dimer_Activation(B)= + let fparam = (50000, 50000, 2000, 2000) in + let mparam = Seq.ofList[("a", 0.0, 200.0, 5.0, 0); + ("K", 1e-15, 1e15, 1e-8, 1); + ("s", 1e-5, 10.0, 1.0, 1)] in + let ltotmax = ref Double.MinValue in + let likefn param = let (a,K,s) = Seq.nth 0 param,Seq.nth 1 param,Seq.nth 2 param in + let logLk = Seq.fold (fun s1 (conc,vals) -> + let obs = Hill(a,0.0,K,2.0) conc in + Seq.fold(fun s2 y -> + let noise = if (y<0.0) then 0.0 else Math.Sqrt(obs)*s in + let v = ModelBase.normal_density(y,obs,noise) in + let v = if v<=0.0 || Double.IsInfinity(v) then 0.0 else log(v) in + s2 + v) s1 vals) 0.0 B in + ltotmax:= if (!ltotmax + let dist = Seq.map(fun (y:float[]) -> y.[i+2]) ParamHist + |> Array.ofSeq in + (n,log,dist)) [("a",false);("K",true);("s",true)] in + let parameters = List.mapi(fun i (name,log,dist) -> {pname=name; value= Seq.nth i param; log=log; dist=dist;}) paramDist |> Array.ofList in + let (AIC,BIC,CIC) = ICs in + let X = Seq.map(fun (x,_) -> x) B |> Array.ofSeq in + { + modelType = ModelTypes.Linear; + AIC = AIC; + BIC = BIC; + CIC = CIC; + model = RandFunc; + res = res; + parameters = parameters; + X = X; + bayestable = ParamHist; + } + +let Sequential(B)= + let fparam = (100000, 100000, 2000, 2000) in + let mparam = Seq.ofList[("a", 0.0, 200.0, 5.0, 0); + ("b", 0.0, 200.0, 0.0, 0); + ("c", 0.0, 200.0, 0.0, 0); + ("K1", 1e-15, 1e15, 1e-8, 1); + ("K2", 1e-15, 1e15, 1e-8, 1); + ("s", 1e-5, 10.0, 1.0, 1)] in + let ltotmax = ref Double.MinValue in + let SeqMech(a,b,c,K1,K2) conc = (a * conc ** 2.0 + b * conc * K1 + c * K2 ** 2.0)/(conc**2.0 + conc*K1 + K2**2.0) in + let likefn param = let (a,b,c,K1,K2,s) = Seq.nth 0 param,Seq.nth 1 param,Seq.nth 2 param,Seq.nth 3 param,Seq.nth 4 param,Seq.nth 5 param in + let logLk = Seq.fold (fun s1 (conc,vals) -> + let obs = SeqMech(a,b,c,K1,K2) conc in + Seq.fold(fun s2 y -> + let noise = if (y<0.0) then 0.0 else Math.Sqrt(obs)*s in + let v = ModelBase.normal_density(y,obs,noise) in + let v = if v<=0.0 || Double.IsInfinity(v) then 0.0 else log(v) in + s2 + v) s1 vals) 0.0 B in + ltotmax:= if (!ltotmax + let dist = Seq.map(fun (y:float[]) -> y.[i+2]) ParamHist + |> Array.ofSeq in + (n,log,dist)) [("a",false);("b",false);("c",false);("K1",true);("K2",true); ("s",true)] in + let parameters = List.mapi(fun i (name,log,dist) -> {pname=name; value= Seq.nth i param; log=log; dist=dist;}) paramDist |> Array.ofList in + let (AIC,BIC,CIC) = ICs in + let X = Seq.map(fun (x,_) -> x) B |> Array.ofSeq in + { + modelType = ModelTypes.Linear; + AIC = AIC; + BIC = BIC; + CIC = CIC; + model = RandFunc; + res = res; + parameters = parameters; + X = X; + bayestable = ParamHist; + } + + +let Linear(B)= + let fparam = (50000, 50000, 2000, 2000) in + let mparam = Seq.ofList[("a",1e-10,1e5, 0.001, 1); + ("b", 1e-5, 1e5, 0.001, 1); + ("s", 1e-5, 1e10, 1.0, 1)] in + let ltotmax = ref Double.MinValue in + let likefn param = let (a,b,s) = Seq.nth 0 param, Seq.nth 1 param, Seq.nth 2 param in + let logLk = Seq.fold (fun s1 (conc,vals) -> + let obs = a*conc+b in + Seq.fold(fun s2 y -> + let noise = if (y<0.0) then 0.0 else Math.Sqrt(obs)*s in + let v = ModelBase.normal_density(y,obs,noise) in + let v = if v<=0.0 || Double.IsInfinity(v) then 0.0 else log(v) in + s2 + v) s1 vals) 0.0 B in + ltotmax:= if (!ltotmax + let dist = Seq.map(fun (y:float[]) -> y.[i+2]) ParamHist + |> Array.ofSeq in + (n,log,dist)) [("a",true);("b",true);("s",true)] in + let parameters = List.mapi(fun i (name,log,dist) -> {pname=name; value= Seq.nth i param; log=log; dist=dist;}) paramDist |> Array.ofList in + let (AIC,BIC,CIC) = ICs in + let X = Seq.map(fun (x,_) -> x) B |> Array.ofSeq in + { + modelType = ModelTypes.Linear; + AIC = AIC; + BIC = BIC; + CIC = CIC; + model = RandFunc; + res = res; + parameters = parameters; + X = X; + bayestable = ParamHist; + } + +//note: currently, this function supports only a single inducible/repressible promoter with a single regulator +let CharacterizeModel(data:seq, modelType)= + match modelType with + | ModelTypes.Hill_General -> Hill_General(data) + | ModelTypes.Hill_Activation -> Hill_Activation(data) + | ModelTypes.Hill_Repression -> Hill_Repression(data) + | ModelTypes.Linear -> Linear(data) + | ModelTypes.Michaelis_Menten_General -> MM_General(data) + | ModelTypes.Michaelis_Menten_Activation -> MM_Activation(data) + | ModelTypes.Michaelis_Menten_Repression -> MM_Repression(data) + | ModelTypes.Dimer_General -> Dimer_General(data) + | ModelTypes.Dimer_Activation -> Dimer_Activation(data) + | ModelTypes.Dimer_Repression -> Dimer_Repression(data) + | ModelTypes.Sequential_Binding -> Sequential(data) + | ModelTypes.Constitutive -> + { + modelType = ModelTypes.Constitutive; + AIC = 0.0; + BIC = 0.0; + CIC = 0.0; + model = (fun (id,x) -> 0.0); + res = 0; + parameters = [||]; + X = Seq.map(fun (x,_) -> x) data |> Array.ofSeq; + bayestable = new List(); + } diff --git a/ClassicGEC/ClassicGECDotNet/characterization.fsi b/ClassicGEC/ClassicGECDotNet/characterization.fsi new file mode 100644 index 0000000..5a8bbd6 --- /dev/null +++ b/ClassicGEC/ClassicGECDotNet/characterization.fsi @@ -0,0 +1,106 @@ +module GEC.Characterization + +open System.Collections.Generic + +type GrowthModels = Gompertz =0| Richards =1 | Logistic =2 +type GrowthModelType = { + mu: float; + lag: float; + tm: float; + K: float; + res: int; + model: (int * float -> float); +} +type DataTypes = Data | Gain | Blank | Negative +type Well = { + Row: char; + Col: int; + Content: string; + Colony: string; + DataType: DataTypes; + Condition: Map; + Signals: double[][]; + SignalNames: string[]; + T: double[]; + GrowthModel: GrowthModelType option; + Filter: int -> bool; //given an signal array index, is this part of the selection + SteadyStates: Map<(string*string),(double*double)>; + Activity: Map<(string*string),double>; +} + +type Plate = { + Name: string; + Data: seq; + Blanks: Map; + + Conditions: Map; + Cname: string; + C: double[]; //conditions + Properties: double[][][]; //computed or measured properties + PropertyNames: string[]; //name of properties + + Gain: Map; + log: string; +} + +type ModelTypes = + | Constitutive = 0 + | Linear = 1 + | Michaelis_Menten_Activation = 2 + | Michaelis_Menten_Repression = 3 + | Michaelis_Menten_General = 4 + | Dimer_Activation = 5 + | Dimer_Repression =6 + | Dimer_General = 7 + | Hill_Activation = 8 + | Hill_Repression = 9 + | Hill_General = 10 + | Sequential_Binding = 11 + +type ResponseTypes = + | EYFP_ECFP = 0 + | EYFP_OD = 1 + | ECFP_OD = 2 + | mu = 3 + | K = 4 + | lag = 5 + | EYFP_mRFP1 = 6 + | ECFP_mRFP1 = 7 + | mRFP1_OD = 8 + +type Parameter = { + pname: string; + value: double; + dist: double[]; + log: bool; +} + +type Model = { + modelType: ModelTypes; + AIC: double; + BIC: double; + CIC: double; //rename this information criterion to the right abbreviation + model: int * double -> double; + res: int; + parameters: Parameter[]; + X: double[]; + bayestable: List; +} + +val string_of_response: ResponseTypes -> string +val LoadPlate: string -> Plate +val getSignal: Well * string -> double[] * double[] //return signal over time +val getSignals: Well * string * string -> double[] * double[] //return signal over time +val getFluorescence: Well -> double[] * seq +val getFOd: Well -> double[] * seq +val getFF: Well*string -> double[] * seq + +val Characterize: Plate*GrowthModels -> Plate +val ComputeProperties: string -> seq -> Plate -> Plate +val FilterByDevice : Plate -> string -> Plate +val getKeys: Map<'a,'b> -> seq<'a> +val CharacterizeModel: seq*ModelTypes -> Model +val getProperties: Plate*string -> seq +val MergePlates: Plate * Plate -> Plate +val DataOutput: Plate -> string +val EmptyPlate: Plate \ No newline at end of file diff --git a/ClassicGEC/ClassicGECDotNet/cssubst.fs b/ClassicGEC/ClassicGECDotNet/cssubst.fs new file mode 100644 index 0000000..168fd41 --- /dev/null +++ b/ClassicGEC/ClassicGECDotNet/cssubst.fs @@ -0,0 +1,92 @@ +[] +module Microsoft.Research.GEC.Cssubst + +open Microsoft.Research.GEC + +//open Microsoft.Research.ModellingEngine +open Microsoft.Research.CRNEngine + +(* ************************************************************************************************************ *) + +(* A "context-sensitive" substitution has four parts. *) +type t = { theta:Subst.t; (* The actual substitution. *) + rho: string list; (* The variables on which "theta" must be injective. *) + sigma: string list list; (* Species names used in the current context. *) + tau: string list list } (* Species names excluded for use. *) + +(* The "empty" context-sensitive substitution. *) +let empty = { theta=Subst.empty; rho=[]; sigma=[]; tau=[] } + +(* Make a context-sensitive substitution. *) +let make (theta:Subst.t) (rho:string list) (sigma:string list list) (tau:string list list) : t = + { theta=theta; rho=rho; sigma=sigma; tau=tau } + +let printListDisplay (f:'a -> string) (xs:'a list) = "[" + (Lib.string_of_list f "; " xs) + "]" +(* Produce a string representation of a context-sensitive substitution. *) +let display (cs:t) = + "{ theta = " + (Subst.display cs.theta) + ";" + Lib.newline + + " rho = " + (printListDisplay Lib.id cs.rho) + ";" + Lib.newline + + " sigma = " + (printListDisplay Ast.complexString cs.sigma) + ";" + Lib.newline + + " tau = " + (printListDisplay Ast.complexString cs.tau) + " }" + +(* Check that a given element of the "csSubst" type satisfies the 2 criteria for a context-sensitive substitution. *) +let isOK (cs:t) = + let check_ii () = + // Assume that cs.rho contains no duplicates... + match Lib.find_duplicate Subst.targetEq (List.map (fun x -> Subst.find x cs.theta) cs.rho) with + | None -> true + | Some _ -> false + in + let check_iii () = Lib.disjoint Ast.complexesEqual cs.sigma cs.tau in + (check_ii ()) && (check_iii ()) + +(* Get the "normal" substitution out of a context-sensitive one. *) +let getSubst (cs:t) : Subst.t = cs.theta + +(* ************************************************************************************************************ *) + +(* "Merge" two context-sensitive substitutions together, and test to see if the result is + also a context-sensitive substitution. *) +let merge (cs1:t) (cs2:t) : t option = + match (Subst.union cs1.theta cs2.theta) with + | None -> None + | Some theta -> + let cs12 = { theta = theta; + rho = Lib.remove_duplicates (=) (cs1.rho @ cs2.rho); + sigma = Lib.remove_duplicates Ast.complexesEqual (cs1.sigma @ cs2.sigma); + tau = Lib.remove_duplicates Ast.complexesEqual (cs1.tau @ cs2.tau) } + in + if isOK cs12 then Some cs12 else None + +(* Compose two lists of context-sensitive substitutions by only retaining those elements of the + "cartesian product" which satisfy the criteria. *) +let compose (css1:t list) (css2:t list) : t list = + (* NB: we don't form the entire cartesian product - it could get quite big. + Instead, have two nested loops with an accumulator running through them. + TO DO: this could be put into CPS to make it tail-recursive... *) + let rec loop (acc:t list) (css1:t list) = + match css1 with + | [] -> acc + | (cs1::css1) -> + let rec loop2 (acc:t list) (css2:t list) = + match css2 with + | [] -> acc + | (cs2::css2) -> + match merge cs1 cs2 with + | None -> loop2 acc css2 + | Some cs12 -> loop2 (acc@[cs12]) css2 + in + let acc = loop2 acc css2 in + loop acc css1 + in + loop [] css1 + +(* Erase the "context" data in a context-sensitive substitution. *) +let eraseContext (cs:t) : t = { theta=cs.theta; rho=[]; sigma=[]; tau=[] } + +(* Check whether a context-sensitive substitution satisfies a list of arithmetic constraints. *) +let satisfiesConstraints (cs:t) (ks:(Ast.aexp*Ast.op*Ast.aexp) list) : bool = + Lib.forall (Subst.satisfiesConstraint cs.theta) ks + +(* Produce a "varAss" (variable assignments) from a context-sensitive substitution. *) +let mkVarAss (cs:t) = Subst.mkVarAss cs.theta diff --git a/ClassicGEC/ClassicGECDotNet/cssubst.fsi b/ClassicGEC/ClassicGECDotNet/cssubst.fsi new file mode 100644 index 0000000..9457700 --- /dev/null +++ b/ClassicGEC/ClassicGECDotNet/cssubst.fsi @@ -0,0 +1,45 @@ +module Microsoft.Research.GEC.Cssubst + +open Microsoft.Research.GEC + +//open Microsoft.Research.ModellingEngine +open Microsoft.Research.CRNEngine + +(* ************************************************************************************************************ *) + +(* Type for "context-sensitive" substitutions. *) +type t + +(* The "empty" context-sensitive substitution. *) +val empty : t + +(* Make a context-sensitive substitution. *) +val make : Subst.t -> string list -> string list list -> string list list -> t + +(* Produce a string representation of a context-sensitive substitution. *) +val display : t -> string + +(* Check that a given element of the "csSubst" type satisfies the 2 criteria for a context-sensitive substitution. *) +val isOK : t -> bool + +(* Get the "normal" substitution out of a context-sensitive one. *) +val getSubst : t -> Subst.t + +(* ************************************************************************************************************ *) + +(* "Merge" two context-sensitive substitutions together, and test to see if the result is + also a context-sensitive substitution. *) +val merge : t -> t -> t option + +(* Compose two lists of context-sensitive substitutions by only retaining those elements of the + "cartesian product" which satisfy the criteria. *) +val compose : t list -> t list -> t list + +(* Erase the "context" data in a context-sensitive substitution. *) +val eraseContext : t -> t + +(* Check whether a context-sensitive substitution satisfies a list of arithmetic constraints. *) +val satisfiesConstraints : t -> (Ast.aexp * Ast.op * Ast.aexp) list -> bool + +(* Produce a "varAss" (variable assignments) from a context-sensitive substitution. *) +val mkVarAss : t -> (string * string) list * (string * string) list * (string * string) list diff --git a/ClassicGEC/ClassicGECDotNet/database.fs b/ClassicGEC/ClassicGECDotNet/database.fs new file mode 100644 index 0000000..5946139 --- /dev/null +++ b/ClassicGEC/ClassicGECDotNet/database.fs @@ -0,0 +1,571 @@ +[] +module Microsoft.Research.GEC.Database + +open Microsoft.Research.GEC +open Microsoft.Research.FSBOLWrapper +open FSBOL +open FSBOL.Annotation +open FSBOL.ComponentDefinition +open FSBOL.ModuleDefinition +open FSBOL.FunctionalComponent +open FSBOL.Participation +open FSBOL.Interaction +open FSBOL.SBOLDocument +open FSBOL.TopLevel +open Parser +open System.Diagnostics + +//open Microsoft.Research.ModellingEngine +open Microsoft.Research.CRNEngine + +(* ************************************************************************************************* *) + +(* The different kinds of property that part types can have. *) + +type device = string * string list + + +type pcrProperty = CODES of string list * float +type promProperty = POS of string list * float * float * float + | NEG of string list * float * float * float + | CON of float + | FRATE of Ast.aexp +type rbsProperty = RATE of float + +(* An encoding of part types, along with their properties. *) +type partType = PCR of pcrProperty + | PROM of promProperty list + | RBS of rbsProperty + | TER + +let fold_string_list (strList:string list) (folder:string) = + match strList.Length with + | 0 -> "" + | 1 -> strList.Head + | _ -> strList.Tail |> List.fold (fun f s -> (f + folder + s)) strList.Head + +let device_to_string (d:device) = + let (devname,deviceComps) = d + devname + "[" + (fold_string_list deviceComps ";") + "]" + +(* Produce a string representation of a part type. *) +let string_of_partType (pt:partType) = + let string_of_promProperty = function + | POS(zs,q1,q2,q3) -> "pos(" + (Ast.complexString zs) + ", " + (Lib.display_float q1) + ", " + (Lib.display_float q2) + ", " + (Lib.display_float q3) + ")" + | NEG(zs,q1,q2,q3) -> "neg(" + (Ast.complexString zs) + ", " + (Lib.display_float q1) + ", " + (Lib.display_float q2) + ", " + (Lib.display_float q3) + ")" + | CON(q) -> "con(" + (Lib.display_float q) + ")" + | FRATE(a) -> "frate(" + (Ast.stringOfAExp a) + ")" + in + match pt with + | PCR(CODES(zs,q)) -> "pcr" + | PROM(pps) -> "prom<" + (Lib.string_of_list string_of_promProperty ", " pps) + ">" + | RBS(RATE(q)) -> "rbs" + | TER -> "ter" + +(* Compute FS(Q+t). *) +let speciesInPartType (qt:partType) : string list list = + let getPromPropertySpeciesNames = function POS(xs,_,_,_) | NEG(xs,_,_,_) -> [xs] | _ -> [] in + let snames = match qt with + | PCR(CODES(xs,_)) -> [xs] + | PROM(pps) -> Lib.collect_union Ast.complexesEqual getPromPropertySpeciesNames pps + | RBS _ | TER -> [] + in + Lib.remove_duplicates (=) snames + + + +(* ************************************************************************************************* *) + +(* A "database" consists of a "parts database" and a "reaction database". + A "parts database" is just a mapping of part identifiers (i.e. strings) to their part types. + A "reaction database" is just a list of reactions. *) +type 'a entry = { value:'a; enabled:bool; comments:string } +type t = { parts:partType entry Stringmap.t; devices: device list; reactions:Gecreaction.t entry list } + +let partTypeToSBOL (name:string) (p:partType entry)= + + let role = match p.value with + | PROM _ -> Role.Promoter + | RBS _ -> Role.RBS + | PCR _ -> Role.CDS + | TER -> Role.Terminator + + let renamedName = name.Replace("::","_") + let gecSO = "www.microsoft.com/gec#" + (*let RB = gecSO + "RB" + let RUB = gecSO + "RUB" + let RTB = gecSO + "RTB" + let RT = gecSO + "RT" + let R = gecSO + "R" + let RD = gecSO + "RD" + let P = gecSO + "P"*) + + let RB = "RB" + let RUB = "RUB" + let RTB = "RTB" + let RT = "RT" + let R = "R" + let RD = "RD" + let P = "P" + + + let annotations:Annotation list = + match p.value with + | PROM(a) -> + let propAnnotations = + a |> List.map(fun promprop -> + match promprop with + | POS(p,rb,rub,rtb) -> + let compositeName = p |> List.reduce(fun a b -> a + "::" + b) + [Helper.create_string_annotation (Name(P)) compositeName ; + Helper.create_double_annotation (Name(RB)) rb; + Helper.create_double_annotation (Name(RUB)) rub; + Helper.create_double_annotation (Name(RTB)) rtb] + | NEG(p,rb,rub,rtb) -> + let compositeName = p |> List.reduce(fun a b -> a + "::" + b) + [Helper.create_string_annotation (Name(P)) compositeName; + Helper.create_double_annotation (Name(RB)) rb; + Helper.create_double_annotation (Name(RUB)) rub; + Helper.create_double_annotation (Name(RTB)) rtb] + | CON(rt) -> + [Helper.create_double_annotation (Name(RT)) rt] + | _ -> []) + [0..(propAnnotations.Length-1)] + |> List.map (fun i -> + let na = NestedAnnotation(Name("PromoterProperty" + i.ToString() + "Annotations"),gecSO + "PromoterProperties",propAnnotations.Item(i)) + Annotation(Name("PromoterProperty" + i.ToString()),AnnotationValue.NestedAnnotation(na))) + | RBS(RATE(r)) -> [Helper.create_double_annotation (Name(R)) r] + | PCR(CODES(codes,rd)) -> + let compositeName = codes |> List.reduce(fun a b -> a + "::" + b) + [Helper.create_string_annotation (Name(P)) compositeName; + Helper.create_double_annotation (Name(RD)) rd] + | TER -> [] + + let version = "1" + let persistentId = "http://www.microsoft.com/gec/db/" + renamedName + "/" + let uri = persistentId + renamedName + "/" + version + "/" + let c = new ComponentDefinition(uri,Some(renamedName),Some(renamedName),Some(version),Some(persistentId),[],[ComponentDefinitionType.DNA],[role],[],[],[],[]) + c.annotations <- annotations + c + + +let createProteinCDs (tableList:((string*(partType entry))list)) = + let partTypes = tableList + |> List.map (fun (x,y) -> y.value) + let promProts = partTypes + |> List.choose ( fun x -> + match x with + | PROM(props) -> Some props + | _ -> None) + |> List.map (fun props -> + props |> List.map(fun prop -> + match prop with + | POS(p,rb,rub,rtb) -> Some(p |> List.reduce(fun a b -> a + "::" + b)) + | NEG(p,rb,rub,rtb) -> Some(p |> List.reduce(fun a b -> a + "::" + b)) + | _ -> None + ) + ) |> List.concat + |> List.filter (fun x-> + match x with + | Some(_) -> true + | None -> false + ) |> List.map (fun x -> x.Value) + + let cdsProts = partTypes + |> List.choose (fun x -> + match x with + | PCR(CODES(prots,r)) -> Some (prots,r) + | _ -> None + ) |> List.map (fun (prots,r) -> + prots |> List.reduce(fun a b -> a + "::" + b) + ) + + let prots = (promProts@cdsProts) |> Set.ofList |> List.ofSeq + prots |> List.map(fun protName -> + let renamedProt = protName.Replace("::","_") + let version = "1" + let persistentId = "http://www.microsoft.com/gec/db/" + renamedProt + "/" + let uri = persistentId + renamedProt + "/" + version + "/" + new ComponentDefinition(uri,Some(renamedProt),Some(renamedProt),Some(version),Some(persistentId),[],[ComponentDefinitionType.Protein],[],[],[],[],[])) + + +let createModuleDefinitions (cds:ComponentDefinition list) (tableList:((string*(partType entry))list))= + let urlPrefix = "http://www.microsoft.com/gec/db/" + let version = "1" + + + let findCDwithURI (uri:string) = + match cds |> List.tryFind (fun cd -> cd.uri = uri) with + | Some (x) -> x + | None -> failwith "Error. This CD should have been created in an earlier step" + let findCDwithDisplayID (display:string) = + let displayIdsMatch (cdDisplayId:string option) (display:string) = + match cdDisplayId with + | Some(d) -> (d=display) + | None -> failwith "Error. This CD should have a displayId created in an earlier step" + match cds |> List.tryFind (fun cd -> displayIdsMatch (cd.displayId) display) with + | Some(x) -> x + | None -> failwith "Error. This CD should have been created in an earlier step" + let pcrs = tableList + |> List.choose (fun (name,x) -> + match x.value with + | PCR(CODES(prots,r)) -> Some(name,prots,r) + | _ -> None + ) + + let proms = tableList + |> List.choose (fun (name,x) -> + match x.value with + | PROM(props) -> Some(name,props) + | _ -> None + ) + + let mds = + pcrs |> List.map (fun (pcrName,prots,r) -> + let compositeName = prots |> List.reduce(fun a b -> a + "_" + b) + let mdsinProms = + proms |> + List.map(fun (promName,props) -> + let mdsInProps = + props |> List.map(fun prop -> + match prop with + | POS(regList,_,_,_) -> + let compositeReg = regList |> List.reduce(fun a b -> a + "_" + b) + if compositeReg = compositeName then + let pcr_cd = findCDwithDisplayID pcrName + let prot_cd = findCDwithDisplayID compositeReg + let prom_cd = findCDwithDisplayID promName + + let compoundNameProd = pcrName + "_" + compositeName + let mdProd_name = compoundNameProd + "_production_md" + let mdProd_perId = urlPrefix + "/" + mdProd_name + "/" + let mdProd_uri = mdProd_perId + version + "/" + + let fc_pcr_name = pcrName + "_FC" + let fc_pcr_perId = urlPrefix + fc_pcr_name + "/" + let fc_pcr_uri = fc_pcr_perId + version + "/" + + let fc_prot_name = compositeName + "_protein_FC" + let fc_prot_perId = urlPrefix + fc_prot_name + "/" + let fc_prot_uri = fc_pcr_perId + version + "/" + + let fc_pcr = new FunctionalComponent(fc_pcr_uri,Some(fc_pcr_name),Some(fc_pcr_name),Some(version),Some(fc_pcr_perId),pcr_cd.uri,ComponentInstance.Access.Private,[],Direction.InOut) + let fc_prot = new FunctionalComponent(fc_prot_uri,Some(fc_prot_name),Some(fc_prot_name),Some(version),Some(fc_prot_perId),prot_cd.uri,ComponentInstance.Access.Private,[],Direction.InOut) + + let part_pcr_name = pcrName+"_participation" + let part_pcr_perId = urlPrefix + part_pcr_name + "/" + let part_pcr_uri = part_pcr_perId + version + "/" + + let part_prot_name = compositeName+"prot_participation" + let part_prot_perId = urlPrefix + part_prot_name + "/" + let part_prot_uri = part_prot_perId + version + "/" + + let part_pcr = new Participation(part_pcr_uri,Some(part_pcr_name),Some(part_pcr_name),Some(version),Some(part_pcr_perId),[ParticipationRole.Template],fc_pcr) + let part_prot = new Participation(part_prot_uri, Some(part_prot_name),Some(part_prot_name),Some(version),Some(part_prot_perId),[ParticipationRole.Product],fc_prot) + + let interactionProd_name = compoundNameProd + "_production_interaction" + let interactionProd_perId = mdProd_perId + "/" + interactionProd_name + "/" + let interactionProd_uri = interactionProd_perId + version + "/" + + let interactionProd = new Interaction(interactionProd_uri,Some(interactionProd_name),Some(interactionProd_name),Some(version),Some(interactionProd_perId),[InteractionType.GeneticProduction],[part_pcr;part_prot]) + + + let mdProd = new ModuleDefinition(mdProd_uri,Some(mdProd_name),Some(mdProd_name),Some(version),Some(mdProd_perId),[],[],[],[interactionProd],[fc_pcr;fc_prot],[]) + + let compoundNameStim = compositeName + "_" + promName + let mdStim_name = compoundNameStim + "_stimulation_md" + let mdStim_perId = urlPrefix + "/" + mdStim_name + "/" + let mdStim_uri = mdStim_perId + "/" + version + "/" + + let fc_complex_name = compositeName + "_complex_FC" + let fc_complex_perId = urlPrefix + fc_complex_name + "/" + let fc_complex_uri = fc_pcr_perId + version + "/" + + let fc_prom_name = promName + "_FC" + let fc_prom_perId = urlPrefix + fc_prom_name + "/" + let fc_prom_uri = fc_prom_perId + version + "/" + + let fc_complex = new FunctionalComponent(fc_complex_uri,Some(fc_complex_name),Some(fc_complex_name),Some(version),Some(fc_complex_perId),prot_cd.uri,ComponentInstance.Access.Private,[],Direction.InOut) + let fc_prom = new FunctionalComponent(fc_prom_uri,Some(fc_prom_name),Some(fc_prom_name),Some(version),Some(fc_prom_perId),prom_cd.uri,ComponentInstance.Access.Private,[],Direction.InOut) + + let part_complex_name = compositeName+"complex_participation" + let part_complex_perId = urlPrefix + part_complex_name + "/" + let part_complex_uri = part_complex_perId + version + "/" + + let part_prom_name = pcrName+"_participation" + let part_prom_perId = urlPrefix + part_prom_name + "/" + let part_prom_uri = part_prom_perId + version + "/" + + let part_complex = new Participation(part_complex_uri,Some(part_complex_name),Some(part_complex_name),Some(version),Some(part_complex_perId),[ParticipationRole.Stimulator],fc_complex) + let part_prom = new Participation(part_prom_uri,Some(part_prom_name),Some(part_prom_name),Some(version),Some(part_prom_perId),[ParticipationRole.Stimulated],fc_prom) + + let interactionStim_name = compoundNameStim + "_stimulation_interaction" + let interactionStim_perId = mdStim_perId + "/" + interactionStim_name + "/" + let interactionStim_uri = interactionStim_perId + "/" + version + "/" + + let interactionStim = new Interaction(interactionStim_uri,Some(interactionStim_name),Some(interactionStim_name),Some(version),Some(interactionStim_perId),[InteractionType.Stimulation],[part_complex;part_prom]) + + let mdStim = new ModuleDefinition(mdStim_uri,Some(mdStim_name),Some(mdStim_name),Some(version),Some(mdStim_perId),[],[],[],[interactionStim],[fc_complex;fc_prom],[]) + + Some([mdProd;mdStim]) + else + None + | NEG(regList,_,_,_) -> + let compositeReg = regList |> List.reduce(fun a b -> a + "::" + b) + if compositeReg = compositeName then + let pcr_cd = findCDwithDisplayID pcrName + let prot_cd = findCDwithDisplayID compositeReg + let prom_cd = findCDwithDisplayID promName + + let compoundNameProd = pcrName + "_" + compositeName + let mdProd_name = compoundNameProd + "_production_md" + let mdProd_perId = urlPrefix + "/" + mdProd_name + "/" + let mdProd_uri = mdProd_perId + version + "/" + + let fc_pcr_name = pcrName + "_FC" + let fc_pcr_perId = urlPrefix + fc_pcr_name + "/" + let fc_pcr_uri = fc_pcr_perId + version + "/" + + let fc_prot_name = compositeName + "_protein_FC" + let fc_prot_perId = urlPrefix + fc_prot_name + "/" + let fc_prot_uri = fc_pcr_perId + version + "/" + + let fc_pcr = new FunctionalComponent(fc_pcr_uri,Some(fc_pcr_name),Some(fc_pcr_name),Some(version),Some(fc_pcr_perId),pcr_cd.uri,ComponentInstance.Access.Private,[],Direction.InOut) + let fc_prot = new FunctionalComponent(fc_prot_uri,Some(fc_prot_name),Some(fc_prot_name),Some(version),Some(fc_prot_perId),prot_cd.uri,ComponentInstance.Access.Private,[],Direction.InOut) + + let part_pcr_name = pcrName+"_participation" + let part_pcr_perId = urlPrefix + part_pcr_name + "/" + let part_pcr_uri = part_pcr_perId + version + "/" + + let part_prot_name = compositeName+"prot_participation" + let part_prot_perId = urlPrefix + part_prot_name + "/" + let part_prot_uri = part_prot_perId + version + "/" + + let part_pcr = new Participation(part_pcr_uri,Some(part_pcr_name),Some(part_pcr_name),Some(version),Some(part_pcr_perId),[ParticipationRole.Template],fc_pcr) + let part_prot = new Participation(part_prot_uri, Some(part_prot_name),Some(part_prot_name),Some(version),Some(part_prot_perId),[ParticipationRole.Product],fc_prot) + + let interactionProd_name = compoundNameProd + "_production_interaction" + let interactionProd_perId = mdProd_perId + "/" + interactionProd_name + "/" + let interactionProd_uri = interactionProd_perId + version + "/" + + let interactionProd = new Interaction(interactionProd_uri,Some(interactionProd_name),Some(interactionProd_name),Some(version),Some(interactionProd_perId),[InteractionType.GeneticProduction],[part_pcr;part_prot]) + + + let mdProd = new ModuleDefinition(mdProd_uri,Some(mdProd_name),Some(mdProd_name),Some(version),Some(mdProd_perId),[],[],[],[interactionProd],[fc_pcr;fc_prot],[]) + + + let compoundNameInh = compositeName + "_" + promName + let mdInh_name = compoundNameInh + "_inhibition_md" + let mdInh_perId = urlPrefix + "/" + mdInh_name + "/" + let mdInh_uri = mdInh_perId + "/" + version + "/" + + let fc_complex_name = compositeName + "_complex_FC" + let fc_complex_perId = urlPrefix + fc_complex_name + "/" + let fc_complex_uri = fc_pcr_perId + version + "/" + + let fc_prom_name = promName + "_FC" + let fc_prom_perId = urlPrefix + fc_prom_name + "/" + let fc_prom_uri = fc_prom_perId + version + "/" + + let fc_complex = new FunctionalComponent(fc_complex_uri,Some(fc_complex_name),Some(fc_complex_name),Some(version),Some(fc_complex_perId),prot_cd.uri,ComponentInstance.Access.Private,[],Direction.InOut) + let fc_prom = new FunctionalComponent(fc_prom_uri,Some(fc_prom_name),Some(fc_prom_name),Some(version),Some(fc_prom_perId),prom_cd.uri,ComponentInstance.Access.Private,[],Direction.InOut) + + let part_complex_name = compositeName+"complex_participation" + let part_complex_perId = urlPrefix + part_complex_name + "/" + let part_complex_uri = part_complex_perId + version + "/" + + let part_prom_name = pcrName+"_participation" + let part_prom_perId = urlPrefix + part_prom_name + "/" + let part_prom_uri = part_prom_perId + version + "/" + + let part_complex = new Participation(part_complex_uri,Some(part_complex_name),Some(part_complex_name),Some(version),Some(part_complex_perId),[ParticipationRole.Inhibitor],fc_complex) + let part_prom = new Participation(part_prom_uri,Some(part_prom_name),Some(part_prom_name),Some(version),Some(part_prom_perId),[ParticipationRole.Inhibited],fc_prom) + + let interactionInh_name = compoundNameInh + "_inhibition_interaction" + let interactionInh_perId = mdInh_perId + "/" + interactionInh_name + "/" + let interactionInh_uri = interactionInh_perId + "/" + version + "/" + + let interactionInh = new Interaction(interactionInh_uri,Some(interactionInh_name),Some(interactionInh_name),Some(version),Some(interactionInh_perId),[InteractionType.Inhibition],[part_complex;part_prom]) + + let mdInh = new ModuleDefinition(mdInh_uri,Some(mdInh_name),Some(mdInh_name),Some(version),Some(mdInh_perId),[],[],[],[interactionInh],[fc_complex;fc_prom],[]) + + Some([mdProd;mdInh]) + else + None + | _ -> None) + |> List.filter (fun optionX -> + match optionX with + | Some (_) -> true + | None -> false) + |> List.map( fun x -> x.Value) + if mdsInProps.IsEmpty then + [] + else + mdsInProps |> List.reduce (fun a b -> a@b) + ) + if mdsinProms.IsEmpty then + [] + else + mdsinProms |>List.reduce (fun a b -> a@b) + ) + if mds.IsEmpty then + [] + else + mds |>List.reduce (fun a b -> a@b) + +let convertTableToSBOLDocument (table:t) = + let cds = table.parts |> List.ofSeq |> List.map (fun (x) -> (x.Key,x.Value)) |> List.map (fun (name,part) -> partTypeToSBOL name part) + + let protCds = createProteinCDs (table.parts |> List.ofSeq |> List.map (fun x -> (x.Key,x.Value))) + let allCds = (cds@protCds) + let mds = createModuleDefinitions allCds (table.parts |> List.ofSeq |> List.map (fun x -> (x.Key,x.Value))) + let collections = + (allCds |> List.map (fun x -> x :> TopLevel)) + @ (mds|> List.map (fun x -> x :> TopLevel)) + SBOLDocument(collections) + +(* The "empty" database. *) +let empty = { parts=Stringmap.empty; devices = []; reactions=[] } + +(* Produce a string representation of a database entry. *) +let string_of_entry (display:'a -> string) (entry:'a entry) : string = + let enabledStr = if entry.enabled then "[*] " else "[ ] " in + let valueStr = display entry.value in + let commentsStr = if entry.comments = "" then "" else " (Comments: \"" + entry.comments + "\")" in + enabledStr + valueStr + commentsStr + +(* Produce a string representation of a database. *) +let display (db:t) : string = + let partsString = Stringmap.fold (fun str x entry -> str + Lib.newline + x + " : " + (string_of_entry string_of_partType entry)) "" db.parts in + let reactionsString = Lib.fold_left (fun str entry -> str + Lib.newline + (string_of_entry Gecreaction.display entry)) "" db.reactions in + "PARTS:" + partsString + Lib.newline + Lib.newline + + "REACTIONS:" + reactionsString + Lib.newline + +(* Find out the part type for an identifer (if it exists). *) +let findPart (db:t) (id:string) : partType option = + match Stringmap.tryFind id db.parts with + | Some entry -> Some entry.value + | None -> None + +(* ************************************************************************************************* *) +(* Functions for adding entries to the database. *) + +(* Convert an abstractComplex into a string list, assuming it is "simple" (i.e. just strings...) *) +let convertSimpleComplex (vs:Ast.abstractComplex) : string list = + let convertSimpleValue (v:Ast.value) : string = + match v with + | Ast.IdVal x -> x + | _ -> failwith ("Only strings are allowed in species names in the database " + Lib.paren("found " + Ast.stringOfValue v)) + in + List.map convertSimpleValue vs + +(* Get a float from an Ast.value. *) +let getValueFloat (v:Ast.value) = + match v with + | Ast.FloatVal f -> f + | _ -> failwith ("Only float rates are allowed in the database " + Lib.paren("found " + Ast.stringOfValue v)) + + +type parser = Parser.t +type partParser = Parser.t + + + +let createEntry (id:string, part:partType) = + let entry:partType entry = {value = part;enabled = true;comments = ""} + (id,entry) + + +let createTable (partMapList:(string*partType)list) (devicelist:device list)= + let tableMap = partMapList |> List.map createEntry + {parts = Stringmap.of_list(tableMap); reactions=[]; devices = devicelist} + + + + +let TAB = Parser.kw "\t" +let COMMA = Parser.kw "," +let SEMICOLON = Parser.kw ";" + +let delimiter = COMMA //Primary delimiter +let sDelimiter = SEMICOLON //Secondary Delimiter used to separate elements or values within a cell + +let NEWLINE = Parser.newline + +let lookaheadLinebreak = Parser.pTry (Parser.linebreak >>. Parser.failParser "" <|> Parser.satisfy Parser.isWhiteSpace >>. preturn ()) +let spacesnlb :t = fun st -> + match many (commentLine <|> commentMultiline () <|> lookaheadLinebreak) <| st with + | OkEmpty (_, st') -> OkEmpty ("", st') + | OkConsumed (_, st') -> OkEmpty ("", st') + | FailEmpty _ -> OkEmpty ("", st) + | FailConsumed (e, p) -> FailConsumed (e, p) +let kwnlb s = pstring s .>> spacesnlb +let bracketnlb l r = Parser.between (Parser.kw l) (Parser.spaces >>. kwnlb r) + +let bracketNoSpace l r = Parser.between (Parser.pstring l) (Parser.spaces >>. Parser.pstring r) +let sqbracketNoSpace a = bracketnlb "[" "]" a +let parenNoSpace a = bracketnlb "(" ")" a +//let nameGEC = (Parser.many1Satisfy Parser.isLetter .>>. Parser.manySatisfy (fun c -> Parser.isLetter c || Parser.isDigit c || c = '_'|| c = '-' || c = '\'') |>> fun (a,b) -> a + b) "an identifier" + +let parsePos = Parser.kw "pos" >>. parenNoSpace(GecSpecies.parse_species .>> sDelimiter .>>. Parser.pfloat .>> sDelimiter .>>. Parser.pfloat .>> sDelimiter .>>. Parser.pfloat) |>> fun(((regBy,rb),rub),rtb) -> POS(regBy,rb,rub,rtb) +let parseNeg = Parser.kw "neg" >>. parenNoSpace(GecSpecies.parse_species .>> sDelimiter .>>. Parser.pfloat .>> sDelimiter .>>. Parser.pfloat .>> sDelimiter .>>. Parser.pfloat) |>> fun(((regBy,rb),rub),rtb) -> NEG(regBy,rb,rub,rtb) +let parseCon = Parser.kw "con" >>. parenNoSpace (Parser.pfloat) |>> fun (rt:float) -> CON(rt) + +let parsePromProperties = Parser.choice[ + parsePos + parseNeg + parseCon + ] + +let parseCodes = Parser.kw "codes" >>. parenNoSpace (GecSpecies.parse_species .>> sDelimiter .>>. Parser.pfloat) |>> fun ((codes:string list), rd:float) -> CODES(codes,rd) +(*let parseConstitutiveProm = parseCon |>> fun (con:promProperty) -> PROM([con]) +let parseRegulatedProm = (Parser.kw "pos" <|> Parser.kw "neg") .>>. parenNoSpace (nameGEC .>> sDelimiter .>>. Parser.pfloat .>> sDelimiter .>>. Parser.pfloat .>> sDelimiter .>>. Parser.pfloat) .>> sDelimiter .>>. parseCon |>> fun ((regType:string,((((regBy:string list),rb:float),rub:float),rtb:float)),conProp:promProperty) -> + match regType with + | "pos" -> PROM([POS(regBy,rb,rub,rtb);conProp]) + | "neg" -> PROM([NEG(regBy,rb,rub,rtb);conProp]) + | _ -> failwith ""*) + +let parseRate = Parser.kw "rate" >>. parenNoSpace (Parser.pfloat) |>> fun(r:float) -> RATE(r) + + +let pdevicedelim = Parser.kw "|" <|> Parser.kw ";" +let (parse_device:t) = Parser.name .>> Parser.spaces .>> Parser.kw "=" .>>. Parser.sqBrackets( Parser.sepBy (Parser.name .>> Parser.spaces) pdevicedelim) +let deviceParser = Parser.kw "devices" >>. + (Parser.sqBrackets (Parser.many parse_device)) .>> Parser.spaces + + + +type dnacomponent = + | Part of string * partType + | Device of device + +let parse_deviceComponents = Parser.kw "components" >>. sqbracketNoSpace (Parser.sepBy (Parser.name .>> Parser.spaces) pdevicedelim) + + +let partParser = + Parser.name .>> delimiter >>= fun n -> + Parser.choice [ + Parser.kw "prom" >>. delimiter >>. (Parser.sepBy parsePromProperties sDelimiter) |>> fun(props) -> Part(n,PROM(props)) + Parser.kw "rbs" >>. delimiter >>. parseRate |>> fun(rate) -> Part(n,RBS(rate)) + Parser.kw "pcr" >>. delimiter >>. parseCodes |>> fun(codes) -> Part(n,PCR(codes)) + pstring "ter" |>> fun (_) -> Part(n, TER) + Parser.kw "device" >>. delimiter >>. parse_deviceComponents |>> fun (components) -> Device(n,components) + ] + + +let fileParser = (Parser.sepBy partParser NEWLINE) + + +let parse = fileParser .>> Parser.eof |>> fun(components) -> + let partComponents = components |> List.choose + (fun x -> + match x with + | Part(x,y) -> Some(x,y) + | _ -> None) + let deviceList = components |> List.choose + (fun x -> + match x with + | Device(x) -> Some(x) + | _ -> None) + + createTable partComponents deviceList diff --git a/ClassicGEC/ClassicGECDotNet/database.fsi b/ClassicGEC/ClassicGECDotNet/database.fsi new file mode 100644 index 0000000..cc4d6cc --- /dev/null +++ b/ClassicGEC/ClassicGECDotNet/database.fsi @@ -0,0 +1,67 @@ +module Microsoft.Research.GEC.Database + +open Microsoft.Research.GEC +open FSBOL.ComponentDefinition +open FSBOL.ModuleDefinition +open FSBOL.SBOLDocument +//open Microsoft.Research.ModellingEngine +open Microsoft.Research.CRNEngine +open Parser + + +(* ************************************************************************************************* *) + +(* Devices. *) +type device = string * string list + +(* The different kinds of property that part types can have. *) +type pcrProperty = CODES of string list * float +type promProperty = POS of string list * float * float * float + | NEG of string list * float * float * float + | CON of float + | FRATE of Ast.aexp +type rbsProperty = RATE of float + + +(* An encoding of part types, along with their properties. *) +type partType = PCR of pcrProperty + | PROM of promProperty list + | RBS of rbsProperty + | TER + +(* Compute FS(Q^t). *) +val speciesInPartType : partType -> string list list + +(* ************************************************************************************************* *) + +(* A "database" consists of a "parts database" and a "reaction database". + A "parts database" is just a mapping of part identifiers (i.e. strings) to their part types. + A "reaction database" is just a list of reactions. *) +type 'a entry = { value:'a; enabled:bool; comments:string } +type t = { parts:partType entry Stringmap.t; devices: device list; reactions:Gecreaction.t entry list } + +val partTypeToSBOL: string -> (partType entry) -> ComponentDefinition +val createModuleDefinitions: (ComponentDefinition list) -> ((string*(partType entry))list) -> (ModuleDefinition list) +val convertTableToSBOLDocument: t -> SBOLDocument +val createProteinCDs: (string * (partType entry)) list -> ComponentDefinition list +(* The "empty" database. *) +val empty : t + +(* Produce a string representation of a database. *) +val display : t -> string + +(* Add a part to the database (part id must be unique). *) +//val addPart : t -> bool -> string -> string -> string -> string -> t + +(* Add a reaction to the database. *) +//val addReaction : t -> bool -> string -> string -> t + +type parser = Parser.t +val parse : parser + +type dnacomponent = + | Part of string * partType + | Device of device + +val partParser: Parser.t + diff --git a/ClassicGEC/ClassicGECDotNet/directivesParser.fs b/ClassicGEC/ClassicGECDotNet/directivesParser.fs new file mode 100644 index 0000000..6fe8ca7 --- /dev/null +++ b/ClassicGEC/ClassicGECDotNet/directivesParser.fs @@ -0,0 +1,580 @@ +[] +module Microsoft.Research.GEC.DirectivesParser + +open Microsoft.Research.CRNEngine +open Parser + +(**********************************************************************) +(**********************************************************************) +(************* Legacy CRN parser **************************************) +(**********************************************************************) +(**********************************************************************) +(* The code to parse directives in this section is duplicated from + SLConversion in Classic DSD. The original Lex grammar for the + Silver Light version of CRN and DSD were also duplicated + (ModellingEngineDotNet had its own parser.mly file, which was copied + and modified over in SLDNADotNet). The grammar for CRN directives + and species should be the same, but since there might + be subtle differences in the two copies of the mly files, + the conversion tool is also duplicated here. *) +(**********************************************************************) + +// utilities +let spaces = Parser.spaces +let choice = Parser.choice +let kw = Parser.kw +let preturn = Parser.preturn +let spFloat = Parser.pfloat .>> spaces +let spInt = Parser.pint32 .>> spaces +let spBool = choice [ kw "true" >>. preturn true + ; kw "false" >>. preturn false] .>> spaces +let spName = Parser.name .>> spaces +let paren = Parser.paren +let braces = Parser.braces +let sqBrackets = Parser.sqBrackets +let sepBy = Parser.sepBy +let sepBy1 = Parser.sepBy1 + +let fpMsg = "Floating point conversion not supported" + +type crnModuleDefinition = (string * string list) +type crnInstructions = ((crnModuleDefinition * Instruction list) list) * Instruction list + +type settings = {settings:Crn_settings; crn: crnInstructions option; overrideCrn: bool} + +type oldSimMode = JIT + | SSA + | OSLO of bool (* is stiff? *) + | SPACIAL_PERIODIC of int32 + | SUNDIALS of bool (* is stiff? *) + | CME_OSLO_OR_SUNDIALS of bool (* is stiff? *) (* the parser is ambiguous on "cme" *) + | LNA_OSLO of bool (* is stiff? *) + +type SpParam = Burnin of int32 + | SpSamples of int32 + | Thin of int32 + | SeparateNoise of bool + | NoiseModel of int + | Prune of bool + +type CoreElem = CoreW of float + | CoreI of float + | CoreO of float + +type PointElem = PointX of float + | PointY of float + | PointW of float + | PointV of float + +type ParSpace = ParReal | ParLog +type ParVar = ParFixed | ParRandomized | ParInitVal +type ParItem = ParAssign of string * float * float * float + | ParItem of string * float * float * float * ParSpace * ParVar + +type SweepVar = SweepVar of string list * Value list list + +type SweepItem = NamedSweep of string * SweepVar list + | UnnamedSweep of SweepVar + +type KMode = KContextual | KStochastic | KDeterministic + +type VerMode = Encoding of int32 + | Abstraction of int32 + | Enumeration of int32 + | PopBound of int32 + | DummyRxn of bool + | EnfInitial of bool + +type oldDirective = Samples of float option * float option * int32 option // start, end, points + | DurationPoints of float option * float option * int32 option // start, end, points + | Scale of float + | Plot of Expression.t list + | Simulation of oldSimMode + | RelTolerance of float + | Tolerance of float // maps to abstolerance in deterministic + | Seed of int32 + // | SpecMax of Species.t * int32 + | OldTime of Time + | Concentration of Concentration + | Dt of float + | XMax of float + | Nx of int32 + | Theta of float + | Params of ParItem list + | Sweeps of SweepItem list + | FitRun of SpParam list + | Kinectics of KMode + | Crn of crnInstructions * bool +// | Verification of VerMode +// | StabilityCorrection of float +// | CoaxialDAngle of float +// | DoubleCoaxialDAngle of float +// | Temperature of float +// | TerminalDAngle of float + +// Tokens +let SAMPLE = kw "sample" +let ALL = kw "all" +let PLOT = kw "plot" +let POINTS = kw "points" +let DURATION = kw "duration" +let SCALE = kw "scale" +let SEED = kw "seed" +let SIMULATION = kw "simulation" +let DETERMINISTICSTIFF = kw "deterministicstiff" +let RELTOLERANCE = kw "reltolerance" +let TOLERANCE = kw "tolerance" <|> kw "abstolerance" +let EVENT = kw "event" +let SPECMAX = kw "specmax" +let TIME = kw "time" +let CONCENTRATION = kw "concentration" +let DT = kw "dt" +let XMAX = kw "xmax" +let NX = kw "nx" +let THETA = kw "theta" +let COAXIALDANGLE = kw "coaxialDangle" +let DOUBLECOAXIALDANGLE = kw "doubleCoaxialDangle" +let COAXIALCORRECTION = kw "coaxialCorrection" +let TEMPERATURE = kw "temperature" +let TERMINALDANGLE = kw "terminalDangle" +let SPATIALIC = kw "spatialic" +let SPATIALBC = kw "spatialbc" +let SPATIALPLOT = kw "spatialplot" +//let COMPILATION = kw "compilation" +let DECLARE = kw "declare" +let DEFAULTDIFFUSION = kw "defaultdiffusion" +let DIFFUSION = kw "diffusion" +let LEAKS = kw "leaks" +let PINLEAK = kw "pinleak" +let PINLEAKS = kw "pinleaks" +let LENGTHS = kw "lengths" +let MIGRATE = kw "migrate" +let LOCALCONCENTRATIONS = kw "localconcentrations" +let POLYMERS = kw "polymers" +let SEQUENCERATES = kw "sequenceRates" +let STABILITYCORRECTION = kw "stabilityCorrection" +let TAU = kw "tau" +let TOEHOLDS = kw "toeholds" +let UNPRODUCTIVE = kw "unproductive" +let VERIFICATION = kw "verification" +let FIT = kw "fit" +let FITRUN = kw "fit_run" +let KINETICS = kw "kinetics" +let PARAMETERS = kw "parameters" +let PLOTWINDOW = kw "plotwindow" +let PREDICATES = kw "predicates" +let SWEEP = kw "sweep" +let CRN = kw "crn" +let OVERRIDE = kw "override" + +let COMMA = kw "," +let SEMI = kw ";" +let AT = kw "@" +let UNDERSCORE = kw "_" +let SUM = kw "sum" +let SUB = kw "sub" +let DIFF = kw "diff" +let PROD = kw "prod" +let DIV = kw "div" +let EQUAL = kw "=" +let DLBRACKET = kw "[[" +let DRBRACKET = kw "]]" +let BAR = kw "|" + +(* each function below parses a specific "directive" string *) +// samples directive +let dirSamples = + SAMPLE >>. Expression.parse spFloat >>= fun x -> + choice [ COMMA >>. Expression.parse spFloat >>= fun y -> + choice [ ALL >>. preturn (Some (Expression.eval id x), Some (Expression.eval id y), Some 0) + ; spInt >>= fun z -> preturn (Some (Expression.eval id x), Some (Expression.eval id y), Some z) + ; preturn (Some (Expression.eval id x), Some (Expression.eval id y), None) ] + ; ALL >>. preturn (None, Some (Expression.eval id x), Some 0) + ; spInt >>= fun y -> preturn (None, Some (Expression.eval id x), Some y) + ; preturn (None, Some (Expression.eval id x), None) ] + >>= (Samples >> preturn) // wraps the result inside Samples + +// duration directive +let dirDuration = + DURATION >>. spFloat >>= fun x -> + choice [ COMMA >>. spFloat >>= fun y -> + choice [ POINTS >>. + choice [ ALL >>. preturn (Some x, Some y, Some 0) + ; spInt >>= fun z -> preturn (Some x, Some y, Some z) ] + ; preturn (Some x, Some y, None) ] + ; POINTS >>. choice [ ALL >>. preturn (None, Some x, Some 0) + ; spInt >>= fun y -> preturn (None, Some x, Some y) ] + ; preturn (None, Some x, None) ] + >>= (DurationPoints >> preturn ) + +// seed directive +let dirSeed = SEED >>. spInt >>= (Seed >> preturn) + +// old molecule parser + // TODO: double check that "--(cogs)" | "--(+ cogs)" | "--(cogs+)" is not used anymore + +// plots +// TODO check empty plot "()" is parsed correctly with many or sepBy, double check that many1 or sepBy1 is not misused +let pPlot pSpecies = Expression.parse pSpecies + + +// plots directive +let pPlots pSpecies sp = Parser.sepBy1 (pPlot pSpecies) SEMI sp +let dirPlot pSpecies = PLOT >>. pPlots pSpecies >>= (Plot >> preturn) + + +let curry f (a, b) = f a b + +//let dirSpecMax = SPECMAX >>. DSDParser.speciesParser .>>. spInt >>= (SpecMax >> preturn) +let dirTime = + let s = Time.Seconds 1.0 + let m = Time.Seconds 6.0 + let h = Time.Seconds 3.6 + let d = Time.Seconds 8.64 + let ret = OldTime >> preturn + TIME >>. choice [ kw "seconds" >>. ret s + ; kw "s" >>. ret s + ; kw "minutes" >>. ret m + ; kw "m" >>. ret m + ; kw "hours" >>. ret h + ; kw "h" >>. ret h + ; kw "days" >>. ret d + ; kw "d" >>. ret d ] + +let dirConcentration = + let m = Concentration.Molar 0 + let mM = Concentration.Molar -3 + let uM = Concentration.Molar -6 + let nM = Concentration.Molar -9 + let pM = Concentration.Molar -12 + let fM = Concentration.Molar -15 + let aM = Concentration.Molar -18 + let zM = Concentration.Molar -21 + let yM = Concentration.Molar -24 + let ret = Concentration >> preturn + CONCENTRATION >>. choice [ kw "molar" >>. ret m + ; kw "M" >>. ret m + ; kw "milimolar" >>. ret mM + ; kw "mM" >>. ret mM + ; kw "millimolar" >>. ret mM + ; kw "micromolar" >>. ret uM + ; kw "uM" >>. ret uM + ; kw "nanomolar" >>. ret nM + ; kw "nM" >>. ret nM + ; kw "picomolar" >>. ret pM + ; kw "pM" >>. ret pM + ; kw "femtomolar" >>. ret fM + ; kw "fM" >>. ret fM + ; kw "attomolar" >>. ret aM + ; kw "aM" >>. ret aM + ; kw "zeptomolar" >>. ret zM + ; kw "zM" >>. ret zM + ; kw "yoctomolar" >>. ret yM + ; kw "yM" >>. ret yM ] +let dirRelativeTolerance = RELTOLERANCE >>. spFloat >>= (RelTolerance >> preturn) +let dirTolerance = TOLERANCE >>. spFloat >>= (Tolerance >> preturn) +let dirScale = SCALE >>. spFloat >>= (Scale >> preturn) + +// simulation +let dirSimulation = + SIMULATION >>. choice [ kw "jit" >>. preturn (Simulation JIT) + ; kw "stochastic" >>. preturn (Simulation SSA) + ; kw "deterministicstiff" >>. preturn (Simulation (OSLO true)) + ; kw "deterministic" >>. preturn (Simulation (OSLO false)) + ; kw "spatial1d" >>. preturn (Simulation (SPACIAL_PERIODIC 1)) + ; kw "spatial2d" >>. preturn (Simulation (SPACIAL_PERIODIC 2)) + ; kw "sundials" >>. preturn (Simulation (SUNDIALS false)) + ; kw "sundialsstiff" >>. preturn (Simulation (SUNDIALS true)) + ; kw "cme" >>. preturn (Simulation (CME_OSLO_OR_SUNDIALS false)) + ; kw "cmestiff" >>. preturn (Simulation (CME_OSLO_OR_SUNDIALS true)) + ; kw "lna" >>. preturn (Simulation (LNA_OSLO false)) + ; kw "lnastiff" >>. preturn (Simulation (LNA_OSLO true)) ] + +let dirDT = DT >>. spFloat >>= (Dt >> preturn) +let dirXMax = XMAX >>. spFloat >>= (XMax >> preturn) +let dirNX = NX >>. spInt >>= (Nx >> preturn) +let dirTheta = THETA >>. spFloat >>= (Theta >> preturn) + +// spatial directives +// TODO: Add spatial directives +let spatialErrorMsg _ = failwith "spatial directives not supported" +let dirSpatialic = SPATIALIC >>= spatialErrorMsg + + + +let dirSpatialbc = SPATIALBC >>= spatialErrorMsg +let dirSpatialPlot = SPATIALPLOT >>= spatialErrorMsg + +let dirDiffusion = DIFFUSION >>= spatialErrorMsg +let dirDefaultDiffusion = DEFAULTDIFFUSION >>= spatialErrorMsg + +// parameters +let paramP = + let f n x y z pType = choice + [ kw "fixedvar" >>. preturn (ParItem (n, x, y, z, pType, ParFixed)) + ; kw "fixed" >>. preturn (ParItem (n, x, y, z, pType, ParFixed)) + ; kw "randomized" >>. preturn (ParItem (n, x, y, z, pType, ParRandomized)) + ; kw "random" >>. preturn (ParItem (n, x, y, z, pType, ParRandomized)) + ; kw "init" >>. preturn (ParItem (n, x, y, z, pType, ParInitVal)) + ; kw "initval" >>. preturn (ParItem (n, x, y, z, pType, ParInitVal)) ] + spName >>= fun n -> + choice [ EQUAL >>. spFloat >>= fun f -> preturn (ParAssign (n, f, f, f)) + ; COMMA >>. Parser.paren (spFloat .>> COMMA .>>. spFloat) .>> COMMA .>>. spFloat .>> COMMA + >>= fun ((x,y), z) -> + choice [ kw "realspace" >>. COMMA >>. f n x y z ParReal + ; kw "real" >>. COMMA >>. f n x y z ParReal + ; kw "log" >>. COMMA >>. f n x y z ParLog + ; kw "logspace" >>. COMMA >>. f n x y z ParLog ] ] + +let dirParameters = PARAMETERS >>. Parser.sqBrackets (sepBy1 paramP SEMI) >>= (Params >> preturn) + +// sweeps +let namesList = Parser.sepBy1 spName COMMA + +let valList = Parser.sepBy1 (Expression.parse spName) COMMA +let valListP = Parser.paren valList +let valTuples = Parser.sepBy1 valListP COMMA + +let varSweep = choice [ Parser.paren namesList .>> EQUAL .>>. Parser.sqBrackets valTuples + >>= (SweepVar >> preturn) + ; spName .>> EQUAL .>>. Parser.sqBrackets valList >>= fun (n, xs) -> + preturn (SweepVar ([n], List.map (fun x -> [x]) xs)) ] +let combSweep = Parser.sepBy1 varSweep COMMA + +let dirSweep = + SWEEP >>. + choice [ paren namesList .>> EQUAL .>>. sqBrackets valTuples >>= + (SweepVar >> UnnamedSweep >> (fun x -> [x]) >> Sweeps >> preturn) + ; spName .>> EQUAL >>= fun n -> + choice [ braces combSweep >>= (fun x -> preturn (Sweeps [NamedSweep (n, x)])) + ; sqBrackets valList >>= (fun x -> preturn (Sweeps [UnnamedSweep (SweepVar ([n], [x]))])) ] ] + + +let dirCrn = + CRN >>. Parser.choice[ + OVERRIDE >>. Parser.braces (Instruction.parse Species.parse Crn_settings.defaults) |>> fun x -> Crn(x,true) + Parser.braces (Instruction.parse Species.parse Crn_settings.defaults) |>> fun x -> Crn(x,false) + ] + +// fit +let dirFit = FIT >>= fun _ -> failwith "fit not supported" + +// fit run +let fitElem = + choice [ kw "burnin" >>. EQUAL >>. spInt >>= (Burnin >> preturn) + ; kw "samples" >>. EQUAL >>. spInt >>= (SpSamples >> preturn) + ; kw "thin" >>. EQUAL >>. spInt >>= (Thin >> preturn) // TODO: default = findintdef "thin" 10 t + ; kw "separatenoise" >>. EQUAL >>. spBool >>= (SeparateNoise >> preturn) // TODO: default = findbooldef true t + ; kw "noisemodel" >>. EQUAL >>. spInt >>= (NoiseModel >> preturn) // TODO: Constant t + ; kw "prune" >>. EQUAL >>. spBool >>= (Prune >> preturn) // TODO: default true t } + ] +let fitRecord = braces (sepBy1 fitElem SEMI) +let dirFitRun sp = (FITRUN >>. fitRecord >>= (FitRun >> preturn)) sp + +// plot window, kinectics +let dirPlotWindow = PLOTWINDOW >>= fun _ -> failwith "plot window not supported" +let dirKinectics = KINETICS >>. choice [ kw "contextual" >>. preturn (Kinectics KContextual) + ; kw "stochastic" >>. preturn (Kinectics KStochastic) + ; kw "deterministic" >>. preturn (Kinectics KDeterministic) ] + +// verification +let dirVerification = VERIFICATION >>= fun _ -> failwith "verification not supported" + + +let pOldDirectives pSpecies = [ dirConcentration + ; dirDT + ; dirDefaultDiffusion + ; dirDiffusion + ; dirDuration + ; dirFit + ; dirFitRun + ; dirKinectics + ; dirNX + ; dirParameters + ; dirPlot pSpecies + ; dirPlotWindow + ; dirRelativeTolerance + ; dirSamples + ; dirScale + ; dirSeed + ; dirSimulation + ; dirSpatialbc + ; dirSpatialic + ; dirSpatialPlot + ; dirSweep + ; dirTheta + ; dirTime + ; dirTolerance + ; dirVerification + ; dirXMax + ; dirCrn] +let oldDirective pSpecies = choice (pOldDirectives pSpecies) + +let oldToCrnParam param = + match param with + | ParAssign (n, f1, f2, f3) -> + let par : Parameter = + { name = n + ; value = f3 + ; prior = Some { interval = Interval.Real + ; variation = Variation.Fixed + ; distribution = Distribution.Uniform {min = f1; max = f2} } } + par + | ParItem (n, f1, f2, f3, parSpace, parVar) -> + let pr : Prior = { interval = match parSpace with + | ParReal -> Interval.Real + | ParLog -> Interval.Log + ; variation = match parVar with + | ParFixed -> Variation.Fixed + | ParRandomized -> Variation.Random + | ParInitVal -> Variation.Initial2 + ; distribution = Distribution.Uniform {min = f1; max = f2}} + let par : Parameter = { name = n + ; value = f3 + ; prior = Some pr } + par + + +let oldToCrnSweepVar (SweepVar (names, values)) : Assignment = + { variables = names + ; values = values } + + +let sweep_id = ref 0 +let new_sweep_name () = + let id = !sweep_id + 1 in + sweep_id := id + "sweep_" + id.ToString() // the hard-coded "sweep_" is from the old DNA solution + +let oldToCrnSweep (sweep:SweepItem) = + match sweep with + | UnnamedSweep sweep -> let newName = new_sweep_name() + Sweep.create(newName,[oldToCrnSweepVar sweep]) + | NamedSweep (n, sweeps) -> let asns = List.map oldToCrnSweepVar sweeps + Sweep.create(n,asns) + + +let fromOpt m x = match m with + | None -> x + | Some y -> y + +let updateSettings (cs : settings ) oldDir = + match oldDir with + | Samples (startOpt, endOpt, pointsOpt) + | DurationPoints (startOpt, endOpt, pointsOpt) -> + {cs with settings = {cs.settings with simulation = {cs.settings.simulation with points = fromOpt pointsOpt cs.settings.simulation.points + ; initial = fromOpt startOpt cs.settings.simulation.initial + ; final = fromOpt endOpt cs.settings.simulation.final}}} + | Scale f -> { cs with settings = {cs.settings with stochastic = { cs.settings.stochastic with scale = f }}} + | Plot ps -> { cs with settings = {cs.settings with simulation = { cs.settings.simulation with plots = List.map (Expression.map Key.Species) ps @ cs.settings.simulation.plots}}} + | Simulation smode -> + {cs with settings = {cs.settings with simulator = + match smode with + | JIT -> Simulator.SSA + | SSA -> Simulator.SSA + | OSLO _ -> Simulator.Oslo + | SPACIAL_PERIODIC _ -> Simulator.PDE + | SUNDIALS _ -> Simulator.Sundials + | CME_OSLO_OR_SUNDIALS _ -> Simulator.CME + | LNA_OSLO _ -> Simulator.LNA + ; deterministic = { + cs.settings.deterministic with + stiff = match smode with + | OSLO isStiff -> isStiff + | LNA_OSLO isStiff -> isStiff + | SUNDIALS isStiff -> isStiff + | CME_OSLO_OR_SUNDIALS isStiff -> isStiff + | SPACIAL_PERIODIC _ -> false + | SSA -> false + | JIT -> false + } + ; simulation = cs.settings.simulation + }} // TODO: add dimensions to spatial settings + | RelTolerance f -> { cs with settings = {cs.settings with deterministic = { cs.settings.deterministic with reltolerance = f }}} + | Tolerance f -> { cs with settings = {cs.settings with deterministic = { cs.settings.deterministic with abstolerance = f }}} + | Seed i -> { cs with settings = {cs.settings with simulation = { cs.settings.simulation with seed = Some i}}} + | OldTime _ -> cs + | Concentration _ -> cs + | Dt f -> { cs with settings = {cs.settings with spatial = { cs.settings.spatial with dt = f }}} + | XMax f -> { cs with settings = {cs.settings with spatial = { cs.settings.spatial with xmax = f }}} + | Nx i -> { cs with settings = {cs.settings with spatial = { cs.settings.spatial with nx = i }}} + | Theta _ -> failwith "theta directive not supported in the spatial simulator" + | Params ps -> { cs with settings = {cs.settings with parameters = List.map oldToCrnParam ps }} + | Sweeps ss -> { cs with settings = {cs.settings with sweeps = List.map oldToCrnSweep ss }} + | FitRun ps -> + let updateSpSet (inf:Inference_settings) spParam = + match spParam with + | Burnin i -> { inf with burnin = i} + | SpSamples i -> { inf with samples = i} + | Thin i -> { inf with thin = i } + | SeparateNoise b -> { inf with noise_parameter = if b + then Noise_parameter.Multiple + else Noise_parameter.Random} + | NoiseModel i -> { inf with noise_model = match i with + | 0 -> Noise_model.Constant + | 1 -> Noise_model.Proportional + | _ -> failwith "Unrecognised noise model. Use linear or proportional." } + | Prune b -> { inf with prune = b} + { cs with settings = {cs.settings with inference = List.fold updateSpSet cs.settings.inference ps }} + | Kinectics kmode -> + { cs with settings = + {cs.settings with + simulation = + {cs.settings.simulation with + kinetics = + match kmode with + | KContextual -> Kinetics.Contextual + | KStochastic -> Kinetics.Stochastic + | KDeterministic -> Kinetics.Deterministic } }} + | Crn (instructions,ovveride) -> {cs with crn = Some(instructions); overrideCrn = ovveride} + +let parseOldDirectives pSpecies : Parser.t = + Parser.many (Parser.kw "directive" >>. oldDirective pSpecies) + .>> spaces + >>= (fun oldSettings -> let def : settings = {settings=Crn_settings.defaults;crn=None;overrideCrn=false} + let settings = List.fold updateSettings def oldSettings + preturn settings) + +(* legacy CRN parser, parses the body of a CRN written in the Silver Light tool's syntax. + The parser is parametric to the species, to allow species names such as '""' + for testing purposes in Classic DSD. *) +(*type instruction = + | Reaction of Reaction + | Initial of Initial + +let convert_instructions (instructions:instruction list) = + let f (reactions,initials) command = + match command with + | Reaction reaction -> reaction::reactions, initials + | Initial initial -> reactions, initial::initials + let reactions, initials = List.fold f ([],[]) instructions + List.rev reactions, List.rev initials + +let create_from_instructions (settings:Crn_settings) (instructions:instruction list) = + let reactions,initials = convert_instructions instructions + Crn.create "" settings reactions initials Stringmap.empty + +let parse_legacy_SL pSpecies = + let zeroVal (init : float) = Expression.Float init + let zero = Expression.Float 0.0 + let unitVal = Expression.Float 1.0 + + // base parsers + let pValue = Expression.parse (Parser.name .>> Parser.spaces) + let pExpr = Expression.parse (Key.parse pSpecies) + + // crn parsers + let pInitial iv = Initial.parse pSpecies pValue zero (zeroVal iv) |>> Initial + let pConstant iv = Parser.kw "constant" >>. pSpecies .>>. pValue >>= fun (sp, v) -> + Parser.preturn (Initial.create(true, v, sp, (zeroVal iv), None) |> Initial) + let pEvent = Parser.kw "event" >>. pSpecies .>>. pValue .>> Parser.kw "@" .>>. pValue + >>= fun ((sp, amount), time) -> Parser.preturn (Initial.create(false, amount, sp, time, None) |> Initial) + let pReaction = Reaction.parse pSpecies pValue pExpr unitVal |>> Reaction + let pLine iv = (pConstant iv <|> pEvent <|> pInitial iv) <|> pReaction + let pBar = Parser.kw "|" + + // full CRN parser + parseOldDirectives pSpecies >>= fun settings -> + Parser.spaces >>. Parser.opt pBar + >>. Parser.sepBy (pLine settings.settings.simulation.initial) pBar + |>> create_from_instructions settings.settings*) \ No newline at end of file diff --git a/ClassicGEC/ClassicGECDotNet/gec.fs b/ClassicGEC/ClassicGECDotNet/gec.fs new file mode 100644 index 0000000..fb4a633 --- /dev/null +++ b/ClassicGEC/ClassicGECDotNet/gec.fs @@ -0,0 +1,783 @@ +[] +module Microsoft.Research.GEC.GECEngine + +open System +open Microsoft.Research.GEC +open Microsoft.Research.CRNEngine +//open Microsoft.Research.ModellingEngine +open Microsoft.Research.CRNEngine +open FSBOL +open FSBOL.JsonSerializer +open FSBOL.SBOLDocument +open FSBOL.TopLevel +open FSBOL.ComponentDefinition +open Microsoft.Research.CRNEngine.InferenceSiteGraph +open Microsoft.Research.GEC.Trans +open Microsoft.Research.GEC.Settings +open Microsoft.Research.GEC.Program +open Microsoft.Research.FSBOLWrapper + +(* Main GUI datatype. *) +type t = { + options:Options.t; + database:Database.t; + solution:(Ast.directive list * Main.tSolution * Trans.gecConstraint list * Trans.tArithmeticConstraints * string list) option + } +let empty = {options = Options.default_options; database = Database.empty; solution = None} + +(******************************************************************************) +(* *** Get/set GUI options. *) + +(* Get or set the "options" part of the GUI data structure. *) +let getOptions (gec:t) = gec.options +let setOptions (opts:Options.t) (gec:t) = {gec with options = opts} + +(* Get, set or erase the "solution" part of the GUI data structure. *) +let setSolution (ds:Ast.directive list) (sol:Main.tSolution) (prologConstraints:Trans.gecConstraint list) (arithmeticConstraints:Trans.tArithmeticConstraints) + (log:string list) (gec:t) = {gec with solution = Some (ds, sol,prologConstraints,arithmeticConstraints,log)} +let getSolution (gec:t) = gec.solution +let eraseSolution (gec:t) = {gec with solution = None} + +(* Access the parts and reactions database. *) +let getDatabase (gec:t) = gec.database +let setDatabase (db:Database.t) (gec:t) = {gec with database = db} + +(* Produce a string representation of the results of the translation process, for debugging purposes... *) +let getDebuggingOutput (g:t) = + match (getSolution g) with + | None -> "" + | Some (ds, sol,prologConstraints,arithmeticConstraints,log) -> + let bbTemplatesDebug = Lib.string_of_list (fun xs -> "[" + (Lib.string_of_list Lib.id "; " xs) + "]") Lib.newline sol.bbDevices in + let prologConstraintsDebug = Lib.string_of_list Trans.printConstraint Lib.newline prologConstraints in + let arithmeticConstraintsDebug = Lib.string_of_list Trans.stringOfArithmeticConstraint Lib.newline arithmeticConstraints in + let lbsProgDebug = Trans.lbsProgToStr sol.lbsProgram [] in // is empty list OK here for varDefs? + let rateDecsDebug = Lib.string_of_list (fun (r,f) -> r + " |==> " + (Lib.display_float f)) Lib.newline sol.rateDecs in + let varAssDebug = sol.getVarAssString() in + let databaseDebug = Database.display (getDatabase g) in + let logDebug = Lib.string_of_list Lib.id Lib.newline log in + let directivesDebug = match ds with [] -> "" | ds -> Lib.string_of_list Ast.stringOfDirective Lib.newline ds in + "bbTemplates:" + Lib.newline + + "============" + Lib.newline + + bbTemplatesDebug + Lib.newline + Lib.newline + + "rateDecs:" + Lib.newline + + "=========" + Lib.newline + + rateDecsDebug + Lib.newline + Lib.newline + + "varAss:" + Lib.newline + + "=======" + Lib.newline + + varAssDebug + Lib.newline + Lib.newline + + "Arithmetic constraints:" + Lib.newline + + "=======================" + Lib.newline + + arithmeticConstraintsDebug + Lib.newline + Lib.newline + + "Database:" + Lib.newline + + "=========" + Lib.newline + + databaseDebug + Lib.newline + Lib.newline + + "lbsProg:" + Lib.newline + + "========" + + lbsProgDebug + Lib.newline + Lib.newline + + "directives:" + Lib.newline + + directivesDebug + Lib.newline + Lib.newline + + "PROLOG Constraints:" + Lib.newline + + "============" + Lib.newline + + prologConstraintsDebug + Lib.newline + Lib.newline + + "log:" + Lib.newline + + "====" + Lib.newline + + logDebug + Lib.newline + +(* LBS program text. *) +let getGECProgramText (g:t) = Options.getGECProgramText (getOptions g) +let setGECProgramText (s:string) (g:t) = setOptions (Options.setGECProgramText s (getOptions g)) g + +(* Option to enable simulation-only reactions. *) +let getSimulationOnlyReactionsOption (g:t) = Options.getSimulationOnlyReactions (getOptions g) +let setSimulationOnlyReactionsOption (b:bool) (g:t) = setOptions (Options.setSimulationOnlyReactions b (getOptions g)) g + +(******************************************************************************) +(* *** Access other information from the datatypes. *) + +(* Have the options changed enough to warrant recompilation? *) +let identicalOptions (gold:t) (gnew:t) = + ((getGECProgramText gold) = (getGECProgramText gnew)) && + ((getSimulationOnlyReactionsOption gold) = (getSimulationOnlyReactionsOption gnew)) && + ((getDatabase gold) = (getDatabase gnew)) + +(* Maybe prefix some directives onto an LBS program. *) +let prefixDirectives (ds:Ast.directive list) (body:string) = + match ds with + | [] -> body + | ds -> (Lib.string_of_list Ast.stringOfDirective Lib.newline ds) + Lib.newline + Lib.newline + body + +(* Get the "default" LBS program, i.e. with general reactions (no substitution applied). *) +let getDefaultLBSProgram (g:t) = + match (getSolution g) with + | Some(ds,sol,_,_,_) -> Some(prefixDirectives ds (sol.getProgramDefault())) + | None -> None + +(* Get a particular LBS program instance, corresponding to a particular set of variable instantiations. *) +let getLBSProgramInstance (num:int) (g:t) = + match (getSolution g) with + | Some(ds,sol,_,_,_) -> + let ds = List.map (Subst.applyToDirective (List.item num sol.substs)) ds in + Some(prefixDirectives ds (sol.getProgramInstance(num))) + | None -> None + +(* Get a particular species instance. *) +let getSpeciesAssignment (num:int) (g:t) = + match (getSolution g) with + | Some(_,sol,_,_,_) -> sol.getSpecAss(num) + | None -> "" + +(* Get a particular devices instance. *) +let getDevicesInstance (num:int) (g:t) = + match (getSolution g) with + | Some(_,sol,_,_,_) -> sol.getDevicesInstance(num) + | None -> "" + +(* Get a particular devices instance as a string list list *) +let getDevicesInstanceStructured (num:int) (g:t) = + match (getSolution g) with + | Some(_,sol,_,_,_) -> sol.getDevicesInstanceStructured(num) + | None -> List.toArray([]) + +(* Get the number of solutions. *) +let getNumSolutions (g:t) = + match (getSolution g) with + | Some(_,sol,_,_,_) -> sol.numSolutions + | None -> 0 + +(* Get the directives text (if any). *) +let getDirectives (g:t) = + match (getSolution g) with + | Some(ds,_,_,_,_) -> Some ds + | None -> None + +(******************************************************************************) +(* Process a GEC program. *) + +let reduce_gecprog (prog:Ast.prog) = + let rec reduce (p:Ast.prog)= + match p with + | Ast.Par(p1,p2) -> + let rp1 = reduce p1 + let rp2 = reduce p2 + match rp1 with + | Ast.Nil -> + match rp2 with + | Ast.Nil -> Ast.Nil + | _ -> rp2 + | _ -> + match rp2 with + | Ast.Nil -> rp1 + | _ -> Ast.Par(rp1,rp2) + | Ast.Seq(p1,p2) -> + let rp1 = reduce p1 + let rp2 = reduce p2 + match rp1 with + | Ast.Nil -> + match rp2 with + | Ast.Nil -> Ast.Nil + | _ -> rp2 + | _ -> + match rp2 with + | Ast.Nil -> rp1 + | _ -> Ast.Seq(rp1,rp2) + | Ast.Comp(c,p1) -> Ast.Comp(c,reduce p1) + | Ast.New(n,p1) -> Ast.New(n,reduce p1) + | Ast.TemplateDef(tname,targs,p1,p2) -> Ast.TemplateDef(tname,targs,reduce p1, reduce p2) + | Ast.Copy(i,p1,b1,b2) -> Ast.Copy(i,reduce p1,b1,b2) + | _ -> p + reduce prog + + +let unroll_gecprog (gecprog:ClassicProgram) = + let template_prog = gecprog.templates + let rec unroll_templates (prog:Ast.prog) = + match prog with + | Ast.TemplateDef(tempname,tempargs,body,next) -> + match next with + | Ast.TemplateDef(_) -> [(tempname,tempargs,body)]@(unroll_templates next) + | Ast.Nil -> [(tempname,tempargs,body)] + | _ -> failwith "Top Templates should not have anything other than TemplateDef and Nil in the recursive structure." + | Ast.Nil -> [] + | _ -> failwith "Top Templates should not have anything other than TemplateDef and Nil in the recursive structure." + + let templates = unroll_templates template_prog + + let find_key (map) key= + map |> List.tryFind(fun (x,y:Ast.abstractComplex) -> x = key) + + let rec sub_exp (e:Ast.aexp) (map) = + match e with + | Ast.FloatAExp _ -> e + | Ast.IdAExp(s) -> + match (find_key (map) s) with + | Some(mkey,mval_list) -> + match mval_list with + | [mval] -> + match mval with + | Ast.IdVal(id) -> Ast.IdAExp(id) + | Ast.FloatVal(f) -> Ast.FloatAExp(f) + | Ast.AlgebraicExp(exp) -> exp + | _ -> failwith "Shouldn't really see a wild card in template invocation?" + | _ -> failwith "Improper Template Invocation" + | None -> e + | Ast.PlusAExp(p1,p2) -> Ast.PlusAExp(sub_exp p1 map,sub_exp p2 map) + | Ast.MinusAExp(p1,p2) -> Ast.MinusAExp(sub_exp p1 map,sub_exp p2 map) + | Ast.MulAExp(p1,p2) -> Ast.MulAExp(sub_exp p1 map,sub_exp p2 map) + | Ast.DivAExp(p1,p2) -> Ast.DivAExp(sub_exp p1 map,sub_exp p2 map) + | Ast.PowAExp(p1,p2) -> Ast.PowAExp(sub_exp p1 map,sub_exp p2 map) + + let sub_value (v:Ast.value) (map) = + match v with + | Ast.IdVal (x) -> + match (find_key map x) with + | Some(mkey,mval_list) -> + match mval_list with + | [mval] -> mval + | _ -> failwith "Improper Template Invocation" + | None -> v + | Ast.FloatVal f -> v + | Ast.WildCardVal -> v + | Ast.AlgebraicExp exp -> Ast.AlgebraicExp(sub_exp exp map) + + let sub_abstractcomplex (ac:Ast.abstractComplex) (map) = + match ac with + | [Ast.IdVal(id)] -> + match (find_key map id) with + | Some(mkey,mval) -> mval + | None -> ac + | _ -> ac + + let sub_string (s:string) (map) = + match (find_key map s) with + | Some(mkey,mval) -> + match mval with + | [Ast.IdVal(id)] -> id + | _ -> failwith "Improper Template Invocation - Compartment name" + | None -> s + + let rec sub_prog (prog:Ast.prog) (map) = + match prog with + | Ast.Brick(v,btype,props) -> + let sv = sub_value v map + let sprops = + props |> List.map (fun (x,y) -> + let sy = y |> List.map (fun z -> + match z with + | [Ast.IdVal(id)] -> + match (find_key (map) id) with + | Some(mkey,mval) -> mval + | None -> z + | _ -> z) + (x,sy)) + Ast.Brick(sv,btype,sprops) + | Ast.Reac(enz,reac,prod,rate,sim) -> + let senz = enz |> List.map (fun x -> sub_abstractcomplex x map) + let sreac = reac |> List.map (fun x -> sub_abstractcomplex x map) + let sprod = prod |> List.map (fun x -> sub_abstractcomplex x map) + Ast.Reac(senz,sreac,sprod,sub_value rate map,sim) + | Ast.Trans(reac,prod,comp,rate,sim,dir) -> Ast.Trans(sub_abstractcomplex reac map,sub_abstractcomplex prod map,sub_string comp map,sub_value rate map,sim,dir) + | Ast.TemplateInv(tname,targs) -> //This maybe a corner case + let sargs = targs |> List.map (fun x -> sub_abstractcomplex x map) + Ast.TemplateInv(tname,sargs) + | Ast.Seq(s1,s2) -> Ast.Seq(sub_prog s1 map,sub_prog s2 map) + | Ast.Par(s1,s2) -> Ast.Par(sub_prog s1 map,sub_prog s2 map) + | Ast.Comp(s,cprog) -> Ast.Comp(sub_string s map,sub_prog cprog map) + | Ast.New(n,nprog) -> Ast.New(sub_string n map,sub_prog nprog map) + | Ast.Constraint(c1,op,c2) -> Ast.Constraint(sub_exp c1 map,op,sub_exp c2 map) + | Ast.Rate(v,rate) -> Ast.Rate(sub_value v map,rate) + | Ast.Copy(i,cprog,b1,b2) -> Ast.Copy(i,sub_prog cprog map,b1,b2) + | _ -> prog + + let rec unroll_prog (prog:Ast.prog) (templates)= + match prog with + | Ast.TemplateInv(tempname,args) -> + match (templates |> List.tryFind (fun(x,y,z) -> x = tempname)) with + | Some(tname,targs,tprog) -> + let subs = List.zip targs args + let sprog = sub_prog tprog subs + unroll_prog sprog templates + | None -> + failwith ("Template " + tempname + " not defined") + | Ast.TemplateDef(name,args,body,next) -> + let unroll_body = unroll_prog body templates //This maybe optional? + unroll_prog next ((name,args,unroll_body)::templates) + | Ast.Seq(s1,s2) -> + let u_s1 = unroll_prog s1 templates + let u_s2 = unroll_prog s2 templates + Ast.Seq(u_s1,u_s2) + | Ast.Par(p1,p2) -> + let u_p1 = unroll_prog p1 templates + let u_p2 = unroll_prog p2 templates + Ast.Par(u_p1,u_p2) + | Ast.Comp (name,prog) -> + let u_prog = unroll_prog prog templates + Ast.Comp(name,u_prog) + | Ast.New(n,prog) -> + let u_prog = unroll_prog prog templates + Ast.New(n,u_prog) + | Ast.Copy(i,prog,b1,b2) -> + let u_prog = unroll_prog prog templates + Ast.Copy(i,u_prog,b1,b2) + | _ -> prog + + let unrolled_top = reduce_gecprog (unroll_prog gecprog.prog templates) + let unrolled_systems = gecprog.systems |> List.map(fun x -> {x with prog = reduce_gecprog (unroll_prog x.prog templates)}) + {gecprog with prog = unrolled_top; systems = unrolled_systems} + + +let translate_systems_to_prog (gecprog:ClassicProgram) = + let systems = gecprog.systems |> List.map (fun x -> Ast.Comp(x.name,x.prog)) + let parsystems = Program.fold_parallel systems + let top_prog = gecprog.prog + + match parsystems with + | Ast.Nil -> top_prog + | _ -> + match top_prog with + | Ast.Nil -> parsystems + | _ -> Ast.Par(top_prog,parsystems) + + + +exception CompileException of string * exn + +let modify_crn (crn:Crn) (settings:Gec_settings) crnSettings= + let instructions = settings.crn + let overrideCrn = settings.overrideCrn + if overrideCrn then + (None,instructions) + //Crn.create_from_instructions crnSettings instructions + else + Some(crn),instructions + (*let basecrn = {crn with settings=crnSettings}.saturate_initials() + let instCrn = Crn.create_from_instructions crnSettings instructions + let reactions' = basecrn.reactions@instCrn.reactions + //let attributes = instCrn.attributes + let attributes' = instCrn.attributes + |> Map.toList + |> List.fold (fun (acc:Stringmap.t) (x,y) -> acc.Add(x,y)) basecrn.attributes + let initials' = basecrn.initials@instCrn.initials + {basecrn with reactions=reactions';attributes=attributes';initials=initials'}*) + +type solve_result = { solution : t + ; graph : InferenceSiteGraph.IGraph + ; sbol : SBOLDocument + ; crnString: string} + +let getLBSSystems (gecprog:ClassicProgram) (lbs:tLBSProg) = + let systems = gecprog.systems + let system_names = systems |> List.map (fun x -> x.name) + + let rec lbsSystem lbs = + match lbs with + | LBSComp(comp,prog) -> + if (system_names |> List.contains comp) then + [lbs] + else + [] + | LBSPar(p1,p2) -> + (lbsSystem p1)@(lbsSystem p2) + | LBSReacAbstraction(_,prog) -> lbsSystem prog + | LBSCompDec(comp,prog) -> lbsSystem prog + | LBSCopy(i,prog) -> lbsSystem prog + | _ -> [] + + let rec lbsTop lbs = + match lbs with + | LBSComp(comp,prog) -> + if (system_names |> List.contains comp) then + Trans.LBSNil + else + lbs + | LBSPar(p1,p2) -> + LBSPar(lbsTop p1,lbsTop p2) + | LBSReacAbstraction(x,prog) -> LBSReacAbstraction(x,lbsTop prog) + | LBSCompDec(comp,prog) -> LBSCompDec(comp,lbsTop prog) + | LBSCopy(i,prog) -> LBSCopy(i,lbsTop prog) + | _ -> lbs + + (lbsTop lbs,lbsSystem lbs) + +let create_inference_graph (crnSettings:Crn_settings) (gecprog:ClassicProgram) (top_crn:(Crn option * crnInstructions)) (system_crn_map) (db)= + let dir_str = Program.crnSettings_to_string crnSettings + let modules_str = Program.modules_to_string crnSettings.simulation.initial gecprog.modules + let devices_str = Lib.string_of_list (fun x -> Program.deviceDefinition_to_string x) "\n" gecprog.devices + let top_prog_str = Program.crn_contents_to_string crnSettings.simulation.initial top_crn + + let system_strings = gecprog.systems + |> List.map (fun sys -> + match (system_crn_map |> List.tryFind(fun (x,crn) -> x = sys.name)) with + | Some(_,crn) -> Program.system_to_string crn gecprog.modules gecprog.devices sys db + | None -> failwith ("Unexpected error. System name not found in to_string method for: " + sys.name) + ) + let system_str = Lib.string_of_list (fun x -> x) "\n" system_strings + + let ig_str = + match gecprog.graph with + | [] -> + match system_crn_map with + | [] -> "" //"node node0 { }" + | _ -> + let system_names = system_crn_map |> List.map (fun (x,y) -> x) + "node node0 { systems = [" + (Lib.string_of_list (fun x -> x) ";" system_names) + "] }" + | _ -> Lib.string_of_list (fun x -> Program.igElement_to_string x) "\n" gecprog.graph + + + dir_str + modules_str + devices_str + top_prog_str + system_str + ig_str + + +let getSBOLAssignment (bbTemplates:Trans.tBbDevices) (table:Database.t) (substs:Subst.t list) (index:int)= + let assignment = substs.Item(index) + + let findPart (id:string) = + match Stringmap.tryFind id table.parts with + | Some entry -> Some entry.value + | None -> None + + let IdExists (id:string) = + match findPart id with + | Some(_) -> true + | None -> false + + let createTUAssignment (tu:string list) = + let createCDAssignment (p:string) = + let partName = + match (IdExists p) with + | true -> + p + | false -> + match assignment.Item(p) with + | Subst.PART(partVal) -> partVal + | _ -> failwith "Can't find the part in the substitution. Some error occurred." + let part = + match Stringmap.tryFind partName table.parts with + | Some entry -> entry + | None -> failwith "Can't find the part in the database. Some error occurred." + + let cd = Database.partTypeToSBOL partName part + (cd,(partName,part)) + let cdList = tu |> List.map (fun x -> (createCDAssignment x)) + cdList + let urlPrefix = "http://www.microsoft.com/gec/db" + let tuList = [0..(bbTemplates.Length-1)] |> + List.map (fun indx -> + let a = (createTUAssignment (bbTemplates.Item(indx))) + let cdList = a |> List.map (fun (x,y) -> x) + let partEntryList = a |> List.map (fun(x,y) -> y) + let tu = + let tuName = ("tu" + indx.ToString()) + let perId = urlPrefix + "/" + tuName + let version = "1" + GECHelper.createHigherFunction tuName perId version cdList + (cdList,tu,partEntryList) + ) + let partCDList = tuList |> List.map(fun (x,y,z) -> x) + let partCDs = match partCDList.Length with + | 0 -> [] + | 1 -> partCDList.Head + | _ -> partCDList |> List.reduce (fun a b -> a@b) + + let tuCDs = tuList |> List.map(fun (x,y,z) -> y) + + let partsUsedList = + let a = tuList |> List.map (fun (x,y,z) -> z) + match a.Length with + | 0 -> [] + | 1 -> a.Head + | _ -> a |> List.reduce (fun b c -> b@c) + + + let partIdList = partsUsedList |> List.map(fun (x,y) -> x) |> Seq.ofList |> List.ofSeq + let partEntryList = + partIdList |> List.map(fun (x) -> + partsUsedList |> List.find (fun (a,b) -> a=x) + ) + + (*let protList = partEntryList + |> List.map (fun (x,y) -> y) + |> List.map (fun entry -> entry.value) + |> List.filter (fun partEntry -> + match partEntry with + | Database.PCR(_) -> true + | _ -> false + ) + |> List.map (fun (Database.PCR(x))-> x)*) + + let protCDs = Database.createProteinCDs partEntryList + + let mdList = Database.createModuleDefinitions (partCDs@protCDs) partEntryList //|> List.map (fun x -> TopLevel.ModuleDefinition(x)) + + let device = + let name = "device" + let perid = urlPrefix + "/" + name + let version = "1" + //GECHelper.createHigherFunction name perid version tuCDs + GECHelper.createHigherFunction name perid version partCDs + + //let allCDs = List.rev(device::( List.rev(tuCDs) @ List.rev(partCDs@protCDs))) + let allCDs = List.rev(device::( (*List.rev(tuCDs) @*) List.rev(partCDs@protCDs))) + + let s = SBOLDocument( + (allCDs |> List.map (fun x -> x :> TopLevel)) + //@ (mdList |> List.map (fun x -> x :> TopLevel)) + ) + s + + +let solveGEC (cancel_flag:bool ref) (program:string) (dbParts:string) (dbReactions:string) : solve_result = + let db_from_string (s:string) = Parser.from_string Database.parse s + let partstable = + try + db_from_string dbParts + with e -> + raise (CompileException ("parts", e)) + + let reactionListParser = Parser.sepBy Gecreaction.parseReaction Parser.newline + let reactiondb_from_string (s:string) = Parser.from_string reactionListParser s + + let createReactionEntry reaction = + let (reactionEntry:Gecreaction.t Database.entry) ={value=reaction;enabled=true;comments=""} + reactionEntry + + let reactiondb = + try + reactiondb_from_string dbReactions |> List.map (fun(x) -> createReactionEntry(x)) + with e -> + raise (CompileException ("reactions", e)) + + try + let table = {partstable with reactions = reactiondb} + let options = Options.setGECProgramText program Options.default_options + let guioptions = setOptions options empty + let gui = setDatabase table guioptions + match Main.parse (getGECProgramText gui) with + | LogicGec _ -> failwith "Logic GEC program not supported yet." + | ClassicGec gecprog -> + let ugecprog = unroll_gecprog gecprog + let prog = translate_systems_to_prog ugecprog + let ds = ugecprog.settings.directives |> Settings.convert_crn_to_gec_directives + let (bbTemplates, prologConstraints, lbsProg, rateDecs, substitutions, arithmeticConstraints, log) = + Trans.translate0 prog (getSimulationOnlyReactionsOption gui) (getDatabase gui) + + let varAss = List.map Cssubst.mkVarAss substitutions + let substs = List.map Cssubst.getSubst substitutions + (* Put the results into a Main.tSolution data structure. *) + let sol = { Main.bbDevices = bbTemplates; + Main.lbsProgram = lbsProg; + Main.rateDecs = rateDecs; + Main.varAss = varAss; + Main.substs = substs; + Main.error = None; + Main.numSolutions = List.length varAss } + + let solution = setSolution ds sol prologConstraints arithmeticConstraints log gui + + + let (toplbs,lbsSystems) = getLBSSystems ugecprog lbsProg + + let crnSettings = Crn_settings.defaults.from_default_directive_list ugecprog.settings.directives + + let top_crn = TransCrn.create toplbs |> (fun x -> modify_crn x ugecprog.settings crnSettings) + let system_crn_map = lbsSystems + |> List.map (fun x -> + let systems = ugecprog.systems + match x with + | Trans.LBSComp(compname,prog) -> + let crn = TransCrn.create x + match (systems |> List.tryFind (fun y -> y.name = compname)) with + | Some(res) -> (compname,modify_crn crn res.settings crnSettings) + | None -> failwith ("Unexpected error. System " + compname + " not found.") + | _ -> failwith "Unexpected LBS Comparment encountered") + + let crnString = create_inference_graph crnSettings ugecprog top_crn system_crn_map table + let igraph = Parser.from_string InferenceSiteGraph.parse crnString + + let (varAss',subst') = + match sol.numSolutions with + | 0 -> + match igraph.nodes.Count with + | 0 -> failwith "This should never happen" + | 1 -> + let model = igraph.nodes |> Map.toSeq |> Seq.head |> snd + match (model.top.initials.IsEmpty) && (model.systems.IsEmpty) with + | true -> ([],[]) + | false -> ([[],[],[]],[Map.empty]) + | _ -> ([[],[],[]],[Map.empty]) + | _ -> (sol.varAss,sol.substs) + + let solution' = + match solution.solution with + | Some(a,sol,b,c,d) -> + let sol' = {sol with Main.varAss = varAss'; Main.numSolutions = varAss'.Length; Main.substs = subst'} + Some(a,sol',b,c,d) + | None -> None + + + let sbol = + match solution' with + | Some(dir,sol,gecConst,arthConst,_) -> getSBOLAssignment sol.bbDevices table sol.substs 0 + | None -> Database.convertTableToSBOLDocument table + { solution = {solution with solution = solution'} + ; graph = igraph + ; sbol = sbol + ; crnString = crnString} + + + with e -> + raise (CompileException ("code", e)) + +(******************************************************************************) + +let rec evaluateExpression (exp:Expression.t<_>) (smap:Subst.t) = + match exp with + | Expression.Key(key) -> + if key = "RMRNADeg" then + 0.001 + else + if not (smap.ContainsKey(key)) then + try + float key + with e -> + failwith "Key not found in substitution" + raise(CompileException ("code", e)) + else + match smap.Item(key) with + | Subst.NUMBER(fl) -> fl + | _ -> failwith "Unexpected format in the map" + | Expression.Float(fl) -> fl + | Expression.Times(times) -> + times |> List.fold (fun acc x -> acc*(evaluateExpression x smap)) 1.0 + | Expression.Divide(divide) -> + let d1 = evaluateExpression divide.div1 smap + let d2 = evaluateExpression divide.div2 smap + if d2 = 0.0 then + failwith "Divide by 0 error." + (d1)/(d2) + | Expression.Power(pow) -> + let b = evaluateExpression pow.base_ smap + let pow = evaluateExpression pow.exponent smap + Math.Pow(b,pow) + | Expression.Plus(plus) -> + plus |> List.fold (fun acc x -> acc+(evaluateExpression x smap)) 0.0 + | Expression.Minus(minus) -> + let sub1 = evaluateExpression minus.sub1 smap + let sub2 = evaluateExpression minus.sub2 smap + sub1 - sub2 + | Expression.Absolute(abs) -> + let vabs = evaluateExpression abs smap + if vabs < 0.0 then + (vabs * (-1.0)) + else + vabs + | Expression.Log(log) -> + let l = evaluateExpression log smap + Math.Log(l) + | Expression.Modulo(modulo) -> + let div = evaluateExpression modulo.div smap + let modul = evaluateExpression modulo.modulo smap + div%modul + | Expression.If(bexp1,bexp2,bexp3) -> + failwith "unexpected expression type" + + +let assignReverseRate (rxn:Reaction) (smap:Subst.t) = + + match rxn.reverse with + | Some(Rate.MassAction(exp:Expression.t)) -> + match exp with + | Expression.Key(rate) -> + if rate = "RMRNADeg" then + {rxn with reverse = Some(Rate.MassAction(Expression.Float(0.001)))} + else + if not (smap.ContainsKey(rate)) then + let mfloat = ref 0.0f + match Single.TryParse(rate, mfloat) with + | true -> {rxn with reverse = Some(Rate.MassAction (Expression.Float(float !mfloat)))} + | false -> rxn + (*try + let mfloat = float rate + {rxn with reverse = Some(Rate.MassAction (Expression.Float(mfloat)))} + with e -> + failwith "Key not found in substitution" + raise(CompileException ("code", e))*) + else + match smap.Item(rate) with + | Subst.NUMBER(fl) -> + {rxn with reverse = Some(Rate.MassAction(Expression.Float(fl)))} + | _ -> failwith "Unexpected format in the map" + + | _ -> + try + let value = evaluateExpression exp smap + {rxn with reverse = Some(Rate.MassAction(Expression.Float(value)))} + with e -> + raise(CompileException ("code", e)) + | Some(Rate.Function(e)) -> rxn //This case is encountered when userdefined CRNs are substituted. + | None -> rxn + + +let assignReaction (rxn:Reaction) (smap:Subst.t) = + match rxn.rate with + | Rate.MassAction(exp:Expression.t) -> + match exp with + | Expression.Key(rate) -> + if rate = "RMRNADeg" then + let newRxn = {rxn with rate = (Rate.MassAction (Expression.Float(0.001)))} + assignReverseRate newRxn smap + else + if not (smap.ContainsKey(rate)) then + let mfloat = ref 0.0f + match Single.TryParse(rate, mfloat) with + | true -> + let newRxn = {rxn with reverse = Some(Rate.MassAction (Expression.Float(float !mfloat)))} + assignReverseRate newRxn smap + | false -> rxn + + (*try + let mfloat = float rate + let newRxn = {rxn with rate = (Rate.MassAction (Expression.Float(mfloat)))} + assignReverseRate newRxn smap + with e -> + failwith "Key not found in substitution" + raise(CompileException ("code", e))*) + else + let newRate = match smap.Item(rate) with + | Subst.NUMBER(fl) -> fl + | _ -> failwith "Unexpected format in the map" + + let newRxn = {rxn with rate = (Rate.MassAction (Expression.Float(newRate)))} + assignReverseRate newRxn smap + | _ -> + try + let value = evaluateExpression exp smap + let newRxn = {rxn with rate = (Rate.MassAction(Expression.Float(value)))} + assignReverseRate newRxn smap + with e -> + raise(CompileException ("code", e)) + | Rate.Function(e) -> rxn //This case is encountered when userdefined CRNs are substituted. + + +type solution_result = { model : InferenceSiteGraph.IGraph + ; sbol : SBOLDocument } + +let getCrnAssignment (igraph:InferenceSiteGraph.IGraph) (gecSol:t) (index:int) : solution_result = + if gecSol.solution.IsNone then + failwith "No solution found" + + let (dirlist,sol,constraints,aritconstraints,d) = gecSol.solution.Value + let substitution = sol.substs.Item(index) + + //SBOL + let sbol = getSBOLAssignment sol.bbDevices gecSol.database sol.substs index + + //CRN + let assign_crn (crn:Crn) = + let assignedReactions = crn.reactions |> List.map(fun x -> assignReaction x substitution) + {crn with reactions = assignedReactions} + + let nodes' = igraph.nodes |> Map.map (fun k node -> + {node with top = (assign_crn node.top); systems = (node.systems |> List.map (fun x -> assign_crn x))}) + + + { model = {igraph with nodes = nodes'} ; sbol = sbol } + \ No newline at end of file diff --git a/ClassicGEC/ClassicGECDotNet/gecreaction.fs b/ClassicGEC/ClassicGECDotNet/gecreaction.fs new file mode 100644 index 0000000..5b6af00 --- /dev/null +++ b/ClassicGEC/ClassicGECDotNet/gecreaction.fs @@ -0,0 +1,124 @@ +[] +module Microsoft.Research.GEC.Gecreaction + +open Microsoft.Research.GEC +open Parser + +//open Microsoft.Research.ModellingEngine +open Microsoft.Research.CRNEngine + +open System.Diagnostics + +(* A type for "database reactions", which records some of the structure of complexes. *) +type normalReacData = { catalysts: string list list; + reactants: string list list; + products: string list list; + rate: float } +type transportReacData = { reactant: string list; + product: string list; + rate: float; + compartment: string; + direction: Ast.direction } +type t = Normal of normalReacData + | Transport of transportReacData + +(* Functions to create GEC reaction datatypes. *) +let makeNormal (catalysts:string list list) (reactants:string list list) (products:string list list) (rate:float) = + Normal {catalysts=catalysts; reactants=reactants; products=products; rate=rate} +let makeTransport (reactant:string list) (product:string list) (rate:float) (compartment:string) (direction:Ast.direction) = + Transport {reactant=reactant; product=product; rate=rate; compartment=compartment; direction=direction} + +(* Decide whether a reaction is a normal or a transport reaction... *) +let isNormal (r:t) = match r with Normal r -> Some (r.catalysts, r.reactants, r.products, r.rate) | _ -> None +let isTransport (r:t) = match r with Transport r -> Some (r.reactant, r.product, r.rate, r.compartment, r.direction) | _ -> None + +(* Produce a string representation of a GEC reaction. *) +let display (r:t) : string = + let mkStr xss = Lib.string_of_list Ast.complexString " + " xss in + match r with + | Normal r -> let prefix = match r.catalysts with [] -> "" | _ -> (mkStr r.catalysts) + " ~ " in + prefix + (mkStr r.reactants) + " ->{" + (Lib.display_float r.rate) + "} " + (mkStr r.products) + | Transport r -> let reactantStr,productStr = + match r.direction with + | Ast.In -> Ast.complexString r.reactant, Ast.compartmentString r.compartment (Ast.complexString r.product) + | Ast.Out -> Ast.compartmentString r.compartment (Ast.complexString r.reactant), Ast.complexString r.product + in + reactantStr + " ->{" + (Lib.display_float r.rate) + "} " + productStr + +(* Are two reactions equal? Must consider reordering of reactions/products/catalysts and the ordering of species within complexes themselves... *) +let equal (r1:t) (r2:t) = + match r1,r2 with + | Normal r1, Normal r2 -> (Lib.is_permutation Ast.complexesEqual r1.catalysts r2.catalysts) && + (Lib.is_permutation Ast.complexesEqual r1.reactants r2.reactants) && + (Lib.is_permutation Ast.complexesEqual r1.products r2.products) && + (r1.rate = r2.rate) + | Transport r1, Transport r2 -> (Ast.complexesEqual r1.reactant r2.reactant) && + (Ast.complexesEqual r1.product r2.product) && + (r1.rate = r2.rate) && + (r1.compartment = r2.compartment) && + (r1.direction = r2.direction) + | _,_ -> false + +(* Get all species names from a GEC reaction. *) +let species (r:t) : string list list = + let allRawSpecies = + match r with + | Normal r -> r.catalysts @ r.reactants @ r.products + | Transport r -> [r.reactant; r.product] + in + Lib.remove_duplicates Ast.complexesEqual allRawSpecies + +(* Apply a substitution to a GEC reaction. *) +let applySubst (theta:Subst.t) (r:t) : t = + match r with + | Normal r -> Normal { r with catalysts = List.map (Subst.applyToComplex theta) r.catalysts; + reactants = List.map (Subst.applyToComplex theta) r.reactants; + products = List.map (Subst.applyToComplex theta) r.products } + | Transport r -> Transport { r with reactant = Subst.applyToComplex theta r.reactant; + product = Subst.applyToComplex theta r.product } + + +let lookaheadLinebreak = Parser.pTry (Parser.linebreak >>. Parser.failParser "" <|> Parser.satisfy Parser.isWhiteSpace >>. preturn ()) +let lookaheadDashSeparator = Parser.pTry(Parser.pstring "->" >>. failParser "" <|> Parser.pstring "-") + // Parser.satisfy (fun c -> Parser.isWhiteSpace c && c <> '\n') +//let whiteSpacenlb : t = skipChar isWhiteSpace "a white space" + +let spacesnlb :t = fun st -> + match many (commentLine <|> commentMultiline () <|> lookaheadLinebreak) <| st with + | OkEmpty (_, st') -> OkEmpty ("", st') + | OkConsumed (_, st') -> OkEmpty ("", st') + | FailEmpty _ -> OkEmpty ("", st) + | FailConsumed (e, p) -> FailConsumed (e, p) + +let kwnlb s = pstring s .>> spacesnlb + +let gecName = (Parser.sepBy Parser.name (Parser.pstring "::")) .>> spacesnlb +let bracketnlb l r = Parser.between (Parser.pstring l) (Parser.spaces >>. kwnlb r) +let parennlb a = bracketnlb "(" ")" a +let sqBracketnlb a = bracketnlb "[" "]" a +let bracesnlb a = bracketnlb "{" "}" a +let compartmentParser = (sqBracketnlb gecName) +let rateParser = bracesnlb Parser.pfloat +let chainNames = Parser.sepBy gecName (Parser.kw "+") + +let parseReaction = chainNames >>= fun n -> + Parser.choice[ + compartmentParser .>> Parser.kw "->" .>>. rateParser .>>. gecName |>> fun(((reactant:string list),rate:float),(product:string list)) -> Transport {reactant = reactant; product=product;rate = rate;compartment = n.Head.Head; direction = Ast.direction.Out} + Parser.skw "~" >>. + Parser.choice[ + Parser.kw "->" >>. rateParser .>>. chainNames |>> fun((rate:float),(products:string list list)) -> Normal {catalysts=n;reactants = [];rate=rate;products=products} + chainNames .>> Parser.kw "->" .>>. rateParser .>>. chainNames |>> fun(((reactants:string list list),rate:float),(products:string list list)) -> Normal {catalysts=n;reactants = reactants;rate=rate;products=products} + ] + Parser.kw "->" >>. rateParser .>>. chainNames >>= fun (r,x) -> + Parser.choice[ + compartmentParser |>> fun(product) -> Transport {reactant = n.Head;product=product;rate=r;compartment=x.Head.Head;direction=Ast.direction.In} + Parser.preturn (Normal {catalysts=[];reactants = n;products=x;rate=r}) + ] + ] + + + +//let parseTransportOut = compartmentParser .>> Parser.kw "->" .>>. rateParser .>>. gecName |>> fun ( ((compartment:string, (reactant:string list)), rate:float), (product: string list)) -> Transport {reactant=reactant; product=product; rate=rate; compartment=compartment; direction=Ast.direction.Out} +//let parseTransportIn = gecName .>> Parser.kw "->" .>>. rateParser .>>. compartmentParser |>> fun(((reactant:string list),rate:float),(compartment:string,(product:string list))) -> Transport {reactant=reactant; product=product; rate=rate; compartment=compartment; direction=Ast.direction.In} + + diff --git a/ClassicGEC/ClassicGECDotNet/gecreaction.fsi b/ClassicGEC/ClassicGECDotNet/gecreaction.fsi new file mode 100644 index 0000000..27024e0 --- /dev/null +++ b/ClassicGEC/ClassicGECDotNet/gecreaction.fsi @@ -0,0 +1,28 @@ +module Microsoft.Research.GEC.Gecreaction + +open Microsoft.Research.GEC + +(* Opaque reaction datatype. *) +type t + +(* Functions to create GEC reaction datatypes. *) +val makeNormal : string list list -> string list list -> string list list -> float -> t +val makeTransport : string list -> string list -> float -> string -> Ast.direction -> t + +(* Decide whether a reaction is a normal or a transport reaction... *) +val isNormal : t -> (string list list * string list list * string list list * float) option +val isTransport : t -> (string list * string list * float * string * Ast.direction) option + +(* Produce a string representation of a GEC reaction. *) +val display : t -> string + +(* Are two reactions equal? *) +val equal : t -> t -> bool + +(* Get all species names from a GEC reaction. *) +val species : t -> string list list + +(* Apply a substitution to a GEC reaction. *) +val applySubst : Subst.t -> t -> t + +val parseReaction : Parser.t diff --git a/ClassicGEC/ClassicGECDotNet/gecspecies.fs b/ClassicGEC/ClassicGECDotNet/gecspecies.fs new file mode 100644 index 0000000..fa95f3f --- /dev/null +++ b/ClassicGEC/ClassicGECDotNet/gecspecies.fs @@ -0,0 +1,61 @@ +[] +module Microsoft.Research.GEC.GecSpecies + +open Parser +open Microsoft.Research.CRNEngine + +type species = string list + +let species_to_gecAbstractComplex (sp:species) = + sp |> List.map (fun x -> + match x with + | "_" -> Ast.WildCardVal + | _ -> Ast.IdVal(x)) + +type t = { + compartment: string option + species:species +} +with + static member empty_Species = + {species = []; compartment=None} + member s.to_string() = + match s.compartment with + | Some(comp) -> comp + "[" + (Lib.string_of_list (fun x -> x) "::" s.species) + "]" + | None -> (Lib.string_of_list (fun x -> x) "::" s.species) + member s.to_crn_string() = + match s.compartment with + | Some(comp) -> comp + "_" + (Lib.string_of_list (fun x -> x) "_" s.species) + | None -> (Lib.string_of_list (fun x -> x) "_" s.species) + member s.to_crn_species() = Species.create(s.to_crn_string()) + member s.to_ast_gecSpecies() = + match s.compartment with + | Some(x) -> Ast.CompartmentSpecies(x,species_to_gecAbstractComplex s.species) + | None -> Ast.SimpleSpecies(species_to_gecAbstractComplex s.species) + +let SPECIES_SEP = Parser.pstring "::" + +let pName = Parser.name_kw Keywords.kwList + +let parse_species_ns = Parser.sepBy (pName) SPECIES_SEP +let parse_species = parse_species_ns .>> Parser.spaces + +let parse_kw (keywords:string list) = + Parser.plookAheadWith( + Parser.choice[ + Parser.pTry((Parser.name_kw keywords) .>> Parser.pstring "[" >>= fun _ -> Parser.preturn true) + Parser.preturn false + ]) + >>= + fun (hasCompartment) -> + if hasCompartment then + pName .>> Parser.pstring "[" .>>. parse_species_ns .>> Parser.pstring "]" .>> Parser.spaces |>> fun(x,y) -> {species=y;compartment=Some(x)} + else + parse_species |>> fun y -> {species=y;compartment=None} + +let parse = parse_kw Keywords.kwList + + +let parse_crn_species = parse |>> fun x -> x.to_crn_string() |> Species.create +let parse_gec_to_crn_species = parse_species |>> fun x -> Lib.string_of_list (fun x -> x) "_" x |> Species.create + diff --git a/ClassicGEC/ClassicGECDotNet/hypothesis.fs b/ClassicGEC/ClassicGECDotNet/hypothesis.fs new file mode 100644 index 0000000..6182380 --- /dev/null +++ b/ClassicGEC/ClassicGECDotNet/hypothesis.fs @@ -0,0 +1,360 @@ +module Microsoft.Research.GEC.Hypothesis + +open Parser +open Microsoft.Research.CRNEngine + + +type parser<'a> = Parser.t<'a> + + +type HypothesisDirective = + | Devices of (string list) + + + +type HypothesisSettings = + { + devices : string list + } + static member defaults = { + devices = [] + } + member setting.from_directive (directive:HypothesisDirective) = + match directive with + | Devices(x) -> {setting with devices=x} + member setting.from_directiveList (directives:HypothesisDirective list) = + directives |> List.fold (fun (s:HypothesisSettings) (d:HypothesisDirective) -> setting.from_directive d) setting + + + +type arguments = (string list) +type crndirective = string +type crnmodule = string * arguments * string +//type device = string * arguments * string + +type crnModules = ((string * string list) * Instruction list) list * Instruction list + +type igPriorType = + | Fixed + | Normal + | TruncatedNormal + +type igPriorOption = + | HasPrior of igPriorType + | NoPrior + +type igPrior = string * igPriorOption + +type igName = string list + +type igedge = igName * (igPrior list) * igName +type ignode = string * (string list) * (Inference_settings option) + + + +type igraphElement = + | Node of ignode + | Edge of igedge + +type moduleDefinition = string * (arguments) + +type deviceDefinition = moduleDefinition * (moduleDefinition list) + +type systemReference = + | System of string + | NoSystem + +type crnSystem = string * systemReference * Crn_settings * HypothesisSettings * crnModules + +type hypothesis = Crn_settings * (crnModules) * (deviceDefinition list) * (crnSystem list) * (igraphElement list) + + +let kwList = ["module";"system";"inference";"directive";"device"] + +//Parsers Start here: + +let parse_species = Parser.(|>>) (Parser.name_kw kwList) Species.create + +let pcomma = Parser.kw "," +let pPipe = Parser.kw "|" +let pDot = Parser.kw "." + +let argumentsParser = Parser.paren (Parser.sepBy Parser.name pcomma) + +let parse_crnDirective = Directive.parse Functional2.parse Functional2.parse_plot + + +let parse_hypothesisDirective = Parser.kw "device" >>. Parser.list_of Parser.name .>> Parser.opt (Parser.kw ";") |>> Devices + +let parse_crnSettings = Crn_settings.parse Functional2.parse Functional2.parse_plot + + +let parse_moduleInvocation = Parser.name .>> Parser.spaces .>>. argumentsParser + +let parse_device = Parser.kw "device" >>. parse_moduleInvocation .>> Parser.kw "=" + .>>. Parser.braces (Parser.sepBy parse_moduleInvocation pPipe) + + + +let parse_instructions pspecies settings = + let zero = Expression.zero + let unitVal = Expression.one + + let pname = Parser.name_kw kwList .>> Parser.spaces + let pvalue = Expression.parse pname + let pexpr = Expression.parse (Key.parse pspecies) + let pcomma = Parser.kw "," + + // crn parsers + let pinitial = Initial.parse pspecies pvalue zero |>> Instruction.Initial2 + let preaction = Reaction.parse pspecies pvalue pexpr unitVal |>> Instruction.Reaction + let pinvoke = Parser.pTry( pname .>> Parser.kw "(") + .>>. Parser.sepBy pvalue pcomma + .>> Parser.kw ")" + |>> Module + let pline = pinvoke <|> preaction <|> pinitial + let pbar = Parser.kw "|" + + // module definitions parser + let pmodule = + Parser.kw "module" + >>. Parser.name .>>. Parser.paren (Parser.sepBy Parser.name pcomma) // module_name(comma-separated args) + .>> Parser.kw "=" + .>>. Parser.braces (Parser.opt pbar >>. Parser.sepBy pline pbar) + + // full CRN parser + Parser.spaces + >>. Parser.many pmodule + .>> Parser.opt pbar + .>>. Parser.sepBy pline pbar + +let parse_crnModules crnSettings = parse_instructions parse_species crnSettings + +let crnDirectiveChoice = parse_crnDirective |>> Choice1Of2 +let hypothesisDirectiveChoice = parse_hypothesisDirective |>> Choice2Of2 + + +let pfixed = Parser.kw "Fixed" |>> fun _ -> Fixed +let pnormal = Parser.kw "Normal" |>> fun _ -> Normal +let ptruncatedNormal = Parser.kw "TruncatedNormal" |>> fun _ -> TruncatedNormal + +let parse_priorType = pfixed <|> pnormal <|> ptruncatedNormal + +let parse_priorOption:Parser.t = (Parser.plookAheadWith ( + Parser.choice[ + Parser.pTry (Parser.kw "=" >>. parse_priorType >>= fun _ -> Parser.preturn true) + Parser.preturn false + ]) + >>= fun hasPriorType -> + if hasPriorType + then Parser.kw "=" >>. parse_priorType |>> fun (x:igPriorType) -> HasPrior(x) + else Parser.preturn(NoPrior) + ) + +let parse_prior:t = Parser.name .>> Parser.spaces .>>. parse_priorOption + + +let parse_igInferenceSettings = Parser.kw ";" >>. Parser.kw "inference" >>. Parser.kw "=" >>. (Inference_settings.parse) + +let parse_igName = Parser.sepBy (Parser.name .>> Parser.spaces) pDot + +let parse_edge = Parser.kw "edge" >>. parse_igName .>> Parser.kw "->" .>>. + Parser.list_of parse_prior .>>. parse_igName |>> fun ((x,y),z) -> Edge(x,y,z) + +let parse_node = Parser.kw "node" >>. (Parser.name .>> Parser.spaces) .>> + Parser.kw "{" .>>. (Parser.kw "systems" >>. Parser.kw "=" >>. + Parser.list_of (Parser.name .>> Parser.spaces)) >>= fun (x,y) -> + Parser.plookAheadWith( + Parser.choice[ + Parser.pTry(Parser.kw ";" >>. Parser.kw "inference" >>= fun _ -> Parser.preturn true) + Parser.preturn false + ]) + >>= fun hasInference -> + if hasInference + then + parse_igInferenceSettings .>> Parser.kw "}" |>> fun (z) -> Node(x,y,Some(z)) + else + Parser.kw "}" |>> fun _ -> Node(x,y,None) + + + +let parse_igraphElement = parse_edge <|> parse_node + + +let parse_withSystem = (Parser.plookAheadWith ( + Parser.choice [ + Parser.pTry(Parser.name .>> Parser.spaces .>> Parser.kw "with" >>= fun _ -> Parser.preturn true) + Parser.preturn false + ]) + >>= fun hasWith -> + if hasWith + then Parser.name .>> Parser.spaces .>> Parser.kw "with" |>> fun x -> System(x) + else Parser.preturn(NoSystem)) + + + + +let parse_hybridDirective = Parser.many (Parser.kw "directive" >>. (crnDirectiveChoice <|> hypothesisDirectiveChoice)) |>> + (fun hybridList -> + let crnList = hybridList |> + List.filter (fun x -> + match x with + | Choice1Of2 t -> true + | _ -> false) |> + List.map (fun x -> + match x with + | Choice1Of2 t -> t + | _ -> failwith "Unexpected choice2 in parse_hybridDirective") + let hypList = hybridList |> + List.filter (fun x -> + match x with + | Choice2Of2 t -> true + | _ -> false) |> + List.map (fun x -> + match x with + | Choice2Of2 t -> t + | _ -> failwith "Unexpected choice1 in parse_hybridDirective") + let crn_settings = Crn_settings.defaults.from_directive_list crnList + let hypothesis_settings = HypothesisSettings.defaults.from_directiveList hypList + (crn_settings,hypothesis_settings) + ) + +let (parse_crn_system:t) = Parser.kw "system" >>. Parser.name .>> Parser.spaces .>> Parser.kw "=" + .>> Parser.kw "{" .>>. parse_withSystem .>>. parse_hybridDirective >>= fun((systemName,withSystem),(crnSettings,hypothesisSettings)) -> + parse_crnModules crnSettings .>> (Parser.kw "}") >>= fun y -> Parser.preturn(systemName,withSystem,crnSettings,hypothesisSettings,y) + + + + +let (parse_hypothesis_content:t) = + parse_crnSettings >>= fun (crnSettings) -> + (parse_crnModules crnSettings) + .>>. (Parser.many parse_device) + .>>. (Parser.many parse_crn_system) + .>>. (Parser.many parse_igraphElement) + |>> fun (((modulelist:crnModules,deviceDefinitions: deviceDefinition list),systemlist:crnSystem list),igraph) -> (crnSettings,modulelist,deviceDefinitions,systemlist,igraph) + + +//To String Methods +let fold_string_list (strList:string list) (folder:string) = + match strList.Length with + | 0 -> "" + | 1 -> strList.Head + | _ -> strList.Tail |> List.fold (fun f s -> (f + folder + s)) strList.Head + +let crnDirectives_to_string (crnSettings:Crn_settings) = crnSettings.to_string Functional2.to_string Functional2.to_string_plot + +let args_to_string (args: arguments) = fold_string_list args "," + +let modules_to_string initial_time (modules:crnModules) = + let moduleList,externalInstructions = modules + let instructionList_to_string (instructions:Instruction list) = + let instructionStringList = instructions |> List.map (fun x -> ("| " + (Instruction.to_string initial_time x))) + fold_string_list instructionStringList "\n" + let module_to_string (((moduleName:string),(moduleArgs:string list)),(instructions:Instruction list)) = + let str = "module " + moduleName + "(" + (args_to_string moduleArgs) + ") = {\n" + + (instructionList_to_string instructions) + "\n}\n" + str + let str = + let moduleListString = moduleList |> List.map (fun x -> (module_to_string x)) + let moduleStr = fold_string_list moduleListString "" + moduleStr + (instructionList_to_string externalInstructions) + str + +let moduleDefinition_to_string (moduleDef:moduleDefinition) = + let (moduleName,moduleArgs) = moduleDef + moduleName + "(" + (args_to_string moduleArgs) + ")" + +let deviceDefinition_to_string (device:deviceDefinition) = + let ((deviceDef),deviceBody) = device + let deviceBodyString = "{" + (fold_string_list (deviceBody |> List.map (fun x -> moduleDefinition_to_string x)) " | ") + "}" + let str = "module " + (moduleDefinition_to_string deviceDef) + " = " + deviceBodyString + str + + +let igNode_to_string (node:ignode) = + let (nodeName,nodeSystems,iSettings) = node + let str = "node " + nodeName + " { systems = [" + (fold_string_list nodeSystems ";") + "]" + match iSettings with + | Some(x) -> str + ";" + "inference " + "=" + (Inference_settings.to_string(x)) + "}" + | None -> str + "}" + + + +let igEdge_to_string (edge:igedge) = + let edgeNameString edgelist = fold_string_list edgelist "." + let priorType_to_string (ptype:igPriorType) = + match ptype with + | Fixed -> "Fixed" + | Normal -> "Truncated" + | TruncatedNormal -> "TruncatedNormal" + let prior_to_string ((p,ptype):igPrior) = + match ptype with + | HasPrior(x) -> p + "=" + (priorType_to_string x) + | NoPrior -> p + let (fromNode,priorlist,toNode) = edge + let str = "edge " + (edgeNameString fromNode) + " -> " + "["+ + (fold_string_list (priorlist |> List.map (fun x-> prior_to_string x)) ";") + + "]" + (edgeNameString toNode) + str + +let igElement_to_string (elem:igraphElement) = + match elem with + | Node(x) -> igNode_to_string x + | Edge(x) -> igEdge_to_string x + +let hypothesisSettings_to_string (hypSettings:HypothesisSettings) (devices:Database.device list) (deviceDefs:moduleDefinition list) (moduleDefs:moduleDefinition list) = + let deviceList = hypSettings.devices + let rec device_unroll (dev:string) (devices:Database.device list) (deviceDefs:moduleDefinition list) (moduleDefs:moduleDefinition list) = + let deviceDefOpt = deviceDefs |> List.tryFind (fun (x,y) -> x=dev) + match deviceDefOpt with + | Some(a) -> [a] + | None -> + let modOpt = (moduleDefs |> List.tryFind (fun (x,y) -> x=dev)) + match modOpt with + | Some(a) -> [a] + | None -> + let devOpt = (devices |> List.tryFind (fun (x,y) -> x=dev )) + match devOpt with + | Some (devName,devComps) -> + let deflist = devComps |> List.map (fun x -> device_unroll x devices deviceDefs moduleDefs) + match deflist.Length with + | 0 -> [] + | _ -> deflist |> List.reduce (fun x y -> x@y) + | None -> + raise (System.ArgumentException("Device in System Directive must be defined.")) + let mdeflistlist = deviceList |> List.map (fun x -> device_unroll x devices deviceDefs moduleDefs) + let mdeflist = + match mdeflistlist.Length with + | 0 -> [] + | _ -> mdeflistlist |> List.reduce (fun x y -> x@y) + fold_string_list (mdeflist |> List.map (fun x -> "| " + (moduleDefinition_to_string x))) "\n" + + + +let system_to_string (sys:crnSystem) (devices:Database.device list) (deviceDefs:moduleDefinition list) (moduleDefs:moduleDefinition list)= + let (sysName,sysRef,crnSettings,hypSettings,crnMods) = sys + let sysRef_to_string (sysRef:systemReference) = + match sysRef with + | System(x) -> x + " with " + | NoSystem -> "" + + let str = "system " + sysName + " = { " + (sysRef_to_string sysRef) + "\n" + + (crnDirectives_to_string crnSettings) + "\n" + + hypothesisSettings_to_string hypSettings devices deviceDefs moduleDefs + + (modules_to_string crnSettings.simulation.initial crnMods) + "\n" + "}\n" + + str + +let hypothesis_to_crn_program (h:hypothesis) (devicelib:Database.device list)= + let (crnSettings,moduleDefs,deviceDefs,systemDefs,igraph) = h + let (modules,_) = moduleDefs + let moduleDefinitions = modules |> List.map fst + let deviceDefinitions = deviceDefs |> List.map fst + let str = crnDirectives_to_string crnSettings + "\n" + + (modules_to_string crnSettings.simulation.initial moduleDefs) + "\n" + + (fold_string_list (deviceDefs |> List.map deviceDefinition_to_string) "\n") + "\n" + + (fold_string_list (systemDefs |> List.map (fun x -> system_to_string x devicelib deviceDefinitions moduleDefinitions)) "\n") + "\n" + + (fold_string_list (igraph |> List.map igElement_to_string) "\n") + + str diff --git a/ClassicGEC/ClassicGECDotNet/jsapi.fs b/ClassicGEC/ClassicGECDotNet/jsapi.fs new file mode 100644 index 0000000..efc873d --- /dev/null +++ b/ClassicGEC/ClassicGECDotNet/jsapi.fs @@ -0,0 +1,68 @@ +[] +module Microsoft.Research.GEC.JSAPI + +open Microsoft.Research.GEC.GECEngine + +#if JavaScript +open WebSharper +#endif + +open Microsoft.Research.CRNEngine +open Microsoft.Research.CRNEngine.JSAPI +open FSBOL +open FSBOL.Component +open FSBOL.ComponentDefinition +open FSBOL.Sequence +open FSBOL.Range +open FSBOL.Location +open FSBOL.SequenceAnnotation +open FSBOL.FunctionalComponent +open FSBOL.Interaction +open FSBOL.ModuleDefinition +open FSBOL.Participation +open FSBOL.TopLevel +open FSBOL.SBOLDocument +open FSBOL.JsonSerializer + + +type ClassicResult = { solution : t + ; solutionCount: int + ; model : GuiIG + ; jsbol : rSBOLDocument + ; sbol : SBOLDocument } + +type LogicResult = { solution : t + ; solutionCount: int + ; model : GuiIG + ; jsbol : rSBOLDocument + ; sbol : SBOLDocument } + +type solve_result = ClassicGEC of ClassicResult | LogicGEC of LogicResult + +let compile (program:string) (dbParts:string) (dbReactions:string) : solve_result = + let output = GECEngine.solveGEC (ref false) program dbParts dbReactions + let graph = GuiIG.from_ig output.graph + let jsbol = JsonSerializer.sbolToJson output.sbol + let scount = + match output.solution.solution with + | Some(_,sol,_,_,_) -> sol.numSolutions + | None -> failwith "Output of solution is null" + ClassicGEC { model = graph; solution = output.solution; solutionCount= scount; jsbol = jsbol; sbol = output.sbol } + +type solution_result = { model : GuiIG + ; jsbol : rSBOLDocument + ; sbol : SBOLDocument + ; crnstring : string} + +let get_solution (so:solve_result) (i:int) : solution_result = + match so with + | ClassicGEC o -> + let model = o.model.to_ig() + + //let model = o.model.nodes |> Map.toSeq |> Seq.head |> snd + //let gmodel = model.to_model() + let result = GECEngine.getCrnAssignment model o.solution (i-1) + let model = GuiIG.from_ig result.model + let jsbol = JsonSerializer.sbolToJson result.sbol + { model = model ; jsbol = jsbol ; sbol = result.sbol ; crnstring = result.model.to_string()} + | LogicGEC o -> failwith "Logic GEC solution selection not implemented yet." \ No newline at end of file diff --git a/ClassicGEC/ClassicGECDotNet/keywords.fs b/ClassicGEC/ClassicGECDotNet/keywords.fs new file mode 100644 index 0000000..85fd2cf --- /dev/null +++ b/ClassicGEC/ClassicGECDotNet/keywords.fs @@ -0,0 +1,18 @@ +[] +module Microsoft.Research.GEC.Keywords + +let kwList = [ + "module"; + "prom"; + "rbs"; + "pcr"; + "ter"; + "pos"; + "con"; + "initPop"; + "directive"; + "rate"; + "codes"; + "new"; + "system"; + "template"] \ No newline at end of file diff --git a/ClassicGEC/ClassicGECDotNet/logicGEC.fs b/ClassicGEC/ClassicGECDotNet/logicGEC.fs new file mode 100644 index 0000000..c1d0c0d --- /dev/null +++ b/ClassicGEC/ClassicGECDotNet/logicGEC.fs @@ -0,0 +1,911 @@ +[] +module Microsoft.Research.GEC.LogicGEC + +open RulesDSD.Syntax +open RulesDSD.Substitution +open RulesDSD.Resolution +open Microsoft.Research.CRNEngine +open Parser + +// variable, wildcard or identifier parser +let pname = (name .>> spaces) <|> kw "_" +let noTypePart = "%NoTypePart" + + +type Element = Part of Part // e.g. r0040::prom + | Var of Var // X + with static member wildcard = Var (-1, "_") + static member doParse domainKeywords postParsingDisambigation idProvider : Parser.t = + Parser.plookAheadWith (pname >>= fun str -> + if domainKeywords |> List.contains str + then preturn None + else choice [ kw "(" >>. preturn None + kw "[" >>. preturn None + kw "[[" >>. preturn None + kw "::" >>. preturn (Some true) + preturn (if str = "_" || System.Char.IsUpper (str.Chars 0) then Some false else Some true) ]) + >>= fun isPart -> + match isPart with + | None -> failParser "" + | Some isConcrete -> if isConcrete + then Part.doParse idProvider domainKeywords postParsingDisambigation |>> Element.Part + else pname |>> fun x -> Element.Var (idProvider x) + static member parse domainKeywords idProvider = Element.doParse idProvider false domainKeywords + static member ToString e = + match e with + | Element.Var v -> printVar v + | Element.Part p -> Part.ToString p +and Part = { name : Term // either a variable or a string. CS: I set Element as parametric value just to make unification and resolution more uniform + ; type_ : Term } // either a variable or a string + with static member Create (name : Term, type_ : Term) = { name = name; type_ = type_ } + static member CreateByName (name:string) = Part.Create(Term.Const name, Term.wildcard) + static member CreateByType (type_:string) = Part.Create(Term.wildcard, Term.Const type_) + static member doParse idProvider domainKeywords postParsingDisambiguation : Parser.t = + Parser.plookAheadWith (pname >>= fun str -> + if domainKeywords |> List.contains str + then preturn None + else choice [ kw "(" >>. preturn None + kw "[" >>. preturn None + kw "[[" >>. preturn None + kw "::" >>. preturn (Some true) + preturn (Some false)]) + >>= fun isPart -> + match isPart with + | None -> failParser "" + | Some isConcrete -> + let toTerm (s) : Term = + if s = "_" then Term.wildcard + elif System.Char.IsUpper (s.Chars 0) + then idProvider s |> Term.Var + else Term.Const s + // let pterm = RulesDSD.Parser.pterm (Element.parse domainKeywords idProvider) idProvider domainKeywords + + pname >>= fun partName -> + let nameTerm = toTerm partName + if isConcrete + then kw "::" >>. pname >>= fun partType -> + let typeTerm = toTerm partType + preturn (Part.Create(nameTerm, typeTerm) ) + else preturn (Part.Create(nameTerm, if postParsingDisambiguation then Term.Const noTypePart + else Term.wildcard)) + static member parse idProvider domainKeywords : Parser.t = Part.doParse idProvider domainKeywords false + static member ToString p = // TODO: add cle + let stringTerm t = + match t with + | Term.Const x -> x + | _ -> Term.ToString t + stringTerm p.name + "::" + stringTerm p.type_ +type Engine = RulesDSD.Syntax.CLE +type Semantics = RulesDSD.Syntax.RulesProgram + +// find all concrete parts mentioned in the semantics (concrete meaning no open Prolog variable, each term is ground) +let getParts (s:Semantics) : Part list = + s.Values + |> Seq.collect(Set.toList >> List.collect Clause.Species >> List.distinct) + |> Seq.distinct + |> Seq.choose (fun e -> + match e with + | Element.Part p -> match p.name, p.type_ with + | Term.Var _, _ + | _, Term.Var _ -> None + | _ -> Some p + | Element.Var _ -> None) + |> Seq.toList + + +let PREDEFINED_PART_TYPE_NAMES = ["ter"; "prom"; "rbs"; "pcr"; "cds"] +let PREDEFINED_PART_TYPES : Term list = PREDEFINED_PART_TYPE_NAMES |> List.map Term.Const + +type Rate = Term +type Complex = Element Mset +let toComplex x : Complex = [1, x] +let mapComplex (f:Element -> Element) (c:Complex) : Complex = + // let g = Process.Map f + let g = Term.Map f + c |> List.map (fun (i, t) -> i, t |> Term.Map f) // |> Term.Map g) + + +let termToDevice cle t : Element list = + let err x = failwithf "Unexpected term %s is not a device (a list of parts )." (Term.ToStringWith cle x) + match t with + | Term.Proc p -> match Process.ToList p with + | [x] -> x + | _ -> err t + | _ -> err t + + +type Instruction = Device of Element list + | Constraint of Literal + | Reaction of Complex option * Complex * Complex * Rate * Rate option // cata, react, prod, rate, bw rate + | Initial of Term * Complex // concentration, molecule + with + static member Map (f:Element -> Element) i = + match i with + | Device d -> d |> List.map f |> Device + | Constraint c -> c |> Literal.Map (Term.Map f) |> Constraint + | Reaction (a,b,c,d,e) -> let g = mapComplex f + let h = Rate.Map f + Reaction (a |> Option.map g, g b, g c, h d, Option.map h e) + | Initial (pop, t) -> Initial ((pop |> Term.Map f), mapComplex f t) + static member Species i : Element list = + let f = List.collect (snd >> Term.Species) + match i with + | Device d -> d + | Constraint c -> Literal.Species c + | Reaction (a,b,c,d,e) -> let s1 = a |> Option.toList |> List.collect f + let s2 = f b + let s3 = f c + + let s4 = d |> Term.Species + let s5 = e |> Option.toList |> List.collect Term.Species + s1 @ s2 @ s3 @ s4 @ s5 |> List.distinct + + | Initial (pop, t) -> (Term.Species pop @ f t) |> List.distinct + static member Apply (cle:CLE) (Sub s:Substitution) i = + match i with + | Device d -> Device (d |> List.map (fun x -> cle.applySub s x)) + | Constraint c -> Constraint (c |> applyL cle (Sub s)) + | Reaction (a,b,c,d,e) -> failwith "Reactions not supported yet" + | Initial (pop, t) -> let pop' = Substitution.Apply(Sub s, pop, cle) + let t' = t |> List.map (fun (i,x) -> i, Substitution.Apply(Sub s, x, cle)) + Initial (pop', t') + static member ToString (cle:CLE) i : string = + let printDevice d = d |> List.map Element.ToString |> String.concat " " |> sprintf "<%s>" + match i with + | Instruction.Device d -> printDevice d + | Instruction.Constraint c -> Literal.ToStringWith cle c + | Reaction (a,b,c,d,e) -> failwith "Reactions not supported yet" + | Initial (pop, t) -> sprintf "%s %s" (Term.ToStringWith cle pop) (Term.ToStringWith cle (TMSet t)) + + static member GetParts (i:Instruction) = + let f e = match e with + | Element.Part p -> match p.name, p.type_ with + | Term.Var _, _ + | _, Term.Var _ -> None + | _ -> Some p + | Element.Var _ -> None + + match i with + | Device d -> d |> List.choose f + | Constraint c -> c |> Literal.Species |> List.choose f + | Initial (c, i) -> let x = c |> Term.Species |> List.choose f + let y = i |> List.collect (snd >> Term.Species >> List.choose f) + x @ y + | Reaction _ -> failwith "Reactions are not supported yet" + |> List.distinct + +// Disambiguation step: +// if X is both a term var and an element var, turn Term.Var X into Term.Pattern [Pattern.Inner [Element.Var X, Locatiom.wildcard]] +// create var to assignments map +let rec updateMap (m:Map option * bool * bool>) // what has v been used for so far? As a term, a part, a part name (store the part type if so, so that var and part type can reconstruvct the full type), a part type, a location? + (v:Var) + (arg:Choice, unit, unit>) = // what is v being used for? + if m.ContainsKey v + then m.Add (v, (match m.[v] with + (a,b,c,d,e) -> + match arg with + | Choice1Of5 _ -> (true,b,c,d,e) + | Choice2Of5 _ -> (a,true,c,d,e) + | Choice3Of5 t -> + // TODO: check if c or t are Term.wildcard + (a,b,Some t,d,e) + | Choice4Of5 _ -> (a,b,c,true,e) + | Choice5Of5 _ -> (a,b,c,d,true) )) + else m.Add (v, match arg with + | Choice1Of5 _ -> (true,false,None,false,false) + | Choice2Of5 _ -> (false,true,None,false,false) + | Choice3Of5 t -> (false,false,Some t,false,false) + | Choice4Of5 _ -> (false,false,None,true,false) + | Choice5Of5 _ -> (false,false,None,false,true) + ) +// +and getMapElement m (e:Element) = + match e with + | Element.Var v -> updateMap m v (Choice2Of5 ()) + | Element.Part p -> + let m' = match p.name with + | Term.Var (i,v) -> updateMap m (i, v) (Choice3Of5 p.type_) + | _ -> getMapTerm m p.name + match p.type_ with + | Term.Var (i,v) -> updateMap m' (i, v) (Choice4Of5 ()) + | _ -> getMapTerm m' p.name + +and getMapLocation m l = + match l with + | Location.Var (x, y) -> let v = (x,y) in updateMap m v (Choice5Of5 ()) + | Location.Loc _ -> m + +and getMapHole m (s:Element, l:Location) = getMapLocation (getMapElement m s) l + +and getMapPattern m = + function + | Pattern.Inner hs -> hs |> List.fold getMapHole m + | Pattern.Nihil -> m + | Pattern.FivePrime hs -> hs |> List.fold getMapHole m + | Pattern.ThreePrime hs -> hs |> List.fold getMapHole m + | Pattern.Nicking(hs1, hs2) -> let m' = hs1 |> List.fold getMapHole m + hs2 |> List.fold getMapHole m' + | Pattern.Strand hs -> hs |> List.fold getMapHole m + +and getMapProcess m = + function + | Process.Proc strandsMap -> strandsMap + |> Map.toList + |> List.map snd + |> List.fold (fun acc s -> s |> List.fold getMapElement acc) m +and getMapComplex m (c:Complex) = + c |> List.fold (fun acc x -> getMapTerm acc (snd x)) m +and getMapTerm m = + function + | Term.Var (x, y) -> updateMap m (x, y) (Choice1Of5 ()) + | Term.Const _ + | Term.Float _ -> m + | Func (_, ts) + | TList ts -> ts |> List.fold getMapTerm m + | TCons (t1, t2) -> let m' = getMapTerm m t1 + getMapTerm m' t2 + | Proc p -> getMapProcess m p + | Pat p -> getMapPattern m p + | Term.TMSet ts -> ts |> List.fold (fun acc (_,v) -> getMapTerm acc v) m + | Term.TCRN ts -> ts |> List.fold getMapTerm m + +and getMapPredicate m = function + | Predicate.Pred(_, args) -> args |> List.fold getMapTerm m + +and getMapLit m = function + | Pos p -> getMapPredicate m p + | Neg p -> getMapPredicate m p + +(* +let zzz (cle:Engine) m xmap xapply = + m + |> + Map.fold (fun x varName assignments -> + // disambiguate each variable + if varName = (-1, "_") + then x // skip wildcards + else + match assignments with + // skip unambiguous variables + | false, false, None, false, false + | true, false, None, false, false + | false, true, None, false, false + | false, false, Some _, false, false + | false, false, None, true, false + | false, false, None, false, true -> x + | _(*hasTVar*), hasEVar, nameVar, hasTypeVar, hasLocVar -> + let hasNameVar = Option.isSome nameVar + let p' = match nameVar with + | Some ty -> { name = Term.Var varName; type_ = ty } + | None -> { name = Term.wildcard; type_ = Term.Var varName } + if hasLocVar + then + if hasEVar || hasNameVar || hasTypeVar + then failwith <| sprintf "Cannot unify location variable \"%s\" with a %s variable" (snd varName) + (if hasTypeVar then "part type" + elif hasNameVar then "part name" + else "part") + else // must be TVar too + let pattern = Term.Pat <| Pattern.Inner [Element.Var (-1,"_"), Location.Var varName] + let sub = Substitution.Create(varName, pattern).Add(varName, Choice2Of4 <| Location.Var varName, cle) + xapply x sub + // disambiguate variable + elif hasNameVar || hasTypeVar + then + if hasEVar + then + // Consider this example: P = C[X], P = [X::Y] + // Disambiguation interprets X in the first term a part with name X and type Y + x + |> xmap (fun t -> + t + |> Term.Map (fun e -> + match e with + | Element.Var (x,y) -> if (x,y) = varName then Part p' else e + | Element.Part p'' -> Part <| if hasNameVar && p''.name = p'.name then p' else p'' + )) + else x // if it's a TVar, nothing to do + else // not a LocVar, NameVar or TypeVar: must be a TVar and EVar + let rec f (term:Term) = + match term with + | Term.Var (x,y) -> if (x,y) = varName + then Term.Pat <| Pattern.Inner [Part p', Location.wildcard] + else term + | Term.Const _ + | Term.Float _ + | Term.Pat _ + | Term.Proc _ -> term + | Term.Func (n, ts) -> Term.Func (n, ts |> List.map f) + | Term.TCons (t1, t2) -> Term.TCons (f t1, f t2) + | Term.TList ts -> Term.TList (ts |> List.map f) + | Term.TCRN ts -> Term.TCRN (ts |> List.map f) + | Term.TMSet ts -> Term.TMSet (ts |> List.map (fun (i, x) -> i, f x)) + x |> xmap f + ) +*) + +/////////////////////////////////// +// Logic GEC Custom Logic Engine // +/////////////////////////////////// +and fvPart (p:Part) = + [p.name; p.type_] + |> List.map (fvt cle) + |> Set.unionMany + +and fvElement (e:Element) = + let rec fv t = + match t with + | Term.Var (-1, "_") -> Set.empty + | Term.Var (x,y) -> Set.singleton (TVar (x,y)) + | Term.Const _ -> Set.empty + | Term.Float _ -> Set.empty + | Term.Func (_, ts) -> ts |> unionFold fv + | Term.TList ts -> ts |> unionFold fv + | Term.TCons (t,t') -> [t;t'] |> unionFold fv + | Term.Pat _ -> Set.empty // p |> fvPattern cle + | Term.Proc _ -> Set.empty // TODO + | Term.TCRN ts -> ts |> unionFold fv + | Term.TMSet ts -> ts |> List.map snd |> unionFold fv + match e with + | Part p -> fvPart p + | Var x -> if x = (-1, "_") then Set.empty else Set.singleton (SVar (x, e)) + +and elemToString (x : Element) : string = + let toString t = match t with + | Term.Const x -> x + | _ -> Term.ToStringWith cle t + match x with + | Part p -> let typ = match p.type_ with + | Term.Var (-1, "_") -> "" + | _ -> " : " + toString p.type_ + toString p.name // + typ + | Var (_, y) -> y + +and elemCompare (x:Element) (y:Element) = + match x, y with + | Part _, Var _ -> RulesDSD.Syntax.LT + | Var _, Part _ -> RulesDSD.Syntax.GT + | Part p1, Part p2 -> Term.Compare cle p1.name p2.name + | Var (v1, _), Var (v2, _) -> compare v1 v2 + +and elemCanonicalForm (x:Element) = x + +and elemUnderscore () = Var (-1, "_") + +and elemRefresh (idProvider : string -> int) e = + match e with + | Part p -> + let refresher = Term.refresh cle idProvider + let n = refresher p.name + let t = refresher p.type_ + + Part (Part.Create(n, t)) + | Var (_, y) -> Var (idProvider y, y) + +and unimplemented _ = failwith "" + +and deviceComposition p q = Process.ToList p @ Process.ToList q |> Process.OfList + +and elemResolveGoal (p, args) _ = + match (p, args) with + | _ -> None + + +and elemDisambiguateVarsWith m (c:Clause) : Clause = + // TODO: is this still necessary? + + // remove "noTypePart" types from parts (in patterns and processes) + let g(e:Element) = + match e with + | Element.Var _ -> e + | Element.Part p -> if p.type_ = Term.Const noTypePart + then { p with type_ = Term.wildcard } + else p + |> Element.Part + + // turn all other "noTypePart" parts into (Term.Const part.name) + let rec f (e:Term) = + match e with + | Term.Pat (Pattern.Inner [Element.Part ({ name = n; type_ = Term.Const "%NoTypePart"}), Location.Var (-1, "_")]) -> n + | Term.Float _ + | Term.Const _ + | Term.Var _ -> e + | Term.Pat p -> p |> Pattern.Map (fun (x, y) -> g x, y) |> Term.Pat + | Term.Proc p -> p |> RulesDSD.Syntax.Process.Map g + |> Term.Proc + | Term.TList ts -> ts |> List.map f |> Term.TList + | Term.TCons (t1, t2) -> Term.TCons (f t1, f t2) + | Term.TCRN ts -> ts |> List.map f |> Term.TCRN + | Term.TMSet ts -> ts |> List.map (fun (i, t) -> i, f t) |> Term.TMSet + | Term.Func (n, ts) -> Term.Func (n, ts |> List.map f) + + let c' = c |> Clause.Map f + match c'.head with + | Pred (_, lits) -> + // collect how each variable is used + c'.body + |> List.fold getMapLit (lits |> List.fold getMapTerm Map.empty) + // m + |> Map.fold (fun (clause:Clause) varName assignments -> + // disambiguate each variable + if varName = (-1, "_") + then clause // skip wildcards + else + match assignments with + // skip unambiguous variables + | false, false, None, false, false + | true, false, None, false, false + | false, true, None, false, false + | false, false, Some _, false, false + | false, false, None, true, false + | false, false, None, false, true -> clause + | _(*hasTVar*), hasEVar, nameVar, hasTypeVar, hasLocVar -> + let hasNameVar = Option.isSome nameVar + let p' = match nameVar with + | Some ty -> { name = Term.Var varName; type_ = ty } + | None -> { name = Term.wildcard; type_ = Term.Var varName } + if hasLocVar + then + if hasEVar || hasNameVar || hasTypeVar + then failwith <| sprintf "Cannot unify location variable \"%s\" with a %s variable" (snd varName) + (if hasTypeVar then "part type" + elif hasNameVar then "part name" + else "part") + else // must be TVar too + let pattern = Term.Pat <| Pattern.Inner [Element.Var (-1,"_"), Location.Var varName] + let sub = Substitution.Create(varName, pattern).Add(varName, Choice2Of4 <| Location.Var varName, cle) + sub.Apply(clause,cle) + // disambiguate variable + elif hasNameVar || hasTypeVar + then + if hasEVar + then + // Consider this example: P = C[X], P = [X::Y] + // Disambiguation interprets X in the first term a part with name X and type Y + clause + |> Clause.Map (fun t -> + t + |> Term.Map (fun e -> + match e with + | Element.Var (x,y) -> if (x,y) = varName then Part p' else e + | Element.Part p'' -> Part <| if hasNameVar && p''.name = p'.name then p' else p'' + )) + else clause // if it's a TVar, nothing to do + else // not a LocVar, NameVar or TypeVar: must be a TVar and EVar + let rec f (term:Term) = + match term with + | Term.Var (x,y) -> if (x,y) = varName + then Term.Pat <| Pattern.Inner [Part p', Location.wildcard] + else term + | Term.Const _ + | Term.Float _ + | Term.Pat _ + | Term.Proc _ -> term + | Term.Func (n, ts) -> Term.Func (n, ts |> List.map f) + | Term.TCons (t1, t2) -> Term.TCons (f t1, f t2) + | Term.TList ts -> Term.TList (ts |> List.map f) + | Term.TCRN ts -> Term.TCRN (ts |> List.map f) + | Term.TMSet ts -> Term.TMSet (ts |> List.map (fun (i, x) -> i, f x)) + clause |> Clause.Map f + ) c' + //) c + +and elemDisambiguateVars (c:Clause) : Clause = + let m = match c.head with Pred (_, lits) -> c.body |> List.fold getMapLit (lits |> List.fold getMapTerm Map.empty) + elemDisambiguateVarsWith m c + +and elemApplySub (theta:Sub) (e:Element) : Element = + match e with + | Var (-1, "_") -> e + | Var v -> if theta.ContainsKey v + then match theta.[v] with + | Choice1Of4 _ -> failwith "" + | Choice2Of4 _ -> failwith "" + | Choice3Of4 x -> x + | Choice4Of4 _ -> failwith "" + else e + | Part p -> let applier (x:Term) = Substitution.Apply(Sub theta, x, cle) + let n = applier p.name + let t = applier p.type_ + Part (Part.Create(n, t)) + +and elemApplyAll (theta:Sub) (x:Choice) = + match x with + | Choice1Of2 e -> elemApplySub theta e + | Choice2Of2 () -> failwith "" + +and elemUnify (x:Element, y:Element) : Sub list = + match x, y with + | Part p, Var x + | Var x, Part p -> [Map.ofList [x, Choice3Of4 <| Part p]] + | Var x, Var y -> [Map.ofList [y, Choice3Of4 <| Var x]] + | Part p1, Part p2 -> + let eq1 = RulesDSD.Unification.TEq (p1.name, p2.name) + let eq2 = RulesDSD.Unification.TEq (p1.type_, p2.type_) + let eqs = [eq1; eq2] + RulesDSD.Unification.unify cle eqs + + |> List.map (fun (Sub x) -> x) + +and cle : Engine = + { toString = elemToString // print 's + toStringTempVar = unimplemented // print 'a + compare = elemCompare // compare two 's, used for sorting; the actual ordering is unimportant, as long as it is a partial order + cast = unimplemented // cast a 'a into a 's (e.g. a bond X can be cast into a site _!X); used in substitutions + toCanonicalForm = elemCanonicalForm // find the canonical form of 's + toCanonicalFormProcess = id // find the canonical form of a process. Since species 's might reference each other (e.g. as in bonds), it is necessary to have a Process level canonical form function + unify = elemUnify // species unification. The core algorithm that finds a 's and 'a variable substitution such that two species are equivalent after applying it + underscore = elemUnderscore // wildcard "_" for 's + applyAll = elemApplyAll // apply a substitution to a species or subspecies + applySub = elemApplySub // apply a species substitution + applySubVar = unimplemented // apply a substitution to a subspecies + fvs = fvElement // free variables in 's + refresh = elemRefresh // provide a copy of 's where variables have been renamed by an ID provider. Used in resolution + disambiguateVars = elemDisambiguateVars // post-parsing step applied to each parsed clause. In Logic DSD this is used to disambiguate the use of domain variables (e.g. in P = C[D][D!i], D can be cast down to an unbound domain rather than a generic site) + ComposeProcesses = deviceComposition // compose two processes together (possibly forming a complex in Logic DSD) + resolveGoal = elemResolveGoal // species-specific predicates resolution. The core resolution algorithm that executes custom predicates for species (e.g. "compl(D, E)" is a custom predicate in Logic DSD to find the complement E of a domain D) + domainKeywords = [] } + + +// free variables +let fvi (i:Instruction) = + let rec fvElement (e:Element) = + match e with + | Element.Part p -> + let f x = fvt cle x + Set.union (f p.name) (f p.type_) + | Element.Var v -> Set.singleton (Variable.SVar (v, e)) + + let rec fvComplex (c:Complex) = + c |> List.fold (fun acc (_, tp) -> + let t = tp |> Term.Species // |> List.collect (Process.ToList >> List.concat) |> List.distinct + Set.union acc (Set.unionMany (t |> List.map fvElement))) Set.empty + + match i with + | Device d -> d |> List.map fvElement |> List.fold (Set.union) Set.empty + | Constraint c -> fvl cle c + | Initial (n,c) -> Set.union (fvt cle n) (fvComplex c) + | Reaction(a,b,c,d,e) -> + let av = a |> Option.toList |> List.map fvComplex + let ev = e |> Option.toList |> List.map (fvt cle) + let fvs = av @ ([b;c] |> List.map fvComplex) @ [fvt cle d] @ ev + Set.unionMany fvs + +type Program = Instruction list + +let enumerateDeviceSubstitutions (cle:Engine) (db:Semantics) (prog:Program) = + let freevars = + prog + |> List.map fvi + |> Set.unionMany + let maxVar = + freevars + |> Set.map (fun x -> + match x with + | Variable.SVar ((n,_), _) + | Variable.IVar ((n,_), _) + | Variable.LVar (n,_) + | Variable.TVar (n,_) -> n) + |> fun s -> if s.IsEmpty then 0 else Set.maxElement s + let counter = ref (maxVar + 1) + + let deviceEnumeration d sols = + d |> List.fold (fun acc elem -> + match acc with + | None -> None + | Some solutions -> + solutions + |> List.collect (fun (s:RulesDSD.Substitution.Substitution) -> + match elem with + | Part part -> + // prepare device query + let pName = s.Apply(part.name , cle) + let pType = s.Apply(part.type_, cle) + let qPart = Part { name = pName; type_ = pType } + let query = [ Pos (Pred ("part", [Term.Pat (Pattern.Inner [qPart, Location.wildcard]) ])) ] + + // interrogate DB + let goal = RulesDSD.Resolution.Goal.Create(query, cle) + match RulesDSD.Resolution.resolveInner [goal] cle counter db [] RulesDSD.Resolution.Mode.AllAnswers with + | None -> [] + | Some newSols -> if solutions = [Substitution.id] + then newSols + else newSols |> List.map (fun s' -> RulesDSD.Substitution.Substitution.Compose s s' cle) + | Var v -> + // look for any part in the DB + let query = [ Pos (Pred ("part", [Term.Pat (Pattern.Inner [Var v, Location.wildcard]) ])) ] + let goal = RulesDSD.Resolution.Goal.Create(query, cle) + match RulesDSD.Resolution.resolveInner [goal] cle counter db [] RulesDSD.Resolution.Mode.AllAnswers with + | None -> [] + | Some newSols -> if solutions = [Substitution.id] + then newSols + else newSols |> List.map (fun s' -> RulesDSD.Substitution.Substitution.Compose s s' cle) ) + |> fun x -> if x.IsEmpty then None else Some (x |> List.distinct) + ) (Some sols) + + prog |> List.fold (fun (solutionsSet:RulesDSD.Substitution.Substitution list option) i -> + match solutionsSet with + | None -> None // some constraint is unsatisfiable; abort enumeration + | Some sols -> + match i with + | Initial (_, [1, Term.Proc p]) -> match p |> Process.ToList with + | [d] -> deviceEnumeration d sols + | _ -> failwithf "Unexpected multiple devices in initial %s." (Instruction.ToString cle i) + | Device d -> deviceEnumeration d sols + + | Constraint c -> let sols' = + sols + |> List.collect (fun (s:RulesDSD.Substitution.Substitution) -> + let c' = s.Apply(c, cle) + let g = RulesDSD.Resolution.Goal.Create([c'], cle) + match RulesDSD.Resolution.resolveInner [g] cle counter db [] RulesDSD.Resolution.Mode.AllAnswers with + | None -> [] + | Some newSols -> if sols.IsEmpty + then newSols + else newSols |> List.map (fun s' -> RulesDSD.Substitution.Substitution.Compose s s' cle) ) + match sols' with + | [] -> None + | _ -> Some sols' + + | Reaction _ -> solutionsSet // TODO: check that the interaction is in the DB? + | Initial _ -> solutionsSet + ) (Some [Substitution.id]) + +let enumerateDevices (cle:Engine) (db:Semantics) (prog:Program) : Program list = + let maxVar = + prog + |> List.map fvi + |> Set.unionMany + |> Set.map (fun x -> + match x with + | Variable.SVar ((n,_), _) + | Variable.IVar ((n,_), _) + | Variable.LVar (n,_) + | Variable.TVar (n,_) -> n) + |> fun s -> if s.IsEmpty then 0 else Set.maxElement s + |> ref + + let fullProgram = + prog + |> List.map (Instruction.Map (fun e -> + match e with + | Element.Var _ -> e + | Element.Part p -> if p.name = Term.wildcard + then + let x = !maxVar + maxVar := !maxVar + 1 + let freshVar = Term.Var(x, sprintf "X_%i" x) + Element.Part { p with name = freshVar} + else e)) + + + let devs = + fullProgram + |> List.filter (fun i -> match i with + | Instruction.Device _ -> true + | Instruction.Initial _ -> true + | _ -> false) + + match enumerateDeviceSubstitutions cle db fullProgram with + | None -> [] + | Some sols -> + sols + |> List.map (fun (RulesDSD.Substitution.Substitution.Sub s) -> + devs + |> List.map (Instruction.Map (cle.applySub s))) + |> List.distinct + + + +(* GEC calculus*) +let makeGecCalculus (db:Semantics) : Calculus> = + // prepare the set of "reaction" predicates to run in the calculus + + // collect all "reactions" signatures + // find all reactions predicate + let reactionsSigs = seq { for kv in db.Keys do + if fst kv = "reactions" then yield kv else () } + |> Seq.sortWith (fun (_, x) (_, y) -> compare x y) + |> Seq.toList + |> Seq.map (fun x -> x, db.Item x) + + { react = fun (oldElements:Term list) (newElement:Term) -> + // find all query combos: reactions(CRN), reactions(newElement, CRN), reactions (newElement, oldElem, CRN), reactions (newElement, oldElem1, oldElem2, ..., CRN) ... + // run all queries + // create new reactions + let newProc = newElement |> Term.Canonical cle + let oldProcs = oldElements |> List.map (Term.Canonical cle) + let rec combo n i : Term list list = + if n <= 0 + then [] + else let ccombo = if n = i + then [[newProc]] + else combo (n-1) i + if ccombo.IsEmpty + then [oldProcs] + else + oldProcs + |> List.collect (fun p -> + ccombo + |> List.map (fun ps -> p :: ps)) + + let queries = + reactionsSigs + |> Seq.filter (fun ((_, numberOfArguments), _) -> numberOfArguments >= 2 ) // take reactions(E1, ...., En, CRN) predicates + |> Seq.collect (fun ((queryName, numberOfArguments), preds) -> + match numberOfArguments with + | 2 -> preds |> Set.map (fun p -> match p.head.Args with [_; x] -> Pos (Pred(queryName, [newProc; x])) | _ -> failwith "") |> Set.toSeq + | n -> let allElementArgs = [1..n-1] |> List.collect (fun i -> combo (n-1) i) + preds + |> Set.map (fun (p:Clause) -> allElementArgs + |> List.map (fun args -> Pos (Pred(queryName, args @ [p.head.Args |> List.last] )))) + |> Set.toSeq + |> Seq.concat) + |> Seq.distinct + + // query the Prolog engine and create CRN reactions if any "reactions()" predicate matched + queries + |> Seq.choose (fun query -> + match RulesDSD.Resolution.resolveAll query db cle with + | None -> None + | Some sols -> + sols + |> List.collect (fun theta -> + match theta.Apply(query, cle) with + | Pos p -> + // reactants are already in canonical form by construction + match p.Args |> List.last with + | Term.TCRN ts -> ts + |> List.map (Term.Canonical cle) + |> List.collect Term.ToReactions + | _ -> let str = query |> Literal.ToStringWith cle + failwithf "Error: enumeration predicate %s generated a non-CRN term." str + | _ -> failwith "" ) + |> Some + ) + |> List.concat + |> List.distinct + |> List.filter (fun r -> r.reactants <> r.products) + } + + +/////////////////////////// +/////////////////////////// +//// Parser +/////////////////////////// +/////////////////////////// + +let pInstruction (idProvider : string -> RulesDSD.Syntax.Var) = + let pElement = Element.doParse cle.domainKeywords true idProvider + let pDevice = Parser.between (kw "<") (kw ">") (Parser.many1 pElement) + let pDeviceAst = pDevice |>> Instruction.Device + let pConstraintAst = RulesDSD.Parser.pliteral cle pElement idProvider cle.domainKeywords |>> Instruction.Constraint + let pInitialAst = RulesDSD.Parser.pterm pElement cle idProvider cle.domainKeywords .>>. + choice [ pDevice |>> Choice1Of2 + RulesDSD.Parser.pterm pElement cle idProvider cle.domainKeywords |>> Choice2Of2 ] + >>= fun (i, x) -> + match x with + | Choice1Of2 x -> preturn (Instruction.Initial (i, x |> List.singleton |> Process.OfList |> Term.Proc |> toComplex)) + | Choice2Of2 x -> preturn (Instruction.Initial (i, x |> toComplex)) + + + Parser.plookAheadWith + (choice [ + // device + kw "<" >>. preturn (Choice1Of4 ()) + // constraint + kw "not" >>. pname >>. kw "(" >>. preturn (Choice2Of4 ()) + pname >>. kw "(" >>. preturn (Choice2Of4 ()) + // reaction + // choice [ pdevice >>. choice [kw "+"; kw "->"; preturn Choice1Of4 ()] // last case is actually a device + // kw "->" ] // no reactants reaction + + // initial + Expression.parse pname >>. preturn (Choice4Of4 ()) + ]) >>= + fun next -> + match next with + | Choice1Of4 _ -> pDeviceAst + | Choice2Of4 _ -> pConstraintAst + | Choice3Of4 _ -> failParser "Reactions not supported yet" + | Choice4Of4 _ -> pInitialAst + + +let generateCRN (cle:Engine) (db:Semantics) (prog:Program) = + // collect devices, initials and reactions // TODO: merge devices and initials into a single field initials of type (Term * Process) + let ps, is, rs = + prog |> List.fold (fun (ps, is, rs) instruction -> + match instruction with + | Constraint _ -> (ps, is, rs) // skip constraints + | Reaction (a,b,c,d,e) -> (ps, is, (a,b,c,d,e) :: rs) + | Device d -> (Process.OfList [d] :: ps, is, rs) + | Initial (a,b) -> if a <> Term.Float 0.0 + then (ps, (a,b)::is, rs) + else (ps, is, rs)) ([], [], []) + + // species namer + let default_namer () : (Term -> string) = + let cache = new System.Collections.Generic.Dictionary, string>() + let names = new System.Collections.Generic.HashSet() + let namer species : string = + let sp = species |> Term.Canonical cle + if cache.ContainsKey sp then + cache.Item sp + else + let mutable unique_name = "" + let mutable c = names.Count + 1 + while unique_name = "" do + if not (names.Contains ("sp" + string c)) then + unique_name <- "sp" + string c + else c <- c + 1 + let name = unique_name + + cache.Add(sp, name) + ignore(names.Add(name)) + name + namer + let namer = default_namer () + + + // prepare initials and reactions for CRN enumeration + // TODO: get the initial concentration from the core GEC program after merging process and initials + let inits = (is |> List.map (fun (n, i) -> let t = match i with + | [1, x] -> x + | _ -> Term.TMSet i + let c : Value = + match n with + | Term.Float x -> Expression.Float x + | Term.Const x -> Expression.Key x + | Term.Var (_, x) -> Expression.Key x + | _ -> failwithf "Initial condition %s must be a float, const or a variable." (Term.ToStringWith cle n) + c, t)) + @ (ps |> List.map (fun p -> Expression.Float 1.0, p |> Term.Proc)) + |> List.map Initial.create + + let toMSet (x:Complex) : Microsoft.Research.CRNEngine.Mset.t> = + x |> List.map (fun (i, sp) -> { Microsoft.Research.CRNEngine.Mset.element = sp + ; Microsoft.Research.CRNEngine.Mset.multiplicity = i}) + let reacts = rs |> List.choose ( fun (catalysts,reactants,products,fwRate,bwRate) -> + let r = reactants |> toMSet + let p = products |> toMSet + match Term.ToRate fwRate with + | None -> None + | Some fr -> + let br = match bwRate with + | None -> None + | Some b -> Term.ToRate b + match catalysts with + | None -> Reaction.create([], r, br, fr, p) |> Some + | Some c -> Reaction.create(c |> toMSet, r, br, fr, p) |> Some ) + + // expand the GEC program into a CRN using the GEC calculus + let equalsSpecies p q = Term.Compare cle (p |> Term.Canonical cle) (q|> Term.Canonical cle) = EQ + let plotMatcher p q = Term.Compare cle p q = EQ + let gecCalculus = makeGecCalculus db + + let gecRenderer (s:Term) : Attributes = + { name = namer s + ; structure = Term.ToStringWith cle s + ; svg = "" } + + + + let crn = Crn.from_calculus_translated + (fun p -> namer p |> Species.create) + gecRenderer + equalsSpecies + plotMatcher + (fun sp -> (fvt cle sp).IsEmpty) + "" + Microsoft.Research.CRNEngine.Crn_settings.defaults + gecCalculus + inits + reacts + false + true + true + |> Crn.group_reactions + + crn + +let pGecProgram : Parser.t = RulesDSD.Parser.pprogram cle (Element.doParse cle.domainKeywords true) \ No newline at end of file diff --git a/ClassicGEC/ClassicGECDotNet/main.fs b/ClassicGEC/ClassicGECDotNet/main.fs new file mode 100644 index 0000000..79c9262 --- /dev/null +++ b/ClassicGEC/ClassicGECDotNet/main.fs @@ -0,0 +1,140 @@ +(* +Provides top-level access to LSB translation. Functions in this module +will invoke the LSB compiler, invoke the Prolog engine and parse the results +in to an appropriate .NET data structure. + +Author: Michael Pedersen. +Copyright Microsoft Research, 2008-2009. +*) + +[] +module Microsoft.Research.GEC.Main + +open Microsoft.Research.GEC.Ast +open Microsoft.Research.GEC.Trans +open Microsoft.Research.CRNEngine +open Microsoft.Research.GEC.DirectivesParser + +open Parser +//open Microsoft.FSharp.Compatibility.OCaml +//open Microsoft.Research.ModellingEngine +open System.IO +open Printf + + + +// make LBS rate definition strings +let mkSingleLBSRateDef (r,f) = "rate " + r + " = " + (Lib.display_float f) + ";" +let mkLBSRateDefs rateDecs = + (Lib.string_of_list mkSingleLBSRateDef Lib.newline (expandRateDecs rateDecs)) + Lib.newline + +// produce a string representation of an assignment... +let stringOfAss (xs:(string * string) list) = + Lib.brack (Lib.string_of_list (fun (x,y) -> Lib.paren(Lib.quote x + ", " + Lib.quote y)) "; " xs) + +/// Input position range, this will likely be replaced by something from FParsec +type pos = {l1 : int; c1 : int; l2 : int; c2 : int} + +// a solution type for passing back to a C# client: +type tSolution = + { + bbDevices : tBbDevices; + lbsProgram : tLBSProg; + rateDecs : tRateDecs; + + // variable assignments represent solutions to constraints: + varAss : ((string * string) list * (string * string) list * (string * string) list) list; + substs : Subst.t list; + + // an error option for reporting errors: + error : (string * pos option) option; + + // the number of solutions to constraints: + numSolutions : int; + } + + // get a specific instance of the device of a solution: + member v.getDevicesInstance(num) = + let devices = v.bbDevices + let (subst,_,_) = List.item num v.varAss + //let devices' = devices |> List.map (fun device -> device |> List.map (fun var -> if (List.mem_assoc var subst) then List.assoc var subst else var)) + let devices' = devices |> List.map (fun device -> device |> List.map (fun var -> match Lib.try_assoc var subst with | Some x -> x | None -> var)) + Lib.brack (Lib.string_of_list (fun xs -> Lib.brack(Lib.string_of_list Lib.id "; " xs)) ";\r " devices') + + // get a specific instance of the device of a solution as a string list list: + member v.getDevicesInstanceStructured(num) = + let devices = v.bbDevices + let (subst,_,_) = List.item num v.varAss + let devices' = devices |> List.map (fun device -> device |> List.map (fun var -> match Lib.try_assoc var subst with | Some x -> x | None -> var)) + let devicesArray = List.toArray(List.map (fun lst -> List.toArray(lst)) devices' ) + devicesArray + + // get a specific instance of the program of a solution: + member v.getProgramInstance(num) = + let prog = v.lbsProgram + let (_,substSpec,substRates) = List.item num v.varAss + let lbsProgStr = lbsProgToStr prog (substSpec@substRates) + (mkLBSRateDefs v.rateDecs) + lbsProgStr + // add a default declaration for mrna degradation: + //let mrnaDegRate = "rate RMRNADeg = " + (Lib.display_float default_RMRNADeg) + ";\n" + //mrnaDegRate + lbsProgStr + + // get the program instance with declared rates assigned: + member v.getProgramDefault() = + //let lbsProgStr = lbsProgToStr v.lbsProgram v.rateDecs + //lbsProgStr + let lbsProgStr = lbsProgToStr v.lbsProgram [] + (mkLBSRateDefs v.rateDecs) + lbsProgStr + + // get a specific instance of a species assignment: + member v.getSpecAss(num) = + let (l1, specVarAss, l3) = List.item num v.varAss + stringOfAss specVarAss + + // get a specific instance of a species assignment: + member v.getRateAss(num) = + let (_, _, rateVars) = List.item num v.varAss + stringOfAss rateVars + + member v.getVarAssString() = + Lib.brack (Lib.string_of_list (fun (xs,ys,zs) -> Lib.paren (stringOfAss xs + ", " + stringOfAss ys + "; " + stringOfAss zs )) ",\r " v.varAss) + +// define an empty solution: +let emptySolution = { bbDevices = []; + lbsProgram = LBSNil + rateDecs = []; + varAss = []; + substs = []; + error = None; + numSolutions = 0; } + +(* +#if JavaScript +let Lexing_from_string = Microsoft.FSharp.Text.Lexing.LexBuffer<_>.FromString +#else +let Lexing_from_string = Lexing.from_string +#endif + +(* Parse the LSB program from the given string. *) +let parse (text:string) = + let prog = + // Create the lexer, presenting the bytes to the lexer as ASCII regardless of the original + // encoding of the string (the lexer specification is designed to consume ASCII) + let lexbuf = Lexing_from_string text + + // Call the parser + try + let prog = GEC.Pars.start Lex.token lexbuf + prog + + with e -> + let bufPos1 = lexbuf.StartPos + let bufPos2 = lexbuf.EndPos + let pos = (bufPos1, bufPos2) + let err = "Parse error near line " + bufPos1.Line.ToString() + ", character " + bufPos2.Column.ToString() + "\n\n" + raise (LBS.Error.CompilerExPos(err, Some pos)) + prog + *) + + +let parse (text:string) = Parser.from_string Program.parse text \ No newline at end of file diff --git a/ClassicGEC/ClassicGECDotNet/options.fs b/ClassicGEC/ClassicGECDotNet/options.fs new file mode 100644 index 0000000..8e53035 --- /dev/null +++ b/ClassicGEC/ClassicGECDotNet/options.fs @@ -0,0 +1,15 @@ +[] +module Microsoft.Research.GEC.Options + +type t = { gecProgram:string + ; simulationOnlyReactions:bool } + +let default_options = { gecProgram="" + ; simulationOnlyReactions=false } + +let keep_ui_options (opts:t) = opts + +let getGECProgramText (opts:t) = opts.gecProgram +let setGECProgramText (s:string) (opts:t) = {opts with gecProgram=s} +let getSimulationOnlyReactions (opts:t) = opts.simulationOnlyReactions +let setSimulationOnlyReactions (b:bool) (opts:t) = {opts with simulationOnlyReactions=b} diff --git a/ClassicGEC/ClassicGECDotNet/options.fsi b/ClassicGEC/ClassicGECDotNet/options.fsi new file mode 100644 index 0000000..f83bc46 --- /dev/null +++ b/ClassicGEC/ClassicGECDotNet/options.fsi @@ -0,0 +1,11 @@ +module Microsoft.Research.GEC.Options + +type t +val default_options : t + +val keep_ui_options : t -> t + +val getGECProgramText : t -> string +val setGECProgramText : string -> t -> t +val getSimulationOnlyReactions : t -> bool +val setSimulationOnlyReactions : bool -> t -> t diff --git a/ClassicGEC/ClassicGECDotNet/paket.references b/ClassicGEC/ClassicGECDotNet/paket.references new file mode 100644 index 0000000..2b6fb0e --- /dev/null +++ b/ClassicGEC/ClassicGECDotNet/paket.references @@ -0,0 +1,3 @@ +group NETSTANDARD + +FSharp.Core \ No newline at end of file diff --git a/ClassicGEC/ClassicGECDotNet/program.fs b/ClassicGEC/ClassicGECDotNet/program.fs new file mode 100644 index 0000000..bdc0b18 --- /dev/null +++ b/ClassicGEC/ClassicGECDotNet/program.fs @@ -0,0 +1,1069 @@ +[] +module Microsoft.Research.GEC.Program + +open Parser +open Microsoft.Research.GEC.Ast +open Microsoft.Research.GEC.Trans +open Microsoft.Research.GEC.LogicGEC +open Microsoft.Research.CRNEngine +open Microsoft.Research.GEC.DirectivesParser +open RulesDSD.Syntax +//open FsCheck + +//open Microsoft.Research.CRNEngine.InferenceSiteGraph + + +type moduleDefinition = string * (string list) +type moduleInvocation = string * (value list) + +type deviceDefinition = moduleDefinition * (moduleInvocation list) + +type crnModules = ((string * string list) * Microsoft.Research.CRNEngine.Instruction list) list // * Instruction list + +type igPriorType = + | Fixed + | Normal + | TruncatedNormal + +type igPriorOption = + | HasPrior of igPriorType + | NoPrior + +type igPrior = string * igPriorOption + +type igName = string list + +type igedge = igName * (igPrior list) * igName +type ignode = string * (string list) * (Inference_settings option) + + + +type igraphElement = + | Node of ignode + | Edge of igedge + + +type systemReference = + | System of string + | NoSystem + +type system = { + name:string; + withSystem:systemReference; + settings:Settings.Gec_settings; + modules:crnModules; + devices:deviceDefinition list; + prog:Ast.prog} + +type ClassicProgram = { + settings:Settings.Gec_settings; + modules:crnModules; + templates:prog; + devices:deviceDefinition list; + systems:system list; + prog:Ast.prog; + graph:igraphElement list + } + +type LogicProgram = { + settings : Settings.Gec_settings; + rules : Semantics; + program : LogicGEC.Instruction list; +} + +type t = ClassicGec of ClassicProgram + | LogicGec of LogicProgram + +let isLogicGecProgram (prog:t) = match prog with LogicGec _ -> true | _ -> false + +let MODULE = Parser.kw "module" +let PROM = Parser.kw "prom" +let RBS = Parser.kw "rbs" +let PCR = Parser.kw "pcr" +let TER = Parser.kw "ter" +let POS = Parser.kw "pos" +let NEG = Parser.kw "neg" +let CON = Parser.kw "con" +let INITPOP = Parser.kw "initPop" +let NEW = Parser.kw "new" +let DIRECTIVE = Parser.kw "directive" +let MODEL = Parser.kw "model" +let DEVICE = Parser.kw "device" +let TEMPLATE = Parser.kw "template" +let SYSTEM = Parser.kw "system" +let PIPE = Parser.kw "|" +let COMMA = Parser.kw "," +let DOT = Parser.kw "." + +let pPipeLookAhead = Parser.pTry(Parser.pstring "||" >>. Parser.failParser "single expected" <|> Parser.pstring "|") +let PARALLEL = Parser.choice [ + pPipeLookAhead + Parser.pstring "||" + ] .>> Parser.spaces + + +//let speciesnameparser = Parser.pTry(Parser.kw "_" >>. Parser.failParser "Reserved as wildcard keyword" <|> (Parser.many1Satisfy Parser.isLetter .>>. Parser.manySatisfy (fun c -> Parser.isLetter c || Parser.isDigit c || c = '_'|| c = '['|| c = ']'|| c = '-' || c = '\'') |>> fun (a,b) -> a + b) "an identifier") + + + +let oldDirectiveLineParser = (DIRECTIVE >>. (DirectivesParser.oldDirective GecSpecies.parse_crn_species)) +//let directiveParser = oldDirectiveLineParser |>> convertOldDirectiveToGECDirective +let directiveParser = oldDirectiveLineParser + +let parse_id_ns = (Parser.name_kw Microsoft.Research.GEC.Keywords.kwList) +let parse_id = parse_id_ns .>> Parser.spaces + +let pSepLookAhead = Parser.pTry(Parser.pstring "::" >>. Parser.failParser "Unexpected Species separator found" <|> Parser.kw ":") +let parse_brickid = parse_id .>> pSepLookAhead + +let parse_species_id = GecSpecies.parse_species |>> fun(splist) -> {GecSpecies.t.empty_Species with species = splist}.to_string() + + + + + +let rec convertExpToAst (exp:Expression.t)= + match exp with + | Expression.Float(float) -> Ast.FloatAExp(float) + | Expression.Key(key) -> Ast.IdAExp(key) + | Expression.Plus(plus) -> + match plus with first::second::remaining -> + let plusfirst = Ast.PlusAExp(convertExpToAst(first),convertExpToAst(second)) + remaining |> List.fold (fun x y -> Ast.PlusAExp(x,convertExpToAst(y))) plusfirst + | _ -> failwith "" + | Expression.Minus(minus) -> Ast.MinusAExp(convertExpToAst(minus.sub1),convertExpToAst(minus.sub2)) + | Expression.Times(times) -> + match times with first::second::remaining -> + let multfirst = Ast.MulAExp(convertExpToAst(first),convertExpToAst(second)) + remaining |> List.fold (fun x y -> Ast.PlusAExp(x,convertExpToAst(y))) multfirst + | _ -> failwith "" + | Expression.Divide(divide) -> Ast.DivAExp(convertExpToAst(divide.div1),convertExpToAst(divide.div2)) + | Expression.Power(power) -> Ast.PowAExp(convertExpToAst(power.base_),convertExpToAst(power.exponent)) + | _ -> failwith "" + + +let expressionParser = Microsoft.Research.CRNEngine.Expression.parse parse_species_id |>> convertExpToAst + + +let parse_value = Parser.choice[ + Parser.kw "_" |>> fun(_) -> Ast.WildCardVal //Wildcard check against IDParser + expressionParser |>> fun(x) -> + match x with + | Ast.IdAExp(y) -> Ast.IdVal(y) + | Ast.FloatAExp(y) -> Ast.FloatVal(y) + | _ -> Ast.AlgebraicExp(x) + ] + + +let parse_initpop = INITPOP >>. GecSpecies.parse_species .>>. Parser.pfloat + |>> fun(complexSpecies,fl:float) -> + Ast.InitPop(GecSpecies.species_to_gecAbstractComplex complexSpecies,fl) + +let LT = (Parser.pTry((Parser.kw "<-" >>. Parser.failParser "Unexpected - symbol found") <|> (Parser.kw "<")) ) |>> fun _ -> Ast.Lt +//let LT = Parser.kw "<" +let GT = Parser.kw ">" |>> fun _ -> Ast.Gt +let EQ = Parser.kw "=" |>> fun _ -> Ast.Eq + + +let COMPAREOP = LT <|> GT <|> EQ + + +let lookaheadLinebreak = Parser.pTry (Parser.linebreak >>. Parser.failParser "" <|> Parser.satisfy Parser.isWhiteSpace >>. preturn ()) +let lookaheadDashSeparator = Parser.pTry(Parser.pstring "->" >>. failParser "" <|> Parser.pstring "-") + // Parser.satisfy (fun c -> Parser.isWhiteSpace c && c <> '\n') +//let whiteSpacenlb : t = skipChar isWhiteSpace "a white space" + +//#region BrickParser +let propParser = Parser.sepBy parse_value (Parser.kw ",") + +type prom = Regprom of string * Option * Ast.value list list //regType * By * Properties + | Conprom of Option + +//let value_from_string (s:string) = Parser.from_string valueParser s + +let convPromToAstProp (a:prom) = + match a with + |Regprom(regtype,regBy,otherprops) -> + if regBy.IsNone then + (regtype,[]) + else + let firstreg = match regBy.Value with + | IdVal(str) -> (Parser.from_string GecSpecies.parse_species str) |> List.map (fun(x) -> Ast.IdVal(x)) + | _ -> [regBy.Value] + let proplist = firstreg::otherprops + (regtype,proplist) + + |Conprom(conprop) -> + if conprop.IsNone then + "con",[] + else + "con",[[conprop.Value]] + +let regProm (t:string) (props:value list) = + match props with + [] -> Regprom(t,None,[]) + | regBy::properties -> + let proplist = properties |> List.map (fun(x) -> [x]) + Regprom(t,Some(regBy),proplist) + +let conProm (props:value list) = + match props with + [] -> Conprom(None) + | conval::error -> + if error.IsEmpty then + Conprom(Some(conval)) + else + //Parser.failParser "Too many consititutive options" //Can I do this? + Conprom(Some(conval)) + +let promSinglePropertyParser = Parser.choice[ + (POS <|> NEG) .>>. Parser.paren propParser |>> fun(reg,props) -> regProm reg props + CON >>. Parser.paren propParser |>> fun(props) -> conProm props + ] + +let promProperties = Parser.sepBy promSinglePropertyParser (Parser.kw ",") + +let rbsProperty = Parser.kw "rate" >>. Parser.paren propParser |>> fun(proplist) -> proplist |> List.map (fun(x)-> ("rate",[[x]])) + +let codesProperty = Parser.kw "codes" >>. Parser.paren propParser |>> fun(proplist) -> + let absComplexlist = proplist |> List.map(fun(x) -> [x]) + ("codes",absComplexlist) + +let brickPartParser = + Parser.choice[ + PROM >>. Parser.choice [ + Parser.kw "<" + >>. promProperties + .>> Parser.kw ">" |>> fun(proplist) -> + let convertedproplist = proplist |> List.map convPromToAstProp + ("prom",convertedproplist) + Parser.preturn("prom",[]) + ] + RBS >>. Parser.choice[ + Parser.kw "<" >>. rbsProperty .>> Parser.kw ">" |>> fun(proplist) -> ("rbs",proplist) + Parser.preturn("rbs",[]) + ] + PCR >>. Parser.choice[ + Parser.kw "<" >>. codesProperty .>> Parser.kw ">" |>> fun(proplist) -> ("pcr",[proplist]) + Parser.preturn("pcr",[]) + ] + TER |>> fun(_) -> ("ter",[]) + ] + + +let parse_brick = + let brickid_to_value (str:string) = + match str with + | "_" -> Ast.WildCardVal + | _ -> Ast.IdVal(str) + Parser.choice[ + parse_brickid >>= fun(brickid) -> + Parser.choice[ + brickPartParser |>> fun(bricktype,propLst) -> Ast.Brick(brickid_to_value brickid,bricktype,propLst) + DEVICE |>> fun _ -> Ast.Device(brickid) + ] + brickPartParser |>> fun(bricktype,propLst) -> Ast.Brick(Ast.WildCardVal,bricktype,propLst) + ] +//#endregion + + + +type nextParser = + | Brick + | Seq + | Reaction + | ModuleInvocation + | Constraint + | Nil + | GecSpecies + | Compartment + + +let parse_constraints = expressionParser .>>. COMPAREOP .>>. expressionParser +let parse_ast_constraints = parse_constraints |>> fun ((lhs,op),rhs) -> Ast.Constraint(lhs,op,rhs) + +let parse_sequence = Parser.sepBy parse_brick (Parser.kw ";") +let parse_ast_sequence = + parse_sequence |>> fun(seq) -> + match seq with + | [] -> Ast.Nil + | [brick] -> brick + | f::s::rem -> + let fs = Ast.Seq(f,s) + match rem.Length with + | 0 -> fs + | _ -> rem |> List.fold (fun acc x -> Ast.Seq(acc,x)) fs + +let parse_template_args = parse_id .>>. Parser.paren (Parser.sepBy parse_value COMMA) + +let parse_template_inv_args = parse_id >>. Parser.paren (Parser.sepBy GecSpecies.parse_species COMMA) +let parse_ast_template_inv = parse_template_args + |>> fun(modname,args) -> + let complexargs = args |> List.map (fun x -> + match x with + | IdVal(id) -> + let strlist = (Parser.from_string GecSpecies.parse_species id) + strlist |> List.map(fun x -> Ast.IdVal(x)) + | _ -> [x] + ) + Ast.TemplateInv(modname,complexargs) + // check with edge cases. should complexes be separated? + +let parse_reaction_species = Parser.sepBy GecSpecies.parse (Parser.kw "+") +let parse_reactants = + Parser.sepBy GecSpecies.parse_species (Parser.kw "+") + |>> fun (reactants) -> + match reactants with + | [[]] -> [] + | _ -> reactants +let parse_reaction_rate = + Parser.opt (Parser.braces parse_value) + +let parse_reaction_rates = parse_reaction_rate .>>. parse_reaction_rate + +type reactionDirection = | Forward | Reversible +let parse_reaction_direction = + Parser.choice [ + Parser.kw "->" |>> fun _ -> Forward + Parser.kw "<->" |>> fun _ -> Reversible + ] + +let parse_enzyme_option = Parser.opt (Parser.kw "~") +let parse_simulation_option = + Parser.opt (Parser.kw "*") + |>> fun (x) -> + match x with + | Some(_) -> true + | None -> false + +let create_transport_reaction (lhs:GecSpecies.t) (rhs:GecSpecies.t) (dir:reactionDirection) ((r1,r2):value option*value option) (sim:bool) = + + let get_direction (lhs:GecSpecies.t) = match lhs.compartment with | None -> Ast.In | Some(_) -> Ast.Out + let get_compartment (lhs:GecSpecies.t) (rhs:GecSpecies.t) = + match lhs.compartment with + | Some(comp) -> comp + | None -> + match rhs.compartment with + | Some(comp) -> comp + | None -> failwith "Malformed Transport Reaction" + let create_forward_transport_reaction (lhs:GecSpecies.t) (rhs:GecSpecies.t) (rate:value) (sim:bool) = + let reactants = GecSpecies.species_to_gecAbstractComplex lhs.species + let products = GecSpecies.species_to_gecAbstractComplex rhs.species + let compartment = get_compartment lhs rhs + let dir = get_direction lhs + Ast.Trans(reactants,products,compartment,rate,sim,dir) + match dir with + | Forward -> match r2 with None -> () | _ -> failwith "Extra rate found in Forward reaction" + | Reversible -> () + + match dir with + | Forward -> + let rate = match r1 with | Some(r) -> r | None -> Ast.WildCardVal + create_forward_transport_reaction lhs rhs rate sim + | Reversible -> + let frate = match r1 with | Some(r) -> r | None -> Ast.WildCardVal + let rrate = match r2 with | Some(r) -> r | None -> Ast.WildCardVal + let forreac = create_forward_transport_reaction lhs rhs frate sim + let revreac = create_forward_transport_reaction rhs lhs rrate sim + Ast.Par(forreac,revreac) + +let create_normal_reaction (enzymes:string list list) (reactants:string list list) (products:string list list) (dir:reactionDirection) ((r1,r2):value option*value option) (sim:bool) = + let reactant_to_ast_val (slist:string list list) = + slist |> List.map (fun x -> GecSpecies.species_to_gecAbstractComplex x) + + let create_forward_reaction (enzymes:abstractComplex list) (reactants:abstractComplex list) (products:abstractComplex list) (rate_option:value option) (sim:bool) = + let rate = + match rate_option with + | Some (x) -> x + | None -> Ast.WildCardVal + Ast.Reac(enzymes,reactants,products,rate,sim) + + match dir with + | Forward -> + match r2 with | None -> () | Some(_) -> failwith "Forward reaction can't have two rates." + create_forward_reaction (reactant_to_ast_val enzymes) (reactant_to_ast_val reactants) (reactant_to_ast_val products) r1 sim + | Reversible -> + match enzymes with | [] -> () | _ -> failwith "Reversible reactions should not have any enzymes." + + let freac = create_forward_reaction [] (reactant_to_ast_val reactants) (reactant_to_ast_val products) r1 sim + let rreac = create_forward_reaction [] (reactant_to_ast_val products) (reactant_to_ast_val reactants) r2 sim + Ast.Par(freac,rreac) + +let parse_reaction = + let compartment_checker (splist:GecSpecies.t list) = + splist |> List.iter (fun sp -> + match sp.compartment with + | Some (comp) -> failwith "Improper format for Transport Reaction" + | None -> ()) + parse_reaction_species >>= fun(species) -> + match species with + | [reactant] -> + match reactant.compartment with + | Some(comp) -> + //Start Transport Reaction + parse_simulation_option + .>>. parse_reaction_direction + .>>. (parse_reaction_rates) + .>>. GecSpecies.parse_species + |>> fun (((simulationonly,reactiondir),rates),products) -> create_transport_reaction reactant {GecSpecies.t.empty_Species with species = products} reactiondir rates simulationonly + | None -> + parse_enzyme_option + .>>. parse_reactants + .>>. parse_simulation_option + .>>. parse_reaction_direction + .>>. (parse_reaction_rates) + .>>. parse_reaction_species + |>> fun (((((enzyme_option,reactants),simulationonly),reactiondir),rates),product_species)-> + match enzyme_option with + | Some(_) -> + let enzymes = + match species with + | [] -> [] + | _ -> species |> List.map (fun x -> x.species) + compartment_checker product_species + let products = product_species |> List.map (fun x -> x.species) + create_normal_reaction enzymes reactants products reactiondir rates simulationonly + | None -> + match product_species with + | [product] -> + match product.compartment with + | Some(comp) -> + create_transport_reaction reactant product reactiondir rates simulationonly + | None -> + let r = + match species with + | [] -> [] + | _ -> species |> List.map (fun x -> x.species) + compartment_checker product_species + let products = product_species |> List.map (fun x -> x.species) + create_normal_reaction [] r products reactiondir rates simulationonly + | _ -> + let r = + match species with + | [] -> [] + | _ -> species |> List.map (fun x -> x.species) + compartment_checker product_species + let products = product_species |> List.map (fun x -> x.species) + create_normal_reaction [] r products reactiondir rates simulationonly + + | _ -> + compartment_checker species //Checks to see if there are any compartments in normal reactions. + parse_enzyme_option + .>>. parse_reactants + .>>. parse_simulation_option + .>>. parse_reaction_direction + .>>. (parse_reaction_rates) + .>>. parse_reaction_species + |>> fun (((((enzyme_option,reactants),simulationonly),reactiondir),rates),product_species)-> + compartment_checker product_species + let enzymes = + match species with + | [] -> [] + | _ -> species |> List.map (fun x -> x.species) + let products = product_species |> List.map (fun x -> x.species) + match enzyme_option with + | Some(_) -> create_normal_reaction enzymes reactants products reactiondir rates simulationonly + | None -> + let r = + match species with + | [] -> [] + | _ -> species |> List.map (fun x -> x.species) + create_normal_reaction [] r products reactiondir rates simulationonly + + + +let reactionOrConstraint = + Parser.choice[ + Parser.kw "~" |>> fun _ -> Reaction + Parser.kw "*" >>. Parser.choice[ + Parser.kw "-" |>> fun _ -> Reaction + Parser.kw "<" |>> fun _ -> Reaction + Parser.preturn Constraint + ] + Parser.pstring "-" >>. Parser.choice[ + Parser.pstring ">" |>> fun _ -> Reaction + Parser.preturn Constraint + ] + Parser.pstring "<" >>. Parser.choice[ + Parser.pstring "-" |>> fun _ -> Reaction + Parser.preturn Constraint + ] + Parser.pstring ">" |>> fun _ -> Constraint + ] + +let pInnerParallelContent = + Parser.plookAheadWith( + Parser.choice[ + Parser.pTry(Parser.pfloat |>> fun _ -> true) + Parser.preturn(false) + ]) + >>= + fun(startsWithFloat) -> + if startsWithFloat then + //Parser an expression and this should be a constraint, right? + parse_ast_constraints + else + //This is where the real plookahead fun begins... + Parser.plookAheadWith( + Parser.choice[ + Parser.pTry(parse_sequence |>> fun _ -> Seq) + GecSpecies.parse |>> fun _ -> GecSpecies + ] + ) + >>= + fun (progType) -> + match progType with + | Seq -> parse_ast_sequence + | GecSpecies -> + Parser.plookAheadWith( + Parser.choice[ + Parser.sepBy GecSpecies.parse (Parser.kw "+") + >>= fun(pseq) -> + match pseq.Length with + | 1 -> Parser.choice[ + Parser.kw "(" |>> fun _ -> ModuleInvocation + reactionOrConstraint + ] + | _ -> reactionOrConstraint + ] + ) + >>= fun (progType2) -> + match progType2 with + | Constraint -> parse_ast_constraints + | ModuleInvocation -> parse_ast_template_inv + | Reaction -> parse_reaction + | _ -> failParser "At this stage, only Constraint, ModuleInvocation, and Reactions were expected" + | _ -> failParser "At this stage, only Seq or GecSpecies was expected as the Next Parser" + + +let fold_parallel (proglist: Ast.prog list) = + match (List.rev proglist) with + | [] -> Ast.Nil + | [prog] -> prog + | first::second::remaining -> + let parfst = Ast.Par(second,first) + if remaining.IsEmpty then + parfst + else + List.foldBack (fun x y -> Ast.Par(x,y)) (List.rev remaining) parfst + +let parse_parallel_inner = Parser.sepBy (Parser.choice [ + parse_initpop + pInnerParallelContent + ]) PARALLEL + |>> fold_parallel + +let parse_new = NEW >>. parse_species_id .>> Parser.kw "." + +let rec parse_new_inner st = + Parser.choice[ + parse_new .>>. parse_new_inner |>> fun(newstr,prog) -> Ast.New(newstr,prog) + parse_parallel_inner + ] st + + +let parse_compartment = Parser.plookAheadWith(Parser.choice[ + Parser.pTry(parse_id .>> Parser.kw "[" .>> GecSpecies.parse_species .>> Parser.kw "]" |>> fun _ -> Reaction) + Parser.pTry(parse_id .>> Parser.kw "[" |>> fun _ -> Compartment) + ]) + >>= fun(progType) -> + match progType with + | Reaction -> parse_reaction + | Compartment -> parse_id .>>. Parser.sqBrackets parse_new_inner |>> fun(compName,prog) -> Ast.Comp(compName,prog) + | _ -> failwith "At this point, the program type should only either be a Reaction or a Compartment." + +let parse_parallel_outer = Parser.sepBy (Parser.choice [ + parse_initpop + parse_compartment + pInnerParallelContent + ]) PARALLEL + |>> fold_parallel + +let rec parse_new_outer st = + Parser.choice[ + parse_new .>>. parse_new_outer |>> fun(newstr,prog) -> Ast.New(newstr,prog) + parse_parallel_outer + ] st + +let rec parse_system_template st = + Parser.choice[ + TEMPLATE >>. parse_template_args + .>>. (Parser.braces parse_new_outer) .>> Parser.kw ";" + .>>. parse_system_template |>> + fun (((temName,temArgs),progBody),progout) -> + let args = temArgs |> List.map(fun x -> match x with | IdVal(y) -> y | _ -> failwith "unexpected format for template arguments") + Ast.TemplateDef(temName,args,progBody,progout) + parse_new_outer + ] st + + +let parse_template = + let rec parse_system_template st = + Parser.choice[ + TEMPLATE >>. parse_template_args + .>>. (Parser.braces parse_new_outer) .>> Parser.kw ";" + .>>. parse_system_template |>> + fun (((temName,temArgs),progBody),progout) -> + let args = temArgs |> List.map(fun x -> match x with | IdVal(y) -> y | _ -> failwith "unexpected format for template arguments") + Ast.TemplateDef(temName,args,progBody,progout) + Parser.preturn Ast.Nil + ] st + parse_system_template .>>. parse_new_outer + + + +let parse_arguments = Parser.paren (Parser.sepBy parse_id COMMA) +let parse_val_arguments = Parser.paren (Parser.sepBy parse_value COMMA) +let parse_moduleDefinition = parse_id .>> Parser.spaces .>>. parse_arguments +let parse_moduleInvocation = parse_id .>> Parser.spaces .>>. parse_val_arguments + +let parse_device = Parser.kw "device" >>. parse_moduleDefinition .>> Parser.kw "=" + .>>. Parser.braces (Parser.sepBy parse_moduleInvocation PIPE) + +let parse_instructions pspecies settings = + let zero = Expression.zero + let unitVal = Expression.one + + let pvalue = Expression.parse parse_id + let pexpr = Expression.parse (Key.parse pspecies) + let pcomma = Parser.kw "," + + // crn parsers + let pinitial = Microsoft.Research.CRNEngine.Initial.parse pspecies pvalue zero |>> Instruction.Initial2 + let preaction = Reaction.parse pspecies pvalue pexpr unitVal |>> Instruction.Reaction + let pinvoke = Parser.pTry( parse_id .>> Parser.kw "(") + .>>. Parser.sepBy pvalue pcomma + .>> Parser.kw ")" + |>> Module + let pline = pinvoke <|> preaction <|> pinitial + let pbar = Parser.kw "|" + + // module definitions parser + let pmodule = + Parser.kw "module" + >>. Parser.name .>>. Parser.paren (Parser.sepBy Parser.name pcomma) // module_name(comma-separated args) + .>> Parser.kw "=" + .>>. Parser.braces (Parser.opt pbar >>. Parser.sepBy pline pbar) + + // full CRN parser + Parser.spaces + >>. Parser.many pmodule + //.>> Parser.opt pbar + //.>>. Parser.sepBy pline pbar + +let parse_crnModules crnSettings = + parse_instructions GecSpecies.parse_gec_to_crn_species crnSettings + + +let pfixed = Parser.kw "Fixed" |>> fun _ -> Fixed +let pnormal = Parser.kw "Normal" |>> fun _ -> Normal +let ptruncatedNormal = Parser.kw "TruncatedNormal" |>> fun _ -> TruncatedNormal + +let parse_priorType = pfixed <|> pnormal <|> ptruncatedNormal + +let parse_priorOption:Parser.t = + Parser.plookAheadWith ( + Parser.choice[ + Parser.pTry (Parser.kw "=" >>. parse_priorType >>= fun _ -> Parser.preturn true) + Parser.preturn false + ]) + >>= fun hasPriorType -> + if hasPriorType + then Parser.kw "=" >>. parse_priorType |>> fun (x:igPriorType) -> HasPrior(x) + else Parser.preturn(NoPrior) + + +let parse_prior:t = Parser.name .>> Parser.spaces .>>. parse_priorOption + + +let parse_igInferenceSettings = Parser.kw ";" >>. Parser.kw "inference" >>. Parser.kw "=" >>. (Inference_settings.parse) + +let parse_igName = Parser.sepBy (Parser.name .>> Parser.spaces) DOT + +let parse_edge = Parser.kw "edge" >>. parse_igName .>> Parser.kw "->" + .>>. Parser.list_of parse_prior .>>. parse_igName |>> fun ((x,y),z) -> Edge(x,y,z) + +let parse_node = + Parser.kw "node" >>. (Parser.name .>> Parser.spaces) + .>> Parser.kw "{" .>>. (Parser.kw "systems" >>. Parser.kw "=" + >>. Parser.list_of (Parser.name .>> Parser.spaces)) >>= fun (x,y) -> + Parser.plookAheadWith( + Parser.choice[ + Parser.pTry(Parser.kw ";" >>. Parser.kw "inference" >>= fun _ -> Parser.preturn true) + Parser.preturn false + ]) + >>= fun hasInference -> + if hasInference + then + parse_igInferenceSettings .>> Parser.kw "}" |>> fun (z) -> Node(x,y,Some(z)) + else + Parser.kw "}" |>> fun _ -> Node(x,y,None) + + + +let parse_igraphElement = parse_edge <|> parse_node + +let parse_withSystem = + Parser.plookAheadWith ( + Parser.choice [ + Parser.pTry(Parser.name .>> Parser.spaces .>> Parser.kw "with" >>= fun _ -> Parser.preturn true) + Parser.preturn false + ]) + >>= fun hasWith -> + if hasWith + then Parser.name .>> Parser.spaces .>> Parser.kw "with" |>> fun x -> System(x) + else Parser.preturn(NoSystem) + +let rename_settings_species (settings:Settings.Gec_settings) = + let rename_species (sp:Species) = + let spName = sp.name + if spName.Contains("[") && spName.Contains("]") then + let spNameParser = Parser.name .>>. Parser.sqBrackets Parser.name |>> fun(x,y) -> (x + "_" + y) + let newName (str:string) = Parser.from_string spNameParser str + Species.create(newName spName) + else + sp + let crn = Crn_settings.defaults.from_default_directive_list settings.directives + let renamed_crn_settings = crn.map (Expression.map (Key.map (fun sp -> rename_species sp))) + renamed_crn_settings + + +let parse_program (crnsettings:Crn_settings)= + Settings.parse_defaults crnsettings >>= fun(top_settings) -> + let top_crn_settings = crnsettings.from_default_directive_list top_settings.directives + parse_crnModules top_crn_settings + .>>. (Parser.many parse_device) + .>>. parse_system_template + |>> fun((crn_modules,device_definitions),gecprog) -> + (top_settings,crn_modules,device_definitions,gecprog) + + +let parse_system (settings:Crn_settings) = + SYSTEM >>. parse_id .>> (Parser.kw "=") .>>. Parser.braces (parse_withSystem .>>. parse_program settings) + |>> fun(systemName,(sysRef,(settings,modules,devices,prog))) -> + {name=systemName; + withSystem=sysRef; + settings=settings; + modules = modules; + devices = devices; + prog = prog} + +let parseClassic (top_settings:Settings.Gec_settings) = + let top_crn_settings = Crn_settings.defaults.from_default_directive_list top_settings.directives + parse_crnModules top_crn_settings + .>>. (Parser.many parse_device) + .>>. parse_template + .>>. (Parser.many (parse_system top_crn_settings)) + .>>. (Parser.many parse_igraphElement) + |>> fun((((modules,devices),(templates,topProg)),systems),igraph) -> + {settings=top_settings; + modules = modules; + devices = devices; + systems = systems; + templates = templates; + prog = topProg; + graph = igraph} + +let getMapInstruction m (i:LogicGEC.Instruction) = + let getMapComplex sp m = + sp |> List.fold (fun acc (_, x) -> getMapTerm acc x) m + match i with + | LogicGEC.Constraint c -> LogicGEC.getMapLit m c + | LogicGEC.Device d -> d |> List.fold (LogicGEC.getMapElement) m + | LogicGEC.Initial(c,sp) -> c + |> LogicGEC.getMapTerm m + |> getMapComplex sp + | LogicGEC.Reaction(a,b,c,d,e) -> + let cs = if a.IsSome then [a.Value; b; c] + else [b;c] + let rs = if e.IsSome then [e.Value; d] + else [d] + let m' = cs |> List.fold (fun acc x -> getMapComplex x acc) m + rs |> List.fold getMapTerm m' + +let parseLogic(settings:Settings.Gec_settings) = + let idProvider = RulesDSD.Syntax.makeProvider () // initialise an ID provider for logical variables, so that the same variable in different predicates/devices is given the same ID + Parser.opt (kw "|") + >>. Parser.sepBy1 (pInstruction idProvider) (kw "|") + >>= fun prog -> + + // find the parts declared in the database + let declaredParts = + match settings.rules with + | None -> failwith "Missing Logic GEC rules in instructions parsing." + | Some rules -> LogicGEC.getParts rules + let declaredNames = + declaredParts + |> List.choose (fun p -> match p.name with Term.Const n -> Some n | _ -> None) + |> Set.ofList + + // part name and types disambiguation step + let parts = + prog + |> List.collect (Instruction.Species) + |> List.fold (fun acc x -> match x with Element.Var _ -> acc | Element.Part p -> p::acc) [] + + let partNames, partTypes = + parts + |> List.fold (fun (acc1, acc2) p -> + let names = + match p.name with + | RulesDSD.Syntax.Term.Const x -> + if not (acc1 |> Set.contains x) && p.type_ <> Term.Const LogicGEC.noTypePart + then Set.add x acc1 + else acc1 + | _ -> acc1 + let types = + match p.type_ with + | RulesDSD.Syntax.Term.Const x -> + if not (acc2 |> Set.contains x) && p.type_ <> Term.Const LogicGEC.noTypePart + then Set.add x acc2 + else acc2 + | _ -> acc2 + names, types + ) (Set.empty, LogicGEC.PREDEFINED_PART_TYPE_NAMES |> Set.ofList) + let ambiguousNames = Set.intersect partNames partTypes + if not (ambiguousNames.IsEmpty) + then ambiguousNames |> Set.toList |> List.head |> failwithf "Ambiguous part declaration: \"%s\" is used as a part name and a part type at the same time." + else + // guess #1: turn undeclared parts back into strings + let prog1 = + let rec f (x:Term) : Term = + match x with + | Term.Pat (Pattern.Inner [y, _]) -> + match y with + | Element.Part {name = Term.Const n + type_ = _ } -> if declaredNames.Contains n || partNames.Contains n + then x + else Term.Const n + | _ -> x + | Term.Pat _ + | Term.Proc _ + | Term.Var _ + | Term.Const _ + | Term.Float _ -> x + | Term.TCRN ts -> Term.TCRN (ts |> List.map f) + | Term.Func (n, ts) -> Term.Func (n, ts |> List.map f) + | Term.TList ts -> Term.TList (ts |> List.map f) + | Term.TCons (t1, t2) -> Term.TCons (f t1, f t2) + | Term.TMSet s -> Term.TMSet (s |> List.map (fun (i, x) -> i, f x)) + prog + |> List.map (fun i -> + match i with + | LogicGEC.Device _ -> i + | LogicGEC.Constraint c -> LogicGEC.Constraint (c |> Literal.Map f) + | LogicGEC.Initial (n,c) -> LogicGEC.Initial (f n, c |> List.map (fun (x,y) -> x, f y)) + | LogicGEC.Reaction (a,b,c,d,e) -> LogicGEC.Reaction (a,b,c,f d, Option.map f e) + ) + + // guess #2: turn a part name into a part type (e.g. "ter" might be parsed as a part called ter and no type, when it's actually a terminator part type ) + let guessPartTypes e = + match e with + | Element.Part {name = Term.Const n; type_ = Term.Const t} -> + if t = noTypePart + then if Set.contains n partTypes + then Element.Part { name = Term.wildcard; type_ = Term.Const n} + else Element.Part { name = Term.Const n; type_ = Term.wildcard} + else e + | _ -> e + + let prog2 = prog1 |> List.map (Instruction.Map guessPartTypes) + + // guess #3: add part types to parts that were only written as part names (e.g. r0011 in "" ) + let declaredDict = declaredParts + |> List.map (fun p -> p.name, p) + |> fun decs -> // W# doesn't process "dict" + let x = new System.Collections.Generic.Dictionary, Part>() + for k,v in decs do + x.Add(k,v) + x + let prog3 = + prog2 + |> List.map (Instruction.Map (fun e -> + match e with + | Element.Var _ -> e + | Element.Part p -> if p.type_ = Term.wildcard && declaredDict.ContainsKey p.name + then Element.Part (declaredDict.Item p.name) + else e + )) + + // disambiguate variables in prog + + + preturn { settings = settings + ; rules = settings.rules.Value // TODO: refactor settings + ; program = prog3 } + +let parse : Parser.t = + Parser.spaces >>. + Settings.parse >>= fun(top_settings) -> + if top_settings.rules.IsNone + then parseClassic top_settings |>> ClassicGec + else parseLogic top_settings |>> LogicGec +/// TO STRING METHODS. + +let crnSettings_to_string (crnSettings:Crn_settings) = crnSettings.to_string Functional2.to_string Functional2.to_string_plot + + +let argsval_to_string (args: value list) = Lib.string_of_list (fun x -> Ast.stringOfValue x) "," (args) +let args_to_string (args: string list) = Lib.string_of_list (fun x -> x) "," (args) + + +let modules_to_string initial_time (modules:crnModules) = + let moduleList = modules + let instructionList_to_string (instructions:Instruction list) = + let instructionStringList = instructions |> List.map (fun x -> ("| " + (Instruction.to_string initial_time x))) + Lib.string_of_list (fun x -> x) "\n" instructionStringList + let module_to_string (((moduleName:string),(moduleArgs:string list)),(instructions:Instruction list)) = + let str = "module " + moduleName + "(" + (args_to_string moduleArgs) + ") = {\n" + + (instructionList_to_string instructions) + "\n}\n" + str + let str = + let moduleListString = moduleList |> List.map (fun x -> (module_to_string x)) + let moduleStr = Lib.string_of_list (fun x -> x) "" moduleListString + moduleStr //+ (instructionList_to_string externalInstructions) + + match modules with + | [] -> "" + | _ -> str + +let crn_contents_to_string (initial_time) (crnExtended:Crn option * crnInstructions) = + + let (crnOpt,crnInstructions) = crnExtended + let (modules,instructions) = crnInstructions + let instructions_tp_string instructions = Lib.string_of_list (fun x -> ("|" + Instruction.to_string initial_time x)) "\n" instructions + let module_to_string (m) = + let ((mname,margs),instructions) = m + mname + "(" + (Lib.string_of_list (fun x -> x) "," margs) + ") = {\n" + + instructions_tp_string instructions + + "}\n" + + let modules_to_string (modules:crnModules) = Lib.string_of_list (fun m -> module_to_string m) "\n" modules + + let inst_string = (modules_to_string modules) + (instructions_tp_string instructions) + + match crnOpt with + | Some(crn) -> + let initials = crn.initials + let reactions = crn.reactions + let not_initial i = Expression.simplify i <> Expression.Float initial_time + let initial_to_string = Initial.to_string Species.to_string (Expression.to_string id) not_initial + let reaction_to_string = Reaction.to_string Species.to_string (Expression.to_string id) Functional2.to_string + let initStr = Lib.string_of_list (fun x -> ("| " + (initial_to_string x))) "\n" initials + let reacStr = Lib.string_of_list (fun x -> ("| " + (reaction_to_string x))) "\n" reactions + inst_string + initStr + reacStr + | None -> inst_string + +let moduleDefinition_to_string (moduleDef:moduleDefinition) = + let (moduleName,moduleArgs) = moduleDef + moduleName + "(" + (args_to_string moduleArgs) + ")" + +let moduleInvocation_to_string (moduleInv:moduleInvocation) = + let (moduleName,moduleArgs) = moduleInv + moduleName + "(" + (argsval_to_string moduleArgs) + ")" + +let deviceDefinition_to_string (device:deviceDefinition) = + let ((deviceDef),deviceBody) = device + let deviceBodyString = "{" + (Lib.string_of_list (fun x -> x) " | " (deviceBody |> List.map (fun x -> moduleInvocation_to_string x))) + "}" + let str = "module " + (moduleDefinition_to_string deviceDef) + " = " + deviceBodyString + str + +let system_to_string (crn) (modules) (deviceDefs) (system:system) (db:Database.t)= + let moduleDefinitions = modules |> List.map fst + let deviceDefinitions = deviceDefs |> List.map fst + + let device_list = + let rec get_devices (prog:Ast.prog) = + match prog with + | Ast.Device(d) -> [d] + | Ast.Seq(s1,s2) -> (get_devices s1)@(get_devices s2) + | Ast.Par(p1,p2) -> (get_devices p1)@(get_devices p2) + | Ast.Comp(c,p) -> get_devices p + | Ast.New(n,p) -> get_devices p + | Ast.TemplateDef(_,_,p1,p2) -> (get_devices p2) + | Ast.Copy(_,p,_,_) -> get_devices p + | _ -> [] + get_devices system.prog + + let hypothesisSettings_to_string (deviceList:string list) (devices:Database.device list) (deviceDefs:moduleDefinition list) (moduleDefs:moduleDefinition list) = + let rec device_unroll (dev:string) (devices:Database.device list) (deviceDefs:moduleDefinition list) (moduleDefs:moduleDefinition list) = + let deviceDefOpt = deviceDefs |> List.tryFind (fun (x,y) -> x=dev) + match deviceDefOpt with + | Some(a) -> [a] + | None -> + let modOpt = (moduleDefs |> List.tryFind (fun (x,y) -> x=dev)) + match modOpt with + | Some(a) -> [a] + | None -> + let devOpt = (devices |> List.tryFind (fun (x,y) -> x=dev )) + match devOpt with + | Some (devName,devComps) -> + let deflist = devComps |> List.map (fun x -> device_unroll x devices deviceDefs moduleDefs) + match deflist.Length with + | 0 -> [] + | _ -> deflist |> List.reduce (fun x y -> x@y) + | None -> + raise (System.ArgumentException("Device in System Directive must be defined.")) + let mdeflistlist = deviceList |> List.map (fun x -> device_unroll x devices deviceDefs moduleDefs) + let mdeflist = + match mdeflistlist.Length with + | 0 -> [] + | _ -> mdeflistlist |> List.reduce (fun x y -> x@y) + let l = (mdeflist |> List.map (fun x -> "| " + (moduleDefinition_to_string x))) + match l with + | [] -> "" + | _ -> Lib.string_of_list (fun x -> x) "\n" l + + let system_to_string (devices:Database.device list) (deviceDefs:moduleDefinition list) (moduleDefs:moduleDefinition list)= + let sysRef_to_string (sysRef:systemReference) = + match sysRef with + | System(x) -> x + " with " + | NoSystem -> "" + let nl_str (str:string) = + match (str.Trim()) with + | "" -> "" + | _ -> str + "\n" + let str = + "system " + system.name + " = { " + (sysRef_to_string system.withSystem) + "\n" + + let crnSettings = Crn_settings.defaults.from_default_directive_list system.settings.directives + nl_str (crnSettings_to_string crnSettings) + + nl_str (modules_to_string crnSettings.simulation.initial system.modules) + + nl_str (crn_contents_to_string crnSettings.simulation.initial crn) + //Crn to String (Only initials and reactions) + hypothesisSettings_to_string (device_list) devices deviceDefs moduleDefs + "\n}\n" + + str + + system_to_string db.devices deviceDefinitions moduleDefinitions + +let igNode_to_string (node:ignode) = + let (nodeName,nodeSystems,iSettings) = node + let str = "node " + nodeName + " { systems = [" + (Lib.string_of_list (fun x -> x) "; " nodeSystems) + "]" + match iSettings with + | Some(x) -> str + "; " + "inference " + "= " + (Inference_settings.to_string(x)) + "}" + | None -> str + "}" + + + +let igEdge_to_string (edge:igedge) = + let edgeNameString edgelist = Lib.string_of_list (fun x -> x) "." edgelist + let priorType_to_string (ptype:igPriorType) = + match ptype with + | Fixed -> "Fixed" + | Normal -> "Truncated" + | TruncatedNormal -> "TruncatedNormal" + let prior_to_string ((p,ptype):igPrior) = + match ptype with + | HasPrior(x) -> p + "=" + (priorType_to_string x) + | NoPrior -> p + let (fromNode,priorlist,toNode) = edge + let str = "edge " + (edgeNameString fromNode) + " -> " + "["+ + (Lib.string_of_list (fun x -> x) "; " (priorlist |> List.map (fun x-> prior_to_string x)) ) + + "] " + (edgeNameString toNode) + str + +let igElement_to_string (elem:igraphElement) = + match elem with + | Node(x) -> igNode_to_string x + | Edge(x) -> igEdge_to_string x + + \ No newline at end of file diff --git a/ClassicGEC/ClassicGECDotNet/settings.fs b/ClassicGEC/ClassicGECDotNet/settings.fs new file mode 100644 index 0000000..fa13bce --- /dev/null +++ b/ClassicGEC/ClassicGECDotNet/settings.fs @@ -0,0 +1,145 @@ +[] +module Microsoft.Research.GEC.Settings +open Microsoft.Research.CRNEngine +open Microsoft.Research.GEC.Ast +open Parser +//open FsCheck + +type crnModuleDefinition = (string * string list) +type crnInstructions = ((crnModuleDefinition * Instruction list) list) * Instruction list + + +let pSpecies = GecSpecies.parse_crn_species + +type Directive = + | Crn of crnInstructions + | Override of crnInstructions + | RmrnaDeg of float + | Rules of LogicGEC.Semantics + static member parse_defaults (settings:Crn_settings<'e>) = + //let parse_species = pSpecies - Clashes with key words... + let parse_species = (GecSpecies.parse_kw Microsoft.Research.CRNEngine.Keywords.kwList) |>> fun x -> x.to_string() |> Species.create + let CRN = Parser.kw "crn" + let OVERRIDE = Parser.kw "override" + let RMRNADEG = Parser.kw "RMRNADeg" + let RULES = Parser.kw "rules" + let parse_crn = CRN + Parser.choice[ + CRN >>. Parser.braces (Instruction.parse parse_species settings) |>> fun x -> Crn x + OVERRIDE >>. Parser.braces (Instruction.parse parse_species settings) |>> fun x -> Override x + RMRNADEG >>. Parser.pfloat .>> Parser.spaces |>> fun x -> RmrnaDeg x + RULES >>. Parser.braces (LogicGEC.pGecProgram) |>> Rules + ] + static member parse = + Directive.parse_defaults Crn_settings.defaults + +type Gec_settings = {directives:Directive list; crn:crnInstructions; overrideCrn:bool; rmrnadeg:float; rules:LogicGEC.Semantics option} +with + static member default_settings = {directives=[]; crn=([],[]); overrideCrn=false;rmrnadeg=0.001;rules=None} + member default_settings.from_directive (gecDirective:Directive)= + match gecDirective with + | Crn (x) -> {default_settings with crn = x; overrideCrn = false} + | Override(x) -> {default_settings with crn = x; overrideCrn = true} + | RmrnaDeg(x) -> {default_settings with rmrnadeg = x} + | Rules x -> {default_settings with rules = Some x} + member default_settings.from_directive_list (ds:Directive list) = + ds |> List.fold (fun (acc:Gec_settings) s -> (acc.from_directive s)) default_settings + + +let parse_species:Parser.t = Expression.parse (Key.parse pSpecies) + ///Special case: a single name x is interpreted as a species instead of a parameter + ///e.g. "plots = [x]" +let parse__species_plot:Parser.t = + let species_from_string = Parser.from_string pSpecies + Expression.parse (Key.parse pSpecies) + |>> fun exp -> + match exp with + | Expression.Key (Key.Parameter s) -> Expression.Key (Key.Species (species_from_string s)) + | _ -> exp + +type directiveType = + | CRNDir of Microsoft.Research.CRNEngine.Directive + | GECDir of Directive + +let parseCrnDir = Directive.parse parse_species parse__species_plot |>> CRNDir + +let parseGecDir_defaults (settings:Crn_settings) = Directive.parse_defaults settings |>> GECDir +let parseGecDir = parseGecDir_defaults Crn_settings.defaults + +let parse_defaults (default_crn_settings:Crn_settings) = + Parser.many (Parser.kw "directive" >>. ( (parseGecDir_defaults default_crn_settings) <|> parseCrnDir)) + |>> fun(dirlist) -> + let crnlist = dirlist |> List.choose(fun elem -> + match elem with + | CRNDir(x) -> Some(x) + | _ -> None) + let geclist = dirlist |> List.choose(fun elem -> + match elem with + | GECDir(x) -> Some(x) + | _ -> None) + //let crnSettings = default_crn_settings.from_default_directive_list crnlist + let settings = { Gec_settings.default_settings with directives = crnlist} + settings.from_directive_list geclist + + +let parse = parse_defaults Crn_settings.defaults + + +let convertExprToAst (exp:Functional) = + + + let gecExp = Parser.from_string (GecSpecies.parse) + let f s = gecExp (Species.to_string s) |> fun x -> x.to_ast_gecSpecies() + Expression.map (Key.map f) exp + (*match exp with + | Expression (Key.Species s) -> + let gecExp = Parser.from_string (GecSpecies.parse) + let gecSpecies = gecExp (Species.to_string s) |> fun x -> x.to_ast_gecSpecies() + Expression.Key(gecSpecies) + + | _ -> failwith "Unexpected expression encountered in directive functional"*) + + + +let convertCRNdirToGECdir (directive:Directive) = + match directive with + | Simulation x -> + let plotSpecies = x.plots |> List.map convertExprToAst + let plots = Ast.PLOT(plotSpecies) + let kinetics = + match x.kinetics with + | Kinetics.Contextual -> Ast.KINETICS(Ast.Contextual_kinetics) + | Kinetics.Stochastic -> Ast.KINETICS(Ast.Stochastic_kinetics) + | Kinetics.Deterministic -> Ast.KINETICS(Ast.Deterministic_kinetics) + [Ast.SAMPLE(x.final,Ast.IntPoints(x.points));kinetics;plots] + | Units x -> [Ast.TIME(x.time);Ast.CONCENTRATION(x.concentration)] + | Microsoft.Research.CRNEngine.Directive.Deterministic x -> [Ast.ABSTOLERANCE(x.abstolerance);Ast.RELTOLERANCE(x.reltolerance)] + | Microsoft.Research.CRNEngine.Directive.Stochastic x -> [Ast.SCALE(x.scale)] + | _ -> [] + (*| Samples(startVal,endVal,inc) -> + if(inc.IsSome) then + if(inc.Value = 0) then + Ast.SAMPLE(endVal.Value,Ast.AllPoints) + else + Ast.SAMPLE(endVal.Value,Ast.IntPoints(inc.Value)) + else + Ast.SAMPLE(endVal.Value,Ast.Default) + | OldTime(sec) -> Ast.TIME(sec) + | Concentration(conc) -> Ast.CONCENTRATION(conc) + | Tolerance(value) -> Ast.ABSTOLERANCE(value) + | RelTolerance(value) -> Ast.RELTOLERANCE(value) + | Scale(value) -> Ast.SCALE(value) + | Kinectics(mode) -> + match mode with + | KContextual -> Ast.KINETICS(Ast.Contextual_kinetics) + | KStochastic -> Ast.KINETICS(Ast.Stochastic_kinetics) + | KDeterministic -> Ast.KINETICS(Ast.Deterministic_kinetics) + | Plot(expList) -> + let gecExpList = expList |> List.map convertExprToAst + Ast.PLOT(gecExpList) + | _ -> failwith "Unknown Directive encountered"*) + + +let convert_crn_to_gec_directives (directives :Directive list) = + let list = directives |> List.map convertCRNdirToGECdir + list |> List.fold (fun acc x -> acc@x) [] \ No newline at end of file diff --git a/ClassicGEC/ClassicGECDotNet/solver.fs b/ClassicGEC/ClassicGECDotNet/solver.fs new file mode 100644 index 0000000..eb96b40 --- /dev/null +++ b/ClassicGEC/ClassicGECDotNet/solver.fs @@ -0,0 +1,288 @@ +[] +module Microsoft.Research.GEC.Solver + +open Microsoft.Research.GEC +//open Microsoft.Research.ModellingEngine +open Microsoft.Research.CRNEngine + +(* ************************************************************************************************************ *) + +(* Some helper functions. *) + +(* NB: copied from trans.fs... NB: altered to handle complexes! *) +//let getComplexNamesFromStrings (prop:string * (string list list)) : string list = match prop with +// | (pname, x::xs) when pname = "pos" || pname = "neg" || pname = "pcr" || pname = "codes" -> [Ast.complexString x] +// | _ -> [] + +(* Get the COMPLEXES which exist in a list of part properties. *) +let getComplexesFromStrings (prop:string * (string list list)) : string list list = + match prop with + | (pname, x::xs) when pname = "pos" || pname = "neg" || pname = "pcr" || pname = "codes" -> [x] + | _ -> [] + +(* Compare a string and a partType to see if they match... *) +let typesAgree (t:string) (partTy:Database.partType) = + match t,partTy with + | "pcr", Database.PCR _ | "prom", Database.PROM _ | "rbs", Database.RBS _ | "ter", Database.TER _ -> true + | _,_ -> false + +(* Find all substitutions that can unify two complexes, in any order... *) +let unifyComplexes ((*variables*)xs:string list) ((*species*)zs:string list) : Subst.t list = + let zs = List.map (fun z -> Subst.SPECIES [z]) zs in + if not(List.length xs = List.length zs) then [] else + let assocLsts = List.map (fun perm -> List.zip xs perm) (Lib.permutations zs) in + Lib.maybemap Subst.multiple assocLsts + +(* Unify two (possibly empty) lists of complexes. *) +let unifyComplexLists ((*variables*)xss:string list list) ((*species*)zss:string list list) : Subst.t list = + match xss,zss with + | [],[] -> [Subst.empty] + | _::_,_::_ -> + if not(List.length xss = List.length zss) then [] else + let rec loop (thetas:Subst.t list) ((*variables*)qss:string list list) ((*species*)wss:string list list) = + match qss,wss with + | [],[] -> thetas + | (qs::qss, ws::wss) -> + let thetas' = Lib.collect (fun theta -> let qs' = Subst.applyToComplex theta qs in + let ws' = Subst.applyToComplex theta ws in + let thetas' = unifyComplexes qs' ws' in + let thetas' = Lib.maybemap (Subst.union theta) thetas' in + let str = + "Trying to unify " + (Ast.complexString qs) + " with " + (Ast.complexString ws) + + " when theta = " + (Subst.display theta) + " *** "+ + " got thetas' = " + (Lib.string_of_list Subst.display " ~~ " thetas') + in + thetas') thetas + in + //let newLog = [] in + loop thetas' qss wss + | _,_ -> failwith "unifyComplexLists: outer lists must be the same length" + in + Lib.collect (fun zss -> loop [Subst.empty] xss zss) (Lib.permutations zss) + | _,_ -> [] + +(* ************************************************************************************************************ *) + +(* Scan the database for matching parts. *) + +(* Try to find substitutions which make a string-based promoter property match a ground one from the database. *) +let tryFindPromoterSubsts (theta_original:Subst.t) (bp:string * (string list list)) (pp:Database.promProperty) : Subst.t list = + let bp = Subst.applyToPartTypeStrings theta_original bp in + let unifyPP (xs,q1,q2,q3) (zs,r1,r2,r3) = + match Subst.multiple [(q1,Subst.NUMBER r1);(q2,Subst.NUMBER r2);(q3,Subst.NUMBER r3)] with + | None -> [] + | Some theta' -> + match Subst.union theta_original theta' with + | None -> [] + | Some theta''' -> Lib.maybemap (fun theta'' -> Subst.union theta'' theta''') (unifyComplexes xs zs) + in + match bp, pp with + | ("frate", [[q]]), Database.FRATE(a) -> + begin match (Subst.unify q (Subst.ALGEBRAIC_EXPRESSION a)) with + | None -> [] + | Some theta -> + begin match Subst.union theta_original theta with + | None -> [] + | Some theta' -> [theta'] + end + end + | ("pos", [xs;[q1];[q2];[q3]]), Database.POS(zs,r1,r2,r3) // + | ("neg", [xs;[q1];[q2];[q3]]), Database.NEG(zs,r1,r2,r3) -> unifyPP (xs,q1,q2,q3) (zs,r1,r2,r3) + | ("con", [[q]]), Database.CON(r) -> + begin match (Subst.unify q (Subst.NUMBER r)) with + | None -> [] + | Some theta -> + begin match Subst.union theta_original theta with + | None -> [] + | Some theta' -> [theta'] + end + end + | _,_ -> [] + +(* Try to find substitutions which make a string-based PCR property match a ground one from the database. *) +let tryFindPCRSubsts (theta_original:Subst.t) (bp:string * (string list list)) (pp:Database.pcrProperty) : Subst.t list = + let bp = Subst.applyToPartTypeStrings theta_original bp in + match bp, pp with + | ("codes", [xs;[q]]), Database.CODES(zs,r) -> + begin match (Subst.unify q (Subst.NUMBER r)) with + | None -> [] + | Some theta -> + begin match Subst.union theta_original theta with + | None -> [] + | Some theta' -> Lib.maybemap (fun theta'' -> Subst.union theta'' theta') (unifyComplexes xs zs) + end + end + | _,_ -> [] + +(* Try to find substitutions which make a string-based RBS property match a ground one from the database. *) +let tryFindRBSSubsts (theta_original:Subst.t) (bp:string * (string list list)) (rp:Database.rbsProperty) : Subst.t list = + let bp = Subst.applyToPartTypeStrings theta_original bp in + match bp, rp with + | ("rate", [[q]]), Database.RATE(r) -> + begin match (Subst.unify q (Subst.NUMBER r)) with + | None -> [] + | Some theta -> + begin match Subst.union theta_original theta with + | None -> [] + | Some theta' -> [theta'] + end + end + | _,_ -> [] + +(* Try to find substitutions which make a string-based RBS property match a ground one from the database. + NB: this always returns an empty list because terminators don't have properties associated with them + (at least the one in the default database doesn't...) *) +let tryFindTerSubsts (theta_original:Subst.t) (bp:string * (string list list)) : Subst.t list = [] + +(* Compute a set of context-sensitive substitutions for a brick, relative to a database. *) +let matchParts (db:Database.t) (brick:string) (t:string) (props:(string * (string list list)) list) : Cssubst.t list * string list = + + (* Recursive function for searching the parts database. *) + let find ((res,log):Cssubst.t list * string list) (partId:string) (entry:Database.partType Database.entry) : Cssubst.t list * string list = + let partTy = entry.value in + if not entry.enabled then (res,log) else + // NB: If we limited the input, could we make this simpler??? + // NB: Should we avoid converting everything to strings in trans.fs??? + // NB: Should we convert the "database" to use a string-based system so it's more flexible for the future? + let init = if not(typesAgree t partTy) then [] else + match (Subst.unify brick (Subst.PART partId)) with Some init -> [init] | None -> [] + in + let rec expand ((thetas,log):Subst.t list * string list) (bps:(string * (string list list)) list) : Subst.t list * string list = + match bps with + | [] -> (thetas,log) + | (bp::bps) -> + let rec substLoop (new_thetas:Subst.t list) (thetas:Subst.t list) = + match thetas with + | [] -> new_thetas + | (theta::thetas) -> + let extra_thetas = + begin match partTy with + | Database.PROM(props) -> Lib.collect (fun pp -> tryFindPromoterSubsts theta bp pp) props + | Database.PCR(prop) -> tryFindPCRSubsts theta bp prop + | Database.RBS(prop) -> tryFindRBSSubsts theta bp prop + | Database.TER -> tryFindTerSubsts theta bp (* NB: no property to put here as terminators don't have any... *) + end + in + substLoop (new_thetas@extra_thetas) thetas + in + let new_thetas = substLoop [] thetas in + let extra_log = ["Thetas are:\n" + (Lib.string_of_list Subst.display"\n" thetas); + "New_thetas are:\n" + (Lib.string_of_list Subst.display"\n" new_thetas)] in + let new_log = log@extra_log in + expand (new_thetas,new_log) bps + in + let initString = "Initial subst: " + (match init with [init] -> Subst.display init | _ -> "*NO MATCH*") in + let propsString = + let inner (zs:string list) = "[" + (Lib.string_of_list Lib.id ";" zs) + "]" in + "Properties: " + (Lib.string_of_list (fun (x,zss) -> x + "(" + (Lib.string_of_list inner "," zss) + ")") "; " props) + in + let thetas,expand_log = expand (init,[]) props in + // Eliminate any duplicate results from the list of substitutions + let thetas = Lib.remove_duplicates Subst.eq thetas in + let mkCSSubst (theta:Subst.t) : (Cssubst.t * string) option = + let rho = Subst.speciesDomain theta in + let ground_props = List.map (Subst.applyToPartTypeStrings theta) props in + let sigma = Lib.collect_union Ast.complexesEqual getComplexesFromStrings ground_props in + let tau = Lib.difference Ast.complexesEqual (Database.speciesInPartType partTy) sigma in + let cs = Cssubst.make theta rho sigma tau in + let log = "Producing a CSSubst: " + Lib.newline + + Cssubst.display cs + Lib.newline + + "...where FS(Q_i) = " + Lib.string_of_list Ast.complexString ", " (Database.speciesInPartType partTy) + Lib.newline + + "...where ground_props = " + Lib.string_of_list (fun (x,ps) -> x+"("+(Lib.string_of_list Ast.complexString ", " ps)+")") ", " ground_props in + if Cssubst.isOK cs then Some (cs,log) else None + in + let new_csSubstsLogs = Lib.maybemap mkCSSubst thetas in + let new_csSubsts, new_CsLogs = Lib.unzip new_csSubstsLogs in + let new_log = propsString::new_CsLogs in + ((res@new_csSubsts),(log@new_log)) + in + Stringmap.fold find ([],[]) db.parts + +(* Compute a set of context-sensitive substitutions for a normal reaction, relative to a database. *) +let matchNormalReactions (db:Database.t) (catalysts:string list list) (reactants:string list list) + (products:string list list) (rate:string) : Cssubst.t list * string list = + + (* Recursive function for searching the reactions database. *) + let find ((res,log):Cssubst.t list * string list) (entry:Gecreaction.t Database.entry) : Cssubst.t list * string list = + if not entry.enabled then (res,log) else + let reac = entry.value in + match Gecreaction.isNormal reac with + | None -> (res,log) + | Some(r_catalysts,r_reactants,r_products,r_rate) -> + let log = log@["Trying reaction " + Lib.quote (Gecreaction.display reac)] in + // All substitutions that unify the catalysts + let thetasE = unifyComplexLists catalysts r_catalysts in + let log = log@["thetasE = " + Lib.string_of_list Subst.display " ~~ " thetasE] in + // Each substitution in thetasE may be expanded to multiple substitutions that also unify the reactants + let thetasER = Lib.collect (fun theta -> let reactants = List.map (Subst.applyToComplex theta) reactants in + let thetas' = unifyComplexLists reactants r_reactants in + Lib.maybemap (Subst.union theta) thetas') thetasE + in + let log = log@["thetasER = " + Lib.string_of_list Subst.display " ~~ " thetasER] in + // Each substitution in thetasER may be expanded to multiple substitutions that also unify the products + let thetasERP = Lib.collect (fun theta -> let products = List.map (Subst.applyToComplex theta) products in + let thetas' = unifyComplexLists products r_products in + Lib.maybemap (Subst.union theta) thetas') thetasER + in + let log=log@["thetasERP = " + Lib.string_of_list Subst.display " ~~ " thetasERP] in + // Each substution in thetasERP may be extended to also unify the rates + let thetasERPr = Lib.maybemap (fun theta -> match Subst.unify rate (Subst.NUMBER r_rate) with + | None -> None + | Some theta' -> Subst.union theta theta') thetasERP + in + // Eliminate any duplicate results from the list of substitutions + let thetasERPr = Lib.remove_duplicates Subst.eq thetasERPr in + let log = log@["thetasERPr = " + Lib.string_of_list Subst.display " ~~ " thetasERPr] in + let mkCSSubst (theta:Subst.t) : Cssubst.t option = + let ground_reaction = Gecreaction.applySubst theta reac in + let rho = Subst.speciesDomain theta in + let sigma = Gecreaction.species ground_reaction in + let cs = Cssubst.make theta rho sigma [] in + if Cssubst.isOK cs then Some cs else None + in + let new_csSubsts = Lib.maybemap mkCSSubst thetasERPr in + ((res@new_csSubsts),log) + in + Lib.fold_left find ([],[]) db.reactions + +(* Compute a set of context-sensitive substitutions for a transport reaction, relative to a database. *) +let matchTransportReactions (db:Database.t) (reactant:string list) (product:string list) (rate:string) + (compartment:string) (direction:Ast.direction) : Cssubst.t list * string list = + + (* Recursive function for searching the reactions database. *) + let find ((res,log):Cssubst.t list * string list) (entry:Gecreaction.t Database.entry) : Cssubst.t list * string list = + if not entry.enabled then (res,log) else + let reac = entry.value in + match Gecreaction.isTransport reac with + | None -> (res,log) + | Some (r_reactant,r_product,r_rate,r_compartment,r_direction) -> + let log = log@["Trying reaction " + Lib.quote (Gecreaction.display reac)] in + if not(r_direction = direction) then (res,log@["...Directions don't match!"]) else + // All substitutions that unify the reactant + let thetasR = unifyComplexes reactant r_reactant in + let log = log@["thetasR = " + Lib.string_of_list Subst.display " ~~ " thetasR] in + // Each substitution in thetasR may be expanded to multiple substitutions that also unify the product + let thetasRP = Lib.collect (fun theta -> let product = Subst.applyToComplex theta product in + let thetas' = unifyComplexes product r_product in + Lib.maybemap (Subst.union theta) thetas') thetasR + in + let log = log@["thetasRP = " + Lib.string_of_list Subst.display " ~~ " thetasRP] in + // Each substution in thetasRP may be extended to also unify the rates + let thetasRPr = Lib.maybemap (fun theta -> match Subst.unify rate (Subst.NUMBER r_rate) with + | None -> None + | Some theta' -> Subst.union theta theta') thetasRP + in + // Eliminate any duplicate results from the list of substitutions + let thetasRPr = Lib.remove_duplicates Subst.eq thetasRPr in + let log = log@["thetasRPr = " + Lib.string_of_list Subst.display" ~~ " thetasRPr] in + let mkCSSubst (theta:Subst.t) : Cssubst.t option = + let ground_reaction = Gecreaction.applySubst theta reac in + let rho = Subst.speciesDomain theta in + let sigma = Gecreaction.species ground_reaction in + let cs = Cssubst.make theta rho sigma [] in + if Cssubst.isOK cs then Some cs else None + in + let new_csSubsts = Lib.maybemap mkCSSubst thetasRPr in + ((res@new_csSubsts),log) + in + Lib.fold_left find ([],[]) db.reactions diff --git a/ClassicGEC/ClassicGECDotNet/solver.fsi b/ClassicGEC/ClassicGECDotNet/solver.fsi new file mode 100644 index 0000000..0204064 --- /dev/null +++ b/ClassicGEC/ClassicGECDotNet/solver.fsi @@ -0,0 +1,16 @@ +module Microsoft.Research.GEC.Solver + +open Microsoft.Research.GEC + +//open Microsoft.Research.ModellingEngine +open Microsoft.Research.CRNEngine + +(* Compute a set of context-sensitive substitutions for a brick, relative to a database. *) +val matchParts : Database.t -> string -> string -> (string * (string list list)) list -> Cssubst.t list * string list + +(* Compute a set of context-sensitive substitutions for a normal reaction, relative to a database. *) +val matchNormalReactions : Database.t -> string list list -> string list list -> string list list -> string -> Cssubst.t list * string list + +(* Compute a set of context-sensitive substitutions for a transport reaction, relative to a database. *) +val matchTransportReactions : Database.t -> reactant:string list -> product:string list -> string -> string -> + Ast.direction -> Cssubst.t list * string list diff --git a/ClassicGEC/ClassicGECDotNet/subst.fs b/ClassicGEC/ClassicGECDotNet/subst.fs new file mode 100644 index 0000000..6b363d3 --- /dev/null +++ b/ClassicGEC/ClassicGECDotNet/subst.fs @@ -0,0 +1,232 @@ +[] +module Microsoft.Research.GEC.Subst +open Microsoft.Research.GEC + +//open Microsoft.Research.ModellingEngine +open Microsoft.Research.CRNEngine + +module Expressions = Microsoft.Research.CRNEngine.Expression +(* ************************************************************************************************************ *) + +(* A "normal" substitution can either produce a species name, a part id or a real number. *) +type target = SPECIES of string list + | PART of string + | NUMBER of float + | ALGEBRAIC_EXPRESSION of Ast.aexp +type t = target Stringmap.t + +(* The empty substitution and singleton substitution. *) +let empty : t = Stringmap.empty +let singleton (x:string) (t:target) : t = empty |> Stringmap.add x t + +(* Produce a string representation of a substitution. *) +let displayTarget = function + | SPECIES ys -> Ast.complexString ys + | PART y -> y + | NUMBER n -> Lib.display_float n + | ALGEBRAIC_EXPRESSION(_) -> "(algebraic_expression)" +let display (theta:t) = + let body = Stringmap.fold (fun acc x tgt -> acc + "(" + Lib.quote x + ", " + Lib.quote (displayTarget tgt) + ")" + "; ") "" theta in + "[" + body + "]" + +(* Find the result of looking up a variable (NB raises an exception if not found...) *) +let find (x:string) (theta:t) = Stringmap.find x theta + +(* Try to find the result of lookup up a variable (returns an option type). *) +let tryFind (x:string) (theta:t) = Stringmap.tryFind x theta + +(* An equality function on substitution targets, which accounts for complexes. *) +let targetEq (tgt1:target) (tgt2:target) : bool = + match tgt1, tgt2 with + | SPECIES xs1, SPECIES xs2 -> Ast.complexesEqual xs1 xs2 + | PART p1, PART p2 -> p1=p2 + | NUMBER f1, NUMBER f2 -> f1=f2 + | _,_ -> false + +(* An equality function on substitutions themselves. *) +let eq (theta1:t) (theta2:t) = + let dom1 = Stringmap.getKeys theta1 in + let dom2 = Stringmap.getKeys theta2 in + if (dom1=dom2) then + Lib.forall (fun x -> targetEq (find x theta1) (find x theta2)) dom1 + else false + +(* Compute the union of two substitutions, if possible. *) +let union (theta1:t) (theta2:t) : t option = + Stringmap.fold (fun acc x t -> + match acc with + | None -> None + | Some smap -> + match Stringmap.tryFind x smap with + | None -> Some(Stringmap.add x t smap) + | Some t' -> if t=t' then Some smap else None) + (Some theta1) theta2 + +(* Compute Dom_S(theta). *) +let speciesDomain (theta:t) = + let f snames x tgt : string list = + match tgt with + | SPECIES _ -> Lib.maybeappend (=) snames x + | _ -> snames + in + Stringmap.fold f [] theta + +(* ************************************************************************************************************ *) + +(* Does a string correspond to a meta-variable? (i.e. does it begin with a capital? *) +let isMetaVariable (x:string) : bool = + System.Char.IsUpper (x.[0]) + +(* Does a string correspond to a floating-point value? *) +let getFloat (x:string) : float option = + let ret = ref 0.0 + if System.Double.TryParse(x, ret) then Some !ret else None + +(* Implement a rudimentary "occurs check". Assumes that x is a metavariable. *) +let occursCheckPassed (x:string) (tgt:target) : bool = + match tgt with + | PART z -> not(x=z) + | SPECIES zs -> not(Lib.contains x zs) + | _ -> true + +(* "Unify" a string from the program with a "substTarget" from the database. *) +let unify (x:string) (tgt:target) : t option = + if isMetaVariable x then + (if occursCheckPassed x tgt then Some(singleton x tgt) else None) + else + match tgt with + | PART z -> if x=z then Some empty else None + | SPECIES zs -> (if zs=[x] then Some empty else None) + | NUMBER f -> (match getFloat x with None -> None | Some f' -> if f=f' then Some empty else None) + | ALGEBRAIC_EXPRESSION a -> None // check this + +(* Turn an association list into a substitution, if possible... *) +let multiple (prs:(string * target) list) : t option = + let rec loop (theta:t) (prs:(string * target) list) = + match prs with + | [] -> Some theta + | ((x,t)::prs) -> + begin match unify x t with + | None -> None + | Some theta' -> + begin match union theta theta' with + | None -> None + | Some theta -> loop theta prs + end + end + in + loop empty prs + +(* Apply a substitution to a complex, represented as strings. *) +let applyToComplex (theta:t) (xs:string list) : string list = + Lib.collect (fun x -> match tryFind x theta with Some(SPECIES zs) -> zs | _ -> [x]) xs + +(* Apply a substitution to a "part type" presented as in trans.fs, using strings... *) +let applyToPartTypeStrings (theta:t) (pt:string * (string list list)) : string * (string list list) = + let (brickType, brickProps) = pt in + let applySubst x = match tryFind x theta with None -> x | Some tgt -> displayTarget tgt in + (brickType, List.map (List.map applySubst) brickProps) + +(* Apply a substitution to a "gecSpecies" (for generic plotting). *) +let applyToGecSpecies (theta:t) (i:Ast.gecSimpleSpecies) : Ast.gecSimpleSpecies = + (* Apply a substitution to a value. *) + let applyToValue (theta:t) (v:Ast.value) : Ast.value list = + match v with + | Ast.IdVal x -> begin match tryFind x theta with + | Some (SPECIES(xs)) -> List.map (fun x -> Ast.IdVal(x)) xs + | _ -> [v] + end + | _ -> [v] + in + (* Apply a substitution to a "simple" GEC species. *) + let applyToSimpleGecSpecies (theta:t) (i:Ast.gecSimpleSpecies) : Ast.gecSimpleSpecies = + match i with + | Ast.SimpleSpecies ac -> Ast.SimpleSpecies(Lib.collect (applyToValue theta) ac) + | Ast.CompartmentSpecies(c,ac) -> Ast.CompartmentSpecies(c, Lib.collect (applyToValue theta) ac) + in + (applyToSimpleGecSpecies theta) i + +(* Apply a substitution to a directive data structure (for generic plotting). *) +let applyToDirective (theta:t) (d:Ast.directive) : Ast.directive = + (* Apply a substitution to a "plottable". *) + let applyToPlottable (theta:t) (p:Ast.gecSimpleSpecies Key Expression.t) = Expressions.map (Key.map (applyToGecSpecies theta)) p in + (* + let rec applyToPlottable (theta:t) (p:Ast.gecSpecies Plottable.t) : Ast.gecSpecies Plottable.t = match p with + | Expressions.PopulationAExp g -> Expressions.PopulationAExp (applyToGecSpecies theta g) + //| Plottable.PLOT_STRING s -> Plottable.PLOT_STRING s + | Expressions.SumAExp ps -> Expressions.SumAExp (List.map (applyToPlottable theta) ps) + in *) + match d with + | Ast.PLOT ps -> Ast.PLOT (List.map (applyToPlottable theta) ps) + | _ -> d + +(* Apply a substitution to an arithmetic expression. *) +let rec applyToArithmeticExpression (theta:t) (a:Ast.aexp) : Ast.aexp = + match a with + | Ast.FloatAExp f -> Ast.FloatAExp f + | Ast.IdAExp x -> begin + match tryFind x theta with + | None -> Ast.IdAExp x + | Some (NUMBER f) -> Ast.FloatAExp f + | Some t -> failwith ("applyToArithmeticExpression: illegal substitution because " + x + " maps to " + (displayTarget t)) + end + | Ast.PlusAExp (a1,a2) -> Ast.PlusAExp((applyToArithmeticExpression theta a1),(applyToArithmeticExpression theta a2)) + | Ast.MinusAExp (a1,a2) -> Ast.MinusAExp((applyToArithmeticExpression theta a1),(applyToArithmeticExpression theta a2)) + | Ast.MulAExp (a1,a2) -> Ast.MulAExp((applyToArithmeticExpression theta a1),(applyToArithmeticExpression theta a2)) + | Ast.DivAExp (a1,a2) -> Ast.DivAExp((applyToArithmeticExpression theta a1),(applyToArithmeticExpression theta a2)) + | Ast.PowAExp (a1,a2) -> Ast.PowAExp((applyToArithmeticExpression theta a1),(applyToArithmeticExpression theta a2)) + +(* ************************************************************************************************************ *) + +(* Does a ground constraint hold between floating point values? *) +let groundConstraintHolds ((f1,op,f2):float*Ast.op*float) : bool = + match op with + | Ast.Lt -> f1 f1>f2 + | Ast.Eq -> f1=f2 + +(* Try to evaluate an algebraic expression to a float, using a given substitution. *) +let rec tryProduceFloat (theta:t) (a:Ast.aexp) : float option = + match a with + | Ast.FloatAExp f -> Some f + | Ast.IdAExp id -> if isMetaVariable id then begin match tryFind id theta with Some(NUMBER f) -> Some f | _ -> None end + else failwith ("Subst.satisfiesConstraint: " + id + " is not a metavariable.") + | Ast.PlusAExp (a1,a2) -> (match (tryProduceFloat theta a1, tryProduceFloat theta a2) with + | Some f1, Some f2 -> Some(f1 + f2) + | _,_ -> None) + | Ast.MinusAExp (a1,a2) -> (match (tryProduceFloat theta a1, tryProduceFloat theta a2) with + | Some f1, Some f2 -> Some(f1 - f2) + | _,_ -> None) + | Ast.MulAExp (a1,a2) -> (match (tryProduceFloat theta a1, tryProduceFloat theta a2) with + | Some f1, Some f2 -> Some(f1 * f2) + | _,_ -> None) + | Ast.DivAExp (a1,a2) -> (match (tryProduceFloat theta a1, tryProduceFloat theta a2) with + | Some f1, Some f2 -> Some(f1 / f2) + | _,_ -> None) + | Ast.PowAExp (a1,a2) -> (match (tryProduceFloat theta a1, tryProduceFloat theta a2) with + | Some f1, Some f2 -> Some(f1 * f2) + | _,_ -> None) + +(* Check whether a substitution satisfies an arithmetic constraint. *) +let satisfiesConstraint (theta:t) ((a1,op,a2):Ast.aexp*Ast.op*Ast.aexp) : bool = + (* Turn a string into a float, using a given substitution, if possible... *) + match (tryProduceFloat theta a1),(tryProduceFloat theta a2) with + | Some f1, Some f2 -> groundConstraintHolds (f1,op,f2) + | _,_ -> true (* Constraints involving uninstantiated variables can always be satisfied. *) + +(* Produce a "varAss" (variable assignments) from a substitution. *) +let mkVarAss (theta:t) : (string * string) list * (string * string) list * (string * string) list = + Stringmap.fold + (fun (parts,species,rates) x tgt -> + match tgt with + | SPECIES ys -> + (parts,(species@[x,(Ast.complexString ys)]),rates) + | PART y -> + ((parts@[x,y]),species,rates) + | NUMBER n -> + (parts,species,(rates@[x,(Lib.display_float n)])) + | ALGEBRAIC_EXPRESSION a -> + (parts,species,(rates@[x,(Ast.lbsStringOfAExp a)])) + ) + ([],[],[]) + theta \ No newline at end of file diff --git a/ClassicGEC/ClassicGECDotNet/subst.fsi b/ClassicGEC/ClassicGECDotNet/subst.fsi new file mode 100644 index 0000000..a91e0d1 --- /dev/null +++ b/ClassicGEC/ClassicGECDotNet/subst.fsi @@ -0,0 +1,71 @@ +module Microsoft.Research.GEC.Subst + +open Microsoft.Research.GEC + +//open Microsoft.Research.ModellingEngine +open Microsoft.Research.CRNEngine + +(* ************************************************************************************************************ *) + +(* The target of a "normal" substitution can either produce a species name, a part id or a real number. *) +type target = SPECIES of string list + | PART of string + | NUMBER of float + | ALGEBRAIC_EXPRESSION of Ast.aexp +type t = target Stringmap.t + +(* The empty substitution. *) +val empty : t + +(* An equality function on substitution targets, which accounts for complexes. *) +val targetEq : target -> target -> bool + +(* An equality function on substitutions themselves. *) +val eq : t -> t -> bool + +(* Produce a string representation of a substitution. *) +val displayTarget : target -> string +val display : t -> string + +(* Compute the union of two substitutions, if possible. *) +val union : t -> t -> t option + +(* Compute Dom_S(theta). *) +val speciesDomain : t -> string list + +(* Find the result of looking up a variable (NB raises an exception if not found...) *) +val find : string -> t -> target + +(* Try to find the result of lookup up a variable (returns an option type). *) +val tryFind : string -> t -> target option + +(* Does a string correspond to a floating-point value? *) +val getFloat : string -> float option + +(* ************************************************************************************************************ *) + +(* "Unify" a string from the program with a "target" from the database. *) +val unify : string -> target -> t option + +(* Turn an association list into a substitution, if possible... *) +val multiple : (string * target) list -> t option + +(* Apply a substitution to a complex. *) +val applyToComplex : t -> string list -> string list + +(* Apply a substitution to a "part type" presented as in trans.fs, using strings... *) +val applyToPartTypeStrings : t -> string * (string list list) -> string * (string list list) + +(* Apply a substitution to a directive data structure (for generic plotting). *) +val applyToDirective : t -> Ast.directive -> Ast.directive + +(* Apply a substitution to an arithmetic expression. *) +val applyToArithmeticExpression : t -> Ast.aexp -> Ast.aexp + +(* ************************************************************************************************************ *) + +(* Check whether a substitution satisfies an arithmetic constraint. *) +val satisfiesConstraint : t -> (Ast.aexp * Ast.op * Ast.aexp) -> bool + +(* Produce a "varAss" (variable assignments) from a substitution. *) +val mkVarAss : t -> (string * string) list * (string * string) list * (string * string) list diff --git a/ClassicGEC/ClassicGECDotNet/trans.fs b/ClassicGEC/ClassicGECDotNet/trans.fs new file mode 100644 index 0000000..8d8c9d1 --- /dev/null +++ b/ClassicGEC/ClassicGECDotNet/trans.fs @@ -0,0 +1,1389 @@ +(* +Defines the main translation function for LSB programs. + +Author: Michael Pedersen. +Copyright Microsoft Research, 2008-2009. +*) + +#light + + +[] +module Microsoft.Research.GEC.Trans + +open System +open Microsoft.Research.GEC.Ast +open System.Text.RegularExpressions +//open Microsoft.Research.ModellingEngine +open Microsoft.Research.CRNEngine + + +// define the type of lbs programs that we translate to: +type tLBSProg = + | LBSReacAbstraction of tLBSReac * tLBSProg // needed for promoters which are possibly characterised by hill functions, but this is only known after a substitution is applied. + | LBSReac of tLBSReac + | LBSDegReac of string list list * string // needed in order to put degradation reactions in all compartments. + | LBSTrans of (string list) * (string list) * string * string * direction + | LBSComp of string * tLBSProg + | LBSPar of tLBSProg * tLBSProg + | LBSInitPop of string list * float + | LBSCompDec of string * tLBSProg + | LBSCopy of int * tLBSProg + | LBSNil + | LBSDevice of string + +// a reactions consists of enzymes; reactants; products; a rate; and a boolean indicating if the rate is mass-action: +and tLBSReac = string list list * string list list * string list list * string * bool + + +// lets now define the type of return objects. +// first there are "translation functions" -- these are used to +// produce reactions representing the genetic translation process. +// the first function is parameterised on both mrna and the target protein (complex). +// the following two functions are parameterised on only one of these. +type tTranslFunc = (string -> string list -> tLBSProg) list +type tTranslFunc1 = (string -> tLBSProg) list +type tTranslFunc2 = (string list -> tLBSProg) list + +// for the translation to reactions we also need to keep track of the "current" +// mrna and target protein -- these will be passed to the above functions when appropriate. +// they are lists in order to cope with parallel composition, but only +// singleton/empty lists are supported by the sequential composition operation for now. +type tCurrentMRNA = string list +type tCurrentProt = string list list + +// rate declarations: +type tRateDecs = (string * float) list + +// now to the targets of the genetic translation. +// first we have a 2d list of brick ids/vars: +type tBbDevices = string list list + + + +// Workaround for issues with TextBox in Silverlight +let newline = "\n" + +// the following family converts translated structures to prolog representations: +let lstToProlog absComp = + "[" + (Lib.string_of_list Lib.id "," absComp) + "]" + +let lst2dToProlog absCompLst = + let absCompLst' = absCompLst |> List.map (fun absComp -> lstToProlog absComp) + "[" + (Lib.string_of_list Lib.id "," absCompLst') + "]" + +let propToProlog p = + match p with + | Some (pname, absCompLst) -> + // note that we can't use lst2dToProlog for the body of the properties, since + // the outer brackets of the 2d list shouldn't be included in this case. + let lstStr = absCompLst |> List.map (fun absComp -> lstToProlog absComp) + pname + "(" + (Lib.string_of_list Lib.id "," lstStr) + ")" + | None -> "_" + +(* These are the only kinds of constraint that are produced by the translation... *) +type gecConstraint = IS_EMPTY_LIST of string + | PROM of string * (string * (string list list)) option + | RBS of string * (string * (string list list)) option + | PCR of string * (string * (string list list)) option + | TER of string * (string * (string list list)) option + | UNION of string * string * string // These always involve VARIABLES + | EXCLUSIVE_NAMES of string * string * string list list * string // These always go VARIABLE-VARIABLE-LITERAL-VARIABLE + | NAMES_DISJOINT of string list list * string * string list list * string // These always go LITERAL-VARIABLE-LITERAL-VARIABLE + | NO_DUPLICATES of string list // These always involve LIST LITERALS + | ARITHMETIC of aexp * Ast.op * aexp + | REACTION of string list list * string list list * string list list * string + | TRANSPORT of string list * string list * Ast.direction * string + +(* Produce a string representation of a constraint. *) +let printConstraint (c:gecConstraint) = + let printClause (r:string) (xs:string list) = + r + "(" + (Lib.string_of_list Lib.id "," xs) + ")" + in + match c with + | IS_EMPTY_LIST(x) -> x + "=[]" + | PROM(x,y) -> printClause "prom" [x;(propToProlog y)] + | RBS(x,y) -> printClause "rbs" [x;(propToProlog y)] + | PCR(x,y) -> printClause "pcr" [x;(propToProlog y)] + | TER(x,y) -> printClause "ter" [x;(propToProlog y)] + | UNION(x,y,z) -> printClause "union" [x;y;z] + | EXCLUSIVE_NAMES(w,x,y,z) -> printClause "exclusiveNames" [w;x;(lst2dToProlog y);z] + | NAMES_DISJOINT(w,x,y,z) -> printClause "namesDisjoint" [(lst2dToProlog w);x;(lst2dToProlog y);z] + | NO_DUPLICATES(x) -> printClause "noDuplicates" [lstToProlog x] + | ARITHMETIC(x,op,y) -> (Ast.stringOfAExp x) + (match op with Ast.Lt -> "<" | Ast.Eq -> "=" | Ast.Gt -> ">") + (Ast.stringOfAExp y) + | REACTION(es,rs,ps,r) -> printClause "reac" [(lst2dToProlog es);(lst2dToProlog rs);(lst2dToProlog ps);(lstToProlog [r])] + | TRANSPORT(x,y,Ast.In,r) -> printClause "transport" [(lstToProlog x); (printClause "compartment" [lstToProlog y]); (lstToProlog [r])] + | TRANSPORT(x,y,Ast.Out,r) -> printClause "transport" [(printClause "compartment" [lstToProlog x]); (lstToProlog y); (lstToProlog [r])] + +(* Given a brick type, return a constructor for the gecConstraint type. *) +let getConstraintConstructor (t:string) = + match t with + | "prom" -> PROM + | "rbs" -> RBS + | "pcr" -> PCR + | "ter" -> TER + | _ -> failwith ("\nType error: unexpected brick type: " + t + "\n") + +// a variable which in Plolog will unify with a list of exclusive species: +type tExcSpecVar = string + +// a list of species names occurring in a given program: +type tSpecNames = string list list + +// a list of constraints for PROLOG: (NB - delete these soon??) +type tPrologConstraints = gecConstraint list +//type tPrologConstraints = string list + +// a type for arithmetic constraints collected for solving at the end +type tArithmeticConstraints = (aexp * op * aexp) list +let stringOfArithmeticConstraint ((a1,op,a2):aexp*op*aexp) = + (Ast.stringOfAExp a1) + " " + (stringOfOp op) + " " + (Ast.stringOfAExp a2) + +// and a set of context-sensitive substitutions. +type tSubstitutions = Cssubst.t list + +// all of the above are collected into a semantic object record: +type tSemObj = { + translFunc : tTranslFunc; + translFunc1 : tTranslFunc1; + translFunc2 : tTranslFunc2; + currentMRNA : tCurrentMRNA; + currentProt : tCurrentProt; + bbDevices : tBbDevices; + prologConstraints : tPrologConstraints; + arithmeticConstraints : tArithmeticConstraints; + substitutions : tSubstitutions; + exclusiveSpecVar : tExcSpecVar; + specNames : tSpecNames; + lbsProg : tLBSProg; + rateDefs : tRateDecs; + log : string list + } + +// now to the definition of environment types (a parameter to the translation function). +// first define the type of substitutions (formal/actual pars) and module environments: +type tsubst = Map +type tenvm = Map tSemObj> + +// collect the latter two into an environment record for convenience -- +// also add simulation-only flag: +type tenv = {envm : tenvm; subst : tsubst; simOnlyReacs : bool} + +// a closure for generating unique numbers (from Expert F# p. 75): +let private newStr = // ref (fun () -> "Fixme") + let count = ref 0 + (fun () -> count := !count + 1; string !count) + +// Reset the "newStr" counter, so we start numbering from scratch each time we compile +//let resetCounter () = +// let count = ref 0 +// newStr := (fun () -> count := !count + 1; Int32.to_string !count) + + + +// use the above for generating new variables: +let rec newVar(existing: string list) = + let a = "X_" + newStr() + if List.contains(a) existing then + newVar(existing) + else + a + + +// define an empty semantic object: + + + +// Note that mRNA degradation rates do not associate naturally with any part. +// So for now, we use a globally defined variable with the following default value. +let RMRNADeg_string = "RMRNADeg" +let default_RMRNADeg = 0.001 + +// Expand a set of rateDecs to include the default RMRNADeg string, if necessary +let expandRateDecs (rateDecs:tRateDecs) : tRateDecs = if (List.exists (fun (x,_) -> x=RMRNADeg_string) rateDecs) then rateDecs + else (RMRNADeg_string, default_RMRNADeg)::rateDecs + +// Turn a set of rateDecs into a substitution +let substOfRateDecs (rateDecs:tRateDecs) : Subst.t = Lib.fold_left (fun theta (r,f) -> Stringmap.add r (Subst.NUMBER f) theta) Subst.empty rateDecs + +// Apply a set of rateDecs to an arithmetic constraint +let applyRateDecs2ArithmeticConstraints (rateDecs:tRateDecs) (acs:tArithmeticConstraints) : tArithmeticConstraints = + let theta = substOfRateDecs rateDecs in + List.map (fun (a1,op,a2) -> ((Subst.applyToArithmeticExpression theta a1),op,(Subst.applyToArithmeticExpression theta a2))) acs + +// flag for ignoring consistency constraints: +let ignoreConsistencyConstraints = ref false + +// flag specifying whether constants or variables should be used when introducing +// e.g. new facts in constraints; the former is for translation of human-readable +// databases to prolog databases: +let useConstants = ref false + +let rec findExpVars (exp:aexp) = + match exp with + | FloatAExp(_) -> [] + | IdAExp(str) -> [str] + | PlusAExp(e1,e2) -> + (findExpVars e1)@(findExpVars e2) + | MinusAExp(e1,e2) -> + (findExpVars e1)@(findExpVars e2) + | MulAExp(e1,e2) -> + (findExpVars e1)@(findExpVars e2) + | DivAExp(e1,e2) -> + (findExpVars e1)@(findExpVars e2) + | PowAExp(e1,e2) -> + (findExpVars e1)@(findExpVars e2) + + +let findValueExp (v:Ast.value) = + match v with + | IdVal(str) -> [str] + | AlgebraicExp(exp) -> findExpVars exp + | _ -> [] + +let findAbstractComplexExp (a:Ast.abstractComplex) = + let alist = a |> List.map(fun (value) -> findValueExp value) + + match alist.Length with + | 0 -> [] + | 1 -> alist.Head + | _ -> alist |> List.reduce (fun a b -> (a@b)) + + +let findAbstractComplexListExp (a: Ast.abstractComplex list) = + let alist = a|> List.map(fun x -> findAbstractComplexExp x) + match alist.Length with + | 0 -> [] + | 1 -> alist.Head + | _ -> alist |> List.reduce (fun a b -> (a@b)) + +let findPropExp (p:Ast.prop) = + let (str,acomplex) = p + let alist = acomplex |> List.map(fun x -> findAbstractComplexExp x) + match alist.Length with + | 0 -> [] + | 1 -> alist.Head + | _ -> alist |> List.reduce (fun a b -> (a@b)) + +let findPropListExp (propList:Ast.prop list) = + let alist = propList |> List.map(fun x-> findPropExp x) + match alist.Length with + | 0 -> [] + | 1 -> alist.Head + | _ -> alist |> List.reduce (fun a b -> (a@b)) + +let rec findExistingVariables (program:prog) = + match program with + | Nil -> [] + | Brick(brickId,_,propList) -> + (findValueExp brickId)@(findPropListExp propList) + | Reac(enz,react,prod,v,_) -> + (findAbstractComplexListExp enz) @ + (findAbstractComplexListExp react) @ + (findAbstractComplexListExp prod) @ + (findValueExp v) + | Trans (react,prod,str,v,_,_) -> + str :: + (findAbstractComplexExp react) @ + (findAbstractComplexExp prod) @ + (findValueExp v) + | TemplateInv (str,args) -> + str :: + (findAbstractComplexListExp args) + | Seq(s1,s2) -> + (findExistingVariables s1)@(findExistingVariables s2) + | Par(p1,p2) -> + (findExistingVariables p1)@(findExistingVariables p2) + | Comp(comp,p) -> + comp::(findExistingVariables p) + | New(var,p) -> + var::(findExistingVariables p) + | TemplateDef(modName,args,p1,p2) -> + modName::args@(findExistingVariables p1)@(findExistingVariables p2) + | Constraint (exp1,_,exp2) -> + (findExpVars exp1)@(findExpVars exp2) + | Ast.Rate(value,_) -> findValueExp value + | InitPop(var,_) -> findAbstractComplexExp var + | Copy (_,p,_,_) -> findExistingVariables p + | Device (d) -> [d] + +// top-level translation function. +// parameterised on a programme, and a boolean flag indicating simulation only reactions. +//let translate_base (p:prog) (simOnlyReacs:bool) (db:Database.t) (mrnadeg:float) = +let rec translate0 (p:prog) (simOnlyReacs:bool) (db:Database.t) = + // create empty environments: + let subst = Map.empty : tsubst + let envm = Map.empty : tenvm + let env = { subst = subst; envm = envm; simOnlyReacs = simOnlyReacs } + let existing = (findExistingVariables p) |> Set.ofList |> List.ofSeq + //Check in Database and GECReaction as well? + let excNv = newVar(existing) + + let emptySemObj = + { + translFunc = []; + translFunc1 = []; + translFunc2 = []; + currentMRNA = []; + currentProt = []; + bbDevices = []; + prologConstraints = [IS_EMPTY_LIST(excNv)]; + arithmeticConstraints = []; + substitutions = []; + exclusiveSpecVar = excNv; + specNames = []; + lbsProg = LBSNil; + rateDefs = []; + log = [] + } + + // invoke main translation function: + let sobj = translate db p env emptySemObj existing + + // filter out those substitutions which don't satisfy the arithmetic constraints we have accumulated + let sobj = {sobj with substitutions = List.filter (fun cs -> Cssubst.satisfiesConstraints cs (applyRateDecs2ArithmeticConstraints sobj.rateDefs sobj.arithmeticConstraints)) sobj.substitutions} + + // append the final set of context-sensitive substitutions to the log + let sobj = {sobj with log = sobj.log@["FINAL SET OF CONTEXT-SENSITIVE SUBSTITUTIONS:" + Lib.newline + Lib.string_of_list Cssubst.display Lib.newline sobj.substitutions]} + + // return relevant fields of semantic object: + (sobj.bbDevices, sobj.prologConstraints, sobj.lbsProg, sobj.rateDefs, sobj.substitutions, sobj.arithmeticConstraints, sobj.log) + + // main translation function. + // parameterised on a program and environment. + and translate (db:Database.t) (p:prog) (env:tenv) (emptySemObj:tSemObj) (existing:string list)= + match p with + | Nil -> + emptySemObj + + | Device(d) -> + {emptySemObj with lbsProg=LBSDevice(d)} + + | Brick(v, t, propLst) -> + // preprocess property list, replacing derived properties (non-quantitative) with their defined counterparts: + let prepProp (prop:prop) = + + match (t, prop) with + | ("prom", ("pos", [tf])) -> + let (r1, r2, r3) = + if !useConstants then + ("0", "0", "0") + else + (newVar(existing), newVar(existing), newVar(existing)) + ("pos", [tf; [IdVal(r1)]; [IdVal(r2)]; [IdVal(r3)]]) + + | ("prom", ("neg", [tf])) -> + let (r1, r2, r3) = + if !useConstants then + ("0", "0", "0") + else + (newVar(existing), newVar(existing), newVar(existing)) + + ("neg", [tf; [IdVal(r1)]; [IdVal(r2)]; [IdVal(r3)]]) + + | ("pcr", ("codes", [prot])) -> + let r = if !useConstants then "0" else newVar(existing) + ("codes", [prot; [IdVal(r)]]) + + | _ -> prop + + // invoke: + let propLst''' = List.map prepProp propLst + + // if promoter does not have a constitutive property, then add one: + let conRate = if !useConstants then "0" else newVar(existing) + let propLst'' = if (t <> "prom" || List.exists (fun (pname, lst) -> pname = "con") propLst''') then + propLst''' + else + ("con", [[IdVal(conRate)]])::propLst''' + + // if promoter does not have a functional rate property, then add one: + (*let funRate = if !useConstants then "0" else newVar() + let propLst'' = if (t <> "prom" || List.exists (fun (pname, lst) -> pname = "frate") propLst'') then + propLst'' + else + ("frate", [[IdVal(funRate)]])::propLst''*) + + // if ribosome binding site does not have a rate property, then add one: + let transcRate = if !useConstants then "1" else newVar(existing) + let propLst' = if (t <> "rbs" || List.exists (fun (pname, lst) -> pname = "rate") propLst'') then + propLst'' + else + ("rate", [[IdVal(transcRate)]])::propLst'' + + // check that brick type is recognised: + if not (t = "prom" || t = "pcr" || t = "rbs" || t = "ter") then + failwith ("\nType error: unexpected brick type: " + t + "\n") + + + // process brick value: + let brick = match transVal v env existing with + | [b] -> b + | _ -> failwith("\nType error: non-atomic value used for brick identifier.\n") + + // translate properties: + let propLst2 = (transPropLst propLst' env existing) + + // get a constraint for each property: + let prologConstraints' = List.map (fun prop -> (getConstraintConstructor t) (brick, (Some prop))) propLst2 + + // in case there are no properties, or if we are translating in order to generate + // prolog database, add a constraint for the existence of an arbitrary biobrick: + let prologConstraints = if prologConstraints'.Length = 0 || !useConstants + then ((getConstraintConstructor t) (brick, None))::prologConstraints' + else prologConstraints' + + // get species names and build constraints for exclusive names. + // first define a function which finds the species names of properties: + let getSpecNames (prop : string * string list list) = + match prop with + | (pname, x::xs) when pname = "pos" || pname = "neg" || pname = "pcr" || pname = "codes" -> [x] + | _ -> [] + + // and invoke: + let specNames = propLst2 |> Seq.collect getSpecNames |> Set.ofSeq |> Set.toList + + // old version of above, where we take all elements of property, including numbers (rates). + // this works and is more general than the above, where we must know the properties, but it clutteres + // the prolog output for presentation and is probably less effifient. + //let specNames = propLst2 |> List.map (fun (pname, absCompLst) -> specNames absCompLst) |> List.flatten + + let nv = newVar(existing) + let exclusiveNamesConstraint' = [EXCLUSIVE_NAMES(t,brick,specNames,nv)] + let exclusiveNamesConstraint = if !ignoreConsistencyConstraints then [] else exclusiveNamesConstraint' + + // update semantic object with information gathered so far, i.e. concerning the translation to biobricks: + let newPrologConstraints = prologConstraints@exclusiveNamesConstraint + + // Compute a list of substitutions for this brick + // NB: default database hard-coded in here... + let substitutions,logEntries = Solver.matchParts db brick t propLst2 + + // Produce some log output for debugging... + let newLog = ("Searched for " + brick + " in the database:")::logEntries in + + + let sobj = {emptySemObj with prologConstraints = emptySemObj.prologConstraints@newPrologConstraints; + substitutions = substitutions; + bbDevices = [[brick]]; + specNames = specNames; + exclusiveSpecVar = nv; + log = emptySemObj.log @ newLog } + + // now update the semantic object with information needed for translation to reactions: + let sobj' = + match t with + | "prom" -> + // create new names for gene and mrna: + let gene = "g" + newStr() + let mrna = "mrna" + newStr() + + // create a degradation reaction for mrna + let mrnaDegReac = LBSReac([],[[mrna]],[[]], RMRNADeg_string, true) + + // create initial population statement for gene: + let initPop = LBSInitPop([gene], 1.0) + + // function for processing properties; ignores frate properties + let rec reacsFromProps prop = + match prop with + // a constitutive expression: + | ("con", [[rate]]) -> + let r1 = LBSReac([],[[gene]],[[gene]; [mrna]], rate, true) + [r1] + + // a "quantitative" expression (either pos or neg): + | (_, [tf; [rBind]; [rUnbind]; [rTranscr]]) -> + + let r1 = LBSReac( [],[[gene]; tf],[gene::tf], rBind, true) + let r2 = LBSReac( [],[gene::tf], [[gene]; tf], rUnbind, true) + let r3 = LBSReac( [],[gene::tf], [gene::tf; [mrna]], rTranscr, true) + [r1;r2;r3] + + // if pos/neg property with no rates, just create fresh variables for rates: + | (pname, [tf]) when (pname="pos" || pname="neg") -> + reacsFromProps (pname, [tf; [newVar(existing)]; [newVar(existing)]; [newVar(existing)]]) + + | _ -> [] + + // apply the above function to get reactions: + let reactions' = + propLst2 |> List.collect reacsFromProps + + // get the frate property and create a functional rate reaction from this: + let fRateProp = + List.tryFind + (fun prop -> + match prop with + | ("frate", [[rateStr]]) -> true + | _ -> false + ) + propLst2 + in + let fRateReac = + match fRateProp with + | Some("frate", [[rateStr]]) when (rateStr <> "0.0" && rateStr <> "0") -> + ( [],[[gene]], [[gene];[mrna]], rateStr, false) + | _ -> + ( [],[[gene]], [[gene];[mrna]], "0.0", false) + + + // put reactions in parallel: + + let lbsProg'' = match reactions' with + | [] -> LBSNil + | [r] -> r + | r1::[r2] -> LBSPar(r1,r2) + | first::second::remaining -> + let firstPar = LBSPar(first,second) + List.fold (fun p1 p2 -> LBSPar(p1,p2)) firstPar remaining + + //let lbsProg'' = Lib.fold_left (fun p1 p2 -> LBSPar(p1, p2)) LBSNil reactions' + + // create abstraction construct with full reactions and the single functional rate reaction: + let lbsProg' = LBSReacAbstraction(fRateReac, lbsProg'') + + // add mRNA degradation and init population: + let lbsProg = LBSPar(lbsProg', LBSPar(mrnaDegReac, initPop)) + + {sobj with lbsProg = lbsProg; currentMRNA = [mrna]} + + | "rbs" -> + // declare a function which, given mrna and protein, returns a reaction: + let f mrna prot = + // find the rate in the first "rate" property encountered, + // or a fresh variable (or constant) if no such property is given. + let translRate = if !useConstants then "1" else newVar(existing) + let rec getRate propLst2 = + match propLst2 with + | [] -> translRate + | ("rate", [[r]])::rest -> r + | _::rest -> getRate rest + + let rate = getRate propLst2 + let r1 = LBSReac([],[[mrna]],[[mrna]; prot], rate, true) + r1 + + {sobj with translFunc = [f]} + + | "pcr" -> + // function for finding the protein coded by this pcr: + let rec protFromProps (props : (string * string list list) list) = + match props with + | [] -> + None + | ("codes", [prot; [degRate]])::rest -> + Some(prot, degRate) + | _::rest -> + protFromProps [] + + // invoke the above function and record the protein in return record: + match (protFromProps propLst2) with + | None -> sobj + | Some(prot, rate) -> + let protDegReac = LBSDegReac([prot], rate) + {sobj with currentProt = [prot]; lbsProg = protDegReac } + + | _ -> + sobj + + sobj' + + | Reac(absCompLst1, absCompLst2, absCompLst3, rate, simOnly) -> + // translate abstract complex lists: + let absCompLst1' = transAbstractComplexLst absCompLst1 env existing + let absCompLst2' = transAbstractComplexLst absCompLst2 env existing + let absCompLst3' = transAbstractComplexLst absCompLst3 env existing + + // translate rate: + let rate' = match transVal rate env existing with + | [r] -> if (!useConstants && isVar r) then "1" else r + | _ -> failwith ("Type error: complex value used as rate.\n") + + // create reaction and constraints: + let lbsReac = LBSReac(absCompLst1', absCompLst2', absCompLst3', rate', true) + let prologConstraint = REACTION(absCompLst1', absCompLst2', absCompLst3', rate') + + // get species names: + let specNames1 = specNames absCompLst1' + let specNames2 = specNames absCompLst2' + let specNames3 = specNames absCompLst3' + + // gather constraints and species names, but not if simulation-only flag is true: + let prologConstraints = if (simOnly || env.simOnlyReacs) then [] else [prologConstraint] + let specNames = if (simOnly || env.simOnlyReacs) then [] else specNames1@specNames2@specNames3 + + // get all substitutions which unify the reaction with one from the database (unless it's a sim-only reaction...) + let substitutions,logEntries = + if (simOnly || env.simOnlyReacs) then [Cssubst.empty],[] + else + Solver.matchNormalReactions db absCompLst1' absCompLst2' absCompLst3' rate' + let logEntries = + let tempReac = Gecreaction.makeNormal absCompLst1' absCompLst2' absCompLst3' -1.0 + let reacStr = (tempReac |> Gecreaction.display |> Lib.quote) + " at rate " + rate' + if (simOnly || env.simOnlyReacs) then ["Reaction " + reacStr + " is simulation only..."] else + ("Looking for a normal reaction of the form " + reacStr)::logEntries + + {emptySemObj with prologConstraints = prologConstraints@emptySemObj.prologConstraints; + substitutions = substitutions; + lbsProg = lbsReac; + specNames = specNames; + log = logEntries + } + + | Trans(absComp1, absComp2, compartment, rate, simOnly, direction) -> + // translate compartment value (may be under scope of new or formal par) + let compartment = match transVal (IdVal(compartment)) env existing with + | [c] -> c + | _ -> failwith ("\nType error: non-atomic value used for compartment identifier.\n") + + let absComp1' = transAbstractComplex absComp1 env existing + let absComp2' = transAbstractComplex absComp2 env existing + + // translate rate: + let rate' = match transVal rate env existing with + | [r] -> if (!useConstants && isVar r) then "1" else r + | _ -> failwith("Type error: complex value used as rate.\n") + + // get species names: + let specNames1 = specNames [absComp1'] + let specNames2 = specNames [absComp2'] + + // create reaction and new constraint: + let lbsTrans = LBSTrans(absComp1', absComp2', compartment, rate', direction) + let prologConstraint = TRANSPORT(absComp1',absComp2',direction,rate') + + // check if simulation-only: + let prologConstraints = if (simOnly || env.simOnlyReacs) then emptySemObj.prologConstraints + else prologConstraint::emptySemObj.prologConstraints + + // get all substitutions which unify the reaction with one from the database (unless it's a sim-only reaction...) + let substitutions,logEntries = + if (simOnly || env.simOnlyReacs) then [Cssubst.empty],[] + else + Solver.matchTransportReactions db absComp1' absComp2' rate' compartment direction + let logEntries = + let tempReac = Gecreaction.makeTransport absComp1' absComp2' -1.0 compartment direction + let reacStr = (tempReac |> Gecreaction.display |> Lib.quote) + " at rate " + rate' + if (simOnly || env.simOnlyReacs) then ["Reaction " + reacStr + " is simulation only..."] else + ("Looking for a transport reaction of the form " + reacStr)::logEntries + + {emptySemObj with prologConstraints = prologConstraints; + substitutions = substitutions; + lbsProg = lbsTrans; + specNames = specNames1@specNames2; + log = logEntries + } + + | TemplateDef(mid, fParLst, body, p') -> + // define the semantic function for the body of this module: + let f aParLst = + + // check that length of formals and actuals match: + if not (List.length aParLst = List.length fParLst) then + + let error = "Length of formal and actual parameter lists do not match (" + mid + "/" + (List.length fParLst).ToString() + " <> " + (List.length aParLst).ToString() + ").\n" + failwith error + + // update substitution: + let subst' = Lib.fold_left (fun (map : tsubst) (fPar, aPar) -> map.Add(fPar, aPar) ) env.subst (List.zip fParLst aParLst) + + // translate body of module in updated environment: + translate db body { env with subst = subst' } emptySemObj existing + + // update the module environment and translate the program following module declaration: + let envm' = env.envm.Add(mid, f) + translate db p' { env with envm = envm' } emptySemObj existing + + | TemplateInv(mid, aParLst) -> + // check that module has been declared: + if not (env.envm.ContainsKey(mid)) then + failwith ("Template " + mid + " has not been defined.\n") + + // translate actual parameter list: + let aParLst' = transAbstractComplexLst aParLst env existing + + // look up the semantic function recorded for this module and invoke it with the evaluated formal parameters: + let f = env.envm.[mid] + f aParLst' + + + | Par(p1, p2) -> + // translate recursively: + let sobj1 = translate db p1 env emptySemObj existing + let sobj2 = translate db p2 env emptySemObj existing + + // find the a list of names and variables from both components, but with no duplicates: + let namesVarsFlat = (List.concat sobj1.specNames)@(List.concat sobj2.specNames) + let namesVarsFlatNoDups = namesVarsFlat |> Set.ofList |> Set.toList + + // constraint saying that names for instantiating variables must be fresh, i.e. + // the namesVarsNoDups list must remain a set when the variables are instantiated: + let freshSubstPrologConstraint = NO_DUPLICATES(namesVarsFlatNoDups) + + // constraint saying that names of programs are disjoint from the respective exclusive names: + let specNames1' = sobj1.specNames |> Set.ofList |> Set.toList + let specNames2' = sobj2.specNames |> Set.ofList |> Set.toList + let disjointPrologConstraint = NAMES_DISJOINT(specNames1', sobj1.exclusiveSpecVar, specNames2', sobj2.exclusiveSpecVar) + + // find the new exclusive names as the union of exclusive names from each component: + let exNamesVar = newVar(existing) + let exNamesUnionPrologConstraint = UNION(sobj1.exclusiveSpecVar, sobj2.exclusiveSpecVar, exNamesVar) + + // collect new constraints: + let prologConstraints = if !ignoreConsistencyConstraints then [] else [freshSubstPrologConstraint; disjointPrologConstraint; exNamesUnionPrologConstraint] + + // combine the two sets of context-sensitive substitutions + let substitutions = Cssubst.compose sobj1.substitutions sobj2.substitutions + + // produce a log entry to record the substitution composition + let newLog = ["ABOUT TO DO A PARALLEL COMPOSITION OF SUBSTITUTIONS..."; + "First one: " + Lib.newline + Lib.string_of_list Cssubst.display Lib.newline sobj1.substitutions; + "Second one: " + Lib.newline + Lib.string_of_list Cssubst.display Lib.newline sobj2.substitutions; + "Result: " + Lib.newline + Lib.string_of_list Cssubst.display Lib.newline substitutions] + + // assemble result and return: + let sobj = { + translFunc = sobj1.translFunc @ sobj2.translFunc; + translFunc1 = sobj1.translFunc1 @ sobj2.translFunc1; + translFunc2 = sobj1.translFunc2 @ sobj2.translFunc2; + currentMRNA = sobj1.currentMRNA @ sobj2.currentMRNA; + currentProt = sobj1.currentProt @ sobj2.currentProt; + bbDevices = sobj1.bbDevices @ sobj2.bbDevices; + prologConstraints = sobj1.prologConstraints @ sobj2.prologConstraints @ prologConstraints; + arithmeticConstraints = sobj1.arithmeticConstraints @ sobj2.arithmeticConstraints; + substitutions = substitutions; + exclusiveSpecVar = exNamesVar; + specNames = sobj1.specNames @ sobj2.specNames; + lbsProg = LBSPar(sobj1.lbsProg, sobj2.lbsProg); + rateDefs = sobj1.rateDefs @ sobj2.rateDefs; + log = sobj1.log @ sobj2.log @ newLog + } + + sobj + + | Seq(p1, p2) -> + // translate recursively: + let sobj1 = translate db p1 env emptySemObj existing + let sobj2 = translate db p2 env emptySemObj existing + + // find the a list of names and variables from both components, but with no duplicates: + let namesVarsFlat = (List.concat sobj1.specNames)@(List.concat sobj2.specNames) + let namesVarsFlatNoDups = namesVarsFlat |> Set.ofList |> Set.toList + + // constraint saying that names for instantiating variables must be fresh, i.e. + // the namesVarsNoDups list must remain a set when the variables are instantiated: + let freshSubstPrologConstraint = NO_DUPLICATES(namesVarsFlatNoDups) + + // constraint saying that names of programs are disjoint from the respective exclusive names: + let specNames1' = sobj1.specNames |> Set.ofList |> Set.toList + let specNames2' = sobj2.specNames |> Set.ofList |> Set.toList + let disjointPrologConstraint = NAMES_DISJOINT(specNames1', sobj1.exclusiveSpecVar, specNames2', sobj2.exclusiveSpecVar) + + // find the new exclusive names as the union of exclusive names from each component: + let exNamesVar = newVar(existing) + let exNamesUnionPrologConstraint = UNION(sobj1.exclusiveSpecVar, sobj2.exclusiveSpecVar, exNamesVar) + + // collect new constraints: + let prologConstraints' = if !ignoreConsistencyConstraints then [] + else [freshSubstPrologConstraint; disjointPrologConstraint; exNamesUnionPrologConstraint] + let prologConstraints = sobj1.prologConstraints @ sobj2.prologConstraints @ prologConstraints' + + // combine the two templates list (what is the technical word for this operation?) + let bbDevices2D = List.map (fun x -> List.map (fun y -> x@y) sobj2.bbDevices) sobj1.bbDevices + let bbDevices = List.concat(bbDevices2D) + + + // ********** END OF BIOBRICK TRANSLATION ************* + // ********** START OF REACTION TRANSLATION ********* + + // check for information about current mrna and update second semantic object accordingly: + let sobj2' = + match sobj1.currentMRNA with + | [] -> + sobj2 + | [mrna] -> + // apply partially evaluated translation functions to this mrna to get reactions: + let newReacs = sobj2.translFunc1 |> List.map (fun f -> (f mrna)) + // create lbs parallel prog from list of reactions: + let lbsProg = match newReacs with + | [] -> LBSNil + | [r] -> r + | r1::[r2] -> LBSPar(r1,r2) + | first::second::remaining -> + let firstPar = LBSPar(first,second) + List.fold (fun p1 p2 -> LBSPar(p1,p2)) firstPar remaining + + //let lbsProg = List.fold (fun p1 p2 -> LBSPar(p1,p2)) LBSNil newReacs + + // apply non-evaluated translation functions to this mrna to obtain new functions: + let newFunc2 = sobj2.translFunc |> List.map (fun f -> (f mrna)) + + // and return: + {sobj2 with lbsProg = LBSPar(sobj2.lbsProg, lbsProg); + translFunc = []; + translFunc1 = []; + translFunc2 = newFunc2; + } + + | _ -> failwith ("Sequential composition is only supported for singleton results, aborting translation [1].\n") + + // check for information about current protein and update first semantic object appropriately: + let (sobj1', sobj2'') = + match sobj2'.currentProt with + | [] -> + (sobj1, sobj2') + | [prot] -> + // apply partially evaluated translation functions to this protein to get reactions: + let newReacs = sobj1.translFunc2 |> List.map (fun f -> f prot) + // create lbs parallel prog from list of reactions: + let lbsProg = match newReacs with + | [] -> LBSNil + | [r] -> r + | r1::[r2] -> LBSPar(r1,r2) + | first::second::remaining -> + let firstPar = LBSPar(first,second) + List.fold (fun p1 p2 -> LBSPar(p1,p2)) firstPar remaining + //let lbsProg = Lib.fold_left (fun p1 p2 -> LBSPar(p1,p2)) LBSNil newReacs + + // apply non-evaluated translation functions to this protein to obtain new functions: + let newFunc1 = sobj1.translFunc |> List.map (fun f -> (fun mrna -> (f mrna prot))) + + // and return: + let sobj1' = { sobj1 with lbsProg = LBSPar(sobj1.lbsProg, lbsProg); + translFunc = []; + translFunc1 = newFunc1; + translFunc2 = []; } + + let sobj2'' = {sobj2' with currentProt = []} + (sobj1', sobj2'') + + | _ -> failwith("sequential composition is only supported for singleton results, aborting translation [2].\n") + + + // propagate the current mrna from the left (this component) to the composite if + // none is defined for the right component: + let currentMRNA = if sobj2''.currentMRNA.Length = 0 then sobj1'.currentMRNA else sobj2''.currentMRNA + + // propagate the current protein from the right (this component) to the composite if + // none is defined for the left component: + let currentProt = if sobj1'.currentProt.Length = 0 then sobj2''.currentProt else sobj1'.currentProt + + // combine the two sets of context-sensitive substitutions + let substitutions = Cssubst.compose sobj1'.substitutions sobj2'.substitutions + + // combine all results (both biobrick and reaction translation) into a semantic object and return: + let sobj = { + translFunc = sobj1'.translFunc @ sobj2'.translFunc; + translFunc1 = sobj1'.translFunc1 @ sobj2'.translFunc1; + translFunc2 = sobj1'.translFunc2 @ sobj2'.translFunc2; + currentMRNA = currentMRNA; + currentProt = currentProt; + bbDevices = bbDevices; + prologConstraints = prologConstraints; + arithmeticConstraints = sobj1'.arithmeticConstraints @ sobj2.arithmeticConstraints; + substitutions = substitutions; + exclusiveSpecVar = exNamesVar; + specNames = sobj1'.specNames @ sobj2'.specNames; + lbsProg = LBSPar(sobj1'.lbsProg, sobj2'.lbsProg); + rateDefs = sobj1.rateDefs @ sobj2.rateDefs; + log = sobj1.log @ sobj2.log + } + + sobj + + + | Comp(cid, p') -> + // translate compartment value (may be under scope of new or formal par) + let cid = match transVal (IdVal(cid)) env existing with + | [cid'] -> cid' + | _ -> failwith("\nType error: non-atomic value used for compartment identifier.\n") + + // translate contained program: + let sobj = translate db p' env emptySemObj existing + + // remove the "context" from the context-sensitive substitutions + let substitutions = List.map Cssubst.eraseContext sobj.substitutions + + // "forget" exclusive names by creating a fresh variable which unifies with the + // empty list, and create an lbs compartment program: + let newVar = newVar(existing) + {sobj with prologConstraints = sobj.prologConstraints @ [IS_EMPTY_LIST(newVar)]; + substitutions = substitutions; + exclusiveSpecVar = newVar; + specNames = []; + lbsProg = LBSComp(cid, sobj.lbsProg); + } + + + | New(id, p') -> + // create a fresh id and update substitution in environment: + let freshId = id + newStr() + let subst' = env.subst.Add(id, [freshId]) + let env' = { env with subst = subst' } + + // translate: + let sobj = translate db p' env' emptySemObj existing + + // add a compartment declaration to lbs prog if the id is lower-case, i.e. a name. if + // the id is not used as a compartment, this will introduce a redundant + // compartment declaration but no harm is done. + + //Websharper compatiblity + let isLowerChar (c:char) = (((int) c >= 97) && ((int) c <= 122)) + + let lbsProg' = if (isLowerChar(id.Chars 0)) then LBSCompDec(freshId, sobj.lbsProg) + else sobj.lbsProg + + // and return. + {sobj with lbsProg = lbsProg'} + + + | Constraint(a1,op,a2) -> + // translate values: + let a1' = transAExp a1 env + let a2' = transAExp a2 env + + let prologConstraint = ARITHMETIC(a1', op, a2') + let arithmeticConstraint = (a1', op, a2') + let newVar = newVar(existing) + {emptySemObj with prologConstraints = prologConstraint::emptySemObj.prologConstraints; + arithmeticConstraints = arithmeticConstraint::emptySemObj.arithmeticConstraints; + substitutions = [Cssubst.empty]} // Is this OK in the case where the program is "just" constraints? Do we care? +(* + | Constraint(a1,op,a2) -> + // translate values: + let v1' = transVal v1 env + let v2' = transVal v2 env + + // check that values are simple and extract them from lists: + let (v1'', v2'') = match (v1', v2') with + | ([x],[y]) -> (x,y) + | _ -> raise (LBS.Error.CompilerExPos("Type error: complex values are not allowed in constraints.\n", None)) + let prologConstraint = ARITHMETIC(v1'', op, v2'') + let arithmeticConstraint = (v1'', op, v2'') + let newVar = newVar() + {emptySemObj with prologConstraints = prologConstraint::emptySemObj.prologConstraints; + arithmeticConstraints = arithmeticConstraint::emptySemObj.arithmeticConstraints; + substitutions = [Cssubst.empty]} // Is this OK in the case where the program is "just" constraints? Do we care? +*) + + | InitPop(absComp, v) -> + // translate initial population statementsn direcly to lbs: + let lbsProg = LBSInitPop(transAbstractComplex absComp env existing, v) + {emptySemObj with substitutions = [Cssubst.empty]; + lbsProg = lbsProg} + + + | Ast.Rate(var, v) -> + // translate var and add rate to semantic object: + let varStr = match transVal var env existing with + | [varStr] -> varStr + | _ -> failwith("Type error: use of complex expression where value expected.\n") + + {emptySemObj with substitutions = [Cssubst.empty]; + rateDefs = [(varStr, v)]} + + + | Copy(num, p, isPar, simOnly) -> + if (num < 1) then + failwith("Type error: copy operator must be given a positive argument.\n") + + // define a function for putting p in par or seq a given number of times: + let rec build num' = + if num' = 1 then + p + else + if isPar then + Par(p, (build (num' - 1))) + else + Seq(p, (build (num' - 1))) + + // build composition num times of prog, but only if simulation-only flag false: + let p' = if simOnly then p else build num + + // translate result: + let sobj = translate db p' env emptySemObj existing + + // if simulation-only, then contruct a LBSCopy program: + // (this avoids copying constraints). + let lbsProg' = if simOnly then + LBSCopy(num, sobj.lbsProg) + else + sobj.lbsProg + + {sobj with lbsProg = lbsProg'} + + + // the following family of functions simply translate values in the given structure +// to their string representations. + and transPropLst propLst (env : tenv) (existing:string list)= + propLst |> List.map (fun prop -> transProp prop env existing) + + and transProp prop (env : tenv) (existing:string list)= + let (propName, absCompLst) = prop + let absCompLst' = transAbstractComplexLst absCompLst env existing + (propName, absCompLst') + + and transAbstractComplexLst absCompLst env existing= + absCompLst |> List.map (fun absComp -> transAbstractComplex absComp env existing) + + and transAbstractComplex absComp env existing = + // translate each value in the abstract complex: + let absComp2 = absComp |> List.map (fun v -> transVal v env existing) |> List.concat + absComp2 + + and transVal v (env : tenv) (existing:string list) = + match v with + // check if an id is to be substituted (either an actual par or a fresh name): + | IdVal(id) -> + if (env.subst.ContainsKey(id)) then + env.subst.[id] + else + [id] + + | FloatVal(f) -> + [Lib.display_float f] + + // wild cards are just short cuts for fresh vars: + | WildCardVal -> + [newVar(existing)] + | AlgebraicExp _ -> failwith "Unexpected AlgebraicExp" + + and transAExp (a:Ast.aexp) (env : tenv) : Ast.aexp = + match a with + | FloatAExp v -> FloatAExp v + | IdAExp id -> + // first check if our environment contains this ID; this is either + // for formal -> actual mappings, or for fresh renaming. + if (env.subst.ContainsKey(id)) then + match env.subst.[id] with + | [x] -> + // result depends on whether x is a float. + (*let f = ref 0.0 + let isFloat = System.Double.TryParse(x, f) + + if isFloat then + FloatAExp(!f) + else + IdAExp(x)*) + NumUtil.case_double FloatAExp (IdAExp x) x + (* + try + FloatAExp(Double.Parse(x)) + with + | _ -> IdAExp(x) + *) + + + | _ -> failwith "Cannot pass a complex expression in module invocations." + + // otherwise check if called in the context of constraint solving; then + // the identifier should be in the Subst environment. if it isn't, just + // create an identifier expression + else + match Subst.getFloat id with + | Some(f) -> FloatAExp(f) + | None -> IdAExp id + + + | PlusAExp (a1,a2) -> PlusAExp(transAExp a1 env, transAExp a2 env) + | MinusAExp (a1,a2) -> MinusAExp(transAExp a1 env, transAExp a2 env) + | MulAExp (a1,a2) -> MulAExp(transAExp a1 env, transAExp a2 env) + | DivAExp (a1,a2) -> DivAExp(transAExp a1 env, transAExp a2 env) + | PowAExp (a1,a2) -> PowAExp(transAExp a1 env, transAExp a2 env) + + // get species names from an abstract complex list: + and specNames absCompLst = + absCompLst |> List.filter (fun absComp -> absComp |> List.forall (fun s -> not(isNum s))) + + // boolean functions for testing types of strings: + and isName (s:string) = Char.IsLower s.[0] + and isVar (s:string) = Char.IsUpper s.[0] || s.[0] = '_' + and isNum (s:string) = (*let d = ref 0.0 in (Double.TryParse(s, d))*) + NumUtil.isNum s + (* + try + Double.Parse(s) |> ignore + true + with + | _ -> false + *) + + // concatenates the elements of the string list with seperating commas: + and concatWith symbol lst = + Lib.fold_left (fun s1 s2 -> if (s1 <> "") then s1 + symbol + s2 else s2) "" lst + + // create a lbs string representing degradation reations from a list of +// LBS degradation reactions and a list of compartments where these should +// be put. + and createDegReacs degReacs comps varDefs = + // function to convert degradation reactions to strings: + let toStr degReac = + match degReac with + | LBSDegReac(complex, rate) -> + let lbsReac = LBSReac([],complex,[],rate, true) + let (str, _, _) = lbsProgToStr' lbsReac varDefs None // note that parent comp (None) will never be relevant here. + str + | _ -> "" + + // invoke on list: + let degReacStrings = degReacs |> List.map toStr + + // remove duplicates from degradation reactions: + let degReacStrings' = degReacStrings |> Set.ofList |> Set.toList + + // remove duplicates from compartment list: + let comps' = comps |> Set.ofList |> Set.toList + + // compose into single string seperated by par: + let degReacsStr = concatWith " | " degReacStrings' + + // insert degradation reactions into each compartment, concatenate compartements in par: + let str = comps' |> List.map (fun c -> newline + c + " [" + degReacsStr + newline + "]") |> (concatWith ("|" + newline)) + + // add degradation in no compartment (world) and return: + if str <> "" then (str + "|" + newline + degReacsStr) else degReacsStr + + + // translate an lbs abstract syntax tree to a concrete syntax string. + // takes as parameters an LBS AST and variable definitions. + and lbsProgToStr lbsProg (varDefs : (string * string) list) = + // get a standard program string, and degradation + compartments seperately: + let (progStr, degReacs, comps) = lbsProgToStr' lbsProg varDefs None + + // get a string with degradation reactions for each compartment in parallel: + let degReacsStr = createDegReacs degReacs comps varDefs + + // append program string to deg string (if any) and return: + if (degReacsStr <> "") then + progStr + " | " + degReacsStr + else + progStr + + // translate an lbs program to a string, returning seperately a list of compartments +// which are not under the scope of any compartment declarations and +// degradation reactions (non-strings, since we need to remove duplicates later). +// The latter need to be added to all compartments seperately for +// systems such as the predator-prey to work -- this +// unfortunately is non-compositional and not very neat. +// apart from an lbs prog, the function takes variable definitions and +// the current parent compartment(a string) as parameters. the former is needed +// to substitute variables for their solutions, and the latter is needed to +// translate transport reactions, such as c[s] -> s, to c[s] -> c[s] -> c'[s] where +// c' is the containing reaction; this respects the LBS compartment semantics. + and lbsProgToStr' lbsProg (varDefs : (string * string) list) parentComp = + + // function for substituting vars for defined values in list of value/vars: + let substVarVal lst = + lst |> List.map (fun x -> match Lib.try_assoc x varDefs with | Some y -> y | None -> x) + + + match lbsProg with + | LBSDevice(d) -> + (d,[],[]) + | LBSReac(enzymes, reactants, products, rate, isMassAction) -> + + let lst2dToLBSSum lst2d = + // replace vars for their definitions: + let lstVarsReplaced = lst2d |> List.map (fun lst -> lst |> substVarVal) + let lst = lstVarsReplaced |> List.map (concatWith "::") + (concatWith " + " lst) + + let sum1 = lst2dToLBSSum enzymes + let sum2 = lst2dToLBSSum reactants + let sum3 = lst2dToLBSSum products + + // replace rate for defined value if necessary: + let rate' = match Lib.try_assoc rate varDefs with Some x -> x | None -> rate + + // determine which rate brackets to use: + let (bracLeft, bracRight) = if isMassAction then ("{", "}") else ("[", "]") + + // don't print the ~ symbol if there are no enzymes: + let prefix = if enzymes = [] then "" else sum1 + " ~ " + + //let str = newline + sprintf "%s%s ->%s%s%s %s " prefix sum2 bracLeft rate' bracRight sum3 + let str = newline + prefix + sum2 + " ->" + bracLeft + rate' + bracRight + " " + sum3 + " " + (str, [], []) + + | LBSReacAbstraction(absReac, program) -> + // if abstract reaction has non-0 rate defined in substitution, use this; otherwise use the detailed reactions in program: + match absReac with + | ( _, _, _, rateVarStr, _) -> + let rateStr = match Lib.try_assoc rateVarStr varDefs with Some x -> x | None -> "0.0" + + if (rateStr <> "0.0" && rateStr <> "0") then + let p = LBSReac(absReac) in + lbsProgToStr' p varDefs parentComp + else + lbsProgToStr' program varDefs parentComp + + + | LBSDegReac(complex, rate) -> + ("", [lbsProg], []) + + | LBSTrans(complex1, complex2, compartment, rate, direction) -> + // replace vars for their defined values: + let complex1' = substVarVal complex1 + let complex2' = substVarVal complex2 + + // convert lists to LBS complexes: + let complex1Str = concatWith "::" complex1' + let complex2Str = concatWith "::" complex2' + + // replace rate for defined value if necessary: + let rate' = match Lib.try_assoc rate varDefs with Some x -> x | None -> rate + + // creates a string representation of spec s inside the current parent comp, taking into accound whether + // or not this is the empty world compartment: + let specInParentComp s = + (match parentComp with + | None -> s + | Some(c') -> c' + "[" + s + "]") + + let str = if direction = In then + // we could use a more complex diffusion-style rate (see commented-out def below), + // but doing so makes the simulation go slow and weird. don't know why. + let arrow = "->{" + rate' + "} " in + //let arrow = "->[" + rate' + " * (" + complex1Str + " -- " + compartment + "[" + complex2Str + "])] " + newline + complex1Str + arrow + compartment + "[" + complex2Str + "]" + else + let arrow = "->{" + rate' + "} " in + //let arrow = "->[" + rate' + " * (" + compartment + "[" + complex1Str + "] -- " + complex2Str + ")] " + newline + compartment + "[" + complex1Str + "] " + arrow + complex2Str + + (str, [], []) + + | LBSComp(cname, p) -> + let (pStr, pDeg, pComps) = lbsProgToStr' p varDefs parentComp + let cStr = newline + newline + cname + " [" + pStr + newline + "]" + (cStr, pDeg, cname::pComps) + + | LBSPar(p1, p2) -> + let (p1Str, p1Deg, p1Comps) = lbsProgToStr' p1 varDefs parentComp + let (p2Str, p2Deg, p2Comps) = lbsProgToStr' p2 varDefs parentComp + + let isAllWhiteSpace text = + not (Seq.exists (fun x -> not (Char.IsWhiteSpace x)) text) + + // don't want to print a lot of empty Nil programs, so ignore parallel + // composition sym if one component is Nil (translates to empty string): + let parSym = if (isAllWhiteSpace p1Str || isAllWhiteSpace p2Str) then "" else "|" + + //let str = sprintf "%s %s %s" p1Str parSym p2Str + let str = p1Str + " " + parSym + " " + p2Str + (str, p1Deg@p2Deg, p1Comps@p2Comps) + + | LBSInitPop(lst, pop) -> + // creates a string representation of spec s inside the current parent comp, taking into account whether + // or not this is the empty world compartment: + let specInParentComp s = + match parentComp with + | None -> s + | Some(c') -> c' + "[" + s + "]" + + let lst' = substVarVal lst + let str = concatWith "::" lst' + let pStr = newline + "init " + str + " " + string pop + (pStr, [], []) + + | LBSCompDec(cname, p) -> + let (pStr, pDeg, pComps) = lbsProgToStr' p varDefs parentComp + + // create degradation reactions for this compartment + // (its important to have them within scope of the compartment declaration): + let degReacsStr = createDegReacs pDeg [cname] varDefs + + let str = newline + "comp " + cname + "; " + pStr + " | " + degReacsStr + newline + + // filter the compartment name out of the return compartment list; + // we don't want degradation reactions to be created for this compartment + // since we already created them locally: + let pComps' = List.filter (fun c -> c <> cname) pComps + + // and return: + (str, pDeg, pComps') + + | LBSCopy(num, p) -> + let (pStr, pDeg, pComps) = lbsProgToStr' p varDefs parentComp + let str = newline + "copy " + (string num) + " { " + newline + pStr + " " + newline + "}" + newline + (str, pDeg, pComps) + + | LBSNil -> ("", [], []) + + +// returns to lists containing the species variables and rate variables contained in a reaction: +let rec getVarsFromLBSProg p = + + match p with + | LBSReac(enzymes, reactants, products, rate, _) -> + let vars1 = getVarsFromLst2d enzymes + let vars2 = getVarsFromLst2d reactants + let vars3 = getVarsFromLst2d products + let varsRate = if isVar rate then [rate] else [] + (vars1@vars2@vars3, varsRate) + + | LBSDegReac(reactants, rate) -> + let p = LBSReac([], reactants, [], rate, true) + getVarsFromLBSProg p + + | LBSTrans(complex1, complex2, compartment, rate, direction) -> + let vars1 = getVarsFromLst2d [complex1] + let vars2 = getVarsFromLst2d [complex2] + let varsRate = if isVar rate then [rate] else [] + (vars1@vars2, varsRate) + + | LBSComp(cname, p) -> + getVarsFromLBSProg p + + | LBSPar(p1, p2) -> + let (vars1, rateVars1) = (getVarsFromLBSProg p1) + let (vars2, rateVars2) = (getVarsFromLBSProg p2) + (vars1@vars2, rateVars1@rateVars2) + + | LBSCompDec(c, p) -> + getVarsFromLBSProg p + + | LBSCopy(num, p) -> + getVarsFromLBSProg p + + | _ -> ([], []) + + + // returns the variables in a 2d list of strings as a list + and getVarsFromLst2d lst2d = + lst2d |> List.concat |> List.filter isVar //|> Set.ofList |> Set.toList + +// translate0 p simOnlyReacs db + + + + +(* NOTES *) + +(* OBS: we cannot translate rate declarations directly to LBS rate declarations. +The reason is that reactions which should be in the scope of such rate declarations +cannot always be generated locally, specifically for translation reactions. + +Here is an example illustrating the problem: + +--- +module transl(out) { + sim-rate RTransl 0.1; rbs +}; + +transl(O1); transl(O2) +--- + +This will result in the following output (since nil programs are not printed): + +rate RTransl; | +rate RTransl; + +This is certainly not what we want. + +So, the current solution is to substitute rates directly into lbs programs or, alternatively, +collect all rate declarations and prefix the main LBS program with these. +*) + \ No newline at end of file diff --git a/ClassicGEC/ClassicGECDotNetTests/ClassicGECDotNetTests.fsproj b/ClassicGEC/ClassicGECDotNetTests/ClassicGECDotNetTests.fsproj new file mode 100644 index 0000000..26392bb --- /dev/null +++ b/ClassicGEC/ClassicGECDotNetTests/ClassicGECDotNetTests.fsproj @@ -0,0 +1,28 @@ + + + + netcoreapp3.1 + false + false + + + + + + + + + + + + + + + + + + ..\..\Lib\Oslo.FSharp\Oslo.FSharp.dll + + + + \ No newline at end of file diff --git a/ClassicGEC/ClassicGECDotNetTests/Program.fs b/ClassicGEC/ClassicGECDotNetTests/Program.fs new file mode 100644 index 0000000..0695f84 --- /dev/null +++ b/ClassicGEC/ClassicGECDotNetTests/Program.fs @@ -0,0 +1 @@ +module Program = let [] main _ = 0 diff --git a/ClassicGEC/ClassicGECDotNetTests/database.test.fs b/ClassicGEC/ClassicGECDotNetTests/database.test.fs new file mode 100644 index 0000000..2ade0e5 --- /dev/null +++ b/ClassicGEC/ClassicGECDotNetTests/database.test.fs @@ -0,0 +1,165 @@ +module Microsoft.Research.GEC.DatabaseTest + +open Microsoft.Research.GEC.Database +open FSBOL +open FSBOL.SBOLDocument +open FSBOL.XmlSerializer +open Xunit +open FsUnit.Xunit +open System.Diagnostics +open System.Xml +open System.IO +open System.Text + +[] +let databaseParserText() = + let sampledb0 = + "i723017,pcr,codes(xylR;0.001)\n"+ + "i723024,pcr,codes(phzM;0.001)\n"+ + "e0040,pcr,codes(gfp;0.01)\n"+ + "c0099,pcr,codes(cviR;0.01)\n"+ + "i723025,pcr,codes(phzS;0.001)\n"+ + "i723028,pcr,codes(pca;0.001)\n"+ + "c0051,pcr,codes(cI;0.01)\n"+ + "c0040,pcr,codes(tetR;0.01)\n"+ + "c0080,pcr,codes(araC;0.01)\n"+ + "c0012,pcr,codes(lacI;0.01)\n"+ + "cunknown2,pcr,codes(unknown2;0.001)\n"+ + "c0061,pcr,codes(luxI;0.01)\n"+ + "c0062,pcr,codes(luxR;0.01)\n"+ + "c0079,pcr,codes(lasR;0.01)\n"+ + "c0078,pcr,codes(lasI;0.01)\n"+ + "cunknown3,pcr,codes(ccdB;0.005)\n"+ + "cunknown4,pcr,codes(ccdA;0.1)\n"+ + "i723020,prom,pos(toluene::xylR;0.001;0.001;1.0);con(0.0001)\n"+ + "r0051,prom,neg(cI;1.0;0.5;0.00005);con(0.12)\n"+ + "r0040,prom,neg(tetR;1.0;0.5;0.00005);con(0.09)\n"+ + "runknown1,prom,neg(unknown1;1.0;0.005;0.001);con(0.04)\n"+ + "b0034,rbs,rate(0.1)\n"+ + "b0015,ter\n" + + "j06504,pcr,codes(mCherry;0.1)" + + let sampledb1 = + "i723017,pcr,codes(xylR;0.001)\n"+ + "i723024,pcr,codes(phzM;0.001)\n"+ + "e0040,pcr,codes(gfp;0.01)\n"+ + "c0099,pcr,codes(cviR;0.01)\n"+ + "i723025,pcr,codes(phzS;0.001)\n"+ + "i723028,pcr,codes(pca;0.001)\n"+ + "c0051,pcr,codes(cI;0.01)\n"+ + "c0040,pcr,codes(tetR;0.01)\n"+ + "c0080,pcr,codes(araC;0.01)\n"+ + "c0012,pcr,codes(lacI;0.01)\n"+ + "cunknown2,pcr,codes(unknown2;0.001)\n"+ + "c0061,pcr,codes(luxI;0.01)\n"+ + "c0062,pcr,codes(luxR;0.01)\n"+ + "c0079,pcr,codes(lasR;0.01)\n"+ + "c0078,pcr,codes(lasI;0.01)\n"+ + "cunknown3,pcr,codes(ccdB;0.005)\n"+ + "cunknown4,pcr,codes(ccdA;0.1)\n"+ + "i723020,prom,pos(toluene::xylR;0.001;0.001;1.0);con(0.0001)\n"+ + "r0051,prom,neg(cI;1.0;0.5;0.00005);con(0.12)\n"+ + "r0040,prom,neg(tetR;1.0;0.5;0.00005);con(0.09)\n"+ + "runknown1,prom,neg(unknown1;1.0;0.005;0.001);con(0.04)\n"+ + "b0034,rbs,rate(0.1)\n"+ + "b0015,ter\n" + + "j06504,pcr,codes(mCherry;0.1)\n"+ + "PRFP,device,components[P;R;RFP;T]\n" + + "PTetRS100LuxR,device,components[PTet;RS100;LuxR;T]" + + + let from_string (s:string) = Parser.from_string parse s + let table0 = from_string sampledb0 + let table1 = from_string sampledb1 + let sbol = Database.convertTableToSBOLDocument table0 + //Debug.WriteLine(sbolXmlString sbol) + + let fwsw = new StreamWriter("gecSBOLdb.xml",false) + let fwxwSettings = new XmlWriterSettings() + fwxwSettings.Indent <- true + fwxwSettings.Encoding <- Encoding.UTF8 + let fwxw = XmlWriter.Create(fwsw,fwxwSettings) + (XmlSerializer.sbolToXml sbol).WriteTo(fwxw) + fwxw.Close() + + Assert.Equal(table0.parts.Count,24) + Assert.True(table0.parts.ContainsKey("b0015")) + Assert.True(table0.parts.ContainsKey("b0034")) + Assert.True(table0.parts.ContainsKey("i723020")) + Assert.True(table0.parts.ContainsKey("r0040")) + Assert.True(table0.parts.ContainsKey("c0012")) + + Assert.Equal(table0.devices.Length,0) + Assert.Equal(table1.devices.Length,2) + + Debug.WriteLine("END OF TEST") + + +[] +let ``PCRParserTest``() = + let pcrEntry = + "i723017,pcr,codes(xylR; 0.001)" + + let from_string (s:string) = Parser.from_string Database.partParser s + let dnacomp = from_string pcrEntry + let (id,pcr) = match dnacomp with + | Part(x,y) -> (x,y) + | _ -> failwith "Unexpected Device found" + + Assert.Equal(id,"i723017") + match pcr with + | Database.PCR(Database.CODES(codes,rate)) -> + Assert.Equal(codes.Length,1) + Assert.Equal(codes.Head,"xylR") + Assert.Equal(rate,0.001) + | _ -> + Debug.WriteLine("Error") + Assert.Equal(true,false) + + Debug.WriteLine("End of Test") + + +[] +let ``RegulationPromParserTest``() = + let negativeRegulation = + "r0051,prom,neg(cI;1.0;0.5;0.00005);con(0.12)" + + let from_string (s:string) = Parser.from_string Database.partParser s + let dnacomp = from_string negativeRegulation + let (id,negProm) = + match dnacomp with + | Part(x,y) -> (x,y) + | _ -> failwith "Unexpected Device found" + + Assert.Equal(id,"r0051") + match negProm with + | Database.PROM(props) -> + Assert.Equal(props.Length,2) + match props with + first::remaining -> + Assert.Equal(props.Head,Database.NEG(["cI"],1.0,0.5,0.00005)) + Assert.Equal(remaining.Head,Database.CON(0.12)) + | _ -> failwith "" + | _ -> + Debug.WriteLine("Unexpected Part type found") + Assert.Equal(true,false) + + Debug.WriteLine("End of Test") + +[] +let ``TerminatorParserTest``() = + let ter = "b0015,ter" + + let from_string (s:string) = Parser.from_string Database.partParser s + let dnacomp = from_string ter + let (id,ter) = + match dnacomp with + | Part(x,y) -> (x,y) + | _ -> failwith "Unexpected Device found" + + Assert.Equal(id,"b0015") + Assert.Equal(ter,Database.TER) + + Debug.WriteLine("End of Test") + + diff --git a/ClassicGEC/ClassicGECDotNetTests/gecreaction.test.fs b/ClassicGEC/ClassicGECDotNetTests/gecreaction.test.fs new file mode 100644 index 0000000..8ebd9f5 --- /dev/null +++ b/ClassicGEC/ClassicGECDotNetTests/gecreaction.test.fs @@ -0,0 +1,130 @@ +module Microsoft.Research.GEC.GecreactionTest + +open Microsoft.Research.GEC.Gecreaction + +open Xunit +open FsUnit.Xunit +open System.Diagnostics + + +[] +let ``TransportParserTest``() = + let transportInReaction = "m3OC6HSL->{1.0}c[m3OC6HSL]" + let transportOutReaction = "c[m3OC12HSL] -> {1.01}m3OC12HSL" + let from_string (s:string) = Parser.from_string parseReaction s + + let tir = from_string transportInReaction + let tirProps = Gecreaction.isTransport tir + if tirProps.IsSome then + let (reactant,product,rate,compartment,direction) = tirProps.Value + Assert.Equal(reactant.Head,"m3OC6HSL") + Assert.Equal(reactant.Length,1) + Assert.Equal(compartment,"c") + Assert.Equal(rate,1.0) + Assert.Equal(direction,Ast.direction.In) + Assert.Equal(product.Length,1) + Assert.Equal(product.Head,"m3OC6HSL") + else + failwith("None encountered. Error.") + let tor = from_string transportOutReaction + let torProps = Gecreaction.isTransport tor + if torProps.IsSome then + let (reactant,product,rate,compartment,direction) = torProps.Value + Assert.Equal(reactant.Head,"m3OC12HSL") + Assert.Equal(reactant.Length,1) + Assert.Equal(compartment,"c") + Assert.Equal(rate,1.01) + Assert.Equal(direction,Ast.direction.Out) + Assert.Equal(product.Length,1) + Assert.Equal(product.Head,"m3OC12HSL") + else + failwith("None encountered. Error.") + Assert.True(false) + + Debug.WriteLine("END of Test") + + +[] +let ``NormalParserTest``() = + let norNoReactants = "luxI ~ -> {1.0}m3OC6HSL" + let from_string (s:string) = Parser.from_string parseReaction s + let nnr = from_string norNoReactants + let nnrProps = Gecreaction.isNormal nnr + if nnrProps.IsSome then + let (catalysts,reactants,products,rate) = nnrProps.Value + Assert.Equal(catalysts.Length,1) + Assert.Equal(catalysts.Head.Head,"luxI") + Assert.True(reactants.IsEmpty) + Assert.Equal(rate,1.0) + Assert.Equal(products.Head.Head,"m3OC6HSL") + Assert.Equal(products.Length,1) + else + failwith("None encountered. Error.") + Assert.True(true) + + let nor1Nocat = "lasR + m3OC12HSL->{1.0}lasR::m3OC12HSL" + let nor1nc = from_string nor1Nocat + let nor1ncProps = Gecreaction.isNormal nor1nc + if nor1ncProps.IsSome then + let (catalysts,reactants,products,rate) = nor1ncProps.Value + Assert.True(catalysts.IsEmpty) + Assert.Equal(reactants.Length,2) + Assert.Equal(reactants.Head.Head,"lasR") + Assert.Equal(rate,1.0) + Assert.Equal(products.Head.Item(0),"lasR") + Assert.Equal(products.Head.Item(1),"m3OC12HSL") + Assert.Equal(products.Length,1) + else + failwith("None encountered. Error.") + Assert.True(true) + + let nor2Nocat = "lasR::m3OC12HSL->{1.0}lasR+m3OC12HSL" + let nor2nc = from_string nor2Nocat + let nor2ncProps = Gecreaction.isNormal nor2nc + if nor2ncProps.IsSome then + let (catalysts,reactants,products,rate) = nor2ncProps.Value + Assert.True(catalysts.IsEmpty) + Assert.Equal(reactants.Length,1) + Assert.Equal(reactants.Head.Length,2) + Assert.Equal(reactants.Head.Item(0),"lasR") + Assert.Equal(reactants.Head.Item(1),"m3OC12HSL") + Assert.Equal(rate,1.0) + Assert.Equal(products.Item(0).Item(0),"lasR") + Assert.Equal(products.Item(1).Item(0),"m3OC12HSL") + Assert.Equal(products.Length,2) + else + failwith("None encountered. Error.") + Assert.True(true) + + let nor1 = "a::b+b::c+dc+e::f ~ i::j->{0.9}t::v+y::u" + let n1 = from_string nor1 + let n1Props = Gecreaction.isNormal n1 + if n1Props.IsSome then + let (catalysts,reactants,products,rate) = n1Props.Value + Assert.Equal(catalysts.Length,4) + Assert.Equal(catalysts.Item(0).Item(0),"a") + Assert.Equal(catalysts.Item(0).Item(1),"b") + Assert.Equal(catalysts.Item(1).Item(0),"b") + Assert.Equal(catalysts.Item(1).Item(1),"c") + Assert.Equal(catalysts.Item(2).Item(0),"dc") + Assert.Equal(catalysts.Item(3).Item(0),"e") + Assert.Equal(catalysts.Item(3).Item(1),"f") + + Assert.Equal(reactants.Length,1) + Assert.Equal(reactants.Head.Length,2) + Assert.Equal(reactants.Head.Item(0),"i") + Assert.Equal(reactants.Head.Item(1),"j") + Assert.Equal(rate,0.9) + Assert.Equal(products.Length,2) + Assert.Equal(products.Item(0).Item(0),"t") + Assert.Equal(products.Item(0).Item(1),"v") + Assert.Equal(products.Item(1).Item(0),"y") + Assert.Equal(products.Item(1).Item(1),"u") + else + failwith("None encountered. Error.") + Assert.True(true) + + Debug.WriteLine("END of Test") + + + diff --git a/ClassicGEC/ClassicGECDotNetTests/gecspecies.test.fs b/ClassicGEC/ClassicGECDotNetTests/gecspecies.test.fs new file mode 100644 index 0000000..a2660cd --- /dev/null +++ b/ClassicGEC/ClassicGECDotNetTests/gecspecies.test.fs @@ -0,0 +1,54 @@ +module Microsoft.Research.GEC.GecSpeciesTest + +open Parser + +open Xunit +open System.Diagnostics + + +[] +let ``speciesToStringTest``() = + let species0 = {GecSpecies.t.empty_Species with species = ["a"]} + let species1 = {GecSpecies.t.empty_Species with species = ["a";"b"]} + let species2 = {GecSpecies.t.empty_Species with species = ["a";"b";"c";"d"]} + Assert.Equal(GecSpecies.t.empty_Species.to_string(),"") + Assert.Equal(species0.to_string(),"a") + Assert.Equal(species1.to_string(),"a::b") + Assert.Equal(species2.to_string(),"a::b::c::d") + +[] +let ``speciesToCrnStringTest``() = + let species0 = {GecSpecies.t.empty_Species with species = ["a"]} + let species1 = {GecSpecies.t.empty_Species with species = ["a";"b"]} + let species2 = {GecSpecies.t.empty_Species with species = ["a";"b";"c";"d"]} + Assert.Equal(GecSpecies.t.empty_Species.to_string(),"") + Assert.Equal(species0.to_crn_string(),"a") + Assert.Equal(species1.to_crn_string(),"a_b") + Assert.Equal(species2.to_crn_string(),"a_b_c_d") + +[] +let speciesParseTest() = + let species0 = "Signal" + let species1 = "Receiver::Signal" + let species2 = "cell[gfp]" + let species3 = "a::b::c" + let get_species (s:string) = Parser.from_string GecSpecies.parse s + let s0 = get_species species0 + let s1 = get_species species1 + let s2 = get_species species2 + let s3 = get_species species3 + + //Compartment tests + Assert.Equal(s0.compartment,None) + Assert.Equal(s1.compartment,None) + Assert.Equal(s2.compartment,Some("cell")) + Assert.Equal(s3.compartment,None) + + //Length tests + Assert.Equal(s0.species.Length,1) + Assert.Equal(s1.species.Length,2) + Assert.Equal(s2.species.Length,1) + Assert.Equal(s3.species.Length,3) + + + diff --git a/ClassicGEC/ClassicGECDotNetTests/hypothesis.test.fs b/ClassicGEC/ClassicGECDotNetTests/hypothesis.test.fs new file mode 100644 index 0000000..c73814e --- /dev/null +++ b/ClassicGEC/ClassicGECDotNetTests/hypothesis.test.fs @@ -0,0 +1,390 @@ +module Microsoft.Research.GEC.HypothesisTest + +open Xunit +open FsUnit.Xunit +open System.Diagnostics + +open Parser +open Microsoft.Research.GEC +open Microsoft.Research.CRNEngine + + +[] +let ``directivesParser``()= + let directiveString = """directive simulator sundials +//directive simulator deterministic +//directive deterministic {stiff = true} +//directive inference {name=target; burnin=400000; samples=400000; thin=50; noise_model=proportional} +directive inference {name=target; burnin=10; samples=10; thin=1; noise_model=proportional} +directive sweeps [ + sweepC6C12 = [ + (condition,C6,C12) = [ + (1,25000,0); (2,8333.33333333333,0); (3,2777.77777777778,0); (4,925.925925925926,0); (5,308.641975308642,0); (6,102.880658436214,0); (7,34.2935528120713,0); (8,11.4311842706904,0); (9,3.81039475689681,0); (10,1.27013158563227,0); (11,0.423377195210757,0); (12,0,0); + (13,0,25000); (14,0,8333.33333333333); (15,0,2777.77777777778); (16,0,925.925925925926); (17,0,308.641975308642); (18,0,102.880658436214); (19,0,34.2935528120713); (20,0,11.4311842706904); (21,0,3.81039475689681); (22,0,1.27013158563227); (23,0,0.423377195210757); (24,0,0); + ]; + ]; + sweepC6C12double = [ + (condition,C6,C12) = [ + (1,25000,0); (2,8333.33333333333,0); (3,2777.77777777778,0); (4,925.925925925926,0); (5,308.641975308642,0); (6,102.880658436214,0); (7,34.2935528120713,0); (8,11.4311842706904,0); (9,3.81039475689681,0); (10,1.27013158563227,0); (11,0.423377195210757,0); (12,0,0); + (13,0,25000); (14,0,8333.33333333333); (15,0,2777.77777777778); (16,0,925.925925925926); (17,0,308.641975308642); (18,0,102.880658436214); (19,0,34.2935528120713); (20,0,11.4311842706904); (21,0,3.81039475689681); (22,0,1.27013158563227); (23,0,0.423377195210757); (24,0,0); + (1,25000,0); (2,8333.33333333333,0); (3,2777.77777777778,0); (4,925.925925925926,0); (5,308.641975308642,0); (6,102.880658436214,0); (7,34.2935528120713,0); (8,11.4311842706904,0); (9,3.81039475689681,0); (10,1.27013158563227,0); (11,0.423377195210757,0); (12,0,0); + (13,0,25000); (14,0,8333.33333333333); (15,0,2777.77777777778); (16,0,925.925925925926); (17,0,308.641975308642); (18,0,102.880658436214); (19,0,34.2935528120713); (20,0,11.4311842706904); (21,0,3.81039475689681); (22,0,1.27013158563227); (23,0,0.423377195210757); (24,0,0); + ]; + ]; +] + +directive simulation { final=20; points=250 } + +directive rates [ + boundLuxR = [luxR]^2 * ((KR6*[c6])^nR + (KR12*[c12])^nR) / ((1.0 + KR6*[c6] + KR12*[c12])^nR); + boundLasR = [lasR]^2 * ((KS6*[c6])^nS + (KS12*[c12])^nS) / ((1.0 + KS6*[c6] + KS12*[c12])^nS); + P76 = (e76 + KGR_76*[boundLuxR] + KGS_76*[boundLasR]) / (1.0 + KGR_76*[boundLuxR] + KGS_76*[boundLasR]); + P81 = (e81 + KGR_81*[boundLuxR] + KGS_81*[boundLasR]) / (1.0 + KGR_81*[boundLuxR] + KGS_81*[boundLasR]); + PBad = (Ara^nA+eA*KAra^nA)/(Ara^nA+KAra^nA); + PTet = 1/(1+[tetR]^nT); + PLac = 1/(1+[lacI]^nL); + plot_od = [x]+x0; + plot_fp = [x]*[fp]+f0; + plot_yfp = [x]*([yfp]+[f500])+yb0; + plot_cfp = [x]*([cfp]+[f430])+cb0; +] + +directive parameters [ + // Background + c0 = 0.001, { distribution=Uniform(1e-4,3e-1) }; + x0 = 0.1, { interval=Real; distribution=Uniform(0,0.2) }; + f0=5000.0,{ interval=Real; distribution=Uniform(0.0,10000.0) }; + yb0=1e3, { interval=Real; distribution=Uniform(0.0,5e3) }; + cb0=1e3, { interval=Real; distribution=Uniform(0.0,1e4) }; + + // Autofluorescence + dfp=0.1, { distribution=Uniform(1e-3,1e0) }; + autoYFP=1e0, { distribution=Uniform(1e-3,1e3) }; + autoCFP=1e0, { distribution=Uniform(1e-3,1e3) }; + + // Standard + dCFP=1e-2, { distribution=Uniform(1e-3,1e0) }; + dYFP=1e-2, { distribution=Uniform(1e-3,1e0) }; + + // Receivers + KR6=1e-2, { distribution=Uniform(1e-8,1e0) }; + KS6=1e-4, { distribution=Uniform(1e-8,1e0) }; + KR12=1e-3, { distribution=Uniform(1e-8,1e0) }; + KS12=1e-2, { distribution=Uniform(1e-8,1e0) }; + nR=0.797, { interval=Real; distribution=Uniform(0.5,2.0) }; + nS=0.797, { interval=Real; distribution=Uniform(0.5,2.0) }; + aR33=1.0, { distribution=Uniform(1e0,1e2) }; + aS175=1.0, { distribution=Uniform(1e0,1e2) }; + aRS100=1.0, { distribution=Uniform(1e0,1e2) }; + aS32=1.0, { distribution=Uniform(1e0,1e2) }; + nL=0.797, { interval=Real; distribution=Uniform(0.5,2.0) }; + nT=0.797, { interval=Real; distribution=Uniform(0.5,2.0) }; + + dR=0.1, { distribution=Uniform(1e-2,1e1) }; + //dS=0.1, { distribution=Uniform(1e-2,1e2) }; + e76=1e-2, { distribution=Uniform(1e-4,1.0) }; + KGR_76=1e-2,{ distribution=Uniform(1e-4,1e0) }; + KGS_76=1e-6,{ distribution=Uniform(1e-8,1e0) }; + e81=1e-2, { distribution=Uniform(1e-4,1.0) }; + KGR_81=1e-6,{ distribution=Uniform(1e-8,1e0) }; + KGS_81=1e-2,{ distribution=Uniform(1e-4,1e0) }; + aCFP=1e3, { distribution=Uniform(1e0,1e5) }; + aYFP=1e3, { distribution=Uniform(1e0,1e5) }; + + // Relays + kC6=1e0, { distribution=Uniform(1e0,1e6) }; + Klux=1.0, { distribution=Uniform(1e0,1e6) }; + dluxI=0.1,{ distribution=Uniform(1e-3,1e1) }; + kC12=1e0, { distribution=Uniform(1e0,1e6) }; + Klas=1.0, { distribution=Uniform(1e0,1e6) }; + dlasI=0.1,{ distribution=Uniform(1e-3,1e1) }; + + // Arabinose + KAra=1.0, { distribution=Uniform(1e-2,1e2) }; + nA=1.0, { interval=Real; distribution=Uniform(0.5,3.0) }; + eA=0.1, { interval=Real; distribution=Uniform(0.0,0.5) }; + + // Degrader + dA6=1e-1, { distribution=Uniform(1e-3,1e1) }; + dA12=1e-1, { distribution=Uniform(1e-3,1e1) }; + daiiA=0.1, { distribution=Uniform(1e-3,1e1) }; + + C6=0.0; C12=0.0; tau=0.0; aR=1.0; aS=1.0; ATC=0.0; IPTG=0.0; + aYFP_PL=1000.0; aCFP_PL=1000.0; Ara=0.0; condition = 0; +]""" + let directives = Parser.from_string Hypothesis.parse_crnSettings directiveString + Debug.Write(directives.to_string Functional2.to_string Functional2.to_string_plot) + () + +[] +let ``moduleParser``()= + let moduleString = """ +module Control(growth,capacity) = { +//| Growth(growth,tlag) + | fp ->[[growth]*[fp]] // Dilution + | ->[[capacity]] fp // Transcription/translation + | fp ->{dfp} // Degradation +} +module cells(growth,tlag,capacity) = { + | init luxR 0 | init lasR 0 | init lacI 0 | init tetR 0 + | init yfp 0 | init cfp 0 | init f430 0 | init f500 0 + | init c6 C6 @ tau | init c12 C12 @ tau // Hack to prevent greedy evaluation of rates from hurting us + | Growth(growth,tlag) + // Autofluorescence + | ->[[capacity]*autoYFP] f500 + | f500 ->[[growth]*[f500]] + | ->[[capacity]*autoCFP] f430 + | f430 ->[[growth]*[f430]] +} + +module AiiA(P,aI,growth,capacity) = { + | ->[[capacity]*aI*[P]] aiiA + | aiiA ->{daiiA} + | aiiA ->[[growth]*[aiiA]] + //| c6 -> [[x]*dA6*[c6]*[aiiA]/(1+KA6*[c6]+KA12*[c12])] + //| c12 -> [[x]*dA12*[c12]*[aiiA]/(1+KA6*[c6]+KA12*[c12])] + | c6 -> [[x]*dA6*[c6]*[aiiA]] + | c12 -> [[x]*dA12*[c12]*[aiiA]] +} +""" + let modules = Parser.from_string (Hypothesis.parse_crnModules Crn_settings.defaults) moduleString + + Debug.WriteLine(Hypothesis.modules_to_string 0.0 modules) + + () + +[] +let ``deviceDirectiveParser``()= + let device0 = "device [LuxR]" + let device1 = "device [LuxR;pTet]" + let device2 = "device [cfp; gfp]" + let dev0 = Parser.from_string Hypothesis.parse_hypothesisDirective device0 + let dev1 = Parser.from_string Hypothesis.parse_hypothesisDirective device1 + let dev2 = Parser.from_string Hypothesis.parse_hypothesisDirective device2 + + () + +[] +let ``deviceDefinitionParser``()= + let device0 = "device PRFP(growth,capacity) = { Control(growth,capacity) }" + let device1 = "device PLacYFPCFP(growth,capacity) = { YFP(PLac,aYFP,growth,capacity) | CFP(PLac,aCFP,growth,capacity) }" + let dev0 = Parser.from_string Hypothesis.parse_device device0 + let dev1 = Parser.from_string Hypothesis.parse_device device1 + Debug.WriteLine(Hypothesis.deviceDefinition_to_string dev0) + Debug.WriteLine(Hypothesis.deviceDefinition_to_string dev1) + () + + +[] +let ``systemParser``()= + let system0 = """system growth = { + directive simulation { final=20; points=250 } + | Growth(growth,tlag) +}""" + let sys0 = Parser.from_string Hypothesis.parse_crn_system system0 + + let system1 = """system growth = { + directive simulation { final=20; points=250 } + directive device [pTet]; + | Growth(growth,tlag) +}""" + + let sys1 = Parser.from_string Hypothesis.parse_crn_system system1 + + let system2 = """system growth = { + control with directive data [R33S175_Y81C76_mRFP1_proc141021] + directive device [pTet]; +}""" + let sys2 = Parser.from_string Hypothesis.parse_crn_system system2 + () + +[] +let ``igElementParser``()= + let element0 = """edge Receivers_growth.Receiver0_growth ->[r=Fixed;K=Fixed;tlag=Fixed] Receivers_control.Receiver0_control""" + let element1 = """edge Relays ->[KR6;KS6;KR12;KS12;nR;nS;aR33;aS175;dR;e76;KGR_76;KGS_76;e81;KGR_81;KGS_81;aCFP;aYFP;] Degrader""" + let element2 = """edge Auto_control ->[dfp] Standard_control""" + let element3 = """edge Auto_control ->[r=Fixed;dfp] Standard_control""" + let element4 = """node Auto { systems = [Auto] }""" + let element5 = """node Receivers_growth { systems = [Receiver0_growth; Receiver1_growth; Receiver2_growth; Receiver3_growth] }""" + let element6 = """node Auto_Growth { systems = [growth]; inference = {burnin=1000; samples=1000; partial=true} }""" + let element7 = """node Auto_Target { systems = [auto]; inference = {burnin=50000; samples=50000} }""" + + let elem0 = Parser.from_string Hypothesis.parse_igraphElement element0 + let elem1 = Parser.from_string Hypothesis.parse_igraphElement element1 + let elem2 = Parser.from_string Hypothesis.parse_igraphElement element2 + let elem3 = Parser.from_string Hypothesis.parse_igraphElement element3 + let elem4 = Parser.from_string Hypothesis.parse_igraphElement element4 + let elem5 = Parser.from_string Hypothesis.parse_igraphElement element5 + let elem6 = Parser.from_string Hypothesis.parse_igraphElement element6 + let elem7 = Parser.from_string Hypothesis.parse_igraphElement element7 + + () + +[] +let ``hypothesisTest``()= + let database = """i723017,pcr,codes(xylR;0.001) +i723024,pcr,codes(phzM;0.001) +e0040,pcr,codes(gfp;0.01) +c0099,pcr,codes(cviR;0.01) +i723025,pcr,codes(phzS;0.001) +i723028,pcr,codes(pca;0.001) +c0051,pcr,codes(cI;0.01) +c0040,pcr,codes(tetR;0.01) +c0080,pcr,codes(araC;0.01) +c0012,pcr,codes(lacI;0.01) +cunknown2,pcr,codes(unknown2;0.001) +c0061,pcr,codes(luxI;0.01) +c0062,pcr,codes(luxR;0.01) +c0079,pcr,codes(lasR;0.01) +c0078,pcr,codes(lasI;0.01) +cunknown3,pcr,codes(ccdB;0.005) +cunknown4,pcr,codes(ccdA;0.1) +i723020,prom,pos(toluene::xylR;0.001;0.001;1.0);con(0.0001) +r0051,prom,neg(cI;1.0;0.5;0.00005);con(0.12) +r0040,prom,neg(tetR;1.0;0.5;0.00005);con(0.09) +runknown1,prom,neg(unknown1;1.0;0.005;0.001);con(0.04) +b0034,rbs,rate(0.1) +b0015,ter +j06504,pcr,codes(mCherry;0.1) +PRFP,device,components[P;R;RFP;T] +PTetRS100LuxR,device,components[PTet;RS100;LuxR;T] +DRR33S175,device,components[PRFP;PTetRS100LuxR] +DRRS,device,components[DRR33S175|LuxR] +EC10G,device,components[P] +PLPL,device,components[P;R;eYFP;T;P;R;eCFP;T]""" + + let hypothesis_content = """directive simulator sundials +directive parameters [ + C6=0.0; C12=0.0; c0 = 0.002; r = 1.0; K = 2.0; rc = 1000.0; tlag=0.0; tau=0.0; + // Autofluorescence + autoYFP=1e0, { interval=Log; distribution=Uniform(1e-3,1e3); variation=Random }; + autoCFP=1e0, { interval=Log; distribution=Uniform(1e-3,1e3); variation=Random }; + // FP + dRFP=0.1, { interval=Log; distribution=Uniform(1e-3,1e0); variation=Random }; + dCFP=1e-2, { interval=Log; distribution=Uniform(1e-3,1e0); variation=Random }; + dYFP=1e-2, { interval=Log; distribution=Uniform(1e-3,1e0); variation=Random }; +] +directive inference { thin=100; noise_model = proportional } +directive simulation {multicore=True} +directive rates [ + growth = [grow]*r*(1 - [x] / K); + capacity = rc; +] + +module CFP(a) = { + ->[[capacity]*a] cfp | + cfp ->{dCFP} | + cfp ->[[growth]*[cfp]] +} +module YFP(a) = { + ->[[capacity]*a] yfp | + yfp ->{dYFP} | + yfp ->[[growth]*[yfp]] +} +module cells() = { + init x c0 | + init grow 1 @ tlag | + init c6 C6 @ tau | + init c12 C12 @ tau | + ->[[growth]*[x]] x +} +module autofluorescence() = { + ->[[capacity]*autoYFP] f530 | + f530 ->[[growth]*[f530]] | + ->[[capacity]*autoCFP] f480 | + f480 ->[[growth]*[f480]] +} +module Control() = { +//| Growth(growth,tlag) + | fp ->[[growth]*[fp]] // Dilution + | ->[[capacity]] fp // Transcription/translation + | fp ->{dRFP} // Degradation +} + +device PRFP() = { Control() } +device PLPL() = { YFP(aYFP) | CFP(aCFP) } + +system growth = { + directive simulation { final=36.0; points=250; plots=[[x]+x0] } + directive parameters [ + r = 1, { interval=Real; distribution=Uniform(0.1,10); variation=Multiple }; + K = 2, { interval=Real; distribution=Uniform(0.1,5); variation=Multiple }; + tlag = 1, { interval=Real; distribution=Uniform(0,10); variation=Multiple }; + x0=0.1,{ interval=Real; distribution=Uniform(0.0,0.2); variation=Random }; + ] + directive rates [growth = [grow]*r*(1 - [x] / K)] + cells() +} +system control = { + directive simulation { final=36.0; points=250; plots=[[x]*[fp]+f0]; plotcolours=["#FF0000"] } + directive parameters [ + r = 1, { interval=Real; distribution=Uniform(0.1,10); variation=Multiple }; + K = 2, { interval=Real; distribution=Uniform(0.1,5); variation=Multiple }; + tlag = 1, { interval=Real; distribution=Uniform(0,10); variation=Multiple }; + rc=1e2, { interval=Log; distribution=Uniform(1e0,1e5); variation=Multiple }; + f0=100.0,{ interval=Real; distribution=Uniform(0.0,10000.0); variation=Random }; + ] + directive rates [growth = [grow]*r*(1 - [x] / K);capacity = rc] + directive device [PRFP] + cells() +} +system auto = { + directive simulation { final=36.0; points=250; plots=[[x]*[f530]+yb0; [x]*[f480]+cb0]; plotcolours=["#FFDF00"; "#ADD8E6"] } + directive parameters [ + r = 1, { interval=Real; distribution=Uniform(0.1,10); variation=Multiple }; + K = 2, { interval=Real; distribution=Uniform(0.1,5); variation=Multiple }; + tlag = 1, { interval=Real; distribution=Uniform(0,10); variation=Multiple }; + rc=1e2, { interval=Log; distribution=Uniform(1e0,1e5); variation=Multiple }; + yb0=1e3, { interval=Real; distribution=Uniform(0.0,5e3); variation=Random }; + cb0=1e3, { interval=Real; distribution=Uniform(0.0,1e4); variation=Random }; + ] + directive rates [growth = [grow]*r*(1 - [x] / K);capacity = rc] + | cells() + | autofluorescence() +} +system prpr = { + directive simulation { final=36.0; points=250; plots=[[x]*([yfp]+[f530])+yb0; [x]*([cfp]+[f480])+cb0]; plotcolours=["#FFDF00"; "#ADD8E6"] } + directive parameters [ + r = 1, { interval=Real; distribution=Uniform(0.1,10); variation=Multiple }; + K = 2, { interval=Real; distribution=Uniform(0.1,5); variation=Multiple }; + tlag = 1, { interval=Real; distribution=Uniform(0,10); variation=Multiple }; + rc=1e2, { interval=Log; distribution=Uniform(1e0,1e5); variation=Multiple }; + aCFP=1e3, { interval=Log; distribution=Uniform(1e0,1e5); variation=Random }; + aYFP=1e3, { interval=Log; distribution=Uniform(1e0,1e5); variation=Random }; + yb0=1e3, { interval=Real; distribution=Uniform(0.0,5e3); variation=Random }; + cb0=1e3, { interval=Real; distribution=Uniform(0.0,1e4); variation=Random }; + ] + directive rates [growth = [grow]*r*(1 - [x] / K);capacity = rc] + directive device [PLPL] + | cells() + | autofluorescence() +} + +//node Auto_Growth { systems = [growth] } +//node Auto_Control { systems = [control] } + +node Auto_Growth { systems = [growth]; inference = {burnin=1000; samples=1000; partial=true} } +node Auto_Control { systems = [control]; inference = {burnin=1000; samples=1000; partial=true} } +node Auto_Target { systems = [auto]; inference = {burnin=50000; samples=50000} } + +node PRPR_Growth { systems = [growth]; inference = {burnin=1000; samples=1000; partial=true} } +node PRPR_Control { systems = [control]; inference = {burnin=100000; samples=100000; partial=true} } +node PRPR_Target { systems = [prpr]; inference = {burnin=100000; samples=100000} } + +edge Auto_Growth.growth ->[r=Fixed;K=Fixed;tlag=Fixed] Auto_Control.control +edge Auto_Control.control ->[r=Fixed;K=Fixed;tlag=Fixed;rc=Fixed] Auto_Target.auto + +edge PRPR_Growth.growth ->[r=Fixed;K=Fixed;tlag=Fixed] PRPR_Control.control +edge PRPR_Control.control ->[r=Fixed;K=Fixed;tlag=Fixed;rc=Fixed] PRPR_Target.prpr + +edge Auto_Control ->[dRFP=TruncatedNormal] PRPR_Control +edge Auto_Target ->[autoYFP=TruncatedNormal;autoCFP=TruncatedNormal] PRPR_Target + +""" + let lib = Parser.from_string Database.parse database + let hypothesis = Parser.from_string Hypothesis.parse_hypothesis_content hypothesis_content + + Debug.WriteLine(Hypothesis.hypothesis_to_crn_program hypothesis lib.devices) + + () + diff --git a/ClassicGEC/ClassicGECDotNetTests/main.test.fs b/ClassicGEC/ClassicGECDotNetTests/main.test.fs new file mode 100644 index 0000000..afa7114 --- /dev/null +++ b/ClassicGEC/ClassicGECDotNetTests/main.test.fs @@ -0,0 +1,105 @@ +module Microsoft.Research.GEC.MainTest + +open Microsoft.Research.GEC.Program + +open Xunit +open FsUnit.Xunit +open System.Diagnostics + + +[] +let ``directivesParserTest``() = + + let sampledir = "directive sample 100000.0" + let sampledir2 = "directive sample 100000.0 1" + let sampledir3 = "directive sample 100000.0 all" + let plotPredprey = "directive plot predator[ccdB]; prey[ccdB]" + let plotab = "directive plot A; B; C" + let plotcellsig = "directive plot cell[gfp]; Signal" + let plotrec = "directive plot receiver[gfp]" + + let parseGECDirective (s:string) = Parser.from_string Program.directiveParser s + + let sampledirfs = parseGECDirective sampledir + let sampledir2fs = parseGECDirective sampledir2 + let sampledir3fs = parseGECDirective sampledir3 + let plotPredpreyfs = parseGECDirective plotPredprey + let plotabfs = parseGECDirective plotab + let plotcellsigfs = parseGECDirective plotcellsig + let plotrecfs = parseGECDirective plotrec + + + Debug.WriteLine("Test completed") + + +[] +let ``expressionParserTest``() = + let exp0 = "a+ c" + let exp1 = "a+b" + let exp2 = "a+b+c" + let exp3 = "a+b+c+d" + let exp4 = "a+b-c" + + let parseExpression (s:string) = Parser.from_string Program.expressionParser s + + let exp0p = parseExpression exp0 + let exp1p = parseExpression exp1 + let exp2p = parseExpression exp2 + let exp3p = parseExpression exp3 + let exp4p = parseExpression exp4 + + Debug.WriteLine("Test Completed") + +[] +let ``brickParserTest``() = + let test (s:string) = Parser.from_string Program.parse_brick s + let a = test "r0051:prom" + let b = test "rbs" + let c = test "pcr" + let d = test "r0051:prom" + let e = test "ter" + let f = test "prom" + let g = test "rbs" + let h = test "pcr" + + Debug.WriteLine("End of Test") + +[] +let ``newparsertest``()= + let prog = "new RB. new RUB.\n" + + "prom" + + let test (s:string) = Parser.from_string Program.parse_new_outer s + let a = test prog + match a with + | Ast.New(id1,prog1) -> + Assert.Equal(id1,"RB") + match prog1 with + | Ast.New(id2,prog2) -> + Assert.Equal(id2,"RUB") + match prog2 with + | Ast.Brick(t,v,propLst) -> + Debug.WriteLine(v) + | _ -> failwith "" + | _ -> failwith "" + | _ -> failwith "" + + Debug.WriteLine("end of test") + +[] +let ``ReactionCodeParserTest``() = + + let rxn = "luxR + Signal -> luxR::Signal" + let test (s:string) = Parser.from_string Program.parse_reaction s + let res = test rxn + Debug.WriteLine("end of test") + +[] +let modInvTest() = + let miprog = "gate(A,B)" + let test (s:string) = Parser.from_string Program.parse_ast_template_inv s + let a = test miprog + + Debug.WriteLine("End of test") + + diff --git a/ClassicGEC/ClassicGECDotNetTests/paket.references b/ClassicGEC/ClassicGECDotNetTests/paket.references new file mode 100644 index 0000000..411449c --- /dev/null +++ b/ClassicGEC/ClassicGECDotNetTests/paket.references @@ -0,0 +1,7 @@ +group DOTNETCORE + +FSharp.Core +FsUnit.xUnit +xunit.core +xunit.runner.console +xunit.runner.visualstudio \ No newline at end of file diff --git a/ClassicGEC/ClassicGECDotNetTests/programParser.test.fs b/ClassicGEC/ClassicGECDotNetTests/programParser.test.fs new file mode 100644 index 0000000..fd8d372 --- /dev/null +++ b/ClassicGEC/ClassicGECDotNetTests/programParser.test.fs @@ -0,0 +1,747 @@ +module Microsoft.Research.GEC.ProgramParserTest + +open Microsoft.Research.GEC.Program + +open Xunit +open FsUnit.Xunit +open System.Diagnostics + +open Parser +open Microsoft.Research.CRNEngine + +let basic_program = """//solution 1 Y = araC +directive simulation {final = 100000.0; points = 1000} + +prom; rbs; pcr; ter""" + +let basic_crn = """directive simulation {final = 100000.0; points = 1000} +directive crn { +module g2module(val) = { +| val g2 +} +| 1 g4 +| g2module(2) +} + +x1:prom; rbs; pcr; ter +""" + +let repressilator = """directive simulation {final = 100000.0; points = 1000; plots = [A; B; C]} + +prom; rbs; pcr; ter; +prom; rbs; pcr; ter; +prom; rbs; pcr; ter""" + +let repressilator_similar = """directive simulation {final = 100000.0; points = 1000; plots = [A; B; C]} + +prom; +rbs; pcr; ter; +prom; +rbs; pcr; ter; +prom; +rbs; pcr; ter + +| 0.4 < RubB | RubB < 0.6 +| 0.4 < RubC | RubC < 0.6 +| 0.4 < RubA | RubA < 0.6 """ + +let repressilator_modules = """directive simulation {final = 100000.0; points = 1000; plots = [A; B; C]} + +template gate(i,o) { + prom; rbs; pcr; ter +}; +gate(A,B) | gate(B,C) | gate(C,A)""" + +let repressilator_modules_similar = """directive simulation {final = 100000.0; points = 1000; plots = [A; B; C]} + +template gate(i,o) { + new RB. new RUB. new RTB. new RT. new R. new RD. + prom;rbs; pcr; ter + | 0.4 < RUB | RUB < 0.6 +}; +gate(A,B) | gate(B,C) | gate(C,A)""" + +let repressilator_system = """//any solution +directive simulation {final = 100000.0; points = 1000; plots = [AF;B;C]} + +template gate(i,o) { + new RB. new RUB. new RTB. new RT. new R. new RD. + prom;rbs; pcr; ter + | 0.4 < RUB | RUB < 0.6 +}; + +system s1{ + gate(A,B) +} + +system s2{ +gate(B,C) +} + +system s3{ +gate(C,A) +} +""" + +let reciever_device = """directive simulation {final = 100000.0; points = 1000; plots = [Signal]} + +cell +[ prom; rbs; pcr; ter +| prom; + rbs; pcr; ter +| Receiver + Signal -> Receiver::Signal +| Receiver::Signal -> Receiver + Signal +] +| Signal -> cell[Signal] +| cell[Signal] -> Signal +| initPop Signal 100.0""" + +let predator_prey = """directive simulation {final = 100000.0; points = 1000; plots = [predator_ccdB; prey_ccdB]} + +predator +[ r0051:prom; rbs; pcr +; rbs; pcr; ter +; prom; rbs; pcr; ter +; r0051:prom; rbs; pcr; ter +| Q1a ~-> H1 | Q2b + H2 <-> Q2b::H2 +| A ~ ccdB -> +| H1 *->{10.0} | H2 *->{10.0} +| ccdB ~ Q1a *->{10.0} +] || + +prey +[ prom; rbs; pcr; ter +; r0051:prom; rbs; pcr +; rbs; pcr; ter +| Q2a ~-> H2 | H1 + Q1b <-> H1::Q1b +| H2 *->{10.0} | H1 *->{10.0} +| ccdB ~ Q2a *->{10.0} +] || + +predator[H1] -> H1 | H1 -> prey[H1] +| prey[H2] -> H2 | H2 -> predator[H2]""" + +let band_detector = """directive simulation {final = 100000.0; points = 1000; plots = [receiver_gfp]} + +receiver +[ runknown5:prom; rbs; pcr; ter +| prom; rbs; pcr;ter +| prom; rbs; pcr;ter +| prom;rbs; pcr;ter +| prom;rbs;pcr;ter +| luxR + Signal -> luxR::Signal +| luxR::Signal -> luxR + Signal +] +| Signal -> receiver[Signal] +| receiver[Signal] -> Signal +| initPop Signal 100.0""" + + +let constant_ratiometric = """directive simulator sundials +directive plot_settings { x_label = "Time (h)"; y_label = "Fluorescence (a.u.)" } +directive parameters [ + // Treatments + C6=0.0; C12=0.0; Ara=0.0; tau=0.0; + // Cell growth + c0 = 0.002; + // Autofluorescence + autoYFP=1e0, { distribution=Uniform(1e-3,1e3) }; + autoCFP=1e0, { distribution=Uniform(1e-3,1e3) }; + // FP + dRFP=0.1, { distribution=Uniform(1e-3,1e0) }; + dCFP=1e-2, { distribution=Uniform(1e-3,1e0) }; + dYFP=1e-2, { distribution=Uniform(1e-3,1e0) }; + // Double receiver + KR6=1e-2, { distribution=Uniform(1e-8,1e0) }; + KS6=1e-4, { distribution=Uniform(1e-8,1e0) }; + KR12=1e-3, { distribution=Uniform(1e-8,1e0) }; + KS12=1e-2, { distribution=Uniform(1e-8,1e0) }; + nR=0.797, { interval=Real; distribution=Uniform(0.5,2.0) }; + nS=0.797, { interval=Real; distribution=Uniform(0.5,2.0) }; + aRS100=1.0, { distribution=Uniform(1e0,1e2) }; + aR33=1.0, { distribution=Uniform(1e0,1e2) }; + aS32=1.0, { distribution=Uniform(1e0,1e2) }; + aS175=1.0, { distribution=Uniform(1e0,1e2) }; + dR=0.1, { distribution=Uniform(1e-2,1e1) }; + //dS=0.1, { distribution=Uniform(1e-2,1e2) }; + e76=1e-2, { distribution=Uniform(1e-4,1.0) }; + KGR_76=1e-2,{ distribution=Uniform(1e-4,1e0) }; + KGS_76=1e-6,{ distribution=Uniform(1e-8,1e0) }; + e81=1e-2, { distribution=Uniform(1e-4,1.0) }; + KGR_81=1e-6,{ distribution=Uniform(1e-8,1e0) }; + KGS_81=1e-2,{ distribution=Uniform(1e-4,1e0) }; + aCFP=1e3, { distribution=Uniform(1e0,1e5) }; + aYFP=1e3, { distribution=Uniform(1e0,1e5) }; + dCFP=1e-2, { distribution=Uniform(1e-3,1e0) }; + dYFP=1e-2, { distribution=Uniform(1e-3,1e0) }; + // Relay P81-LuxI + kC6=1e0, { distribution=Uniform(1e0,1e6) }; + Klux=1.0, { distribution=Uniform(1e0,1e6) }; + dluxI=0.1,{ distribution=Uniform(1e-3,1e1) }; + // Relay P76-LasI + kC12=1e0, { distribution=Uniform(1e0,1e6) }; + Klas=1.0, { distribution=Uniform(1e0,1e6) }; + dlasI=0.1,{ distribution=Uniform(1e-3,1e1) }; + // PBad + KAra=1.0, { distribution=Uniform(1e-2,1e2) }; + nA=1.0, { interval=Real; distribution=Uniform(0.5,3.0) }; + eA=0.1, { interval=Real; distribution=Uniform(0.0,0.5) }; + // AiiA + dA6=1e-1, { distribution=Uniform(1e-3,1e1) }; + dA12=1e-1, { distribution=Uniform(1e-3,1e1) }; + daiiA=0.1, { distribution=Uniform(1e-3,1e1) }; +] +directive inference { burnin=200; samples=200; thin=20; noise_model = proportional } +directive simulation {multicore=True} +directive rates [ + growth = [grow]*r*(1 - [x] / K); + capacity = rc; + boundLuxR = [luxR]^2 * ((KR6*[c6])^nR + (KR12*[c12])^nR) / ((1.0 + KR6*[c6] + KR12*[c12])^nR); + boundLasR = [lasR]^2 * ((KS6*[c6])^nS + (KS12*[c12])^nS) / ((1.0 + KS6*[c6] + KS12*[c12])^nS); + P76 = (e76 + KGR_76*[boundLuxR] + KGS_76*[boundLasR]) / (1.0 + KGR_76*[boundLuxR] + KGS_76*[boundLasR]); + P81 = (e81 + KGR_81*[boundLuxR] + KGS_81*[boundLasR]) / (1.0 + KGR_81*[boundLuxR] + KGS_81*[boundLasR]); + PBad = (Ara^nA+eA*KAra^nA)/(Ara^nA+KAra^nA); + one = 1.0; +] + +module CFP(P,a,growth,capacity) = { + ->[[capacity]*a*[P]] cfp | + cfp ->{dCFP} | + cfp ->[[growth]*[cfp]] +} +module YFP(P,a,growth,capacity) = { + ->[[capacity]*a*[P]] yfp | + yfp ->{dYFP} | + yfp ->[[growth]*[yfp]] +} +module LuxR(aR,growth,capacity) = { + ->[[capacity]*aR] luxR | + luxR ->{dR} | + luxR ->[[growth]*[luxR]] +} +module LasR(aS,growth,capacity) = { + ->[[capacity]*aS] lasR | + lasR ->{dR} | + lasR ->[[growth]*[lasR]] +} +module LuxI(P,growth,capacity) = { + ->[[capacity]*[P]] luxI | + luxI ->{dluxI} | + luxI ->[[growth]*[luxI]] | + ->[kC6*[capacity]*[x]*[luxI]/(1+[luxI]/Klux)] c6 +} +module LasI(P,growth,capacity) = { + ->[[capacity]*[P]] lasI | + lasI ->{dlasI} | + lasI ->[[growth]*[lasI]] | + ->[kC12*[capacity]*[x]*[lasI]/(1+[lasI]/Klas)] c12 +} +module AiiA(P,aI,growth,capacity) = { + ->[[capacity]*aI*[P]] aiiA | + aiiA ->{daiiA} | + aiiA ->[[growth]*[aiiA]] | + c6 -> [[x]*dA6*[c6]*[aiiA]] | + c12 -> [[x]*dA12*[c12]*[aiiA]] +} +module cells(growth,tlag) = { + init x c0 | init grow 1 @ tlag | + init c6 C6 @ tau | init c12 C12 @ tau | + ->[[growth]*[x]] x +} +module autofluorescence(growth,capacity) = { + ->[[capacity]*autoYFP] f530 | + f530 ->[[growth]*[f530]] | + ->[[capacity]*autoCFP] f480 | + f480 ->[[growth]*[f480]] +} +module doublereceiver(aR,aS,growth,capacity) = { + LuxR(aR,growth,capacity) | + LasR(aS,growth,capacity) | + YFP(P81,aYFP,growth,capacity) | + CFP(P76,aCFP,growth,capacity) +} + +// Models of each GEC device +device prpr() = { YFP(one,aYFP,growth,capacity) | CFP(one,aCFP,growth,capacity) } +device drPcat() = { doublereceiver(1.0,1.0,growth,capacity) } +device drRS100S32() = { doublereceiver(aRS100,aS32,growth,capacity) } +device drR33S32() = { doublereceiver(aR33,aS32,growth,capacity) } +device drR33S175() = { doublereceiver(aR33,aS175,growth,capacity) } +device relayP76LasI() = { LasI(P76,growth,capacity) } +device relayP81LuxI() = { LuxI(P81,growth,capacity) } +device pBadYFP() = { YFP(PBad,aYFP,growth,capacity) } +device pBadAiiA() = { AiiA(PBad,1.0,growth,capacity) } + +// Systems for growth and control that will be reused heavily +system growth = { + directive simulation { final=36.0; points=250; plots=[[x]+x0]; multicore=True; sweeps=[sweep_R33S175_PBadaiia_dataset7] } + directive plot_settings { y_label = "OD" } + directive parameters [ + r = 1, { interval=Real; distribution=Uniform(0.1,10); variation=Multiple }; + K = 2, { interval=Real; distribution=Uniform(0.1,5); variation=Multiple }; + tlag = 1, { interval=Real; distribution=Uniform(0,10); variation=Multiple }; + x0=0.1,{ interval=Real; distribution=Uniform(0.0,0.2) }; + ] + directive rates [growth = [grow]*r*(1 - [x] / K)] + directive sweeps [ + sweep_R33S175_PBadaiia_dataset7 = [(EtOH,chlor,C6,C12,Ara) = [(0,0,25000,0,5); (0,0,25000,0,2.5); (0,0,25000,0,1.25); (0,0,25000,0,0.625); (0,0,25000,0,0.3125); (0,0,25000,0,0); (0,0,0,25000,5); (0,0,0,25000,2.5); (0,0,0,25000,1.25); (0,0,0,25000,0.625); (0,0,0,25000,0.3125); (0,0,0,25000,0); (0,0,5000,0,5); (0,0,5000,0,2.5); (0,0,5000,0,1.25); (0,0,5000,0,0.625); (0,0,5000,0,0.3125); (0,0,5000,0,0); (0,0,0,5000,5); (0,0,0,5000,2.5); (0,0,0,5000,1.25); (0,0,0,5000,0.625); (0,0,0,5000,0.3125); (0,0,0,5000,0); (0,0,1000,0,5); (0,0,1000,0,2.5); (0,0,1000,0,1.25); (0,0,1000,0,0.625); (0,0,1000,0,0.3125); (0,0,1000,0,0); (0,0,0,1000,5); (0,0,0,1000,2.5); (0,0,0,1000,1.25); (0,0,0,1000,0.625); (0,0,0,1000,0.3125); (0,0,0,1000,0); (0,0,200,0,5); (0,0,200,0,2.5); (0,0,200,0,1.25); (0,0,200,0,0.625); (0,0,200,0,0.3125); (0,0,200,0,0); (0,0,0,200,5); (0,0,0,200,2.5); (0,0,0,200,1.25); (0,0,0,200,0.625); (0,0,0,200,0.3125); (0,0,0,200,0); (0,0,40,0,5); (0,0,40,0,2.5); (0,0,40,0,1.25); (0,0,40,0,0.625); (0,0,40,0,0.3125); (0,0,40,0,0); (0,0,0,40,5); (0,0,0,40,2.5); (0,0,0,40,1.25); (0,0,0,40,0.625); (0,0,0,40,0.3125); (0,0,0,40,0); (0,0,8,0,5); (0,0,8,0,2.5); (0,0,8,0,1.25); (0,0,8,0,0.625); (0,0,8,0,0.3125); (0,0,8,0,0); (0,0,0,8,5); (0,0,0,8,2.5); (0,0,0,8,1.25); (0,0,0,8,0.625); (0,0,0,8,0.3125); (0,0,0,8,0); (0,0,1.6,0,5); (0,0,1.6,0,2.5); (0,0,1.6,0,1.25); (0,0,1.6,0,0.625); (0,0,1.6,0,0.3125); (0,0,1.6,0,0); (0,0,0,1.6,5); (0,0,0,1.6,2.5); (0,0,0,1.6,1.25); (0,0,0,1.6,0.625); (0,0,0,1.6,0.3125); (0,0,0,1.6,0); (0,0,0,0,5); (0,0,0,0,2.5); (0,0,0,0,1.25); (0,0,0,0,0.625); (0,0,0,0,0.3125); (0,0,0,0,0); (0,0,0,0,5); (0,0,0,0,2.5); (0,0,0,0,1.25); (0,0,0,0,0.625); (0,0,0,0,0.3125); (0,0,0,0,0)]]; + ] + directive data [R33S175_PBadaiia_OD_proc_PBadAiia_Ara_C6C12] + directive crn { cells(growth,tlag) } +} +system control = { + directive simulation { final=36.0; points=250; plots=[[x]*[fp]+f0]; plotcolours=["#FF0000"]; multicore=True; sweeps=[sweep_R33S175_PBadaiia_dataset7] } + directive plot_settings { y_label = "RFP fluorescence (a.u.)" } + directive parameters [ + r = 1, { interval=Real; distribution=Uniform(0.1,10); variation=Multiple }; + K = 2, { interval=Real; distribution=Uniform(0.1,5); variation=Multiple }; + tlag = 1, { interval=Real; distribution=Uniform(0,10); variation=Multiple }; + rc=1e2, { distribution=Uniform(1e0,1e5); variation=Multiple }; + f0=100.0,{ interval=Real; distribution=Uniform(0.0,10000.0) }; + ] + directive rates [growth = [grow]*r*(1 - [x] / K);capacity = rc] + directive sweeps [ + sweep_R33S175_PBadaiia_dataset7 = [(EtOH,chlor,C6,C12,Ara) = [(0,0,25000,0,5); (0,0,25000,0,2.5); (0,0,25000,0,1.25); (0,0,25000,0,0.625); (0,0,25000,0,0.3125); (0,0,25000,0,0); (0,0,0,25000,5); (0,0,0,25000,2.5); (0,0,0,25000,1.25); (0,0,0,25000,0.625); (0,0,0,25000,0.3125); (0,0,0,25000,0); (0,0,5000,0,5); (0,0,5000,0,2.5); (0,0,5000,0,1.25); (0,0,5000,0,0.625); (0,0,5000,0,0.3125); (0,0,5000,0,0); (0,0,0,5000,5); (0,0,0,5000,2.5); (0,0,0,5000,1.25); (0,0,0,5000,0.625); (0,0,0,5000,0.3125); (0,0,0,5000,0); (0,0,1000,0,5); (0,0,1000,0,2.5); (0,0,1000,0,1.25); (0,0,1000,0,0.625); (0,0,1000,0,0.3125); (0,0,1000,0,0); (0,0,0,1000,5); (0,0,0,1000,2.5); (0,0,0,1000,1.25); (0,0,0,1000,0.625); (0,0,0,1000,0.3125); (0,0,0,1000,0); (0,0,200,0,5); (0,0,200,0,2.5); (0,0,200,0,1.25); (0,0,200,0,0.625); (0,0,200,0,0.3125); (0,0,200,0,0); (0,0,0,200,5); (0,0,0,200,2.5); (0,0,0,200,1.25); (0,0,0,200,0.625); (0,0,0,200,0.3125); (0,0,0,200,0); (0,0,40,0,5); (0,0,40,0,2.5); (0,0,40,0,1.25); (0,0,40,0,0.625); (0,0,40,0,0.3125); (0,0,40,0,0); (0,0,0,40,5); (0,0,0,40,2.5); (0,0,0,40,1.25); (0,0,0,40,0.625); (0,0,0,40,0.3125); (0,0,0,40,0); (0,0,8,0,5); (0,0,8,0,2.5); (0,0,8,0,1.25); (0,0,8,0,0.625); (0,0,8,0,0.3125); (0,0,8,0,0); (0,0,0,8,5); (0,0,0,8,2.5); (0,0,0,8,1.25); (0,0,0,8,0.625); (0,0,0,8,0.3125); (0,0,0,8,0); (0,0,1.6,0,5); (0,0,1.6,0,2.5); (0,0,1.6,0,1.25); (0,0,1.6,0,0.625); (0,0,1.6,0,0.3125); (0,0,1.6,0,0); (0,0,0,1.6,5); (0,0,0,1.6,2.5); (0,0,0,1.6,1.25); (0,0,0,1.6,0.625); (0,0,0,1.6,0.3125); (0,0,0,1.6,0); (0,0,0,0,5); (0,0,0,0,2.5); (0,0,0,0,1.25); (0,0,0,0,0.625); (0,0,0,0,0.3125); (0,0,0,0,0); (0,0,0,0,5); (0,0,0,0,2.5); (0,0,0,0,1.25); (0,0,0,0,0.625); (0,0,0,0,0.3125); (0,0,0,0,0)]]; + ] + directive data [R33S175_PBadaiia_mRFP1_proc_PBadAiia_Ara_C6C12] + directive crn { + cells(growth,tlag) + | fp ->[[growth]*[fp]] // Dilution + | ->[[capacity]] fp // Transcription/translation + | fp ->{dRFP} // Degradation + } +} + +system target = { + directive simulation { final=36.0; points=250; plots=[[x]*([yfp]+[f530])+yb0; [x]*([cfp]+[f480])+cb0]; plotcolours=["#FFDF00"; "#ADD8E6"] } + directive parameters [ + r = 1, { interval=Real; distribution=Uniform(0.1,10); variation=Multiple }; + K = 2, { interval=Real; distribution=Uniform(0.1,5); variation=Multiple }; + tlag = 1, { interval=Real; distribution=Uniform(0,10); variation=Multiple }; + rc=1e2, { distribution=Uniform(1e0,1e5); variation=Multiple }; + yb0=1e3, { interval=Real; distribution=Uniform(0.0,5e3) }; + cb0=1e3, { interval=Real; distribution=Uniform(0.0,1e4) }; + ] + directive rates [growth = [grow]*r*(1 - [x] / K);capacity = rc] + directive crn { cells(growth,tlag) | autofluorescence(growth,capacity) } +} + +system auto = { target with + directive simulation { final=36.0; points=250; plots=[[x]*[f530]+yb0; [x]*[f480]+cb0]; plotcolours=["#FFDF00"; "#ADD8E6"]; multicore=True; sweeps=[sweep_EC10G_dataset0] } + directive sweeps [ + sweep_EC10G_dataset0 = [(EtOH,chlor,C6,C12,Ara) = [(1700000000,0,0,0,0); (170000000,0,0,0,0); (17000000,0,0,0,0); (1700000,0,0,0,0); (170000,0,0,0,0); (17000,0,0,0,0); (1700,0,0,0,0); (170,0,0,0,0); (17,0,0,0,0); (1.7,0,0,0,0); (0.17,0,0,0,0); (0,0,0,0,0); (1700000000,0,0,0,0); (170000000,0,0,0,0); (17000000,0,0,0,0); (1700000,0,0,0,0); (170000,0,0,0,0); (17000,0,0,0,0); (1700,0,0,0,0); (170,0,0,0,0); (17,0,0,0,0); (1.7,0,0,0,0); (0.17,0,0,0,0); (0,0,0,0,0); (1700000000,0,0,0,0); (170000000,0,0,0,0); (17000000,0,0,0,0); (1700000,0,0,0,0); (170000,0,0,0,0); (17000,0,0,0,0); (1700,0,0,0,0); (170,0,0,0,0); (17,0,0,0,0); (1.7,0,0,0,0); (0.17,0,0,0,0); (0,0,0,0,0); (1700000000,0,0,0,0); (170000000,0,0,0,0); (17000000,0,0,0,0); (1700000,0,0,0,0); (170000,0,0,0,0); (17000,0,0,0,0); (1700,0,0,0,0); (170,0,0,0,0); (17,0,0,0,0); (1.7,0,0,0,0); (0.17,0,0,0,0); (0,0,0,0,0)]]; + ] + directive data [EC10G_EYFP_ECFP_proc_EC10G_EtOH] +} + +system prpr = { target with + directive simulation {multicore=True; sweeps=[sweep_PLPL_dataset1]} + directive parameters [ + r = 1, { interval=Real; distribution=Uniform(0.1,10); variation=Multiple }; + K = 2, { interval=Real; distribution=Uniform(0.1,5); variation=Multiple }; + tlag = 1, { interval=Real; distribution=Uniform(0,10); variation=Multiple }; + rc=1e2, { distribution=Uniform(1e0,1e5); variation=Multiple }; + aCFP=1e3, { distribution=Uniform(1e0,1e5); variation=Random }; + aYFP=1e3, { distribution=Uniform(1e0,1e5); variation=Random }; + yb0=1e3, { interval=Real; distribution=Uniform(0.0,5e3) }; + cb0=1e3, { interval=Real; distribution=Uniform(0.0,1e4) }; + ] + directive sweeps [ + sweep_PLPL_dataset1 = [(EtOH,chlor,C6,C12,Ara) = [(0,5,0,0,0); (0,5,0,0,0); (0,2.5,0,0,0); (0,2.5,0,0,0); (0,1.25,0,0,0); (0,1.25,0,0,0); (0,0.625,0,0,0); (0,0.625,0,0,0); (0,0.3125,0,0,0); (0,0.3125,0,0,0); (0,0,0,0,0); (0,0,0,0,0)]]; + ] + directive data [PLPL_EYFP_ECFP_proc_PLPL_Chlor] + prpr:device +} + +// DR (Pcat-Pcat) +system growth_PcatPcat = { growth with + directive simulation {multicore=True; sweeps=[sweep_Pcat_Y81C76_dataset4]} + directive sweeps [ + sweep_Pcat_Y81C76_dataset4 = [(EtOH,chlor,C6,C12,Ara) = [(0,0,25000,0,0); (0,0,8333.33333333333,0,0); (0,0,2777.77777777778,0,0); (0,0,925.925925925926,0,0); (0,0,308.641975308642,0,0); (0,0,102.880658436214,0,0); (0,0,34.2935528120713,0,0); (0,0,11.4311842706904,0,0); (0,0,3.81039475689681,0,0); (0,0,1.27013158563227,0,0); (0,0,0.423377195210757,0,0); (0,0,0,0,0); (0,0,0,25000,0); (0,0,0,8333.33333333333,0); (0,0,0,2777.77777777778,0); (0,0,0,925.925925925926,0); (0,0,0,308.641975308642,0); (0,0,0,102.880658436214,0); (0,0,0,34.2935528120713,0); (0,0,0,11.4311842706904,0); (0,0,0,3.81039475689681,0); (0,0,0,1.27013158563227,0); (0,0,0,0.423377195210757,0); (0,0,0,0,0); (0,0,25000,0,0); (0,0,8333.33333333333,0,0); (0,0,2777.77777777778,0,0); (0,0,925.925925925926,0,0); (0,0,308.641975308642,0,0); (0,0,102.880658436214,0,0); (0,0,34.2935528120713,0,0); (0,0,11.4311842706904,0,0); (0,0,3.81039475689681,0,0); (0,0,1.27013158563227,0,0); (0,0,0.423377195210757,0,0); (0,0,0,0,0); (0,0,0,25000,0); (0,0,0,8333.33333333333,0); (0,0,0,2777.77777777778,0); (0,0,0,925.925925925926,0); (0,0,0,308.641975308642,0); (0,0,0,102.880658436214,0); (0,0,0,34.2935528120713,0); (0,0,0,11.4311842706904,0); (0,0,0,3.81039475689681,0); (0,0,0,1.27013158563227,0); (0,0,0,0.423377195210757,0); (0,0,0,0,0)]]; + ] + directive data [Pcat_Y81C76_OD_proc141006] +} + +system control_PcatPcat = { control with + directive simulation {multicore=True; sweeps=[sweep_Pcat_Y81C76_dataset4]} + directive sweeps [ + sweep_Pcat_Y81C76_dataset4 = [(EtOH,chlor,C6,C12,Ara) = [(0,0,25000,0,0); (0,0,8333.33333333333,0,0); (0,0,2777.77777777778,0,0); (0,0,925.925925925926,0,0); (0,0,308.641975308642,0,0); (0,0,102.880658436214,0,0); (0,0,34.2935528120713,0,0); (0,0,11.4311842706904,0,0); (0,0,3.81039475689681,0,0); (0,0,1.27013158563227,0,0); (0,0,0.423377195210757,0,0); (0,0,0,0,0); (0,0,0,25000,0); (0,0,0,8333.33333333333,0); (0,0,0,2777.77777777778,0); (0,0,0,925.925925925926,0); (0,0,0,308.641975308642,0); (0,0,0,102.880658436214,0); (0,0,0,34.2935528120713,0); (0,0,0,11.4311842706904,0); (0,0,0,3.81039475689681,0); (0,0,0,1.27013158563227,0); (0,0,0,0.423377195210757,0); (0,0,0,0,0); (0,0,25000,0,0); (0,0,8333.33333333333,0,0); (0,0,2777.77777777778,0,0); (0,0,925.925925925926,0,0); (0,0,308.641975308642,0,0); (0,0,102.880658436214,0,0); (0,0,34.2935528120713,0,0); (0,0,11.4311842706904,0,0); (0,0,3.81039475689681,0,0); (0,0,1.27013158563227,0,0); (0,0,0.423377195210757,0,0); (0,0,0,0,0); (0,0,0,25000,0); (0,0,0,8333.33333333333,0); (0,0,0,2777.77777777778,0); (0,0,0,925.925925925926,0); (0,0,0,308.641975308642,0); (0,0,0,102.880658436214,0); (0,0,0,34.2935528120713,0); (0,0,0,11.4311842706904,0); (0,0,0,3.81039475689681,0); (0,0,0,1.27013158563227,0); (0,0,0,0.423377195210757,0); (0,0,0,0,0)]]; + ] + directive data [Pcat_Y81C76_mRFP1_proc141006] +} + +system dr_PcatPcat = { target with + directive simulation {multicore=True; sweeps=[sweep_Pcat_Y81C76_dataset4]} + directive sweeps [ + sweep_Pcat_Y81C76_dataset4 = [(EtOH,chlor,C6,C12,Ara) = [(0,0,25000,0,0); (0,0,8333.33333333333,0,0); (0,0,2777.77777777778,0,0); (0,0,925.925925925926,0,0); (0,0,308.641975308642,0,0); (0,0,102.880658436214,0,0); (0,0,34.2935528120713,0,0); (0,0,11.4311842706904,0,0); (0,0,3.81039475689681,0,0); (0,0,1.27013158563227,0,0); (0,0,0.423377195210757,0,0); (0,0,0,0,0); (0,0,0,25000,0); (0,0,0,8333.33333333333,0); (0,0,0,2777.77777777778,0); (0,0,0,925.925925925926,0); (0,0,0,308.641975308642,0); (0,0,0,102.880658436214,0); (0,0,0,34.2935528120713,0); (0,0,0,11.4311842706904,0); (0,0,0,3.81039475689681,0); (0,0,0,1.27013158563227,0); (0,0,0,0.423377195210757,0); (0,0,0,0,0); (0,0,25000,0,0); (0,0,8333.33333333333,0,0); (0,0,2777.77777777778,0,0); (0,0,925.925925925926,0,0); (0,0,308.641975308642,0,0); (0,0,102.880658436214,0,0); (0,0,34.2935528120713,0,0); (0,0,11.4311842706904,0,0); (0,0,3.81039475689681,0,0); (0,0,1.27013158563227,0,0); (0,0,0.423377195210757,0,0); (0,0,0,0,0); (0,0,0,25000,0); (0,0,0,8333.33333333333,0); (0,0,0,2777.77777777778,0); (0,0,0,925.925925925926,0); (0,0,0,308.641975308642,0); (0,0,0,102.880658436214,0); (0,0,0,34.2935528120713,0); (0,0,0,11.4311842706904,0); (0,0,0,3.81039475689681,0); (0,0,0,1.27013158563227,0); (0,0,0,0.423377195210757,0); (0,0,0,0,0)]]; + ] + directive data [Pcat_Y81C76_EYFP_ECFP_proc141006] + drPcat:device +} + +// DR (RS100-S32) +system growth_RS100S32 = { growth with + directive simulation {multicore=True; sweeps=[sweep_RS100S32_Y81C76_dataset3]} + directive sweeps [ + sweep_RS100S32_Y81C76_dataset3 = [(EtOH,chlor,C6,C12,Ara) = [(0,0,25000,0,0); (0,0,8333.33333333333,0,0); (0,0,2777.77777777778,0,0); (0,0,925.925925925926,0,0); (0,0,308.641975308642,0,0); (0,0,102.880658436214,0,0); (0,0,34.2935528120713,0,0); (0,0,11.4311842706904,0,0); (0,0,3.81039475689681,0,0); (0,0,1.27013158563227,0,0); (0,0,0.423377195210757,0,0); (0,0,0,0,0); (0,0,0,25000,0); (0,0,0,8333.33333333333,0); (0,0,0,2777.77777777778,0); (0,0,0,925.925925925926,0); (0,0,0,308.641975308642,0); (0,0,0,102.880658436214,0); (0,0,0,34.2935528120713,0); (0,0,0,11.4311842706904,0); (0,0,0,3.81039475689681,0); (0,0,0,1.27013158563227,0); (0,0,0,0.423377195210757,0); (0,0,0,0,0)]]; + ] + directive data [RS100S32_Y81C76_OD_proc140916] +} + +system control_RS100S32 = { control with + directive simulation {multicore=True; sweeps=[sweep_RS100S32_Y81C76_dataset3]} + directive sweeps [ + sweep_RS100S32_Y81C76_dataset3 = [(EtOH,chlor,C6,C12,Ara) = [(0,0,25000,0,0); (0,0,8333.33333333333,0,0); (0,0,2777.77777777778,0,0); (0,0,925.925925925926,0,0); (0,0,308.641975308642,0,0); (0,0,102.880658436214,0,0); (0,0,34.2935528120713,0,0); (0,0,11.4311842706904,0,0); (0,0,3.81039475689681,0,0); (0,0,1.27013158563227,0,0); (0,0,0.423377195210757,0,0); (0,0,0,0,0); (0,0,0,25000,0); (0,0,0,8333.33333333333,0); (0,0,0,2777.77777777778,0); (0,0,0,925.925925925926,0); (0,0,0,308.641975308642,0); (0,0,0,102.880658436214,0); (0,0,0,34.2935528120713,0); (0,0,0,11.4311842706904,0); (0,0,0,3.81039475689681,0); (0,0,0,1.27013158563227,0); (0,0,0,0.423377195210757,0); (0,0,0,0,0)]]; + ] + directive data [RS100S32_Y81C76_mRFP1_proc140916] +} + +system dr_RS100S32 = { target with + directive simulation {multicore=True; sweeps=[sweep_RS100S32_Y81C76_dataset3]} + directive sweeps [ + sweep_RS100S32_Y81C76_dataset3 = [(EtOH,chlor,C6,C12,Ara) = [(0,0,25000,0,0); (0,0,8333.33333333333,0,0); (0,0,2777.77777777778,0,0); (0,0,925.925925925926,0,0); (0,0,308.641975308642,0,0); (0,0,102.880658436214,0,0); (0,0,34.2935528120713,0,0); (0,0,11.4311842706904,0,0); (0,0,3.81039475689681,0,0); (0,0,1.27013158563227,0,0); (0,0,0.423377195210757,0,0); (0,0,0,0,0); (0,0,0,25000,0); (0,0,0,8333.33333333333,0); (0,0,0,2777.77777777778,0); (0,0,0,925.925925925926,0); (0,0,0,308.641975308642,0); (0,0,0,102.880658436214,0); (0,0,0,34.2935528120713,0); (0,0,0,11.4311842706904,0); (0,0,0,3.81039475689681,0); (0,0,0,1.27013158563227,0); (0,0,0,0.423377195210757,0); (0,0,0,0,0)]]; + ] + directive data [RS100S32_Y81C76_EYFP_ECFP_proc140916] + drRS100S32:device +} + +// DR (R33-S32) +system growth_R33S32 = { growth with + directive simulation {multicore=True; sweeps=[sweep_R33S32_Y81C76_dataset3]} + directive sweeps [ + sweep_R33S32_Y81C76_dataset3 = [(EtOH,chlor,C6,C12,Ara) = [(0,0,25000,0,0); (0,0,8333.33333333333,0,0); (0,0,2777.77777777778,0,0); (0,0,925.925925925926,0,0); (0,0,308.641975308642,0,0); (0,0,102.880658436214,0,0); (0,0,34.2935528120713,0,0); (0,0,11.4311842706904,0,0); (0,0,3.81039475689681,0,0); (0,0,1.27013158563227,0,0); (0,0,0.423377195210757,0,0); (0,0,0,0,0); (0,0,0,25000,0); (0,0,0,8333.33333333333,0); (0,0,0,2777.77777777778,0); (0,0,0,925.925925925926,0); (0,0,0,308.641975308642,0); (0,0,0,102.880658436214,0); (0,0,0,34.2935528120713,0); (0,0,0,11.4311842706904,0); (0,0,0,3.81039475689681,0); (0,0,0,1.27013158563227,0); (0,0,0,0.423377195210757,0); (0,0,0,0,0)]]; + ] + directive data [R33S32_Y81C76_OD_proc140916] +} + +system control_R33S32 = { control with + directive simulation {multicore=True; sweeps=[sweep_R33S32_Y81C76_dataset3]} + directive sweeps [ + sweep_R33S32_Y81C76_dataset3 = [(EtOH,chlor,C6,C12,Ara) = [(0,0,25000,0,0); (0,0,8333.33333333333,0,0); (0,0,2777.77777777778,0,0); (0,0,925.925925925926,0,0); (0,0,308.641975308642,0,0); (0,0,102.880658436214,0,0); (0,0,34.2935528120713,0,0); (0,0,11.4311842706904,0,0); (0,0,3.81039475689681,0,0); (0,0,1.27013158563227,0,0); (0,0,0.423377195210757,0,0); (0,0,0,0,0); (0,0,0,25000,0); (0,0,0,8333.33333333333,0); (0,0,0,2777.77777777778,0); (0,0,0,925.925925925926,0); (0,0,0,308.641975308642,0); (0,0,0,102.880658436214,0); (0,0,0,34.2935528120713,0); (0,0,0,11.4311842706904,0); (0,0,0,3.81039475689681,0); (0,0,0,1.27013158563227,0); (0,0,0,0.423377195210757,0); (0,0,0,0,0)]]; + ] + directive data [R33S32_Y81C76_mRFP1_proc140916] +} + +system dr_R33S32 = { target with + directive simulation {multicore=True; sweeps=[sweep_R33S32_Y81C76_dataset3]} + directive sweeps [ + sweep_R33S32_Y81C76_dataset3 = [(EtOH,chlor,C6,C12,Ara) = [(0,0,25000,0,0); (0,0,8333.33333333333,0,0); (0,0,2777.77777777778,0,0); (0,0,925.925925925926,0,0); (0,0,308.641975308642,0,0); (0,0,102.880658436214,0,0); (0,0,34.2935528120713,0,0); (0,0,11.4311842706904,0,0); (0,0,3.81039475689681,0,0); (0,0,1.27013158563227,0,0); (0,0,0.423377195210757,0,0); (0,0,0,0,0); (0,0,0,25000,0); (0,0,0,8333.33333333333,0); (0,0,0,2777.77777777778,0); (0,0,0,925.925925925926,0); (0,0,0,308.641975308642,0); (0,0,0,102.880658436214,0); (0,0,0,34.2935528120713,0); (0,0,0,11.4311842706904,0); (0,0,0,3.81039475689681,0); (0,0,0,1.27013158563227,0); (0,0,0,0.423377195210757,0); (0,0,0,0,0)]]; + ] + directive data [R33S32_Y81C76_EYFP_ECFP_proc140916] + drR33S32:device +} + +// DR (R33-S175) +system growth_R33S175 = { growth with + directive simulation {multicore=True; sweeps=[sweep_R33S175_Y81C76_dataset2]} + directive sweeps [ + sweep_R33S175_Y81C76_dataset2 = [(EtOH,chlor,C6,C12,Ara) = [(0,0,25000,0,0); (0,0,8333.33333333333,0,0); (0,0,2777.77777777778,0,0); (0,0,925.925925925926,0,0); (0,0,308.641975308642,0,0); (0,0,102.880658436214,0,0); (0,0,34.2935528120713,0,0); (0,0,11.4311842706904,0,0); (0,0,3.81039475689681,0,0); (0,0,1.27013158563227,0,0); (0,0,0.423377195210757,0,0); (0,0,0,0,0); (0,0,0,25000,0); (0,0,0,8333.33333333333,0); (0,0,0,2777.77777777778,0); (0,0,0,925.925925925926,0); (0,0,0,308.641975308642,0); (0,0,0,102.880658436214,0); (0,0,0,34.2935528120713,0); (0,0,0,11.4311842706904,0); (0,0,0,3.81039475689681,0); (0,0,0,1.27013158563227,0); (0,0,0,0.423377195210757,0); (0,0,0,0,0)]]; + ] + directive data [R33S175_Y81C76_OD_proc141021] +} + +system control_R33S175 = { control with + directive simulation {multicore=True; sweeps=[sweep_R33S175_Y81C76_dataset2]} + directive sweeps [ + sweep_R33S175_Y81C76_dataset2 = [(EtOH,chlor,C6,C12,Ara) = [(0,0,25000,0,0); (0,0,8333.33333333333,0,0); (0,0,2777.77777777778,0,0); (0,0,925.925925925926,0,0); (0,0,308.641975308642,0,0); (0,0,102.880658436214,0,0); (0,0,34.2935528120713,0,0); (0,0,11.4311842706904,0,0); (0,0,3.81039475689681,0,0); (0,0,1.27013158563227,0,0); (0,0,0.423377195210757,0,0); (0,0,0,0,0); (0,0,0,25000,0); (0,0,0,8333.33333333333,0); (0,0,0,2777.77777777778,0); (0,0,0,925.925925925926,0); (0,0,0,308.641975308642,0); (0,0,0,102.880658436214,0); (0,0,0,34.2935528120713,0); (0,0,0,11.4311842706904,0); (0,0,0,3.81039475689681,0); (0,0,0,1.27013158563227,0); (0,0,0,0.423377195210757,0); (0,0,0,0,0)]]; + ] + directive data [R33S175_Y81C76_mRFP1_proc141021] +} +system dr_R33S175 = { target with + directive simulation {multicore=True; sweeps=[sweep_R33S175_Y81C76_dataset2]} + directive sweeps [ + sweep_R33S175_Y81C76_dataset2 = [(EtOH,chlor,C6,C12,Ara) = [(0,0,25000,0,0); (0,0,8333.33333333333,0,0); (0,0,2777.77777777778,0,0); (0,0,925.925925925926,0,0); (0,0,308.641975308642,0,0); (0,0,102.880658436214,0,0); (0,0,34.2935528120713,0,0); (0,0,11.4311842706904,0,0); (0,0,3.81039475689681,0,0); (0,0,1.27013158563227,0,0); (0,0,0.423377195210757,0,0); (0,0,0,0,0); (0,0,0,25000,0); (0,0,0,8333.33333333333,0); (0,0,0,2777.77777777778,0); (0,0,0,925.925925925926,0); (0,0,0,308.641975308642,0); (0,0,0,102.880658436214,0); (0,0,0,34.2935528120713,0); (0,0,0,11.4311842706904,0); (0,0,0,3.81039475689681,0); (0,0,0,1.27013158563227,0); (0,0,0,0.423377195210757,0); (0,0,0,0,0)]]; + ] + directive data [R33S175_Y81C76_EYFP_ECFP_proc141021] + drR33S175:device +} + +// Timed additions circuit (for prediction) +system doublereceiverTimed = { dr_R33S175 with directive parameters [ sigma = 1.0 ] } + +// Relays +system growth_P76LasI = { growth with + directive simulation {multicore=True; sweeps=[sweep_R33S175DR_P76LasI_dataset5]} + directive sweeps [ + sweep_R33S175DR_P76LasI_dataset5 = [(EtOH,chlor,C6,C12,Ara) = [(0,0,25000,0,0); (0,0,8333.333333,0,0); (0,0,2777.777778,0,0); (0,0,925.925926,0,0); (0,0,308.641975,0,0); (0,0,102.880658,0,0); (0,0,34.293553,0,0); (0,0,11.431184,0,0); (0,0,3.810395,0,0); (0,0,1.270132,0,0); (0,0,0.423377,0,0); (0,0,0,0,0); (0,0,0,25000,0); (0,0,0,8333.333333,0); (0,0,0,2777.777778,0); (0,0,0,925.925926,0); (0,0,0,308.641975,0); (0,0,0,102.880658,0); (0,0,0,34.293553,0); (0,0,0,11.431184,0); (0,0,0,3.810395,0); (0,0,0,1.270132,0); (0,0,0,0.423377,0); (0,0,0,0,0); (0,0,25000,0,0); (0,0,8333.333333,0,0); (0,0,2777.777778,0,0); (0,0,925.925926,0,0); (0,0,308.641975,0,0); (0,0,102.880658,0,0); (0,0,34.293553,0,0); (0,0,11.431184,0,0); (0,0,3.810395,0,0); (0,0,1.270132,0,0); (0,0,0.423377,0,0); (0,0,0,0,0); (0,0,0,25000,0); (0,0,0,8333.333333,0); (0,0,0,2777.777778,0); (0,0,0,925.925926,0); (0,0,0,308.641975,0); (0,0,0,102.880658,0); (0,0,0,34.293553,0); (0,0,0,11.431184,0); (0,0,0,3.810395,0); (0,0,0,1.270132,0); (0,0,0,0.423377,0); (0,0,0,0,0)]]; + ] + directive data [R33S175DR_P76LasI_OD_proc_Relays_RemovedOutlier] +} + +system control_P76LasI = { control with + directive simulation {multicore=True; sweeps=[sweep_R33S175DR_P76LasI_dataset5]} + directive sweeps [ + sweep_R33S175DR_P76LasI_dataset5 = [(EtOH,chlor,C6,C12,Ara) = [(0,0,25000,0,0); (0,0,8333.333333,0,0); (0,0,2777.777778,0,0); (0,0,925.925926,0,0); (0,0,308.641975,0,0); (0,0,102.880658,0,0); (0,0,34.293553,0,0); (0,0,11.431184,0,0); (0,0,3.810395,0,0); (0,0,1.270132,0,0); (0,0,0.423377,0,0); (0,0,0,0,0); (0,0,0,25000,0); (0,0,0,8333.333333,0); (0,0,0,2777.777778,0); (0,0,0,925.925926,0); (0,0,0,308.641975,0); (0,0,0,102.880658,0); (0,0,0,34.293553,0); (0,0,0,11.431184,0); (0,0,0,3.810395,0); (0,0,0,1.270132,0); (0,0,0,0.423377,0); (0,0,0,0,0); (0,0,25000,0,0); (0,0,8333.333333,0,0); (0,0,2777.777778,0,0); (0,0,925.925926,0,0); (0,0,308.641975,0,0); (0,0,102.880658,0,0); (0,0,34.293553,0,0); (0,0,11.431184,0,0); (0,0,3.810395,0,0); (0,0,1.270132,0,0); (0,0,0.423377,0,0); (0,0,0,0,0); (0,0,0,25000,0); (0,0,0,8333.333333,0); (0,0,0,2777.777778,0); (0,0,0,925.925926,0); (0,0,0,308.641975,0); (0,0,0,102.880658,0); (0,0,0,34.293553,0); (0,0,0,11.431184,0); (0,0,0,3.810395,0); (0,0,0,1.270132,0); (0,0,0,0.423377,0); (0,0,0,0,0)]]; + ] + directive data [R33S175DR_P76LasI_mRFP1_proc_Relays_RemovedOutlier] +} +system relay_P76LasI = { dr_R33S175 with + directive simulation {multicore=True; sweeps=[sweep_R33S175DR_P76LasI_dataset5]} + directive sweeps [ + sweep_R33S175DR_P76LasI_dataset5 = [(EtOH,chlor,C6,C12,Ara) = [(0,0,25000,0,0); (0,0,8333.333333,0,0); (0,0,2777.777778,0,0); (0,0,925.925926,0,0); (0,0,308.641975,0,0); (0,0,102.880658,0,0); (0,0,34.293553,0,0); (0,0,11.431184,0,0); (0,0,3.810395,0,0); (0,0,1.270132,0,0); (0,0,0.423377,0,0); (0,0,0,0,0); (0,0,0,25000,0); (0,0,0,8333.333333,0); (0,0,0,2777.777778,0); (0,0,0,925.925926,0); (0,0,0,308.641975,0); (0,0,0,102.880658,0); (0,0,0,34.293553,0); (0,0,0,11.431184,0); (0,0,0,3.810395,0); (0,0,0,1.270132,0); (0,0,0,0.423377,0); (0,0,0,0,0); (0,0,25000,0,0); (0,0,8333.333333,0,0); (0,0,2777.777778,0,0); (0,0,925.925926,0,0); (0,0,308.641975,0,0); (0,0,102.880658,0,0); (0,0,34.293553,0,0); (0,0,11.431184,0,0); (0,0,3.810395,0,0); (0,0,1.270132,0,0); (0,0,0.423377,0,0); (0,0,0,0,0); (0,0,0,25000,0); (0,0,0,8333.333333,0); (0,0,0,2777.777778,0); (0,0,0,925.925926,0); (0,0,0,308.641975,0); (0,0,0,102.880658,0); (0,0,0,34.293553,0); (0,0,0,11.431184,0); (0,0,0,3.810395,0); (0,0,0,1.270132,0); (0,0,0,0.423377,0); (0,0,0,0,0)]]; + ] + directive data [R33S175DR_P76LasI_EYFP_ECFP_proc_Relays_RemovedOutlier] + relayP76LasI:device +} + +system growth_P81LuxI = { growth with + directive simulation {multicore=True; sweeps=[sweep_R33S175DR_P81LuxI_dataset5]} + directive sweeps [ + sweep_R33S175DR_P81LuxI_dataset5 = [(EtOH,chlor,C6,C12,Ara) = [(0,0,25000,0,0); (0,0,8333.333333,0,0); (0,0,2777.777778,0,0); (0,0,925.925926,0,0); (0,0,308.641975,0,0); (0,0,102.880658,0,0); (0,0,34.293553,0,0); (0,0,11.431184,0,0); (0,0,3.810395,0,0); (0,0,1.270132,0,0); (0,0,0.423377,0,0); (0,0,0,0,0); (0,0,0,25000,0); (0,0,0,8333.333333,0); (0,0,0,2777.777778,0); (0,0,0,925.925926,0); (0,0,0,308.641975,0); (0,0,0,102.880658,0); (0,0,0,34.293553,0); (0,0,0,11.431184,0); (0,0,0,3.810395,0); (0,0,0,1.270132,0); (0,0,0,0.423377,0); (0,0,0,0,0); (0,0,25000,0,0); (0,0,8333.333333,0,0); (0,0,2777.777778,0,0); (0,0,925.925926,0,0); (0,0,308.641975,0,0); (0,0,102.880658,0,0); (0,0,34.293553,0,0); (0,0,11.431184,0,0); (0,0,3.810395,0,0); (0,0,1.270132,0,0); (0,0,0.423377,0,0); (0,0,0,0,0); (0,0,0,25000,0); (0,0,0,8333.333333,0); (0,0,0,2777.777778,0); (0,0,0,925.925926,0); (0,0,0,308.641975,0); (0,0,0,102.880658,0); (0,0,0,34.293553,0); (0,0,0,11.431184,0); (0,0,0,3.810395,0); (0,0,0,1.270132,0); (0,0,0,0.423377,0); (0,0,0,0,0)]]; + ] + directive data [R33S175DR_P81LuxI_OD_proc_Relays_RemovedOutlier] +} + +system control_P81LuxI = { control with + directive simulation {multicore=True; sweeps=[sweep_R33S175DR_P81LuxI_dataset5]} + directive sweeps [ + sweep_R33S175DR_P81LuxI_dataset5 = [(EtOH,chlor,C6,C12,Ara) = [(0,0,25000,0,0); (0,0,8333.333333,0,0); (0,0,2777.777778,0,0); (0,0,925.925926,0,0); (0,0,308.641975,0,0); (0,0,102.880658,0,0); (0,0,34.293553,0,0); (0,0,11.431184,0,0); (0,0,3.810395,0,0); (0,0,1.270132,0,0); (0,0,0.423377,0,0); (0,0,0,0,0); (0,0,0,25000,0); (0,0,0,8333.333333,0); (0,0,0,2777.777778,0); (0,0,0,925.925926,0); (0,0,0,308.641975,0); (0,0,0,102.880658,0); (0,0,0,34.293553,0); (0,0,0,11.431184,0); (0,0,0,3.810395,0); (0,0,0,1.270132,0); (0,0,0,0.423377,0); (0,0,0,0,0); (0,0,25000,0,0); (0,0,8333.333333,0,0); (0,0,2777.777778,0,0); (0,0,925.925926,0,0); (0,0,308.641975,0,0); (0,0,102.880658,0,0); (0,0,34.293553,0,0); (0,0,11.431184,0,0); (0,0,3.810395,0,0); (0,0,1.270132,0,0); (0,0,0.423377,0,0); (0,0,0,0,0); (0,0,0,25000,0); (0,0,0,8333.333333,0); (0,0,0,2777.777778,0); (0,0,0,925.925926,0); (0,0,0,308.641975,0); (0,0,0,102.880658,0); (0,0,0,34.293553,0); (0,0,0,11.431184,0); (0,0,0,3.810395,0); (0,0,0,1.270132,0); (0,0,0,0.423377,0); (0,0,0,0,0)]]; + ] + directive data [R33S175DR_P81LuxI_mRFP1_proc_Relays_RemovedOutlier] +} +system relay_P81LuxI = { dr_R33S175 with + directive simulation {multicore=True; sweeps=[sweep_R33S175DR_P81LuxI_dataset5]} + directive sweeps [ + sweep_R33S175DR_P81LuxI_dataset5 = [(EtOH,chlor,C6,C12,Ara) = [(0,0,25000,0,0); (0,0,8333.333333,0,0); (0,0,2777.777778,0,0); (0,0,925.925926,0,0); (0,0,308.641975,0,0); (0,0,102.880658,0,0); (0,0,34.293553,0,0); (0,0,11.431184,0,0); (0,0,3.810395,0,0); (0,0,1.270132,0,0); (0,0,0.423377,0,0); (0,0,0,0,0); (0,0,0,25000,0); (0,0,0,8333.333333,0); (0,0,0,2777.777778,0); (0,0,0,925.925926,0); (0,0,0,308.641975,0); (0,0,0,102.880658,0); (0,0,0,34.293553,0); (0,0,0,11.431184,0); (0,0,0,3.810395,0); (0,0,0,1.270132,0); (0,0,0,0.423377,0); (0,0,0,0,0); (0,0,25000,0,0); (0,0,8333.333333,0,0); (0,0,2777.777778,0,0); (0,0,925.925926,0,0); (0,0,308.641975,0,0); (0,0,102.880658,0,0); (0,0,34.293553,0,0); (0,0,11.431184,0,0); (0,0,3.810395,0,0); (0,0,1.270132,0,0); (0,0,0.423377,0,0); (0,0,0,0,0); (0,0,0,25000,0); (0,0,0,8333.333333,0); (0,0,0,2777.777778,0); (0,0,0,925.925926,0); (0,0,0,308.641975,0); (0,0,0,102.880658,0); (0,0,0,34.293553,0); (0,0,0,11.431184,0); (0,0,0,3.810395,0); (0,0,0,1.270132,0); (0,0,0,0.423377,0); (0,0,0,0,0)]]; + ] + directive data [R33S175DR_P81LuxI_EYFP_ECFP_proc_Relays_RemovedOutlier] + relayP81LuxI:device +} + +// PBad +system pbad = { target with + directive simulation { final=36.0; points=250; plots=[[x]*([yfp]+[f530])+yb0]; plotcolours=["#FFDF00"]; multicore=True; sweeps=[sweep_PBad_eYFP_dataset6] } + directive parameters [ + r = 1, { interval=Real; distribution=Uniform(0.1,10); variation=Multiple }; + K = 2, { interval=Real; distribution=Uniform(0.1,5); variation=Multiple }; + tlag = 1, { interval=Real; distribution=Uniform(0,10); variation=Multiple }; + rc=1e2, { distribution=Uniform(1e0,1e5); variation=Multiple }; + aYFP=1.0, { distribution=Uniform(1e0,1e5) }; + yb0=1e3, { interval=Real; distribution=Uniform(0.0,5e3) }; + ] + directive sweeps [ + sweep_PBad_eYFP_dataset6 = [(EtOH,chlor,C6,C12,Ara) = [(0,0,0,0,25); (0,0,0,0,0.78); (0,0,0,0,12.5); (0,0,0,0,0.39); (0,0,0,0,6.25); (0,0,0,0,0.195); (0,0,0,0,3.125); (0,0,0,0,0.0975); (0,0,0,0,1.5625); (0,0,0,0,0.04875); (0,0,0,0,0.78125); (0,0,0,0,0.024375)]]; + ] + directive data [PBad_eYFP_EYFP_proc_PBadYFP] + pBadYFP:device +} + +// AiiA +system aiia = { dr_R33S175 with + directive simulation {multicore=True; sweeps=[sweep_R33S175_PBadaiia_dataset7]} + directive deterministic {reltolerance=1e-12; abstolerance=1e-10} + directive sweeps [ + sweep_R33S175_PBadaiia_dataset7 = [(EtOH,chlor,C6,C12,Ara) = [(0,0,25000,0,5); (0,0,25000,0,2.5); (0,0,25000,0,1.25); (0,0,25000,0,0.625); (0,0,25000,0,0.3125); (0,0,25000,0,0); (0,0,0,25000,5); (0,0,0,25000,2.5); (0,0,0,25000,1.25); (0,0,0,25000,0.625); (0,0,0,25000,0.3125); (0,0,0,25000,0); (0,0,5000,0,5); (0,0,5000,0,2.5); (0,0,5000,0,1.25); (0,0,5000,0,0.625); (0,0,5000,0,0.3125); (0,0,5000,0,0); (0,0,0,5000,5); (0,0,0,5000,2.5); (0,0,0,5000,1.25); (0,0,0,5000,0.625); (0,0,0,5000,0.3125); (0,0,0,5000,0); (0,0,1000,0,5); (0,0,1000,0,2.5); (0,0,1000,0,1.25); (0,0,1000,0,0.625); (0,0,1000,0,0.3125); (0,0,1000,0,0); (0,0,0,1000,5); (0,0,0,1000,2.5); (0,0,0,1000,1.25); (0,0,0,1000,0.625); (0,0,0,1000,0.3125); (0,0,0,1000,0); (0,0,200,0,5); (0,0,200,0,2.5); (0,0,200,0,1.25); (0,0,200,0,0.625); (0,0,200,0,0.3125); (0,0,200,0,0); (0,0,0,200,5); (0,0,0,200,2.5); (0,0,0,200,1.25); (0,0,0,200,0.625); (0,0,0,200,0.3125); (0,0,0,200,0); (0,0,40,0,5); (0,0,40,0,2.5); (0,0,40,0,1.25); (0,0,40,0,0.625); (0,0,40,0,0.3125); (0,0,40,0,0); (0,0,0,40,5); (0,0,0,40,2.5); (0,0,0,40,1.25); (0,0,0,40,0.625); (0,0,0,40,0.3125); (0,0,0,40,0); (0,0,8,0,5); (0,0,8,0,2.5); (0,0,8,0,1.25); (0,0,8,0,0.625); (0,0,8,0,0.3125); (0,0,8,0,0); (0,0,0,8,5); (0,0,0,8,2.5); (0,0,0,8,1.25); (0,0,0,8,0.625); (0,0,0,8,0.3125); (0,0,0,8,0); (0,0,1.6,0,5); (0,0,1.6,0,2.5); (0,0,1.6,0,1.25); (0,0,1.6,0,0.625); (0,0,1.6,0,0.3125); (0,0,1.6,0,0); (0,0,0,1.6,5); (0,0,0,1.6,2.5); (0,0,0,1.6,1.25); (0,0,0,1.6,0.625); (0,0,0,1.6,0.3125); (0,0,0,1.6,0); (0,0,0,0,5); (0,0,0,0,2.5); (0,0,0,0,1.25); (0,0,0,0,0.625); (0,0,0,0,0.3125); (0,0,0,0,0); (0,0,0,0,5); (0,0,0,0,2.5); (0,0,0,0,1.25); (0,0,0,0,0.625); (0,0,0,0,0.3125); (0,0,0,0,0)]]; + ] + directive data [R33S175_PBadaiia_EYFP_ECFP_proc_PBadAiia_Ara_C6C12] + | pBadAiiA:device +} + +// Auto +node Auto_Growth { systems = [growth]; inference = {partial=true} } +node Auto_Control { systems = [control]; inference = {partial=true} } +node Auto_Target { systems = [auto] } +edge Auto_Growth.growth ->[r=Fixed;K=Fixed;tlag=Fixed] Auto_Control.control +edge Auto_Control.control ->[r=Fixed;K=Fixed;tlag=Fixed;rc=Fixed] Auto_Target.auto + +// PRPR +node PRPR_Growth { systems = [growth]; inference = {partial=true} } +node PRPR_Control { systems = [control]; inference = {partial=true} } +node PRPR_Target { systems = [prpr] } +edge PRPR_Growth.growth ->[r=Fixed;K=Fixed;tlag=Fixed] PRPR_Control.control +edge PRPR_Control.control ->[r=Fixed;K=Fixed;tlag=Fixed;rc=Fixed] PRPR_Target.prpr +edge Auto_Control ->[dRFP] PRPR_Control +edge Auto_Target ->[autoYFP;autoCFP] PRPR_Target + +// DR +node DR_Growth { systems = [growth_PcatPcat; growth_RS100S32; growth_R33S32; growth_R33S175]; inference = {partial=true} } +node DR_Control { systems = [control_PcatPcat; control_RS100S32; control_R33S32; control_R33S175]; inference = {partial=true} } +node DR_Target { systems = [dr_PcatPcat; dr_RS100S32; dr_R33S32; dr_R33S175] } +edge DR_Growth.growth_PcatPcat ->[r=Fixed;K=Fixed;tlag=Fixed] DR_Control.control_PcatPcat +edge DR_Growth.growth_RS100S32 ->[r=Fixed;K=Fixed;tlag=Fixed] DR_Control.control_RS100S32 +edge DR_Growth.growth_R33S32 ->[r=Fixed;K=Fixed;tlag=Fixed] DR_Control.control_R33S32 +edge DR_Growth.growth_R33S175 ->[r=Fixed;K=Fixed;tlag=Fixed] DR_Control.control_R33S175 +edge DR_Control.control_PcatPcat ->[r=Fixed;K=Fixed;tlag=Fixed;rc=Fixed] DR_Target.dr_PcatPcat +edge DR_Control.control_RS100S32 ->[r=Fixed;K=Fixed;tlag=Fixed;rc=Fixed] DR_Target.dr_RS100S32 +edge DR_Control.control_R33S32 ->[r=Fixed;K=Fixed;tlag=Fixed;rc=Fixed] DR_Target.dr_R33S32 +edge DR_Control.control_R33S175 ->[r=Fixed;K=Fixed;tlag=Fixed;rc=Fixed] DR_Target.dr_R33S175 +edge PRPR_Control ->[dRFP] DR_Control +edge PRPR_Target ->[autoYFP; autoCFP; dYFP; dCFP] DR_Target + +// Relays +node Relays_Growth { systems = [growth_P76LasI; growth_P81LuxI]; inference = {partial=true} } +node Relays_Control { systems = [control_P76LasI; control_P81LuxI]; inference = {partial=true} } +node Relays_Target { systems = [relay_P76LasI; relay_P81LuxI] } +edge Relays_Growth.growth_P76LasI ->[r=Fixed;K=Fixed;tlag=Fixed] Relays_Control.control_P76LasI +edge Relays_Growth.growth_P81LuxI ->[r=Fixed;K=Fixed;tlag=Fixed] Relays_Control.control_P81LuxI +edge Relays_Control.control_P76LasI ->[r=Fixed;K=Fixed;tlag=Fixed;rc=Fixed] Relays_Target.relay_P76LasI +edge Relays_Control.control_P81LuxI ->[r=Fixed;K=Fixed;tlag=Fixed;rc=Fixed] Relays_Target.relay_P81LuxI +edge DR_Control ->[dRFP] Relays_Control +edge DR_Target ->[ + autoYFP;autoCFP;dYFP;dCFP; + aR33;aS175;aYFP;aCFP;e76;e81;KGR_76;KGS_76;KGR_81;KGS_81;KR6;KS6;KR12;KS12;nR;nS;dR; +] Relays_Target + +// PBad +node PBad_Growth { systems = [growth]; inference = {partial=true} } +node PBad_Control { systems = [control]; inference = {partial=true} } +node PBad_Target { systems = [pbad] } +edge PBad_Growth.growth ->[r=Fixed;K=Fixed;tlag=Fixed] PBad_Control.control +edge PBad_Control.control ->[r=Fixed;K=Fixed;tlag=Fixed;rc=Fixed] PBad_Target.pbad +edge PRPR_Control ->[dRFP] PBad_Control +edge PRPR_Target ->[autoYFP;dYFP] PBad_Target + +// AiiA +node AiiA_Growth { systems = [growth]; inference = {partial=true} } +node AiiA_Control { systems = [control]; inference = {partial=true} } +node AiiA_Target { systems = [aiia] } +edge AiiA_Growth.growth ->[r=Fixed;K=Fixed;tlag=Fixed] AiiA_Control.control +edge AiiA_Control.control ->[r=Fixed;K=Fixed;tlag=Fixed;rc=Fixed] AiiA_Target.aiia +edge DR_Control ->[dRFP] AiiA_Control +edge DR_Target ->[ + autoYFP;autoCFP;dYFP;dCFP; + aR33;aS175;aYFP;aCFP;e76;e81;KGR_76;KGS_76;KGR_81;KGS_81;KR6;KS6;KR12;KS12;nR;nS;dR; +] AiiA_Target +edge PBad_Target ->[KAra; nA; eA] AiiA_Target""" + +[] +let ``progBasicTest``() = + + let prog = basic_program + Debug.WriteLine(prog) + let testprog (s:string) = Parser.from_string Program.parse s + match testprog prog with + | ClassicGec gecprog -> + let crn_settings = Crn_settings.defaults.from_default_directive_list gecprog.settings.directives + Assert.Equal(crn_settings.simulation.final,100000.0) + Assert.Equal(crn_settings.simulation.points,1000) + match gecprog.prog with + | Ast.Seq(p1,brick) -> + match brick with + | Ast.Brick(Ast.WildCardVal,str,props) -> Assert.Equal(str,"ter") + | _ -> failwith "Unexpected Type found" + | _ -> + Debug.WriteLine("Error. Seq expected") + Assert.Equal(true,false) + Debug.WriteLine("End of Test") + | _ -> failwith "Unexpected Logic GEC program." + +[] +let ``progRepressilatorTest``() = + let progRepressilator = repressilator + + Debug.WriteLine(progRepressilator) + + let testprog (s:string) = Parser.from_string Program.parse s + let gecprog = testprog progRepressilator + + Debug.WriteLine("End of Test") + +[] +let ``progRepressilatorSimilarTest``()= + let progRepressilatorSimilar = repressilator_similar + + + Debug.WriteLine(progRepressilatorSimilar) + + let testprog (s:string) = Parser.from_string Program.parse s + let gecprog = testprog progRepressilatorSimilar + + Debug.WriteLine("End of Test") + +[] +let ``progRepressilatorModulesTest``()= + + let progRepressilatorModules = repressilator_modules + Debug.WriteLine(progRepressilatorModules) + let testprog (s:string) = Parser.from_string Program.parse s + let gecprog = testprog progRepressilatorModules + Debug.WriteLine("End of Test") + +[] +let ``progRepressilatorModuleSimilarTest``()= + + let progRepressilatorModuleSimilar = repressilator_modules_similar + Debug.WriteLine(progRepressilatorModuleSimilar) + let testprog (s:string) = Parser.from_string Program.parse s + let gecprog = testprog progRepressilatorModuleSimilar + Debug.WriteLine("End of Test") + +[] +let ``progReceiverDeviceTest``()= + + let progReceiverDevice = reciever_device + Debug.WriteLine(progReceiverDevice) + + let testprog (s:string) = Parser.from_string Program.parse s + let gecprog = testprog progReceiverDevice + + Debug.WriteLine("End of Test") + + + +[] +let ``progPredatorPreyTest``()= + + let progPredatorPrey = predator_prey + + Debug.WriteLine(progPredatorPrey) + + let testprog (s:string) = Parser.from_string Program.parse s + let gecprog = testprog progPredatorPrey + + Debug.WriteLine("End of Test") + +[] +let crnDirectiveProgTest() = + let progWithCrn = basic_crn + let testprog (s:string) = Parser.from_string Program.parse s + match testprog progWithCrn with + | ClassicGec gecprog -> + let crn_settings = Crn_settings.defaults.from_default_directive_list gecprog.settings.directives + Assert.Equal(crn_settings.simulation.final,100000.0) + Assert.False(gecprog.settings.overrideCrn) + let (moduledefs,instructions) = gecprog.settings.crn + Assert.Equal(moduledefs.Length,1) + Assert.Equal(instructions.Length,2) + | _ -> failwith "Unexpected Logic GEC program." + + + +[] +let ``progSandboxTest``()= + + let get_obj s = Parser.from_string Program.pInnerParallelContent s + + let str0 = "4 * x > 5" + let str1 = "b5:rbs;b1:ter" + let str2 = "a > 6" + let str3 = "m(a::g,6+C)" + let obj = get_obj str0 + let obj = get_obj str1 + let obj = get_obj str2 + let obj = get_obj str3 + + let str = "cell[signal] -> signal" + let reac = get_obj str + + let str4 = "a + b + c > t + 6 - g" + let reac4 = get_obj str4 + let str5 = "" + let reac5 = get_obj str5 + + let nilprog = Parser.from_string Program.parse_new_outer "" + + + () + +[] +let ``progBandDetectorTest``()= + + let progBandDetector = band_detector + + Debug.WriteLine(progBandDetector) + let testprog (s:string) = Parser.from_string Program.parse s + let gecprog = testprog progBandDetector + Debug.WriteLine("End of Test") + diff --git a/ClassicGEC/ClassicGECDotNetTests/transCrn.test.fs b/ClassicGEC/ClassicGECDotNetTests/transCrn.test.fs new file mode 100644 index 0000000..84465a5 --- /dev/null +++ b/ClassicGEC/ClassicGECDotNetTests/transCrn.test.fs @@ -0,0 +1,200 @@ +module Microsoft.Research.GEC.TransCrnTest + +open Microsoft.Research.GEC.GECEngine +open Microsoft.Research.GEC.JSAPI +open Microsoft.Research.GEC.TransCrn +open Microsoft.Research.CRNEngine +open Xunit +open FsUnit.Xunit +open System.Xml +open System.Diagnostics +open Parser +open FSBOL + + + +let databaseText = """i723017,pcr,codes(xylR;0.001) +i723024,pcr,codes(phzM;0.001) +e0040,pcr,codes(gfp;0.01) +c0099,pcr,codes(cviR;0.01) +i723025,pcr,codes(phzS;0.001) +i723028,pcr,codes(pca;0.001) +c0051,pcr,codes(cI;0.01) +c0040,pcr,codes(tetR;0.01) +c0080,pcr,codes(araC;0.01) +c0012,pcr,codes(lacI;0.01) +cunknown2,pcr,codes(unknown2;0.001) +c0061,pcr,codes(luxI;0.01) +c0062,pcr,codes(luxR;0.01) +c0079,pcr,codes(lasR;0.01) +c0078,pcr,codes(lasI;0.01) +cunknown3,pcr,codes(ccdB;0.005) +cunknown4,pcr,codes(ccdA;0.1) +i723020,prom,pos(toluene::xylR;0.001;0.001;1.0);con(0.0001) +r0051,prom,neg(cI;1.0;0.5;0.00005);con(0.12) +r0040,prom,neg(tetR;1.0;0.5;0.00005);con(0.09) +runknown1,prom,neg(unknown1;1.0;0.005;0.001);con(0.04) +r0080,prom,neg(araC;1.0;0.000001;0.0001);pos(araC::arabinose;0.001;0.001;1.0);con(0.1) +r0011,prom,neg(lacI;1.0;0.5;0.00005);con(0.1) +r0062,prom,pos(lasR::m3OC12HSL;1.0;0.8;0.1);pos(luxR::m3OC6HSL;1.0;0.8;0.1);con(0.01) +r0090,prom,pos(lasR::m3OC12HSL;1.0;0.8;0.1);con(0.01) +r0099,prom,pos(cviR::m3OC6HSL;1.0;0.8;0.1);con(0.01) +b0034,rbs,rate(0.1) +b0015,ter +cunknown5,pcr,codes(ccdA2;10.0) +runknown5,prom,con(10.0) +j06504,pcr,codes(mCherry;0.1) +prpr,device,components[pr;rbs34;eyfp;ter1;pr;rbs34;ecfp;ter1] +drPcat,device,components[pCat;rbs34;luxR;rbs34;lasR;ter1;pLas81;rbs34;eyfp;ter1;plux76;rbs34;ecfp;ter1] +drRS100S32,device,components[pTet;rbss100;luxR;ter1;pLac;rbs32;lasR;ter1;pLas81;rbs34;eyfp;ter1;plux76;rbs34;ecfp;ter1] +drR33S32,device,components[pTet;rbs33;luxR;ter1;pLac;rbs32;lasR;ter1;pLas81;rbs34;eyfp;ter1;plux76;rbs34;ecfp;ter1] +drR33S175,device,components[pTet;rbs33;luxR;ter1;pLac;rbsS175;lasR;ter1;pLas81;rbs34;eyfp;ter1;plux76;rbs34;ecfp;ter1] +relayP76LasI,device,components[pLux76;rbs900;lasI;l3s2p21] +relayP81LuxI,device,components[pLas81;rbs32;luxI;l3s2p21] +pBadYFP,device,components[pBad;rbs34;eyfp;l3s2p21] +lactonase,device,components[pBad;rbs34;aiia;l3s2p21]""" + +let reactions = """toluene + xylR ->{1.0} toluene::xylR +phzM ~ pca ->{1.0} metPCA +phzS ~ metPCA ->{1.0} pyo +luxR + m3OC6HSL ->{0.5} luxR::m3OC6HSL +lasR + m3OC12HSL ->{0.5} lasR::m3OC12HSL +cviR + m3OC6HSL ->{0.5} cviR::m3OC6HSL +cviR + m3OC12HSL ->{0.5} cviR::m3OC12HSL +luxI ~ ->{1.0} m3OC6HSL +lasI ~ ->{1.0} m3OC12HSL +ccdA ~ ccdB ->{1.0} +c[m3OC6HSL] ->{0.5} m3OC6HSL +m3OC6HSL ->{0.5} c[m3OC6HSL] +c[m3OC12HSL] ->{0.5} m3OC12HSL +m3OC12HSL ->{0.5} c[m3OC12HSL] +luxR::m3OC6HSL ->{1.0} luxR + m3OC6HSL +cviR::m3OC6HSL ->{1.0} cviR + m3OC6HSL +cviR::m3OC12HSL ->{1.0} cviR + m3OC12HSL +lasR::m3OC12HSL ->{1.0} lasR + m3OC12HSL +ccdA2 ~ ccdB ->{0.00001} +lacI + iptg ->{1.0} lacI::iptg +tetR + aTc ->{1.0} tetR::aTc""" + + + +[] +let constantRatiometricTest() = + System.Threading.Thread.CurrentThread.CurrentCulture <- System.Globalization.CultureInfo.InvariantCulture + let (cancel_flag: bool ref) = ref false + + let devices = """device prpr() = { cells() | autofluorescence() | YFP(aYFP) | CFP(aCFP) } +device drPcat() = { cells() | autofluorescence() | LuxR(1.0) | LasR(1.0) | YFP(P81,aYFP) | CFP(P76,aCFP) } +device drRS100S32() = { cells() | autofluorescence() | LuxR(aRS100) | LasR(aS32) | YFP(P81,aYFP) | CFP(P76,aCFP) } +device drR33S32() = { cells() | autofluorescence() | LuxR(aR33) | LasR(aS32) | YFP(P81,aYFP) | CFP(P76,aCFP) } +device drR33S175() = { cells() | autofluorescence() | LuxR(aR33) | LasR(aS175) | YFP(P81,aYFP) | CFP(P76,aCFP) } +device relayP76LasI() = { cells() | autofluorescence() | LuxR(aR33) | LasR(aS175) | LasI(P76) | YFP(P81,aYFP) | CFP(P76,aCFP) } +device relayP81LuxI() = { cells() | autofluorescence() | LuxR(aR33) | LasR(aS175) | LuxI(P81) | YFP(P81,aYFP) | CFP(P76,aCFP) } +device pBadYFP() = { cells() | autofluorescence() | YFP(PBad,aYFP) } +device lactonase() = { cells() | autofluorescence() | LuxR(aR33) | LasR(aS175) | AiiA(PBad,1.0) | YFP(P81,aYFP) | CFP(P76,aCFP)} +""" + + let d = Parser.from_string (Parser.many Program.parse_device) devices + let prog = Parser.from_string Program.parse ProgramParserTest.constant_ratiometric + + let basicsolution = GECEngine.solveGEC cancel_flag ProgramParserTest.constant_ratiometric databaseText reactions + (*match basicsolution.solution.solution with + |Some(_,sol,_,_,_) -> Assert.Equal(4,sol.numSolutions) + | _ -> failwith "Error in solving basic program"*) + + () + +[] +let gecSolutionCount() = + + let db_from_string (s:string) = Parser.from_string Database.parse s + let partstable = db_from_string databaseText + + let reactionListParser = Parser.sepBy Gecreaction.parseReaction Parser.newline + let reactiondb_from_string (s:string) = Parser.from_string reactionListParser s + + let createReactionEntry reaction = + let (reactionEntry:Gecreaction.t Database.entry) ={value=reaction;enabled=true;comments=""} + reactionEntry + + let reactiondb = reactiondb_from_string reactions |> List.map (fun(x) -> createReactionEntry(x)) + + let table = {partstable with reactions = reactiondb} + + let (cancel_flag: bool ref) = ref false + + //basic + //repressilator + //repressilatorSimilar + //repressilatorModules + //repressilatorModulesSimilar + //receiverDevice + //predatorPrey + //bandDetector + + let basicsolution = GECEngine.solveGEC cancel_flag ProgramParserTest.basic_program databaseText reactions + match basicsolution.solution.solution with + |Some(_,sol,_,_,_) -> Assert.Equal(4,sol.numSolutions) + | _ -> failwith "Error in solving basic program" + + + let repressilatorsolution = GECEngine.solveGEC cancel_flag ProgramParserTest.repressilator databaseText reactions + match repressilatorsolution.solution.solution with + | Some(_,sol,_,_,_) -> Assert.Equal(24,sol.numSolutions) + | _ -> failwith "Error in solving repressilator program" + + let repressilatorSimilarsolution = GECEngine.solveGEC cancel_flag ProgramParserTest.repressilator_similar databaseText reactions + match repressilatorSimilarsolution.solution.solution with + | Some(_,sol,_,_,_) -> Assert.Equal(6,sol.numSolutions) + | _ -> failwith "Error in solving repressilator Similar program" + + let repressilatorModulessolution = GECEngine.solveGEC cancel_flag ProgramParserTest.repressilator_modules databaseText reactions + match repressilatorModulessolution.solution.solution with + | Some(_,sol,_,_,_) -> Assert.Equal(24,sol.numSolutions) + | _ -> failwith "Error in solving repressilator Modules program" + + let repressilatorModulesSimilarsolution = GECEngine.solveGEC cancel_flag ProgramParserTest.repressilator_similar databaseText reactions + match repressilatorModulesSimilarsolution.solution.solution with + | Some(_,sol,_,_,_) -> Assert.Equal(6,sol.numSolutions) + | _ -> failwith "Error in solving repressilator Modules similar program" + + let receiverDevicesolution = GECEngine.solveGEC cancel_flag ProgramParserTest.reciever_device databaseText reactions + match receiverDevicesolution.solution.solution with + | Some(_,sol,_,_,_) -> Assert.Equal(34,sol.numSolutions) + | _ -> failwith "Error in solving receiver Device program" + + let predatorPreysolution = GECEngine.solveGEC cancel_flag ProgramParserTest.predator_prey databaseText reactions + match predatorPreysolution.solution.solution with + | Some(_,sol,_,_,_) -> Assert.Equal(16,sol.numSolutions) + | _ -> failwith "Error in solving predator-Prey program" + + let bandDetectorsolution = GECEngine.solveGEC cancel_flag ProgramParserTest.band_detector databaseText reactions + match bandDetectorsolution.solution.solution with + | Some(_,sol,_,_,_) -> Assert.Equal(1,sol.numSolutions) + | _ -> failwith "Error in solving band Detector program" + + Debug.WriteLine("End of test") + + + +[] +let ``CrnTemplateTest_JSAPI_AbstractCRN``() = + let prog = ProgramParserTest.basic_program + match Microsoft.Research.GEC.JSAPI.compile prog databaseText reactions with + | (ClassicGEC solve_result) as sr -> + let crngec = solve_result.model.nodes |> Map.toSeq |> Seq.head |> snd + (*let crngec = + match solve_result.model with + | CRNgui(x) -> x*) + + let validateReaction (r:Reaction) = + let validateSpecies sp = List.exists (fun (i:Initial) -> i.species = sp) crngec.top.initials |> Assert.True + List.iter validateSpecies (Mset.elements r.reactants) + List.iter validateSpecies (Mset.elements r.products) + List.iter validateSpecies (Mset.elements r.catalysts) + List.iter validateReaction crngec.top.reactions + let crn = crngec.top.to_crn() + let solution_result = Microsoft.Research.GEC.JSAPI.get_solution sr 1 + let crn = crngec.top.to_crn() + Debug.WriteLine("End of test") + | LogicGEC _ -> failwith "Unexpected Logic GEC program." \ No newline at end of file diff --git a/ClassicGEC/ClassicGECHTML.sln b/ClassicGEC/ClassicGECHTML.sln new file mode 100644 index 0000000..adea7a4 --- /dev/null +++ b/ClassicGEC/ClassicGECHTML.sln @@ -0,0 +1,227 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29709.97 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MSAGL_JS", "..\HTML5SharedGUI\MSAGL_JS\MSAGL_JS.csproj", "{2F3B8603-CFF1-4946-B242-6F848801B49A}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CodeEditor", "..\HTML5SharedGUI\CodeEditor\CodeEditor.csproj", "{B234C1D7-96F4-40A2-A323-3B18646BF95C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CRNComponent", "..\HTML5SharedGUI\CRNComponent\CRNComponent.csproj", "{6DF7A0C1-2048-4A51-8599-E1C0B958A5E2}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InferenceViewer", "..\HTML5SharedGUI\InferenceViewer\InferenceViewer.csproj", "{179FDF3E-67B8-4E2F-9089-650BB1319AF2}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SimulationViewer", "..\HTML5SharedGUI\SimulationViewer\SimulationViewer.csproj", "{0ECCE305-85C0-403F-A980-EEB9379BD5A4}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "CRNEngineJS", "..\CRNEngine\CRNEngineJS\CRNEngineJS.fsproj", "{836AF075-6448-4CD9-8020-434B963FF5E2}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "Filzbach.FSharp.JS", "..\Filzbach.FSharp.JS\Filzbach.FSharp.JS.fsproj", "{4DF94589-6870-4A4C-BFAE-5825EF4634E7}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "ParserCombinatorsJS", "..\ParserCombinators\ParserCombinatorsJS\ParserCombinatorsJS.fsproj", "{2EED2DFA-7D94-4E12-ADC5-455FC9F85BF9}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CRNEngineTSWrapper", "..\CRNEngine\CRNEngineTSWrapper\CRNEngineTSWrapper.csproj", "{FB1F1936-AC22-41B4-AF2F-E20A486E3416}" + ProjectSection(ProjectDependencies) = postProject + {836AF075-6448-4CD9-8020-434B963FF5E2} = {836AF075-6448-4CD9-8020-434B963FF5E2} + EndProjectSection +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "ReactionDiffusionJS", "..\PDESolvers\ReactionDiffusionJS\ReactionDiffusionJS.fsproj", "{1CF4EE5A-8217-4D9A-89DE-55F8D01ACD40}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "ClassicGECJS", "ClassicGECJS\ClassicGECJS.fsproj", "{512586EF-5357-49E1-A5A0-71B4389589A2}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClassicGECTSWrapper", "ClassicGECTSWrapper\ClassicGECTSWrapper.csproj", "{A7A666E0-2ADE-4496-A84A-267BBE68B5A1}" + ProjectSection(ProjectDependencies) = postProject + {FB1F1936-AC22-41B4-AF2F-E20A486E3416} = {FB1F1936-AC22-41B4-AF2F-E20A486E3416} + {836AF075-6448-4CD9-8020-434B963FF5E2} = {836AF075-6448-4CD9-8020-434B963FF5E2} + {512586EF-5357-49E1-A5A0-71B4389589A2} = {512586EF-5357-49E1-A5A0-71B4389589A2} + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClassicGECHTML5", "ClassicGECHTML5\ClassicGECHTML5.csproj", "{CBC756D7-8BB7-4CEC-95C7-FDB9363BAC63}" + ProjectSection(ProjectDependencies) = postProject + {A7A666E0-2ADE-4496-A84A-267BBE68B5A1} = {A7A666E0-2ADE-4496-A84A-267BBE68B5A1} + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClassicGECTSWrapper_Samples", "ClassicGECTSWrapper_Samples\ClassicGECTSWrapper_Samples.csproj", "{2574F603-4B6C-4A30-BFDD-E3BC09EEDFDF}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HTML5CRN_Lib", "..\HTML5SharedGUI\HTML5CRN_Lib\HTML5CRN_Lib.csproj", "{B4C3F008-B6CA-4D63-9B98-6AC2D97B4E9B}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSBOLWrapperJS", "..\FSBOLWrapper\FSBOLWrapperJS\FSBOLWrapperJS.fsproj", "{4A5FC975-B3C1-4C89-967A-A146DED20962}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "ClassicGECBrowserIntegrationTests", "ClassicGECBrowserIntegrationTests\ClassicGECBrowserIntegrationTests.fsproj", "{8B8E819B-1BA1-4559-BE26-FF0215614921}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GenericComponents", "..\HTML5SharedGUI\GenericComponents\GenericComponents.csproj", "{4CD88A62-7023-4216-B37F-02FD6AF0595F}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "CRNIntegrationTestLib", "..\CRNEngine\CRNIntegrationTestLib\CRNIntegrationTestLib.fsproj", "{37984538-A573-4A89-9EA7-AEAF95D2806A}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "RulesDSDJS", "..\RulesDSD\RulesDSDJS\RulesDSDJS.fsproj", "{1203D047-DFC7-4F75-B232-F5F1479DF687}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2F3B8603-CFF1-4946-B242-6F848801B49A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2F3B8603-CFF1-4946-B242-6F848801B49A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2F3B8603-CFF1-4946-B242-6F848801B49A}.Debug|x64.ActiveCfg = Debug|Any CPU + {2F3B8603-CFF1-4946-B242-6F848801B49A}.Debug|x64.Build.0 = Debug|Any CPU + {2F3B8603-CFF1-4946-B242-6F848801B49A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2F3B8603-CFF1-4946-B242-6F848801B49A}.Release|Any CPU.Build.0 = Release|Any CPU + {2F3B8603-CFF1-4946-B242-6F848801B49A}.Release|x64.ActiveCfg = Release|Any CPU + {2F3B8603-CFF1-4946-B242-6F848801B49A}.Release|x64.Build.0 = Release|Any CPU + {B234C1D7-96F4-40A2-A323-3B18646BF95C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B234C1D7-96F4-40A2-A323-3B18646BF95C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B234C1D7-96F4-40A2-A323-3B18646BF95C}.Debug|x64.ActiveCfg = Debug|Any CPU + {B234C1D7-96F4-40A2-A323-3B18646BF95C}.Debug|x64.Build.0 = Debug|Any CPU + {B234C1D7-96F4-40A2-A323-3B18646BF95C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B234C1D7-96F4-40A2-A323-3B18646BF95C}.Release|Any CPU.Build.0 = Release|Any CPU + {B234C1D7-96F4-40A2-A323-3B18646BF95C}.Release|x64.ActiveCfg = Release|Any CPU + {B234C1D7-96F4-40A2-A323-3B18646BF95C}.Release|x64.Build.0 = Release|Any CPU + {6DF7A0C1-2048-4A51-8599-E1C0B958A5E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6DF7A0C1-2048-4A51-8599-E1C0B958A5E2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6DF7A0C1-2048-4A51-8599-E1C0B958A5E2}.Debug|x64.ActiveCfg = Debug|Any CPU + {6DF7A0C1-2048-4A51-8599-E1C0B958A5E2}.Debug|x64.Build.0 = Debug|Any CPU + {6DF7A0C1-2048-4A51-8599-E1C0B958A5E2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6DF7A0C1-2048-4A51-8599-E1C0B958A5E2}.Release|Any CPU.Build.0 = Release|Any CPU + {6DF7A0C1-2048-4A51-8599-E1C0B958A5E2}.Release|x64.ActiveCfg = Release|Any CPU + {6DF7A0C1-2048-4A51-8599-E1C0B958A5E2}.Release|x64.Build.0 = Release|Any CPU + {179FDF3E-67B8-4E2F-9089-650BB1319AF2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {179FDF3E-67B8-4E2F-9089-650BB1319AF2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {179FDF3E-67B8-4E2F-9089-650BB1319AF2}.Debug|x64.ActiveCfg = Debug|Any CPU + {179FDF3E-67B8-4E2F-9089-650BB1319AF2}.Debug|x64.Build.0 = Debug|Any CPU + {179FDF3E-67B8-4E2F-9089-650BB1319AF2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {179FDF3E-67B8-4E2F-9089-650BB1319AF2}.Release|Any CPU.Build.0 = Release|Any CPU + {179FDF3E-67B8-4E2F-9089-650BB1319AF2}.Release|x64.ActiveCfg = Release|Any CPU + {179FDF3E-67B8-4E2F-9089-650BB1319AF2}.Release|x64.Build.0 = Release|Any CPU + {0ECCE305-85C0-403F-A980-EEB9379BD5A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0ECCE305-85C0-403F-A980-EEB9379BD5A4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0ECCE305-85C0-403F-A980-EEB9379BD5A4}.Debug|x64.ActiveCfg = Debug|Any CPU + {0ECCE305-85C0-403F-A980-EEB9379BD5A4}.Debug|x64.Build.0 = Debug|Any CPU + {0ECCE305-85C0-403F-A980-EEB9379BD5A4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0ECCE305-85C0-403F-A980-EEB9379BD5A4}.Release|Any CPU.Build.0 = Release|Any CPU + {0ECCE305-85C0-403F-A980-EEB9379BD5A4}.Release|x64.ActiveCfg = Release|Any CPU + {0ECCE305-85C0-403F-A980-EEB9379BD5A4}.Release|x64.Build.0 = Release|Any CPU + {836AF075-6448-4CD9-8020-434B963FF5E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {836AF075-6448-4CD9-8020-434B963FF5E2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {836AF075-6448-4CD9-8020-434B963FF5E2}.Debug|x64.ActiveCfg = Debug|Any CPU + {836AF075-6448-4CD9-8020-434B963FF5E2}.Debug|x64.Build.0 = Debug|Any CPU + {836AF075-6448-4CD9-8020-434B963FF5E2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {836AF075-6448-4CD9-8020-434B963FF5E2}.Release|Any CPU.Build.0 = Release|Any CPU + {836AF075-6448-4CD9-8020-434B963FF5E2}.Release|x64.ActiveCfg = Release|Any CPU + {836AF075-6448-4CD9-8020-434B963FF5E2}.Release|x64.Build.0 = Release|Any CPU + {4DF94589-6870-4A4C-BFAE-5825EF4634E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4DF94589-6870-4A4C-BFAE-5825EF4634E7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4DF94589-6870-4A4C-BFAE-5825EF4634E7}.Debug|x64.ActiveCfg = Debug|Any CPU + {4DF94589-6870-4A4C-BFAE-5825EF4634E7}.Debug|x64.Build.0 = Debug|Any CPU + {4DF94589-6870-4A4C-BFAE-5825EF4634E7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4DF94589-6870-4A4C-BFAE-5825EF4634E7}.Release|Any CPU.Build.0 = Release|Any CPU + {4DF94589-6870-4A4C-BFAE-5825EF4634E7}.Release|x64.ActiveCfg = Release|Any CPU + {4DF94589-6870-4A4C-BFAE-5825EF4634E7}.Release|x64.Build.0 = Release|Any CPU + {2EED2DFA-7D94-4E12-ADC5-455FC9F85BF9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2EED2DFA-7D94-4E12-ADC5-455FC9F85BF9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2EED2DFA-7D94-4E12-ADC5-455FC9F85BF9}.Debug|x64.ActiveCfg = Debug|Any CPU + {2EED2DFA-7D94-4E12-ADC5-455FC9F85BF9}.Debug|x64.Build.0 = Debug|Any CPU + {2EED2DFA-7D94-4E12-ADC5-455FC9F85BF9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2EED2DFA-7D94-4E12-ADC5-455FC9F85BF9}.Release|Any CPU.Build.0 = Release|Any CPU + {2EED2DFA-7D94-4E12-ADC5-455FC9F85BF9}.Release|x64.ActiveCfg = Release|Any CPU + {2EED2DFA-7D94-4E12-ADC5-455FC9F85BF9}.Release|x64.Build.0 = Release|Any CPU + {FB1F1936-AC22-41B4-AF2F-E20A486E3416}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FB1F1936-AC22-41B4-AF2F-E20A486E3416}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FB1F1936-AC22-41B4-AF2F-E20A486E3416}.Debug|x64.ActiveCfg = Debug|Any CPU + {FB1F1936-AC22-41B4-AF2F-E20A486E3416}.Debug|x64.Build.0 = Debug|Any CPU + {FB1F1936-AC22-41B4-AF2F-E20A486E3416}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FB1F1936-AC22-41B4-AF2F-E20A486E3416}.Release|Any CPU.Build.0 = Release|Any CPU + {FB1F1936-AC22-41B4-AF2F-E20A486E3416}.Release|x64.ActiveCfg = Release|Any CPU + {FB1F1936-AC22-41B4-AF2F-E20A486E3416}.Release|x64.Build.0 = Release|Any CPU + {1CF4EE5A-8217-4D9A-89DE-55F8D01ACD40}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1CF4EE5A-8217-4D9A-89DE-55F8D01ACD40}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1CF4EE5A-8217-4D9A-89DE-55F8D01ACD40}.Debug|x64.ActiveCfg = Debug|Any CPU + {1CF4EE5A-8217-4D9A-89DE-55F8D01ACD40}.Debug|x64.Build.0 = Debug|Any CPU + {1CF4EE5A-8217-4D9A-89DE-55F8D01ACD40}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1CF4EE5A-8217-4D9A-89DE-55F8D01ACD40}.Release|Any CPU.Build.0 = Release|Any CPU + {1CF4EE5A-8217-4D9A-89DE-55F8D01ACD40}.Release|x64.ActiveCfg = Release|Any CPU + {1CF4EE5A-8217-4D9A-89DE-55F8D01ACD40}.Release|x64.Build.0 = Release|Any CPU + {512586EF-5357-49E1-A5A0-71B4389589A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {512586EF-5357-49E1-A5A0-71B4389589A2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {512586EF-5357-49E1-A5A0-71B4389589A2}.Debug|x64.ActiveCfg = Debug|Any CPU + {512586EF-5357-49E1-A5A0-71B4389589A2}.Debug|x64.Build.0 = Debug|Any CPU + {512586EF-5357-49E1-A5A0-71B4389589A2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {512586EF-5357-49E1-A5A0-71B4389589A2}.Release|Any CPU.Build.0 = Release|Any CPU + {512586EF-5357-49E1-A5A0-71B4389589A2}.Release|x64.ActiveCfg = Release|Any CPU + {512586EF-5357-49E1-A5A0-71B4389589A2}.Release|x64.Build.0 = Release|Any CPU + {A7A666E0-2ADE-4496-A84A-267BBE68B5A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A7A666E0-2ADE-4496-A84A-267BBE68B5A1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A7A666E0-2ADE-4496-A84A-267BBE68B5A1}.Debug|x64.ActiveCfg = Debug|Any CPU + {A7A666E0-2ADE-4496-A84A-267BBE68B5A1}.Debug|x64.Build.0 = Debug|Any CPU + {A7A666E0-2ADE-4496-A84A-267BBE68B5A1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A7A666E0-2ADE-4496-A84A-267BBE68B5A1}.Release|Any CPU.Build.0 = Release|Any CPU + {A7A666E0-2ADE-4496-A84A-267BBE68B5A1}.Release|x64.ActiveCfg = Release|Any CPU + {A7A666E0-2ADE-4496-A84A-267BBE68B5A1}.Release|x64.Build.0 = Release|Any CPU + {CBC756D7-8BB7-4CEC-95C7-FDB9363BAC63}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CBC756D7-8BB7-4CEC-95C7-FDB9363BAC63}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CBC756D7-8BB7-4CEC-95C7-FDB9363BAC63}.Debug|x64.ActiveCfg = Debug|Any CPU + {CBC756D7-8BB7-4CEC-95C7-FDB9363BAC63}.Debug|x64.Build.0 = Debug|Any CPU + {CBC756D7-8BB7-4CEC-95C7-FDB9363BAC63}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CBC756D7-8BB7-4CEC-95C7-FDB9363BAC63}.Release|Any CPU.Build.0 = Release|Any CPU + {CBC756D7-8BB7-4CEC-95C7-FDB9363BAC63}.Release|x64.ActiveCfg = Release|Any CPU + {CBC756D7-8BB7-4CEC-95C7-FDB9363BAC63}.Release|x64.Build.0 = Release|Any CPU + {2574F603-4B6C-4A30-BFDD-E3BC09EEDFDF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2574F603-4B6C-4A30-BFDD-E3BC09EEDFDF}.Debug|x64.ActiveCfg = Debug|Any CPU + {2574F603-4B6C-4A30-BFDD-E3BC09EEDFDF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2574F603-4B6C-4A30-BFDD-E3BC09EEDFDF}.Release|x64.ActiveCfg = Release|Any CPU + {B4C3F008-B6CA-4D63-9B98-6AC2D97B4E9B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B4C3F008-B6CA-4D63-9B98-6AC2D97B4E9B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B4C3F008-B6CA-4D63-9B98-6AC2D97B4E9B}.Debug|x64.ActiveCfg = Debug|Any CPU + {B4C3F008-B6CA-4D63-9B98-6AC2D97B4E9B}.Debug|x64.Build.0 = Debug|Any CPU + {B4C3F008-B6CA-4D63-9B98-6AC2D97B4E9B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B4C3F008-B6CA-4D63-9B98-6AC2D97B4E9B}.Release|Any CPU.Build.0 = Release|Any CPU + {B4C3F008-B6CA-4D63-9B98-6AC2D97B4E9B}.Release|x64.ActiveCfg = Release|Any CPU + {B4C3F008-B6CA-4D63-9B98-6AC2D97B4E9B}.Release|x64.Build.0 = Release|Any CPU + {4A5FC975-B3C1-4C89-967A-A146DED20962}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4A5FC975-B3C1-4C89-967A-A146DED20962}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4A5FC975-B3C1-4C89-967A-A146DED20962}.Debug|x64.ActiveCfg = Debug|Any CPU + {4A5FC975-B3C1-4C89-967A-A146DED20962}.Debug|x64.Build.0 = Debug|Any CPU + {4A5FC975-B3C1-4C89-967A-A146DED20962}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4A5FC975-B3C1-4C89-967A-A146DED20962}.Release|Any CPU.Build.0 = Release|Any CPU + {4A5FC975-B3C1-4C89-967A-A146DED20962}.Release|x64.ActiveCfg = Release|Any CPU + {4A5FC975-B3C1-4C89-967A-A146DED20962}.Release|x64.Build.0 = Release|Any CPU + {8B8E819B-1BA1-4559-BE26-FF0215614921}.Debug|Any CPU.ActiveCfg = Debug|x64 + {8B8E819B-1BA1-4559-BE26-FF0215614921}.Debug|Any CPU.Build.0 = Debug|x64 + {8B8E819B-1BA1-4559-BE26-FF0215614921}.Debug|x64.ActiveCfg = Debug|x64 + {8B8E819B-1BA1-4559-BE26-FF0215614921}.Debug|x64.Build.0 = Debug|x64 + {8B8E819B-1BA1-4559-BE26-FF0215614921}.Release|Any CPU.ActiveCfg = Release|x64 + {8B8E819B-1BA1-4559-BE26-FF0215614921}.Release|x64.ActiveCfg = Release|x64 + {8B8E819B-1BA1-4559-BE26-FF0215614921}.Release|x64.Build.0 = Release|x64 + {4CD88A62-7023-4216-B37F-02FD6AF0595F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4CD88A62-7023-4216-B37F-02FD6AF0595F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4CD88A62-7023-4216-B37F-02FD6AF0595F}.Debug|x64.ActiveCfg = Debug|Any CPU + {4CD88A62-7023-4216-B37F-02FD6AF0595F}.Debug|x64.Build.0 = Debug|Any CPU + {4CD88A62-7023-4216-B37F-02FD6AF0595F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4CD88A62-7023-4216-B37F-02FD6AF0595F}.Release|Any CPU.Build.0 = Release|Any CPU + {4CD88A62-7023-4216-B37F-02FD6AF0595F}.Release|x64.ActiveCfg = Release|Any CPU + {4CD88A62-7023-4216-B37F-02FD6AF0595F}.Release|x64.Build.0 = Release|Any CPU + {37984538-A573-4A89-9EA7-AEAF95D2806A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {37984538-A573-4A89-9EA7-AEAF95D2806A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {37984538-A573-4A89-9EA7-AEAF95D2806A}.Debug|x64.ActiveCfg = Debug|Any CPU + {37984538-A573-4A89-9EA7-AEAF95D2806A}.Debug|x64.Build.0 = Debug|Any CPU + {37984538-A573-4A89-9EA7-AEAF95D2806A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {37984538-A573-4A89-9EA7-AEAF95D2806A}.Release|Any CPU.Build.0 = Release|Any CPU + {37984538-A573-4A89-9EA7-AEAF95D2806A}.Release|x64.ActiveCfg = Release|Any CPU + {37984538-A573-4A89-9EA7-AEAF95D2806A}.Release|x64.Build.0 = Release|Any CPU + {1203D047-DFC7-4F75-B232-F5F1479DF687}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1203D047-DFC7-4F75-B232-F5F1479DF687}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1203D047-DFC7-4F75-B232-F5F1479DF687}.Debug|x64.ActiveCfg = Debug|Any CPU + {1203D047-DFC7-4F75-B232-F5F1479DF687}.Debug|x64.Build.0 = Debug|Any CPU + {1203D047-DFC7-4F75-B232-F5F1479DF687}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1203D047-DFC7-4F75-B232-F5F1479DF687}.Release|Any CPU.Build.0 = Release|Any CPU + {1203D047-DFC7-4F75-B232-F5F1479DF687}.Release|x64.ActiveCfg = Release|Any CPU + {1203D047-DFC7-4F75-B232-F5F1479DF687}.Release|x64.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {B7CBE076-B324-473D-9A42-7AE164D8F1E0} + EndGlobalSection +EndGlobal diff --git a/ClassicGEC/ClassicGECHTML5/.gitignore b/ClassicGEC/ClassicGECHTML5/.gitignore new file mode 100644 index 0000000..d02ba88 --- /dev/null +++ b/ClassicGEC/ClassicGECHTML5/.gitignore @@ -0,0 +1,23 @@ +Scripts/**/*.js +!Scripts/VISBOL/visbol/**/*.js +!Scripts/VISBOL/pathseg.js +!Scripts/VISBOL/visbolbundle.js +Scripts/**/*.js.map +Scripts/**/*.d.ts +!Scripts/typings/**/*.d.ts +Tests/**/*.js +Tests/**/*.js.map +Tests/**/*.d.ts + +#residual files from before webpack +Scripts/ClassicGEC +Scripts/CodeEditor +Scripts/CRN +Scripts/CrnApp +Scripts/CRNEngine +Scripts/IDD +Scripts/InferenceViewer +Scripts/KnockoutGrid +Scripts/MSAGL +Scripts/SimulationViewer +vs \ No newline at end of file diff --git a/ClassicGEC/ClassicGECHTML5/AppBootstrap.js.map b/ClassicGEC/ClassicGECHTML5/AppBootstrap.js.map new file mode 100644 index 0000000..7e12d6a --- /dev/null +++ b/ClassicGEC/ClassicGECHTML5/AppBootstrap.js.map @@ -0,0 +1 @@ +{"version":3,"file":"AppBootstrap.js","sourceRoot":"","sources":["AppBootstrap.ts"],"names":[],"mappings":";AAAA,OAAO,CAAC,CAAC,UAAU,CAAC,EAAE;IAClB,OAAO,CAAC,CAAC,+BAA+B,CAAC,EAAE;QACvC,OAAO,CAAC,CAAC,eAAe,CAAC,CAAC,EAAE;QAC5B,CAAC,CAAA;IACL,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"} \ No newline at end of file diff --git a/ClassicGEC/ClassicGECHTML5/ClassicGECHTML5.csproj b/ClassicGEC/ClassicGECHTML5/ClassicGECHTML5.csproj new file mode 100644 index 0000000..0ee7049 --- /dev/null +++ b/ClassicGEC/ClassicGECHTML5/ClassicGECHTML5.csproj @@ -0,0 +1,50 @@ + + + + netcoreapp3.1 + true + + Library + --mutex file install + $([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\..\packages\javascriptbuild\Node.js.redist\tools\win-x64\node.exe')) + + + + + + + + + + + + + + $([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\..\packages\javascriptbuild\Node.js.redist\tools\win-x64\node.exe')) + + + + + + + + $(CopyAllFilesToSingleFolderForPackageDependsOn); + CollectWebpackOutput; + + + $(CopyAllFilesToSingleFolderForMsdeployDependsOn); + CollectWebpackOutput; + + + + + + <_CustomFiles Include="dist\**\*" /> + + %(RecursiveDir)%(Filename)%(Extension) + + + + + + \ No newline at end of file diff --git a/ClassicGEC/ClassicGECHTML5/Config.js.map b/ClassicGEC/ClassicGECHTML5/Config.js.map new file mode 100644 index 0000000..333c9c0 --- /dev/null +++ b/ClassicGEC/ClassicGECHTML5/Config.js.map @@ -0,0 +1 @@ +{"version":3,"file":"Config.js","sourceRoot":"","sources":["Config.ts"],"names":[],"mappings":";AAAA,OAAO,CAAC,MAAM,CAAC;IACX,KAAK,EAAE;QACH,QAAQ,EAAE,kBAAkB;QAC5B,kBAAkB,EAAE,0BAA0B;QAC9C,GAAG,EAAE,0BAA0B;QAC/B,QAAQ,EAAE,gBAAgB;QAC1B,IAAI,EAAE,gBAAgB;QACtB,QAAQ,EAAE,cAAc;QACxB,aAAa,EAAE,mBAAmB;QAClC,SAAS,EAAE,aAAa;QACxB,WAAW,EAAE,mBAAmB;QAChC,UAAU,EAAE,mBAAmB;QAC/B,KAAK,EAAE,aAAa;QACpB,mBAAmB,EAAE,2BAA2B;QAChD,UAAU,EAAE,mBAAmB;QAC/B,YAAY,EAAE,iCAAiC;QAC/C,iBAAiB;QACjB,IAAI,EAAE,cAAc;QACpB,0BAA0B;QAC1B,WAAW,EAAE,mBAAmB;QAChC,WAAW,EAAE,mBAAmB;QAChC,UAAU,EAAE,6BAA6B;QACzC,KAAK,EAAE,eAAe;QAEtB,OAAO,EAAE,wBAAwB;QACjC,MAAM,EAAE,6BAA6B;KACxC;IACD,IAAI,EAAE;QACF,QAAQ,EAAE,EAAE,IAAI,EAAE,CAAC,SAAS,CAAC,EAAE;QAC/B,QAAQ,EAAE;YACN,OAAO,EAAE,GAAG;SACf;QACD,UAAU,EAAE,EAAE,IAAI,EAAE,CAAC,QAAQ,CAAC,EAAE;QAChC,kBAAkB,EAAE,EAAE,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE;KAC7C;IACD,WAAW,EAAE,EAAE;CAClB,CAAC,CAAC"} \ No newline at end of file diff --git a/ClassicGEC/ClassicGECHTML5/Docs/license.html b/ClassicGEC/ClassicGECHTML5/Docs/license.html new file mode 100644 index 0000000..0fced3e --- /dev/null +++ b/ClassicGEC/ClassicGECHTML5/Docs/license.html @@ -0,0 +1,7181 @@ + + + + + + + + + + + Microsoft Visual GEC - Standalone (free) Use Terms + + + + + + + + + + + + + + + + + + +
+ +

+ + MICROSOFT + SOFTWARE LICENSE TERMS + +

+ +
+ +

+ + MICROSOFT + VISUAL GEC + +

+ +
+ +
+ + +
+ +
+
+ +

+ + + IF + YOU LIVE IN (OR ARE A BUSINESS WITH A PRINCIPAL PLACE OF BUSINESS IN) THE + UNITED STATES, PLEASE READ THE “BINDING ARBITRATION AND CLASS ACTION WAIVER” SECTION + BELOW. IT AFFECTS HOW DISPUTES ARE RESOLVED. + + +

+ +
+ + +
+ +
+
+ +

+ + These license terms are an agreement between you + and Microsoft Corporation (or one of its affiliates). They apply to the + software named above and any Microsoft services or software updates (except to + the extent such services or updates are accompanied by new or + + additional terms, in which case those different terms apply + prospectively and do not alter your or Microsoft’s rights relating to + pre-updated software or services + ). IF YOU COMPLY WITH THESE LICENSE TERMS, YOU HAVE THE RIGHTS BELOW.BY USING THE SOFTWARE, YOU ACCEPT THESE TERMS. +

+ +

+ + + 1.    + + + INSTALLATION AND USE RIGHTS. + +

+ +

+ + + + + a)    + + + General. + + You may install and use any + number of copies of the software. + + + +

+ + + +

+ + + b)    + + + Third Party Software. + + The software may + include third party applications that Microsoft, not the third party, licenses + to you under this agreement. Any included notices for third party applications + are for your information only. + +

+ +

+ + + 2.    + + + DATA COLLECTION. + + The software may + collect information about you and your use of the software and send that to + Microsoft. Microsoft may use this information to provide services and improve + Microsoft’s products and services. Your opt-out rights, if any, are described + in the product documentation. Some features in the software may enable + collection of data from users of your applications that access or use the + software. If you use these features to enable data collection in your + applications, you must comply with applicable law, including getting any required + user consent, and maintain a prominent privacy policy that accurately informs + users about how you use, collect, and share their data. You can learn more + about Microsoft’s data collection and use in the product documentation and the + Microsoft Privacy Statement at + https://go.microsoft.com/fwlink/?LinkId=521839 + . You agree to + comply with all applicable provisions of the Microsoft Privacy Statement. + +

+ +

+ + + 3.    + + + SCOPE OF LICENSE. + + The software is + licensed, not sold. Microsoft reserves all other rights. Unless applicable law + gives you more rights despite this limitation, you will not (and have no right + to): + +

+ +

+ + + a) +     + + + + work + around any technical limitations in the software that only allow you to use it + in certain ways; + +

+ +

+ + + b) +     + + + + reverse + engineer, decompile or disassemble the software; + +

+ +

+ + + c) +     + + + + remove, + minimize, block, or modify any notices of Microsoft or its suppliers in the + software; + +

+ +

+ + + d) +     + + + + use + the software for commercial, non-profit, or revenue-generating activities; + +

+ +

+ + + e) +     + + + + use + the software in any way that is against the law or to create or propagate + malware; or + +

+ +

+ + + f) +      + + + + share, + publish, distribute, or lend the software, provide the software as a + stand-alone hosted solution for others to use, or transfer the software or this + agreement to any third party. + +

+ +

+ + + 4.    + + + EXPORT RESTRICTIONS. + + You must comply + with all domestic and international export laws and regulations that apply to + the software, which include restrictions on destinations, end users, and end + use. For further information on export restrictions, visit http://aka.ms/exporting. + +

+ +

+ + + 5.    + + + SUPPORT SERVICES. + + Microsoft is not + obligated under this agreement to provide any support services for the + software. Any support provided is “as is”, “with all faults”, and without + warranty of any kind. + +

+ +

+ + + 6.    + + + UPDATES. + + The software may periodically + check for updates, and download and install them for you. You may obtain + updates only from Microsoft or authorized sources. Microsoft may need to update + your system to provide you with updates. You agree to receive these automatic + updates without any additional notice. Updates may not include or support all + existing software features, services, or peripheral devices. + +

+ +

+ + + + + 7.    + + + + BINDING + ARBITRATION AND CLASS ACTION WAIVER. This Section applies if you live in (or, + if a business, your principal place of business is in) the United States. + + + If you and + Microsoft have a dispute, you and Microsoft agree to try for 60 days to resolve + it informally. If you and Microsoft can’t, you and Microsoft agree to + binding + individual arbitration before the American Arbitration Associatio + n under + the Federal Arbitration Act (“FAA”), and + not to sue in court in front of a + judge or jury + . Instead, a neutral arbitrator will decide. + Class action + lawsuits, class-wide arbitrations, private attorney-general actions, + and + any other proceeding where someone acts in a representative capacity + are not + allowed + ; nor is combining individual proceedings without the consent of all + parties. The complete Arbitration Agreement contains more terms and is at + + + + + + http://aka.ms/arb-agreement-1 + + + + + . You and Microsoft agree to these terms. + + +

+ +

+ + + 8.    + + + TERMINATION. + + Without prejudice to any + other rights, Microsoft may terminate this agreement if you fail to comply with + any of its terms or conditions. In such event, you must destroy all copies of + the software and all of its component parts. + +

+ +

+ + + 9.    + + + ENTIRE AGREEMENT. + + This agreement, and + any other terms Microsoft may provide for supplements, updates, or third-party + applications, is the entire agreement for the software. + +

+ +

+ + + 10. + + + APPLICABLE LAW AND PLACE TO RESOLVE DISPUTES. + + If you acquired the software in the United States or Canada, the + laws of the state or province where you live (or, if a business, where your + principal place of business is located) govern the interpretation of this + agreement, claims for its breach, and all other claims (including consumer + protection, unfair competition, and tort claims), regardless of conflict of + laws principles, except that the FAA governs everything related to arbitration. + If you acquired the software in any other country, its laws apply, except that + the FAA governs everything related to arbitration. If U.S. federal jurisdiction + exists, you and Microsoft consent to exclusive jurisdiction and venue in the + federal court in King County, Washington for all disputes heard in court + (excluding arbitration). If not, you and Microsoft consent to exclusive + jurisdiction and venue in the Superior Court of King County, Washington for all + disputes heard in court (excluding arbitration). + +

+ +

+ + + 11. + + + CONSUMER RIGHTS; REGIONAL VARIATIONS. + + This agreement describes certain legal rights. You may have other rights, + including consumer rights, under the laws of your state, province, or country. + Separate and apart from your relationship with Microsoft, you may also have + rights with respect to the party from which you acquired the software. This + agreement does not change those other rights if the laws of your state, + province, or country do not permit it to do so. For example, if you acquired + the software in one of the below regions, or mandatory country law applies, + then the following provisions apply to you: + +

+ +

+ + + + a)    + + + + Australia. + + You have statutory guarantees + under the Australian Consumer Law and nothing in this agreement is intended to + affect those rights. + +

+ +

+ + + + b)    + + + + Canada. + + If you acquired this software in + Canada, you may stop receiving updates by turning off the automatic update + feature, disconnecting your device from the Internet (if and when you + re-connect to the Internet, however, the software will resume checking for and + installing updates), or uninstalling the software. The product documentation, + if any, may also specify how to turn off updates for your specific device or + software. + +

+ +

+ + + + c)    + + + + Germany and Austria + . +

+ +

+ + i.Warranty. + + The properly licensed software will perform + substantially as described in any Microsoft materials that accompany the + software. However, Microsoft gives no contractual guarantee in relation to the + licensed software. + +

+ +

+ + ii.Limitation of Liability. + + In case of intentional conduct, gross + negligence, claims based on the Product Liability Act, as well as, in case of + death or personal or physical injury, Microsoft is liable according to the + statutory law. + +

+ +

+ + Subject to the + foregoing clause ii., Microsoft will only be liable for slight negligence if + Microsoft is in breach of such material contractual obligations, the + fulfillment of which facilitate the due performance of this agreement, the + breach of which would endanger the purpose of this agreement and the compliance + with which a party may constantly trust in (so-called "cardinal + obligations"). In other cases of slight negligence, Microsoft will not be + liable for slight negligence. + +

+ +

+ + + 12. + + + + DISCLAIMER OF WARRANTY. THE SOFTWARE IS LICENSED “AS IS.” YOU BEAR + THE RISK OF USING IT. MICROSOFT GIVES NO EXPRESS WARRANTIES, GUARANTEES, OR CONDITIONS. + TO THE EXTENT PERMITTED UNDER APPLICABLE LAWS, MICROSOFT EXCLUDES ALL IMPLIED + WARRANTIES, INCLUDING MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND + NON-INFRINGEMENT. + + +

+ +

+ + + 13. + + + + LIMITATION ON AND EXCLUSION OF DAMAGES. IF YOU HAVE ANY BASIS FOR + RECOVERING DAMAGES DESPITE THE PRECEDING DISCLAIMER OF WARRANTY, YOU CAN + RECOVER FROM MICROSOFT AND ITS SUPPLIERS ONLY DIRECT DAMAGES UP TO U.S. $5.00. + YOU CANNOT RECOVER ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST PROFITS, + SPECIAL, INDIRECT OR INCIDENTAL DAMAGES. + + +

+ +

+ + This + limitation applies to (a) anything related to the software, services, content + (including code) on third party Internet sites, or third party applications; + and (b) claims for breach of contract, warranty, guarantee, or condition; + strict liability, negligence, or other tort; or any other claim; in each case + to the extent permitted by applicable law. + +

+ +

+ + It also applies even + if Microsoft knew or should have known about the possibility of the damages. + The above limitation or exclusion may not apply to you because your state, + province, or country may not allow the exclusion or limitation of incidental, + consequential, or other damages. + +

+ +

 

+ +

+ + Please + note: As this software is distributed in Canada, some of the clauses in this + agreement are provided below in French. + +

+ +

+ + Remarque: + Ce logiciel étant distribué au Canada, certaines des clauses dans ce contrat + sont fournies ci-dessous en français. + +

+ +

+ + EXONÉRATION + DE GARANTIE. Le logiciel visé par une licence est offert « tel quel ». Toute + utilisation de ce logiciel est à votre seule risque et péril. Microsoft + n’accorde aucune autre garantie expresse. Vous pouvez bénéficier de droits + additionnels en vertu du droit local sur la protection des consommateurs, que + ce contrat ne peut modifier. La ou elles sont permises par le droit locale, les + garanties implicites de qualité marchande, d’adéquation à un usage particulier + et d’absence de contrefaçon sont exclues. + +

+ +

+ + LIMITATION + DES DOMMAGES-INTÉRÊTS ET EXCLUSION DE RESPONSABILITÉ POUR LES DOMMAGES. Vous + pouvez obtenir de Microsoft et de ses fournisseurs une indemnisation en cas de + dommages directs uniquement à hauteur de 5,00 $ US. Vous ne pouvez prétendre à + aucune indemnisation pour les autres dommages, y compris les dommages spéciaux, + indirects ou accessoires et pertes de bénéfices. + +

+ +

+ + Cette + limitation concerne: + +

+ +

+ + •tout ce qui est relié au logiciel, aux + services ou au contenu (y compris le code) figurant sur des sites Internet + tiers ou dans des programmes tiers; et + +

+ +

+ + •les réclamations au titre de violation de + contrat ou de garantie, ou au titre de responsabilité stricte, de négligence ou + d’une autre faute dans la limite autorisée par la loi en vigueur. + +

+ +

+ + Elle + s’applique également, même si Microsoft connaissait ou devrait connaître + l’éventualité d’un tel dommage. Si votre pays n’autorise pas l’exclusion ou la + limitation de responsabilité pour les dommages indirects, accessoires ou de + quelque nature que ce soit, il se peut que la limitation ou l’exclusion + ci-dessus ne s’appliquera pas à votre égard. + +

+ +

+ + EFFET + JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous pourriez + avoir d’autres droits prévus par les lois de votre pays. Le présent contrat ne + modifie pas les droits que vous confèrent les lois de votre pays si celles-ci + ne le permettent pas. + +

+ +

 

+ +
+ + + + diff --git a/ClassicGEC/ClassicGECHTML5/Scripts/Adapters/GECCodeSource.ts b/ClassicGEC/ClassicGECHTML5/Scripts/Adapters/GECCodeSource.ts new file mode 100644 index 0000000..31951e9 --- /dev/null +++ b/ClassicGEC/ClassicGECHTML5/Scripts/Adapters/GECCodeSource.ts @@ -0,0 +1,20 @@ +import Editor from '../GECCodeEditor'; +import * as ModificationIndicator from '../../../../HTML5SharedGUI/GenericComponents/Scripts/ModificationIndicators'; +import * as Features from '../Features'; +import * as KOCodeEditor from '../../../../HTML5SharedGUI/HTML5CRN_Lib/Scripts/Adapters/KnockoutBasedCodeEditor'; +import * as GenericParseOperation from '../../../../HTML5SharedGUI/HTML5CRN_Lib/Scripts/Operations/GenericCodeParsing'; +import { INamedMonarchLanguage } from '../../../../HTML5SharedGUI/CodeEditor/Scripts/CodeEditor'; +import * as ko from 'knockout'; + +export class CodeEditor extends KOCodeEditor.KOCodeEditor<{}> implements GenericParseOperation.ICodeSource<{}>, GenericParseOperation.IErrorDisplay, Features.IUIAutoBindable { + constructor(private language: INamedMonarchLanguage, private examples: Array, modifIndicator: ModificationIndicator.IModificationIndicator, options: {}) { + super(modifIndicator, options); + } + + //Features.IUIAutoBindable implementation + public AutoBind() { + //CodeEditor create + var codeEditor = new Editor(this.language, this.examples); + ko.applyBindings(this.vm, document.getElementById('gecCode')); + } +} \ No newline at end of file diff --git a/ClassicGEC/ClassicGECHTML5/Scripts/Adapters/PartsDBCodeSource.ts b/ClassicGEC/ClassicGECHTML5/Scripts/Adapters/PartsDBCodeSource.ts new file mode 100644 index 0000000..a93c9e4 --- /dev/null +++ b/ClassicGEC/ClassicGECHTML5/Scripts/Adapters/PartsDBCodeSource.ts @@ -0,0 +1,20 @@ +import Editor from '../PartsCodeEditor'; +import * as ModificationIndicator from '../../../../HTML5SharedGUI/GenericComponents/Scripts/ModificationIndicators'; +import * as Features from '../Features'; +import * as KOCodeEditor from '../../../../HTML5SharedGUI/HTML5CRN_Lib/Scripts/Adapters/KnockoutBasedCodeEditor'; +import * as GenericParseOperation from '../../../../HTML5SharedGUI/HTML5CRN_Lib/Scripts/Operations/GenericCodeParsing'; +import { INamedMonarchLanguage } from '../../../../HTML5SharedGUI/CodeEditor/Scripts/CodeEditor'; +import * as ko from 'knockout'; + +export class CodeEditor extends KOCodeEditor.KOCodeEditor<{}> implements GenericParseOperation.ICodeSource<{}>, GenericParseOperation.IErrorDisplay, Features.IUIAutoBindable { + constructor(private language: INamedMonarchLanguage, private examples: Array, modifIndicator: ModificationIndicator.IModificationIndicator, options: {}) { + super(modifIndicator, options); + } + + //Features.IUIAutoBindable implementation + public AutoBind() { + //CodeEditor create + var codeEditor = new Editor(this.language, this.examples); + ko.applyBindings(this.vm, document.getElementById('gecParts')); + } +} \ No newline at end of file diff --git a/ClassicGEC/ClassicGECHTML5/Scripts/Adapters/ReactionsDBCodeSource.ts b/ClassicGEC/ClassicGECHTML5/Scripts/Adapters/ReactionsDBCodeSource.ts new file mode 100644 index 0000000..1ee8338 --- /dev/null +++ b/ClassicGEC/ClassicGECHTML5/Scripts/Adapters/ReactionsDBCodeSource.ts @@ -0,0 +1,20 @@ +import Editor from '../ReactionsCodeEditor'; +import * as ModificationIndicator from '../../../../HTML5SharedGUI/GenericComponents/Scripts/ModificationIndicators'; +import * as Features from '../Features'; +import * as KOCodeEditor from '../../../../HTML5SharedGUI/HTML5CRN_Lib/Scripts/Adapters/KnockoutBasedCodeEditor'; +import * as GenericParseOperation from '../../../../HTML5SharedGUI/HTML5CRN_Lib/Scripts/Operations/GenericCodeParsing'; +import { INamedMonarchLanguage } from '../../../../HTML5SharedGUI/CodeEditor/Scripts/CodeEditor'; +import * as ko from 'knockout'; + +export class CodeEditor extends KOCodeEditor.KOCodeEditor<{}> implements GenericParseOperation.ICodeSource<{}>, GenericParseOperation.IErrorDisplay, Features.IUIAutoBindable { + constructor(private language: INamedMonarchLanguage, private examples: Array, modifIndicator: ModificationIndicator.IModificationIndicator, options: {}) { + super(modifIndicator, options); + } + + //Features.IUIAutoBindable implementation + public AutoBind() { + //CodeEditor create + var codeEditor = new Editor(this.language, this.examples); + ko.applyBindings(this.vm, document.getElementById('gecReactions')); + } +} \ No newline at end of file diff --git a/ClassicGEC/ClassicGECHTML5/Scripts/App.ts b/ClassicGEC/ClassicGECHTML5/Scripts/App.ts new file mode 100644 index 0000000..072cf97 --- /dev/null +++ b/ClassicGEC/ClassicGECHTML5/Scripts/App.ts @@ -0,0 +1,673 @@ +/*import { ServiceWorker } from './Scripts/ServiceWorker'; +let serviceWorker = new ServiceWorker();*/ + +import "jqueryui"; +import * as $ from 'jquery'; +import "../Styles/App.css"; +import "../../../node_modules/jquery-ui/themes/base/all.css" +import "../../../node_modules/katex/dist/katex.min.css" +import "../../../HTML5SharedGUI/KnockoutGrid/table.css" +// We override IDD styles with General.css, so we require IDD styles to be loaded prior to General.css. +import "../../../node_modules/interactive-data-display/dist/idd.css" +import "../../../HTML5SharedGUI/CodeEditor/Styles/codepad.css" +import "../../../HTML5SharedGUI/SimulationViewer/Styles/simulation.css" +import "../../../HTML5SharedGUI/InferenceViewer/Styles/inference.css" +import "../../../HTML5SharedGUI/CRNComponent/Styles/crn.css" +import "idd"; +declare var InteractiveDataDisplay: any; +import * as visbol from '../../../node_modules/visbol/index.js'; +import * as visbolfont from '../../../node_modules/visbol/font/sbolv/main.js'; +import * as Utils from '../../../HTML5SharedGUI/HTML5CRN_Lib/Scripts/Utils'; +import "pathseg"; +import { jsbolToObject } from "../../ClassicGECTSWrapper/Scripts/JSBOL"; + +// import convertJsonToXml from './json2xml'; +import GECLanguage from './GECLang'; +import PartsLanguage from './PartsLang'; +import ReactionsLanguage from './ReactionsLang'; +import Options from '../../../HTML5SharedGUI/GenericComponents/Scripts/Options'; +import "../../../HTML5SharedGUI/GenericComponents/Scripts/Dropdown"; +import * as CodeEditor from '../../../HTML5SharedGUI/HTML5CRN_Lib/Scripts/Adapters/KnockoutBasedCRNCodeEditor'; +import { CodeEditor as GECCodeEditor } from './Adapters/GECCodeSource'; +import { CodeEditor as PartsDBCodeEditor } from './Adapters/PartsDBCodeSource'; +import { CodeEditor as ReactionsDBCodeEditor } from './Adapters/ReactionsDBCodeSource'; +import * as CodeStorage from '../../../HTML5SharedGUI/HTML5CRN_Lib/Scripts/Adapters/CodeEditorStorageDecorator'; +import * as CodeParser from '../../../HTML5SharedGUI/HTML5CRN_Lib/Scripts/Adapters/ModellingEngineCRNParser'; +import * as CrnEditor from '../../../HTML5SharedGUI/HTML5CRN_Lib/Scripts/Adapters/KnockoutBasedCRNViewer'; +import * as CrnExport from '../../../HTML5SharedGUI/HTML5CRN_Lib/Scripts/Adapters/KnockoutBasedCRNExport'; +import * as SimRunner from '../../../HTML5SharedGUI/HTML5CRN_Lib/Scripts/Adapters/ModellingEngineSimulationRunner'; +import * as SimRunnerSpat1D from '../../../HTML5SharedGUI/HTML5CRN_Lib/Scripts/Adapters/ModellingEngineSpatial1DSimulationRunner'; +import * as SimRunnerSpat2D from '../../../HTML5SharedGUI/HTML5CRN_Lib/Scripts/Adapters/ModellingEngineSpatial2DSimulationRunner'; +import * as InferenceRunner from '../../../HTML5SharedGUI/HTML5CRN_Lib/Scripts/Adapters/ModellingEngineInferenceRunner'; +import { Adapter as SSARunner } from "../../../HTML5SharedGUI/HTML5CRN_Lib/Scripts/Adapters/ModellingEngineSSA"; +import { Viewer as SSASummaryViewer } from "../../../HTML5SharedGUI/HTML5CRN_Lib/Scripts/Adapters/KnockoutBasedSSASummaryViewer"; +import * as SimViewer from '../../../HTML5SharedGUI/HTML5CRN_Lib/Scripts/Adapters/SimViewerAdapter'; +import { StoredSettings as SpatialViewerSettings } from "../../../HTML5SharedGUI/SimulationViewer/Scripts/SpatialViewerSettings"; +import SpatialViewer1D from "../../../HTML5SharedGUI/SimulationViewer/Scripts/Spatial1DViewer"; +import SpatialViewer2D from "../../../HTML5SharedGUI/SimulationViewer/Scripts/Spatial2DViewer"; +import * as HintScreen from '../../../HTML5SharedGUI/GenericComponents/Scripts/HintScreen'; +import * as ModificationIndicator from '../../../HTML5SharedGUI/GenericComponents/Scripts/ModificationIndicators'; +import * as SVF from '../../../HTML5SharedGUI/SimulationViewer/Scripts/SimulationViewerFramework'; +import CRNEngine from '../../../CRNEngine/CRNEngineTSWrapper/Scripts/CRNEngine'; +import ClassicGEC from '../../ClassicGECTSWrapper/Scripts/ClassicGEC'; +import * as InferenceParametersViewer from '../../../HTML5SharedGUI/InferenceViewer/Scripts/InferredParametersViewer'; +import * as InferenceModelDynamicsViewer from '../../../HTML5SharedGUI/InferenceViewer/Scripts/ModelDataDynamics'; +import * as InferencePosteriorViewer from '../../../HTML5SharedGUI/InferenceViewer/Scripts/PosteriorViewer'; +import * as InferenceSummary from '../../../HTML5SharedGUI/InferenceViewer/Scripts/InferenceSummary'; +import * as InferenceCompositeViewer from '../../../HTML5SharedGUI/InferenceViewer/Scripts/CompositeViewer'; +import { Viewer as SSATextViewer } from '../../../HTML5SharedGUI/HTML5CRN_Lib/Scripts/Components/SSATextViewer'; +import { Viewer as SSACompoundViewer } from '../../../HTML5SharedGUI/HTML5CRN_Lib/Scripts/Components/SSACompoundViewer'; +import * as SumToVum from '../../../HTML5SharedGUI/HTML5CRN_Lib/Scripts/Adapters/SumToVum'; +import { Viewer as PMViewer } from '../../../HTML5SharedGUI/HTML5CRN_Lib/Scripts/Adapters/ProbabilityMapsAdapter'; +import SSAGraphViewer from '../../../HTML5SharedGUI/HTML5CRN_Lib/Scripts/Adapters/SSAGraphAdapter'; +import CRNCompoundViewer from '../../../HTML5SharedGUI/HTML5CRN_Lib/Scripts/Components/CRNCompoundViewer'; +import CRNGraphViewer from '../../../HTML5SharedGUI/HTML5CRN_Lib/Scripts/Adapters/CRNGraphAdapter'; +import * as LongOperations from '../../../HTML5SharedGUI/HTML5CRN_Lib/Scripts/Operations/LongOperations'; +import * as LongOperationsKO from '../../../HTML5SharedGUI/HTML5CRN_Lib/Scripts/Operations/LongOperationsKO'; +import * as ParseOperation from '../../../HTML5SharedGUI/HTML5CRN_Lib/Scripts/Operations/ParseCodeFillCRN'; +import * as ExportOperation from '../../../HTML5SharedGUI/HTML5CRN_Lib/Scripts/Operations/ModellingEngineExporter'; +import * as GecParseOperation from './Operations/GecParseOperation'; +import * as GetSolutionOperation from './Operations/GetSolutionOperation'; +import * as SimulateOperation from '../../../HTML5SharedGUI/HTML5CRN_Lib/Scripts/Operations/SimulateParsedCRN'; +import * as Spatial1DSimulation from '../../../HTML5SharedGUI/HTML5CRN_Lib/Scripts/Operations/Spatial1DSimulation'; +import * as Spatial2DSimulation from '../../../HTML5SharedGUI/HTML5CRN_Lib/Scripts/Operations/Spatial2DSimulation'; +import { SimulationType, Operation as DispatchedSimulateOperation } from '../../../HTML5SharedGUI/HTML5CRN_Lib/Scripts/Operations/AutoChoiceSimulation'; +import * as InferOperation from '../../../HTML5SharedGUI/HTML5CRN_Lib/Scripts/Operations/Inference'; +import * as TabSelectOperation from '../../../HTML5SharedGUI/HTML5CRN_Lib/Scripts/Operations/TabSelect'; +import { Operation as SSAOperation } from '../../../HTML5SharedGUI/HTML5CRN_Lib/Scripts/Operations/StateSpaceAnalysis'; +import { Operation as SynthesisOperation } from '../../../HTML5SharedGUI/HTML5CRN_Lib/Scripts/Operations/Synthesis'; +import CRNSelector from '../../../HTML5SharedGUI/CRNComponent/Scripts/CRNSelector'; +import InferenceGraphAdapter from '../../../HTML5SharedGUI/HTML5CRN_Lib/Scripts/Adapters/InferenceGraphAdapter'; +import SynthesisAdapter from '../../../HTML5SharedGUI/HTML5CRN_Lib/Scripts/Adapters/ModellingEngineSynthesis'; +import { SynthesisViewer } from '../../../HTML5SharedGUI/SimulationViewer/Scripts/SynthesisViewer'; + +import { KnockoutBasedDataSetsList as DataSetList } from '../../../HTML5SharedGUI/CRNComponent/Scripts/crnDataSets'; +import { KnockoutGridDataSetViewer as DataSetViewer } from '../../../HTML5SharedGUI/CRNComponent/Scripts/crnDataSets'; +import { ObservationsSource } from '../../../HTML5SharedGUI/HTML5CRN_Lib/Scripts/Adapters/MultipleDataSetObsSource'; +import { MemoryDataSetStorage, LocalStorageDataSetStorage, IndexedDBDataSetStorage } from '../../../HTML5SharedGUI/CRNComponent/Scripts/DataSetStorage'; + +import * as GECInterfaces from '../../ClassicGECTSWrapper/Scripts/Interfaces'; +import IDDTabs from "../../../HTML5SharedGUI/GenericComponents/Scripts/IDDTabs"; + +var examplesPath = "./Examples/GECModels/"; +var examples: ExamplesGroup[] = [ + { + // NOTE: the URLs here are supposed to be resolved relativly to the HTML page that runs the script. Usually it is ($app_root)/index.html. + // As the path to the code is $app_root/CodeExamples/* the relatice url here is CodeExamples/* + Name: "Examples", + Correspondence: { + "Basic": examplesPath + "basic.txt", + "Repressilator Similar": examplesPath + "repressilator_similar.txt", + "Repressilator Modules": examplesPath + "repressilator_modules.txt", + "Repressilator Modules Similar": examplesPath + "repressilator_modules_similar.txt", + "Receiver Device": examplesPath + "receiver_device.txt", + "Predator-Prey": examplesPath + "predator_prey.txt", + "Band Detector": examplesPath + "band_detector.txt" + } + } +]; + +//Phase 1. Creating the functional components +let dataSetStorage = (() => { + var ret: IndexedDBDataSetStorage | MemoryDataSetStorage = null; + if (window.indexedDB !== undefined) + ret = new IndexedDBDataSetStorage("CRNdb"); + else + ret = new MemoryDataSetStorage(); //e.g. Edge InPrivate + return ret; +})(); +var dataSetList = new DataSetList(dataSetStorage); +var longOperationsManager = new LongOperationsKO.LongOperationsKO(); +var gecCodeModificationIndicator = new ModificationIndicator.TabSuffixIndicator($(".j-gec-tab-header")); +var codeModificationIndicator = new ModificationIndicator.TabSuffixIndicator($(".j-code-tab-header")); +var crnModificationIndicator = new ModificationIndicator.TabSuffixIndicator($(".j-crn-tab-header")); +var classicGEC = new ClassicGEC(Options.Server()); +var gecCodeSource = new GECCodeEditor(GECLanguage, examples, gecCodeModificationIndicator, {}); +var partsDBCodeSource = new PartsDBCodeEditor(PartsLanguage, [], gecCodeModificationIndicator, {}); +var reactionsDBCodeSource = new ReactionsDBCodeEditor(ReactionsLanguage, [], gecCodeModificationIndicator, {}); +var codeSource = new CodeEditor.KOCRNCodeEditor(codeModificationIndicator); +var codeStorage = new CodeStorage.CodeEditorStorageDecorator(codeSource, "CRN"); +var gecCodeStorage = new CodeStorage.CodeEditorStorageDecorator(gecCodeSource, "GEC"); +var partsCodeStorage = new CodeStorage.CodeEditorStorageDecorator(partsDBCodeSource, "GECParts"); +var reactionsCodeStorage = new CodeStorage.CodeEditorStorageDecorator(reactionsDBCodeSource, "GECReactions"); +var crnExport = new CrnExport.CRNExport(classicGEC); +var options = new Options(classicGEC); +var codeParser = new CodeParser.Parser(classicGEC); +var crnEditor = new CrnEditor.CRNEditor(dataSetList, crnModificationIndicator); +var currentlySelectedDataSetSource = new ObservationsSource(dataSetStorage); +var infRunner = new InferenceRunner.Adapter(classicGEC, currentlySelectedDataSetSource); +var ssaRunner = new SSARunner(classicGEC); +var ssaSummaryViewer = new SSASummaryViewer(); +var crnVM = crnEditor.GetVM(); +var inferenceGraphViewer = new InferenceGraphAdapter(crnVM); +var ssaGraphViewer = new SSAGraphViewer(crnVM); +var crnGraphViewer = new CRNGraphViewer(crnVM); +var simViewer = new SimViewer.Viewer(); +var spatialViewerSettings = new SpatialViewerSettings("black,green"); +var spatialViewer1D = new SpatialViewer1D(spatialViewerSettings); +var spatialViewer2D = new SpatialViewer2D(spatialViewerSettings); +var dataSetViewer = new DataSetViewer(); +var probabilityMapsViewer = new PMViewer(classicGEC, spatialViewerSettings); +var simRunner = new SimRunner.SimulationRunner(classicGEC, currentlySelectedDataSetSource); +var spat1DSimRunner = new SimRunnerSpat1D.SimulationRunner(classicGEC); +var spat2DSimRunner = new SimRunnerSpat2D.SimulationRunner(classicGEC); +var crnSelector = new CRNSelector(crnVM); +var synthesisAdapter = new SynthesisAdapter(classicGEC); + +//var crnSettings = new CRNSettingsVM(); +//inference viewers: +var infParamViewer = new InferenceParametersViewer.InferredParametersViewer(crnSelector); +var infDynamicsViewer = new InferenceModelDynamicsViewer.ModelDataDynamics(crnSelector); +var infPosteriorViewer = new InferencePosteriorViewer.PosteriorViewer(crnSelector); +var infSummary = new InferenceSummary.InferenceSummary(crnSelector); +var infViewer = new InferenceCompositeViewer.Viewer([infParamViewer, infDynamicsViewer, infSummary, infPosteriorViewer]); +var synthesisViewer = new SynthesisViewer(classicGEC); + +//SSA viewers +var ssaTextViewer = new SSATextViewer(); +var ctmcCompoundViewer = new SSACompoundViewer(ssaGraphViewer, ssaTextViewer, ssaSummaryViewer); +var crnCompoundViewer = new CRNCompoundViewer(crnEditor); + +var unitsExtractor = function (): SVF.IVisualizationUpdateMessage { + return { + MessageType: SVF.VisualizationUpdateMessageType.UnitsInformation, + EncapsulatedUpdate: Utils.ExponentToConcentrationString(crnEditor.GetConcentrationUnits()) + } +}; +var plotSettingsExtractor = function (): SVF.IVisualizationUpdateMessage { + return { + MessageType: SVF.VisualizationUpdateMessageType.PlotSettingsInfo, + EncapsulatedUpdate: crnEditor.GetPlotSettings() + } +}; + +var plotSettingsExtractorForInference = function (): InferOperation.IPlotSettingsValues { + return crnEditor.GetPlotSettings(); +}; + +var currentCRNSimulationType = function () { + var ig = crnEditor.getModel(); + var model = null; + for (var n in ig.nodes) { + model = ig.nodes[n]; + break; + } + if (model.top.settings.simulator != "PDE") + return SimulationType.nonspatial; + if (model.top.settings.spatial.dimensions == 1) + return SimulationType.spatial1D; + if (model.top.settings.spatial.dimensions == 2) + return SimulationType.spatial2D; + throw "unsupported operation type"; +} + +var solutionSelector: HTMLSelectElement = $("#solution-selector")[0]; +function setSolutionsCount(count: number) { + while (solutionSelector.hasChildNodes()) + solutionSelector.removeChild(solutionSelector.firstChild); + for (var i = 1; i <= count; i++) { + var opt = document.createElement("option"); + opt.text = i.toString(); + opt.value = i.toString(); + solutionSelector.appendChild(opt); + } +} +var getSolutionIdx = () => { + var idx = solutionSelector.selectedIndex; + if (idx < 0) + return -1; + return parseInt(solutionSelector.options[idx].value); +} + +//================================================ +//Start JSBOL -> SBOLJS Conversion + +var visbolDesign: any; + +function showSBOL(jsbol: GECInterfaces.jSBOLDocument) { + + + try { + //console.log(JSON.stringify(jsbol)); + + var sbolobj = jsbolToObject(jsbol); + + var visbolDiv = $("#visbolContainer")[0]; + while (visbolDiv.children.length > 0) + visbolDiv.removeChild(visbolDiv.firstChild); + + //var index = $("#resultsTabs").find("#visbolTab").index() - 1; + //$("#resultsTabs").tabs("option", "active", index); + + //var xmlsbol = convertJsonToXml(jsbol); + + //console.log("Start printing XML version"); + //console.dirxml(xmlsbol); + //console.log("Finished printing XML version of SBOL") + + var component: any = { + segments: [] + } + + //console.log(JSON.stringify(jsbol)); + + //console.log("About to print the display list for each component definition..."); + //sbolobj.componentDefinitions.forEach( (componentDefinition:any) => console.log(visbol.getDisplayList(componentDefinition))); + //console.log("All display lists printed."); + + + + sbolobj.componentDefinitions.forEach((componentDefinition: any) => { + if (componentDefinition.name == 'device') { + + var fullseq = visbol.getDisplayList.getDisplayList(componentDefinition).components[0].segments[0].sequence + var firsthalf = fullseq.slice(0, fullseq.length / 2) + var halfseg = visbol.getDisplayList.getDisplayList(componentDefinition).components[0].segments[0] + halfseg.sequence = firsthalf + component.segments = component.segments.concat(halfseg) + //component.segments = component.segments.concat(visbol.getDisplayList.getDisplayList(componentDefinition).components[0].segments[0]) + } + + }); + //xmlsbol.componentDefinitions.forEach(componentDefinition => component.segments = component.segments.concat(visbol.getDisplayList(componentDefinition).components[0].segments[0])); + + var displayList: any = { version: 1, components: [component] }; + var font: any = visbolfont; + visbolDesign = new visbol.Design({ element: visbolDiv, font: font }); + visbolDesign.setDisplayList(displayList); + visbolDesign.redraw(); + + /*var xml = json2xml(jsbol); + console.log(visbol != null); + var xmlstring = JSON.stringify(xml); + visbolDiv.text(xmlstring);*/ + + } catch (e) { + console.log(e) + } +} + +//Phase 2. Assembling higher level functionality from the components above + +var parseCrnOperation = new ParseOperation.Operation(codeStorage, codeParser, crnCompoundViewer, codeSource); +var parseGecOperation = new GecParseOperation.Operation(classicGEC, gecCodeStorage, partsCodeStorage, reactionsCodeStorage, setSolutionsCount, showSBOL, crnExport, gecCodeSource, partsDBCodeSource, reactionsDBCodeSource); +var selectSolutionOperation = new GetSolutionOperation.Operation(getSolutionIdx, classicGEC, codeSource, crnCompoundViewer, showSBOL, crnExport); +var exportOperation = new ExportOperation.Exporter(classicGEC, crnEditor, crnSelector, crnExport); +var simulateOperation = new SimulateOperation.Operation(crnEditor, crnSelector, simRunner, simViewer, ctmcCompoundViewer, probabilityMapsViewer, crnCompoundViewer, crnExport, unitsExtractor, plotSettingsExtractor, SumToVum.getModelfromSim, SumToVum.getExportsFromSim, SumToVum.getStateSpaceFromSim, SumToVum.Convert); +var simulateSpatial1DOperation = new Spatial1DSimulation.Operation(crnEditor, crnSelector, spat1DSimRunner, spatialViewer1D); +var simulateSpatial2DOperation = new Spatial2DSimulation.Operation(crnEditor, crnSelector, spat2DSimRunner, spatialViewer2D); +var synthesisOperation = new SynthesisOperation(crnEditor, synthesisAdapter, synthesisViewer); + +var autoChoiceSimulationOperation = new DispatchedSimulateOperation( + currentCRNSimulationType, + simulateSpatial1DOperation, $('#spatial1dViewer'), + simulateSpatial2DOperation, $('#spatial2dViewer'), + simulateOperation, $('#simulationViewer')); + +var inferOperation = new InferOperation.Operation(crnEditor, currentlySelectedDataSetSource, infRunner, infViewer, crnExport, plotSettingsExtractorForInference); + +var ssaOperation = new SSAOperation(crnEditor, ssaRunner, ctmcCompoundViewer, false); + +var selectGECCodeTab = new TabSelectOperation.Operation($("#gecTabs"), "#gecCode"); +var selectCRNDirectivesTab = new TabSelectOperation.Operation($('#inputTabs'), "#crnDirectives"); +var selectInferTab = new TabSelectOperation.Operation($('#resultsTabs'), "#inferenceViewer"); +var selectModelDynamicsTab = new TabSelectOperation.Operation($('#inferenceViewer'), "#inferenceDynamics"); +var selectSimulationTab = new TabSelectOperation.Operation($('#resultsTabs'), "#simulationViewerTab"); +var selectSSATab = new TabSelectOperation.Operation($('#resultsTabs'), "#StatesViewerTab"); +var selectSSATextTab = new TabSelectOperation.Operation($('#StatesViewerTab'), "#ssaTextTab"); +var selectSBOLTab = new TabSelectOperation.Operation($('#resultsTabs'), '#visbolTab'); +var selectSynthesisTab = new TabSelectOperation.Operation($('#resultsTabs'), "#synthesisTab"); + +//var simHintScreen = new HintScreen.HintScreen(autoChoiceSimulationOperation); +//var graphHintScreen = new HintScreen.HintScreen(new HintScreen.CombinedHintRemoveNotifier([parseCrnOperation])); + + +//Phase 3. Setting up the layout +// Turn the main areas into tabs. + +IDDTabs(null, (newPanel => { + // Force redraw of visbol when the relevant tab is focused (workaround for issue where visbol doesn't draw on hidden tabs). + if (newPanel[0].id == 'visbolTab') + visbolDesign.redraw(); +})); + +//bind functional components +codeSource.AutoBind(); +gecCodeSource.AutoBind(); +partsDBCodeSource.AutoBind(); +reactionsDBCodeSource.AutoBind(); +crnEditor.Bind(document.getElementById('crnTabs')); +inferenceGraphViewer.Bind(document.getElementById('inferenceGraph')); +var exportAreas = $(".c-export").get(); +for (var c in exportAreas) + crnExport.Bind(exportAreas[c]); +crnExport.BindToTabs(document.getElementById("crnExport")); +dataSetList.Bind($("#datasets-viewer").get()[0]); +dataSetViewer.Bind($("#dataset-viewer").get()[0]); +//simHintScreen.Bind(document.getElementById('simulationHintScreen')); +//graphHintScreen.Bind(document.getElementById('graphHintScreen')); +simViewer.Bind(document.getElementById('simulationViewer')); +spatialViewer1D.bind(document.getElementById('spatial1dViewer')); +spatialViewer2D.bind(document.getElementById('spatial2dViewer')); +ssaSummaryViewer.Bind(document.getElementById('ssaSummary')); +infDynamicsViewer.Bind(document.getElementById('inferenceDynamics')); +infParamViewer.Bind(document.getElementById('inferenceParameters')); +infPosteriorViewer.Bind(document.getElementById('inferencePosterior')); +infSummary.Bind(document.getElementById('inferenceSummary')); +ssaTextViewer.Bind(document.getElementById('ssaTextTab')); +probabilityMapsViewer.Bind(document.getElementById('probabilitiesTab')); +ssaGraphViewer.Bind(document.getElementById('ssaGraph')); +crnGraphViewer.Bind(document.getElementById('crnGraph')); +longOperationsManager.Bind(document.getElementById('toolbar')); +crnSelector.Bind(document.getElementById('CRNSelector')); +ko.applyBindings(crnVM, document.getElementById('crnInferenceGraphTab')); +options.bind(document.getElementById('options')); +synthesisViewer.Bind(document.getElementById('synthesisTab')); + +dataSetList.getSelectedObservable().subscribe((val) => { + val ? dataSetViewer.Show(val) : dataSetViewer.Show(null); +}); + +var files = ["TestInference.txt", "Join_Simulated.txt", "AM_obs.csv", "AM_obs_noised.csv", + "Rep_Simulated.csv"]; +dataSetList.Initialize("Examples/Observations/", files); + +partsDBCodeSource.ShowCode(classicGEC.Parts); +reactionsDBCodeSource.ShowCode(classicGEC.Reactions); +$("#gecTabs").tabs("option", "active", 2); + +function getActiveTabID(tabName: string) { + return $("#" + tabName + " .ui-tabs-panel:visible").attr("id"); +} +function getActiveInputTabID() { + return getActiveTabID("inputTabs"); +} +function getActiveCrnTabID() { + return getActiveTabID("crnTabs"); +} +function getActiveGECTabID() { + return getActiveTabID("gecTabs"); +} + +$("#separator").draggable({ + axis: "x", + containment: "parent", + scroll: false, + drag: (event, ui) => { + var pos = ui.position.left; + var percLeft = 100 * pos / ui.helper.parent().width(); + var percRight = 100 - percLeft; + $("#input-area").css({ width: "calc(" + percLeft + "% - 5px)" }); + $("#output-area").css({ width: "calc(" + percRight + "% - 15px)" }); + InteractiveDataDisplay.updateLayouts($("#output-area")); + }, + stop: (event, ui) => { + let left = 100 * ui.position.left / ui.helper.parent().width(); + $("#separator").css({ left: left + "%" }); + } +}); + + +$("#dataset-separator").draggable({ + axis: "y", + containment: "#crnData", + cursorAt: { top: 4 }, + scroll: false, + drag: function (event, ui) { + var pos = ui.position.top; + var percTop = 100 * pos / ui.helper.parent().height(); + var percBottom = 100 - percTop; + $("#datasets-viewer").css({ height: "calc(" + percTop + "% - 4px)" }); + $("#dataset-viewer").css({ height: "calc(" + percBottom + "% - 4px)" }); + } +}); +$("#dataset-separator").css({ position: "static" }); // jqueryui draggable sets position to relative automatically + +//Phase 4. Setting up button handlers + +var isSelectingSolution = false; +longOperationsManager.CanStartNewAction.subscribe(val => { + if (isSelectingSolution && val) { + setTimeout(() => solutionSelector.focus()); + isSelectingSolution = false; + } +}); +solutionSelector.onchange = () => { + var operations = [selectSolutionOperation, exportOperation]; + isSelectingSolution = true; + longOperationsManager.EnqueueOperations(operations); +} + +document.getElementById('parseButton').onclick = function (e) { + var tabID = getActiveInputTabID(); + var operations: Array = [] + switch (tabID) { + case "gecTabs": + tabID = getActiveGECTabID(); + switch (tabID) { + case "gecParts": + case "gecReactions": + case "gecCode": + operations = [parseGecOperation, selectGECCodeTab, selectSBOLTab, selectSolutionOperation, exportOperation]; + break; + default: + throw "not implemented yet"; + } + break; + case "crnTabs": + tabID = getActiveCrnTabID(); + switch (tabID) { + case "crnData": + case "crnCode"://code + operations = [parseCrnOperation, exportOperation, selectCRNDirectivesTab]; + break; + case "crnDirectives"://directives + case "crnParameters"://parameters + case "crnSpecies"://species + case "crnReactions"://reactions + case "crnInferenceGraph": // inference graph + operations = [parseCrnOperation]; + break; + default: + throw "not implemented yet"; + } + break; + } + longOperationsManager.EnqueueOperations(operations); +} + +document.getElementById('exportButton').onclick = function (e) { + var tabID = getActiveInputTabID(); + var operations: Array = []; + switch (tabID) { + case "gecTabs": + switch (getActiveGECTabID()) { + case "gecParts": + case "gecReactions": + case "gecCode": + operations = [parseGecOperation, selectGECCodeTab, selectSolutionOperation, exportOperation]; + break; + default: + throw "not implemented yet"; + } + break; + case "crnTabs": + switch (getActiveCrnTabID()) { + case "crnData": + case "crnCode"://crn code + operations = [parseCrnOperation, exportOperation]; + break; + case "crnDirectives"://directives + case "crnParameters"://parameters + case "crnSpecies"://species + case "crnReactions"://reactions + case "crnInferenceGraph": // inference graph + operations = [exportOperation]; + break; + default: + throw "not implemented yet"; + } + } + longOperationsManager.EnqueueOperations(operations); +} + +document.getElementById('simulateButton').onclick = function (e) { + var tabID = getActiveInputTabID(); + var operations: Array = [] + switch (tabID) { + case "gecTabs": + tabID = getActiveGECTabID(); + switch (tabID) { + case "gecParts": + case "gecReactions": + case "gecCode": + operations = [parseGecOperation, selectGECCodeTab, selectSolutionOperation, parseCrnOperation, selectSimulationTab, autoChoiceSimulationOperation]; + break; + default: + throw "not implemented yet"; + } + break; + case "crnTabs": + tabID = getActiveCrnTabID(); + switch (tabID) { + case "crnData": + case "crnCode"://code + operations = [parseCrnOperation, exportOperation, selectSimulationTab, autoChoiceSimulationOperation]; + break; + case "crnDirectives"://directives + case "crnParameters"://parameters + case "crnSpecies"://species + case "crnReactions"://reactions + case "crnInferenceGraph": // inference graph + operations = [exportOperation, selectSimulationTab, autoChoiceSimulationOperation]; + break; + default: + throw "not implemented yet"; + } + break; + } + longOperationsManager.EnqueueOperations(operations); +} + +document.getElementById('synthesisButton').onclick = function (e) { + if (!longOperationsManager.CanStartNewAction()) + return; + var tabIndex = getActiveInputTabID(); + var operations: Array = [] + switch (tabIndex) { + case "sgTab": + switch (getActiveGECTabID()) { + case "gecParts": + case "gecReactions": + case "gecCode": + operations = [parseGecOperation, selectGECCodeTab, selectSolutionOperation, parseCrnOperation, selectSynthesisTab, synthesisOperation]; + break; + default: + throw "not implemented yet"; + } + break; + case "crnTabs": + switch (getActiveCrnTabID()) { + case "crnData": + case "crnCode"://code + operations = [parseCrnOperation, exportOperation, selectSynthesisTab, synthesisOperation]; + break; + case "crnDirectives"://directives + case "crnParameters"://parameters + case "crnSpecies"://species + case "crnReactions"://reactions + case "crnInferenceGraph"://inference graph + operations = [selectSynthesisTab, synthesisOperation]; + break; + default: + throw "not implemented yet"; + } + } + longOperationsManager.EnqueueOperations(operations); +} + +document.getElementById('statesButton').onclick = function (e) { + var tabID = getActiveInputTabID(); + var operations: Array = [] + switch (tabID) { + case "gecTabs": + tabID = getActiveGECTabID(); + switch (tabID) { + case "gecParts": + case "gecReactions": + case "gecCode": + operations = [parseGecOperation, selectGECCodeTab, selectSolutionOperation, parseCrnOperation, selectSSATab, selectSSATextTab, ssaOperation]; + break; + default: + throw "not implemented yet"; + } + break; + case "crnTabs": + tabID = getActiveCrnTabID(); + switch (tabID) { + case "crnData": + case "crnCode"://code + operations = [parseCrnOperation, exportOperation, selectSSATab, selectSSATextTab, ssaOperation]; + break; + case "crnDirectives"://directives + case "crnParameters"://parameters + case "crnSpecies"://species + case "crnReactions"://reactions + case "crnInferenceGraph": // inference graph + operations = [exportOperation, selectSSATab, selectSSATextTab, ssaOperation]; + break; + default: + throw "not implemented yet"; + } + break; + } + longOperationsManager.EnqueueOperations(operations); +} + +document.getElementById('inferButton').onclick = function (e) { + var tabID = getActiveInputTabID(); + var operations: Array = [] + switch (tabID) { + case "gecTabs": + tabID = getActiveGECTabID(); + switch (tabID) { + case "gecParts": + case "gecReactions": + case "gecCode": + operations = [parseGecOperation, selectGECCodeTab, selectSolutionOperation, parseCrnOperation, selectInferTab, selectModelDynamicsTab, inferOperation]; + break; + default: + throw "not implemented yet"; + } + break; + case "crnTabs": + tabID = getActiveCrnTabID(); + switch (tabID) { + case "crnData": + case "crnCode"://code + operations = [parseCrnOperation, exportOperation, selectInferTab, selectModelDynamicsTab, inferOperation]; + break; + case "crnDirectives"://directives + case "crnParameters"://parameters + case "crnSpecies"://species + case "crnReactions"://reactions + case "crnInferenceGraph": // inference graph + operations = [exportOperation, selectInferTab, selectModelDynamicsTab, inferOperation]; + break; + default: + throw "not implemented yet"; + } + break; + } + longOperationsManager.EnqueueOperations(operations); +} + +document.getElementById('stopButton').onclick = function (e) { + longOperationsManager.Stop(); +} + +//serviceWorker.Bind(document.getElementById('worker')); + +Utils.RemoveLoadingOverlay(); + +console.log("ClassicGEC loaded"); \ No newline at end of file diff --git a/ClassicGEC/ClassicGECHTML5/Scripts/Features.ts b/ClassicGEC/ClassicGECHTML5/Scripts/Features.ts new file mode 100644 index 0000000..bcc69aa --- /dev/null +++ b/ClassicGEC/ClassicGECHTML5/Scripts/Features.ts @@ -0,0 +1,9 @@ +//bind to specific DOM element and occupy it +export interface IUIBindable { + Bind(elem: HTMLElement): void; +} + +//bind to the DOM, but automatically finds out a place to bind (e.g. by predefined element id) +export interface IUIAutoBindable { + AutoBind(): void; +} \ No newline at end of file diff --git a/ClassicGEC/ClassicGECHTML5/Scripts/GECCodeEditor.ts b/ClassicGEC/ClassicGECHTML5/Scripts/GECCodeEditor.ts new file mode 100644 index 0000000..2ce09ca --- /dev/null +++ b/ClassicGEC/ClassicGECHTML5/Scripts/GECCodeEditor.ts @@ -0,0 +1,10 @@ +import CodePad from "../../../HTML5SharedGUI/CodeEditor/Scripts/CodePad"; +import { INamedMonarchLanguage } from '../../../HTML5SharedGUI/CodeEditor/Scripts/CodeEditor'; + +class GECCodeEditor extends CodePad { + constructor(language: INamedMonarchLanguage, examples: Array) { + super(language, "gec-editor-widget", examples); + } +} + +export default GECCodeEditor; \ No newline at end of file diff --git a/ClassicGEC/ClassicGECHTML5/Scripts/GECLang.ts b/ClassicGEC/ClassicGECHTML5/Scripts/GECLang.ts new file mode 100644 index 0000000..e0597b2 --- /dev/null +++ b/ClassicGEC/ClassicGECHTML5/Scripts/GECLang.ts @@ -0,0 +1,176 @@ +var GECLanguage = { + displayName: 'GEC', // start by writing your language name here + name: 'GEC', + mimeTypes: ['text/x-crn'], + fileExtensions: ['crn'], + + // used in the editor to insert comments (ctrl+/ or shift+alt+A) + lineComment: '// ', + blockCommentStart: '(*', + blockCommentEnd: '*)', + + // Set defaultToken to invalid to see what you do not tokenize yet + //defaultToken: 'invalid', + + keywords: [ + "CNil", + "END", + "Nil", + "SNil", + "agent", + "and", + "as", + "binding", + "bool", + "comp", + "conc", + "copy", + "directive", + "ff", + "float", + "force", + "gen", + "if", + "init", + "inside", + "int", + "kappa", + "module", + "moments", + "mutation", + "new", + "not", + "or", + "phos", + "plot", + "plot_settings", + "rate", + "rates", + "sample", + "scale", + "script", + "specout", + "spec", + "string", + "sum", + "tolerance", + "abstolerance", + "reltolerance", + "parameter", + "spatialplot", + "spatialic", + "diffusion", + "dt", + "xmax", + "nx", + "task", + "theta", + "tt", + "vol", + "compilation", + "simulation", + "event", + "parameters", + "fit", + "sweep", + "fit_run", + "plotwindow", + "predicate", + "query", + "seed", + "synthesis" + ], + + /*builtins: [ + 'rank', 'rankdir', 'ranksep', 'size', 'ratio', + 'label', 'headlabel', 'taillabel', + 'arrowhead', 'samehead', 'samearrowhead', + 'arrowtail', 'sametail', 'samearrowtail', 'arrowsize', + 'labeldistance', 'labelangle', 'labelfontsize', + 'dir', 'width', 'height', 'angle', + 'fontsize', 'fontcolor', 'same', 'weight', 'color', + 'bgcolor', 'style', 'shape', 'fillcolor', 'nodesep', 'id', + ],*/ + + attributes: [ + 'doublecircle', 'circle', 'diamond', 'box', 'point', 'ellipse', 'record', + 'inv', 'invdot', 'dot', 'dashed', 'dotted', 'filled', 'back', 'forward', + ], + + // we include these common regular expressions + symbols: /[=>&]+/, 'string.html'], + [/&\w+;/, 'string.html.escape'], + [/&/, 'string.html'], + [//, { token: 'string.html.quote', bracket: '@close', next: '@pop' }], + ],*/ + + string: [ + [/[^\\"&]+/, 'string'], + [/\\"/, 'string.escape'], + [/&\w+;/, 'string.escape'], + [/[\\&]/, 'string'], + [/"/, { token: 'string.quote', bracket: '@close', next: '@pop' }] + ], + + whitespace: [ + [/[ \t\r\n]+/, 'white'], + [/\/\*/, 'comment', '@comment'], + [/\/\/.*$/, 'comment'], + [/#.$/, 'comment'], + ], + }, +}; +export default GECLanguage; \ No newline at end of file diff --git a/ClassicGEC/ClassicGECHTML5/Scripts/Operations/GecParseOperation.ts b/ClassicGEC/ClassicGECHTML5/Scripts/Operations/GecParseOperation.ts new file mode 100644 index 0000000..cf4839f --- /dev/null +++ b/ClassicGEC/ClassicGECHTML5/Scripts/Operations/GecParseOperation.ts @@ -0,0 +1,76 @@ +import * as $ from 'jquery'; +import GEC from '../../../ClassicGECTSWrapper/Scripts/ClassicGEC'; +import * as Interfaces from '../../../ClassicGECTSWrapper/Scripts/Interfaces'; +import * as CRN from '../../../../CRNEngine/CRNEngineTSWrapper/Scripts/Interfaces'; +import * as Operations from "../../../../HTML5SharedGUI/HTML5CRN_Lib/Scripts/Operations/LongOperations"; +import * as GenericParsing from "../../../../HTML5SharedGUI/HTML5CRN_Lib/Scripts/Operations/GenericCodeParsing"; + +export interface IExportsViewer { + ShowExport(update: CRN.ExportDef): void; +} + +export class Operation implements Operations.IOperation { + constructor( + private gec: GEC, + private codeSource: GenericParsing.ICodeSource, + private partsSource: GenericParsing.ICodeSource, + private reactionsSource: GenericParsing.ICodeSource, + private showSolutionsCount: (count: number) => void, + private showSBOL: (jsbol: Interfaces.jSBOLDocument) => void, + private exports: IExportsViewer, + private codeErrorDisplay: GenericParsing.IErrorDisplay, + private partsErrorDisplay: GenericParsing.IErrorDisplay, + private reactionsErrorDisplay: GenericParsing.IErrorDisplay) { + } + + public Initiate(): JQueryPromise { + this.gec.Parts = this.partsSource.GetCode(); + this.gec.Reactions = this.reactionsSource.GetCode(); + var code = this.codeSource.GetCode(); + var observables = this.gec.UserCompile(code); + var deferred = jQuery.Deferred(); + observables.solution_count.subscribe(next => { + this.showSolutionsCount(next); + this.exitMessage = "completed with " + (next == 0 ? "no" : next.toString()) + " solution" + (next == 1 ? "" : "s"); + this.codeErrorDisplay.ClearErrors(); + this.partsErrorDisplay.ClearErrors(); + this.reactionsErrorDisplay.ClearErrors(); + deferred.resolve(next); + }, error => { + this.showSolutionsCount(0); + var errorString: string = error.message == null ? JSON.stringify(error) : error.message; + this.exitMessage = "failed with " + errorString; + var errorObj: GenericParsing.IError = { text: errorString }; + if (error.positions != null && error.positions.length > 0) { + var row = error.positions[0].row; + var column = error.positions[0].column + 1; + errorObj.text += " at row " + row + ", column " + column; + var len = error.positions[0].text.length; + errorObj.location = { rowStart: row, rowEnd: row, colStart: column, colEnd: column }; + } + if (errorString.substr(0, 5) == "parts") + this.partsErrorDisplay.ShowErrors([errorObj]); + else if (errorString.substr(0, 9) == "reactions") + this.reactionsErrorDisplay.ShowErrors([errorObj]); + else + this.codeErrorDisplay.ShowErrors([errorObj]); + deferred.reject(error); + }, () => { }); + observables.jsbol.subscribeOnNext(jsbol => this.showSBOL(jsbol)); + observables.exports.subscribe(exp => this.exports.ShowExport(exp), err => { }, () => { }); + return deferred; + } + + public Abort(): void { + this.gec.Abort(); + } + + public GetName(): string { + return "GEC parsing"; + } + + private exitMessage: string; + public GetExitMessage(): string { + return this.exitMessage; + } +} \ No newline at end of file diff --git a/ClassicGEC/ClassicGECHTML5/Scripts/Operations/GetSolutionOperation.ts b/ClassicGEC/ClassicGECHTML5/Scripts/Operations/GetSolutionOperation.ts new file mode 100644 index 0000000..df84802 --- /dev/null +++ b/ClassicGEC/ClassicGECHTML5/Scripts/Operations/GetSolutionOperation.ts @@ -0,0 +1,90 @@ +import * as $ from 'jquery'; +import GEC from '../../../ClassicGECTSWrapper/Scripts/ClassicGEC'; +import * as Interfaces from '../../../ClassicGECTSWrapper/Scripts/Interfaces'; +import * as CRN from '../../../../CRNEngine/CRNEngineTSWrapper/Scripts/Interfaces'; +import * as Operations from "../../../../HTML5SharedGUI/HTML5CRN_Lib/Scripts/Operations/LongOperations"; +import * as HintScreen from "../../../../HTML5SharedGUI/GenericComponents/Scripts/HintScreen"; + +//Dependencies to be injected + +export interface ICodeViewer { + ShowCode(code: string): void; +} + +/** Displays the CRN entities with GUI */ +export interface ICRNViewer { + UpdateValuesWith(update: CRN.IG, customSettings: void, fromJIT: boolean): void; +} + +export interface IExportsViewer { + ShowExport(update: CRN.ExportDef): void; +} + +/** + * Gets the code from the CodeEditor, passes it to the parser, receives CRN entities, updates CRN viewer with them, updates data files selecting control with parsed "data directive" files. + * If any parsing error occurs, displays it with errorDisplay + */ +export class Operation implements Operations.IOperation, HintScreen.IHintRemoveNotifier { + constructor( + private getIdx: () => number, + private gec: GEC, + private crnCodeViewer: ICodeViewer, + private crnViewer: ICRNViewer, + private showSBOL: (jsbol: Interfaces.jSBOLDocument) => void, + private exports: IExportsViewer) { + } + + public Initiate(): JQueryPromise { + var deferred = $.Deferred(); + var idx = this.getIdx(); + if (idx == -1) { + this.m_ExitMessage = "no solutions found"; + deferred.reject(); + } + else { + var observables = this.gec.UserGetSolution(idx); + var error = (err: any) => { + this.m_ExitMessage = JSON.stringify(err); + deferred.reject(); + } + observables.solution.subscribe(solution => { + this.m_ExitMessage = "Solution " + idx + " selected"; + this.InterpretSuccessfulResults(solution); + deferred.resolve(); + }, error, () => { }); + observables.jsbol.subscribe(jsbol => this.showSBOL(jsbol), err => { }, () => { }); + observables.exports.subscribe(exp => this.exports.ShowExport(exp), err => { }, () => { }); + } + return deferred; + } + + public Abort() { + this.gec.Abort(); + this.m_ExitMessage = "Aborted"; + } + + //defining abstract functions + public GetName() { + return "Retrieving GEC solution"; + } + + private m_ExitMessage: string; + + public GetExitMessage() { + return this.m_ExitMessage; + } + + protected InterpretSuccessfulResults(solution: Interfaces.GECSolution) { + this.crnViewer.UpdateValuesWith(solution.model, null, false); + this.crnCodeViewer.ShowCode(solution.code); + this.notificationCallbacks.forEach(c => { c() }); // notifing that hints now can be removed + } + + //HintScreen.IHintRemoveNotifier implementation + private notificationCallbacks: Array<() => void> = []; + + public SubscribeRemoveHint(callback: () => void) { + this.notificationCallbacks.push(callback); + } +} + diff --git a/ClassicGEC/ClassicGECHTML5/Scripts/PartsCodeEditor.ts b/ClassicGEC/ClassicGECHTML5/Scripts/PartsCodeEditor.ts new file mode 100644 index 0000000..fbd0f6c --- /dev/null +++ b/ClassicGEC/ClassicGECHTML5/Scripts/PartsCodeEditor.ts @@ -0,0 +1,10 @@ +import CodePad from "../../../HTML5SharedGUI/CodeEditor/Scripts/CodePad"; +import { INamedMonarchLanguage } from '../../../HTML5SharedGUI/CodeEditor/Scripts/CodeEditor'; + +class GECCodeEditor extends CodePad { + constructor(language: INamedMonarchLanguage, examples: Array) { + super(language, "parts-editor-widget", examples); + } +} + +export default GECCodeEditor; \ No newline at end of file diff --git a/ClassicGEC/ClassicGECHTML5/Scripts/PartsLang.ts b/ClassicGEC/ClassicGECHTML5/Scripts/PartsLang.ts new file mode 100644 index 0000000..1ad503c --- /dev/null +++ b/ClassicGEC/ClassicGECHTML5/Scripts/PartsLang.ts @@ -0,0 +1,171 @@ +var PartsLanguage = { + displayName: 'GECParts', // start by writing your language name here + name: 'GECParts', + mimeTypes: ['text/x-crn'], + fileExtensions: ['crn'], + + // used in the editor to insert comments (ctrl+/ or shift+alt+A) + lineComment: '// ', + blockCommentStart: '(*', + blockCommentEnd: '*)', + + // Set defaultToken to invalid to see what you do not tokenize yet + //defaultToken: 'invalid', + + keywords: [ + "CNil", + "END", + "Nil", + "SNil", + "agent", + "and", + "as", + "binding", + "bool", + "comp", + "conc", + "copy", + "directive", + "ff", + "float", + "force", + "gen", + "if", + "init", + "inside", + "int", + "kappa", + "module", + "mutation", + "new", + "not", + "or", + "phos", + "plot", + "rate", + "sample", + "scale", + "script", + "specout", + "spec", + "string", + "sum", + "tolerance", + "abstolerance", + "reltolerance", + "parameter", + "spatialplot", + "spatialic", + "diffusion", + "dt", + "xmax", + "nx", + "theta", + "tt", + "vol", + "compilation", + "simulation", + "event", + "parameters", + "fit", + "sweep", + "fit_run", + "plotwindow", + "predicate", + "query", + "seed" + ], + + /*builtins: [ + 'rank', 'rankdir', 'ranksep', 'size', 'ratio', + 'label', 'headlabel', 'taillabel', + 'arrowhead', 'samehead', 'samearrowhead', + 'arrowtail', 'sametail', 'samearrowtail', 'arrowsize', + 'labeldistance', 'labelangle', 'labelfontsize', + 'dir', 'width', 'height', 'angle', + 'fontsize', 'fontcolor', 'same', 'weight', 'color', + 'bgcolor', 'style', 'shape', 'fillcolor', 'nodesep', 'id', + ],*/ + + attributes: [ + 'doublecircle', 'circle', 'diamond', 'box', 'point', 'ellipse', 'record', + 'inv', 'invdot', 'dot', 'dashed', 'dotted', 'filled', 'back', 'forward', + ], + + // we include these common regular expressions + symbols: /[=>&]+/, 'string.html'], + [/&\w+;/, 'string.html.escape'], + [/&/, 'string.html'], + [//, { token: 'string.html.quote', bracket: '@close', next: '@pop' }], + ],*/ + + string: [ + [/[^\\"&]+/, 'string'], + [/\\"/, 'string.escape'], + [/&\w+;/, 'string.escape'], + [/[\\&]/, 'string'], + [/"/, { token: 'string.quote', bracket: '@close', next: '@pop' }] + ], + + whitespace: [ + [/[ \t\r\n]+/, 'white'], + [/\/\*/, 'comment', '@comment'], + [/\/\/.*$/, 'comment'], + [/#.$/, 'comment'], + ], + }, +}; +export default PartsLanguage; \ No newline at end of file diff --git a/ClassicGEC/ClassicGECHTML5/Scripts/ReactionsCodeEditor.ts b/ClassicGEC/ClassicGECHTML5/Scripts/ReactionsCodeEditor.ts new file mode 100644 index 0000000..3296c1a --- /dev/null +++ b/ClassicGEC/ClassicGECHTML5/Scripts/ReactionsCodeEditor.ts @@ -0,0 +1,10 @@ +import CodePad from "../../../HTML5SharedGUI/CodeEditor/Scripts/CodePad"; +import { INamedMonarchLanguage } from '../../../HTML5SharedGUI/CodeEditor/Scripts/CodeEditor'; + +class GECCodeEditor extends CodePad { + constructor(language: INamedMonarchLanguage, examples: Array) { + super(language, "reactions-editor-widget", examples); + } +} + +export default GECCodeEditor; \ No newline at end of file diff --git a/ClassicGEC/ClassicGECHTML5/Scripts/ReactionsLang.ts b/ClassicGEC/ClassicGECHTML5/Scripts/ReactionsLang.ts new file mode 100644 index 0000000..b95b4a5 --- /dev/null +++ b/ClassicGEC/ClassicGECHTML5/Scripts/ReactionsLang.ts @@ -0,0 +1,172 @@ +var ReactionsLanguage = { + displayName: 'GECReactions', // start by writing your language name here + name: 'GECReactions', + mimeTypes: ['text/x-crn'], + fileExtensions: ['crn'], + + // used in the editor to insert comments (ctrl+/ or shift+alt+A) + lineComment: '// ', + blockCommentStart: '(*', + blockCommentEnd: '*)', + + // Set defaultToken to invalid to see what you do not tokenize yet + //defaultToken: 'invalid', + + keywords: [ + "CNil", + "END", + "Nil", + "SNil", + "agent", + "and", + "as", + "binding", + "bool", + "comp", + "conc", + "copy", + "directive", + "ff", + "float", + "force", + "gen", + "if", + "init", + "inside", + "int", + "kappa", + "module", + "mutation", + "new", + "not", + "or", + "phos", + "plot", + "rate", + "rates", + "sample", + "scale", + "script", + "specout", + "spec", + "string", + "sum", + "tolerance", + "abstolerance", + "reltolerance", + "parameter", + "spatialplot", + "spatialic", + "diffusion", + "dt", + "xmax", + "nx", + "theta", + "tt", + "vol", + "compilation", + "simulation", + "event", + "parameters", + "fit", + "sweep", + "fit_run", + "plotwindow", + "predicate", + "query", + "seed" + ], + + /*builtins: [ + 'rank', 'rankdir', 'ranksep', 'size', 'ratio', + 'label', 'headlabel', 'taillabel', + 'arrowhead', 'samehead', 'samearrowhead', + 'arrowtail', 'sametail', 'samearrowtail', 'arrowsize', + 'labeldistance', 'labelangle', 'labelfontsize', + 'dir', 'width', 'height', 'angle', + 'fontsize', 'fontcolor', 'same', 'weight', 'color', + 'bgcolor', 'style', 'shape', 'fillcolor', 'nodesep', 'id', + ],*/ + + attributes: [ + 'doublecircle', 'circle', 'diamond', 'box', 'point', 'ellipse', 'record', + 'inv', 'invdot', 'dot', 'dashed', 'dotted', 'filled', 'back', 'forward', + ], + + // we include these common regular expressions + symbols: /[=>&]+/, 'string.html'], + [/&\w+;/, 'string.html.escape'], + [/&/, 'string.html'], + [//, { token: 'string.html.quote', bracket: '@close', next: '@pop' }], + ],*/ + + string: [ + [/[^\\"&]+/, 'string'], + [/\\"/, 'string.escape'], + [/&\w+;/, 'string.escape'], + [/[\\&]/, 'string'], + [/"/, { token: 'string.quote', bracket: '@close', next: '@pop' }] + ], + + whitespace: [ + [/[ \t\r\n]+/, 'white'], + [/\/\*/, 'comment', '@comment'], + [/\/\/.*$/, 'comment'], + [/#.$/, 'comment'], + ], + }, +}; +export default ReactionsLanguage; \ No newline at end of file diff --git a/ClassicGEC/ClassicGECHTML5/Styles/App.css b/ClassicGEC/ClassicGECHTML5/Styles/App.css new file mode 100644 index 0000000..61297df --- /dev/null +++ b/ClassicGEC/ClassicGECHTML5/Styles/App.css @@ -0,0 +1,8 @@ +#solution-selector-container { + margin-left: 20px; + margin-right: 20px; + display: inline; +} +#solution-selector { + min-width: 50px; +} diff --git a/ClassicGEC/ClassicGECHTML5/Templates/index.html b/ClassicGEC/ClassicGECHTML5/Templates/index.html new file mode 100644 index 0000000..faefbde --- /dev/null +++ b/ClassicGEC/ClassicGECHTML5/Templates/index.html @@ -0,0 +1,259 @@ + + + + Classic GEC Tool + + + + +
+
+
+

Loading...

+
+
+
+ +
+
+ +
+ +
+ +
+
+ +
+
+ +
+
+
+ +
+
+ +
+
+
+ +
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+
+ +
+ +
+ +
+
+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+ + +
+
+ +
+ +
+
+ +
+
+ +
+ +
+
+ +
+
+ +
+
+
+ +
+
+
+ +
+ +
+
+

GEC Tool

+
+
+ +
+
+ +
+
+
+ +
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/ClassicGEC/ClassicGECHTML5/build.fsx b/ClassicGEC/ClassicGECHTML5/build.fsx new file mode 100644 index 0000000..a2df255 --- /dev/null +++ b/ClassicGEC/ClassicGECHTML5/build.fsx @@ -0,0 +1,37 @@ +#r "paket: groupref Build //" +#load "./.fake/build.fsx/intellisense.fsx" + +#if !FAKE +#r "netstandard" +#endif + +open Fake.Core +open Fake.Core.TargetOperators + +#load "../../Builds/Builds/BuildHelper.fs" +open BuildHelper + +let localPort = "18852" +let projectFile = "ClassicGECHTML5.csproj" +let projectFolder = "." + +Target.create "Run" (fun _ -> + runDotNet ("serve -d dist -p "+localPort+" -o") projectFolder +) + +Target.create "Clean" (fun _ -> + runDotNet "clean" projectFolder +) + +Target.create "Build" (fun _ -> + runDotNet "build" projectFolder +) + +Target.create "Yarn" yarnInstall + +"Clean" + ==> "Yarn" + ==> "Build" + ==> "Run" + +Target.runOrDefault "Build" diff --git a/ClassicGEC/ClassicGECHTML5/declarations.d.ts b/ClassicGEC/ClassicGECHTML5/declarations.d.ts new file mode 100644 index 0000000..8958425 --- /dev/null +++ b/ClassicGEC/ClassicGECHTML5/declarations.d.ts @@ -0,0 +1,18 @@ +declare module "*.html" +declare module "idd" { + var InteractiveDataDisplay: any; + export = InteractiveDataDisplay; +} +declare module "tinycolor" { + var tinycolor: any; + export = tinycolor; +} +declare module "worker-loader*" { + class WebpackWorker extends Worker { + constructor(); + } + export default WebpackWorker; +} +declare module "*index.js" +declare module "*main.js" +declare module "sboljs" \ No newline at end of file diff --git a/ClassicGEC/ClassicGECHTML5/favicon.ico b/ClassicGEC/ClassicGECHTML5/favicon.ico new file mode 100644 index 0000000..85a4d9f Binary files /dev/null and b/ClassicGEC/ClassicGECHTML5/favicon.ico differ diff --git a/ClassicGEC/ClassicGECHTML5/paket.references b/ClassicGEC/ClassicGECHTML5/paket.references new file mode 100644 index 0000000..999fa17 --- /dev/null +++ b/ClassicGEC/ClassicGECHTML5/paket.references @@ -0,0 +1,5 @@ +group JavaScriptBuild + +Yarn.MSBuild +Node.js.redist +Microsoft.TypeScript.MSBuild \ No newline at end of file diff --git a/ClassicGEC/ClassicGECHTML5/run.cmd b/ClassicGEC/ClassicGECHTML5/run.cmd new file mode 100644 index 0000000..d8cba23 --- /dev/null +++ b/ClassicGEC/ClassicGECHTML5/run.cmd @@ -0,0 +1 @@ +dotnet fake build --target run \ No newline at end of file diff --git a/ClassicGEC/ClassicGECHTML5/tsconfig.json b/ClassicGEC/ClassicGECHTML5/tsconfig.json new file mode 100644 index 0000000..568e71e --- /dev/null +++ b/ClassicGEC/ClassicGECHTML5/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.common", + "include": [ + "*.ts", + "Scripts/*.ts", + "Scripts/Adapters/*.ts", + "Scripts/Operations/*.ts", + ] +} diff --git a/ClassicGEC/ClassicGECHTML5/web.Debug.config b/ClassicGEC/ClassicGECHTML5/web.Debug.config new file mode 100644 index 0000000..9fdb00f --- /dev/null +++ b/ClassicGEC/ClassicGECHTML5/web.Debug.config @@ -0,0 +1,31 @@ + + + + + + + + + + \ No newline at end of file diff --git a/ClassicGEC/ClassicGECHTML5/web.Release.config b/ClassicGEC/ClassicGECHTML5/web.Release.config new file mode 100644 index 0000000..d71b662 --- /dev/null +++ b/ClassicGEC/ClassicGECHTML5/web.Release.config @@ -0,0 +1,32 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/ClassicGEC/ClassicGECHTML5/web.config b/ClassicGEC/ClassicGECHTML5/web.config new file mode 100644 index 0000000..61577ba --- /dev/null +++ b/ClassicGEC/ClassicGECHTML5/web.config @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + + + + \ No newline at end of file diff --git a/ClassicGEC/ClassicGECHTML5/webpack.config.js b/ClassicGEC/ClassicGECHTML5/webpack.config.js new file mode 100644 index 0000000..92dc0f0 --- /dev/null +++ b/ClassicGEC/ClassicGECHTML5/webpack.config.js @@ -0,0 +1,138 @@ +/// +"use strict"; +var webpack = require('webpack'); +var HtmlWebpackPlugin = require('html-webpack-plugin'); +var CleanWebpackPlugin = require('clean-webpack-plugin'); +var WorkboxPlugin = require('workbox-webpack-plugin'); +var path = require('path'); +var MonacoWebpackPlugin = require('monaco-editor-webpack-plugin'); +var CopyWebpackPlugin = require('copy-webpack-plugin'); + +module.exports = env => { + if (env === undefined || env === null) + env = {}; + if (env.mode === undefined || env === null) + env.mode = "development"; + console.log("Mode is set to " + env.mode); + return { + mode: env.mode, + entry: { + app: "./Scripts/app.js" + }, + output: { + filename: "./[name].[chunkhash].js", + path: path.resolve(__dirname, 'dist') + }, + optimization: { + splitChunks: { + chunks: 'all' + } + }, + // Suppress warnings about large file sizes. This is a complex app and we have a lot of code. That's why we have a loading screen. + performance: { hints: false }, + resolve: { + alias: { + idd$: path.resolve(__dirname, '../../node_modules/interactive-data-display/dist/idd_knockout.js'), + svg$: path.resolve(__dirname, '../../node_modules/svgjs'), + filesaver$: path.resolve(__dirname, '../../node_modules/file-saver'), + jquery$: path.resolve(__dirname, '../../node_modules/jquery') + } + }, + node: { + fs: 'empty' + }, + module: { + rules: [ + { + // https://github.com/webpack/webpack/issues/1406 + // Possible long-term fix: switch from KO to TKO. + test: require.resolve('jquery'), + use: [{ + loader: 'expose-loader', + options: 'jQuery' + }] + }, + { + test: /\.css$/, + use: ['style-loader', 'css-loader'] + }, + { + test: /\.(woff(2)?|ttf|eot)(\?v=\d+\.\d+\.\d+)?$/, + use: [{ + loader: 'file-loader', + options: { + name: '[name].[ext]', + outputPath: 'fonts/' + } + }] + }, + { + test: /\.(svg|png)(\?v=\d+\.\d+\.\d+)?$/, + use: [{ + loader: 'file-loader', + options: { + name: '[name].[ext]', + outputPath: 'img/' + } + }] + }, + { + test: /\.wasm$/, + type: "javascript/auto", + loader: "file-loader" + } + ] + }, + plugins: [ + new CleanWebpackPlugin(['dist']), + new CopyWebpackPlugin([{ + from: 'Examples/**', + to: '.', + context: '../', + flatten: false + }, { + from: 'Examples/**', + to: '.', + context: '../../CRNEngine/', + flatten: false, + }, { + from: '../../HTML5SharedGUI/GenericComponents/Styles/shared.css', + to: 'shared.css', + flatten: true + }, { + from: '../../HTML5SharedGUI/SimulationViewer/Img/refresh_icon.png', + to: 'img/refresh_icon.png', + flatten: true + }, { + from: '../../CRNEngine/HTML5CRN/favicon.ico', + to: 'favicon.ico', + flatten: true + }, { + from: './web.config', + to: '.', + flatten: true + }]), + new webpack.ProvidePlugin({ + $: 'jquery', + jQuery: 'jquery', + Rx: 'rx', + ko: 'knockout', + SVG: 'svgjs', + saveAs: 'file-saver', + jQuery_mousewheel: 'jquery-mousewheel' + }), + new MonacoWebpackPlugin({ languages: [] }), + new HtmlWebpackPlugin({ + template: './Templates/index.html', + filename: './index.html' //relative to root of the application + }), + new WorkboxPlugin.GenerateSW({ + swDest: './service-worker.js', + clientsClaim: true, + skipWaiting: true, + // We have quite a lot of code, but we still want to precache it. + maximumFileSizeToCacheInBytes: 5 * 1024 * 1024 + }) + ] + } +}; \ No newline at end of file diff --git a/ClassicGEC/ClassicGECIntegrationTests/AssemblyInfo.fs b/ClassicGEC/ClassicGECIntegrationTests/AssemblyInfo.fs new file mode 100644 index 0000000..6cb475d --- /dev/null +++ b/ClassicGEC/ClassicGECIntegrationTests/AssemblyInfo.fs @@ -0,0 +1,41 @@ +namespace ClassicGECIntegrationTests.AssemblyInfo + +open System.Reflection +open System.Runtime.CompilerServices +open System.Runtime.InteropServices + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[] +[] +[] +[] +[] +[] +[] +[] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [] +[] +[] + +do + () \ No newline at end of file diff --git a/ClassicGEC/ClassicGECIntegrationTests/ClassicGECIntegrationTests.fsproj b/ClassicGEC/ClassicGECIntegrationTests/ClassicGECIntegrationTests.fsproj new file mode 100644 index 0000000..119142f --- /dev/null +++ b/ClassicGEC/ClassicGECIntegrationTests/ClassicGECIntegrationTests.fsproj @@ -0,0 +1,35 @@ + + + + netcoreapp3.1 + Exe + x64 + x64 + true + + + + + + + + + + + + + ..\..\Lib\Oslo.FSharp\Oslo.FSharp.dll + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ClassicGEC/ClassicGECIntegrationTests/Program.fs b/ClassicGEC/ClassicGECIntegrationTests/Program.fs new file mode 100644 index 0000000..476c5d8 --- /dev/null +++ b/ClassicGEC/ClassicGECIntegrationTests/Program.fs @@ -0,0 +1,35 @@ +open System +open System.IO +open Expecto +open canopy +open canopy.classic +open canopy.types +open Microsoft.AspNetCore.Hosting +open Microsoft.Research.CRNEngineServerLib +open Microsoft.Research.ClassicGECWebServer +open Microsoft.Research.CRNIntegrationTestLib + +[] +let main args = + System.Globalization.CultureInfo.DefaultThreadCurrentCulture <- System.Globalization.CultureInfo.InvariantCulture + + let (groups,timeout,args) = Program.separateArgs args + + let server = Server.startWebServer Program.processRequest Program.homeFolder Program.jobsFolder Program.port + + let result = + try + let url = Server.starturl Program.port + BrowserSetup.configureCanopy timeout + let tests = Tests.tests groups Tests.Localhost url + Program.run args tests + finally + printfn "Shutting down server..." + server.StopAsync() |> ignore + canopy.classic.quit() + + if System.Diagnostics.Debugger.IsAttached then + printf "Press any key to exit" + System.Console.ReadKey() |> ignore + + result \ No newline at end of file diff --git a/ClassicGEC/ClassicGECIntegrationTests/Tests.fs b/ClassicGEC/ClassicGECIntegrationTests/Tests.fs new file mode 100644 index 0000000..fc2c4ee --- /dev/null +++ b/ClassicGEC/ClassicGECIntegrationTests/Tests.fs @@ -0,0 +1,49 @@ +module Tests + +open Expecto +open canopy +open canopy.classic +open OpenQA.Selenium +open Microsoft.Research.CRNIntegrationTestLib.Tests + +let testCaseExample address = testCaseExample address "#gec-editor" + +let tests groups mode address = + let groups = if groups = [||] then [|"default"|] else groups + printfn "Testing: %s" (System.String.Join(", ",groups)) + testList "UI" [ + if Array.contains "all_examples" groups then yield testList "all_examples" [ + load address + let options = (element "#gecCode").FindElement(By.CssSelector ".c-examples").FindElements(By.CssSelector "option") |> Seq.map (fun (opt:IWebElement) -> opt.Text) |> Seq.skip 1 + for ex in options do yield testCaseExample address ex + ] + if Array.contains "default" groups then yield testList "default" [ + //Direct URL request + (*yield testCase "Smoke" <| fun _ -> + let body = + Request.createUrl Get Microsoft.Research.ClassicDSDServer.Program.url + |> Request.responseAsString + |> run + + Expect.stringContains body "Classic DSD Tool" "It really should"*) + //Canopy browser automation + yield testCase "Canopy Smoke" <| fun _ -> + load address + () + + yield testCase "Simulation Smoke" <| fun _ -> + load address + selectExample "#gec-editor" "Basic" + simulate false + () + + (*yield testCase "Inference Smoke" <| fun _ -> + load () + + selectExample "Join - Inference" + + infer() + + ()*) + ] + ] \ No newline at end of file diff --git a/ClassicGEC/ClassicGECIntegrationTests/build.fsx b/ClassicGEC/ClassicGECIntegrationTests/build.fsx new file mode 100644 index 0000000..b91a1a8 --- /dev/null +++ b/ClassicGEC/ClassicGECIntegrationTests/build.fsx @@ -0,0 +1,33 @@ +#r "paket: groupref Build //" +#load ".fake/build.fsx/intellisense.fsx" +open Fake.Core +open Fake.DotNet +open Fake.IO +open Fake.IO.FileSystemOperators +open Fake.IO.Globbing.Operators +open BlackFox.Fake + +#load "../../Builds/Builds/PublishHelper.fs" +open PublishHelper +#load "../ClassicGECWebServer/BuildSettings.fs" + +let copyRequiredFilestoOutput projectDir outDir configuration = + copySundials projectDir outDir configuration + copyWebStuff projectDir outDir ClassicGECServer.BuildSettings.homeFolder + copyJobStuff projectDir outDir ClassicGECServer.BuildSettings.jobsFolder + +let build = BuildTask.createFn "Build" [] (fun args -> + let settings = parseSettings args.Context.Arguments + copyRequiredFilestoOutput settings.["ProjectDir"] settings.["OutDir"] settings.["Configuration"] +) + +//Example: +//dotnet fake build --target Publish ProjectDir="E:\dev\biocomputing\ClassicGEC\ClassicGECServer\" PublishDir="bin\Debug\netcoreapp3.0\publish\" Configuration=Debug +let publish = BuildTask.createFn "Publish" [] (fun args -> + let settings = parseSettings args.Context.Arguments + copyRequiredFilestoOutput settings.["ProjectDir"] settings.["PublishDir"] settings.["Configuration"] +) + +let nothing = BuildTask.createEmpty "Nothing" [] + +BuildTask.runOrDefaultWithArguments nothing \ No newline at end of file diff --git a/ClassicGEC/ClassicGECIntegrationTests/paket.references b/ClassicGEC/ClassicGECIntegrationTests/paket.references new file mode 100644 index 0000000..0d34aef --- /dev/null +++ b/ClassicGEC/ClassicGECIntegrationTests/paket.references @@ -0,0 +1,9 @@ +group DOTNETCORE + +Canopy +Expecto +FSharp.Core +Selenium.WebDriver +Selenium.WebDriver.ChromeDriver +Selenium.WebDriver.GeckoDriver.Win64 +Selenium.WebDriver.MicrosoftWebDriver \ No newline at end of file diff --git a/ClassicGEC/ClassicGECJS/ClassicGECJS.fsproj b/ClassicGEC/ClassicGECJS/ClassicGECJS.fsproj new file mode 100644 index 0000000..35326f4 --- /dev/null +++ b/ClassicGEC/ClassicGECJS/ClassicGECJS.fsproj @@ -0,0 +1,111 @@ + + + + netstandard2.0 + true + + + TRACE;JavaScript + + + TRACE;JavaScript + + + + logicGEC.fs + + + options.fsi + + + options.fs + + + keywords.fs + + + ast.fs + + + subst.fsi + + + subst.fs + + + gecspecies.fs + + + gecreaction.fsi + + + gecreaction.fs + + + directivesParser.fs + + + settings.fs + + + database.fsi + + + database.fs + + + cssubst.fsi + + + cssubst.fs + + + solver.fsi + + + solver.fs + + + NumUtil.fs + + + trans.fs + + + hypothesis.fs + + + program.fs + + + main.fs + + + transCrn.fs + + + gec.fs + + + jsapi.fs + + + + + + + + + + + + + + + + + ..\..\Lib\Oslo-FSharp.websharper\Oslo.FSharp.WebSharper.dll + + + + \ No newline at end of file diff --git a/ClassicGEC/ClassicGECJS/Content/placeholder.js b/ClassicGEC/ClassicGECJS/Content/placeholder.js new file mode 100644 index 0000000..abdc011 --- /dev/null +++ b/ClassicGEC/ClassicGECJS/Content/placeholder.js @@ -0,0 +1 @@ +// This file takes the place of the W# output, in cases where W# is not invoked (i.e. server mode). A file must exist, even if it's empty, so that Webpack can handle references properly. \ No newline at end of file diff --git a/ClassicGEC/ClassicGECJS/app.config b/ClassicGEC/ClassicGECJS/app.config new file mode 100644 index 0000000..2bc077c --- /dev/null +++ b/ClassicGEC/ClassicGECJS/app.config @@ -0,0 +1,13 @@ + + + + + + + + + True + + + + \ No newline at end of file diff --git a/ClassicGEC/ClassicGECJS/jsonapi.fs b/ClassicGEC/ClassicGECJS/jsonapi.fs new file mode 100644 index 0000000..5c20396 --- /dev/null +++ b/ClassicGEC/ClassicGECJS/jsonapi.fs @@ -0,0 +1,14 @@ +[] +module Microsoft.Research.GEC.JSONAPI + +open WebSharper +open Microsoft.Research.CRNEngine + +let compile (code:string) (parts:string) (reactions:string) : obj = + let result = JSAPI.compile code parts reactions + WebSharper.Json.Encode result + +let get_solution (o:obj) (idx:int) : obj = + let o = WebSharper.Json.Decode o + let result = JSAPI.get_solution o idx + WebSharper.Json.Encode result \ No newline at end of file diff --git a/ClassicGEC/ClassicGECJS/paket.references b/ClassicGEC/ClassicGECJS/paket.references new file mode 100644 index 0000000..d7d6361 --- /dev/null +++ b/ClassicGEC/ClassicGECJS/paket.references @@ -0,0 +1,4 @@ +group NETSTANDARD + WebSharper.FSharp + FSharp.Core + FSBOLJS \ No newline at end of file diff --git a/ClassicGEC/ClassicGECJS/wsconfig.json b/ClassicGEC/ClassicGECJS/wsconfig.json new file mode 100644 index 0000000..ec083b6 --- /dev/null +++ b/ClassicGEC/ClassicGECJS/wsconfig.json @@ -0,0 +1,5 @@ +{ + "project": "bundle", + "outputDir": "Content", + "javascriptExport": ["Microsoft.Research.CRNEngine.JSONAPI"] +} \ No newline at end of file diff --git a/ClassicGEC/ClassicGECRunAllExamples/ClassicGECRunAllExamples.fsproj b/ClassicGEC/ClassicGECRunAllExamples/ClassicGECRunAllExamples.fsproj new file mode 100644 index 0000000..c057583 --- /dev/null +++ b/ClassicGEC/ClassicGECRunAllExamples/ClassicGECRunAllExamples.fsproj @@ -0,0 +1,29 @@ + + + + netcoreapp3.1 + Exe + x64 + x64 + + + + + + + + + + + + + + ..\..\Lib\Oslo.FSharp\Oslo.FSharp.dll + + + + + + + + \ No newline at end of file diff --git a/ClassicGEC/ClassicGECRunAllExamples/Program.fs b/ClassicGEC/ClassicGECRunAllExamples/Program.fs new file mode 100644 index 0000000..294059d --- /dev/null +++ b/ClassicGEC/ClassicGECRunAllExamples/Program.fs @@ -0,0 +1,15 @@ +module Microsoft.Research.CRNEngine.RunAllExamples.Program +open Microsoft.Research.CRNEngine +open Microsoft.Research.CliLibrary.Testing + +// Here we assume that we are only interested in the first solution, equivalent to how the GUI handles inference from a GEC program +let parser code = + let solveResult = Microsoft.Research.GEC.GECEngine.solveGEC (ref false) code Microsoft.Research.GEC.Databases.defaultParts Microsoft.Research.GEC.Databases.defaultReactions + let firstSolution = Microsoft.Research.GEC.GECEngine.getCrnAssignment solveResult.graph solveResult.solution 0 + firstSolution.model + +[] +let main(args) = + System.Threading.Thread.CurrentThread.CurrentCulture <- System.Globalization.CultureInfo.InvariantCulture + System.Threading.Thread.CurrentThread.CurrentUICulture <- System.Globalization.CultureInfo.InvariantCulture + testValidate (fun _ -> None) parser args \ No newline at end of file diff --git a/ClassicGEC/ClassicGECRunAllExamples/paket.references b/ClassicGEC/ClassicGECRunAllExamples/paket.references new file mode 100644 index 0000000..e382998 --- /dev/null +++ b/ClassicGEC/ClassicGECRunAllExamples/paket.references @@ -0,0 +1,4 @@ +group DOTNETCORE + +argu +FSharp.Core \ No newline at end of file diff --git a/ClassicGEC/ClassicGECServer.sln b/ClassicGEC/ClassicGECServer.sln new file mode 100644 index 0000000..df0a5a9 --- /dev/null +++ b/ClassicGEC/ClassicGECServer.sln @@ -0,0 +1,183 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29503.13 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "CRNEngineDotNet", "..\CRNEngine\CRNEngineDotNet\CRNEngineDotNet.fsproj", "{AE45211A-A65D-4827-A1F9-07A20EB0F154}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "Filzbach.FSharp.Portable", "..\Filzbach.FSharp\Filzbach.FSharp.Portable.fsproj", "{2849368F-AC32-4D1E-B6D6-9C52261A5F2D}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "MomentClosure", "..\MomentClosure\MomentClosure\MomentClosure.fsproj", "{5D417D97-CC0E-4415-968D-97E16FF131D5}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "ParserCombinators", "..\ParserCombinators\ParserCombinators\ParserCombinators.fsproj", "{DD8FEC26-6D1D-4642-A706-04070B6D5494}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "ReactionDiffusion", "..\PDESolvers\ReactionDiffusion\ReactionDiffusion.fsproj", "{529BEDB7-C73A-4A77-BFD9-1628D75C321B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SundialsSolver15", "..\SundialsSolver\SundialsSolver15\SundialsSolver15.vcxproj", "{866880DC-BF1E-4C12-8238-72E7EFF44AFB}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "CRNEngineTests", "..\CRNEngine\CRNEngineTests\CRNEngineTests.fsproj", "{8E0427CB-DD8F-46BE-A5BC-C02CF55F152D}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "ClassicGECWebServer", "ClassicGECWebServer\ClassicGECWebServer.fsproj", "{1DE5B345-EA66-4B52-8807-8E115F666215}" + ProjectSection(ProjectDependencies) = postProject + {866880DC-BF1E-4C12-8238-72E7EFF44AFB} = {866880DC-BF1E-4C12-8238-72E7EFF44AFB} + EndProjectSection +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "ClassicGECDotNet", "ClassicGECDotNet\ClassicGECDotNet.fsproj", "{74DDCD31-9968-4B9B-8E5D-F07EDB7CE332}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClassicGECHTML5", "ClassicGECHTML5\ClassicGECHTML5.csproj", "{CBC756D7-8BB7-4CEC-95C7-FDB9363BAC63}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InferenceViewer", "..\HTML5SharedGUI\InferenceViewer\InferenceViewer.csproj", "{179FDF3E-67B8-4E2F-9089-650BB1319AF2}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SimulationViewer", "..\HTML5SharedGUI\SimulationViewer\SimulationViewer.csproj", "{0ECCE305-85C0-403F-A980-EEB9379BD5A4}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MSAGL_JS", "..\HTML5SharedGUI\MSAGL_JS\MSAGL_JS.csproj", "{2F3B8603-CFF1-4946-B242-6F848801B49A}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CodeEditor", "..\HTML5SharedGUI\CodeEditor\CodeEditor.csproj", "{B234C1D7-96F4-40A2-A323-3B18646BF95C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CRNComponent", "..\HTML5SharedGUI\CRNComponent\CRNComponent.csproj", "{6DF7A0C1-2048-4A51-8599-E1C0B958A5E2}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CRNEngineTSWrapper", "..\CRNEngine\CRNEngineTSWrapper\CRNEngineTSWrapper.csproj", "{FB1F1936-AC22-41B4-AF2F-E20A486E3416}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "CRNEngineServerLib", "..\CRNEngine\CRNEngineServerLib\CRNEngineServerLib.fsproj", "{4522F647-5919-41E3-82E7-F886A640680B}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClassicGECTSWrapper", "ClassicGECTSWrapper\ClassicGECTSWrapper.csproj", "{A7A666E0-2ADE-4496-A84A-267BBE68B5A1}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "CliLibrary", "..\CRNEngine\CliLibrary\CliLibrary.fsproj", "{EEF843A3-43F8-4E6B-AB7F-9ADE3A5AF022}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HTML5CRN_Lib", "..\HTML5SharedGUI\HTML5CRN_Lib\HTML5CRN_Lib.csproj", "{B4C3F008-B6CA-4D63-9B98-6AC2D97B4E9B}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSBOLWrapper", "..\FSBOLWrapper\FSBOLWrapper\FSBOLWrapper.fsproj", "{AD19FE90-3663-4161-AC2D-08B4381D4808}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "ClassicGECIntegrationTests", "ClassicGECIntegrationTests\ClassicGECIntegrationTests.fsproj", "{0278F0E2-D752-47C1-A2E5-EF4BB7828C93}" + ProjectSection(ProjectDependencies) = postProject + {866880DC-BF1E-4C12-8238-72E7EFF44AFB} = {866880DC-BF1E-4C12-8238-72E7EFF44AFB} + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CRNJobsManager", "..\CRNEngine\CRNJobsManager\CRNJobsManager.csproj", "{20DDF233-1536-4C13-92E1-B2F578142811}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GenericComponents", "..\HTML5SharedGUI\GenericComponents\GenericComponents.csproj", "{B1130E5F-166A-45BC-A966-EA9053557788}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "CRNIntegrationTestLib", "..\CRNEngine\CRNIntegrationTestLib\CRNIntegrationTestLib.fsproj", "{0A50EC28-1F57-483F-809F-3153BD887261}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "CRNEngineCloudLib", "..\CRNEngine\CRNEngineCloudLib\CRNEngineCloudLib.fsproj", "{66A501F9-427B-4DB8-9C72-9A844D917D2A}" +EndProject +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "RulesDSD", "..\RulesDSD\RulesDSD\RulesDSD.fsproj", "{30177D74-4775-4629-BB08-CA533C6EB294}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {AE45211A-A65D-4827-A1F9-07A20EB0F154}.Debug|x64.ActiveCfg = Debug|Any CPU + {AE45211A-A65D-4827-A1F9-07A20EB0F154}.Debug|x64.Build.0 = Debug|Any CPU + {AE45211A-A65D-4827-A1F9-07A20EB0F154}.Release|x64.ActiveCfg = Release|Any CPU + {AE45211A-A65D-4827-A1F9-07A20EB0F154}.Release|x64.Build.0 = Release|Any CPU + {2849368F-AC32-4D1E-B6D6-9C52261A5F2D}.Debug|x64.ActiveCfg = Debug|x64 + {2849368F-AC32-4D1E-B6D6-9C52261A5F2D}.Debug|x64.Build.0 = Debug|x64 + {2849368F-AC32-4D1E-B6D6-9C52261A5F2D}.Release|x64.ActiveCfg = Release|x64 + {2849368F-AC32-4D1E-B6D6-9C52261A5F2D}.Release|x64.Build.0 = Release|x64 + {5D417D97-CC0E-4415-968D-97E16FF131D5}.Debug|x64.ActiveCfg = Debug|Any CPU + {5D417D97-CC0E-4415-968D-97E16FF131D5}.Debug|x64.Build.0 = Debug|Any CPU + {5D417D97-CC0E-4415-968D-97E16FF131D5}.Release|x64.ActiveCfg = Release|Any CPU + {5D417D97-CC0E-4415-968D-97E16FF131D5}.Release|x64.Build.0 = Release|Any CPU + {DD8FEC26-6D1D-4642-A706-04070B6D5494}.Debug|x64.ActiveCfg = Debug|Any CPU + {DD8FEC26-6D1D-4642-A706-04070B6D5494}.Debug|x64.Build.0 = Debug|Any CPU + {DD8FEC26-6D1D-4642-A706-04070B6D5494}.Release|x64.ActiveCfg = Release|Any CPU + {DD8FEC26-6D1D-4642-A706-04070B6D5494}.Release|x64.Build.0 = Release|Any CPU + {529BEDB7-C73A-4A77-BFD9-1628D75C321B}.Debug|x64.ActiveCfg = Debug|Any CPU + {529BEDB7-C73A-4A77-BFD9-1628D75C321B}.Debug|x64.Build.0 = Debug|Any CPU + {529BEDB7-C73A-4A77-BFD9-1628D75C321B}.Release|x64.ActiveCfg = Release|Any CPU + {529BEDB7-C73A-4A77-BFD9-1628D75C321B}.Release|x64.Build.0 = Release|Any CPU + {866880DC-BF1E-4C12-8238-72E7EFF44AFB}.Debug|x64.ActiveCfg = Debug|x64 + {866880DC-BF1E-4C12-8238-72E7EFF44AFB}.Debug|x64.Build.0 = Debug|x64 + {866880DC-BF1E-4C12-8238-72E7EFF44AFB}.Release|x64.ActiveCfg = Release|x64 + {866880DC-BF1E-4C12-8238-72E7EFF44AFB}.Release|x64.Build.0 = Release|x64 + {8E0427CB-DD8F-46BE-A5BC-C02CF55F152D}.Debug|x64.ActiveCfg = Debug|Any CPU + {8E0427CB-DD8F-46BE-A5BC-C02CF55F152D}.Debug|x64.Build.0 = Debug|Any CPU + {8E0427CB-DD8F-46BE-A5BC-C02CF55F152D}.Release|x64.ActiveCfg = Release|Any CPU + {8E0427CB-DD8F-46BE-A5BC-C02CF55F152D}.Release|x64.Build.0 = Release|Any CPU + {1DE5B345-EA66-4B52-8807-8E115F666215}.Debug|x64.ActiveCfg = Debug|x64 + {1DE5B345-EA66-4B52-8807-8E115F666215}.Debug|x64.Build.0 = Debug|x64 + {1DE5B345-EA66-4B52-8807-8E115F666215}.Release|x64.ActiveCfg = Release|x64 + {1DE5B345-EA66-4B52-8807-8E115F666215}.Release|x64.Build.0 = Release|x64 + {74DDCD31-9968-4B9B-8E5D-F07EDB7CE332}.Debug|x64.ActiveCfg = Debug|Any CPU + {74DDCD31-9968-4B9B-8E5D-F07EDB7CE332}.Debug|x64.Build.0 = Debug|Any CPU + {74DDCD31-9968-4B9B-8E5D-F07EDB7CE332}.Release|x64.ActiveCfg = Release|Any CPU + {74DDCD31-9968-4B9B-8E5D-F07EDB7CE332}.Release|x64.Build.0 = Release|Any CPU + {CBC756D7-8BB7-4CEC-95C7-FDB9363BAC63}.Debug|x64.ActiveCfg = Debug|Any CPU + {CBC756D7-8BB7-4CEC-95C7-FDB9363BAC63}.Debug|x64.Build.0 = Debug|Any CPU + {CBC756D7-8BB7-4CEC-95C7-FDB9363BAC63}.Release|x64.ActiveCfg = Release|Any CPU + {CBC756D7-8BB7-4CEC-95C7-FDB9363BAC63}.Release|x64.Build.0 = Release|Any CPU + {179FDF3E-67B8-4E2F-9089-650BB1319AF2}.Debug|x64.ActiveCfg = Debug|Any CPU + {179FDF3E-67B8-4E2F-9089-650BB1319AF2}.Debug|x64.Build.0 = Debug|Any CPU + {179FDF3E-67B8-4E2F-9089-650BB1319AF2}.Release|x64.ActiveCfg = Release|Any CPU + {179FDF3E-67B8-4E2F-9089-650BB1319AF2}.Release|x64.Build.0 = Release|Any CPU + {0ECCE305-85C0-403F-A980-EEB9379BD5A4}.Debug|x64.ActiveCfg = Debug|Any CPU + {0ECCE305-85C0-403F-A980-EEB9379BD5A4}.Debug|x64.Build.0 = Debug|Any CPU + {0ECCE305-85C0-403F-A980-EEB9379BD5A4}.Release|x64.ActiveCfg = Release|Any CPU + {0ECCE305-85C0-403F-A980-EEB9379BD5A4}.Release|x64.Build.0 = Release|Any CPU + {2F3B8603-CFF1-4946-B242-6F848801B49A}.Debug|x64.ActiveCfg = Debug|Any CPU + {2F3B8603-CFF1-4946-B242-6F848801B49A}.Debug|x64.Build.0 = Debug|Any CPU + {2F3B8603-CFF1-4946-B242-6F848801B49A}.Release|x64.ActiveCfg = Release|Any CPU + {2F3B8603-CFF1-4946-B242-6F848801B49A}.Release|x64.Build.0 = Release|Any CPU + {B234C1D7-96F4-40A2-A323-3B18646BF95C}.Debug|x64.ActiveCfg = Debug|Any CPU + {B234C1D7-96F4-40A2-A323-3B18646BF95C}.Debug|x64.Build.0 = Debug|Any CPU + {B234C1D7-96F4-40A2-A323-3B18646BF95C}.Release|x64.ActiveCfg = Release|Any CPU + {B234C1D7-96F4-40A2-A323-3B18646BF95C}.Release|x64.Build.0 = Release|Any CPU + {6DF7A0C1-2048-4A51-8599-E1C0B958A5E2}.Debug|x64.ActiveCfg = Debug|Any CPU + {6DF7A0C1-2048-4A51-8599-E1C0B958A5E2}.Debug|x64.Build.0 = Debug|Any CPU + {6DF7A0C1-2048-4A51-8599-E1C0B958A5E2}.Release|x64.ActiveCfg = Release|Any CPU + {6DF7A0C1-2048-4A51-8599-E1C0B958A5E2}.Release|x64.Build.0 = Release|Any CPU + {FB1F1936-AC22-41B4-AF2F-E20A486E3416}.Debug|x64.ActiveCfg = Debug|Any CPU + {FB1F1936-AC22-41B4-AF2F-E20A486E3416}.Debug|x64.Build.0 = Debug|Any CPU + {FB1F1936-AC22-41B4-AF2F-E20A486E3416}.Release|x64.ActiveCfg = Release|Any CPU + {FB1F1936-AC22-41B4-AF2F-E20A486E3416}.Release|x64.Build.0 = Release|Any CPU + {4522F647-5919-41E3-82E7-F886A640680B}.Debug|x64.ActiveCfg = Debug|Any CPU + {4522F647-5919-41E3-82E7-F886A640680B}.Debug|x64.Build.0 = Debug|Any CPU + {4522F647-5919-41E3-82E7-F886A640680B}.Release|x64.ActiveCfg = Release|Any CPU + {4522F647-5919-41E3-82E7-F886A640680B}.Release|x64.Build.0 = Release|Any CPU + {A7A666E0-2ADE-4496-A84A-267BBE68B5A1}.Debug|x64.ActiveCfg = Debug|Any CPU + {A7A666E0-2ADE-4496-A84A-267BBE68B5A1}.Debug|x64.Build.0 = Debug|Any CPU + {A7A666E0-2ADE-4496-A84A-267BBE68B5A1}.Release|x64.ActiveCfg = Release|Any CPU + {A7A666E0-2ADE-4496-A84A-267BBE68B5A1}.Release|x64.Build.0 = Release|Any CPU + {EEF843A3-43F8-4E6B-AB7F-9ADE3A5AF022}.Debug|x64.ActiveCfg = Debug|Any CPU + {EEF843A3-43F8-4E6B-AB7F-9ADE3A5AF022}.Debug|x64.Build.0 = Debug|Any CPU + {EEF843A3-43F8-4E6B-AB7F-9ADE3A5AF022}.Release|x64.ActiveCfg = Release|Any CPU + {EEF843A3-43F8-4E6B-AB7F-9ADE3A5AF022}.Release|x64.Build.0 = Release|Any CPU + {B4C3F008-B6CA-4D63-9B98-6AC2D97B4E9B}.Debug|x64.ActiveCfg = Debug|Any CPU + {B4C3F008-B6CA-4D63-9B98-6AC2D97B4E9B}.Debug|x64.Build.0 = Debug|Any CPU + {B4C3F008-B6CA-4D63-9B98-6AC2D97B4E9B}.Release|x64.ActiveCfg = Release|Any CPU + {B4C3F008-B6CA-4D63-9B98-6AC2D97B4E9B}.Release|x64.Build.0 = Release|Any CPU + {AD19FE90-3663-4161-AC2D-08B4381D4808}.Debug|x64.ActiveCfg = Debug|Any CPU + {AD19FE90-3663-4161-AC2D-08B4381D4808}.Debug|x64.Build.0 = Debug|Any CPU + {AD19FE90-3663-4161-AC2D-08B4381D4808}.Release|x64.ActiveCfg = Release|Any CPU + {AD19FE90-3663-4161-AC2D-08B4381D4808}.Release|x64.Build.0 = Release|Any CPU + {0278F0E2-D752-47C1-A2E5-EF4BB7828C93}.Debug|x64.ActiveCfg = Debug|x64 + {0278F0E2-D752-47C1-A2E5-EF4BB7828C93}.Debug|x64.Build.0 = Debug|x64 + {0278F0E2-D752-47C1-A2E5-EF4BB7828C93}.Release|x64.ActiveCfg = Release|x64 + {0278F0E2-D752-47C1-A2E5-EF4BB7828C93}.Release|x64.Build.0 = Release|x64 + {20DDF233-1536-4C13-92E1-B2F578142811}.Debug|x64.ActiveCfg = Debug|Any CPU + {20DDF233-1536-4C13-92E1-B2F578142811}.Debug|x64.Build.0 = Debug|Any CPU + {20DDF233-1536-4C13-92E1-B2F578142811}.Release|x64.ActiveCfg = Release|Any CPU + {20DDF233-1536-4C13-92E1-B2F578142811}.Release|x64.Build.0 = Release|Any CPU + {B1130E5F-166A-45BC-A966-EA9053557788}.Debug|x64.ActiveCfg = Debug|Any CPU + {B1130E5F-166A-45BC-A966-EA9053557788}.Debug|x64.Build.0 = Debug|Any CPU + {B1130E5F-166A-45BC-A966-EA9053557788}.Release|x64.ActiveCfg = Release|Any CPU + {B1130E5F-166A-45BC-A966-EA9053557788}.Release|x64.Build.0 = Release|Any CPU + {0A50EC28-1F57-483F-809F-3153BD887261}.Debug|x64.ActiveCfg = Debug|Any CPU + {0A50EC28-1F57-483F-809F-3153BD887261}.Debug|x64.Build.0 = Debug|Any CPU + {0A50EC28-1F57-483F-809F-3153BD887261}.Release|x64.ActiveCfg = Release|Any CPU + {0A50EC28-1F57-483F-809F-3153BD887261}.Release|x64.Build.0 = Release|Any CPU + {66A501F9-427B-4DB8-9C72-9A844D917D2A}.Debug|x64.ActiveCfg = Debug|Any CPU + {66A501F9-427B-4DB8-9C72-9A844D917D2A}.Debug|x64.Build.0 = Debug|Any CPU + {66A501F9-427B-4DB8-9C72-9A844D917D2A}.Release|x64.ActiveCfg = Release|Any CPU + {66A501F9-427B-4DB8-9C72-9A844D917D2A}.Release|x64.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {E643CAE2-AD10-4B8C-ADD6-C5A3EC142FAE} + EndGlobalSection +EndGlobal diff --git a/ClassicGEC/ClassicGECTSWrapper/.gitignore b/ClassicGEC/ClassicGECTSWrapper/.gitignore new file mode 100644 index 0000000..fd1c08e --- /dev/null +++ b/ClassicGEC/ClassicGECTSWrapper/.gitignore @@ -0,0 +1,12 @@ +Samples/**/*.d.ts +Samples/**/*.js +Samples/**/*.js.map +Scripts/*.d.ts +Scripts/*.js +Scripts/*.wasm +Scripts/*.js.map +!Scripts/declarations.d.ts + +#residual files from before webpack +Scripts/CRNEngine +Scripts/src \ No newline at end of file diff --git a/ClassicGEC/ClassicGECTSWrapper/ClassicGECTSWrapper.csproj b/ClassicGEC/ClassicGECTSWrapper/ClassicGECTSWrapper.csproj new file mode 100644 index 0000000..e68a357 --- /dev/null +++ b/ClassicGEC/ClassicGECTSWrapper/ClassicGECTSWrapper.csproj @@ -0,0 +1,28 @@ + + + + netcoreapp3.1 + true + + Library + --mutex file install + $([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\..\packages\javascriptbuild\Node.js.redist\tools\win-x64\node.exe')) + + + Always + + + + rem this ensures that a file exists in the place where webpack expects it, in cases where we do not run W#. + if not exist $(MSBuildProjectDirectory)\..\ClassicGECJS\Content\ClassicGECJS.js copy /Y $(MSBuildProjectDirectory)\..\ClassicGECJS\Content\placeholder.js $(MSBuildProjectDirectory)\..\ClassicGECJS\Content\ClassicGECJS.js + if not exist $(MSBuildProjectDirectory)\..\ClassicGECJS\Content\ClassicGECJS.min.js copy /Y $(MSBuildProjectDirectory)\..\ClassicGECJS\Content\placeholder.js $(MSBuildProjectDirectory)\..\ClassicGECJS\Content\ClassicGECJS.min.js + + + + + + false + + + + \ No newline at end of file diff --git a/ClassicGEC/ClassicGECTSWrapper/Scripts/ClassicGEC.ts b/ClassicGEC/ClassicGECTSWrapper/Scripts/ClassicGEC.ts new file mode 100644 index 0000000..a6546ac --- /dev/null +++ b/ClassicGEC/ClassicGECTSWrapper/Scripts/ClassicGEC.ts @@ -0,0 +1,52 @@ +import "jquery"; +import * as Rx from 'rx'; +import * as InternalInterfaces from '../../../CRNEngine/CRNEngineTSWrapper/Scripts/InternalInterfaces'; +import * as CRNInterfaces from '../../../CRNEngine/CRNEngineTSWrapper/Scripts/Interfaces'; +import * as Interfaces from './Interfaces'; +import CRNEngine from '../../../CRNEngine/CRNEngineTSWrapper/Scripts/CRNEngine'; +import DefaultDatabase from './DefaultDatabase'; +import ClassicGECWorker from "worker-loader?filename=./ClassicGEC.worker.[hash].js!./ClassicGEC.worker.js"; + +/** Provides asynchronous access to GEC F# methods. */ +class ClassicGEC extends CRNEngine { + constructor(server: boolean) { + super(server, ClassicGECWorker); + } + + private DoGECRequestResponse(task: Interfaces.WorkerRequest) { + return this.DoRequestResponse(task); + } + + private parts: string = DefaultDatabase.parts; + get Parts(): string { return this.parts; } + set Parts(value: string) { this.parts = value; } + + private reactions: string = DefaultDatabase.reactions; + get Reactions(): string { return this.reactions; } + set Reactions(value: string) { this.reactions = value; } + + UserCompile(code: string): Interfaces.CompileGECObservables { + var task: Interfaces.WorkerRequest_GECCompile = { mtype: "gec.compile", code: code, parts: this.parts, reactions: this.reactions }; + var messages = >this.DoGECRequestResponse(task); + var ret = { + crn: messages.where(v => v.mtype == "model").select(v => (v).model), + exports: messages.where(v => v.mtype == "export").select(v => (v).export), + solution_count: messages.where(v => v.mtype == "gec.solutions").select(v => (v).count), + jsbol: messages.where(v => v.mtype == "gec.jsbol").select(v => (v).document), + }; + return ret; + } + + UserGetSolution(idx: number): Interfaces.GetSolutionObservables { + var task: Interfaces.WorkerRequest_GECGetSolution = { mtype: "gec.getsolution", idx: idx }; + let messages = >this.DoGECRequestResponse(task); + let ret = { + solution: messages.where(v => v.mtype == "gec.solution").select(v => (v).solution), + jsbol: messages.where(v => v.mtype == "gec.jsbol").select(v => (v).document), + exports: messages.where(v => v.mtype == "export").select(v => (v).export) + }; + return ret; + } +} + +export default ClassicGEC \ No newline at end of file diff --git a/ClassicGEC/ClassicGECTSWrapper/Scripts/ClassicGEC.worker.ts b/ClassicGEC/ClassicGECTSWrapper/Scripts/ClassicGEC.worker.ts new file mode 100644 index 0000000..61a6a76 --- /dev/null +++ b/ClassicGEC/ClassicGECTSWrapper/Scripts/ClassicGEC.worker.ts @@ -0,0 +1,88 @@ +// Import the generic Worker. Note that here I'm importing it as a regular module, rather than as a web worker constructor (i.e. via worker-loader). +import * as CRNEngineWorker from "../../../CRNEngine/CRNEngineTSWrapper/Scripts/CRNEngine.worker"; +import { WebSharperGeneratedInterfaces as WGI } from "./WebSharperGeneratedInterfaces"; +import * as Interfaces from "./Interfaces"; +import * as CRNInterfaces from "./../../../CRNEngine/CRNEngineTSWrapper/Scripts/InternalInterfaces"; +import { jsbolToExport } from "./JSBOL"; + +// Configure the main worker. +CRNEngineWorker.config.loader = () => { + var classicGECJS = require("raw-loader!./../../ClassicGECJS/Content/ClassicGECJS.min.js"); + classicGECJS = classicGECJS.replace(/('|")use strict('|");?/, ''); + eval.call(null, classicGECJS); + compile = Microsoft.Research.GEC.JSONAPI.compile; + get_solution = Microsoft.Research.GEC.JSONAPI.get_solution +} +CRNEngineWorker.config.processMessage = processMessageGEC; + +// Declare some shortcuts. +declare var Microsoft: any; +var compile: WGI.compile; +var get_solution: WGI.get_solution; + +var local_result: WGI.Microsoft.Research.GEC.JSAPI.solve_result; +var local_solution: WGI.Microsoft.Research.GEC.JSAPI.solution_result; + +function handleCompile(code: string, parts: string, reactions: string) { + if (code == null) code = ""; + if (parts == null) parts = ""; + if (reactions == null) reactions = ""; + // Invoke compilation on the given code. + local_result = compile(code, parts, reactions); + local_solution = null; + // Send the solution count to the main thread. + var count = (local_result.solution).solution[1].numSolutions; + var solsmsg: Interfaces.WorkerResponse_GECSolutions = { mtype: "gec.solutions", count: count }; + self.postMessage(solsmsg, undefined); + var jsbolmsg: Interfaces.WorkerResponse_JSBOL = { mtype: "gec.jsbol", document: local_result.jsbol }; + self.postMessage(jsbolmsg, undefined); +} + +function handleGetSolution(idx: number) { + local_solution = get_solution(local_result, idx); + var solmsg: Interfaces.WorkerResponse_GECSolution = { mtype: "gec.solution", solution: { model: local_solution.model, code: local_solution.crnstring } }; + self.postMessage(solmsg, undefined); + var jsbolmsg: Interfaces.WorkerResponse_JSBOL = { mtype: "gec.jsbol", document: local_solution.jsbol }; + self.postMessage(jsbolmsg, undefined); +} + +/** Processes a task coming from the main thread. Calculus-specific tasks will be handled here, CRN generic tasks will be passed to the processMessage function in CRNEngine/Worker. */ +function processMessageGEC(e: any) { + var req = e.data; + console.log("worker request: " + req.mtype); + try { + switch (req.mtype) { + case "generateexports": + // I want to send the normal exports, and then send the XML SBOL export. + CRNEngineWorker.handleGenerateExports((req).model, (req).nodeId); + var exportmsg: CRNInterfaces.WorkerResponse_Export = null; + if (local_solution != null) + exportmsg = jsbolToExport(local_solution.jsbol); + else if (local_result != null) + exportmsg = jsbolToExport(local_result.jsbol); + if (exportmsg != null) + self.postMessage(exportmsg, undefined); + break; + case "gec.compile": + handleCompile((req).code, (req).parts, (req).reactions); + break; + case "gec.getsolution": + handleGetSolution((req).idx); + break; + default: + // Let the generic worker handle this. Note that it will also send the finished signal, so I don't need to. + CRNEngineWorker.processMessage(e); + return; + } + CRNEngineWorker.sendFinished(); + } + catch (exc) { + if (exc.Data0 == null) + CRNEngineWorker.handleException(exc); + else { + exc.Data1.extra = exc.Data0; + exc.Data1.message = "Error while parsing " + exc.Data0 + ": " + exc.Data1.message; + CRNEngineWorker.handleException(exc.Data1); + } + } +}; \ No newline at end of file diff --git a/ClassicGEC/ClassicGECTSWrapper/Scripts/DefaultDatabase.ts b/ClassicGEC/ClassicGECTSWrapper/Scripts/DefaultDatabase.ts new file mode 100644 index 0000000..48fe2aa --- /dev/null +++ b/ClassicGEC/ClassicGECTSWrapper/Scripts/DefaultDatabase.ts @@ -0,0 +1,64 @@ +var database = { + parts: "i723017,pcr,codes(xylR;0.001)\n" + + "i723024, pcr, codes(phzM;0.001)\n" + + "e0040, pcr, codes(gfp;0.01)\n" + + "c0099, pcr, codes(cviR;0.01)\n" + + "i723025, pcr, codes(phzS;0.001)\n" + + "i723028, pcr, codes(pca;0.001)\n" + + "c0051, pcr, codes(cI;0.01)\n" + + "c0040, pcr, codes(tetR;0.01)\n" + + "c0080, pcr, codes(araC;0.01)\n" + + "c0012, pcr, codes(lacI;0.01)\n" + + "cunknown2, pcr, codes(unknown2;0.001)\n" + + "c0061, pcr, codes(luxI;0.01)\n" + + "c0062, pcr, codes(luxR;0.01)\n" + + "c0079, pcr, codes(lasR;0.01)\n" + + "c0078, pcr, codes(lasI;0.01)\n" + + "cunknown3, pcr, codes(ccdB;0.005)\n" + + "cunknown4, pcr, codes(ccdA;0.1)\n" + + "i723020, prom, pos(toluene::xylR;0.001; 0.001; 1.0); con(0.0001)\n" + + "r0051, prom, neg(cI; 1.0; 0.5; 0.00005); con(0.12)\n" + + "r0040, prom, neg(tetR; 1.0; 0.5; 0.00005); con(0.09)\n" + + "runknown1, prom, neg(unknown1; 1.0; 0.005; 0.001); con(0.04)\n" + + "r0080, prom, neg(araC; 1.0; 0.000001; 0.0001); pos(araC::arabinose; 0.001; 0.001; 1.0); con(0.1)\n" + + "r0011, prom, neg(lacI; 1.0; 0.5; 0.00005); con(0.1)\n" + + "r0062, prom, pos(lasR::m3OC12HSL; 1.0; 0.8; 0.1); pos(luxR::m3OC6HSL; 1.0; 0.8; 0.1); con(0.01)\n" + + "r0090, prom, pos(lasR::m3OC12HSL; 1.0; 0.8; 0.1); con(0.01)\n" + + "r0099, prom, pos(cviR::m3OC6HSL; 1.0; 0.8; 0.1); con(0.01)\n" + + "b0034, rbs, rate(0.1)\n" + + "b0015, ter\n" + + "cunknown5, pcr, codes(ccdA2; 10.0)\n" + + "runknown5, prom, con(10.0)\n" + + "j06504, pcr, codes(mCherry; 0.1)\n" + + "prpr, device, components[pr; rbs34; eyfp; ter1; pr; rbs34; ecfp; ter1]\n" + + "drPcat, device, components[pCat; rbs34; luxR; rbs34; lasR; ter1; pLas81; rbs34; eyfp; ter1; plux76; rbs34; ecfp; ter1]\n" + + "drRS100S32, device, components[pTet; rbss100; luxR; ter1; pLac; rbs32; lasR; ter1; pLas81; rbs34; eyfp; ter1; plux76; rbs34; ecfp; ter1]\n" + + "drR33S32, device, components[pTet; rbs33; luxR; ter1; pLac; rbs32; lasR; ter1; pLas81; rbs34; eyfp; ter1; plux76; rbs34; ecfp; ter1]\n" + + "drR33S175, device, components[pTet; rbs33; luxR; ter1; pLac; rbsS175; lasR; ter1; pLas81; rbs34; eyfp; ter1; plux76; rbs34; ecfp; ter1]\n" + + "relayP76LasI, device, components[pLux76; rbs900; lasI; l3s2p21]\n" + + "relayP81LuxI, device, components[pLas81; rbs32; luxI; l3s2p21]\n" + + "pBadYFP, device, components[pBad; rbs34; eyfp; l3s2p21]\n" + + "lactonase, device, components[pBad; rbs34; aiia; l3s2p21]", + reactions: "toluene + xylR ->{1.0} toluene::xylR\r\n" + + "phzM ~ pca ->{1.0} metPCA\r\n" + + "phzS ~ metPCA ->{1.0} pyo\r\n" + + "luxR + m3OC6HSL ->{0.5} luxR::m3OC6HSL\r\n" + + "lasR + m3OC12HSL ->{0.5} lasR::m3OC12HSL\r\n" + + "cviR + m3OC6HSL ->{0.5} cviR::m3OC6HSL\r\n" + + "cviR + m3OC12HSL ->{0.5} cviR::m3OC12HSL\r\n" + + "luxI ~ ->{1.0} m3OC6HSL\r\n" + + "lasI ~ ->{1.0} m3OC12HSL\r\n" + + "ccdA ~ ccdB ->{1.0}\r\n" + + "c[m3OC6HSL] ->{0.5} m3OC6HSL\r\n" + + "m3OC6HSL ->{0.5} c[m3OC6HSL]\r\n" + + "c[m3OC12HSL] ->{0.5} m3OC12HSL\r\n" + + "m3OC12HSL ->{0.5} c[m3OC12HSL]\r\n" + + "luxR::m3OC6HSL ->{1.0} luxR + m3OC6HSL\r\n" + + "cviR::m3OC6HSL ->{1.0} cviR + m3OC6HSL\r\n" + + "cviR::m3OC12HSL ->{1.0} cviR + m3OC12HSL\r\n" + + "lasR::m3OC12HSL ->{1.0} lasR + m3OC12HSL\r\n" + + "ccdA2 ~ ccdB ->{0.00001}\r\n" + + "lacI + iptg ->{1.0} lacI::iptg\r\n" + + "tetR + aTc ->{1.0} tetR::aTc" +} +export default database \ No newline at end of file diff --git a/ClassicGEC/ClassicGECTSWrapper/Scripts/GenerateInterfaces.bat b/ClassicGEC/ClassicGECTSWrapper/Scripts/GenerateInterfaces.bat new file mode 100644 index 0000000..7f36fa1 --- /dev/null +++ b/ClassicGEC/ClassicGECTSWrapper/Scripts/GenerateInterfaces.bat @@ -0,0 +1 @@ +.\..\..\..\packages\javascriptbuild\TypesTSFS\tools\TypesTSFS.exe --style websharper --projectfilepath "../../ClassicGECJS/ClassicGECJS.fsproj" --outputpath "./WebSharperGeneratedInterfaces.ts" \ No newline at end of file diff --git a/ClassicGEC/ClassicGECTSWrapper/Scripts/Interfaces.ts b/ClassicGEC/ClassicGECTSWrapper/Scripts/Interfaces.ts new file mode 100644 index 0000000..5d232e3 --- /dev/null +++ b/ClassicGEC/ClassicGECTSWrapper/Scripts/Interfaces.ts @@ -0,0 +1,30 @@ +import * as CRN from '../../../CRNEngine/CRNEngineTSWrapper/Scripts/InternalInterfaces'; +import { WebSharperGeneratedInterfaces as WGI } from "./WebSharperGeneratedInterfaces"; +import * as Interfaces from '../../../CRNEngine/CRNEngineTSWrapper/Scripts/Interfaces'; + +export type jSBOLDocument = WGI.FSBOL.JsonSerializer.rSBOLDocument; + +export type CompileGECObservables = { + solution_count: Rx.Observable, + jsbol: Rx.Observable, + exports: Rx.Observable +} + +export type GECSolution = { model: Interfaces.IG, code: string } + +export type GetSolutionObservables = { + solution: Rx.Observable, + jsbol: Rx.Observable, + exports: Rx.Observable +} + +export type WorkerRequest_GECCompile = { mtype: "gec.compile", code: string, parts: string, reactions: string } +export type WorkerRequest_GECGetSolution = { mtype: "gec.getsolution", idx: number } + +export type WorkerRequest = WorkerRequest_GECCompile | WorkerRequest_GECGetSolution | CRN.WorkerRequest; + +export type WorkerResponse_GECSolutions = { mtype: "gec.solutions", count: number } +export type WorkerResponse_JSBOL = { mtype: "gec.jsbol", document: jSBOLDocument } +export type WorkerResponse_GECSolution = { mtype: "gec.solution", solution: GECSolution } + +export type WorkerResponse = WorkerResponse_GECSolutions | WorkerResponse_JSBOL | WorkerResponse_GECSolution | CRN.WorkerResponse; \ No newline at end of file diff --git a/ClassicGEC/ClassicGECTSWrapper/Scripts/JSBOL.ts b/ClassicGEC/ClassicGECTSWrapper/Scripts/JSBOL.ts new file mode 100644 index 0000000..0cfa37d --- /dev/null +++ b/ClassicGEC/ClassicGECTSWrapper/Scripts/JSBOL.ts @@ -0,0 +1,67 @@ +import * as CRNInterfaces from "./../../../CRNEngine/CRNEngineTSWrapper/Scripts/InternalInterfaces"; +import * as Interfaces from "./Interfaces"; +import * as sboljs from 'sboljs'; + +export function jsbolToObject(jsbol: Interfaces.jSBOLDocument) { + var sboldoc = new sboljs() + jsbol.componentDefinitions.forEach(cd => { + var compdef = sboldoc.componentDefinition(); + compdef.name = cd.name + cd.roles.forEach(role => compdef.addRole(role)); + cd.types.forEach(t => compdef.addType(t)); + compdef.version = cd.version + compdef.uri = cd.uri + compdef.persistentIdentity = cd.persistentIdentity + compdef.displayId = cd.displayId + cd.components.forEach(comp => { + var component = sboldoc.component(); + + component.name = comp.name; + component.displayId = comp.displayId; + component.persistentIdentity = comp.persistentIdentity; + component.version = comp.version; + component.uri = comp.uri; + + component.definition = comp.definition + component.access = comp.access; + + + compdef.addComponent(component); + }); + + cd.sequenceAnnotations.forEach(sa => { + var seqann = sboldoc.sequenceAnnotation(); + seqann.name = sa.name; + seqann.displayId = sa.displayId; + seqann.persistentIdentity = sa.persistentIdentity; + seqann.version = sa.version; + seqann.uri = sa.uri; + + sa.ranges.forEach(range => { + var r = sboldoc.range(); + r.name = range.name; + r.displayId = range.displayId; + r.persistentIdentity = range.persistentIdentity; + r.version = range.version; + r.uri = range.uri; + r.start = range.startIndex; + r.end = range.endIndex; + r.orientation = range.orientation; + seqann.addLocation(r); + }); + + sa.roles.forEach(role => seqann.addRole(role)); + + compdef.addSequenceAnnotation(seqann); + + }); + }); + return sboldoc; +} + +export function jsbolToExport(jsbol: Interfaces.jSBOLDocument) { + var sboldoc = jsbolToObject(jsbol); + var sbolxmlstring = sboldoc.serializeXML(); + var exportmsg: CRNInterfaces.WorkerResponse_Export = { mtype: "export", export: { "content_type": "text/plain", id: "sbol", display_name: "SBOL", content: sbolxmlstring } }; + return exportmsg; +} diff --git a/ClassicGEC/ClassicGECTSWrapper/Scripts/WebSharperGeneratedInterfaces.ts b/ClassicGEC/ClassicGECTSWrapper/Scripts/WebSharperGeneratedInterfaces.ts new file mode 100644 index 0000000..fa3eeca --- /dev/null +++ b/ClassicGEC/ClassicGECTSWrapper/Scripts/WebSharperGeneratedInterfaces.ts @@ -0,0 +1,980 @@ +//These interfaces are code generated from F#, any changes to this file will be lost. +export namespace WebSharperGeneratedInterfaces { + + export namespace FSBOL.ComponentInstance { + export type Access = "Public" | "Private" + export const AccessSelect = ["Public", "Private"] + } + + export namespace Microsoft.Research.CRNEngine { + export interface Assignment { + variables: Array; + values: Array>>; + } + export interface Attributes { + name: string; + structure: string; + svg: string; + } + export interface Column { + name: string; + values: Array; + } + export interface Crn_settings { + simulation: Microsoft.Research.CRNEngine.Simulation_settings; + simulations: Array>; + stochastic: Microsoft.Research.CRNEngine.Stochastic_settings; + deterministic: Microsoft.Research.CRNEngine.Deterministic_settings; + spatial: Microsoft.Research.CRNEngine.Spatial_settings; + inference: Microsoft.Research.CRNEngine.Inference_settings; + moment_closure: Microsoft.Research.CRNEngine.Moment_closure_settings.t>>; + synthesis: Microsoft.Research.CRNEngine.Synthesis_settings; + data: Array; + units: Microsoft.Research.CRNEngine.Units; + simulator: Microsoft.Research.CRNEngine.Simulator; + parameters: Array; + sweeps: Array; + rates: { [key: string]: e }; + plot: Microsoft.Research.CRNEngine.Plot_settings; + } + export interface Dataset { + file: string; + data: Array>; + } + export interface Deterministic_settings { + stiff: boolean; + abstolerance: number; + reltolerance: number; + } + export interface Gui { + name: string; + settings: Microsoft.Research.CRNEngine.Crn_settings; + reactions: Array>; + initials: Array>; + attributes: { [key: string]: Microsoft.Research.CRNEngine.Attributes }; + } + export interface GuiIG { + task?: Microsoft.Research.CRNEngine.Task; + nodes: { [key: string]: Microsoft.Research.CRNEngine.GuiModel }; + edges: { [key: string]: Array }; + expanded: boolean; + } + export interface GuiIGEdge { + location: Microsoft.Research.CRNEngine.InferenceSiteGraph.Location; + parameters: Array; + } + export interface GuiIGTargetParameter { + source: string; + target: string; + prior: Microsoft.Research.CRNEngine.InferenceSiteGraph.PriorKind; + } + export interface GuiModel { + top: Microsoft.Research.CRNEngine.Gui; + systems: Array; + } + export interface Inference_settings { + name: string; + burnin: number; + samples: number; + thin: number; + noise_model: Microsoft.Research.CRNEngine.Noise_model; + noise_parameter: Microsoft.Research.CRNEngine.Noise_parameter; + prune: boolean; + seed: number; + seeds: Array; + lowerbound?: number; + timer: boolean; + partial_evaluation: boolean; + print_console: boolean; + print_summary: boolean; + } + export interface Initial { + constant: boolean; + value: v; + species: s; + time?: v; + spatial?: Microsoft.Research.CRNEngine.Spatial_initial.t; + } + export interface LogNormal { + mu: number; + sigma: number; + } + export interface Normal { + mean: number; + stdev: number; + } + export interface Parameter { + name: string; + value: number; + prior?: Microsoft.Research.CRNEngine.Prior; + } + export interface Plot_settings { + x_label: string; + y_label: string; + title: string; + label_font_size: number; + tick_font_size: number; + x_ticks: Array; + y_ticks: Array; + x_min?: number; + x_max?: number; + y_min?: number; + y_max?: number; + v_boundaries: Array; + h_boundaries: Array; + } + export interface Prior { + interval: Microsoft.Research.CRNEngine.Interval; + distribution: Microsoft.Research.CRNEngine.Distribution; + variation: Microsoft.Research.CRNEngine.Variation; + } + export interface Reaction { + catalysts: Array>; + reactants: Array>; + reverse?: Microsoft.Research.CRNEngine.Rate; + rate: Microsoft.Research.CRNEngine.Rate; + products: Array>; + } + export interface Simulation_settings { + name: string; + initial: number; + final: number; + points: number; + plots: Array; + plotcolours: Array; + seed?: number; + kinetics: Microsoft.Research.CRNEngine.Kinetics; + times: Array; + multicore: boolean; + data: Array; + sweeps: Array; + } + export interface Spatial_settings { + parameters: Array; + diffusibles: Array; + dimensions: number; + boundary: Microsoft.Research.CRNEngine.Boundary; + xmax: number; + nx: number; + dt: number; + default_diffusion: number; + random: number; + } + export interface Stochastic_settings { + scale: number; + steps?: number; + trajectories: number; + stationary_skiptime?: number; + } + export interface Sweep { + name: string; + assignments: Array; + } + export interface Synthesis_settings { + mode: Microsoft.Research.CRNEngine.Synthesis_mode + solver: Microsoft.Research.CRNEngine.Z3Solver + timeout?: number; + } + export interface Table { + times: Array; + columns: Array>; + } + export interface Task { + task_type: Microsoft.Research.CRNEngine.TaskType; + copies: number; + copy_id: number; + nodes: number; + } + export interface Truncated { + mean: number; + stdev: number; + min: number; + max: number; + } + export interface Uniform { + min: number; + max: number; + } + export interface Units { + concentration: Microsoft.Research.CRNEngine.Concentration; + time: Microsoft.Research.CRNEngine.Time; + space: Microsoft.Research.CRNEngine.Space; + } + export type Boundary = "Periodic" | "ZeroFlux" + export const BoundarySelect = ["Periodic", "ZeroFlux"] + export interface Concentration { + Molar: number; + } + export interface Distribution { + Uniform?: Microsoft.Research.CRNEngine.Uniform; + Normal?: Microsoft.Research.CRNEngine.Normal; + LogNormal?: Microsoft.Research.CRNEngine.LogNormal; + TruncatedNormal?: Microsoft.Research.CRNEngine.Truncated; + } + export type Interval = "Real" | "Log" + export const IntervalSelect = ["Real", "Log"] + export type Kinetics = "Contextual" | "Stochastic" | "Deterministic" + export const KineticsSelect = ["Contextual", "Stochastic", "Deterministic"] + export type Noise_model = "Constant" | "Proportional" + export const Noise_modelSelect = ["Constant", "Proportional"] + export type Noise_parameter = { Fixed: number } | "Random" | "Multiple" + export interface Rate { + MassAction?: v; + Function?: e; + } + export type Simulator = "Oslo" | "Sundials" | "SSA" | "CME" | "CMESundials" | "LNA" | "PDE" | "MC" + export const SimulatorSelect = ["Oslo", "Sundials", "SSA", "CME", "CMESundials", "LNA", "PDE", "MC"] + export interface Space { + Metres: number; + } + export type Synthesis_mode = "Multistability" | "Turing" + export const Synthesis_modeSelect = ["Multistability", "Turing"] + export type TaskType = "Parse" | "Simulate" | "Infer" + export const TaskTypeSelect = ["Parse", "Simulate", "Infer"] + export type Time = { Seconds: number } + export type Variation = "Random" | "Fixed" | "Initial2" | "Multiple" + export const VariationSelect = ["Random", "Fixed", "Initial2", "Multiple"] + export type Z3Solver = "NLSat" | "Portfolio" + export const Z3SolverSelect = ["NLSat", "Portfolio"] + } + + export namespace FSBOL.Attachment { + export interface Attachment { + //format : () => string | null; + //hash : () => string | null; + //size : () => System.Int64 | null; + //source : () => string; + } + } + + export namespace System { + + } + + export namespace FSBOL.Implementation { + export interface Implementation { + //built : () => FSBOL.Implementation.Built | null; + } + export interface Built { + CD?: FSBOL.ComponentDefinition.ComponentDefinition; + MD?: FSBOL.ModuleDefinition.ModuleDefinition; + } + } + + export namespace FSBOL.Collection { + export interface Collection { + //members : () => Array; + } + } + + export namespace FSBOL.CombinatorialDerivation { + export interface CombinatorialDerivation { + //strategy : () => FSBOL.CombinatorialDerivation.Strategy | null; + //template : () => string; + //variableComponents : () => Array; + } + export type Strategy = "Enumerate" | "Sample" + export const StrategySelect = ["Enumerate", "Sample"] + } + + export namespace FSBOL.Component { + export interface Component { + //roleIntegrations : () => Array; + //roles : () => Array; + } + export type RoleIntegration = "OverrideRoles" | "MergeRoles" + export const RoleIntegrationSelect = ["OverrideRoles", "MergeRoles"] + } + + export namespace FSBOL.ComponentDefinition { + export interface ComponentDefinition { + //components : () => Array; + //roles : () => Array; + //sequenceAnnotations : () => Array; + //sequenceConstraints : () => Array; + //sequences : () => Array; + //types : () => Array; + } + export interface ComponentDefinitionType { + DNA?: string; + RNA?: string; + Protein?: string; + SmallMolecule?: string; + Complex?: string; + Linear?: string; + Circular?: string; + SingleStranded?: string; + DoubleStranded?: string; + OtherType?: string; + } + } + + export namespace FSBOL.FunctionalComponent { + export interface FunctionalComponent { + //direction : () => FSBOL.FunctionalComponent.Direction; + } + export type Direction = "In" | "Out" | "InOut" | "NoDirection" + export const DirectionSelect = ["In", "Out", "InOut", "NoDirection"] + } + + export namespace FSBOL.Sequence { + export interface Sequence { + //elements : () => string; + //encoding : () => FSBOL.Sequence.Encoding; + } + export interface Encoding { + IUPACDNA?: string; + IUPACPROTEIN?: string; + SMILES?: string; + OtherEncoding?: string; + } + } + + export namespace FSBOL.Model { + export interface Model { + //framework : () => FSBOL.Model.Framework; + //language : () => FSBOL.Model.Language; + //source : () => string; + } + export interface Framework { + Continuous?: string; + Discrete?: string; + OtherFramework?: string; + } + export interface Language { + SBML?: string; + CellML?: string; + BioPax?: string; + OtherLanguage?: string; + } + } + + export namespace FSBOL.Interaction { + export interface Interaction { + //participations : () => Array; + //types : () => Array; + } + export interface InteractionType { + Inhibition?: string; + Stimulation?: string; + BiochemicalReaction?: string; + NonCovalentBinding?: string; + Degradation?: string; + GeneticProduction?: string; + Control?: string; + OtherInteractionType?: string; + } + } + + export namespace Microsoft.Research.CRNEngine.InferenceSiteGraph { + export interface Location { + NodeLoc?: string; + SystemLoc?: Opaque.FSharpTuple; + } + export type PriorKind = "Fixed2" | "Normal" | "LogNormal" | "TruncatedNormal" + export const PriorKindSelect = ["Fixed2", "Normal", "LogNormal", "TruncatedNormal"] + } + + export namespace FSBOL.Location { + export interface Location { + //orientation : () => FSBOL.Location.Orientation; + } + export interface Orientation { + Inline?: string; + ReverseComplement?: string; + OtherOrientation?: string; + } + } + + export namespace FSBOL.MapsTo { + export interface MapsTo { + //local : () => string; + //refinement : () => FSBOL.MapsTo.Refinement; + //remote : () => string; + } + export interface Refinement { + UseRemote?: string; + UseLocal?: string; + VerifyIdentical?: string; + Merge?: string; + OtherRefinement?: string; + } + } + + export namespace FSBOL.Module { + export interface Module { + //definition : () => string; + //mapsTos : () => Array; + } + } + + export namespace FSBOL.ModuleDefinition { + export interface ModuleDefinition { + //functionalComponents : () => Array; + //interactions : () => Array; + //models : () => Array; + //modules : () => Array; + //roles : () => Array; + } + } + + export namespace FSBOL.VariableComponent { + export interface VariableComponent { + //operator : () => FSBOL.VariableComponent.Operator; + //variable : () => string; + //variantCollections : () => Array; + //variantDerivations : () => Array; + //variants : () => Array; + } + export type Operator = "ZeroOrOne" | "One" | "ZeroOrMore" | "OneOrMore" + export const OperatorSelect = ["ZeroOrOne", "One", "ZeroOrMore", "OneOrMore"] + } + + export namespace Microsoft.FSharp.Core { + + } + + export namespace FSBOL.Participation { + export interface Participation { + //participant : () => FSBOL.FunctionalComponent.FunctionalComponent; + //roles : () => Array; + } + export interface ParticipationRole { + Inhibitor?: string; + Inhibited?: string; + Stimulator?: string; + Stimulated?: string; + Reactant?: string; + Product?: string; + PromoterParticipation?: string; + Modifier?: string; + Modified?: string; + Template?: string; + OtherParticipationRole?: string; + } + } + + export namespace FSBOL.SequenceConstraint { + export interface SequenceConstraint { + //object : () => FSBOL.Component.Component; + //restriction : () => FSBOL.SequenceConstraint.Restriction; + //subject : () => FSBOL.Component.Component; + } + export interface Restriction { + Precedes?: string; + SameOrientationAs?: string; + OppositeOrientationAs?: string; + DifferentFrom?: string; + OtherRestriction?: string; + } + } + + export namespace FSBOL.Role { + export interface Role { + Promoter?: string; + RBS?: string; + CDS?: string; + Terminator?: string; + Gene?: string; + Operator?: string; + EngineeredGene?: string; + MRNA?: string; + Effector?: string; + TranscriptionFactor?: string; + OtherRole?: string; + } + } + + export namespace FSBOL.SBOLDocument { + export interface SBOLDocument { + //attachments : () => Array; + //collections : () => Array; + //combinatorialDerivations : () => Array; + //componentDefinitions : () => Array; + //implementations : () => Array; + //models : () => Array; + //moduleDefinitions : () => Array; + //sequences : () => Array; + } + } + + export namespace FSBOL.SequenceAnnotation { + export interface SequenceAnnotation { + //componentObj : () => FSBOL.Component.Component | null; + //locations : () => Array; + //roles : () => Array; + } + } + + export namespace FSBOL.TopLevel { + export interface TopLevel { + //attachments : () => Array; + } + } + + export namespace Microsoft.Research.GEC.Ast { + export interface aexp { + FloatAExp?: number; + IdAExp?: string; + PlusAExp?: Microsoft.Research.GEC.Ast.aexp[]; + MinusAExp?: Microsoft.Research.GEC.Ast.aexp[]; + MulAExp?: Microsoft.Research.GEC.Ast.aexp[]; + DivAExp?: Microsoft.Research.GEC.Ast.aexp[]; + PowAExp?: Microsoft.Research.GEC.Ast.aexp[]; + } + } + + export namespace Microsoft.Research.CRNEngine.Expression { + export interface divide { + div1: Microsoft.Research.CRNEngine.Expression.t; + div2: Microsoft.Research.CRNEngine.Expression.t; + } + export interface minus { + sub1: Microsoft.Research.CRNEngine.Expression.t; + sub2: Microsoft.Research.CRNEngine.Expression.t; + } + export interface modulo { + div: Microsoft.Research.CRNEngine.Expression.t; + modulo: Microsoft.Research.CRNEngine.Expression.t; + } + export interface power { + base_: Microsoft.Research.CRNEngine.Expression.t; + exponent: Microsoft.Research.CRNEngine.Expression.t; + } + export interface bexp { + BTrue?: string; + BFalse?: string; + BLT?: Microsoft.Research.CRNEngine.Expression.t[]; + BLeq?: Microsoft.Research.CRNEngine.Expression.t[]; + BEq?: Microsoft.Research.CRNEngine.Expression.t[]; + BGeq?: Microsoft.Research.CRNEngine.Expression.t[]; + BGT?: Microsoft.Research.CRNEngine.Expression.t[]; + BNot?: Microsoft.Research.CRNEngine.Expression.bexp; + BAnd?: Microsoft.Research.CRNEngine.Expression.bexp[]; + BOr?: Microsoft.Research.CRNEngine.Expression.bexp[]; + } + export interface t { + Key?: k; + Float?: number; + Times?: Array>; + Divide?: Microsoft.Research.CRNEngine.Expression.divide; + Power?: Microsoft.Research.CRNEngine.Expression.power; + Plus?: Array>; + Minus?: Microsoft.Research.CRNEngine.Expression.minus; + Absolute?: Microsoft.Research.CRNEngine.Expression.t; + Log?: Microsoft.Research.CRNEngine.Expression.t; + Modulo?: Microsoft.Research.CRNEngine.Expression.modulo; + Ceiling?: Microsoft.Research.CRNEngine.Expression.t; + Floor?: Microsoft.Research.CRNEngine.Expression.t; + Round?: Microsoft.Research.CRNEngine.Expression.t; + If?: (Microsoft.Research.CRNEngine.Expression.bexp | Microsoft.Research.CRNEngine.Expression.t)[]; + } + } + + export namespace Microsoft.Research.CRNEngine.Spatial_initial { + export interface core { + inner: number; + outer: number; + width: number; + } + export interface point { + x: number; + y: number; + width: number; + value: number; + } + export interface rectangle { + xmin: number; + xmax: number; + ymin: number; + ymax: number; + value: number; + } + export interface t { + random: number; + core?: Microsoft.Research.CRNEngine.Spatial_initial.core; + points: Array; + rectangles: Array; + } + } + + export namespace Microsoft.Research.GEC.Database { + export interface entry { + value: a; + enabled: boolean; + comments: string; + } + export interface t { + parts: { [key: string]: Microsoft.Research.GEC.Database.entry }; + devices: Array; + reactions: Array>; + } + export interface partType { + PCR?: Microsoft.Research.GEC.Database.pcrProperty; + PROM?: Array; + RBS?: Microsoft.Research.GEC.Database.rbsProperty; + TER?: string; + } + export interface pcrProperty { + CODES: (Array | number)[]; + } + export interface promProperty { + POS?: (Array | number)[]; + NEG?: (Array | number)[]; + CON?: number; + FRATE?: Microsoft.Research.GEC.Ast.aexp; + } + export type rbsProperty = { RATE: number } + } + + export namespace Microsoft.Research.CRNEngine.Mset { + export interface entry { + element: a; + multiplicity: number; + } + } + + export namespace FSBOL.JsonSerializer { + export interface rAnnotation { + qName: FSBOL.JsonSerializer.rQName; + valueType: string; + literal: FSBOL.JsonSerializer.rLiteral; + uri: string; + nestedQName: FSBOL.JsonSerializer.rQName; + annotations: Array; + } + export interface rAttachment { + uri: string; + version: string; + name: string; + displayId: string; + persistentIdentity: string; + attachments: Array; + description: string; + annotations: Array; + source: string; + format: string; + size: number; + hash: string; + } + export interface rCollection { + uri: string; + version: string; + name: string; + displayId: string; + persistentIdentity: string; + attachments: Array; + description: string; + annotations: Array; + members: Array; + } + export interface rCombinatorialDerivation { + uri: string; + version: string; + name: string; + displayId: string; + persistentIdentity: string; + attachments: Array; + description: string; + annotations: Array; + strategy: string; + template: string; + variableComponents: Array; + } + export interface rComponent { + uri: string; + version: string; + name: string; + displayId: string; + persistentIdentity: string; + description: string; + annotations: Array; + definition: string; + access: string; + mapsTos: Array; + roles: Array; + roleIntegrations: Array; + } + export interface rComponentDefinition { + uri: string; + version: string; + name: string; + displayId: string; + persistentIdentity: string; + attachments: Array; + description: string; + annotations: Array; + components: Array; + sequenceAnnotations: Array; + sequenceConstraints: Array; + sequences: Array; + types: Array; + roles: Array; + } + export interface rCut { + uri: string; + version: string; + name: string; + displayId: string; + persistentIdentity: string; + description: string; + annotations: Array; + orientation: string; + at: number; + } + export interface rFunctionalComponent { + uri: string; + version: string; + name: string; + displayId: string; + persistentIdentity: string; + description: string; + annotations: Array; + definition: string; + access: string; + mapsTos: Array; + direction: string; + } + export interface rGenericLocation { + uri: string; + version: string; + name: string; + displayId: string; + persistentIdentity: string; + description: string; + annotations: Array; + orientation: string; + } + export interface rImplementation { + uri: string; + version: string; + name: string; + displayId: string; + persistentIdentity: string; + attachments: Array; + description: string; + annotations: Array; + built: string; + } + export interface rInteraction { + uri: string; + version: string; + name: string; + displayId: string; + persistentIdentity: string; + description: string; + annotations: Array; + types: Array; + participations: Array; + } + export interface rLiteral { + literalType: string; + string: string; + int: number; + int64: number; + double: number; + bool: boolean; + } + export interface rMapsTo { + uri: string; + version: string; + name: string; + displayId: string; + persistentIdentity: string; + description: string; + annotations: Array; + local: string; + remote: string; + refinment: string; + } + export interface rModel { + uri: string; + version: string; + name: string; + displayId: string; + persistentIdentity: string; + attachments: Array; + description: string; + annotations: Array; + source: string; + language: string; + framework: string; + } + export interface rModule { + uri: string; + version: string; + name: string; + displayId: string; + persistentIdentity: string; + description: string; + annotations: Array; + definition: string; + mapsTos: Array; + } + export interface rModuleDefinition { + uri: string; + version: string; + name: string; + displayId: string; + persistentIdentity: string; + attachments: Array; + description: string; + annotations: Array; + roles: Array; + functionalComponents: Array; + interactions: Array; + modules: Array; + models: Array; + } + export interface rParticipation { + uri: string; + version: string; + name: string; + displayId: string; + persistentIdentity: string; + description: string; + annotations: Array; + roles: Array; + participant: string; + } + export interface rQName { + qNameType: string; + name: string; + prefix: string; + nameSpaceUri: string; + } + export interface rRange { + uri: string; + version: string; + name: string; + displayId: string; + persistentIdentity: string; + description: string; + annotations: Array; + orientation: string; + startIndex: number; + endIndex: number; + } + export interface rSBOLDocument { + attachments: Array; + sequences: Array; + componentDefinitions: Array; + moduleDefinitions: Array; + models: Array; + implementations: Array; + collections: Array; + CombinatorialDerivation: Array; + } + export interface rSequence { + uri: string; + version: string; + name: string; + displayId: string; + persistentIdentity: string; + attachments: Array; + description: string; + annotations: Array; + elements: string; + encoding: string; + } + export interface rSequenceAnnotation { + uri: string; + version: string; + name: string; + displayId: string; + persistentIdentity: string; + description: string; + annotations: Array; + ranges: Array; + cuts: Array; + genericLocations: Array; + roles: Array; + componentObj: string; + } + export interface rSequenceConstraint { + uri: string; + version: string; + name: string; + displayId: string; + persistentIdentity: string; + description: string; + annotations: Array; + subject: string; + object: string; + restriction: string; + } + export interface rVariableComponent { + uri: string; + version: string; + name: string; + displayId: string; + persistentIdentity: string; + description: string; + annotations: Array; + operator: string; + variants: Array; + variantCollections: Array; + variantDerivations: Array; + variable: string; + } + } + + export namespace Microsoft.Research.GEC.JSAPI { + export interface solution_result { + model: Microsoft.Research.CRNEngine.GuiIG; + jsbol: FSBOL.JsonSerializer.rSBOLDocument; + sbol: FSBOL.SBOLDocument.SBOLDocument; + crnstring: string; + } + export interface solve_result { + solution: Microsoft.Research.GEC.GECEngine.t; + solutionCount: number; + model: Microsoft.Research.CRNEngine.GuiIG; + jsbol: FSBOL.JsonSerializer.rSBOLDocument; + sbol: FSBOL.SBOLDocument.SBOLDocument; + } + } + + export namespace Microsoft.Research.GEC.GECEngine { + export interface t { + options: Microsoft.Research.GEC.Options.t; + database: Microsoft.Research.GEC.Database.t; + solution?: Opaque.FSharpTuple; + } + } + + export namespace Microsoft.Research.GEC.Options { + export interface t { } + } + + export namespace Microsoft.Research.GEC.Gecreaction { + export interface t { } + } + + export namespace Microsoft.Research.CRNEngine.Moment_closure_settings { + export interface t { + order: number; + initial_minimum: number; + log_evaluation: boolean; + plots: Array; + } + } + + export namespace Opaque { + export interface FSharpMap { } + export interface Dictionary { } + export interface FSharpTuple { } + } + export namespace System { + export interface Object { } + } + + export interface compile { + (program: string, dbParts: string, dbReactions: string): Microsoft.Research.GEC.JSAPI.solve_result + } + + export interface get_solution { + (o: Microsoft.Research.GEC.JSAPI.solve_result, i: number): Microsoft.Research.GEC.JSAPI.solution_result + } + +} \ No newline at end of file diff --git a/ClassicGEC/ClassicGECTSWrapper/Scripts/declarations.d.ts b/ClassicGEC/ClassicGECTSWrapper/Scripts/declarations.d.ts new file mode 100644 index 0000000..066a6d3 --- /dev/null +++ b/ClassicGEC/ClassicGECTSWrapper/Scripts/declarations.d.ts @@ -0,0 +1,9 @@ +declare module "worker-loader*" { + class WebpackWorker extends Worker { + constructor(); + } + + export default WebpackWorker; +} + +declare module "*" // Effectively disables checking that an imported file is a module. This is brutal, but saves a ton of headaches. See https://github.com/Microsoft/TypeScript/issues/15031. If at any point TS provides a better way to allow using a js file as an untyped module, we should switch to that. \ No newline at end of file diff --git a/ClassicGEC/ClassicGECTSWrapper/app.config b/ClassicGEC/ClassicGECTSWrapper/app.config new file mode 100644 index 0000000..10b094f --- /dev/null +++ b/ClassicGEC/ClassicGECTSWrapper/app.config @@ -0,0 +1,9 @@ + + + + + True + + + + diff --git a/ClassicGEC/ClassicGECTSWrapper/paket.references b/ClassicGEC/ClassicGECTSWrapper/paket.references new file mode 100644 index 0000000..18629da --- /dev/null +++ b/ClassicGEC/ClassicGECTSWrapper/paket.references @@ -0,0 +1,6 @@ +group JavaScriptBuild + +Yarn.MSBuild +Node.js.redist +TypesTSFS +Microsoft.TypeScript.MSBuild \ No newline at end of file diff --git a/ClassicGEC/ClassicGECTSWrapper/tsconfig.json b/ClassicGEC/ClassicGECTSWrapper/tsconfig.json new file mode 100644 index 0000000..d5cc870 --- /dev/null +++ b/ClassicGEC/ClassicGECTSWrapper/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tsconfig.common", + "include": [ + "Scripts/*.ts", + "Samples/**/*.ts" + ] +} diff --git a/ClassicGEC/ClassicGECTSWrapper/web.Debug.config b/ClassicGEC/ClassicGECTSWrapper/web.Debug.config new file mode 100644 index 0000000..9fdb00f --- /dev/null +++ b/ClassicGEC/ClassicGECTSWrapper/web.Debug.config @@ -0,0 +1,31 @@ + + + + + + + + + + \ No newline at end of file diff --git a/ClassicGEC/ClassicGECTSWrapper/web.Release.config b/ClassicGEC/ClassicGECTSWrapper/web.Release.config new file mode 100644 index 0000000..d71b662 --- /dev/null +++ b/ClassicGEC/ClassicGECTSWrapper/web.Release.config @@ -0,0 +1,32 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/ClassicGEC/ClassicGECTSWrapper/web.config b/ClassicGEC/ClassicGECTSWrapper/web.config new file mode 100644 index 0000000..0a866ec --- /dev/null +++ b/ClassicGEC/ClassicGECTSWrapper/web.config @@ -0,0 +1,33 @@ + + + + + + + + + + + + True + + + + + True + + + + + + \ No newline at end of file diff --git a/ClassicGEC/ClassicGECTSWrapper_Samples/.gitignore b/ClassicGEC/ClassicGECTSWrapper_Samples/.gitignore new file mode 100644 index 0000000..93f5647 --- /dev/null +++ b/ClassicGEC/ClassicGECTSWrapper_Samples/.gitignore @@ -0,0 +1,6 @@ +dist +**/*.js +!webpack.config.js +**/*.d.ts +!declarations.d.ts +**/*.map \ No newline at end of file diff --git a/ClassicGEC/ClassicGECTSWrapper_Samples/ClassicGECTSWrapper_Samples.csproj b/ClassicGEC/ClassicGECTSWrapper_Samples/ClassicGECTSWrapper_Samples.csproj new file mode 100644 index 0000000..f7933c1 --- /dev/null +++ b/ClassicGEC/ClassicGECTSWrapper_Samples/ClassicGECTSWrapper_Samples.csproj @@ -0,0 +1,43 @@ + + + + netcoreapp3.1 + true + + Library + --mutex file install + + + + + + + + $([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\..\packages\javascriptbuild\Node.js.redist\tools\win-x64\node.exe')) + + + + + + + + $(CopyAllFilesToSingleFolderForPackageDependsOn); + CollectWebpackOutput; + + + $(CopyAllFilesToSingleFolderForMsdeployDependsOn); + CollectWebpackOutput; + + + + + + <_CustomFiles Include="dist\**\*" /> + + %(RecursiveDir)%(Filename)%(Extension) + + + + + + \ No newline at end of file diff --git a/ClassicGEC/ClassicGECTSWrapper_Samples/Compile/app.ts b/ClassicGEC/ClassicGECTSWrapper_Samples/Compile/app.ts new file mode 100644 index 0000000..a6255f4 --- /dev/null +++ b/ClassicGEC/ClassicGECTSWrapper_Samples/Compile/app.ts @@ -0,0 +1,56 @@ +import ClassicGEC from "../../ClassicGECTSWrapper/Scripts/ClassicGEC"; +import * as CRNInterfaces from "../../../CRNEngine/CRNEngineTSWrapper/Scripts/Interfaces"; +import "../samples.css" + +var codeBox = document.getElementById("codeBox"); +var partsBox = document.getElementById("partsBox"); +var reactionsBox = document.getElementById("reactionsBox"); +var status = document.getElementById("status"); + +var me = new ClassicGEC(); + +function appendStatus(header: string, text?: string) { + var p = document.createElement("p"); + var b = document.createElement("b"); + b.appendChild(document.createTextNode(header)); + p.appendChild(b); + if (text != null) + p.appendChild(document.createTextNode(text)); + status.appendChild(p); +} + +function clearStatus() { + while (status.firstChild) + status.removeChild(status.firstChild); +} + +function onFail(process: string, t: string, result: CRNInterfaces.Error) { + appendStatus(process + " fail (" + t + ")", JSON.stringify(result) + ")"); +} + +function onCompileDone() { + var observables = me.UserGetSolution(0); + observables.solution.subscribe(solution => appendStatus("getsolution progress (solution): ", JSON.stringify(solution)), error => onFail("getsolution", "solution", error), () => appendStatus("getsolution success (solution)")); + observables.jsbol.subscribe(jsbol => appendStatus("getsolution progress (jsbol): ", JSON.stringify(jsbol)), error => onFail("getsolution", "jsbol", error), () => appendStatus("getsolution success (jsbol)")); + observables.exports.subscribe(expdef => appendStatus("getsolution progress (exports): ", JSON.stringify(expdef)), error => onFail("getsolution", "exports", error), () => appendStatus("getsolution success (exports)")); +} + +function compileClicked() { + clearStatus(); + appendStatus("parse start"); + var code = codeBox.value; + me.Parts = partsBox.value; + me.Reactions = reactionsBox.value; + var observables = me.UserCompile(code); + observables.solution_count.subscribe(count => appendStatus("compile progress (solution_count): ", JSON.stringify(count)), error => onFail("compile", "solution_count", error), () => { appendStatus("compile success (solution_count)"); onCompileDone(); }); + observables.jsbol.subscribe(jsbol => appendStatus("compile progress (jsbol): ", JSON.stringify(jsbol)), error => onFail("compile", "jsbol", error), () => appendStatus("compile success (jsbol)")); + observables.exports.subscribe(expdef => appendStatus("compile progress (exports): ", JSON.stringify(expdef)), error => onFail("compile", "exports", error), () => appendStatus("compile success (exports)")); +} + +document.getElementById("compileButton").onclick = compileClicked; + +import sample from "raw-loader!../test.txt"; + +codeBox.value = sample; +partsBox.value = me.Parts; +reactionsBox.value = me.Reactions; diff --git a/ClassicGEC/ClassicGECTSWrapper_Samples/Compile/index.html b/ClassicGEC/ClassicGECTSWrapper_Samples/Compile/index.html new file mode 100644 index 0000000..7fb5e96 --- /dev/null +++ b/ClassicGEC/ClassicGECTSWrapper_Samples/Compile/index.html @@ -0,0 +1,25 @@ + + + + ClassicGECTSWrapper Compile Sample + + + +
+
+

Parts:

+ +
+
+

Reactions:

+ +
+
+

Code:

+ +
+
+ +
+ + \ No newline at end of file diff --git a/ClassicGEC/ClassicGECTSWrapper_Samples/declarations.d.ts b/ClassicGEC/ClassicGECTSWrapper_Samples/declarations.d.ts new file mode 100644 index 0000000..848f698 --- /dev/null +++ b/ClassicGEC/ClassicGECTSWrapper_Samples/declarations.d.ts @@ -0,0 +1,7 @@ +declare module "raw-loader*" +declare module "worker-loader*" { + class WebpackWorker extends Worker { + constructor(); + } + export default WebpackWorker; +} diff --git a/ClassicGEC/ClassicGECTSWrapper_Samples/paket.references b/ClassicGEC/ClassicGECTSWrapper_Samples/paket.references new file mode 100644 index 0000000..6592879 --- /dev/null +++ b/ClassicGEC/ClassicGECTSWrapper_Samples/paket.references @@ -0,0 +1,5 @@ +group JavaScriptBuild + +Yarn.MSBuild +Node.js.redist +Microsoft.TypeScript.MSBuild \ No newline at end of file diff --git a/ClassicGEC/ClassicGECTSWrapper_Samples/samples.css b/ClassicGEC/ClassicGECTSWrapper_Samples/samples.css new file mode 100644 index 0000000..182b0b3 --- /dev/null +++ b/ClassicGEC/ClassicGECTSWrapper_Samples/samples.css @@ -0,0 +1,39 @@ +html { + height: 97%; +} + +body { + height: 100%; +} + +.codeBox { + height: 100%; + width: 100%; +} + +.headerCodeBox { + flex-grow: 1; + display: flex; + flex-direction: column; + margin-right: 10px; + margin-bottom: 5px; +} + +.headerP { + font-weight: bold; + margin: 0px; +} + +.multiCodeBoxContainer { + display: flex; + flex-direction: row; + height: 45%; +} + +.status { + font-family: monospace; +} + + .status > p { + margin: 0px; + } diff --git a/ClassicGEC/ClassicGECTSWrapper_Samples/test.txt b/ClassicGEC/ClassicGECTSWrapper_Samples/test.txt new file mode 100644 index 0000000..c2e6570 --- /dev/null +++ b/ClassicGEC/ClassicGECTSWrapper_Samples/test.txt @@ -0,0 +1,25 @@ +directive sample 100000.0 1000 +directive plot predator[ccdB]; prey[ccdB] + +predator +[ r0051:prom; rbs; pcr +; rbs; pcr; ter +; prom; rbs; pcr; ter +; r0051:prom; rbs; pcr; ter +| Q1a ~-> H1 | Q2b + H2 <-> Q2b-H2 +| A ~ ccdB -> +| H1 *->{10.0} | H2 *->{10.0} +| ccdB ~ Q1a *->{10.0} +] || + +prey +[ prom; rbs; pcr; ter +; r0051:prom; rbs; pcr +; rbs; pcr; ter +| Q2a ~-> H2 | H1 + Q1b <-> H1-Q1b +| H2 *->{10.0} | H1 *->{10.0} +| ccdB ~ Q2a *->{10.0} +] || + +predator[H1] -> H1 | H1 -> prey[H1] +| prey[H2] -> H2 | H2 -> predator[H2] \ No newline at end of file diff --git a/ClassicGEC/ClassicGECTSWrapper_Samples/tsconfig.json b/ClassicGEC/ClassicGECTSWrapper_Samples/tsconfig.json new file mode 100644 index 0000000..8bbd2b7 --- /dev/null +++ b/ClassicGEC/ClassicGECTSWrapper_Samples/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tsconfig.common", + "include": [ + "*.ts", + "Compile/*.ts" + ] +} diff --git a/ClassicGEC/ClassicGECTSWrapper_Samples/web.Debug.config b/ClassicGEC/ClassicGECTSWrapper_Samples/web.Debug.config new file mode 100644 index 0000000..fae9cfe --- /dev/null +++ b/ClassicGEC/ClassicGECTSWrapper_Samples/web.Debug.config @@ -0,0 +1,30 @@ + + + + + + + + + + \ No newline at end of file diff --git a/ClassicGEC/ClassicGECTSWrapper_Samples/web.Release.config b/ClassicGEC/ClassicGECTSWrapper_Samples/web.Release.config new file mode 100644 index 0000000..da6e960 --- /dev/null +++ b/ClassicGEC/ClassicGECTSWrapper_Samples/web.Release.config @@ -0,0 +1,31 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/ClassicGEC/ClassicGECTSWrapper_Samples/web.config b/ClassicGEC/ClassicGECTSWrapper_Samples/web.config new file mode 100644 index 0000000..b32bd31 --- /dev/null +++ b/ClassicGEC/ClassicGECTSWrapper_Samples/web.config @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + + + + \ No newline at end of file diff --git a/ClassicGEC/ClassicGECTSWrapper_Samples/webpack.config.js b/ClassicGEC/ClassicGECTSWrapper_Samples/webpack.config.js new file mode 100644 index 0000000..c8be4f4 --- /dev/null +++ b/ClassicGEC/ClassicGECTSWrapper_Samples/webpack.config.js @@ -0,0 +1,71 @@ +"use strict"; +var webpack = require('webpack'); +var HtmlWebpackPlugin = require('html-webpack-plugin'); +var CleanWebpackPlugin = require('clean-webpack-plugin'); +var path = require('path'); +module.exports = [{ + mode: "development", + entry: { + 'Compile': "./Compile/app.js" + }, + output: { + filename: "./[name].[hash].js", + path: path.resolve(__dirname, 'dist') + }, + optimization: { + splitChunks: { + chunks: 'all' + } + }, + resolve: { + alias: { + idd$: path.resolve(__dirname, '../../node_modules/interactive-data-display/dist/idd_knockout.js'), + svg$: path.resolve(__dirname, '../../node_modules/svgjs'), + filesaver$: path.resolve(__dirname, '../../node_modules/file-saver'), + jquery$: path.resolve(__dirname, '../../node_modules/jquery') + } + }, + node: { + fs: 'empty' + }, + module: { + rules: [ + { + test: /\.css$/, + use: ['style-loader', 'css-loader'] + }, + { + test: /\.(svg|png)(\?v=\d+\.\d+\.\d+)?$/, + use: [{ + loader: 'file-loader', + options: { + name: '[name].[ext]', + outputPath: 'img/' + } + }] + }, + { + test: /\.wasm$/, + type: "javascript/auto", + loader: "file-loader" + } + ] + }, + plugins: [ + new CleanWebpackPlugin(['dist']), + new webpack.ProvidePlugin({ + $: 'jquery', + jQuery: 'jquery', + Rx: 'rx', + ko: 'knockout', + SVG: 'svgjs', + saveAs: 'file-saver', + jQuery_mousewheel: 'jquery-mousewheel' + }), + new HtmlWebpackPlugin({ + template: './Compile/index.html', + excludeChunks: ['JIT'], + filename: './Compile.html' + }) + ] +}]; \ No newline at end of file diff --git a/ClassicGEC/ClassicGECTests/ClassicGECTests.fsproj b/ClassicGEC/ClassicGECTests/ClassicGECTests.fsproj new file mode 100644 index 0000000..7099d78 --- /dev/null +++ b/ClassicGEC/ClassicGECTests/ClassicGECTests.fsproj @@ -0,0 +1,35 @@ + + + + netcoreapp3.1 + Exe + + + x64 + + + x64 + + + + + + + + + + + + + + + ..\..\Lib\Oslo.FSharp\Oslo.FSharp.dll + + + + + \ No newline at end of file diff --git a/ClassicGEC/ClassicGECTests/deviceEnumerationTests.fs b/ClassicGEC/ClassicGECTests/deviceEnumerationTests.fs new file mode 100644 index 0000000..dffcbad --- /dev/null +++ b/ClassicGEC/ClassicGECTests/deviceEnumerationTests.fs @@ -0,0 +1,975 @@ +module deviceEnumerationTests + +open Xunit +open FsUnit +open Microsoft.Research.CRNEngine + + +open RulesDSD.Syntax +open Microsoft.Research.GEC +open Microsoft.Research.GEC.LogicGEC + +let db = """//////////////////////////// +//////////////////////////// +// Knowledge Graph encoding +//////////////////////////// +//////////////////////////// + +//////////////// +// devices list +//////////////// +device(d1_P76_CFP, "GCTCTTCAGAAAC"). +device(d2_P81_YFP, "GCTCTTCAACGAC"). +device(d3_r0011_b0034_luxR, "GCTCTTCACATAA"). +device(d4_r0011_S175_lasR, "GCTCTTCATTTAATTGTGA"). +device(r0040_b0033_cinR, "GCTCTTCATTTAATTGTGG"). +device(d5_PSB3K3_Dest, "AATTTTGTGTCGCCCTTGA"). + +// linkers +device(linker1, "GCTCTTCAG"). +device(linker2, "GCTCTTCAA"). +device(linker3, "GCTCTTCAC"). +device(linker4, "GCTCTTCAT"). + +////////////////////////////// +// drop-down menus selection +////////////////////////////// +menu("component1", [ d1_P76_CFP + ; linker1 ]). + +menu("component2", [ d2_P81_YFP + ; linker2 ]). + +menu("component3", [ d3_r0011_b0034_luxR + ; linker3 + ; r0040_b0033_cinR ]). + +menu("component4", [ d4_r0011_S175_lasR + ; linker4 ]). + +menu("backbone", [ d5_PSB3K3_Dest ]). + +/////////////// +// annotations (assuming they are provided by querying the Knowledge Graph) +/////////////// +annotateSeq("GCTCTTCAGAAAC", ). // 1_P76_CFP +annotateSeq("GCTCTTCAACGAC", ). // 2_P81_YFP +annotateSeq("GCTCTTCACATAA", ). // 3_r0011_b0034_luxR +annotateSeq("GCTCTTCATTTAATTGTGA", ). // 4_r0011_S175_lasR +annotateSeq("GCTCTTCATTTAATTGTGG", ). // r0040_b0033_cinR +annotateSeq("AATTTTGTGTCGCCCTTGA", ). // PSB3K3_Dest + +annotateSeq("GCTCTTCAG", ). // Linker 1 +annotateSeq("GCTCTTCAA", ). // Linker 2 +annotateSeq("GCTCTTCAC", ). // Linker 3 +annotateSeq("GCTCTTCAT", ). // Linker 4 + +///////// +// parts +//////// +// Restriction site +part(sapl_gaa, "RestrictionSite"). // add sequence to part +part(sapl_acg, "RestrictionSite"). +part(sapl_cat, "RestrictionSite"). +part(sapl_ttt, "RestrictionSite"). +part(sapl_ggt, "RestrictionSite"). + +part(sapl_acg_RC, "RestrictionSite"). +part(sapl_cat_RC, "RestrictionSite"). +part(sapl_ttt_RC, "RestrictionSite"). +part(sapl_ggt_RC, "RestrictionSite"). +part(sapl_gaa_RC, "RestrictionSite"). + +// Promoter +part(P76, "Promoter"). // HSL-regulated +part(P81, "Promoter"). // HSL-regulated +part(Plac_R0011, "Promoter"). +part(Ptet_R0040, "Promoter"). + +// HSL-regulated +property(P76, "HSL-regulated"). +property(P81, "HSL-regulated"). + +// intended +// luxr binds p76 +// lasr binds p81 +// x-talk +// luxr binds p81 +// lasr binds p76 +// CinR binds p81 +// CinR binds p76 + +// Linker +part(Linker1, "Linker"). +part(Linker2, "Linker"). +part(Linker3, "Linker"). +part(Linker4, "Linker"). + +// CDS +part(eCFP, "CDS"). +part(eYFP, "CDS"). +part(LuxR, "CDS"). // receiver +part(LasR, "CDS"). // receiver +part(CinR, "CDS"). +part(levansucrase, "CDS"). // missing +// missing: c6 c12 +initials("c6"). +initials("c12"). + +// LuxR +interaction("production", "LuxR", "Lux"). +reagent("Lux", "chemical"). +property("Lux", "HSL-regulator"). + +interaction("bind", "Lux", "P76"). +interaction("bind", "Lux", "P81"). // crosstalk + +// LasR +interaction("production", "LasR", "Las"). +reagent("Las", "chemical"). +property("Las", "HSL-regulator"). +interaction("bind", "Las", "P81"). +interaction("bind", "Las", "P76"). // crosstalk + +// CinR +interaction("production", "CinR", "Cin"). +reagent("Cin", "chemical"). +property("Cin", "HSL-regulator"). +interaction("bind", "Cin", "P81"). // crosstalk +interaction("bind", "Cin", "P76"). // crosstalk + +// YFP +interaction("production", "eYFP", "YFP"). +reagent("YFP", "chemical"). +property("YFP", "fluorophore"). + +// CFP +interaction("production", "eCFP", "CFP"). +reagent("CFP", "chemical"). +property("CFP", "fluorophore"). + +// RBS +part(scar34scar, "RBS"). +part(scar33scar, "RBS"). +part(scarS175, "RBS"). +part(B0033, "RBS"). + +// Terminator +part(B0015, "Terminator"). +part(L3S2P2s, "Terminator"). + +///////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////// + +/////////////////////////// +/////////////////////////// +// Combinatorial assembly +/////////////////////////// +/////////////////////////// + +// Utilities +parts(Device, Parts) :- + device(Device, Sequence), + annotateSeq(Sequence, Parts). + +produces(Device, Molecule) :- + parts(Device, Parts), Parts = C[ P ] + type(P, cds(codes(Molecule))), + //interaction("production", P, Molecule), + reagent(Molecule, "chemical"). + +producesKind(Device, M, TypeOfMolecule) :- + produces(Device, M), + property(M, TypeOfMolecule). + +isLinker(Device) :- + parts(Device, Parts), + member(P, Parts), + part(P, "Linker"). + +binds(Device, Molecule) :- + parts(Device, Ps), + member(Part, Ps), + interaction("bind", Molecule, Part). + +//////////////////////////////////////////// +// Condition 1: not all devices are linkers +//////////////////////////////////////////// +consecutiveLinkers([C1; C2; C3; C4]) :- isLinker(C1), isLinker(C2), isLinker(C3), isLinker(C4). + +(* recursive version: +consecutiveLinkers([]). +consecutiveLinkers([D # Rest ]) :- isLinker(D), consecutiveLinkers(Rest). *) + +//////////////////////////////////////////// +// Condition 2: must have a fluorophore +//////////////////////////////////////////// +hasFluorophore(Devices) :- + member(D, Devices), + producesKind(D, M, "fluorophore"). + +/////////////////////////////////////////////////// +// Condition 3: don't produce the same fluorophore +// (Negate the condition below in the code) +/////////////////////////////////////////////////// +produceSameFluorophore(Devices) :- + member(D1, Devices), + member(D2, Devices), + not (D1 = D2), + produces(D1, M), + property(M, "fluorophore"), + produces(D2, M). + +/////////////////////////////////////////////////// +// Condition 4: all non-constitutive promoters must be regulated by some device +// (Negate the condition below in the code) +/////////////////////////////////////////////////// +hasHSLRegulator(Devices, M, P) :- + member(D, Devices), + producesKind(D, M', "HSL-regulator"), + interaction("bind", M', P), + M = M'. + +isHSLRegulated(Devices, M, P') :- + member(D, Devices), + parts(D, Parts), + member(P', Parts), + property(P', "HSL-regulated"), + interaction("bind", M, P'), + P = P'. + +uninducedHSL(Devices) :- + hasHSLRegulator(Devices, M, _), + not isHSLRegulated(Devices, M, _). + +//uninducedHSL(Devices) :- not isHSLRegulated(Devices, _, _). +uninducedHSL(Devices) :- + isHSLRegulated(Devices, _, P), + not hasHSLRegulator(Devices, _, P). + +/////////////////////////////////////////////////// +// Condition 5: no protein is regulated twice +// (Negate the condition below in the code) +/////////////////////////////////////////////////// +produceSameProtein(Devices, M) :- + member(D1, Devices), + member(D2, Devices), + not (D1 = D2), + producesKind(D1, M', "HSL-regulator"), + produces(D2, M'), + M = M'. + +/////////////////////////////////////////////////// +// Condition 6: no two proteins regulated the same promoter +// (Negate the condition below in the code) +/////////////////////////////////////////////////// +regulateSamePromoter(Devices) :- + member(D1, Devices), + producesKind(D1, M1, "HSL-regulator"), + member(D2, Devices), + producesKind(D2, M2, "HSL-regulator"), + not (M1 = M2), + member(D, Devices), + binds(D, M1), + binds(D, M2). + +/////////////////////////////////////////////////// +// Condition 7: no promoter produces different proteins +// (Negate the condition below in the code) +/////////////////////////////////////////////////// +samePromoterDifferentProtein(Devices) :- + member(D1, Devices), parts(D1, Ps1), + member(D2, Devices), parts(D2, Ps2), + member(P, Ps1), part(P, "Promoter"), + member(P, Ps2), + member(C1, Ps1), part(C1, "Promoter"), + member(C2, Ps2), part(C2, "Promoter"), + produces(C1, M1), + produces(C2, M2), + not(M1 = M2). + +///////////////////////////////////////// +// Main combinatorial assembly algorithm +///////////////////////////////////////// +find_device(C, X) :- + + // populate menus + menu("component1", Cs1), member(C1, Cs1), + menu("component2", Cs2), member(C2, Cs2), + menu("component3", Cs3), member(C3, Cs3), + menu("component4", Cs4), member(C4, Cs4), + menu("backbone", Bkb), member(B, Bkb), + + Devices = [C1; C2; C3; C4], (* 24 combinations *) + // 1) not all devices are linkers + not consecutiveLinkers(Devices), (* filtered: linker1 linker2 linker3 linker4 d5_PSB3K3_Dest *) + + // 2) a fluorophore must be produced + hasFluorophore(Devices), (* filtered: linker1 linker2 d3_r0011_b0034_luxR d4_r0011_S175_lasR d5_PSB3K3_Dest + linker1 linker2 d3_r0011_b0034_luxR linker4 d5_PSB3K3_Dest + linker1 linker2 linker3 d4_r0011_S175_lasR d5_PSB3K3_Dest + linker1 linker2 r0040_b0033_cinR d4_r0011_S175_lasR d5_PSB3K3_Dest + linker1 linker2 r0040_b0033_cinR linker4 d5_PSB3K3_Dest *) + + // 3) all fluorophores have a different colour + not produceSameFluorophore(Devices), (* no device is filtered *) + + // 4) AHL promoter implies AHL receiver (possibly viceversa) + not uninducedHSL(Devices), (* filtered: linker1 d2_P81_YFP linker3 linker4 d5_PSB3K3_Dest + d1_P76_CFP linker2 linker3 linker4 d5_PSB3K3_Dest + d1_P76_CFP d2_P81_YFP linker3 linker4 d5_PSB3K3_Dest *) + + // 5) no protein is regulated twice + // no two parts produce the same molecule + not produceSameProtein(Devices), (* no device is filtered *) + + // 6) no promoter is regulated twice + // not regulateSamePromoter(Devices), (* disabled *) + + // 7) no promoter produces two different proteints + not samePromoterDifferentProtein(Devices), + + X = C[]. + (*final list, 9 combinations: + linker1 d2_P81_YFP r0040_b0033_cinR d4_r0011_S175_lasR d5_PSB3K3_Dest + linker1 d2_P81_YFP d3_r0011_b0034_luxR d4_r0011_S175_lasR d5_PSB3K3_Dest + d1_P76_CFP linker2 r0040_b0033_cinR d4_r0011_S175_lasR d5_PSB3K3_Dest + d1_P76_CFP linker2 d3_r0011_b0034_luxR d4_r0011_S175_lasR d5_PSB3K3_Dest + d1_P76_CFP d2_P81_YFP r0040_b0033_cinR d4_r0011_S175_lasR d5_PSB3K3_Dest + d1_P76_CFP d2_P81_YFP d3_r0011_b0034_luxR d4_r0011_S175_lasR d5_PSB3K3_Dest + linker1 d2_P81_YFP r0040_b0033_cinR linker4 d5_PSB3K3_Dest + linker1 d2_P81_YFP linker3 d4_r0011_S175_lasR d5_PSB3K3_Dest + linker1 d2_P81_YFP d3_r0011_b0034_luxR linker4 d5_PSB3K3_Dest + d1_P76_CFP linker2 r0040_b0033_cinR linker4 d5_PSB3K3_Dest + d1_P76_CFP linker2 linker3 d4_r0011_S175_lasR d5_PSB3K3_Dest + d1_P76_CFP linker2 d3_r0011_b0034_luxR linker4 d5_PSB3K3_Dest + d1_P76_CFP d2_P81_YFP r0040_b0033_cinR linker4 d5_PSB3K3_Dest + d1_P76_CFP d2_P81_YFP linker3 d4_r0011_S175_lasR d5_PSB3K3_Dest + d1_P76_CFP d2_P81_YFP d3_r0011_b0034_luxR linker4 d5_PSB3K3_Dest *) + +reaction([P], "found", D) :- P = C[], find_device(C, D).""" + +/////////////////////////////////// +/////////////////////////////////// +/////////////////////////////////// +/////////////////////////////////// +/////////////////////////////////// +/////////////////////////////////// + +let part1 : LogicGEC.Part = + { name = Term.Const "A" + type_ = Term.Const "promoter" } + +let part2 : LogicGEC.Part = + { name = Term.Const "B" + type_ = Term.Const "RBS" } + +let toTerm (e:Element) = Term.Pat (Pattern.Inner [e, Location.wildcard]) +let toDB = List.map Clause.Create >> toProgram + +/// simple database with just two parts +let db1 = toDB [ Pred("part", [toTerm (Part part1)]) + Pred("part", [toTerm (Part part2)]) ] + +let part1': LogicGEC.Part = + { name = Term.Const "A2" + type_ = Term.Const "promoter" } + +let part1'': LogicGEC.Part = + { name = Term.Const "dummy" + type_ = Term.Const "dummy" } + +let part3 : LogicGEC.Part = + { name = Term.Const "C" + type_ = Term.Const "CDS" } + +let part4 : LogicGEC.Part = + { name = Term.Const "D" + type_ = Term.Const "terminator" } + +/// simple database with just five parts: a promoter, rbs, cds, terminator, and a "dummy" part that has the same properties as the promoter +let db2 = toDB [ Pred("part", [toTerm (Part part1')]) + Pred("part", [toTerm (Part part1'')]) + Pred("part", [toTerm (Part part2)]) + Pred("part", [toTerm (Part part3)]) + Pred("part", [toTerm (Part part4)]) + Pred("neg", [part1'.name; Term.Const "c6" ]) + Pred("neg", [part1''.name; Term.Const "c6" ]) + Pred("codes", [part1''.name; Term.Const "c7" ]) + Pred("codes", [part3.name; Term.Const "c6" ]) ] + + +[] +let testDevicesCustom() = + let crn = "" |> Crn.from_string + let result = crn.simulate_case () + // TODO + () + +[] +let testDeviceEnumOnePart () = + // query: find the device < X >, where X is any one part in the database + let x = Term.Var (0, "X") + let query = [ Device [Part {name = x; type_ = Term.wildcard }] ] + + match LogicGEC.enumerateDeviceSubstitutions LogicGEC.cle db1 query with + | None + | Some [] -> failwith "No solution found" + | Some sols -> Assert.Equal(sols.Length, 2) + let sol1 = sols.Head + let found1 = sol1.Apply(x, LogicGEC.cle) + Assert.Equal (Term.Const "A", found1) + let sol2 = sols.Tail.Head + let found2 = sol2.Apply(x, LogicGEC.cle) + Assert.Equal (Term.Const "B", found2) + + +[] +let testDeviceEnumTwoParts () = + // query: find the device , where X and Y are any two distinct parts in the database + let x = Element.Var (0, "X") + let y = Element.Var (1, "Y") + let query = [ Device [ x; y] + ; Constraint (Neg (Pred ("=", [toTerm x; toTerm y])))] + + match LogicGEC.enumerateDeviceSubstitutions LogicGEC.cle db1 query with + | None + | Some [] -> failwith "No solution found" + | Some sols -> Assert.Equal(2, sols.Length) + let p1 = Part part1 + let p2 = Part part2 + + let sol1 = sols.Head + let x1 = sol1.Apply(x, LogicGEC.cle) + let y1 = sol1.Apply(y, LogicGEC.cle) + let d1 = [x1; y1] + + let sol2 = sols.Tail.Head + let x2 = sol2.Apply(x, LogicGEC.cle) + let y2 = sol2.Apply(y, LogicGEC.cle) + let d2 = [x2; y2] + + let exp1 = [p1; p2] + let exp2 = [p2; p1] + Assert.True( (d1 = exp1 && d2 = exp2) + || (d1 = exp2 && d2 = exp1) ) + +[] +let testDeviceEnumOnePartType () = + // query: find the device < X : RBS >, where X is an RBS + let x = Term.Var (0, "X") + let y = Term.Const "RBS" + let query = [ LogicGEC.Instruction.Device [Part { name = x; type_ = y }] ] + + match LogicGEC.enumerateDeviceSubstitutions LogicGEC.cle db1 query with + | None + | Some [] -> failwith "No solution found" + | Some sols -> Assert.Equal(sols.Length, 1) + let sol1 = sols.Head + let found1 = sol1.Apply(x, LogicGEC.cle) + Assert.Equal (Term.Const "B", found1) + +[] +let testDeviceEnumTwoPartTypes () = + // query: find the device + let v1 = Term.Var (0, "X") + let v2 = Term.Var (1, "Y") + let x1 = Part {name = v1; type_ = Term.Const "promoter" } + let x2 = Part {name = v2; type_ = Term.Const "RBS" } + let query = [ LogicGEC.Instruction.Device [x1; x2] ] + + match LogicGEC.enumerateDeviceSubstitutions LogicGEC.cle db1 query with + | None + | Some [] -> failwith "No solution found" + | Some sols -> + Assert.Equal(1, sols.Length) + let sol1 = sols.Head + let x1 = sol1.Apply(x1, LogicGEC.cle) |> toTerm + let y1 = sol1.Apply(x2, LogicGEC.cle) |> toTerm + let d = [x1; y1] + + let p1 = toTerm (Part part1) + let p2 = toTerm (Part part2) + let exp = [p1; p2] + + let test = exp = d + Assert.True(test) + +[] +let testDeviceEnumOnePartTypeProperty () = + // query: find the device > + let vp = Term.Var (0, "X") + let v2 = Term.Var (1, "P") + let prom = Part { Part.CreateByType("dummy") with name = vp } // ; props = Term.TList [Term.Func("neg", [v2])] } + + let query = [ LogicGEC.Instruction.Device [prom] ] + + match LogicGEC.enumerateDeviceSubstitutions LogicGEC.cle db2 query with + | None + | Some [] -> failwith "No solution found" + | Some sols -> + Assert.Equal(1, sols.Length) + let sol1 = sols.Head + let fp = sol1.Apply(vp, LogicGEC.cle) + + Assert.Equal(Term.Const "dummy", fp) + +[] +let testDeviceEnumOnePartProperty () = + // query: find the device >, where _ means any type containing property neg(P) + let x = Term.Var (0, "X") + let p = Term.Var (1, "P") + let part = Part.Create(x, Term.wildcard) |> Part + + let query = [ LogicGEC.Instruction.Device [part] + ; LogicGEC.Instruction.Constraint (Pos (Predicate.Pred ("neg", [ x; p]))) ] + + match LogicGEC.enumerateDeviceSubstitutions LogicGEC.cle db2 query with + | None + | Some [] -> failwith "No solution found" + | Some sols -> + Assert.Equal(2, sols.Length) + let sol1 = sols.Head + let s1 = sol1.Apply(x, LogicGEC.cle) + + let sol2 = sols.Tail.Head + let s2 = sol2.Apply(x, LogicGEC.cle) + + let actual = Set.ofList [s1;s2] + let expected = Set.ofList [part1'.name; part1''.name] + let b = actual = expected + + Assert.True(b) + + +[] +let testDeviceEnumSelfRepressilator () = + // query: find the device _:RBS _:CDS _:terminator> + let vp = Term.Var (0, "X") + let vr = Term.Var (0, "Y") + let vc = Term.Var (0, "W") + let vt = Term.Var (0, "Z") + let v2 = Term.Var (1, "P") + let prom = Part { Part.CreateByType("promoter") with name = vp } //; props = Term.TList [Term.Func("neg", [v2] )] } + let rbs = Part { Part.CreateByType("RBS") with name = vr } + let cds = Part { Part.CreateByType("CDS") with name = vc } //; props = Term.TList [Term.Func("codes", [v2]) ] } + let ter = Part { Part.CreateByType("terminator") with name = vt } + + let query = [ LogicGEC.Instruction.Device [prom; rbs; cds; ter] ] + + match LogicGEC.enumerateDeviceSubstitutions LogicGEC.cle db2 query with + | None + | Some [] -> failwith "No solution found" + | Some sols -> + Assert.Equal(1, sols.Length) + let sol1 = sols.Head + let fp = sol1.Apply(vp, LogicGEC.cle) + let fr = sol1.Apply(vr, LogicGEC.cle) + let fc = sol1.Apply(vc, LogicGEC.cle) + let ft = sol1.Apply(vt, LogicGEC.cle) + + Assert.Equal(Term.Const "A2", fp) + Assert.Equal(Term.Const "B", fr) + Assert.Equal(Term.Const "C", fc) + Assert.Equal(Term.Const "D", ft) + + +[] +let testDeviceEnumSelfRepressilators () = + // query: find the device <_:promoter _:RBS _:CDS _:terminator> + let x = Term.Var (0, "X") + let y = Term.Var (0, "Y") + let w = Term.Var (0, "W") + let z = Term.Var (0, "Z") + let p = Term.Var (1, "P") + let prom = Part ( Part.Create(x, Term.wildcard) ) // ByProperties([Term.Func("neg", [p] )]) with name = x } + let rbs = Part { Part.CreateByType("RBS") with name = y } + let cds = Part { Part.CreateByType("CDS") with name = w } //; props = Term.TList [Term.Func("codes", [p]) ] } + let ter = Part { Part.CreateByType("terminator") with name = z } + + let query = [ LogicGEC.Instruction.Device [prom; rbs; cds; ter] + ; LogicGEC.Instruction.Constraint (Pos (Predicate.Pred ("neg", [ x; p ]))) + ; LogicGEC.Instruction.Constraint (Pos (Predicate.Pred ("codes", [ w; p ]))) ] + + match LogicGEC.enumerateDeviceSubstitutions LogicGEC.cle db2 query with + | None + | Some [] -> failwith "No solution found" + | Some sols -> + Assert.Equal(2, sols.Length) + let sol1 = sols.Head + let fp1 = sol1.Apply(x, LogicGEC.cle) + let fr1 = sol1.Apply(y, LogicGEC.cle) + let fc1 = sol1.Apply(w, LogicGEC.cle) + let ft1 = sol1.Apply(z, LogicGEC.cle) + + let sol2 = sols.Tail.Head + let fp2 = sol2.Apply(x, LogicGEC.cle) + let fr2 = sol2.Apply(y, LogicGEC.cle) + let fc2 = sol2.Apply(w, LogicGEC.cle) + let ft2 = sol2.Apply(z, LogicGEC.cle) + + Assert.Equal(Term.Const "B", fr1) + Assert.Equal(Term.Const "C", fc1) + Assert.Equal(Term.Const "D", ft1) + + Assert.Equal(Term.Const "B", fr2) + Assert.Equal(Term.Const "C", fc2) + Assert.Equal(Term.Const "D", ft2) + + let proms = [fp1; fp2] |> Set.ofList + let expected = [part1'.name; part1''.name] |> Set.ofList + let b = proms = expected + Assert.True(b) + + + + +[] +let testParseRepressilator() = + let code1 = + """directive simulation {final = 100000.0; points = 1000} +directive rules { + """ + + let parts = """ + // parts + part(r0062::prom). pos(r0062, luxR:c6, 0.01, 0.01, 0.01). // luxR:c6 is a complex + part(r0090::prom). pos(r0090, lasR:c12, 0.01, 0.01, 0.01). + part(r0011::prom). neg(r0011, lacI, 0.01, 0.01, 0.01). + part(r0040::prom). neg(r0040, tetR, 0.01, 0.01, 0.01). + part(r0051::prom). neg(r0051, cI, 0.01, 0.01, 0.01). + + part(b0033::rbs). + part(b0034::rbs). + + part(e0040::pcr). codes(e0040, gfp, 0.01). + part(c0062::pcr). codes(c0062, luxR, 0.01). + part(c0079::pcr). codes(c0079, lasR, 0.01). + part(c0012::pcr). codes(c0012, lacI, 0.01). + part(c0040::pcr). codes(c0040, tetR, 0.01). + + part(b0015::ter). + """ + + let code2 = """ + // simplified regulation lookups + pos(Part, TF) :- pos(Part, TF, _, _, _). + neg(Part, TF) :- neg(Part, TF, _, _, _). + codes(Part, Pr) :- codes(Part, Pr, _). + + // interactions + bind(lacI,iptg). + bind(tetR,aTc). + bind(luxR,c6). + bind(lasR,c12). + synthesise(luxI,c6). + synthesise(lasI,c12). + transport(cell,c6). + transport(cell,c12). + + //////////////////////// + // Semantics + //////////////////////// + // positive regulation + reactions(S, CRN) :- + S = C[ Prom::prom Rbs::rbs Pcr::cds Ter::ter ], + pos(Prom, TF, Kb, Ku, Kt), + G = gene(), + M = mRNA(), + CRN = { TF + G <->{Kb}{Ku} TF:G + | G:TF ->{Kt} G:TF + M }. + + + // negative regulation + reactions(S, CRN) :- + S = C[ Prom::prom Rbs::rbs Pcr::cds Ter::ter ], + neg(Prom, TF, Kb, Ku, Kt), + G = gene(), + M = mRNA(), + CRN = { TF + G <->{Kb}{Ku} TF:G + | G:TF ->{Kt} G:TF + M }. + + // constitutive expression + reactions(S,CRN) :- + S = C[ Prom::prom Rbs::rbs Pcr::cds Ter::ter ], + con(Prom, Kt), + G = gene(), + M = mRNA(), + CRN = { G ->{Kt} G + M }. + + // translation + reactions(M, CRN) :- + M = mRNA(S), + S = C[Rbs::rbs Pcr::cds ], + rbs(Rbs, Kl), + codes(Pcr, P, Kd), + CRN = { M ->{Kl} M + P + | P ->{Kd} }. + + // degradation + reactions(M, CRN) :- + M = mRNA(S), + CRN = {M ->{0.001}}. + } + + //////////////////////// + // Genetic instructions + //////////////////////// + | + | + | codes(X1, R) + | pos(X2, R:S) + | codes(X3, gfp) + | bind(R, S) +""" + let code = code1 + parts + code2 + + let parser = Microsoft.Research.GEC.Program.parse + match Parser.from_string parser code with + | Program.t.LogicGec bundle -> + // assign fresh variables to wildcard parts (e.g. prom is a part with type prom and name "_") + let maxVar = + bundle.program + |> List.map fvi + |> Set.unionMany + |> Set.map (fun x -> + match x with + | Variable.SVar ((n,_), _) + | Variable.IVar ((n,_), _) + | Variable.LVar (n,_) + | Variable.TVar (n,_) -> n) + |> Set.maxElement + |> ref + + let fullProgram = + bundle.program + |> List.map (Instruction.Map (fun e -> + match e with + | Element.Var _ -> e + | Element.Part p -> if p.name = Term.wildcard + then + let x = !maxVar + maxVar := !maxVar + 1 + let freshVar = Term.Var(x, sprintf "X_%i" x) + Element.Part { p with name = freshVar} + else e)) + + let solutions = LogicGEC.enumerateDeviceSubstitutions LogicGEC.cle bundle.rules fullProgram + Assert.True(solutions.IsSome) + + let devs = + fullProgram + |> List.filter (fun i -> match i with Instruction.Device _ -> true | _ -> false) + + let actualDevices = + solutions + |> Option.get + |> List.map (fun (RulesDSD.Substitution.Substitution.Sub s) -> + devs + |> List.map (Instruction.Map (cle.applySub s)) + |> List.sort) + + |> List.distinct + + (* + let foundDevices = + solutions |> List.map (fun sigma -> + devs + |> List.map (fun d -> d) ) + *) + + let expectedText = """} + | + | """ + + let expectedCode = code1 + parts + expectedText + let expectedDevice = + match Parser.from_string parser expectedCode with + | Program.t.LogicGec bundle -> + bundle.program + |> List.sort + | _ -> failwith "" + + Assert.Contains(expectedDevice, actualDevices ) + + | Program.t.ClassicGec _ -> failwith "Unexpected Classic GEC program." + + + +[] +let testParseReceiverWithInitials() = + let code1 = + """directive simulation {final = 100000.0; points = 1000} +directive rules { + """ + + let parts = """ + // parts + part(r0062::prom). pos(r0062, luxR:c6, 0.01, 0.01, 0.01). // luxR:c6 is a complex + part(r0090::prom). pos(r0090, lasR:c12, 0.01, 0.01, 0.01). + part(r0011::prom). neg(r0011, lacI, 0.01, 0.01, 0.01). + part(r0040::prom). neg(r0040, tetR, 0.01, 0.01, 0.01). + part(r0051::prom). neg(r0051, cI, 0.01, 0.01, 0.01). + + part(b0033::rbs). + part(b0034::rbs). + + part(e0040::pcr). codes(e0040, gfp, 0.01). + part(c0062::pcr). codes(c0062, luxR, 0.01). + part(c0079::pcr). codes(c0079, lasR, 0.01). + part(c0012::pcr). codes(c0012, lacI, 0.01). + part(c0040::pcr). codes(c0040, tetR, 0.01). + + part(b0015::ter). + """ + + let code2 = """ + // simplified regulation lookups + pos(Part, TF) :- pos(Part, TF, _, _, _). + neg(Part, TF) :- neg(Part, TF, _, _, _). + codes(Part, Pr) :- codes(Part, Pr, _). + + // interactions + bind(lacI,iptg). + bind(tetR,aTc). + bind(luxR,c6). + bind(lasR,c12). + synthesise(luxI,c6). + synthesise(lasI,c12). + transport(cell,c6). + transport(cell,c12). + + //////////////////////// + // Semantics + //////////////////////// + // positive regulation + reactions(S, CRN) :- + S = C[ Prom::prom Rbs::rbs Pcr::cds Ter::ter ], + pos(Prom, TF, Kb, Ku, Kt), + G = gene(), + M = mRNA(), + CRN = { TF + G <->{Kb}{Ku} TF:G + | G:TF ->{Kt} G:TF + M }. + + + // negative regulation + reactions(S, CRN) :- + S = C[ Prom::prom Rbs::rbs Pcr::cds Ter::ter ], + neg(Prom, TF, Kb, Ku, Kt), + G = gene(), + M = mRNA(), + CRN = { TF + G <->{Kb}{Ku} TF:G + | G:TF ->{Kt} G:TF + M }. + + // constitutive expression + reactions(S,CRN) :- + S = C[ Prom::prom Rbs::rbs Pcr::cds Ter::ter ], + con(Prom, Kt), + G = gene(), + M = mRNA(), + CRN = { G ->{Kt} G + M }. + + // translation + reactions(M, CRN) :- + M = mRNA(S), + S = C[Rbs::rbs Pcr::cds ], + rbs(Rbs, Kl), + codes(Pcr, P, Kd), + CRN = { M ->{Kl} M + P + | P ->{Kd} }. + + // degradation + reactions(M, CRN) :- + M = mRNA(S), + CRN = {M ->{0.001}}. + } + + //////////////////////// + // Genetic instructions + //////////////////////// + | 10 + | 10 + | codes(X1, R) + | pos(X2, R:S) + | codes(X3, gfp) + | bind(R, S) +""" + let code = code1 + parts + code2 + + let parser = Microsoft.Research.GEC.Program.parse + match Parser.from_string parser code with + | Program.t.LogicGec bundle -> + // assign fresh variables to wildcard parts (e.g. prom is a part with type prom and name "_") + let maxVar = + bundle.program + |> List.map fvi + |> Set.unionMany + |> Set.map (fun x -> + match x with + | Variable.SVar ((n,_), _) + | Variable.IVar ((n,_), _) + | Variable.LVar (n,_) + | Variable.TVar (n,_) -> n) + |> Set.maxElement + |> ref + + let fullProgram = + bundle.program + |> List.map (Instruction.Map (fun e -> + match e with + | Element.Var _ -> e + | Element.Part p -> if p.name = Term.wildcard + then + let x = !maxVar + maxVar := !maxVar + 1 + let freshVar = Term.Var(x, sprintf "X_%i" x) + Element.Part { p with name = freshVar} + else e)) + + let solutions = LogicGEC.enumerateDeviceSubstitutions LogicGEC.cle bundle.rules fullProgram + Assert.True(solutions.IsSome) + + let devs = + fullProgram + |> List.filter (fun i -> match i with Instruction.Initial _ -> true | _ -> false) + + let actualDevices = + solutions + |> Option.get + |> List.map (fun (RulesDSD.Substitution.Substitution.Sub s) -> + devs + |> List.map (Instruction.Map (cle.applySub s)) + |> List.sort) + + |> List.distinct + + (* + let foundDevices = + solutions |> List.map (fun sigma -> + devs + |> List.map (fun d -> d) ) + *) + + let expectedText = """} + | 10 + | 10 """ + + let expectedCode = code1 + parts + expectedText + let expectedDevice = + match Parser.from_string parser expectedCode with + | Program.t.LogicGec bundle -> + bundle.program + |> List.sort + | _ -> failwith "" + + Assert.Contains(expectedDevice, actualDevices ) + + | Program.t.ClassicGec _ -> failwith "Unexpected Classic GEC program." \ No newline at end of file diff --git a/ClassicGEC/ClassicGECTests/modelGenerationTests.fs b/ClassicGEC/ClassicGECTests/modelGenerationTests.fs new file mode 100644 index 0000000..7b1118a --- /dev/null +++ b/ClassicGEC/ClassicGECTests/modelGenerationTests.fs @@ -0,0 +1,257 @@ +module modelGenerationTests + + +open Xunit +open FsUnit +open Microsoft.Research.CRNEngine + + +open RulesDSD.Syntax +open Microsoft.Research.GEC.LogicGEC + + + + + + +let lacI = Term.Const "lacI" +let tetR = Term.Const "tetR" +let cI = Term.Const "cI" +let r0011 : Part = + { name = Const "r0011" + type_ = Const "prom" } +let r0011a = Pred ("neg", [r0011.name; lacI; Float 1.0; Float 0.5; Float 0.00005]) +let r0011b = Pred ("con", [r0011.name; Float 0.1]) + +let r0040 : Part = + { name = Term.Const "r0040" + type_ = Term.Const "prom" } +let r0040a = Pred ("neg", [r0040.name; tetR; Float 1.0; Float 0.5; Float 0.00005]) +let r0040b = Pred ("con", [r0040.name; Float 0.09]) + +let r0051 : Part = + { name = Const "r0051" + type_ = Const "prom" } +let r0051a = Pred ("neg", [r0051.name; cI; Float 1.0; Float 0.5; Float 0.00005]) +let r0051b = Pred ("con", [r0051.name; Float 0.12]) + +let b0034 : Part = + { name = Const "b0034" + type_ = Const "rbs" } +let b0034a = Pred ("rbs", [b0034.name; Float 0.1]) + +let c0012 : Part = + { name = Const "c0012" + type_ = Const "cds" } +let c0012a = Pred ("codes", [c0012.name; lacI; Float 0.01]) + +let c0040 : Part = + { name = Const "c0040" + type_ = Const "cds" } +let c0040a = Pred ("codes", [c0040.name; tetR; Float 0.01]) + +let c0051 : Part = + { name = Const "c0051" + type_ = Const "cds" } +let c0051a = Pred ("codes", [c0051.name; cI; Float 0.01]) + +let b0015 : Part = + { name = Const "b0015" + type_ = Const "ter" } + +let toTerm (e:Element) = Term.Pat (Pattern.Inner [e, Location.wildcard]) +let dummyDB = [ Pred("part", [toTerm (Part r0011)]) |> Clause.Create + Pred("part", [toTerm (Part b0034)]) |> Clause.Create + Pred("part", [toTerm (Part c0040)]) |> Clause.Create + Pred("part", [toTerm (Part b0015)]) |> Clause.Create + Pred("part", [toTerm (Part r0040)]) |> Clause.Create + Pred("part", [toTerm (Part c0051)]) |> Clause.Create + Pred("part", [toTerm (Part r0051)]) |> Clause.Create + Pred("part", [toTerm (Part c0012)]) |> Clause.Create + r0011a |> Clause.Create + r0011b |> Clause.Create + r0040a |> Clause.Create + r0040b |> Clause.Create + r0051a |> Clause.Create + r0051b |> Clause.Create + b0034a |> Clause.Create + c0012a |> Clause.Create + c0040a |> Clause.Create + c0051a |> Clause.Create ] + +let getMassActionRegulation () = + let varCount = ref 0 + let tvar s = let i = !varCount + varCount := i + 1 + Term.Var(i, s) + + let s = tvar "S" + let crn = tvar "CRN" + let prom = tvar "Prom" + let rbs = tvar "Rbs" + let pcr = tvar "Pcr" + let ter = tvar "Ter" + let c = tvar "C" + let tf = tvar "TF" + let kb = tvar "Kb" + let ku = tvar "Ku" + let kt = tvar "Kt" + let g = tvar "G" + let m = tvar "M" + let kl = tvar "Kl" + let p = tvar "P" + let kd = tvar "Kd" + + let promT = Term.Const "prom" + let rbsT = Term.Const "rbs" + let cdsT = Term.Const "cds" + let terT = Term.Const "ter" + + let negHead = Predicate.Pred ("reactions", [s; crn]) + let promQuery = Part.Create(prom, promT) |> Element.Part + let rbsQuery = Part.Create(rbs, rbsT) |> Element.Part + let pcrQuery = Part.Create(pcr, cdsT) |> Element.Part + let terQuery = Part.Create(ter, terT) |> Element.Part + let pattern = Term.Pat (Pattern.Inner [ promQuery, Location.wildcard + ; rbsQuery, Location.wildcard + ; pcrQuery, Location.wildcard + ; terQuery, Location.wildcard ]) + let holes = TList [pattern] + let promE = Element.Part { name = prom; type_ = promT } + let rbsE = Element.Part { name = rbs; type_ = rbsT } + let pcrE = Element.Part { name = pcr; type_ = cdsT } + let terE = Element.Part { name = ter; type_ = terT } + + let gene = Term.Func("gene", [Process.OfList [[promE; rbsE; pcrE; terE]] |> Term.Proc]) + let rna = Term.Func("mRNA", [Process.OfList [[rbsE; pcrE]] |> Term.Proc]) + + // TF + G <->{Kb}{Ku} TF:G + let r1 = Term.Func("_rxn", [ Term.TMSet [] + ; Term.TMSet [1, tf; 1, g] + ; Term.Func("_massActionRate", [Term.Func("_key", [kb])] ) + ; Term.Func("_massActionRate", [Term.Func("_key", [ku])] ) + ; Term.TMSet [1, Term.TMSet [1, tf; 1, g]] ]) + // G:TF ->{Kt} G:TF + M + let r2 = Term.Func("_rxn", [ Term.TMSet [] + ; Term.TMSet [1, Term.TMSet [1, g; 1, tf]] + ; Term.Func("_massActionRate", [Term.Func("_key", [kt])] ) + ; Term.Func("", [] ) + ; Term.TMSet [1, Term.TMSet [1, g; 1, tf]; 1, m] ]) + let crnT = Term.TCRN [r1; r2] + let negBody = [ Predicate.Pred ("is", [s; c; holes]) |> Pos + ; Predicate.Pred ("neg", [prom; tf; kb; ku; kt]) |> Pos + ; Predicate.Pred ("=", [g; gene]) |> Pos + ; Predicate.Pred ("=", [m; rna]) |> Pos + ; Predicate.Pred ("=", [crn; crnT]) |> Pos ] + let negRule = Clause.Create(negHead, negBody) + + (* + constitutive(S,CRN) :- + S = C[ Prom::prom Rbs::rbs Pcr::pcr Ter::ter ], + con(Prom, Kt), + G = gene(), + M = mrna(), + CRN = { | G ->{Kt} G + M }. + *) + + let r2' = Term.Func("_rxn", [ Term.TMSet [] + ; Term.TMSet [1, g] + ; Term.Func("_massActionRate", [Term.Func("_key", [kt])] ) + ; Term.Func("", [] ) + ; Term.TMSet [1, g; 1, m] ]) + let conCrn = Term.TCRN [r2'] + let promQuery = Part.Create(prom, Term.Const "prom") |> Element.Part + let rbsQuery = Part.Create(rbs, Term.Const "rbs") |> Element.Part + let pcrQuery = Part.Create(pcr, Term.Const "cds") |> Element.Part + let terQuery = Part.Create(ter, Term.Const "ter") |> Element.Part + let pattern = Term.Pat (Pattern.Inner [ promQuery, Location.wildcard + ; rbsQuery, Location.wildcard + ; pcrQuery, Location.wildcard + ; terQuery, Location.wildcard ]) + let holes = TList [pattern] + let conBody = [ Predicate.Pred ("is", [s; c; holes]) |> Pos + ; Predicate.Pred ("con", [prom; kt]) |> Pos + ; Predicate.Pred ("=", [g; gene]) |> Pos + ; Predicate.Pred ("=", [m; rna]) |> Pos + ; Predicate.Pred ("=", [crn; conCrn]) |> Pos ] + let conHead = negHead + let conRule = Clause.Create(conHead, conBody) + + (* translation rule: + reactions(M, CRN) :- + M = mrna(S), + S = C[Rbs:: Pcr::pcr ], + rbs(Rbs, Kl), + codes(Pcr, P, Kd), + CRN = { | M ->{Kl} M + P + | P ->{Kd} }. + *) + let rbsQuery = Part.Create(rbs, Term.Const "rbs") |> Element.Part + let pcrQuery = Part.Create(pcr, Term.Const "cds") |> Element.Part + let pattern = Term.Pat (Pattern.Inner [ rbsQuery, Location.wildcard + ; pcrQuery, Location.wildcard ]) + let holes = TList [pattern] + let tr1 = Term.Func("_rxn", [ Term.TMSet [] + ; Term.TMSet [1, m] + ; Term.Func("_massActionRate", [Term.Func("_key", [kl])] ) + ; Term.Func("", [] ) + ; Term.TMSet [1, m; 1, p] ]) + let tr2 = Term.Func("_rxn", [ Term.TMSet [] + ; Term.TMSet [1, p] + ; Term.Func("_massActionRate", [Term.Func("_key", [kd])] ) + ; Term.Func("", [] ) + ; Term.TMSet [] ]) + let translCrn = Term.TCRN [tr1; tr2] + + let translHead = Predicate.Pred ("reactions", [m; crn]) + let translBody = [ Predicate.Pred ("=", [m; Term.Func("mRNA", [s])]) |> Pos + ; Predicate.Pred ("is", [s; c; holes]) |> Pos + ; Predicate.Pred ("rbs", [rbs; kl]) |> Pos + ; Predicate.Pred ("codes", [pcr; p; kd]) |> Pos + ; Predicate.Pred ("=", [crn; translCrn]) |> Pos ] + + let translRule = Clause.Create(translHead, translBody) + + (* all mRNA degrades with rate 0.001: + reactions(mrna(M), {mrna(M) ->{0.001}} ) *) + let degCrn = Term.TCRN [ Term.Func("_rxn", [ Term.TMSet [] + ; Term.TMSet [1, m] + ; Term.Func("_massActionRate", [Term.Float 0.001] ) + ; Term.Func("", [] ) + ; Term.TMSet [] ]) ] + let degHead = Predicate.Pred ("reactions", [m; crn]) + let degBody = [ Predicate.Pred ("=", [m; Term.Func("mRNA", [s])]) |> Pos + ; Predicate.Pred ("=", [crn; degCrn]) |> Pos ] + let degRule = Clause.Create(degHead, degBody) + + [ negRule; degRule; conRule; translRule ] + +[] +let testModelGenRepressilator() = + // build a model for the repressilator device: + // r0011; b0034; c0040; b0015; r0040; b0034; c0051; b0015; r0051; b0034; c0012; b0015 + // which is one of the solutions found for the repressilator during device enumeration + + // simple database with eight parts, plus negative regulation, constitute, mRNA transcription and mRNA degradation rules + let db2 = dummyDB @ getMassActionRegulation () |> toProgram + let repressilator = [r0011; b0034; c0040; b0015; r0040; b0034; c0051; b0015; r0051; b0034; c0012; b0015] + |> List.map Part + let prog = [ Instruction.Device repressilator ] + let generatedCrn = generateCRN cle db2 prog + Assert.Equal(18, generatedCrn.reactions.Length) + +[] +let testModelGenRepressilatorInits() = + let db2 = dummyDB @ getMassActionRegulation () |> toProgram + let repressilator : Complex = + [r0011; b0034; c0040; b0015; r0040; b0034; c0051; b0015; r0051; b0034; c0012; b0015] + |> List.map Part + |> fun x -> [0, x] + |> Map.ofList + |> Process.Proc + |> Term.Proc + |> fun x -> [1, x] + let prog = [ Instruction.Initial (Term.Float 10.0, repressilator) ] + let generatedCrn = generateCRN cle db2 prog + let debug = generatedCrn.to_string () + Assert.Equal(18, generatedCrn.reactions.Length) \ No newline at end of file diff --git a/ClassicGEC/ClassicGECTests/paket.references b/ClassicGEC/ClassicGECTests/paket.references new file mode 100644 index 0000000..0f7443b --- /dev/null +++ b/ClassicGEC/ClassicGECTests/paket.references @@ -0,0 +1,9 @@ +group DOTNETCORE + +FsCheck +FsUnit.xUnit +argu +xunit.core +xunit.runner.console +xunit.runner.visualstudio +FSharp.Core \ No newline at end of file diff --git a/ClassicGEC/ClassicGECTests/parsingTests.fs b/ClassicGEC/ClassicGECTests/parsingTests.fs new file mode 100644 index 0000000..02a53f8 --- /dev/null +++ b/ClassicGEC/ClassicGECTests/parsingTests.fs @@ -0,0 +1,311 @@ +module parsingTests + +open Xunit +open FsUnit +open Microsoft.Research.CRNEngine + +open RulesDSD.Syntax +open Microsoft.Research.GEC +open Microsoft.Research.GEC.LogicGEC + +[] +let testParseSinglePart() = + let pName = "r0011" + let pType = "prom" + let idProvider = newIdProvider () (ref Map.empty) + + let a : Part = pName |> Parser.from_string (Part.parse idProvider cle.domainKeywords) + let e : Part = Part.Create (Const pName, Term.wildcard) + Assert.Equal(e, a) + + let a : Part = pName + "::" + pType |> Parser.from_string (Part.parse idProvider cle.domainKeywords) + let e : Part = Part.Create (Const pName, Const "prom") + Assert.Equal(e, a) + + let a : Part = pName + "::" + pType |> Parser.from_string (Part.parse idProvider cle.domainKeywords) + let e : Part = Part.Create (Const pName, Const pType) + Assert.Equal(e, a) + + let a : Part = pName + "::" + pType |> Parser.from_string (Part.parse idProvider cle.domainKeywords) + let e : Part = Part.Create (Const pName, Const pType) + Assert.Equal(e, a) + + // Variables + let x = "X" + let y = "Y" + let xTerm = idProvider x |> Term.Var + let yTerm = idProvider y |> Term.Var + let a : Part = x + |> Parser.from_string (Part.parse idProvider cle.domainKeywords) + let e : Part = Part.Create (xTerm, Term.wildcard) + Assert.Equal(e, a) + + let a : Part = x + "::" + pType + |> Parser.from_string (Part.parse idProvider cle.domainKeywords) + let e : Part = Part.Create (xTerm, Const pType) + Assert.Equal(e, a) + + let a : Part = x + "::" + y + |> Parser.from_string (Part.parse idProvider cle.domainKeywords) + let e : Part = Part.Create (xTerm, yTerm) + Assert.Equal(e, a) + + let a : Part = pName + "::" + y + |> Parser.from_string (Part.parse idProvider cle.domainKeywords) + let e : Part = Part.Create (Const pName, yTerm) + Assert.Equal(e, a) + + + +[] +let testParseClassicGecParts() = + let idProvider = newIdProvider () (ref Map.empty) + + // r0011 + let e = modelGenerationTests.r0011 + let a = """r0011::prom""" |> Parser.from_string (Part.parse idProvider cle.domainKeywords) + Assert.Equal(e, a) + + // r0040 + let e = modelGenerationTests.r0040 + let a = """r0040::prom""" |> Parser.from_string (Part.parse idProvider cle.domainKeywords) + Assert.Equal(e, a) + + // r0051 + let e = modelGenerationTests.r0051 + let a = """r0051::prom""" |> Parser.from_string (Part.parse idProvider cle.domainKeywords) + Assert.Equal(e, a) + + // b0034 + let e = modelGenerationTests.b0034 + let a = """b0034::rbs""" |> Parser.from_string (Part.parse idProvider cle.domainKeywords) + Assert.Equal(e, a) + + // c0012 + let e = modelGenerationTests.c0012 + let a = """c0012::cds""" |> Parser.from_string (Part.parse idProvider cle.domainKeywords) + Assert.Equal(e, a) + + // c0040 + let e = modelGenerationTests.c0040 + let a = """c0040::cds""" |> Parser.from_string (Part.parse idProvider cle.domainKeywords) + Assert.Equal(e, a) + + // c0051 + let e = modelGenerationTests.c0051 + let a = """c0051::cds""" |> Parser.from_string (Part.parse idProvider cle.domainKeywords) + Assert.Equal(e, a) + + // b0015 + let e = modelGenerationTests.b0015 + let a = """b0015::ter""" |> Parser.from_string (Part.parse idProvider cle.domainKeywords) + Assert.Equal(e, a) + +let db = """ +part( r0011::prom). + neg( r0011, lacI, 1.0, 0.5, 0.00005). + con( r0011, 0.1). + +part( r0040::prom). + neg( r0040, tetR, 1.0, 0.5, 0.00005). + con( r0040, 0.09). + +part( r0051::prom). + neg( r0051, cI, 1.0, 0.5, 0.00005). + con( r0051, 0.12 ). + +part( b0034::rbs ). + rbs(b0034, 0.1). + +part( c0012::cds ). + codes( c0012, lacI, 0.01 ). +part( c0040::cds ). + codes( c0040, tetR, 0.01 ). +part( c0051::cds ). + codes(c0051, cI, 0.01). + +part( b0015::ter). +""" +[] +let testParseClassicGecDB() = + let e = modelGenerationTests.dummyDB |> RulesDSD.Syntax.toProgram + let a = Parser.from_string (pGecProgram) db + let eSeq = e |> Dictionary.toSeq + let aSeq = a |> Dictionary.toSeq + // check signatures + let eSig = eSeq |> Seq.map fst |> Seq.toList + let aSig = aSeq |> Seq.map fst |> Seq.toList + List.zip eSig aSig + |> List.map (fun (e,a) -> Assert.Equal(e,a)) + |> ignore + + // check predicates + eSig + |> List.map(fun s -> + let eClauses = e.[s] |> Set.toList |> List.sort + let aClauses = a.[s] |> Set.toList |> List.sort + Assert.Equal(eClauses.Length, aClauses.Length) + + List.zip eClauses aClauses + |> List.map (fun (e,a) ->Assert.Equal(e,a))) + + +let simpleRegulationSemantics = """ +// negative regulation +reactions(S, CRN) :- + S = C[ Prom::prom Rbs::rbs Pcr::cds Ter::ter ], + neg(Prom, TF, Kb, Ku, Kt), + G = gene(), + M = mRNA(), + CRN = { TF + G <->{Kb}{Ku} TF:G + | G:TF ->{Kt} G:TF + M }. + +// constitutive expression +reactions(S,CRN) :- + S = C[ Prom::prom Rbs::rbs Pcr::cds Ter::ter ], + con(Prom, Kt), + G = gene(), + M = mRNA(), + CRN = { G ->{Kt} G + M }. + +// translation +reactions(M, CRN) :- + M = mRNA(S), + S = C[Rbs::rbs Pcr::cds ], + rbs(Rbs, Kl), + codes(Pcr, P, Kd), + CRN = { M ->{Kl} M + P + | P ->{Kd} }. + +// degradation +reactions(M, CRN) :- + M = mRNA(S), + CRN = {M ->{0.001}}. +""" + + +[] +let testParseSimpleRegulationSemantics() = + let a = Parser.from_string (pGecProgram) simpleRegulationSemantics + let e : RulesProgram = modelGenerationTests.getMassActionRegulation () |> RulesDSD.Syntax.toProgram + + let eSeq = e |> Dictionary.toSeq + let aSeq = a |> Dictionary.toSeq + // check signatures + let eSig = eSeq |> Seq.map fst |> Seq.toList + let aSig = aSeq |> Seq.map fst |> Seq.toList + + + List.zip eSig aSig + |> List.map (fun (e,a) -> Assert.Equal(e,a)) + |> ignore + + eSig + |> List.map(fun s -> + let eClauses = e.[s] |> Set.toList |> List.sort + let aClauses = a.[s] |> Set.toList |> List.sort + Assert.Equal(eClauses.Length, aClauses.Length) + + List.zip eClauses aClauses + |> List.map (fun (e,a) ->Assert.Equal(e,a))) + + + +[] +let testParseDeviceEnumerationReceiver() = + let code = """ + | + | + | codes(X1,Receiver) + | pos(Receiver:Signal,X2) + | codes(X3,gfp) + | bind(Receiver,Signal) + """ + + let semantics = new System.Collections.Generic.Dictionary<_,_>() + let settings = { Microsoft.Research.GEC.Settings.Gec_settings.default_settings with rules = Some semantics } + let parser = Microsoft.Research.GEC.Program.parseLogic settings + let actual = Parser.from_string parser code + + let idProvider = makeProvider() + + let toPattern (p:Part) = Term.Pat (Pattern.Inner [Element.Part p, Location.wildcard]) + + let expected : Microsoft.Research.GEC.Program.LogicProgram = + { settings = settings + rules = semantics + program = [ LogicGEC.Device [ Element.Part (Part.CreateByType "prom") + Element.Part (Part.CreateByType "rbs") + Element.Part (Part.Create(Term.Var(idProvider "X1"), Term.Const "pcr")) + Element.Part (Part.CreateByType "ter") ] + LogicGEC.Device [ Element.Part (Part.Create(Term.Var(idProvider "X2"), Term.Const "prom")) + Element.Part (Part.CreateByType "rbs") + Element.Part (Part.Create(Term.Var(idProvider "X3"), Term.Const "pcr")) + Element.Part (Part.CreateByType "ter") ] + LogicGEC.Constraint(Literal.Pos (Pred("codes", [ Term.Var(idProvider "X1"); Term.Var(idProvider "Receiver")]))) + LogicGEC.Constraint(Literal.Pos (Pred("pos", [ Term.TMSet [1, Term.Var(idProvider "Receiver"); 1, Term.Var(idProvider "Signal")] |> Term.Canonical cle; Term.Var(idProvider "X2") ]))) + LogicGEC.Constraint(Literal.Pos (Pred("codes", [ Term.Var(idProvider "X3"); Term.Const "gfp" ]))) + LogicGEC.Constraint(Literal.Pos (Pred("bind", [ Term.Var(idProvider "Receiver"); Term.Var(idProvider "Signal")]))) + + ] + } + + Assert.Equal(expected, actual) + + + +[] +let testParseDeviceEnumerationReceiverWithInitials() = + let code = """ + | 10 + | 10 + | codes(X1,Receiver) + | pos(Receiver:Signal,X2) + | codes(X3,gfp) + | bind(Receiver,Signal) + """ + + let semantics = new System.Collections.Generic.Dictionary<_,_>() + let settings = { Microsoft.Research.GEC.Settings.Gec_settings.default_settings with rules = Some semantics } + let parser = Microsoft.Research.GEC.Program.parseLogic settings + let actual = Parser.from_string parser code + + let idProvider = makeProvider() + + let toPattern (p:Part) = Term.Pat (Pattern.Inner [Element.Part p, Location.wildcard]) + + let expected : Microsoft.Research.GEC.Program.LogicProgram = + { settings = settings + rules = semantics + program = [ LogicGEC.Initial + ( Term.Float 10.0, + [ Element.Part (Part.CreateByType "prom") + Element.Part (Part.CreateByType "rbs") + Element.Part (Part.Create(Term.Var(idProvider "X1"), Term.Const "pcr")) + Element.Part (Part.CreateByType "ter") ] + |> List.singleton + |> Process.OfList + |> Term.Proc + |> toComplex) + LogicGEC.Initial + ( Term.Float 10.0, + [ Element.Part (Part.Create(Term.Var(idProvider "X2"), Term.Const "prom")) + Element.Part (Part.CreateByType "rbs") + Element.Part (Part.Create(Term.Var(idProvider "X3"), Term.Const "pcr")) + Element.Part (Part.CreateByType "ter") ] + |> List.singleton + |> Process.OfList + |> Term.Proc + |> toComplex) + LogicGEC.Constraint(Literal.Pos (Pred("codes", [ Term.Var(idProvider "X1"); Term.Var(idProvider "Receiver")]))) + LogicGEC.Constraint(Literal.Pos (Pred("pos", [ Term.TMSet [1, Term.Var(idProvider "Receiver"); 1, Term.Var(idProvider "Signal")] |> Term.Canonical cle; Term.Var(idProvider "X2") ]))) + LogicGEC.Constraint(Literal.Pos (Pred("codes", [ Term.Var(idProvider "X3"); Term.Const "gfp" ]))) + LogicGEC.Constraint(Literal.Pos (Pred("bind", [ Term.Var(idProvider "Receiver"); Term.Var(idProvider "Signal")]))) + + ] + } + + Assert.Equal(expected, actual) + + + diff --git a/ClassicGEC/ClassicGECWebServer/App.config b/ClassicGEC/ClassicGECWebServer/App.config new file mode 100644 index 0000000..9b89096 --- /dev/null +++ b/ClassicGEC/ClassicGECWebServer/App.config @@ -0,0 +1,358 @@ + + + + + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + \ No newline at end of file diff --git a/ClassicGEC/ClassicGECWebServer/AssemblyInfo.fs b/ClassicGEC/ClassicGECWebServer/AssemblyInfo.fs new file mode 100644 index 0000000..f4d2e14 --- /dev/null +++ b/ClassicGEC/ClassicGECWebServer/AssemblyInfo.fs @@ -0,0 +1,41 @@ +namespace ClassicGECWebServer.AssemblyInfo + +open System.Reflection +open System.Runtime.CompilerServices +open System.Runtime.InteropServices + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[] +[] +[] +[] +[] +[] +[] +[] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [] +[] +[] + +do + () \ No newline at end of file diff --git a/ClassicGEC/ClassicGECWebServer/BuildSettings.fs b/ClassicGEC/ClassicGECWebServer/BuildSettings.fs new file mode 100644 index 0000000..362f042 --- /dev/null +++ b/ClassicGEC/ClassicGECWebServer/BuildSettings.fs @@ -0,0 +1,5 @@ +module ClassicGECServer.BuildSettings + +let homeFolder = "ClassicGECHTML5" +let jobsFolder = "CRNJobsManager" +let port = 8084 \ No newline at end of file diff --git a/ClassicGEC/ClassicGECWebServer/ClassicGECWebServer.fsproj b/ClassicGEC/ClassicGECWebServer/ClassicGECWebServer.fsproj new file mode 100644 index 0000000..15d1608 --- /dev/null +++ b/ClassicGEC/ClassicGECWebServer/ClassicGECWebServer.fsproj @@ -0,0 +1,46 @@ + + + + netcoreapp3.1 + Exe + x64 + True + x64 + + + + + + + + + + + PreserveNewest + + + + + + + + + + + + + ..\..\Lib\Oslo.FSharp\Oslo.FSharp.dll + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ClassicGEC/ClassicGECWebServer/GEC.fs b/ClassicGEC/ClassicGECWebServer/GEC.fs new file mode 100644 index 0000000..e6ffa1b --- /dev/null +++ b/ClassicGEC/ClassicGECWebServer/GEC.fs @@ -0,0 +1,95 @@ +module Microsoft.Research.ClassicGECWebServer.GEC + +open System.Net.WebSockets +open Messages +open Microsoft.Research.GEC +open Microsoft.Research.CRNEngine +open Microsoft.Research.CRNEngine.JSAPI +open Microsoft.Research +open Microsoft.Research.CRNEngineServerLib.Messages +open Microsoft.Research.CRNEngineServerLib.Serialisation +open Microsoft.Research.GEC.GECEngine +open FSBOL +open System.IO +open System.Xml + +let mutable currentResult : GEC.JSAPI.solve_result option = None +let mutable currentSolution : GEC.JSAPI.solution_result option = None + +let serializeSBOLDocumentToXML sbol = + let xml = XmlSerializer.sbolToXml sbol + let stringWriter = new StringWriter() + let settings = new XmlWriterSettings(); + settings.Indent <- true; + let xmlWriter = XmlWriter.Create(stringWriter, settings); + xml.WriteTo(xmlWriter); + xmlWriter.Flush(); + let ret = stringWriter.GetStringBuilder().ToString(); + xmlWriter.Dispose(); + stringWriter.Dispose(); + ret + +let processCompileGECRequest code dbparts dbreactions (webSocket:WebSocket) = + let sendObject o = sendObject webSocket o + try + match GEC.JSAPI.compile code dbparts dbreactions with + | GEC.JSAPI.LogicGEC _ -> failwith "Logic GEC JS not supported yet." + | GEC.JSAPI.ClassicGEC result -> + currentResult <- Some (GEC.JSAPI.ClassicGEC result) + currentSolution <- None + let model = result.model + sendObject { Response_Program.mtype = "program" + Response_Program.model = model } + sendObject { Response_GECSolutions.mtype = "gec.solutions" + Response_GECSolutions.count = (match result.solution.solution with Some (_,s,_,_,_) -> s.numSolutions | _ -> 0) } + sendObject { Response_SBOL.mtype = "gec.jsbol" + Response_SBOL.document = result.jsbol } + with e -> match e with + | :? CompileException as e -> match (e.Data0, e.Data1) with + | parser, (:? Parser.Exception as e) -> sendObject { mtype = "error" + error = { message = parser+": "+e.Message; positions=Some e.Errors } } + | _ -> sendObject { mtype = "error" + error = { message = e.Message; positions = None } } + | :? Parser.Exception as e -> sendObject { mtype = "error" + error = { message = e.Message; positions = Some e.Errors } } + | _ -> sendObject { mtype = "error" + error = { message = e.Message; positions = None } } + +let processGetSolution idx (webSocket:WebSocket) = + let sendObject o = sendObject webSocket o + let result = JSAPI.get_solution (match currentResult with Some res -> res | None -> failwith "no result") idx + currentSolution <- Some result + let model = result.model + sendObject { Response_GECSolution.mtype = "gec.solution" + Response_GECSolution.solution = { model = model; code = result.crnstring } } + sendObject { Response_SBOL.mtype = "gec.jsbol" + Response_SBOL.document = result.jsbol } + let xsbol = serializeSBOLDocumentToXML result.sbol + sendObject { Response_Export.mtype = "export" + Response_Export.export = { content_type = "text/plain" + id = "sbol" + node_id = None + instance = None + display_name = "SBOL" + content = Some [|xsbol|] + save_content = None } } + +let getXMLExport () = + let xsbol = match currentSolution with + | Some solution -> serializeSBOLDocumentToXML solution.sbol |> Some + | None -> match currentResult with + | Some (GEC.JSAPI.ClassicGEC result) -> serializeSBOLDocumentToXML result.sbol |> Some + | Some (GEC.JSAPI.LogicGEC _) -> failwith "Logic GEC is not supported yet." + | None -> None + let export = match xsbol with + | Some xsbol -> + { Response_Export.mtype = "export" + Response_Export.export = { content_type = "text/plain" + id = "sbol" + node_id = None + instance = None + display_name = "SBOL" + content = Some [|xsbol|] + save_content = None } } |> Some + | None -> None + export \ No newline at end of file diff --git a/ClassicGEC/ClassicGECWebServer/Messages.fs b/ClassicGEC/ClassicGECWebServer/Messages.fs new file mode 100644 index 0000000..a3e29a6 --- /dev/null +++ b/ClassicGEC/ClassicGECWebServer/Messages.fs @@ -0,0 +1,32 @@ +module Microsoft.Research.ClassicGECWebServer.Messages + +open Microsoft.Research.CRNEngine +open Microsoft.Research.Filzbach +open Microsoft.Research +open Microsoft.Research.CRNEngine.JSAPI + +type Request_GECCompile = + { mtype : string + code : string + parts : string + reactions : string } + +type Request_GECGetSolution = + { mtype : string + idx : int } + +type Response_GECSolutions = + { mtype : string + count : int } + +type Response_SBOL = + { mtype : string + document : FSBOL.JsonSerializer.rSBOLDocument } + +type GECSolution = + { model : GuiIG + code : string } + +type Response_GECSolution = + { mtype : string + solution : GECSolution } \ No newline at end of file diff --git a/ClassicGEC/ClassicGECWebServer/Program.fs b/ClassicGEC/ClassicGECWebServer/Program.fs new file mode 100644 index 0000000..65145e1 --- /dev/null +++ b/ClassicGEC/ClassicGECWebServer/Program.fs @@ -0,0 +1,42 @@ +module Microsoft.Research.ClassicGECWebServer.Program + +open System +open System.Net.WebSockets +open Microsoft.AspNetCore +open Microsoft.AspNetCore.Hosting +open System.Threading +open Microsoft.Research.CRNEngineServerLib +open Microsoft.Research.CRNEngineServerLib.Serialisation +open Microsoft.Research.CRNEngineServerLib.Messages +open Microsoft.Research.CRNEngineServerLib.Server +open Microsoft.Research.ClassicGECWebServer + +let processRequest (webSocket:WebSocket) (mtype:string) (json:string) (cancel:bool ref) = + //TODO: switch to codegen of interface rather than relying on strings + match mtype with + | "statespace" -> + let stateSpace = WebSharper.Json.Deserialize json + if stateSpace.jit then failwith "GEC does not support JIT state space exploration" + StateSpace.processStateSpaceRequest stateSpace.model webSocket + | "gec.compile" -> + let compileGec = WebSharper.Json.Deserialize json + GEC.processCompileGECRequest compileGec.code compileGec.parts compileGec.reactions webSocket + | "gec.getsolution" -> + let getSolution = WebSharper.Json.Deserialize json + GEC.processGetSolution getSolution.idx webSocket + | "generateexports" -> + let generateExports = WebSharper.Json.Deserialize json + Exports.processGenerateExportsRequest generateExports.model generateExports.nodeId webSocket + match GEC.getXMLExport () with + | Some export -> sendObject webSocket export + | None -> () + | _ -> defaultProcessRequest webSocket mtype json cancel + +let homeFolder = "ClassicGECHTML5" +let jobsFolder = "CRNJobsManager" +let port = 8085 + +[] +let main argv = + Server.main processRequest homeFolder jobsFolder port + 0 \ No newline at end of file diff --git a/ClassicGEC/ClassicGECWebServer/build.fsx b/ClassicGEC/ClassicGECWebServer/build.fsx new file mode 100644 index 0000000..b91a1a8 --- /dev/null +++ b/ClassicGEC/ClassicGECWebServer/build.fsx @@ -0,0 +1,33 @@ +#r "paket: groupref Build //" +#load ".fake/build.fsx/intellisense.fsx" +open Fake.Core +open Fake.DotNet +open Fake.IO +open Fake.IO.FileSystemOperators +open Fake.IO.Globbing.Operators +open BlackFox.Fake + +#load "../../Builds/Builds/PublishHelper.fs" +open PublishHelper +#load "../ClassicGECWebServer/BuildSettings.fs" + +let copyRequiredFilestoOutput projectDir outDir configuration = + copySundials projectDir outDir configuration + copyWebStuff projectDir outDir ClassicGECServer.BuildSettings.homeFolder + copyJobStuff projectDir outDir ClassicGECServer.BuildSettings.jobsFolder + +let build = BuildTask.createFn "Build" [] (fun args -> + let settings = parseSettings args.Context.Arguments + copyRequiredFilestoOutput settings.["ProjectDir"] settings.["OutDir"] settings.["Configuration"] +) + +//Example: +//dotnet fake build --target Publish ProjectDir="E:\dev\biocomputing\ClassicGEC\ClassicGECServer\" PublishDir="bin\Debug\netcoreapp3.0\publish\" Configuration=Debug +let publish = BuildTask.createFn "Publish" [] (fun args -> + let settings = parseSettings args.Context.Arguments + copyRequiredFilestoOutput settings.["ProjectDir"] settings.["PublishDir"] settings.["Configuration"] +) + +let nothing = BuildTask.createEmpty "Nothing" [] + +BuildTask.runOrDefaultWithArguments nothing \ No newline at end of file diff --git a/ClassicGEC/ClassicGECWebServer/index.html b/ClassicGEC/ClassicGECWebServer/index.html new file mode 100644 index 0000000..73a6ad3 --- /dev/null +++ b/ClassicGEC/ClassicGECWebServer/index.html @@ -0,0 +1 @@ +HELLO DSD \ No newline at end of file diff --git a/ClassicGEC/ClassicGECWebServer/paket.references b/ClassicGEC/ClassicGECWebServer/paket.references new file mode 100644 index 0000000..00eb6d6 --- /dev/null +++ b/ClassicGEC/ClassicGECWebServer/paket.references @@ -0,0 +1,10 @@ +group DOTNETCORE + +Giraffe +Microsoft.AspNetCore +Microsoft.AspNetCore.StaticFiles +Microsoft.AspNetCore.WebSockets +Microsoft.AspNetCore.WebSockets.Server +#Streams +FSharp.Core +WebSharper.Core \ No newline at end of file diff --git a/ClassicGEC/Examples/GECModels/band_detector.txt b/ClassicGEC/Examples/GECModels/band_detector.txt new file mode 100644 index 0000000..b9de18d --- /dev/null +++ b/ClassicGEC/Examples/GECModels/band_detector.txt @@ -0,0 +1,14 @@ +directive simulation {final = 50000.0; points = 500; plots = [receiver_gfp]} + +receiver +[ runknown5:prom; rbs; pcr; ter +| prom; rbs; pcr;ter +| prom; rbs; pcr;ter +| prom;rbs; pcr;ter +| prom;rbs;pcr;ter +| luxR + Signal -> luxR::Signal +| luxR::Signal -> luxR + Signal +] +| Signal -> receiver[Signal] +| receiver[Signal] -> Signal +| initPop Signal 100.0 \ No newline at end of file diff --git a/ClassicGEC/Examples/GECModels/basic.txt b/ClassicGEC/Examples/GECModels/basic.txt new file mode 100644 index 0000000..79d2918 --- /dev/null +++ b/ClassicGEC/Examples/GECModels/basic.txt @@ -0,0 +1,4 @@ +//solution 1 Y = araC +directive simulation {final = 100000.0; points = 1000} + +prom; rbs; pcr; ter \ No newline at end of file diff --git a/ClassicGEC/Examples/GECModels/predator_prey.txt b/ClassicGEC/Examples/GECModels/predator_prey.txt new file mode 100644 index 0000000..3d00f28 --- /dev/null +++ b/ClassicGEC/Examples/GECModels/predator_prey.txt @@ -0,0 +1,24 @@ +directive simulation {final = 100000.0; points = 1000; plots = [predator_ccdB; prey_ccdB]} + +predator +[ r0051:prom; rbs; pcr +; rbs; pcr; ter +; prom; rbs; pcr; ter +; r0051:prom; rbs; pcr; ter +| Q1a ~-> H1 | Q2b + H2 <-> Q2b::H2 +| A ~ ccdB -> +| H1 *->{10.0} | H2 *->{10.0} +| ccdB ~ Q1a *->{10.0} +] || + +prey +[ prom; rbs; pcr; ter +; r0051:prom; rbs; pcr +; rbs; pcr; ter +| Q2a ~-> H2 | H1 + Q1b <-> H1::Q1b +| H2 *->{10.0} | H1 *->{10.0} +| ccdB ~ Q2a *->{10.0} +] || + +predator[H1] -> H1 | H1 -> prey[H1] +| prey[H2] -> H2 | H2 -> predator[H2] \ No newline at end of file diff --git a/ClassicGEC/Examples/GECModels/receiver_device.txt b/ClassicGEC/Examples/GECModels/receiver_device.txt new file mode 100644 index 0000000..32ff90f --- /dev/null +++ b/ClassicGEC/Examples/GECModels/receiver_device.txt @@ -0,0 +1,12 @@ +directive simulation {final = 100000.0; points = 1000; plots = [Signal]} + +cell +[ prom; rbs; pcr; ter +| prom; + rbs; pcr; ter +| Receiver + Signal -> Receiver::Signal +| Receiver::Signal -> Receiver + Signal +] +| Signal -> cell[Signal] +| cell[Signal] -> Signal +| initPop Signal 100.0 \ No newline at end of file diff --git a/ClassicGEC/Examples/GECModels/repressilator_modules.txt b/ClassicGEC/Examples/GECModels/repressilator_modules.txt new file mode 100644 index 0000000..70748ce --- /dev/null +++ b/ClassicGEC/Examples/GECModels/repressilator_modules.txt @@ -0,0 +1,6 @@ +directive simulation {final = 100000.0; points = 1000; plots = [A; B; C]} + +template gate(i,o) { + prom; rbs; pcr; ter +}; +gate(A,B) | gate(B,C) | gate(C,A) \ No newline at end of file diff --git a/ClassicGEC/Examples/GECModels/repressilator_modules_similar.txt b/ClassicGEC/Examples/GECModels/repressilator_modules_similar.txt new file mode 100644 index 0000000..8d5e8ea --- /dev/null +++ b/ClassicGEC/Examples/GECModels/repressilator_modules_similar.txt @@ -0,0 +1,8 @@ +directive simulation {final = 100000.0; points = 1000; plots = [A; B; C]} + +template gate(i,o) { + new RB. new RUB. new RTB. new RT. new R. new RD. + prom;rbs; pcr; ter + | 0.4 < RUB | RUB < 0.6 +}; +gate(A,B) | gate(B,C) | gate(C,A) \ No newline at end of file diff --git a/ClassicGEC/Examples/GECModels/repressilator_similar.txt b/ClassicGEC/Examples/GECModels/repressilator_similar.txt new file mode 100644 index 0000000..248e402 --- /dev/null +++ b/ClassicGEC/Examples/GECModels/repressilator_similar.txt @@ -0,0 +1,12 @@ +directive simulation {final = 100000.0; points = 1000; plots = [A; B; C]} + +prom; +rbs; pcr; ter; +prom; +rbs; pcr; ter; +prom; +rbs; pcr; ter + +| 0.4 < RubB | RubB < 0.6 +| 0.4 < RubC | RubC < 0.6 +| 0.4 < RubA | RubA < 0.6 \ No newline at end of file diff --git a/ClassicGEC/Examples/Results/band_detector.csv b/ClassicGEC/Examples/Results/band_detector.csv new file mode 100644 index 0000000..69495cd --- /dev/null +++ b/ClassicGEC/Examples/Results/band_detector.csv @@ -0,0 +1,503 @@ +Time,receiver_gfp +0,0 +100.02060968151537,4 +200.0235028085403,7 +300.02466686234146,12 +400.0256456818009,12 +500.02777302389205,4 +600.0261546908744,1 +700.0275919645397,1 +800.0288187103721,0 +900.0287679635784,0 +1000.0301872282646,0 +1100.029975901197,0 +1200.0306725989528,0 +1300.0334869317367,0 +1400.0349732816371,0 +1500.0348523395521,0 +1600.035128016974,0 +1700.0359717560705,0 +1800.035914019848,0 +1900.0369899158811,0 +2000.0377129361539,0 +2100.0379808007856,0 +2200.0373802630875,0 +2300.0385948816224,0 +2400.0379134638056,0 +2500.04062287006,0 +2600.0407501935074,0 +2700.0423135588526,0 +2800.042874756687,0 +2900.0430445179063,0 +3000.044220027159,0 +3100.0435589953636,0 +3200.0446511695536,0 +3300.0450106721732,0 +3400.045038233435,0 +3500.04596346297,0 +3600.04583008927,0 +3700.0463528858177,0 +3800.0454974325753,0 +3900.046865516563,0 +4000.0458236858676,0 +4100.0467630306075,0 +4200.048351259069,0 +4300.049158526296,0 +4400.049279356403,0 +4500.048923309308,0 +4600.049648162631,0 +4700.049311427717,0 +4800.050806450938,0 +4900.050782550269,0 +5000.0512833439225,0 +5100.051302071789,0 +5200.051767171538,0 +5300.052419325133,0 +5400.053173354988,0 +5500.053577509014,0 +5600.054818842554,0 +5700.055187908452,0 +5800.055437302429,0 +5900.056542585254,0 +6000.056450419211,0 +6100.057660957094,0 +6200.058040146941,0 +6300.058593683041,0 +6400.058402365434,0 +6500.055573035928,0 +6600.059742983686,0 +6700.059517202601,5 +6800.060468516272,8 +6900.0605109925245,8 +7000.060563300007,8 +7100.063394899366,10 +7200.063617494085,16 +7300.063647059625,24 +7400.064371847522,25 +7500.065036303397,24 +7600.0657196257525,18 +7700.066487514201,16 +7800.066431045649,11 +7900.0663588028865,13 +8000.067327820066,10 +8100.06744230592,4 +8200.067054710005,2 +8300.067869464241,1 +8400.067839982385,0 +8500.06712494147,0 +8600.066736535364,0 +8700.06836084838,0 +8800.068600018063,0 +8900.069005377001,0 +9000.069465800534,0 +9100.070861649467,0 +9200.071348636575,0 +9300.071561259505,3 +9400.071725758415,8 +9500.071849164655,10 +9600.071414439351,7 +9700.072286667511,5 +9800.073063089085,15 +9900.074062249256,14 +10000.075513649119,14 +10100.075735503966,10 +10200.076233669439,12 +10300.076701025315,5 +10400.077489899662,5 +10500.077275851781,3 +10600.077202873383,0 +10700.077823037429,0 +10800.078695896393,0 +10900.078672646787,0 +11000.079924912845,0 +11100.080057222782,0 +11200.079803173145,0 +11300.080229188692,0 +11400.079536265903,0 +11500.08114346221,0 +11600.08136365496,0 +11700.082156279843,0 +11800.082186803813,0 +11900.082526361082,4 +12000.081971723359,11 +12100.082080187658,8 +12200.08302291862,11 +12300.083350474924,10 +12400.082489975566,10 +12500.083156035642,13 +12600.08368289988,14 +12700.08440781648,17 +12800.08399018028,22 +12900.084754105179,15 +13000.084763090943,16 +13100.083634386085,13 +13200.085376220497,6 +13300.085125627566,9 +13400.086690289656,8 +13500.085426508962,5 +13600.086970419019,8 +13700.087768563566,11 +13800.088100753088,9 +13900.087655251691,7 +14000.088850673468,3 +14100.08982306462,0 +14200.089274284237,3 +14300.091416315094,4 +14400.091106180524,5 +14500.091380850548,7 +14600.091628773767,14 +14700.091852738458,18 +14800.093838978091,13 +14900.094299279526,10 +15000.092786198291,4 +15100.09141844133,2 +15200.094748136,0 +15300.096117742536,0 +15400.09618368205,0 +15500.095179366252,0 +15600.096816577488,0 +15700.09765987674,0 +15800.09843337093,0 +15900.099427753797,4 +16000.099388147057,4 +16100.100583994597,8 +16200.101101286662,13 +16300.101381053792,14 +16400.101985875615,8 +16500.10323610919,7 +16600.10463931568,11 +16700.105578578106,11 +16800.106782694005,10 +16900.106834647337,7 +17000.107220403417,4 +17100.10744885714,4 +17200.107501592578,8 +17300.10852297478,10 +17400.10873013706,12 +17500.109164617246,5 +17600.109949817885,1 +17700.109957189587,1 +17800.11042272482,0 +17900.110297239786,0 +18000.110070905754,0 +18100.11154865086,0 +18200.112248934096,0 +18300.11182664548,0 +18400.110809467154,0 +18500.11071737819,0 +18600.112674754975,0 +18700.113896293176,0 +18800.113396991488,0 +18900.113527093312,0 +19000.114453589315,0 +19100.11443915314,0 +19200.1147156649,0 +19300.115292034927,0 +19400.11551927219,0 +19500.115467737243,0 +19600.11606084394,0 +19700.114629023978,0 +19800.115686100224,0 +19900.116956529237,0 +20000.118108773677,0 +20100.118910762067,0 +20200.118999783303,0 +20300.11842536999,0 +20400.1201697274,0 +20500.122336924305,0 +20600.12221786719,0 +20700.12318102855,0 +20800.123271687644,0 +20900.123637655277,0 +21000.12389893372,0 +21100.124482761945,0 +21200.124253787213,0 +21300.12564067713,0 +21400.12599970876,0 +21500.125765494417,0 +21600.12760232921,0 +21700.127676239023,0 +21800.127909494153,0 +21900.128123523904,0 +22000.127895032067,8 +22100.127516786677,9 +22200.127350954954,9 +22300.127864433005,7 +22400.128523426305,1 +22500.129144747352,0 +22600.129514657307,6 +22700.13000286722,10 +22800.130365972986,9 +22900.13093555283,12 +23000.131328545463,6 +23100.130104200038,3 +23200.131088997623,0 +23300.132074495523,0 +23400.13212893375,0 +23500.133056838353,0 +23600.13391673292,0 +23700.13397544206,0 +23800.13581973709,0 +23900.135587492587,0 +24000.136544442823,0 +24100.13704794379,0 +24200.137197361237,0 +24300.138355941126,0 +24400.138951831694,0 +24500.139353604176,0 +24600.140655649167,0 +24700.140202927876,0 +24800.14031231982,0 +24900.1413236585,0 +25000.139838761286,0 +25100.14133445543,0 +25200.142482360527,0 +25300.14180236833,0 +25400.143647962876,0 +25500.143656605444,0 +25600.143321485953,0 +25700.144304168567,0 +25800.144655340384,0 +25900.14354782908,0 +26000.144401032845,0 +26100.14465281543,0 +26200.14499913843,0 +26300.144409731452,0 +26400.14566380023,0 +26500.14662198586,0 +26600.14638904049,0 +26700.146423430615,0 +26800.147465316273,0 +26900.147429555167,0 +27000.148504289693,0 +27100.148117707256,0 +27200.148420089972,0 +27300.14876846697,0 +27400.14941250654,0 +27500.148671899933,0 +27600.14889012488,0 +27700.149883021742,0 +27800.150326008832,0 +27900.15086932182,0 +28000.151353044566,0 +28100.151353505767,0 +28200.151957925333,0 +28300.151864193027,0 +28400.15238812959,0 +28500.152961410153,0 +28600.152921798563,0 +28700.153974863628,0 +28800.15387832379,0 +28900.154784284652,0 +29000.15460287158,0 +29100.154908437646,0 +29200.15466710021,0 +29300.15559512141,0 +29400.156373736638,0 +29500.156700349584,0 +29600.15608410952,0 +29700.156654459348,0 +29800.156423582263,0 +29900.15739597229,0 +30000.15822039833,0 +30100.15859227728,0 +30200.15895942691,0 +30300.160449344377,0 +30400.16087509206,0 +30500.159991016637,0 +30600.161396540032,0 +30700.161146051312,0 +30800.161533334212,0 +30900.16126396383,0 +31000.161766878726,0 +31100.16292626371,0 +31200.163416747047,0 +31300.16325298774,0 +31400.163826442946,0 +31500.164859891676,0 +31600.16577459933,0 +31700.166004085113,0 +31800.166980204813,0 +31900.167169991877,0 +32000.167501468077,0 +32100.167444559742,0 +32200.167926538867,0 +32300.167504697554,0 +32400.167936401194,0 +32500.16805334378,0 +32600.16823937454,0 +32700.170033757302,0 +32800.17025728586,0 +32900.1712834077,0 +33000.17128992058,0 +33100.17140947783,0 +33200.172296248835,0 +33300.17286681384,0 +33400.17370772586,0 +33500.17390029894,0 +33600.17458532106,0 +33700.17467743658,0 +33800.17583548831,0 +33900.17684760812,0 +34000.17669193203,0 +34100.17673652218,0 +34200.178067117864,0 +34300.17876915723,0 +34400.178759293565,0 +34500.180672242364,0 +34600.17984167807,0 +34700.18142454426,0 +34800.181335288034,0 +34900.18192831487,0 +35000.18221347722,0 +35100.18296671624,0 +35200.18292299049,0 +35300.18339454181,0 +35400.18362516064,0 +35500.18408598374,0 +35600.18429640888,0 +35700.18456098601,0 +35800.18446387974,0 +35900.18445377258,0 +36000.183044828635,0 +36100.185202128036,0 +36200.18607578648,0 +36300.186515052636,0 +36400.18654782682,0 +36500.186782496516,0 +36600.187179341396,0 +36700.18713741679,0 +36800.186797308765,0 +36900.18706415204,0 +37000.18822918548,0 +37100.18982771472,0 +37200.190427815294,0 +37300.19120791102,0 +37400.19128620663,0 +37500.19160997273,0 +37600.19166494679,0 +37700.19184763821,0 +37800.19227507993,0 +37900.19251470071,0 +38000.19277332929,0 +38100.19315950386,0 +38200.193738919166,0 +38300.19256678565,0 +38400.19278723446,0 +38500.193929491936,0 +38600.19524277187,0 +38700.195623301646,0 +38800.19503830502,0 +38900.19646151396,0 +39000.19853914121,0 +39100.198521400554,0 +39200.20019064166,0 +39300.200363714146,0 +39400.200465036156,0 +39500.20026824744,0 +39600.20052848284,0 +39700.20077784986,0 +39800.201321858716,0 +39900.201236439774,0 +40000.20171924776,0 +40100.20168646345,0 +40200.201352184544,0 +40300.20140351234,0 +40400.20233712264,0 +40500.202463014444,0 +40600.20155267879,0 +40700.20363528551,0 +40800.202642164775,0 +40900.20362693603,0 +41000.20446688382,0 +41100.20439545574,0 +41200.20516026138,0 +41300.205182141246,0 +41400.205460916135,0 +41500.20591649927,0 +41600.20693428995,0 +41700.20742988544,0 +41800.207651417346,0 +41900.20809199624,0 +42000.20823059664,0 +42100.20808274787,0 +42200.20772628857,0 +42300.20877925875,0 +42400.21053029872,0 +42500.21139155731,0 +42600.21109076057,0 +42700.21305517059,0 +42800.21244528182,0 +42900.21281698364,0 +43000.21354227573,0 +43100.21397940288,0 +43200.21415328987,0 +43300.21438900006,0 +43400.215377282024,0 +43500.215172125485,0 +43600.21457257686,0 +43700.21547065817,0 +43800.21693832743,0 +43900.21701805509,0 +44000.21770280433,0 +44100.21797579017,0 +44200.21861982538,0 +44300.21950148216,0 +44400.21977530882,0 +44500.218778021845,0 +44600.22074670178,0 +44700.220945866226,0 +44800.21960181349,0 +44900.22064639493,0 +45000.2211811319,0 +45100.2218419591,0 +45200.22012978984,0 +45300.22137087031,0 +45400.22184271304,0 +45500.223508270705,0 +45600.22376164941,0 +45700.224064115035,0 +45800.22545440091,0 +45900.22545706543,0 +46000.2257410921,0 +46100.22526787081,0 +46200.226908849545,0 +46300.22792707221,0 +46400.22668662529,0 +46500.22833619727,0 +46600.228197668446,0 +46700.22723930528,0 +46800.22915863442,0 +46900.22906689879,0 +47000.2305369993,0 +47100.230625724835,0 +47200.23102031955,0 +47300.23055666963,0 +47400.231715151494,0 +47500.232395560524,0 +47600.232143759844,0 +47700.23342351303,0 +47800.233246228636,0 +47900.23236743956,0 +48000.23523702314,0 +48100.235788672886,0 +48200.236324372054,0 +48300.23611436989,0 +48400.23834194808,0 +48500.23726326729,0 +48600.240048484506,0 +48700.240526734226,0 +48800.24082024714,0 +48900.24119232924,0 +49000.24132255938,0 +49100.240883882834,0 +49200.24155521004,0 +49300.24172978272,0 +49400.241308023724,0 +49500.24222983674,0 +49600.2427410415,0 +49700.24412163536,0 +49800.243801991965,0 +49900.244258164676,0 +49999.99934171795,0 +49999.99999999999,0 \ No newline at end of file diff --git a/ClassicGEC/Examples/Results/basic.csv b/ClassicGEC/Examples/Results/basic.csv new file mode 100644 index 0000000..a2d5083 --- /dev/null +++ b/ClassicGEC/Examples/Results/basic.csv @@ -0,0 +1,993 @@ +Time,g703,mrna704,Y,g703_Y +0,1,0,0,0 +114.4087098123049,1,1,8,0 +213.64960850945798,0,1,11,1 +316.09964977222927,0,1,8,1 +416.00114258762466,0,1,9,1 +516.3892683572595,0,1,9,1 +616.6841953141621,0,2,8,1 +716.0475686066388,0,3,30,1 +817.4867862580577,0,3,25,1 +917.4378688558688,0,2,21,1 +1019.1211496069247,0,2,18,1 +1116.5392238437053,0,2,16,1 +1223.3625115577531,0,2,17,1 +1324.3122194156797,0,2,26,1 +1424.324303861969,0,2,21,1 +1525.9982697972569,0,2,14,1 +1632.067437228867,0,2,17,1 +1732.2008540996974,0,2,23,1 +1834.2098143705205,0,2,23,1 +1937.6901312733537,0,2,16,1 +2038.5619052318245,0,2,14,1 +2142.094585506736,0,1,21,1 +2241.2782000265347,0,1,12,1 +2345.6614547017175,0,1,12,1 +2448.1597501051647,0,1,15,1 +2553.047420303934,0,1,10,1 +2655.195124021906,0,1,11,1 +2756.6931230073587,0,1,12,1 +2856.362214178119,0,1,14,1 +2961.638842782575,0,1,12,1 +3062.5719226892043,1,2,8,0 +3160.7917052266394,0,3,19,1 +3262.201421126965,0,4,32,1 +3364.060320195971,0,5,36,1 +3464.5641868439816,0,5,50,1 +3565.21710035201,0,5,45,1 +3664.6453558572093,0,5,42,1 +3769.0328133910452,0,4,42,1 +3870.605307323887,0,2,25,1 +3971.8812920676232,0,2,17,1 +4072.9686218714464,0,2,14,1 +4174.965260541385,0,2,16,1 +4278.692267342976,0,1,17,1 +4377.5677704957025,0,1,13,1 +4478.524770788447,0,2,10,1 +4578.387390270901,0,3,20,1 +4683.060126364357,0,2,25,1 +4785.6403161302005,0,2,16,1 +4887.181164902342,0,2,21,1 +4986.196842826158,0,2,17,1 +5087.623267920732,0,3,27,1 +5188.831728680149,0,3,31,1 +5287.645786019582,0,2,28,1 +5390.081242461225,0,2,24,1 +5491.643945597525,0,2,28,1 +5591.805978563282,1,2,19,0 +5691.740235794135,0,3,20,1 +5791.243697920884,0,3,34,1 +5893.013082627013,0,3,38,1 +5992.087439707258,0,2,32,1 +6093.867929658104,0,1,20,1 +6194.314814614409,0,1,12,1 +6294.9767198910595,0,1,11,1 +6395.464303430156,0,1,7,1 +6495.57748761099,0,1,9,1 +6595.471785072732,0,1,8,1 +6696.942212046354,0,1,11,1 +6799.295755682694,0,1,10,1 +6898.307028682683,0,1,11,1 +7000.281842335844,0,1,9,1 +7100.49032116891,0,1,13,1 +7200.857795959457,1,1,11,0 +7300.693683860958,0,2,10,1 +7401.678040290344,0,2,13,1 +7501.971733861656,0,2,18,1 +7603.881597242681,0,2,22,1 +7703.337557482545,0,2,20,1 +7804.834187191614,0,2,29,1 +7905.08038580944,0,2,20,1 +8009.231364797431,0,2,18,1 +8112.10453711929,0,3,22,1 +8210.317063565757,0,2,18,1 +8314.14558598762,0,2,21,1 +8413.998412872666,0,2,21,1 +8516.406586551024,0,2,16,1 +8617.1623276722,0,2,21,1 +8714.10423567966,0,2,22,1 +8817.781218289101,0,3,22,1 +8919.541230428675,0,3,22,1 +9021.591591057431,0,3,32,1 +9123.384846923793,0,2,34,1 +9223.064013743562,0,3,19,1 +9324.97108478648,0,4,26,1 +9424.824757615012,0,5,43,1 +9526.350207261043,0,4,53,1 +9626.534159519406,0,4,45,1 +9726.657964802493,0,4,43,1 +9827.896431157866,0,3,37,1 +9928.093062531763,0,3,30,1 +10031.062489868687,0,2,28,1 +10130.844308283342,0,2,29,1 +10229.899544647687,0,3,29,1 +10331.791031182065,0,3,22,1 +10433.383778967813,0,3,29,1 +10534.806518039615,0,3,34,1 +10636.32243880973,0,3,34,1 +10737.021212656035,0,4,42,1 +10838.157388534055,0,5,54,1 +10938.381303550539,0,5,44,1 +11038.598176700578,0,3,40,1 +11137.855944922145,0,4,47,1 +11239.202183448991,0,3,32,1 +11337.715826162916,0,3,36,1 +11441.650159276522,0,2,29,1 +11542.693609412045,0,2,28,1 +11642.915654114355,0,2,20,1 +11744.666734512892,0,2,22,1 +11849.208424396238,0,2,20,1 +11948.457069081622,0,3,20,1 +12049.863059251207,0,2,26,1 +12151.996416838625,0,2,23,1 +12252.924726381092,0,1,15,1 +12353.281574950495,0,1,15,1 +12453.866703230695,0,2,11,1 +12550.066508041367,0,2,13,1 +12652.006258743248,0,2,23,1 +12756.751236284905,0,2,26,1 +12859.02265493859,0,1,19,1 +12955.088844721817,0,1,14,1 +13059.99088027283,0,0,4,1 +13159.645782257554,0,1,2,1 +13260.847968653088,0,0,6,1 +13366.31302521929,0,1,3,1 +13466.626947933984,0,1,9,1 +13566.87992398686,0,2,20,1 +13670.20342879911,1,2,27,0 +13769.974465925812,0,2,23,1 +13868.666481498063,0,1,24,1 +13972.341357669891,1,2,17,0 +14072.410755329603,0,2,21,1 +14172.86200923575,0,4,28,1 +14273.196965701678,0,4,29,1 +14373.013953568185,0,4,54,1 +14473.385809235298,0,4,35,1 +14575.347598640237,0,3,28,1 +14674.135412060554,0,3,30,1 +14776.686151072046,0,3,28,1 +14875.949715323499,0,4,38,1 +14976.437164794166,0,5,36,1 +15078.190280207655,0,5,51,1 +15177.957861753692,0,5,47,1 +15279.076246098692,0,3,43,1 +15378.897507468695,0,2,19,1 +15478.990748551218,0,3,17,1 +15582.26987063678,0,3,30,1 +15681.887277893968,0,3,37,1 +15782.944131438991,0,3,31,1 +15882.478097622006,0,3,23,1 +15984.88031240527,0,4,30,1 +16084.915660867151,0,4,36,1 +16186.282301309458,0,3,29,1 +16286.30233305065,0,3,30,1 +16386.91131082947,0,3,30,1 +16488.50579649569,0,3,28,1 +16588.610653350628,0,3,39,1 +16691.229829916127,0,2,28,1 +16791.48080382276,0,2,24,1 +16890.3449551714,0,2,24,1 +16992.502559241246,0,2,17,1 +17092.823281302102,0,2,20,1 +17193.30692998023,0,2,24,1 +17295.62841012333,0,2,27,1 +17396.49635252191,0,2,22,1 +17494.393975966694,0,2,22,1 +17594.77730949332,0,2,22,1 +17697.598144013402,0,2,23,1 +17799.29247138437,0,2,20,1 +17900.861497765898,0,2,22,1 +18001.74378268655,0,2,20,1 +18100.690020097663,0,2,11,1 +18200.62258897355,0,3,21,1 +18303.79641244812,0,2,18,1 +18404.730437785627,0,3,14,1 +18505.272321958782,0,3,27,1 +18606.321236331885,0,2,17,1 +18706.365140847407,0,2,22,1 +18808.027507328465,0,2,19,1 +18911.90226577606,0,3,23,1 +19011.439256488015,0,3,35,1 +19112.484796557368,0,4,26,1 +19213.331500882523,0,4,32,1 +19313.479598513342,0,4,31,1 +19414.00657743175,0,4,35,1 +19513.96332667252,0,4,31,1 +19615.357614572826,1,5,43,0 +19714.797627464894,0,6,53,1 +19815.571994917802,0,5,56,1 +19916.02348513189,0,4,54,1 +20015.69736137059,0,4,58,1 +20116.918449324814,0,4,52,1 +20217.529366242157,0,4,46,1 +20316.955437849538,0,3,40,1 +20419.618659820444,0,3,39,1 +20523.189657568735,0,3,32,1 +20625.563806180107,0,4,37,1 +20724.392154758556,0,3,38,1 +20826.179662073457,0,3,27,1 +20928.28355698336,0,3,33,1 +21030.146235816515,0,1,21,1 +21122.773478275376,0,1,13,1 +21229.9936919635,0,1,10,1 +21332.681171301527,0,1,9,1 +21435.75624242158,0,1,11,1 +21537.562162496048,0,1,9,1 +21639.40452540911,0,2,14,1 +21740.87759557275,0,2,13,1 +21840.72038100113,0,2,15,1 +21941.501430793774,0,2,10,1 +22042.764129370815,0,1,13,1 +22141.53969777733,0,1,9,1 +22244.655087750274,0,1,11,1 +22347.156803023572,0,2,9,1 +22448.723905539384,0,2,20,1 +22550.845787491588,0,2,17,1 +22652.44266003078,0,2,20,1 +22753.059079678926,0,2,21,1 +22854.500686929918,0,2,28,1 +22954.7009157121,0,2,25,1 +23051.638984762238,0,2,18,1 +23153.493781341487,0,2,26,1 +23256.013072267826,0,1,19,1 +23355.903465590927,0,1,16,1 +23456.394853511934,0,2,16,1 +23557.54251249223,0,3,18,1 +23656.140477354544,0,2,29,1 +23758.202643766857,0,2,30,1 +23858.830364432353,0,3,26,1 +23959.62897511997,0,3,30,1 +24058.603498762368,0,3,34,1 +24159.143139806543,0,3,34,1 +24259.64485506424,0,2,27,1 +24360.735954050728,0,2,21,1 +24462.110791112154,0,2,21,1 +24564.585597110225,0,2,22,1 +24663.04872935018,0,2,21,1 +24765.216200870196,0,2,18,1 +24865.55385684593,0,3,33,1 +24964.756898730764,0,3,30,1 +25064.160311339638,0,4,30,1 +25166.578549659233,0,4,29,1 +25268.48451841611,0,4,26,1 +25367.406852154403,0,4,29,1 +25468.617368831896,0,4,39,1 +25569.3349819657,0,4,34,1 +25670.07596265631,0,5,40,1 +25772.211553894034,0,5,45,1 +25873.15968438637,0,5,52,1 +25971.946360395003,0,5,56,1 +26073.393050631617,0,5,52,1 +26171.56295582964,0,3,53,1 +26276.014415458973,0,3,27,1 +26375.620707767863,0,3,31,1 +26477.983073316565,0,2,19,1 +26577.936938506366,0,3,22,1 +26677.94482505566,0,3,32,1 +26778.95026236865,0,3,28,1 +26878.480478226218,0,4,24,1 +26980.051274646547,0,4,28,1 +27080.235636088968,0,4,43,1 +27177.86746164481,0,3,42,1 +27278.97403354885,0,3,28,1 +27380.333954065984,0,3,25,1 +27481.673814256934,0,2,21,1 +27581.607622554453,0,2,22,1 +27683.07131089929,0,1,20,1 +27786.92212997745,0,1,14,1 +27885.549231956527,0,1,18,1 +27990.903230277454,0,1,17,1 +28091.075412511047,0,2,11,1 +28192.23839123923,0,2,10,1 +28293.236498246526,0,2,17,1 +28393.695226636726,0,2,23,1 +28493.851414428867,0,2,23,1 +28595.63297215962,0,2,29,1 +28696.2144359937,0,1,18,1 +28799.205721618473,0,2,16,1 +28899.303546521012,0,1,9,1 +29000.956626352392,0,2,13,1 +29100.080653497578,0,1,13,1 +29199.94191615085,0,1,15,1 +29301.443505234845,0,2,18,1 +29402.261989326526,0,2,27,1 +29500.61165253132,0,2,28,1 +29602.296294494136,0,2,18,1 +29705.88583075035,0,3,34,1 +29805.7786657574,0,3,35,1 +29905.19302217783,0,3,35,1 +30007.838350181013,0,3,33,1 +30110.219406869335,0,3,32,1 +30209.16537638742,0,3,35,1 +30312.94035058878,0,2,25,1 +30413.73657624922,0,2,32,1 +30519.460078988224,1,2,20,0 +30619.37029017909,0,2,16,1 +30717.904772408503,0,2,24,1 +30822.420332696023,0,2,24,1 +30921.553654198433,0,2,20,1 +31021.961959499826,0,3,28,1 +31119.039421591082,0,3,32,1 +31224.204593203693,0,3,32,1 +31325.651322735648,0,3,37,1 +31424.90724428374,0,3,32,1 +31526.099499915832,0,4,45,1 +31625.69179137401,0,3,37,1 +31727.403992659354,0,3,27,1 +31828.88430166209,0,3,22,1 +31929.74274024965,0,3,26,1 +32030.309433094655,0,2,19,1 +32129.22168581686,0,5,24,1 +32233.584233199384,0,4,34,1 +32333.568782661103,0,4,39,1 +32433.106410946897,0,3,56,1 +32534.58582835067,0,3,46,1 +32635.0834455812,0,3,48,1 +32736.373278293413,0,2,27,1 +32834.260119141596,0,3,18,1 +32936.74265138625,0,3,24,1 +33039.79492645612,0,3,31,1 +33141.76757179891,0,1,20,1 +33243.46407770025,0,1,18,1 +33345.78018847268,0,1,9,1 +33445.05569553249,0,0,5,1 +33547.159557610896,0,0,2,1 +33647.6033904049,0,2,5,1 +33748.34470037493,0,0,13,1 +33850.17446837975,0,0,3,1 +33950.82495745414,1,1,2,0 +34050.80230869988,0,3,13,1 +34150.02361372981,0,4,31,1 +34252.29716668968,0,4,34,1 +34353.083960605865,0,3,42,1 +34453.10422160108,0,2,37,1 +34553.21663903164,0,1,21,1 +34654.36707970263,0,1,10,1 +34755.63674791856,0,1,13,1 +34855.36117058002,0,1,14,1 +34956.23533397815,0,1,12,1 +35052.45338598855,0,1,11,1 +35159.85907273904,0,1,7,1 +35257.25321056872,0,2,13,1 +35359.71952077697,0,1,21,1 +35460.40291860734,0,1,15,1 +35561.21652542153,0,1,12,1 +35659.77215065126,0,1,11,1 +35764.35482521428,0,1,11,1 +35869.15839460161,0,1,12,1 +35962.73543450029,0,1,6,1 +36070.69797608899,0,2,7,1 +36171.010815038186,0,3,17,1 +36274.34830149754,0,3,23,1 +36373.33562000105,0,2,38,1 +36474.71436888212,0,2,39,1 +36578.877291836165,0,2,30,1 +36681.21668818721,0,2,26,1 +36782.56838398949,0,2,26,1 +36881.69029833215,0,2,23,1 +36984.5394099591,0,2,18,1 +37086.149805292414,0,2,14,1 +37188.88814604465,0,2,23,1 +37291.09768276942,0,2,26,1 +37390.280718156326,0,3,32,1 +37491.655769601675,0,3,29,1 +37592.264339633606,0,3,25,1 +37692.687224404006,0,2,24,1 +37792.60440065954,0,1,14,1 +37895.182131974965,0,1,16,1 +37999.21617091763,0,2,17,1 +38099.69771689937,0,2,14,1 +38200.223665646525,0,2,14,1 +38300.25887716894,0,2,24,1 +38401.055553349484,0,2,19,1 +38501.46959074636,0,3,20,1 +38604.43587111251,0,3,17,1 +38704.59628098338,0,2,21,1 +38802.84725014121,0,2,16,1 +38906.46744296689,0,2,22,1 +39007.42247954815,0,2,20,1 +39107.34714835525,0,2,22,1 +39209.82986802184,0,4,33,1 +39312.584066340605,0,4,37,1 +39412.81234874991,0,4,40,1 +39512.92622120261,0,4,40,1 +39612.11946483742,0,4,43,1 +39713.45897299442,0,4,39,1 +39812.38364298098,0,4,54,1 +39914.18389430736,0,4,47,1 +40016.63490341436,0,4,36,1 +40117.80215146996,0,2,42,1 +40220.29826023201,0,2,23,1 +40318.25522254477,0,2,18,1 +40420.55204236949,0,2,24,1 +40521.768419503525,0,2,25,1 +40623.538038803476,0,2,25,1 +40724.634776967134,0,2,26,1 +40825.76890147064,0,2,27,1 +40926.35246971474,0,2,21,1 +41026.898461208584,0,1,16,1 +41128.15408107409,0,0,7,1 +41227.661626648114,1,0,4,0 +41327.38772998392,0,1,4,1 +41429.97777737312,0,2,11,1 +41529.115477806285,0,2,20,1 +41630.468927561174,0,2,22,1 +41731.94128928655,0,2,31,1 +41832.11931439701,0,2,27,1 +41933.326696932265,0,2,24,1 +42033.92538708515,0,2,20,1 +42134.22335961278,0,2,24,1 +42240.039355330795,0,1,16,1 +42341.733900282685,0,3,15,1 +42442.67618488869,0,4,29,1 +42546.18049067264,0,4,34,1 +42645.23053914202,0,2,35,1 +42748.121699507916,0,3,20,1 +42849.47677447336,0,3,28,1 +42952.61875190865,0,3,19,1 +43052.04911511453,0,2,20,1 +43153.45796060171,0,2,13,1 +43254.30162620558,0,2,25,1 +43355.2429103722,0,2,26,1 +43459.384796026774,0,2,18,1 +43560.88131846389,0,0,18,1 +43662.69507608887,0,0,6,1 +43763.00427705394,0,1,9,1 +43863.1910270788,0,2,14,1 +43966.77904932828,0,2,21,1 +44066.89653415791,0,3,25,1 +44167.270114647945,0,3,29,1 +44268.30271232095,0,3,35,1 +44369.79770848475,0,3,25,1 +44470.24649456552,0,3,35,1 +44571.44700516236,0,3,42,1 +44672.47663173291,0,3,33,1 +44771.83208734792,0,3,38,1 +44875.37043340901,0,3,35,1 +44974.95838741175,0,3,41,1 +45076.56631373343,1,2,23,0 +45175.68876120223,0,2,26,1 +45276.17620927811,0,1,19,1 +45376.84792947686,0,1,14,1 +45481.44118190568,0,1,15,1 +45582.10309656802,0,1,11,1 +45682.41907412475,0,1,13,1 +45783.83684458859,0,1,17,1 +45889.22490685058,0,1,8,1 +45989.87376042706,0,1,8,1 +46091.219454651364,0,1,11,1 +46190.21883792085,0,1,16,1 +46294.880068358085,0,1,11,1 +46393.21674760878,0,1,13,1 +46494.28358746293,0,1,19,1 +46593.83772924403,0,1,13,1 +46699.741996278266,1,1,12,0 +46799.42741525239,1,1,6,0 +46898.7063526334,0,0,3,1 +46989.907815927734,0,1,2,1 +47102.379636994,0,1,7,1 +47202.312381603064,0,1,7,1 +47303.018819955025,0,1,12,1 +47408.500838259606,0,1,7,1 +47505.73013130908,0,1,11,1 +47610.3098200105,0,2,9,1 +47709.933385008175,0,3,16,1 +47810.5976663313,0,3,25,1 +47911.93921567547,0,3,34,1 +48013.76507154735,0,2,34,1 +48115.28730239457,0,2,22,1 +48216.475770947516,0,2,24,1 +48318.46694825942,0,2,15,1 +48420.827423189134,0,3,22,1 +48522.18898459582,0,2,25,1 +48621.81976986757,0,1,18,1 +48722.381732408234,0,1,18,1 +48820.267588785086,0,1,15,1 +48921.92613764454,0,0,13,1 +49025.05691497607,0,1,3,1 +49124.894992000016,0,2,11,1 +49226.33333819183,0,2,14,1 +49328.66269540166,0,3,22,1 +49428.71805329981,0,3,32,1 +49529.60455684601,0,3,31,1 +49631.703918729174,0,4,35,1 +49732.94509919242,0,4,40,1 +49832.30037829484,0,4,37,1 +49933.31208458139,0,3,42,1 +50034.39185259074,0,3,33,1 +50133.65776856215,0,3,29,1 +50239.3475402964,0,3,36,1 +50339.95729290723,0,3,33,1 +50438.7482770393,0,3,26,1 +50541.0288648042,0,4,36,1 +50641.642211650396,0,5,33,1 +50742.06911269849,0,4,33,1 +50844.44835451704,0,5,43,1 +50947.7469312862,0,5,42,1 +51047.536902908236,0,5,43,1 +51147.52358142646,0,5,51,1 +51248.35728433994,0,5,57,1 +51348.43286302802,0,5,52,1 +51448.471700375114,0,6,51,1 +51544.61195833295,0,6,50,1 +51648.3195697196,0,5,64,1 +51749.86493567582,0,5,57,1 +51849.89618201949,0,4,51,1 +51950.89232833995,0,3,41,1 +52052.934108447495,0,3,27,1 +52154.08451798847,0,4,26,1 +52254.089269940145,0,4,51,1 +52354.53408807712,0,4,46,1 +52454.836877168345,0,5,45,1 +52555.812095283625,0,4,47,1 +52655.63662753809,0,5,46,1 +52756.995827002225,0,5,33,1 +52857.67868613121,0,5,44,1 +52957.92869847436,0,5,55,1 +53058.70828162537,0,5,61,1 +53158.302892167114,0,5,59,1 +53258.51508125209,0,5,52,1 +53358.76446161041,0,4,46,1 +53459.18401978575,0,3,43,1 +53556.40106787355,0,2,38,1 +53658.696176637335,0,2,35,1 +53757.53079117024,0,1,23,1 +53863.395843119506,0,1,15,1 +53964.7270506887,0,3,30,1 +54067.375739769384,0,2,21,1 +54166.76528457898,0,2,13,1 +54268.102363674734,0,3,30,1 +54367.405085042104,0,5,38,1 +54468.23208076738,0,5,46,1 +54570.00197034184,0,5,49,1 +54670.85763706869,0,5,48,1 +54771.14001629334,0,5,42,1 +54871.217140688415,0,5,37,1 +54972.877569507546,0,5,45,1 +55072.48863213676,0,5,49,1 +55173.190461658756,0,3,40,1 +55274.15942724306,0,3,33,1 +55375.09522171054,0,2,32,1 +55478.5437151245,0,2,21,1 +55577.31049270076,0,1,17,1 +55680.76135028929,0,0,14,1 +55783.54947448686,0,0,6,1 +55885.176674197304,1,2,8,0 +55985.06402200392,0,2,19,1 +56085.448124949435,0,3,21,1 +56188.44665895437,0,3,25,1 +56290.70630463016,0,3,31,1 +56391.21559591289,0,1,22,1 +56491.49298679228,0,1,10,1 +56593.38881925396,0,1,7,1 +56694.58871657106,0,1,7,1 +56793.59327672733,0,2,11,1 +56894.58829015393,0,2,16,1 +56996.33662469889,0,3,20,1 +57096.416188941635,0,3,24,1 +57196.40091279458,0,3,27,1 +57297.79414443089,0,3,36,1 +57399.328595420884,0,3,32,1 +57500.77711818089,0,3,29,1 +57600.380971116305,0,3,26,1 +57701.83097340785,0,2,32,1 +57802.932789374565,0,3,22,1 +57904.07116723218,0,3,28,1 +58005.65277016794,0,3,38,1 +58108.049985527505,0,3,27,1 +58206.510642059286,0,3,27,1 +58308.55967446632,0,3,30,1 +58410.586874951994,0,2,24,1 +58511.43956592496,0,2,19,1 +58614.065302240044,0,2,24,1 +58715.10755989854,0,2,24,1 +58813.35915843704,0,1,18,1 +58917.11152627119,0,1,10,1 +59015.40651835326,0,1,16,1 +59116.66686292541,0,1,14,1 +59222.563592064325,1,1,7,0 +59321.78810565559,0,1,9,1 +59422.79293399234,0,2,18,1 +59524.20332785671,0,1,10,1 +59627.5061470984,0,1,12,1 +59729.09927681937,0,1,12,1 +59830.675452490126,0,1,5,1 +59931.55212796422,0,3,11,1 +60031.922319159596,0,3,25,1 +60136.224336526626,0,3,25,1 +60238.097845325174,0,3,23,1 +60337.82659894038,0,4,32,1 +60438.49219910733,0,4,39,1 +60537.32288369946,0,4,28,1 +60638.880886482155,0,4,34,1 +60739.557969066416,0,3,29,1 +60841.29193578789,0,2,20,1 +60941.82521731878,0,4,25,1 +61042.316534517144,0,3,35,1 +61142.64110794357,0,3,33,1 +61243.48337248781,1,3,26,0 +61342.870852015316,0,4,31,1 +61443.1345931683,0,4,36,1 +61543.880706742646,0,3,29,1 +61644.00842415957,0,3,31,1 +61745.47644562045,0,2,29,1 +61848.280676677336,0,2,20,1 +61948.34666883836,0,2,17,1 +62051.64444460953,0,2,25,1 +62152.837837180414,1,2,24,0 +62252.671433822215,0,2,20,1 +62349.99956916173,0,1,19,1 +62452.52374131105,0,2,20,1 +62551.957373299665,0,1,18,1 +62653.10515492791,0,2,15,1 +62753.79264875952,0,2,18,1 +62858.43889956089,0,2,14,1 +62957.87142743459,0,2,18,1 +63058.93636323557,0,1,19,1 +63161.68806344662,0,1,17,1 +63261.379629132236,0,1,7,1 +63360.62598641777,0,2,14,1 +63456.48669243747,0,1,12,1 +63561.72544328656,0,1,9,1 +63666.70734955222,0,1,7,1 +63767.13310407226,0,1,5,1 +63866.883560841554,0,1,8,1 +63969.86463553858,0,1,7,1 +64069.67848326738,0,0,4,1 +64171.58315856745,0,0,1,1 +64274.08641488346,0,1,4,1 +64380.0147867715,0,1,10,1 +64480.62878359176,0,2,23,1 +64581.90619703022,0,2,26,1 +64683.34648556018,0,3,25,1 +64783.23098593643,0,4,37,1 +64884.64291765456,0,4,42,1 +64984.69792359582,0,2,24,1 +65084.75801342598,0,2,18,1 +65187.209883782365,0,2,13,1 +65292.93792868377,0,2,26,1 +65392.514827470164,0,1,16,1 +65492.70051390844,0,3,16,1 +65594.27786126622,0,3,23,1 +65694.17607035486,0,3,22,1 +65793.00561662803,0,3,27,1 +65895.80314124725,0,3,32,1 +65996.44296962104,0,4,34,1 +66096.53824224573,0,4,35,1 +66196.76235246331,0,4,40,1 +66297.82198284159,0,2,35,1 +66399.2143475567,0,2,23,1 +66502.57710949256,0,1,16,1 +66601.96253081955,0,1,10,1 +66702.00522718522,0,1,8,1 +66803.37270100939,0,1,8,1 +66909.52993548255,0,1,5,1 +67010.69965532547,0,2,13,1 +67112.73554255889,0,2,16,1 +67211.31231479063,0,2,22,1 +67312.64073758431,0,2,26,1 +67412.89344549493,0,1,23,1 +67513.36932006365,0,0,13,1 +67612.14406351426,0,1,6,1 +67711.41237381464,0,1,10,1 +67813.72760778738,0,1,10,1 +67916.54340443587,0,1,14,1 +68017.4129008714,0,1,16,1 +68119.10644906978,0,0,11,1 +68218.8268499185,0,2,18,1 +68319.54675082098,0,2,16,1 +68418.00243498845,0,1,16,1 +68522.18156941597,0,1,15,1 +68624.49056087021,0,1,8,1 +68725.14205476383,0,1,9,1 +68824.03634906092,0,2,14,1 +68927.77900571005,0,2,25,1 +69026.89767371812,0,1,18,1 +69128.95780868657,0,2,11,1 +69227.94323495805,0,3,23,1 +69330.49619966859,0,3,26,1 +69430.45586147954,0,3,26,1 +69532.30817482932,0,2,22,1 +69632.3214281425,0,2,17,1 +69734.00330044495,0,2,18,1 +69835.68009956005,0,2,18,1 +69941.94908744133,0,2,26,1 +70043.96287125745,0,2,21,1 +70149.03722938689,0,2,30,1 +70248.57595512042,0,3,24,1 +70351.22414663974,0,3,26,1 +70453.48006558736,0,3,29,1 +70553.94948329836,0,3,31,1 +70654.39651422645,0,2,32,1 +70755.05745241547,0,2,30,1 +70856.90766125689,0,2,23,1 +70957.5263340064,1,2,10,0 +71051.1667004729,0,2,14,1 +71157.02284209763,0,2,21,1 +71258.08184137632,0,3,28,1 +71359.80192296003,0,2,31,1 +71459.84509728414,0,2,17,1 +71561.84728729748,0,2,16,1 +71662.84711689365,0,2,13,1 +71764.79946567796,0,3,24,1 +71865.72724237353,0,3,26,1 +71965.49391607636,0,2,15,1 +72065.50836278962,0,2,19,1 +72165.69932146974,0,2,22,1 +72267.01174833377,0,2,24,1 +72369.22117989942,0,2,24,1 +72469.8521580524,0,2,25,1 +72569.74017921167,0,2,21,1 +72672.56183254387,0,3,29,1 +72772.92540508756,0,3,26,1 +72872.7882892206,0,3,35,1 +72973.81115142441,0,3,26,1 +73075.11725836048,0,4,30,1 +73175.25503899674,0,5,36,1 +73276.65808820701,0,5,45,1 +73376.41338625041,0,5,55,1 +73476.49169561912,0,6,51,1 +73577.9638593775,0,4,51,1 +73678.10489732826,0,4,29,1 +73778.66345176136,0,4,43,1 +73877.4767558122,0,4,43,1 +73978.91697725977,0,4,40,1 +74079.72456395684,0,4,43,1 +74180.42609019564,0,3,26,1 +74279.39073113195,0,2,21,1 +74380.63364967488,0,2,19,1 +74481.16399061598,0,2,26,1 +74580.55243434788,0,2,28,1 +74682.81570193062,0,2,26,1 +74782.93069570808,0,2,24,1 +74883.58059262267,1,2,19,0 +74982.95814161446,0,2,16,1 +75084.48707683133,0,1,19,1 +75185.6326072263,1,1,16,0 +75284.69106663078,0,1,11,1 +75388.99207742533,0,2,18,1 +75490.25490076125,0,2,14,1 +75590.96568049613,0,3,19,1 +75691.10897513,0,3,28,1 +75794.37770330446,0,2,32,1 +75895.61430690753,0,2,22,1 +75996.61510666195,1,1,19,0 +76096.7376523948,0,1,11,1 +76197.23411900208,0,2,18,1 +76302.21012572556,1,2,13,0 +76399.56030842377,0,2,26,1 +76502.19850719735,0,2,19,1 +76605.1612226537,0,3,29,1 +76705.04492343728,0,3,30,1 +76807.92805694732,0,3,28,1 +76909.54046837905,0,2,30,1 +77008.77511619698,0,2,25,1 +77110.42131835056,0,2,28,1 +77212.52666670158,0,2,17,1 +77312.01209977656,0,2,6,1 +77411.53544014838,0,3,20,1 +77515.50492655518,0,3,37,1 +77615.37210434958,0,3,29,1 +77714.69744242904,0,3,30,1 +77814.6567202901,0,2,17,1 +77917.08948996119,0,2,20,1 +78016.86809465765,0,2,22,1 +78118.90362662282,0,3,24,1 +78220.34160517507,0,3,27,1 +78320.66685713657,0,3,39,1 +78423.55140519781,0,3,39,1 +78524.98219308964,0,3,30,1 +78625.18072998962,0,3,37,1 +78728.56530019119,0,2,26,1 +78826.87366146054,0,3,22,1 +78929.84283935852,0,4,49,1 +79031.77871730973,0,3,35,1 +79132.17493699706,0,3,33,1 +79232.69381842285,0,3,29,1 +79337.19650316171,0,3,37,1 +79438.21555282695,0,4,36,1 +79538.69269134973,0,3,30,1 +79641.68329596065,0,3,22,1 +79741.56637800399,0,3,31,1 +79843.78352574557,0,3,32,1 +79946.98225923824,0,3,24,1 +80046.94144073814,0,3,27,1 +80147.41473972349,0,2,31,1 +80247.33475757102,0,2,22,1 +80338.7513162738,0,1,17,1 +80448.59747934162,0,1,10,1 +80549.75732255896,0,1,18,1 +80651.44154059263,0,4,29,1 +80753.45658481114,0,2,30,1 +80856.63871055986,0,1,19,1 +80957.05624575297,0,1,9,1 +81057.93643907396,0,2,16,1 +81161.06915270051,0,2,12,1 +81262.845395429,0,2,18,1 +81363.2660190042,0,2,17,1 +81465.28847343176,0,2,14,1 +81567.81526354965,0,1,12,1 +81668.06095173988,0,3,23,1 +81768.88144295754,0,3,25,1 +81869.27406462896,0,2,19,1 +81969.40307539009,0,3,32,1 +82070.81158281957,0,3,25,1 +82168.80602092567,0,3,30,1 +82273.41322269084,0,3,31,1 +82374.55369995492,0,3,24,1 +82475.4552411858,0,1,17,1 +82576.25067544445,0,1,17,1 +82678.34255453073,0,1,15,1 +82778.70998782647,0,3,25,1 +82880.8373096868,0,2,25,1 +82980.57143341143,0,2,27,1 +83080.80798817115,0,2,21,1 +83182.76029759042,0,1,21,1 +83282.91161856995,1,1,13,0 +83381.06267232717,0,1,9,1 +83486.67495647838,0,1,11,1 +83588.32480293713,1,2,15,0 +83688.25897091726,0,2,22,1 +83786.98301965873,0,2,20,1 +83888.944442714,0,2,22,1 +83992.13646267993,0,2,19,1 +84094.02130245524,0,2,25,1 +84195.3396174335,0,2,22,1 +84297.22170274783,0,2,24,1 +84398.5598053123,0,2,18,1 +84499.71899944305,0,2,21,1 +84597.95036226646,0,2,18,1 +84701.6532421449,0,3,24,1 +84800.80558811105,0,3,28,1 +84902.8506234969,0,4,38,1 +85002.40510132702,0,4,29,1 +85104.10724422996,0,4,46,1 +85202.98361257503,0,4,41,1 +85306.36547027166,0,4,38,1 +85407.87681246015,0,3,42,1 +85507.85330720339,0,4,32,1 +85609.04827462549,0,4,36,1 +85710.09532783907,0,3,35,1 +85810.08111030802,0,3,38,1 +85910.52313950092,0,3,24,1 +86009.13859991297,0,3,27,1 +86110.45270306511,0,3,29,1 +86216.03928132809,0,2,31,1 +86316.58591798073,0,2,25,1 +86416.01631620116,0,1,14,1 +86517.03144403691,0,1,14,1 +86618.25449657431,0,3,12,1 +86719.24983708166,0,4,31,1 +86819.75097938855,0,4,39,1 +86919.9043002787,0,3,40,1 +87019.32571841571,0,3,32,1 +87122.31836430781,0,3,28,1 +87222.00179319583,0,3,28,1 +87322.57328634652,0,3,40,1 +87424.77046958636,0,2,29,1 +87523.73933361168,0,2,24,1 +87626.46363025304,0,2,26,1 +87725.89642356496,0,2,24,1 +87831.70374066161,0,2,19,1 +87932.18624450183,0,2,15,1 +88032.76048807998,0,3,17,1 +88133.05152386487,0,1,21,1 +88230.05741721827,0,1,14,1 +88336.28886705065,0,1,14,1 +88436.21084584537,0,1,9,1 +88540.51804498554,0,2,11,1 +88643.98404864057,1,2,19,0 +88743.87941584778,0,1,16,1 +88841.94672346978,0,2,15,1 +88944.54071247944,0,2,17,1 +89044.07884367181,0,3,18,1 +89146.7493779985,0,4,22,1 +89247.31377979393,1,4,33,0 +89345.91123496977,0,5,39,1 +89447.08100849912,0,4,47,1 +89544.72313372201,0,4,42,1 +89648.03402199701,0,5,40,1 +89748.47013239498,0,7,48,1 +89848.89747366142,0,6,63,1 +89949.64200364401,0,4,62,1 +90047.5067465854,0,4,52,1 +90151.0141333068,0,4,45,1 +90251.37744675558,0,4,55,1 +90352.1048304103,0,4,50,1 +90452.64785746743,0,4,41,1 +90554.1053540677,0,4,40,1 +90656.264094598,0,4,34,1 +90756.7155061269,0,4,43,1 +90856.28947582646,0,4,43,1 +90958.29848704759,0,3,26,1 +91058.76005758133,0,3,37,1 +91159.65714610185,0,3,24,1 +91260.05518352633,1,3,32,0 +91359.3465047491,0,2,20,1 +91460.45833940382,0,2,20,1 +91562.57747206469,0,1,14,1 +91662.26965428873,0,1,16,1 +91762.91635754974,0,1,16,1 +91863.65167851446,1,2,14,0 +91961.32571113597,0,3,10,1 +92066.54622160559,0,3,26,1 +92170.54693981043,0,3,30,1 +92270.74781843662,0,4,37,1 +92371.37182271089,0,4,38,1 +92471.92352764127,0,3,42,1 +92572.1280385216,0,2,33,1 +92675.29764526681,0,2,20,1 +92773.90602868893,0,2,21,1 +92877.07773608441,0,2,26,1 +92977.27677627752,0,4,29,1 +93077.8107311176,0,4,35,1 +93177.24634638305,0,4,42,1 +93277.72738369845,0,4,44,1 +93379.21036650575,0,4,42,1 +93477.856215713,0,4,32,1 +93579.2911708059,0,5,45,1 +93679.88799751092,0,5,45,1 +93780.13610246772,0,5,49,1 +93883.8575225605,0,4,45,1 +93983.96095821871,0,4,46,1 +94084.16684248888,0,4,41,1 +94185.30535243428,0,4,40,1 +94284.897248408,0,4,41,1 +94385.7616359391,0,5,45,1 +94486.80235722811,0,5,50,1 +94586.6440818263,0,5,48,1 +94687.42056606569,0,5,43,1 +94788.32887560727,0,5,51,1 +94890.9055651268,0,5,52,1 +94991.42329531793,0,4,41,1 +95092.70492676558,0,3,35,1 +95192.33403156394,0,3,44,1 +95294.51073965507,0,3,36,1 +95394.45165685452,0,2,30,1 +95497.93547969217,0,2,25,1 +95592.24042413096,0,2,17,1 +95702.71623884374,0,2,16,1 +95802.91429572551,0,2,28,1 +95905.99632955958,0,3,34,1 +96004.89835479828,0,3,25,1 +96105.85330284506,0,3,15,1 +96205.13021435754,0,4,27,1 +96306.31541551802,0,4,35,1 +96406.51013711895,0,4,42,1 +96507.51863140019,0,4,49,1 +96607.77400194766,0,3,28,1 +96713.29441476097,0,3,32,1 +96813.25983902084,0,4,38,1 +96912.49917243805,0,4,36,1 +97012.38611004523,0,4,33,1 +97114.1882163009,0,3,32,1 +97219.00227783303,0,3,29,1 +97321.03779814833,0,3,28,1 +97423.15362823637,0,4,37,1 +97523.48105361755,0,3,36,1 +97624.48555869154,0,3,35,1 +97723.99893661283,0,3,28,1 +97825.18599290427,0,2,20,1 +97926.21754372062,0,2,15,1 +98027.6677427961,0,3,21,1 +98129.98409317633,0,4,32,1 +98231.29404726712,0,5,42,1 +98330.91259964873,0,5,46,1 +98431.18084984922,0,5,56,1 +98532.30681576415,0,5,62,1 +98630.35423313854,0,4,49,1 +98733.34752051676,0,4,39,1 +98834.56702749536,0,4,34,1 +98934.41754820394,0,3,40,1 +99035.30555153184,0,2,28,1 +99136.44924830023,0,2,20,1 +99235.24775590663,0,2,11,1 +99337.5017648225,0,2,4,1 +99437.9907052726,0,0,7,1 +99536.10068893187,0,0,2,1 +99637.68489199784,0,1,5,1 +99745.35496445268,0,1,4,1 +99846.2372379984,0,1,10,1 +99947.94029284408,0,2,16,1 +99998.80668201568,0,2,17,1 +99999.99999998807,0,2,17,1 \ No newline at end of file diff --git a/ClassicGEC/Examples/Results/predator_prey.csv b/ClassicGEC/Examples/Results/predator_prey.csv new file mode 100644 index 0000000..0c2034d --- /dev/null +++ b/ClassicGEC/Examples/Results/predator_prey.csv @@ -0,0 +1,1003 @@ +Time,predator_ccdB,prey_ccdB +0,0,0 +103.7965511487902,0,0 +203.78259856132678,2,11 +303.84917048495885,0,24 +403.9171822929292,4,61 +503.946261318051,3,110 +604.0148525888825,2,137 +704.0502076964971,0,245 +804.0781958062751,0,343 +904.0732818427473,3,391 +1004.0998613581747,3,457 +1104.0858156590093,3,541 +1204.1158142929519,4,660 +1304.113276699057,18,703 +1404.1395512188071,1,756 +1504.144401229737,3,753 +1604.1260760637058,0,735 +1704.1425192772988,1,706 +1804.1572844136183,1,753 +1904.1530818725457,1,846 +2004.16572711341,4,929 +2104.1716818651194,3,993 +2204.1782714581104,1,997 +2304.167463769372,2,990 +2404.1799407696635,2,1031 +2504.2112776936347,0,1049 +2604.2205545129304,3,1118 +2704.219374455929,0,1118 +2804.22372273912,1,1205 +2904.2240492865776,3,1294 +3004.228844316505,2,1327 +3104.287825124614,2,1403 +3204.2942497943513,2,1443 +3304.3091232218712,3,1496 +3404.314346693135,7,1420 +3504.2991506415087,5,1428 +3604.3479029406426,1,1442 +3704.3877436667017,6,1502 +3804.394828860801,3,1447 +3904.3989388318946,1,1411 +4004.432040456169,3,1375 +4104.44617362178,15,1324 +4204.475573483595,5,1354 +4304.468002787686,3,1372 +4404.475255915584,6,1386 +4504.488208940777,1,1372 +4604.496870533714,6,1404 +4704.501547434786,7,1424 +4804.505441446609,8,1434 +4904.515966037497,120,1363 +5004.492959044831,3,1342 +5104.509670864501,7,1308 +5204.5299089822265,5,1275 +5304.519449827843,5,1206 +5404.526090241034,3,1190 +5504.537593773622,4,1105 +5604.543384282422,2,1134 +5704.539348251835,3,1104 +5804.568739640293,6,1078 +5904.570398545199,0,1131 +6004.590570226379,3,1125 +6104.585555559588,3,1093 +6204.59579434982,1,1112 +6304.597752871596,2,1145 +6404.594138660775,1,1118 +6504.575857117324,1,1150 +6604.612254305535,1,1153 +6704.6261741339495,1,1141 +6804.627553444981,0,1158 +6904.614714971181,0,1196 +7004.626317286077,2,1239 +7104.573482273674,0,1211 +7204.641657158888,2,1205 +7304.6490602784515,0,1253 +7404.657508378812,1,1314 +7504.653400809625,1,1370 +7604.691381158499,2,1360 +7704.6848977900545,0,1352 +7804.706444544412,1,1306 +7904.736675351641,3,1335 +8004.730174282227,0,1386 +8104.741001471773,3,1465 +8204.757978084886,1,1583 +8304.768101438342,1,1539 +8404.772607533536,1,1530 +8504.776942491746,3,1517 +8604.772113843435,0,1518 +8704.781681037655,2,1610 +8804.790530568693,0,1738 +8904.797518844754,4,1740 +9004.805737875064,4,1719 +9104.814140639939,4,1788 +9204.823719982996,5,1793 +9304.832959181002,10,1723 +9404.816778925997,2,1610 +9504.838170512898,1,1526 +9604.845997545925,5,1436 +9704.839658187468,3,1445 +9804.848119162143,6,1503 +9904.857504666375,1,1530 +10004.853409465508,5,1513 +10104.91299529188,5,1452 +10204.9152404731,3,1455 +10304.912670675183,1,1464 +10404.922961113369,3,1525 +10504.927886744203,1,1557 +10604.940651736693,0,1570 +10704.965294387384,1,1563 +10804.972084237232,6,1585 +10904.993352925823,4,1537 +11004.994084433583,3,1492 +11105.003537288287,2,1527 +11205.003691259859,0,1567 +11304.989897496294,3,1507 +11405.02396924536,1,1530 +11505.022824688407,3,1552 +11605.038626199852,7,1579 +11705.008542953066,4,1605 +11805.061903440292,7,1582 +11905.075195524283,4,1639 +12005.06753997118,4,1655 +12105.078980887803,5,1578 +12205.083685814796,7,1532 +12305.086376374416,4,1556 +12405.092809062944,0,1566 +12505.098775825158,1,1562 +12605.114119196429,3,1486 +12705.111762365374,2,1462 +12805.122708637562,2,1506 +12905.139710922105,0,1549 +13005.137571120431,0,1495 +13105.13194560228,1,1573 +13205.148115459293,1,1590 +13305.145516634428,3,1556 +13405.164833534342,1,1517 +13505.18039586244,2,1508 +13605.18124851796,3,1488 +13705.194965400215,0,1561 +13805.194778220499,1,1692 +13905.207418297006,0,1611 +14005.217441507722,0,1605 +14105.229885918994,4,1628 +14205.238178065578,2,1621 +14305.275136331262,0,1580 +14405.280091407576,1,1620 +14505.274506105781,0,1645 +14605.27452010511,1,1686 +14705.283578822015,2,1662 +14805.271047352731,0,1657 +14905.296613601067,1,1608 +15005.31830187454,0,1650 +15105.26026744601,2,1734 +15205.323150176258,2,1662 +15305.329017756216,1,1670 +15405.34105274999,3,1741 +15505.3405207028,0,1692 +15605.342356037761,4,1691 +15705.354037365898,3,1637 +15805.358029369589,0,1561 +15905.364952825028,4,1590 +16005.397279028512,5,1578 +16105.398040201419,1,1546 +16205.40609074998,0,1515 +16305.41961911488,1,1546 +16405.42582783978,0,1511 +16505.438548345297,0,1555 +16605.442615506778,1,1565 +16705.456765102146,0,1560 +16805.452035804177,6,1548 +16905.439525757985,2,1591 +17005.43493590895,1,1606 +17105.473550419367,1,1509 +17205.477621026446,4,1487 +17305.47799439588,2,1513 +17405.486627445433,0,1505 +17505.47917843487,2,1590 +17605.49793985513,0,1713 +17705.524843073523,0,1644 +17805.535138480685,3,1535 +17905.527172992195,4,1607 +18005.554305841284,3,1547 +18105.562936601287,2,1587 +18205.550199467754,1,1597 +18305.55512103906,1,1627 +18405.56556669392,4,1608 +18505.581921256944,3,1553 +18605.572687157146,5,1521 +18705.59445807994,2,1558 +18805.59186183326,0,1592 +18905.628629613057,1,1707 +19005.641913079737,0,1759 +19105.63386998936,1,1865 +19205.649199527157,0,1900 +19305.653121775747,2,1821 +19405.657058183453,4,1709 +19505.667514205932,4,1704 +19605.667792956876,1,1721 +19705.672272984786,7,1724 +19805.68333434958,1,1747 +19905.67056399673,0,1749 +20005.695690025328,1,1744 +20105.691774836152,2,1724 +20205.700864366827,1,1721 +20305.70227909143,5,1710 +20405.704827470032,1,1682 +20505.706173771967,0,1697 +20605.701746779912,0,1685 +20705.71549999827,4,1609 +20805.724230897984,2,1604 +20905.719858560456,0,1520 +21005.746833553516,0,1472 +21105.748442020693,2,1440 +21205.756736122592,5,1488 +21305.776026396346,0,1504 +21405.790616349208,1,1459 +21505.784524921186,2,1511 +21605.78648182215,0,1489 +21705.800330433565,1,1567 +21805.80097878841,4,1587 +21905.805592307275,1,1555 +22005.80706080598,1,1564 +22105.80864858517,1,1578 +22205.80495983707,1,1558 +22305.817380693265,3,1582 +22405.821895683617,3,1547 +22505.807105140735,1,1516 +22605.826880272725,2,1472 +22705.8436002109,1,1459 +22805.839769125847,0,1501 +22905.84844595563,1,1560 +23005.864721622733,1,1610 +23105.876581220316,0,1723 +23205.894673776624,0,1809 +23305.897019550255,1,1890 +23405.906510753633,2,1804 +23505.892511628255,0,1832 +23605.920024000126,2,1820 +23705.925856074155,0,1750 +23805.96032964394,0,1657 +23905.961797503598,2,1656 +24005.964856942188,3,1601 +24105.963879310126,1,1572 +24205.960338684436,1,1506 +24305.966150524004,2,1371 +24405.971129944297,2,1371 +24505.996099544904,1,1343 +24605.99666897474,2,1351 +24706.00670469867,1,1364 +24806.009408527654,2,1319 +24906.014648803688,1,1291 +25006.004677410292,0,1287 +25106.01909158485,1,1296 +25206.029877787492,2,1279 +25306.03058579855,0,1375 +25406.041146676776,1,1376 +25506.032607760946,1,1357 +25606.042605232957,1,1411 +25706.044642842837,3,1442 +25806.04682989968,2,1544 +25906.059409034002,1,1515 +26006.02783530858,2,1519 +26106.04796196216,1,1581 +26206.061836960424,8,1575 +26306.0805011029,5,1571 +26406.07180159099,2,1565 +26506.08676177599,2,1588 +26606.089025172147,7,1612 +26706.115395530167,3,1543 +26806.114603389058,1,1512 +26906.12389853627,0,1503 +27006.124042969466,1,1457 +27106.12806379329,3,1469 +27206.130382389412,1,1503 +27306.126777399986,0,1539 +27406.149053119127,1,1529 +27506.139326309407,0,1539 +27606.177327915357,2,1594 +27706.164685815915,0,1666 +27806.183774801964,2,1742 +27906.191220995242,2,1759 +28006.196774682092,2,1810 +28106.201972634724,1,1865 +28206.197832943762,0,1902 +28306.224200445246,1,1850 +28406.221628298827,0,1779 +28506.238665320638,0,1688 +28606.25343376604,2,1670 +28706.25496918425,1,1622 +28806.271266731226,0,1582 +28906.270950609065,0,1610 +29006.283765627042,2,1645 +29106.23978978202,0,1726 +29206.298577405072,1,1799 +29306.30962930244,2,1886 +29406.30295821129,3,1860 +29506.314835408884,0,1843 +29606.314813281642,0,1829 +29706.32062002427,3,1858 +29806.318781195518,1,1855 +29906.338104898787,0,1907 +30006.347627062452,2,1911 +30106.353874668293,2,1965 +30206.372017891626,0,1957 +30306.38813818384,4,1817 +30406.397141338322,1,1867 +30506.396498866692,0,1829 +30606.408237013136,5,1897 +30706.415149539796,0,1822 +30806.415626317088,1,1760 +30906.406191449558,2,1723 +31006.423254828733,1,1651 +31106.43092903763,2,1633 +31206.43805568955,1,1644 +31306.445712354674,0,1660 +31406.461825218437,0,1649 +31506.457799909454,0,1647 +31606.473696712583,1,1710 +31706.47549325981,1,1733 +31806.485294702892,3,1745 +31906.481458528426,1,1784 +32006.481030083763,0,1829 +32106.49802305176,3,1863 +32206.505758491963,3,1913 +32306.51932718096,4,1900 +32406.503817631503,2,1917 +32506.543364175897,0,1903 +32606.546733071962,0,1938 +32706.54258723499,1,1958 +32806.55468349023,2,1944 +32906.55508614439,1,1886 +33006.5615910376,2,1922 +33106.56860021988,0,2028 +33206.58677539164,0,1994 +33306.60289725782,0,1946 +33406.60647592831,1,1932 +33506.61332581221,1,1898 +33606.60599443494,1,1834 +33706.6191051085,1,1775 +33806.620493859446,0,1732 +33906.63639747226,3,1710 +34006.657197347035,0,1790 +34106.64579785968,0,1865 +34206.66299473079,2,1926 +34306.65473129589,1,1963 +34406.67469285926,1,2015 +34506.673864212346,3,1971 +34606.654751141345,1,1965 +34706.684097061596,4,1910 +34806.65979584277,0,1907 +34906.69535108753,4,1864 +35006.69768731207,1,1775 +35106.69229901667,1,1756 +35206.70495734826,3,1661 +35306.69161517108,1,1637 +35406.728610443955,0,1647 +35506.72861553249,0,1625 +35606.7436877166,0,1612 +35706.742641524615,1,1628 +35806.76271152009,1,1626 +35906.775365463545,3,1586 +36006.79245690241,1,1503 +36106.800933681116,1,1504 +36206.789565366955,0,1505 +36306.79145562057,0,1499 +36406.83041311808,3,1490 +36506.819374587874,3,1479 +36606.83612260494,2,1481 +36706.848730316284,3,1409 +36806.85460769937,7,1502 +36906.85161612344,3,1575 +37006.84869733604,2,1552 +37106.86199299501,4,1511 +37206.866103373926,1,1438 +37306.862381162035,1,1457 +37406.84785795284,1,1489 +37506.87396147539,1,1486 +37606.886770039295,0,1507 +37706.89259482332,0,1523 +37806.905108729145,1,1546 +37906.9094484189,1,1580 +38006.92224403987,0,1504 +38106.944803864986,1,1573 +38206.95445094382,2,1510 +38306.9606665757,0,1616 +38406.96782470239,1,1684 +38506.9735119234,0,1733 +38606.9811937146,0,1720 +38706.97819553118,2,1658 +38806.98204246001,0,1616 +38906.986941288626,2,1593 +39006.99343599514,1,1554 +39106.99158552513,0,1550 +39206.99250364729,1,1610 +39306.99285361662,2,1683 +39406.99458319203,0,1739 +39507.00225482659,1,1881 +39606.98113916768,0,1859 +39707.00998626057,1,1848 +39807.00067077072,1,1839 +39907.01172899272,2,1888 +40007.01542639585,0,1914 +40107.03723422589,2,1883 +40207.070887831054,2,1877 +40307.08711986826,0,1805 +40407.097903266804,3,1749 +40507.14737521782,1,1706 +40607.14095631294,0,1647 +40707.16519221084,0,1664 +40807.176747628066,1,1731 +40907.16372732378,3,1792 +41007.182574128645,1,1823 +41107.16721247506,0,1843 +41207.19887036493,0,1812 +41307.202372194704,0,1779 +41407.201764624726,0,1777 +41507.20342561735,1,1828 +41607.210698494695,0,1772 +41707.22370685472,1,1726 +41807.2145240983,1,1665 +41907.2342139571,1,1626 +42007.23738522282,2,1645 +42107.25345961273,0,1645 +42207.248574883495,2,1631 +42307.25193906795,0,1655 +42407.25146189716,0,1678 +42507.26837692982,1,1656 +42607.27879160123,1,1670 +42707.28443537328,1,1701 +42807.28387370954,1,1814 +42907.280325759166,0,1843 +43007.28079995004,0,1777 +43107.31177618055,4,1839 +43207.32134708358,2,1760 +43307.32966244743,4,1718 +43407.34672812019,0,1710 +43507.36391786531,3,1735 +43607.36348547763,1,1683 +43707.37739105813,2,1761 +43807.36473733045,2,1755 +43907.36998259553,2,1803 +44007.37242777137,0,1782 +44107.37537555451,3,1729 +44207.38180711048,1,1711 +44307.414613876645,2,1711 +44407.3780310078,1,1726 +44507.42446800166,1,1747 +44607.44677266178,0,1791 +44707.44847745055,0,1715 +44807.45808525491,2,1725 +44907.47262813077,2,1665 +45007.47165823763,1,1652 +45107.47120239718,0,1593 +45207.46479551296,4,1594 +45307.49308775833,1,1562 +45407.4960646337,0,1533 +45507.50021115845,0,1523 +45607.504158233,2,1445 +45707.50889252791,2,1453 +45807.50849018741,4,1472 +45907.52265321694,1,1514 +46007.51512772177,3,1580 +46107.531588751175,3,1588 +46207.521692430506,0,1632 +46307.54572316004,2,1622 +46407.559911590324,2,1646 +46507.55199771729,3,1641 +46607.56218609447,3,1647 +46707.55864311069,1,1676 +46807.562997952096,3,1683 +46907.59857572217,0,1798 +47007.60041125109,2,1820 +47107.59892288546,0,1823 +47207.617839648046,1,1777 +47307.61576143418,1,1831 +47407.62541719073,1,1811 +47507.639349376244,3,1789 +47607.643074626794,2,1729 +47707.641150521835,0,1686 +47807.63789197494,2,1664 +47907.65058604776,2,1671 +48007.65946925573,1,1676 +48107.66438476105,3,1714 +48207.67082745261,1,1697 +48307.690520890166,0,1703 +48407.69426835238,0,1611 +48507.708509127675,2,1609 +48607.70067438834,1,1610 +48707.73071410603,3,1568 +48807.732255992436,0,1570 +48907.74299857952,2,1584 +49007.74472527182,3,1554 +49107.738710082194,0,1628 +49207.756767318526,1,1597 +49307.754277745036,0,1575 +49407.771050847885,0,1610 +49507.74379992007,0,1517 +49607.76660283984,2,1489 +49707.766744973225,0,1490 +49807.764387459276,0,1517 +49907.805475772555,1,1568 +50007.8151136624,1,1682 +50107.8154544474,4,1660 +50207.81035544109,0,1748 +50307.787515786236,0,1801 +50407.8392931078,1,1838 +50507.8186436882,1,1852 +50607.84316176112,2,1829 +50707.84392594584,1,1891 +50807.83956162129,0,1886 +50907.855194180105,0,1759 +51007.884315486925,1,1708 +51107.88777783335,1,1652 +51207.90072321254,1,1559 +51307.90032430143,4,1495 +51407.914248748806,2,1488 +51507.89795814367,0,1465 +51607.906248067404,1,1470 +51707.919370182746,0,1521 +51807.94308552442,0,1576 +51907.9497862779,1,1661 +52007.947404190345,0,1714 +52107.96134137355,0,1686 +52207.98225501629,2,1760 +52307.98450998519,2,1631 +52408.000672378505,2,1642 +52508.01437359292,1,1737 +52608.02719617789,1,1832 +52708.03243229564,2,1814 +52808.02473221828,1,1804 +52908.040144811646,1,1719 +53008.04527304635,0,1687 +53108.06320335014,0,1629 +53208.07101586371,0,1671 +53308.083431571664,1,1734 +53408.091881061686,1,1687 +53508.0778231446,1,1691 +53608.097853737556,1,1686 +53708.09831858094,2,1634 +53808.10737282023,0,1686 +53908.103444800734,4,1619 +54008.116441248145,1,1574 +54108.145106394055,2,1579 +54208.16428565631,0,1585 +54308.16333232224,2,1563 +54408.19376310902,2,1552 +54508.18784833142,1,1469 +54608.20382989639,5,1528 +54708.23288053812,2,1535 +54808.24119446749,6,1547 +54908.23456698414,5,1664 +55008.24635734077,1,1707 +55108.26331737094,0,1691 +55208.26361081969,3,1726 +55308.253825714484,2,1703 +55408.27966774151,1,1652 +55508.279105304005,0,1551 +55608.29137433451,3,1508 +55708.30591785396,0,1517 +55808.30322734679,2,1521 +55908.30716443623,1,1539 +56008.31050264839,2,1581 +56108.308173819656,1,1581 +56208.31535132753,1,1559 +56308.33677835798,2,1579 +56408.33083763375,1,1616 +56508.33464318758,1,1579 +56608.33067867752,0,1614 +56708.335588800845,3,1631 +56808.33973242948,0,1604 +56908.36287103492,3,1550 +57008.37839339918,1,1490 +57108.39405956847,3,1497 +57208.40970175717,0,1496 +57308.44408620382,1,1538 +57408.44869982409,1,1559 +57508.468613931254,2,1547 +57608.48042771096,1,1474 +57708.48163008833,3,1479 +57808.489727211614,1,1481 +57908.49889815207,2,1576 +58008.49032888547,1,1576 +58108.49532654719,0,1627 +58208.51323556927,2,1612 +58308.52553817192,1,1733 +58408.51649888382,3,1781 +58508.52342971775,1,1844 +58608.53425264689,1,1885 +58708.50584675176,4,1921 +58808.546726024004,0,1936 +58908.542863185474,2,2010 +59008.546256468886,1,2045 +59108.557019901455,1,2021 +59208.559669202135,0,2135 +59308.540640906154,2,2205 +59408.57826280374,1,2261 +59508.57580371313,1,2267 +59608.589143147874,2,2131 +59708.5929783826,1,2084 +59808.59222379398,1,2032 +59908.594743497175,3,2049 +60008.620948212374,1,2039 +60108.61413922665,1,2003 +60208.629218155846,1,1925 +60308.61299049102,8,1871 +60408.648219232055,1,1830 +60508.65113259461,4,1850 +60608.66395902843,5,1830 +60708.66536647664,2,1830 +60808.67301961902,7,1805 +60908.676863738365,6,1778 +61008.66577167025,2,1870 +61108.66450732118,3,1969 +61208.663709111475,1,2153 +61308.68115519463,4,2194 +61408.6779817618,1,2206 +61508.685601429905,2,2196 +61608.688048442345,3,2124 +61708.68752002244,0,2034 +61808.69962473923,0,1859 +61908.75058603232,6,1831 +62008.76119147824,2,1870 +62108.77538740549,5,1837 +62208.79567084969,0,1846 +62308.8025373668,0,1932 +62408.812408058155,0,1966 +62508.82044026578,2,1945 +62608.818013334996,0,1974 +62708.818601281775,0,1941 +62808.80711902886,1,1889 +62908.85388468404,1,1813 +63008.86355674351,3,1712 +63108.869859843864,3,1635 +63208.884060506825,2,1599 +63308.88850424694,1,1579 +63408.89809977874,0,1511 +63508.89856669383,2,1449 +63608.905576847625,1,1392 +63708.94165080175,2,1427 +63808.94483283551,0,1502 +63908.944704202535,0,1509 +64008.95091287852,1,1518 +64108.945242697715,1,1523 +64208.968841293194,0,1582 +64309.00650712996,3,1591 +64409.006712598755,1,1612 +64509.01729317927,0,1627 +64609.0253011311,2,1617 +64709.03159318252,0,1643 +64809.03098187342,1,1640 +64909.04183507353,0,1671 +65009.04507667115,1,1659 +65109.05472392625,1,1659 +65209.07729322523,2,1630 +65309.08640982865,0,1674 +65409.09468297248,0,1713 +65509.08614686306,2,1660 +65609.09595143009,0,1658 +65709.10497116488,0,1750 +65809.11042240629,2,1808 +65909.1388911697,0,1789 +66009.15627119111,0,1802 +66109.19974206867,2,1849 +66209.22799820686,0,1870 +66309.2376450521,1,1816 +66409.23940441571,3,1874 +66509.23311730081,0,1872 +66609.24891120254,0,1907 +66709.26201996389,0,1821 +66809.24598432935,0,1836 +66909.29291890323,1,1825 +67009.30010512602,1,1848 +67109.30377329336,1,1852 +67209.32265475139,2,1909 +67309.34743372776,1,1943 +67409.35573689299,0,1930 +67509.35300366962,1,1955 +67609.34095859544,0,1944 +67709.36993294022,1,1875 +67809.39700892151,2,1977 +67909.40935889725,0,1969 +68009.36627579921,0,2036 +68109.40066343058,1,2057 +68209.41848248012,2,2053 +68309.41658554644,0,2110 +68409.46594905021,1,2136 +68509.47432014835,1,2122 +68609.46644688775,0,2008 +68709.48122084962,2,1980 +68809.4889897627,1,2035 +68909.48584926705,1,1989 +69009.4948820753,0,1985 +69109.49182584943,2,1985 +69209.5270035207,2,1912 +69309.47589645119,0,1859 +69409.54737219613,0,1844 +69509.56327846613,1,1937 +69609.55982228304,4,1971 +69709.57257537328,2,1934 +69809.59897700314,2,1950 +69909.60246675085,3,1996 +70009.61945833189,4,2071 +70109.63975102118,1,2135 +70209.64576964275,0,2271 +70309.66641369325,2,2303 +70409.66411488173,0,2313 +70509.67437325811,4,2298 +70609.6740462891,0,2281 +70709.67153023375,0,2226 +70809.69741456496,0,2222 +70909.71062756907,3,2227 +71009.72150395875,1,2148 +71109.72671279636,0,2049 +71209.72230275808,0,2024 +71309.76866237115,3,1947 +71409.76584820573,1,1927 +71509.7687493704,3,1903 +71609.76563603425,0,1809 +71709.79659111703,0,1804 +71809.79438213559,3,1805 +71909.7978322309,1,1791 +72009.80618801591,0,1786 +72109.82175590783,0,1773 +72209.81617222265,0,1786 +72309.84267333045,2,1849 +72409.8678238316,0,1887 +72509.88163185633,0,1798 +72609.88600967059,0,1807 +72709.90213924582,1,1751 +72809.90751640245,2,1782 +72909.9151922228,0,1793 +73009.92361118349,1,1844 +73109.93163855546,2,1821 +73209.94042659116,1,1799 +73309.93640675608,0,1831 +73409.93527536243,2,1821 +73509.95783141252,0,1860 +73609.96715815269,0,1809 +73709.99234316342,2,1877 +73809.99491960212,3,1849 +73909.99217155727,1,1902 +74009.99725403347,1,1894 +74110.00079608193,2,1830 +74210.00254056505,2,1828 +74310.00130630116,2,1814 +74410.00464053992,0,1711 +74510.02340564458,1,1666 +74610.02954271837,1,1643 +74710.0290141816,1,1683 +74810.04183922743,1,1683 +74910.05348086968,1,1676 +75010.05838871615,0,1653 +75110.06134378802,1,1607 +75210.06363822578,1,1541 +75310.0685573859,16,1585 +75410.06780603793,1,1548 +75510.089845471,0,1589 +75610.10513245623,2,1568 +75710.10676451279,4,1587 +75810.10174451293,0,1611 +75910.10805949967,2,1579 +76010.11796992284,1,1511 +76110.1148072299,0,1496 +76210.12307525941,1,1529 +76310.12419415469,3,1647 +76410.12632045758,3,1604 +76510.12235784157,2,1539 +76610.12712981564,1,1455 +76710.12640860757,3,1486 +76810.12572071269,0,1421 +76910.13675993547,0,1469 +77010.1224669808,0,1494 +77110.13841567986,1,1556 +77210.14606759,1,1579 +77310.14322851939,1,1651 +77410.15157161599,1,1638 +77510.15811749252,1,1668 +77610.1570252979,2,1658 +77710.15959395767,0,1627 +77810.17265238817,0,1613 +77910.18473506342,4,1528 +78010.18875358303,2,1591 +78110.19578422,1,1655 +78210.19496186324,1,1686 +78310.20869976968,0,1714 +78410.23129195045,0,1681 +78510.22599402521,0,1646 +78610.2155709471,0,1647 +78710.23474546237,0,1662 +78810.24694808517,3,1680 +78910.25109368682,3,1666 +79010.25581341263,1,1624 +79110.25615348676,2,1510 +79210.28435915292,2,1461 +79310.30500161384,0,1449 +79410.30732254968,1,1464 +79510.31527084099,3,1382 +79610.31379835981,4,1367 +79710.35240249764,0,1378 +79810.36739724397,2,1419 +79910.37450006937,2,1451 +80010.371946238,3,1438 +80110.3886516337,1,1490 +80210.39020597098,1,1469 +80310.387828974,0,1458 +80410.39823606011,3,1447 +80510.3985140842,1,1488 +80610.39572485979,1,1437 +80710.40155073491,2,1508 +80810.38186952012,0,1640 +80910.40403345798,0,1701 +81010.41762103254,0,1688 +81110.42700420225,1,1714 +81210.43365863885,0,1699 +81310.44126586846,3,1750 +81410.43473420003,1,1765 +81510.44768359537,0,1781 +81610.44893759616,1,1757 +81710.43404740452,1,1763 +81810.46480961169,2,1708 +81910.46706885418,3,1687 +82010.46958316035,1,1667 +82110.47046445016,0,1594 +82210.49231455971,2,1576 +82310.48448054033,2,1626 +82410.49406228481,0,1578 +82510.49067638342,0,1512 +82610.52505292372,0,1476 +82710.52569248131,0,1485 +82810.5308687267,0,1502 +82910.57219833609,1,1550 +83010.57543080168,0,1622 +83110.58068931964,3,1688 +83210.58125573439,1,1717 +83310.58686876489,1,1759 +83410.60581843683,8,1712 +83510.62317999502,2,1781 +83610.63408293894,3,1761 +83710.62306545326,0,1615 +83810.65397156152,2,1521 +83910.66121138968,3,1539 +84010.65668330352,2,1570 +84110.65133683238,0,1554 +84210.66404619798,2,1563 +84310.67938952427,0,1653 +84410.69053709872,1,1661 +84510.68552596531,2,1607 +84610.70801654206,2,1548 +84710.71386770745,4,1529 +84810.72066824642,3,1576 +84910.72301096818,1,1594 +85010.71802211727,4,1570 +85110.71345579826,0,1590 +85210.72443256028,5,1654 +85310.70859840699,1,1671 +85410.73358901383,1,1637 +85510.73552622297,3,1764 +85610.74585625768,93,1738 +85710.757330538,2,1658 +85810.76428758053,1,1624 +85910.77313806016,2,1608 +86010.77868798986,1,1557 +86110.77031501195,1,1459 +86210.76695428701,0,1513 +86310.80668495908,3,1533 +86410.81807400117,7,1567 +86510.80125747064,3,1616 +86610.83329960838,2,1630 +86710.81870029285,2,1648 +86810.84423733392,6,1686 +86910.84320942685,3,1617 +87010.85725803494,1,1693 +87110.86113824091,2,1693 +87210.84771426368,4,1680 +87310.86234782384,2,1666 +87410.87091908362,3,1628 +87510.8839893922,1,1584 +87610.88870202728,4,1511 +87710.87546946423,9,1497 +87810.89569313076,1,1477 +87910.93806326376,0,1419 +88010.94290738774,4,1356 +88110.94254581492,1,1376 +88210.96617901856,1,1389 +88310.97742987185,0,1432 +88410.97635363038,2,1451 +88510.99361682257,0,1479 +88610.99467912431,3,1482 +88710.99902510962,1,1578 +88811.00462721262,1,1574 +88911.02412207317,1,1570 +89011.03151814449,1,1601 +89111.07406780904,0,1648 +89211.08454950209,0,1716 +89311.08053767565,1,1743 +89411.07909959908,2,1772 +89511.09441910862,1,1784 +89611.08286692569,1,1859 +89711.1096804473,1,1952 +89811.10892076335,1,2006 +89911.15305001877,2,2080 +90011.15602994301,1,2086 +90111.15884588599,0,2203 +90211.17183214283,0,2235 +90311.17495929345,1,2190 +90411.17631101086,0,2134 +90511.16823465063,0,2105 +90611.18965624618,0,2023 +90711.20452339231,0,2023 +90811.19586883677,1,1929 +90911.20028137293,0,1822 +91011.22241675071,0,1779 +91111.23420787186,0,1835 +91211.2401774474,0,1798 +91311.25042611247,3,1770 +91411.2524184629,0,1803 +91511.25827293277,1,1740 +91611.266629969,1,1790 +91711.2689511609,0,1724 +91811.28632385776,1,1781 +91911.29802922593,2,1823 +92011.31970440628,3,1817 +92111.35612853496,0,1760 +92211.37881721868,0,1687 +92311.36044030476,1,1590 +92411.38384754074,1,1641 +92511.39466541546,0,1632 +92611.38474358594,2,1687 +92711.40526318173,0,1688 +92811.4243824719,2,1698 +92911.42214415669,1,1782 +93011.44619095488,6,1927 +93111.44524291545,3,1974 +93211.44358058505,3,1997 +93311.43584799676,3,2061 +93411.44538112986,1,2017 +93511.44804321692,10,2003 +93611.46471195426,4,1962 +93711.45149436184,65,2069 +93811.49017744702,6,2006 +93911.49145743657,3,1955 +94011.49903070019,2,1860 +94111.49218182598,0,1930 +94211.50372451748,3,1957 +94311.5178196262,0,1987 +94411.51423182111,2,1959 +94511.52317387528,1,1963 +94611.52311690093,1,1951 +94711.56256243029,0,1845 +94811.59054092184,4,1825 +94911.60827224568,2,1777 +95011.60915610926,0,1715 +95111.62370734171,1,1652 +95211.61814874373,0,1655 +95311.64096337848,1,1731 +95411.63942834715,1,1719 +95511.65018042011,4,1712 +95611.65538487931,1,1684 +95711.65381196134,1,1622 +95811.66640019539,3,1625 +95911.67211752175,2,1653 +96011.66894143766,3,1595 +96111.69351235015,2,1649 +96211.68841096941,4,1607 +96311.70212855768,2,1629 +96411.71490039123,0,1705 +96511.72024895338,3,1793 +96611.73925379582,3,1892 +96711.73565175479,1,1880 +96811.74873291959,3,1917 +96911.75329883103,3,1933 +97011.77168880335,0,1849 +97111.75004633689,1,1846 +97211.76493320319,3,1755 +97311.79771688288,2,1750 +97411.79689547181,2,1788 +97511.80451542894,2,1820 +97611.78454301435,4,1786 +97711.81559173348,0,1850 +97811.8213595537,1,1830 +97911.82834179449,2,1856 +98011.8315213657,2,1870 +98111.83456881132,3,1803 +98211.84163783133,2,1763 +98311.83898854627,1,1735 +98411.83840558883,1,1712 +98511.8366414702,0,1720 +98611.84877544464,5,1652 +98711.86197938802,2,1703 +98811.86090999318,0,1688 +98911.87084809008,2,1775 +99011.87928758876,1,1754 +99111.86480056467,3,1740 +99211.88506166424,0,1698 +99311.886669534,3,1645 +99411.89080442624,0,1606 +99511.91957414724,1,1587 +99611.92088123884,2,1574 +99711.91685674134,3,1555 +99811.92674705051,1,1537 +99911.92613884488,0,1511 +99999.99924185193,2,1390 +100000,2,1390 \ No newline at end of file diff --git a/ClassicGEC/Examples/Results/receiver_device.csv b/ClassicGEC/Examples/Results/receiver_device.csv new file mode 100644 index 0000000..ce2b82e --- /dev/null +++ b/ClassicGEC/Examples/Results/receiver_device.csv @@ -0,0 +1,1003 @@ +Time,Signal +0,100 +99.99448220193615,54 +200.0333168152934,60 +300.0596386062409,61 +400.06825201321124,54 +500.09560234915654,53 +600.1104633334057,51 +700.1400937872187,48 +800.1974841052,48 +900.1943780488783,52 +1000.2060971282382,48 +1100.227255645933,40 +1200.2414996599468,48 +1300.262507875662,48 +1400.2461566850761,46 +1500.2868095635606,54 +1600.2639248576877,53 +1700.3391546905975,45 +1800.3885006342966,47 +1900.3588535938493,52 +2000.379104515662,58 +2100.332012298288,58 +2200.355954830446,47 +2300.3787438511513,46 +2400.4030739135937,44 +2500.4010670567795,52 +2600.4363762663415,49 +2700.4528759875802,51 +2800.4507982126775,50 +2900.4624141466397,52 +3000.4741294999867,52 +3100.473433790619,54 +3200.5333623793094,63 +3300.538596779971,47 +3400.5996192695166,54 +3500.6107977820693,52 +3600.5821945878943,57 +3700.6113001958474,46 +3800.666425136527,43 +3900.7012167088305,47 +4000.6978773196856,47 +4100.694303765785,39 +4200.729695342102,53 +4300.760539029202,41 +4400.788061341328,44 +4500.754690090947,42 +4600.791304639302,51 +4700.768293650205,56 +4800.8217921593205,51 +4900.85976387888,49 +5000.867581128029,56 +5100.850700033965,52 +5200.891455220531,50 +5300.920259225562,45 +5400.7992146223305,61 +5500.955703306552,54 +5600.962987227577,51 +5700.911350933753,48 +5800.956150542697,39 +5900.968222908016,50 +6000.97266207434,48 +6101.007097528637,49 +6201.043354521652,57 +6300.9893071423085,49 +6401.068043853281,51 +6501.080105251995,53 +6601.074897616402,49 +6701.101236814671,50 +6801.139666121895,45 +6901.181238913794,52 +7001.209389894865,51 +7101.223712384219,57 +7201.250833898599,46 +7301.231105178394,53 +7401.2616570612345,53 +7501.2563453691855,52 +7601.234804286586,49 +7701.265139520716,54 +7801.271936731481,53 +7901.25583795382,46 +8001.257751062773,48 +8101.273302229096,54 +8201.326326346682,49 +8301.345409630707,55 +8401.35266552162,47 +8501.355435949292,43 +8601.389436238715,49 +8701.321671780757,54 +8801.386117655684,57 +8901.406042810362,55 +9001.40324336866,41 +9101.391692051382,51 +9201.494718761525,37 +9301.509475972702,50 +9401.525271748516,51 +9501.523956347826,52 +9601.507645119855,49 +9701.568586788308,48 +9801.608223957655,51 +9901.640475806762,51 +10001.647986495833,46 +10101.67451457586,51 +10201.634683611146,53 +10301.673414539939,45 +10401.736370732982,57 +10501.763337516515,58 +10601.772402096543,47 +10701.82102773283,59 +10801.796252743046,44 +10901.849571444758,52 +11001.825285995203,55 +11101.899510308505,51 +11201.91327395345,48 +11301.926125362483,53 +11401.913658508542,50 +11501.89482894786,47 +11601.95041415564,62 +11701.987720474806,54 +11801.983712790368,47 +11902.013468588395,57 +12002.016994779962,46 +12102.000503021109,48 +12202.0335324243,45 +12302.003718766033,48 +12402.074387893705,46 +12502.092979723331,55 +12602.078220186066,57 +12702.183088088852,51 +12802.203718810815,46 +12902.218593131836,48 +13002.222886140116,49 +13102.198392333616,48 +13202.278027077386,56 +13302.277702265013,38 +13402.249789409609,51 +13502.280258765337,59 +13602.303762721736,53 +13702.418419096559,50 +13802.414865214076,42 +13902.41071189504,45 +14002.405865804456,35 +14102.429490378643,35 +14202.427393216845,30 +14302.443571241613,32 +14402.463836700223,27 +14502.480175600556,28 +14602.49312568345,15 +14702.478797082635,24 +14802.492579495492,23 +14902.489542604651,29 +15002.503633379474,30 +15102.50936212658,33 +15202.509081446513,38 +15302.512452091265,38 +15402.52305672477,39 +15502.501135194581,41 +15602.551371432795,39 +15702.556669579115,37 +15802.581300101097,33 +15902.56589939068,30 +16002.589288287098,33 +16102.612714049785,42 +16202.63008960937,42 +16302.594327293977,33 +16402.64420068527,41 +16502.653011369603,46 +16602.673185178013,34 +16702.640400603854,43 +16802.69243267998,40 +16902.70405184768,38 +17002.714514226904,44 +17102.738636576345,39 +17202.742055814433,44 +17302.74547907605,36 +17402.769399653473,37 +17502.765602977808,42 +17602.81280426323,45 +17702.818594806788,43 +17802.82398925687,42 +17902.831187929885,51 +18002.834413097054,45 +18102.831202310488,46 +18202.90902473958,43 +18302.903141773153,46 +18402.925307525078,52 +18502.952240216673,37 +18602.963069881192,47 +18702.991682004606,41 +18803.004137923963,51 +18903.00868133098,51 +19003.036910727114,46 +19103.04571950603,51 +19203.049852473916,46 +19303.057335943056,45 +19403.061633556565,52 +19503.050780470705,46 +19603.0893049244,52 +19703.10422929148,49 +19803.108350449776,54 +19903.105892354728,47 +20003.088985594062,43 +20103.105579275958,46 +20203.101339759967,38 +20303.152867601264,44 +20403.172343841856,52 +20503.18585386314,61 +20603.17905445278,46 +20703.18719415986,51 +20803.19072898732,51 +20903.18247825199,49 +21003.230292548964,41 +21103.212911419854,44 +21203.19637936885,47 +21303.238363091088,37 +21403.25980977395,47 +21503.25727178088,45 +21603.274341244858,36 +21703.280789591125,40 +21803.299679380805,49 +21903.298243884114,41 +22003.319802511753,40 +22103.307124361017,41 +22203.28530505942,54 +22303.336273043915,48 +22403.339652505594,64 +22503.34751363788,58 +22603.352635606996,53 +22703.408815541345,47 +22803.41002853158,41 +22903.39781316072,49 +23003.419492241595,56 +23103.433641891064,51 +23203.45055915515,45 +23303.46851784323,42 +23403.469712687238,54 +23503.49345616307,52 +23603.514144548386,52 +23703.50937968815,51 +23803.552954918923,41 +23903.634473978687,53 +24003.658855892736,43 +24103.688397431495,44 +24203.671891919952,43 +24303.702925600548,44 +24403.72249648535,46 +24503.771755007594,48 +24603.78276624355,47 +24703.782526165676,45 +24803.776004492513,44 +24903.82056578179,44 +25003.835588894133,50 +25103.840693858387,50 +25203.85148849659,44 +25303.814956650087,34 +25403.864195471113,52 +25503.891760463775,37 +25603.88750762813,27 +25703.912175653386,34 +25803.912153106474,29 +25903.926882569132,22 +26003.9221846723,23 +26103.929309478626,19 +26203.933510964947,20 +26303.934217310325,16 +26403.945939191377,15 +26503.945570575732,13 +26603.95458181331,17 +26703.951420472873,15 +26803.929869356783,16 +26903.95288526992,9 +27003.950504936853,13 +27103.961386182516,15 +27203.96415169677,17 +27303.939124537123,18 +27403.976856337817,6 +27503.969729198423,10 +27603.971162066286,13 +27703.987143285274,11 +27803.987079871466,13 +27903.990339245775,15 +28003.993148237358,14 +28103.99581169081,12 +28204.002785631666,16 +28304.004368143775,19 +28404.01173139644,13 +28504.035468220594,16 +28604.035952006,10 +28704.032371218636,12 +28804.036748144885,10 +28904.047605453572,12 +29004.054879837673,14 +29104.06406239272,12 +29204.043817261994,10 +29304.06031086389,14 +29404.07439870277,1 +29504.07640255014,14 +29604.09349937286,9 +29704.0914966906,9 +29804.085299306174,6 +29904.09851710412,12 +30004.107081256643,13 +30104.125349516355,10 +30204.136155761305,17 +30304.136301754086,12 +30404.138222897847,14 +30504.127947298693,21 +30604.14394067915,22 +30704.156473768053,27 +30804.14670622364,28 +30904.182051942018,28 +31004.177876153866,27 +31104.178068302605,25 +31204.218193692726,28 +31304.230708321553,30 +31404.242619702643,37 +31504.264476566743,31 +31604.264843441455,37 +31704.266224383387,34 +31804.278823939047,33 +31904.27823925178,35 +32004.305925691235,40 +32104.300870532505,33 +32204.304206174078,40 +32304.31629149181,38 +32404.335397885272,41 +32504.323135828785,44 +32604.334282287065,34 +32704.37194486375,34 +32804.3548310876,39 +32904.3999728689,33 +33004.397341668555,39 +33104.44531895161,42 +33204.484347479,38 +33304.48479169357,36 +33404.50894072537,38 +33504.5288715504,42 +33604.54290199724,49 +33704.57345680964,43 +33804.58067068052,41 +33904.56755876692,46 +34004.60007169104,44 +34104.62309331795,39 +34204.61321610662,43 +34304.62077482533,50 +34404.649680584334,39 +34504.64834584447,50 +34604.66852432367,43 +34704.669939168394,41 +34804.66735710536,37 +34904.68528493543,49 +35004.66970167766,47 +35104.74403981108,49 +35204.73709397451,41 +35304.77436900723,42 +35404.84680276922,54 +35504.85483390784,47 +35604.85229833309,39 +35704.86570378424,47 +35804.87985908708,47 +35904.89357640553,46 +36004.87616700359,43 +36104.89452180385,50 +36204.89012771526,43 +36304.92965868557,55 +36404.937476310704,49 +36504.95537868815,51 +36604.96067225737,50 +36704.96941469809,39 +36804.98599621591,55 +36904.99355776064,50 +37005.009101350064,49 +37105.02334597853,51 +37205.02893129338,41 +37305.04014538114,44 +37405.06829713995,35 +37505.085235061044,48 +37605.08336318311,47 +37705.09922001268,50 +37805.09909021102,46 +37905.11333880471,46 +38005.19043269094,47 +38105.14957630345,51 +38205.203168462016,57 +38305.17641493591,48 +38405.22807917081,55 +38505.230878376045,43 +38605.24583475419,48 +38705.2525535703,52 +38805.27087943025,45 +38905.27260136806,55 +39005.27774910256,45 +39105.27511631513,54 +39205.28442957848,48 +39305.299310137656,50 +39405.32502677187,48 +39505.32764781859,54 +39605.337832442296,54 +39705.343913928446,46 +39805.338670687364,47 +39905.350125022414,54 +40005.32016317034,48 +40105.36063172057,52 +40205.33579782645,49 +40305.384705681405,51 +40405.39742455593,48 +40505.4119739663,53 +40605.413571589204,49 +40705.45406620239,49 +40805.46858648234,47 +40905.46359335694,59 +41005.446448158116,52 +41105.46752970073,53 +41205.494893520234,46 +41305.48765658745,50 +41405.50417909205,41 +41505.5088535649,52 +41605.49510003339,54 +41705.51873163934,50 +41805.53643105132,52 +41905.55731028348,47 +42005.5687294515,55 +42105.58586421754,55 +42205.64480498757,55 +42305.663486170044,42 +42405.67204763505,67 +42505.70924284806,46 +42605.704718153356,45 +42705.7093170916,52 +42805.74814898935,46 +42905.74772844888,46 +43005.778176201995,54 +43105.76723224118,54 +43205.77889608201,52 +43305.79101143,46 +43405.80602748139,56 +43505.75727494543,55 +43605.82049845349,49 +43705.80249496509,44 +43805.83285608333,43 +43905.86055936094,57 +44005.86107990215,49 +44105.831594245545,46 +44205.916031840075,50 +44305.886438765585,50 +44405.918323558515,47 +44505.92490055903,54 +44605.94419999928,42 +44705.950932644584,64 +44805.93487348937,48 +44905.95160822085,48 +45005.96635716934,50 +45106.004887632735,41 +45206.010819008734,55 +45306.01372171485,38 +45406.03324877432,49 +45506.05004148436,49 +45606.09829706779,49 +45706.10014079594,44 +45806.10057383836,50 +45906.138578281134,52 +46006.16299246531,49 +46106.1812762059,48 +46206.17288515214,48 +46306.187500402426,50 +46406.22279651159,47 +46506.236700853064,49 +46606.26095821521,41 +46706.262090980934,43 +46806.24836917961,53 +46906.3136920386,50 +47006.31227803101,46 +47106.33348423738,45 +47206.338641719514,52 +47306.377262949936,41 +47406.37334069557,44 +47506.38035954849,58 +47606.38650588613,46 +47706.33683189901,45 +47806.380564776155,43 +47906.387951744335,59 +48006.44035202601,58 +48106.4207323955,46 +48206.51216063545,49 +48306.50170018245,46 +48406.53039266211,52 +48506.548403612884,54 +48606.5351659496,48 +48706.57077431212,42 +48806.538472241504,37 +48906.592767484275,39 +49006.608646225126,28 +49106.602085550956,30 +49206.61073165956,30 +49306.61296943909,24 +49406.61405325748,23 +49506.611319263764,18 +49606.627795247376,16 +49706.63387977784,20 +49806.622397213665,16 +49906.63726768398,22 +50006.64039436677,21 +50106.64379788099,17 +50206.660346906014,13 +50306.66528435434,22 +50406.66834412167,9 +50506.64641319905,27 +50606.66676873848,21 +50706.67380130549,27 +50806.669227727485,28 +50906.67214928903,24 +51006.67631634963,25 +51106.68554224496,34 +51206.69731453162,33 +51306.693901755985,39 +51406.739965903434,39 +51506.727740127004,34 +51606.74852464446,36 +51706.79727222699,33 +51806.7856889147,42 +51906.79412851046,36 +52006.824491810105,45 +52106.85374481979,44 +52206.866574771295,43 +52306.86530994373,36 +52406.85122405573,42 +52506.88682207315,39 +52606.89792811612,41 +52706.885464168256,39 +52806.91496673577,37 +52906.91247086794,42 +53006.88299523137,41 +53106.90181473141,52 +53206.92889106295,49 +53306.94221430378,46 +53406.8865483758,37 +53506.94156346873,43 +53606.93099918345,43 +53706.923044768744,43 +53806.973560861334,53 +53907.00633536323,51 +54007.0119995566,48 +54107.00033682328,49 +54207.00715643841,57 +54307.02941108945,49 +54407.05300712455,55 +54507.06877872673,47 +54607.09458515472,48 +54707.100140338174,51 +54807.12620394051,45 +54907.13914468673,51 +55007.15548548961,56 +55107.16116377373,41 +55207.18698121852,42 +55307.20395390104,41 +55407.19671001115,56 +55507.21195569172,44 +55607.23267538654,51 +55707.174905260326,45 +55807.25500445376,45 +55907.24328696079,42 +56007.24528647489,47 +56107.28546528548,44 +56207.304107867465,48 +56307.31901076686,53 +56407.30447362899,49 +56507.328037466585,46 +56607.35558300825,51 +56707.37945051744,49 +56807.41129495067,45 +56907.394926877576,51 +57007.43608796728,46 +57107.437562472354,46 +57207.40479834558,55 +57307.435270461036,53 +57407.47959180565,50 +57507.48156397628,46 +57607.486010893976,46 +57707.48671937449,48 +57807.529637023865,53 +57907.544341830675,54 +58007.55039707362,57 +58107.57627643544,53 +58207.58362200173,41 +58307.604417954906,50 +58407.629797232235,52 +58507.6524260415,47 +58607.66620628441,45 +58707.658971006385,35 +58807.661981287936,45 +58907.691228180825,56 +59007.69671910569,48 +59107.68802788289,51 +59207.71895742902,61 +59307.7191995369,51 +59407.74056318288,51 +59507.73495626469,49 +59607.77273729966,50 +59707.74879480618,54 +59807.770656063105,54 +59907.79313588622,44 +60007.78991973097,53 +60107.83416870539,53 +60207.889126638365,49 +60307.86553525615,50 +60407.98107397546,54 +60507.99463979961,52 +60608.000194414715,48 +60707.99383828257,57 +60808.017421928496,56 +60908.05673457385,49 +61008.08132754158,44 +61108.07879267778,58 +61208.09912214099,49 +61308.11378774124,43 +61408.132464690614,50 +61508.157546484064,50 +61608.14139511563,55 +61708.167634252706,55 +61808.12112694427,51 +61908.22331786046,51 +62008.26791785831,47 +62108.27352916878,52 +62208.286899240884,51 +62308.370990207186,52 +62408.392168378276,52 +62508.414487281625,55 +62608.432401001315,46 +62708.43828996904,50 +62808.475324788895,55 +62908.513749867605,58 +63008.546502913785,46 +63108.5291490471,53 +63208.54487852466,64 +63308.56173576294,55 +63408.54763252942,53 +63508.53238485887,52 +63608.55223686727,54 +63708.57186993352,50 +63808.60259246682,47 +63908.58734778094,56 +64008.58876937875,48 +64108.657358450764,51 +64208.70340507065,51 +64308.722928081086,48 +64408.75142620297,40 +64508.8194329785,58 +64608.82755417332,61 +64708.82269817299,51 +64808.78814172911,49 +64908.85440647204,53 +65008.84781927379,57 +65108.875066765315,44 +65208.874249038556,51 +65308.89603058189,46 +65408.91341905147,44 +65508.94052132788,44 +65608.947528161,50 +65708.94028016123,56 +65808.89915224967,54 +65909.01444848704,53 +66009.03799956175,45 +66109.0516033027,49 +66209.08442937264,41 +66309.1304600005,53 +66409.12758595381,46 +66509.1727174882,42 +66609.17141507502,42 +66709.20384638355,52 +66809.28534040584,48 +66909.25122529689,49 +67009.25194093912,48 +67109.31121919757,56 +67209.3328434222,45 +67309.37260128626,53 +67409.37275202894,40 +67509.40243056629,60 +67609.42145150313,51 +67709.43953189737,45 +67809.34885838453,47 +67909.48150780481,57 +68009.51574198817,47 +68109.51582029904,43 +68209.53565736902,49 +68309.50344808974,46 +68409.58657380042,47 +68509.61460966541,57 +68609.59877545574,46 +68709.61260565836,60 +68809.61589515289,49 +68909.64103401998,50 +69009.63599062421,45 +69109.65696831829,52 +69209.69004086101,49 +69309.68213179323,50 +69409.68667013153,59 +69509.67655149892,50 +69609.6979745189,51 +69709.68146895546,51 +69809.72568747554,52 +69909.73237290728,45 +70009.74379246027,49 +70109.75894061393,49 +70209.75476191608,47 +70309.73685411563,58 +70409.81459858517,55 +70509.83668097942,44 +70609.81866195677,45 +70709.82419936641,55 +70809.85931571233,53 +70909.88519103927,45 +71009.91562180729,54 +71109.96660645578,53 +71209.9862180904,50 +71309.97661142849,51 +71409.99129062823,51 +71510.04776899787,54 +71610.05837015432,47 +71710.06155998558,50 +71810.09524352608,46 +71910.10078738559,47 +72010.07651678112,53 +72110.13773313162,49 +72210.21422899129,48 +72310.23714715446,49 +72410.23804677493,44 +72510.2370452769,49 +72610.25479988512,54 +72710.30431713464,47 +72810.3229957757,57 +72910.32764242416,48 +73010.38754258891,65 +73110.40741184531,50 +73210.43111323366,41 +73310.47888178664,54 +73410.47154449811,44 +73510.51395792436,42 +73610.51692094801,59 +73710.53192980145,53 +73810.5173330332,60 +73910.52991883589,55 +74010.52000572452,49 +74110.54376049597,46 +74210.5494015394,51 +74310.58994908155,50 +74410.59582827172,49 +74510.57976099565,54 +74610.57762352323,56 +74710.5807457707,59 +74810.65923543449,47 +74910.68505307037,54 +75010.66253727656,50 +75110.6739993294,60 +75210.65916415765,56 +75310.69407967215,52 +75410.73304433608,42 +75510.74342590386,56 +75610.7634713095,43 +75710.8415598368,49 +75810.79905351391,51 +75910.86882393209,51 +76010.85200059031,52 +76110.86540471135,51 +76210.90175194372,56 +76310.91697670233,50 +76410.93503486319,55 +76510.9796539881,39 +76610.98159550464,49 +76710.95308919119,49 +76811.03387097572,46 +76911.13001627129,41 +77011.13938144543,42 +77111.13725132709,51 +77211.16017847821,51 +77311.16975752593,54 +77411.32886931152,47 +77511.34892511187,54 +77611.34143665193,50 +77711.34970968073,47 +77811.3563193613,45 +77911.36361247083,40 +78011.40253114051,31 +78111.41727458987,40 +78211.40726569148,27 +78311.4336081926,25 +78411.43835630872,20 +78511.44755063088,23 +78611.44524397122,16 +78711.43411705486,21 +78811.45640561993,19 +78911.46184394108,20 +79011.46792592059,16 +79111.46524527071,16 +79211.47477743865,15 +79311.4705629552,14 +79411.48152487152,10 +79511.48695894689,12 +79611.48912512587,17 +79711.48541171901,19 +79811.49006994494,20 +79911.49457678948,28 +80011.49651285583,29 +80111.50875586302,38 +80211.49692983297,32 +80311.5019798507,36 +80411.52577249667,29 +80511.53247341864,35 +80611.51803455022,32 +80711.54939064012,31 +80811.53743973994,39 +80911.55607600641,40 +81011.5451274162,43 +81111.55876316776,35 +81211.57828957793,41 +81311.56471055397,39 +81411.59022093087,38 +81511.59751134254,41 +81611.61160718503,51 +81711.61312569807,31 +81811.61888899391,36 +81911.59231711195,37 +82011.6332534218,50 +82111.62159531769,51 +82211.65704129964,40 +82311.6686016566,48 +82411.69281622207,45 +82511.69947714612,40 +82611.69766681414,43 +82711.70593102457,43 +82811.71754797391,32 +82911.70230574938,49 +83011.73554089294,48 +83111.75071467666,41 +83211.72404879495,44 +83311.7694353117,38 +83411.76792934166,38 +83511.79122588293,44 +83611.75261019269,47 +83711.76558785448,46 +83811.80425651923,50 +83911.82474609741,46 +84011.82841177293,51 +84111.83181775901,36 +84211.85043840001,48 +84311.86397447946,46 +84411.88297863689,37 +84511.86929814138,49 +84611.8645400104,45 +84711.88067842848,45 +84811.88213179562,42 +84911.88773251315,41 +85011.9049859417,50 +85111.90984846513,43 +85211.91172263713,45 +85311.94469267454,50 +85411.94582153784,56 +85511.93986798385,48 +85611.891592924,44 +85711.98631784305,43 +85811.97347267531,45 +85912.03593658075,52 +86012.03697111727,54 +86112.04836877513,46 +86212.05510471412,51 +86312.04923017252,49 +86412.05900794857,54 +86512.10507072776,56 +86612.10645316064,48 +86712.11506788505,59 +86812.11734364033,56 +86912.11455589237,49 +87012.16793010067,48 +87112.21258589119,51 +87212.2414397761,54 +87312.19062807444,54 +87412.24957568408,47 +87512.24135242408,42 +87612.29818522799,43 +87712.29418282259,53 +87812.30635331177,52 +87912.32214615901,47 +88012.3304677266,49 +88112.342846874,63 +88212.39237341727,38 +88312.36388739888,51 +88412.4213937118,49 +88512.43778578671,50 +88612.43555464614,50 +88712.43834449384,44 +88812.41154343619,58 +88912.44695702069,48 +89012.44093798852,54 +89112.46273655041,48 +89212.49343555387,46 +89312.49981743051,48 +89412.53600020311,55 +89512.54210911316,41 +89612.54939045545,47 +89712.56514031834,37 +89812.60166001749,49 +89912.67999977885,49 +90012.619807738,61 +90112.74341565902,51 +90212.77033845376,47 +90312.79361678202,54 +90412.78657434344,54 +90512.84034718112,55 +90612.79534578105,48 +90712.85136393456,58 +90812.84803022616,49 +90912.87525119976,52 +91012.91498865628,47 +91112.91116889173,59 +91212.93262292832,43 +91312.92494706294,51 +91412.96666452252,53 +91512.98977511904,51 +91612.99380277666,41 +91713.03438029492,35 +91813.03315653365,38 +91913.04888914073,38 +92013.0455269663,36 +92113.0544895799,29 +92213.05346914541,32 +92313.06459564988,29 +92413.07098354722,17 +92513.06885314376,34 +92613.08993817198,34 +92713.10121254523,32 +92813.09916217848,27 +92913.1092573126,29 +93013.12093471218,32 +93113.13129023962,34 +93213.13690824917,35 +93313.13614554293,26 +93413.16814846887,34 +93513.19873842002,36 +93613.22216868647,36 +93713.22794436157,43 +93813.23684506993,26 +93913.23891641728,38 +94013.2600965264,43 +94113.263119896,51 +94213.25823772654,38 +94313.27797491167,47 +94413.27028936589,44 +94513.31225800018,39 +94613.32346906424,38 +94713.34575511399,39 +94813.37683949897,35 +94913.37898601594,49 +95013.38584462243,43 +95113.38804814698,48 +95213.39359653012,47 +95313.41662521922,45 +95413.40344608076,38 +95513.43158925528,35 +95613.43183163274,40 +95713.46105111418,41 +95813.46884272828,43 +95913.44636510314,38 +96013.47492954526,48 +96113.48349528392,42 +96213.4826587601,47 +96313.4974182634,47 +96413.50250006525,51 +96513.5304451148,55 +96613.54940190999,40 +96713.56145270057,52 +96813.56972947808,43 +96913.59377011443,42 +97013.62280211825,43 +97113.62957738386,48 +97213.61312065039,49 +97313.65241477703,44 +97413.65057160726,49 +97513.63109368263,41 +97613.67775661903,44 +97713.67948242268,40 +97813.66706660436,42 +97913.68406424196,53 +98013.70355749715,50 +98113.7084927525,50 +98213.65367148568,38 +98313.7233289037,42 +98413.72486496247,33 +98513.72079332505,52 +98613.72363961024,48 +98713.75576936554,49 +98813.76017453111,46 +98913.80949985859,52 +99013.8184336809,51 +99113.82627662488,44 +99213.83251748297,51 +99313.8444001967,48 +99413.88308209377,48 +99513.84979741744,41 +99613.90297354021,51 +99713.90048587449,51 +99813.95361986253,51 +99913.94948363226,56 +99999.95728937362,47 +99999.99999999958,47 \ No newline at end of file diff --git a/ClassicGEC/Examples/Results/repressilator_modules.csv b/ClassicGEC/Examples/Results/repressilator_modules.csv new file mode 100644 index 0000000..eb2a3d8 --- /dev/null +++ b/ClassicGEC/Examples/Results/repressilator_modules.csv @@ -0,0 +1,1002 @@ +Time,A,B,C +0,0,0,0 +103.91123546487174,0,26,23 +205.27497329774786,3,83,43 +305.4403636186551,10,129,52 +405.5268628679468,8,125,40 +505.946195422491,13,132,31 +606.1653517484071,8,116,16 +706.5593799409236,16,109,11 +806.4436884368034,11,111,12 +906.1706275152397,11,92,11 +1007.1289118149933,10,79,20 +1107.2566430564082,11,74,22 +1206.4317642205658,18,76,16 +1307.559537432179,19,52,12 +1407.992867688328,14,43,17 +1508.050058060913,8,38,24 +1607.7964023715658,14,52,19 +1707.735753118315,13,64,12 +1808.3985220644756,8,49,14 +1908.0812603885245,14,45,18 +2008.7077319008217,29,39,14 +2108.3821871561618,53,42,12 +2209.159427401333,47,32,5 +2309.084014973059,57,34,0 +2409.4064188862876,85,38,0 +2509.560600107608,110,35,0 +2609.8409607601884,109,34,3 +2709.7534041431445,97,31,1 +2810.016420291013,102,30,0 +2909.8411650178823,149,23,0 +3009.7826933059728,156,17,3 +3110.385260909921,135,22,8 +3210.2566329071733,146,20,10 +3310.2905471651557,152,13,9 +3410.257324609446,148,18,8 +3510.522491851695,134,25,10 +3610.8754703240456,137,21,8 +3711.178626275728,144,19,8 +3811.351965713598,118,15,13 +3911.512709104262,129,15,9 +4011.655886303876,112,17,13 +4112.017063229273,131,21,13 +4212.185567312904,87,10,15 +4312.787773183292,82,4,11 +4412.510211118717,87,1,23 +4512.6399449719165,91,0,26 +4612.90562623805,89,7,48 +4712.893276352519,87,6,45 +4813.994037593715,71,20,39 +4914.298293926317,48,24,36 +5014.867524983751,39,14,31 +5115.0970043221,38,20,32 +5215.096900113966,45,16,26 +5315.8238502744,46,13,19 +5415.9141792701985,48,13,19 +5515.996093450112,34,19,13 +5615.889371782633,48,22,22 +5716.6930976976655,46,31,32 +5817.299424400423,44,26,26 +5917.602687348175,40,26,30 +6017.897213233401,31,27,24 +6118.343633961529,35,14,41 +6218.58218845076,38,10,22 +6319.489906066127,38,7,27 +6419.341722859131,23,9,24 +6519.721253937668,29,8,28 +6620.157646757462,24,7,20 +6719.556658659775,27,4,32 +6820.246584850718,31,4,40 +6920.226938637144,36,4,47 +7020.482598935067,39,8,53 +7120.738540561613,41,17,36 +7220.937148243938,41,15,30 +7321.446071885893,41,13,24 +7421.204848497338,47,9,24 +7521.95382036663,30,11,28 +7622.976194370749,30,6,26 +7722.956166408864,28,3,16 +7823.042922278822,19,2,35 +7923.723193037357,13,2,51 +8023.638861277981,21,1,81 +8124.291964932402,18,0,121 +8224.639569604662,11,1,143 +8324.640640532465,10,0,129 +8424.490921795785,9,0,163 +8525.315060572482,6,5,159 +8625.438291000866,7,10,152 +8725.21900582938,3,13,139 +8826.069282293938,0,18,94 +8926.01949152394,0,34,97 +9027.084532898596,0,76,77 +9127.185705131458,0,187,52 +9227.272866283478,0,285,50 +9327.406823981708,0,375,50 +9427.510507791581,0,411,43 +9527.538969122767,5,449,31 +9627.539302339568,11,446,25 +9727.81379729904,11,386,17 +9828.140971235385,12,355,18 +9928.135098035435,13,306,17 +10028.356868304918,14,234,18 +10128.358710352713,22,239,13 +10228.418869615496,25,193,11 +10328.392807901959,24,170,8 +10428.536274821197,23,174,7 +10528.236734572074,28,129,7 +10628.387357829095,23,133,7 +10729.044458745173,26,124,7 +10828.909235495561,26,127,14 +10929.048393145002,36,109,6 +11029.256624782392,26,96,1 +11129.392279610382,48,77,0 +11230.085596320767,82,59,0 +11330.15276825258,105,62,0 +11430.303760616926,128,57,0 +11530.733560048353,138,53,0 +11631.015987975406,116,59,0 +11731.67178184373,111,34,0 +11832.05227692824,170,32,0 +11932.150680373605,240,26,0 +12032.28667173352,348,20,0 +12132.306507137087,475,14,0 +12232.398418664714,554,25,0 +12332.592035410167,634,20,0 +12432.5784455772,701,25,0 +12532.682239826037,737,30,0 +12632.711393061561,753,20,0 +12732.760596598911,700,21,2 +12832.821933468987,645,23,3 +12932.830371730473,611,23,2 +13033.017497161605,527,13,1 +13133.113787652184,472,13,11 +13233.052816138372,444,13,12 +13333.072809871357,408,7,22 +13433.207008951174,392,13,20 +13533.166189885675,351,7,15 +13633.191950223507,337,2,19 +13733.303665981759,338,1,29 +13833.386553456483,256,1,36 +13933.80347804562,261,0,45 +14033.965198565886,207,0,94 +14133.72936319437,189,0,138 +14234.14102054902,153,0,195 +14334.279913273806,143,0,245 +14434.423174287867,139,0,309 +14534.455951520646,110,0,353 +14634.405491380227,95,0,415 +14734.70546879825,82,0,504 +14834.687538407878,81,0,601 +14934.912022906952,62,0,655 +15034.975483864913,75,0,652 +15134.96292908238,72,0,716 +15235.101516376919,54,0,714 +15335.111859795328,48,0,752 +15435.1460890678,41,0,736 +15535.137332789269,37,0,861 +15635.316658645464,37,0,891 +15735.433420921963,35,0,893 +15835.368044922017,36,7,905 +15935.480969758435,32,8,900 +16035.50802815676,31,13,802 +16135.520694937855,30,9,763 +16235.552844509919,21,9,649 +16335.562753507887,17,9,630 +16435.669314282564,21,12,541 +16535.729268573454,16,16,536 +16635.73919028712,20,19,476 +16735.856394314203,23,23,428 +16835.61159428425,11,8,369 +16936.04527151302,12,16,355 +17035.914238601952,12,18,286 +17136.17209543873,11,27,312 +17236.36093366946,11,37,288 +17336.60586127413,17,42,259 +17436.809133746916,27,47,262 +17536.691290159386,16,50,238 +17636.87631752254,6,40,242 +17736.876818246248,7,36,215 +17837.040453945217,11,34,202 +17937.076678728336,7,33,168 +18037.380765659105,5,45,166 +18137.43253371791,6,44,153 +18237.443453547046,7,61,141 +18337.59563942835,9,59,132 +18437.63351359136,3,47,114 +18537.54143312436,12,41,83 +18637.708478411518,7,44,77 +18737.730608253114,11,37,57 +18837.28499776187,16,41,51 +18937.0796459162,17,45,56 +19038.098468481407,20,52,59 +19137.952118044956,21,39,46 +19237.49217238702,16,44,64 +19338.679967065727,13,35,67 +19439.5937613055,11,27,58 +19540.38589979148,7,26,42 +19640.22227467349,9,31,39 +19740.636068785345,8,47,43 +19840.64755259374,11,58,31 +19940.602574679233,11,66,33 +20040.72443050798,10,61,24 +20141.54570340322,17,77,24 +20241.675801315694,9,74,22 +20341.45711991326,7,78,29 +20442.057158850952,8,72,33 +20542.220369929648,7,79,34 +20642.124129837717,9,90,24 +20742.4981792959,26,81,30 +20842.7035344396,30,73,21 +20943.52399751663,44,90,21 +21042.921901197024,54,86,16 +21143.7717927901,52,72,19 +21243.819920549566,66,75,19 +21344.71316684686,59,85,19 +21444.81851140769,65,51,21 +21545.425825738123,56,49,17 +21645.937304563195,52,55,15 +21746.388608476114,48,55,14 +21846.478330926915,43,55,16 +21946.210657959313,40,53,18 +22046.594048411356,39,54,18 +22146.80175151657,32,33,15 +22247.388164776607,34,33,6 +22347.37687360637,55,39,3 +22447.942423679455,43,51,3 +22547.947820132606,64,42,4 +22647.320624242453,75,34,8 +22747.691628808283,58,36,9 +22848.162196675094,62,35,11 +22948.2412206233,73,42,2 +23049.988464978313,60,55,1 +23150.032757896617,64,52,2 +23250.407636832835,100,43,4 +23350.566073149275,121,42,10 +23450.31518966283,106,46,6 +23550.881262742467,117,43,4 +23651.048716060563,137,47,1 +23751.066470654656,140,44,5 +23851.227964019385,101,30,14 +23951.98289031135,79,20,23 +24051.819523368285,66,29,30 +24152.07904163031,58,20,34 +24253.07117685162,57,13,33 +24353.518774583797,63,9,38 +24454.562808877457,56,5,43 +24554.507029968823,57,4,26 +24655.132847447352,42,2,22 +24756.190245509817,38,2,28 +24856.198951864,43,1,37 +24956.127444847276,40,2,51 +25056.757839690512,35,1,66 +25156.828506014623,37,0,70 +25257.241080138363,29,0,146 +25357.662994967097,15,0,233 +25457.6992014166,14,0,298 +25557.96734281583,10,6,354 +25657.972387948455,11,8,322 +25758.09419340209,9,9,294 +25858.18222301933,10,9,265 +25957.816100510663,8,11,234 +26058.23825876695,15,29,218 +26158.27487764547,16,36,171 +26258.203359595547,18,38,136 +26358.521379623853,26,38,142 +26458.55394856564,23,30,126 +26557.844107120072,26,35,132 +26658.7475957175,21,32,136 +26758.987716471183,21,34,123 +26858.750286566024,26,20,116 +26959.04068549308,27,32,118 +27058.81857653427,21,30,106 +27158.70399400282,17,30,118 +27259.62797418525,14,26,112 +27359.656587528138,16,32,98 +27458.798542947367,5,37,99 +27559.28914978139,11,42,104 +27659.951240137583,22,34,119 +27760.36201502483,18,36,96 +27860.458753389437,19,28,76 +27960.908388276872,24,34,75 +28061.19499151892,26,34,46 +28161.109053125205,29,33,39 +28261.618333140552,22,26,41 +28360.903107651895,19,25,38 +28462.36381407543,16,13,28 +28561.769476748654,14,18,31 +28662.559554811796,11,13,39 +28761.51843362575,9,17,33 +28863.21974793743,4,21,31 +28963.146670984108,7,48,18 +29063.71535342858,17,67,19 +29163.890677228923,32,76,24 +29263.813201550194,34,65,28 +29364.60087336799,29,75,18 +29464.328317415955,34,74,19 +29565.019418996853,21,73,11 +29665.39613976109,27,59,3 +29765.601351954585,41,67,2 +29865.5207982654,39,63,1 +29966.39543995261,68,51,0 +30066.37898004625,94,45,1 +30166.8292056778,138,46,0 +30266.63801384113,201,41,0 +30366.961014780925,264,42,0 +30467.176545827955,359,36,0 +30567.186939573527,500,24,0 +30667.188414478227,545,27,0 +30767.496836265953,618,23,0 +30867.568422955184,645,19,0 +30967.57324710226,688,21,0 +31067.730006305956,768,28,0 +31167.753597242227,787,21,1 +31267.883614707513,826,15,0 +31367.90152130927,805,16,0 +31467.72968504187,805,25,0 +31567.967999288576,833,19,8 +31667.997214402305,759,19,19 +31767.97658271964,695,12,18 +31868.113033612826,656,11,16 +31968.070447936916,621,10,18 +32068.1393847244,544,13,19 +32168.164778316775,434,10,25 +32268.174370722612,428,8,30 +32368.09861727296,388,1,26 +32468.013597869558,340,1,41 +32568.187503436246,276,1,42 +32668.148533756837,265,0,73 +32768.217375301836,268,0,98 +32868.19917388746,232,0,120 +32968.838940812486,175,0,114 +33068.908127322386,150,0,121 +33169.19508017688,130,0,194 +33269.332817617105,130,0,246 +33369.38464066873,90,0,289 +33469.361370683626,104,0,384 +33569.34114436292,105,0,435 +33669.51385032953,94,0,464 +33769.528459983616,71,0,519 +33869.729928967274,69,0,622 +33969.77444132697,57,0,618 +34069.79740661193,46,0,609 +34169.86817093377,48,0,636 +34269.9679238556,32,0,645 +34369.89871048942,20,0,703 +34469.97490834967,18,0,639 +34570.038155997216,21,0,614 +34670.1030832296,18,0,700 +34770.066042451836,18,0,684 +34870.165017440246,17,0,671 +34970.24367293371,19,0,652 +35070.342900927644,19,0,653 +35170.31500724812,17,0,674 +35270.49707534653,13,0,685 +35370.66004862262,10,0,684 +35470.6481525108,19,3,683 +35570.47228579141,17,5,632 +35670.89152296186,5,16,544 +35771.17223356475,2,16,481 +35871.26704400036,2,24,505 +35971.230483654974,1,33,479 +36071.29100904177,1,55,421 +36171.45848888005,0,87,358 +36271.54654581023,1,90,346 +36371.57484449789,1,152,333 +36471.845714441195,0,170,296 +36572.18262086913,0,183,289 +36672.15790584913,0,212,275 +36772.157023231826,0,236,237 +36872.25159817118,0,292,240 +36972.27972272099,0,355,232 +37072.087893853706,0,377,226 +37172.33807535092,0,475,179 +37272.43850303034,0,533,173 +37372.56388985371,0,643,168 +37472.58001455527,0,689,140 +37572.68468113788,0,763,126 +37672.85500634077,0,857,102 +37772.902554347995,0,925,103 +37872.89673061782,0,896,87 +37972.896095110664,0,964,71 +38072.97873189999,0,922,65 +38173.02329280787,0,937,45 +38273.02681920163,0,989,51 +38372.83265744082,0,967,57 +38473.05308383648,0,966,48 +38572.998838657564,0,995,39 +38673.054752034885,0,1039,43 +38772.952151749625,0,1032,43 +38873.17100578963,0,1044,44 +38973.24972687144,0,1094,23 +39073.159363137034,9,987,28 +39173.236839834666,13,916,26 +39273.46002459392,21,840,25 +39373.42479476658,22,759,20 +39473.510445979875,18,620,13 +39573.49293760747,28,530,8 +39673.810588659886,29,513,12 +39773.84083535642,33,547,5 +39873.854793709295,37,464,3 +39974.0568476996,60,425,0 +40074.185498902894,45,402,0 +40174.1660989814,68,344,0 +40274.34792766874,84,289,0 +40374.5359765659,111,241,1 +40474.515374968636,143,231,1 +40574.46378591579,172,222,0 +40674.62414961122,220,207,0 +40774.91213220646,316,213,0 +40874.9128975766,439,190,0 +40974.95052764285,577,177,0 +41074.96574910084,622,146,0 +41175.014343418,637,127,0 +41275.03131651584,704,113,0 +41375.02812158011,716,96,0 +41475.174052592796,762,82,0 +41575.19652740498,826,90,0 +41675.11352076779,829,78,0 +41775.3278208018,872,82,0 +41875.37007670215,930,75,0 +41975.41708090427,964,62,0 +42075.444383723676,1042,57,0 +42175.39272936143,1100,65,0 +42275.47055227507,1141,53,0 +42375.468494753506,1099,48,0 +42475.48713623248,1103,36,0 +42575.531136145815,1099,46,0 +42675.53126459388,1096,32,0 +42775.53008063621,1145,15,0 +42875.579549323185,1043,7,0 +42975.57015364767,1125,1,2 +43075.61629458461,1046,0,64 +43175.65998147353,916,0,123 +43275.6563619109,897,0,191 +43375.74858817659,746,0,240 +43475.68199647167,708,0,276 +43575.78477686963,604,0,332 +43675.73742231557,573,0,401 +43775.8920075484,491,0,431 +43875.90066655083,415,0,502 +43975.82873190759,406,0,525 +44075.91763886026,393,0,627 +44176.00693739209,377,0,633 +44275.97064797488,319,0,673 +44376.073155611004,307,0,633 +44476.04154977589,265,0,658 +44576.047347880056,220,0,714 +44676.132095432724,179,0,716 +44776.20789381131,131,0,765 +44876.19555469188,125,0,786 +44976.20015939138,97,0,764 +45076.272705500916,79,0,803 +45176.26171815432,94,0,796 +45276.53725406935,81,0,818 +45376.509485508905,81,0,789 +45476.372465011395,63,0,777 +45576.59000922864,49,0,795 +45676.71553818004,37,8,870 +45776.75864321816,35,10,789 +45876.90939163348,33,7,715 +45976.967702147296,36,9,651 +46077.022713192826,23,10,598 +46176.988421913804,27,9,558 +46277.0725469175,26,8,493 +46377.15581230283,27,8,413 +46476.978287003796,25,8,355 +46577.29883052063,22,10,350 +46677.53062184545,5,6,309 +46777.37458462024,2,4,247 +46877.62611349149,1,5,224 +46977.62576695994,0,12,207 +47077.637509892294,0,30,228 +47178.158454311284,1,72,195 +47278.022304739905,1,94,186 +47378.24490501133,1,124,172 +47478.341346462774,0,145,178 +47578.453660343024,1,168,134 +47678.31957296403,0,189,126 +47778.571073470186,0,250,107 +47878.56425717938,0,301,93 +47978.84040220937,0,378,83 +48079.17439270704,0,460,61 +48179.14136325079,2,511,42 +48279.27426726966,7,495,49 +48379.293294201336,3,463,35 +48479.32420534836,8,416,42 +48579.29720514008,4,366,24 +48679.57954441958,9,344,28 +48779.59130230192,15,313,26 +48879.6715022994,18,290,11 +48979.85894147189,20,271,5 +49079.811644628535,26,267,3 +49179.86657913903,21,231,3 +49279.65399161342,50,194,0 +49380.02832106967,120,192,0 +49480.15593184564,167,203,0 +49579.82815302672,223,177,0 +49680.154042609,343,166,0 +49780.35421455383,429,142,0 +49880.35424331603,468,104,6 +49980.50936069484,487,95,9 +50080.510463392064,451,81,5 +50180.5386875397,452,69,8 +50280.5267616311,409,63,6 +50380.672222931054,365,51,7 +50480.43799271522,390,41,12 +50580.46316921008,313,43,11 +50680.82312212925,284,49,14 +50780.85254811854,253,41,15 +50880.932331318065,247,31,26 +50980.27115631493,248,29,13 +51081.33652011187,211,42,6 +51181.240300852995,223,41,1 +51281.257525194356,244,37,1 +51381.19813329679,278,29,1 +51481.422105421094,282,18,0 +51581.737079775485,293,14,1 +51681.81288244137,292,13,0 +51781.760078450105,298,17,1 +51881.87784883866,268,19,0 +51981.933199601954,349,17,0 +52082.13902929159,384,13,0 +52182.199439005446,446,2,0 +52282.24773787813,500,3,8 +52382.29680754707,468,0,39 +52482.32997048557,487,0,134 +52582.30556548886,474,0,167 +52682.424418378105,412,0,225 +52782.37374743871,357,0,319 +52882.47266693399,327,0,395 +52982.53016736079,294,0,464 +53082.57219448218,257,0,501 +53182.70772495185,223,0,532 +53282.63481702207,216,0,558 +53382.75446460995,232,0,567 +53482.803786390985,184,0,616 +53582.79837698153,172,0,638 +53682.80007738721,166,0,647 +53782.9840622171,152,0,705 +53882.95661714303,132,4,698 +53983.076258181565,174,8,620 +54083.175803111495,168,6,523 +54183.22872001067,140,12,457 +54283.710055922566,109,10,444 +54383.49126534866,105,7,422 +54483.881798650145,116,10,367 +54584.08390524762,108,14,321 +54684.07978216943,68,9,301 +54784.26093771734,70,10,288 +54884.16298904742,71,15,281 +54984.32318212749,64,13,210 +55084.646275954336,41,13,200 +55184.65464105604,37,20,192 +55284.575981514565,34,15,219 +55384.990049261425,40,26,203 +55485.06332469333,34,21,179 +55585.126196832796,33,22,139 +55685.42850805933,25,31,157 +55785.24418520562,33,21,156 +55885.5843047766,28,12,149 +55985.65941162739,19,9,145 +56085.20721691792,16,8,100 +56186.18190950562,10,7,113 +56286.41391953437,11,6,128 +56386.94789533891,11,3,120 +56486.860743071185,11,1,130 +56587.418731703794,11,0,147 +56687.31536691248,12,1,168 +56787.76656870909,13,0,185 +56887.61815066278,12,1,211 +56988.278288957525,6,8,210 +57088.31431485473,8,12,203 +57187.903545145185,7,13,186 +57288.67638687372,7,25,185 +57388.951504311546,5,21,157 +57488.96318793667,10,24,155 +57589.04660396707,3,30,169 +57689.17759830952,1,45,141 +57789.22817600563,1,55,142 +57889.444366407224,0,77,111 +57989.85041104072,0,106,115 +58089.99777564001,0,137,85 +58190.01727628042,0,195,74 +58290.22614458613,0,270,76 +58390.676182585994,0,356,74 +58490.90001547276,7,388,52 +58591.01283755387,4,419,63 +58691.135002033625,1,389,50 +58791.145110486636,0,421,53 +58891.01150609755,0,439,51 +58990.83852539622,4,533,46 +59091.254282535396,7,508,43 +59191.46104745853,3,504,50 +59291.58635905287,7,565,38 +59391.60782369305,7,491,39 +59491.82418449659,8,433,44 +59591.87885097491,5,396,42 +59692.089834105755,11,375,29 +59791.87644287786,17,366,30 +59892.404990175244,20,357,27 +59992.403831135285,15,351,15 +60092.39768372318,12,337,18 +60192.53732609703,19,313,20 +60292.72962294882,27,278,13 +60392.989978749116,28,263,19 +60492.989630715456,33,218,25 +60592.7263499386,38,197,21 +60693.213358524146,54,170,9 +60793.159285556256,50,142,5 +60893.30107192781,38,132,2 +60994.341147480205,44,144,0 +61094.91928439626,93,140,0 +61194.94548145197,155,120,0 +61294.956622585065,222,108,0 +61395.11385433507,273,110,0 +61494.96050602904,352,112,0 +61595.5310218978,384,94,0 +61695.48464854882,415,102,0 +61795.57392811677,456,90,0 +61895.47983258193,528,100,0 +61995.67643340064,632,89,0 +62095.711607210294,698,62,0 +62195.735477271126,759,48,0 +62295.83787723843,755,42,0 +62395.867023717896,919,32,0 +62495.86263806162,960,22,5 +62595.8723737297,951,19,10 +62695.92840242974,883,11,8 +62795.89331549765,822,10,18 +62896.02128549805,721,10,21 +62996.0265795647,649,11,20 +63096.03032267688,579,7,40 +63195.99518813253,552,1,44 +63296.10825538188,518,0,71 +63395.81648251823,458,1,92 +63496.3843147478,429,0,140 +63596.29154438921,375,1,134 +63696.44066311408,355,1,137 +63796.47156376697,342,0,162 +63896.72989927413,326,0,194 +63996.66187026119,294,0,242 +64096.944292734566,273,0,290 +64196.9835266383,290,0,395 +64296.97144799121,277,0,391 +64397.06516575655,270,0,366 +64497.127632869786,238,0,419 +64597.15001798481,206,0,495 +64697.17642591753,182,0,595 +64797.200423001916,164,3,648 +64897.120888155776,162,3,636 +64997.32626613069,117,8,628 +65097.30722296733,109,7,577 +65197.32502047289,111,7,503 +65297.31649430921,118,13,471 +65397.35848656337,104,11,439 +65497.464568765514,96,13,454 +65597.4519348394,84,4,367 +65697.67985494848,52,7,318 +65797.72124560633,34,4,287 +65898.13657922448,43,1,287 +65998.47612844195,25,0,275 +66098.08374337431,22,0,267 +66198.47590217383,15,0,309 +66298.7377109199,16,4,299 +66398.75809451201,11,10,303 +66498.72334265048,9,6,308 +66598.96975370022,9,10,274 +66699.36286993048,7,13,263 +66799.38867993947,6,19,232 +66899.58455990984,9,24,247 +66999.70007509606,10,19,197 +67099.39524614188,10,14,181 +67199.98889757357,10,8,180 +67300.15176740178,8,6,177 +67400.03306436358,9,12,167 +67500.1806072963,7,25,152 +67600.47926455986,5,22,122 +67700.45961016376,2,33,105 +67801.04983181355,0,36,102 +67901.28623336207,0,74,93 +68001.90659763617,0,93,107 +68102.02636082216,1,117,94 +68202.07774438453,1,149,83 +68301.89258853643,1,164,99 +68402.18901028184,0,158,86 +68501.8412264954,0,188,72 +68602.36448542499,0,249,52 +68702.29115077609,0,309,53 +68802.55575941417,0,443,65 +68902.74966508165,0,489,57 +69002.6524050068,0,540,41 +69102.74678317284,0,582,48 +69202.96647390889,0,592,47 +69302.85293680556,0,625,40 +69402.96978773472,0,674,40 +69503.12820373672,0,739,29 +69603.15541809393,4,779,14 +69703.16301578625,10,778,11 +69803.17430369536,9,671,14 +69903.2613652501,3,668,13 +70003.25841404256,1,627,13 +70103.43314455243,0,559,12 +70203.30253574478,0,502,13 +70303.55911284738,6,490,9 +70403.59524434003,16,421,14 +70503.76244994138,22,393,6 +70603.71612958751,30,339,11 +70703.78804607246,34,270,7 +70803.88784190372,47,265,9 +70903.9106962088,54,264,9 +71003.62606394643,49,241,13 +71104.82000913615,54,215,14 +71204.72311505368,53,210,9 +71304.97962079158,82,182,13 +71405.27249310179,72,200,9 +71505.30423621488,67,159,4 +71605.55027632492,91,147,0 +71705.4782077441,133,153,0 +71805.55546112364,242,130,0 +71905.65609144978,296,133,0 +72005.59532645429,399,115,0 +72105.55060995795,518,109,0 +72205.63787276656,553,90,0 +72305.80640585657,613,91,0 +72405.84787516852,692,64,0 +72505.84967617595,790,54,0 +72605.8482072258,815,53,0 +72705.82060981948,867,49,0 +72805.91279451242,865,52,0 +72905.92902757225,828,40,0 +73005.89526038276,890,38,0 +73106.00381380515,986,27,0 +73205.99711340977,1067,23,0 +73305.99540933105,991,25,5 +73406.03760180037,949,33,5 +73505.87863719928,827,28,1 +73606.08840631101,833,25,0 +73706.14664442772,772,29,0 +73806.19933952882,803,26,10 +73906.13595028293,764,29,8 +74006.2946032621,642,23,8 +74106.33023116546,561,18,10 +74206.15835610432,525,26,15 +74306.39519959445,519,28,23 +74406.43883199374,458,24,16 +74506.43518330838,392,24,11 +74606.65734244151,378,23,7 +74706.2039118052,307,19,7 +74806.86935568127,337,19,9 +74906.84394647408,324,19,10 +75007.06695554106,308,23,10 +75107.06150640869,284,15,12 +75206.96795901856,236,14,25 +75307.78090538707,215,11,15 +75408.09346313404,200,14,14 +75508.13000043346,156,11,25 +75608.78882093409,151,8,31 +75708.96101266811,140,10,23 +75809.00979900936,114,11,27 +75908.92968896852,119,16,31 +76008.55497499541,99,27,18 +76109.56693712724,96,18,30 +76209.82583186663,80,20,36 +76309.75377013157,61,14,22 +76410.1453768141,79,8,23 +76510.03537247989,65,7,26 +76610.96363255633,64,8,14 +76710.61425661572,69,4,21 +76810.83658474783,61,5,31 +76911.26356822933,63,2,42 +77011.8210596954,50,5,44 +77111.51556628614,41,4,51 +77212.51989364951,32,5,62 +77312.80758209426,18,6,74 +77412.5050668241,15,2,95 +77513.13967360399,19,2,104 +77612.45447184521,17,1,121 +77713.86699776394,19,0,122 +77814.34680186318,18,0,172 +77914.43887709791,16,0,191 +78014.4743481833,18,0,244 +78114.38903074227,23,0,327 +78214.63978554538,23,0,375 +78314.68119324412,25,0,420 +78414.6602591375,21,0,478 +78514.94226263084,20,0,418 +78615.02995665568,21,0,475 +78715.02840392849,17,0,497 +78815.12055260211,12,4,540 +78915.07612746765,5,17,545 +79015.1321108846,1,11,553 +79115.27797204738,0,24,491 +79215.27553401749,0,40,420 +79315.48515679842,0,94,385 +79415.62347402253,0,167,295 +79515.59792917052,0,237,257 +79615.78715704946,0,306,290 +79715.85726122675,0,410,253 +79815.88931303694,0,532,246 +79916.00120900353,0,656,194 +80015.99035064143,0,712,201 +80116.01445176269,0,773,156 +80216.0816953415,0,769,131 +80316.12314208863,0,798,135 +80416.16997070963,0,793,120 +80516.13805713052,0,881,117 +80616.26910313788,0,874,121 +80716.27795228899,0,834,115 +80816.27489059065,0,850,116 +80916.29557082002,0,873,100 +81016.28473277869,0,918,117 +81116.39606517646,0,904,104 +81216.34544273939,0,907,92 +81316.41807699358,0,916,80 +81416.41750233306,0,877,69 +81516.39234132023,0,908,74 +81616.54528265247,0,822,64 +81716.61773485588,0,807,61 +81816.41526521507,0,771,57 +81916.67754731954,0,796,66 +82016.71152816349,0,838,69 +82116.75141785863,0,981,55 +82216.80802564441,2,944,48 +82316.83341411156,6,947,45 +82416.95642959689,12,909,38 +82517.0702278602,16,844,31 +82617.08436605305,18,745,31 +82717.0490826536,15,625,27 +82817.23549896885,21,587,20 +82917.49820944773,29,504,19 +83017.67605432222,22,429,15 +83117.86068137111,23,359,13 +83217.95457107744,27,324,11 +83318.05613617065,41,305,12 +83418.1142919284,38,295,8 +83518.36160991112,35,279,5 +83618.35529041376,40,270,0 +83718.45610365778,110,232,0 +83818.5317516379,220,217,0 +83918.98578977553,284,194,0 +84019.2016201548,394,164,0 +84119.32885929808,446,150,0 +84219.35257436802,592,152,0 +84319.43176187773,663,144,0 +84419.43559080559,711,120,0 +84519.46533177218,712,96,0 +84619.68925680415,690,66,0 +84719.68103852487,740,54,0 +84819.59613284511,746,46,5 +84919.67494336671,766,44,11 +85019.75602554268,768,46,7 +85119.79912416471,664,45,8 +85219.8040932813,633,43,10 +85320.03876908924,617,27,8 +85420.05984979247,621,24,11 +85520.08324940146,548,20,9 +85620.36314211923,480,20,10 +85720.54159769621,426,15,4 +85820.585263794,402,12,3 +85920.99154968237,396,7,10 +86021.09591265483,342,8,6 +86121.0824375159,290,4,19 +86221.18316414606,281,8,32 +86321.22326010255,231,10,38 +86421.5422463905,204,5,51 +86521.63518510113,178,7,48 +86621.80919648398,158,10,53 +86721.87487472004,148,11,57 +86822.08272818748,116,13,57 +86922.30273230183,114,8,42 +87022.5339271133,102,14,48 +87122.96718301288,87,17,43 +87223.27509430048,83,16,43 +87323.48843359452,54,13,35 +87423.59641881639,43,8,34 +87523.65543758041,38,19,29 +87624.63072180038,18,20,21 +87724.10678194097,10,27,17 +87825.12792588276,7,18,17 +87925.34194636527,2,28,15 +88025.3215713608,1,37,22 +88125.53092739418,0,69,25 +88226.08586047859,0,126,22 +88326.42094795793,5,131,8 +88426.34539304313,11,129,2 +88526.47611328126,12,147,0 +88626.60624811308,44,138,0 +88726.88652127588,79,152,0 +88826.99287850539,181,132,0 +88926.74579364176,286,100,0 +89027.12898548257,395,76,0 +89127.2262570268,496,79,0 +89227.39224496929,613,62,0 +89327.5764532606,707,39,0 +89427.5828154209,766,29,3 +89527.65901095723,832,44,4 +89627.75420484837,804,39,6 +89727.79545237485,730,29,14 +89827.86471334014,731,27,13 +89927.84907691223,684,22,16 +90027.91947316933,577,32,19 +90128.07608809034,503,31,15 +90228.17872389781,445,31,14 +90328.21188550263,403,36,16 +90428.1291023666,378,21,14 +90528.2985934436,307,24,19 +90628.52793876242,283,24,21 +90728.91555456909,293,20,18 +90829.31922011991,260,25,18 +90929.11229508687,240,12,22 +91029.42919604381,221,11,21 +91129.6651150286,200,9,23 +91229.9798606634,169,4,23 +91330.07382391793,142,8,29 +91430.06053899572,129,15,26 +91530.442349184,145,21,36 +91629.77142923551,137,20,25 +91730.75410881138,130,26,30 +91830.54474896495,101,22,29 +91931.27653025475,90,26,38 +92031.24941923474,66,20,33 +92131.80582702516,59,21,36 +92231.84918469883,51,17,33 +92332.7171869947,69,9,30 +92433.01205161064,68,2,19 +92533.05145093836,48,2,18 +92633.27518756292,45,1,38 +92733.63400322679,38,0,72 +92833.56838312956,27,0,149 +92934.11172254264,20,0,218 +93034.24468658156,17,0,272 +93134.27884595437,21,0,312 +93234.46018986708,18,0,341 +93334.46960294049,15,0,352 +93434.38034752884,18,8,393 +93534.6413955782,26,5,415 +93634.58677713489,14,4,368 +93735.18614384836,7,0,348 +93834.8101994181,15,0,306 +93935.33320656912,11,0,323 +94035.49055851092,13,0,381 +94135.57470451835,16,0,402 +94235.63744368734,8,0,438 +94335.79260647867,11,0,509 +94435.91803114804,12,3,507 +94535.87476736112,6,8,518 +94636.04037402314,4,11,462 +94736.19324433502,2,22,441 +94836.0399011328,1,21,420 +94936.1774754013,0,61,348 +95036.30989765112,0,131,323 +95136.36388024177,0,212,332 +95236.5029078477,0,306,282 +95336.59523099817,0,411,233 +95436.66969556722,0,409,220 +95536.62713394579,0,413,168 +95636.69242826941,0,487,172 +95736.71897928047,0,541,166 +95836.8964542962,0,570,138 +95936.95153883634,0,626,151 +96036.92003403466,0,606,140 +96137.0642105573,0,650,124 +96237.05418360743,0,626,102 +96337.14829687006,0,766,76 +96437.16443472721,0,768,73 +96537.19038789897,0,778,69 +96637.4896810076,0,769,53 +96737.62614815135,0,768,36 +96837.65228685043,0,848,38 +96937.6631880946,0,918,36 +97037.75098867327,0,933,32 +97137.77855310103,0,984,36 +97237.70631498922,0,945,25 +97337.92680618768,0,913,18 +97437.9802874181,6,920,13 +97538.061325625,2,844,14 +97638.09287457938,0,843,24 +97738.09362194444,10,765,13 +97838.10762253772,13,696,14 +97938.11650486609,15,615,8 +98038.29062990371,16,628,6 +98138.17986806354,7,538,7 +98238.16353181467,7,474,10 +98338.39708899318,15,422,11 +98438.54009905795,20,399,14 +98538.65424840078,15,348,7 +98638.31097327484,25,273,7 +98738.67973370303,25,227,4 +98838.71480995565,30,179,2 +98938.6417284288,33,146,2 +99038.91866334192,35,121,1 +99138.93995162165,76,97,0 +99239.53012677889,159,70,0 +99339.16676383071,264,59,0 +99440.02962579156,348,49,0 +99540.29471426392,423,46,0 +99640.38453125526,476,37,0 +99740.38438157868,516,34,0 +99840.87804343985,589,32,0 +99940.8490129389,655,22,0 +99999.95161541106,704,17,0 +99999.99999999952,704,17,0 \ No newline at end of file diff --git a/ClassicGEC/Examples/Results/repressilator_modules_similar.csv b/ClassicGEC/Examples/Results/repressilator_modules_similar.csv new file mode 100644 index 0000000..eb2a3d8 --- /dev/null +++ b/ClassicGEC/Examples/Results/repressilator_modules_similar.csv @@ -0,0 +1,1002 @@ +Time,A,B,C +0,0,0,0 +103.91123546487174,0,26,23 +205.27497329774786,3,83,43 +305.4403636186551,10,129,52 +405.5268628679468,8,125,40 +505.946195422491,13,132,31 +606.1653517484071,8,116,16 +706.5593799409236,16,109,11 +806.4436884368034,11,111,12 +906.1706275152397,11,92,11 +1007.1289118149933,10,79,20 +1107.2566430564082,11,74,22 +1206.4317642205658,18,76,16 +1307.559537432179,19,52,12 +1407.992867688328,14,43,17 +1508.050058060913,8,38,24 +1607.7964023715658,14,52,19 +1707.735753118315,13,64,12 +1808.3985220644756,8,49,14 +1908.0812603885245,14,45,18 +2008.7077319008217,29,39,14 +2108.3821871561618,53,42,12 +2209.159427401333,47,32,5 +2309.084014973059,57,34,0 +2409.4064188862876,85,38,0 +2509.560600107608,110,35,0 +2609.8409607601884,109,34,3 +2709.7534041431445,97,31,1 +2810.016420291013,102,30,0 +2909.8411650178823,149,23,0 +3009.7826933059728,156,17,3 +3110.385260909921,135,22,8 +3210.2566329071733,146,20,10 +3310.2905471651557,152,13,9 +3410.257324609446,148,18,8 +3510.522491851695,134,25,10 +3610.8754703240456,137,21,8 +3711.178626275728,144,19,8 +3811.351965713598,118,15,13 +3911.512709104262,129,15,9 +4011.655886303876,112,17,13 +4112.017063229273,131,21,13 +4212.185567312904,87,10,15 +4312.787773183292,82,4,11 +4412.510211118717,87,1,23 +4512.6399449719165,91,0,26 +4612.90562623805,89,7,48 +4712.893276352519,87,6,45 +4813.994037593715,71,20,39 +4914.298293926317,48,24,36 +5014.867524983751,39,14,31 +5115.0970043221,38,20,32 +5215.096900113966,45,16,26 +5315.8238502744,46,13,19 +5415.9141792701985,48,13,19 +5515.996093450112,34,19,13 +5615.889371782633,48,22,22 +5716.6930976976655,46,31,32 +5817.299424400423,44,26,26 +5917.602687348175,40,26,30 +6017.897213233401,31,27,24 +6118.343633961529,35,14,41 +6218.58218845076,38,10,22 +6319.489906066127,38,7,27 +6419.341722859131,23,9,24 +6519.721253937668,29,8,28 +6620.157646757462,24,7,20 +6719.556658659775,27,4,32 +6820.246584850718,31,4,40 +6920.226938637144,36,4,47 +7020.482598935067,39,8,53 +7120.738540561613,41,17,36 +7220.937148243938,41,15,30 +7321.446071885893,41,13,24 +7421.204848497338,47,9,24 +7521.95382036663,30,11,28 +7622.976194370749,30,6,26 +7722.956166408864,28,3,16 +7823.042922278822,19,2,35 +7923.723193037357,13,2,51 +8023.638861277981,21,1,81 +8124.291964932402,18,0,121 +8224.639569604662,11,1,143 +8324.640640532465,10,0,129 +8424.490921795785,9,0,163 +8525.315060572482,6,5,159 +8625.438291000866,7,10,152 +8725.21900582938,3,13,139 +8826.069282293938,0,18,94 +8926.01949152394,0,34,97 +9027.084532898596,0,76,77 +9127.185705131458,0,187,52 +9227.272866283478,0,285,50 +9327.406823981708,0,375,50 +9427.510507791581,0,411,43 +9527.538969122767,5,449,31 +9627.539302339568,11,446,25 +9727.81379729904,11,386,17 +9828.140971235385,12,355,18 +9928.135098035435,13,306,17 +10028.356868304918,14,234,18 +10128.358710352713,22,239,13 +10228.418869615496,25,193,11 +10328.392807901959,24,170,8 +10428.536274821197,23,174,7 +10528.236734572074,28,129,7 +10628.387357829095,23,133,7 +10729.044458745173,26,124,7 +10828.909235495561,26,127,14 +10929.048393145002,36,109,6 +11029.256624782392,26,96,1 +11129.392279610382,48,77,0 +11230.085596320767,82,59,0 +11330.15276825258,105,62,0 +11430.303760616926,128,57,0 +11530.733560048353,138,53,0 +11631.015987975406,116,59,0 +11731.67178184373,111,34,0 +11832.05227692824,170,32,0 +11932.150680373605,240,26,0 +12032.28667173352,348,20,0 +12132.306507137087,475,14,0 +12232.398418664714,554,25,0 +12332.592035410167,634,20,0 +12432.5784455772,701,25,0 +12532.682239826037,737,30,0 +12632.711393061561,753,20,0 +12732.760596598911,700,21,2 +12832.821933468987,645,23,3 +12932.830371730473,611,23,2 +13033.017497161605,527,13,1 +13133.113787652184,472,13,11 +13233.052816138372,444,13,12 +13333.072809871357,408,7,22 +13433.207008951174,392,13,20 +13533.166189885675,351,7,15 +13633.191950223507,337,2,19 +13733.303665981759,338,1,29 +13833.386553456483,256,1,36 +13933.80347804562,261,0,45 +14033.965198565886,207,0,94 +14133.72936319437,189,0,138 +14234.14102054902,153,0,195 +14334.279913273806,143,0,245 +14434.423174287867,139,0,309 +14534.455951520646,110,0,353 +14634.405491380227,95,0,415 +14734.70546879825,82,0,504 +14834.687538407878,81,0,601 +14934.912022906952,62,0,655 +15034.975483864913,75,0,652 +15134.96292908238,72,0,716 +15235.101516376919,54,0,714 +15335.111859795328,48,0,752 +15435.1460890678,41,0,736 +15535.137332789269,37,0,861 +15635.316658645464,37,0,891 +15735.433420921963,35,0,893 +15835.368044922017,36,7,905 +15935.480969758435,32,8,900 +16035.50802815676,31,13,802 +16135.520694937855,30,9,763 +16235.552844509919,21,9,649 +16335.562753507887,17,9,630 +16435.669314282564,21,12,541 +16535.729268573454,16,16,536 +16635.73919028712,20,19,476 +16735.856394314203,23,23,428 +16835.61159428425,11,8,369 +16936.04527151302,12,16,355 +17035.914238601952,12,18,286 +17136.17209543873,11,27,312 +17236.36093366946,11,37,288 +17336.60586127413,17,42,259 +17436.809133746916,27,47,262 +17536.691290159386,16,50,238 +17636.87631752254,6,40,242 +17736.876818246248,7,36,215 +17837.040453945217,11,34,202 +17937.076678728336,7,33,168 +18037.380765659105,5,45,166 +18137.43253371791,6,44,153 +18237.443453547046,7,61,141 +18337.59563942835,9,59,132 +18437.63351359136,3,47,114 +18537.54143312436,12,41,83 +18637.708478411518,7,44,77 +18737.730608253114,11,37,57 +18837.28499776187,16,41,51 +18937.0796459162,17,45,56 +19038.098468481407,20,52,59 +19137.952118044956,21,39,46 +19237.49217238702,16,44,64 +19338.679967065727,13,35,67 +19439.5937613055,11,27,58 +19540.38589979148,7,26,42 +19640.22227467349,9,31,39 +19740.636068785345,8,47,43 +19840.64755259374,11,58,31 +19940.602574679233,11,66,33 +20040.72443050798,10,61,24 +20141.54570340322,17,77,24 +20241.675801315694,9,74,22 +20341.45711991326,7,78,29 +20442.057158850952,8,72,33 +20542.220369929648,7,79,34 +20642.124129837717,9,90,24 +20742.4981792959,26,81,30 +20842.7035344396,30,73,21 +20943.52399751663,44,90,21 +21042.921901197024,54,86,16 +21143.7717927901,52,72,19 +21243.819920549566,66,75,19 +21344.71316684686,59,85,19 +21444.81851140769,65,51,21 +21545.425825738123,56,49,17 +21645.937304563195,52,55,15 +21746.388608476114,48,55,14 +21846.478330926915,43,55,16 +21946.210657959313,40,53,18 +22046.594048411356,39,54,18 +22146.80175151657,32,33,15 +22247.388164776607,34,33,6 +22347.37687360637,55,39,3 +22447.942423679455,43,51,3 +22547.947820132606,64,42,4 +22647.320624242453,75,34,8 +22747.691628808283,58,36,9 +22848.162196675094,62,35,11 +22948.2412206233,73,42,2 +23049.988464978313,60,55,1 +23150.032757896617,64,52,2 +23250.407636832835,100,43,4 +23350.566073149275,121,42,10 +23450.31518966283,106,46,6 +23550.881262742467,117,43,4 +23651.048716060563,137,47,1 +23751.066470654656,140,44,5 +23851.227964019385,101,30,14 +23951.98289031135,79,20,23 +24051.819523368285,66,29,30 +24152.07904163031,58,20,34 +24253.07117685162,57,13,33 +24353.518774583797,63,9,38 +24454.562808877457,56,5,43 +24554.507029968823,57,4,26 +24655.132847447352,42,2,22 +24756.190245509817,38,2,28 +24856.198951864,43,1,37 +24956.127444847276,40,2,51 +25056.757839690512,35,1,66 +25156.828506014623,37,0,70 +25257.241080138363,29,0,146 +25357.662994967097,15,0,233 +25457.6992014166,14,0,298 +25557.96734281583,10,6,354 +25657.972387948455,11,8,322 +25758.09419340209,9,9,294 +25858.18222301933,10,9,265 +25957.816100510663,8,11,234 +26058.23825876695,15,29,218 +26158.27487764547,16,36,171 +26258.203359595547,18,38,136 +26358.521379623853,26,38,142 +26458.55394856564,23,30,126 +26557.844107120072,26,35,132 +26658.7475957175,21,32,136 +26758.987716471183,21,34,123 +26858.750286566024,26,20,116 +26959.04068549308,27,32,118 +27058.81857653427,21,30,106 +27158.70399400282,17,30,118 +27259.62797418525,14,26,112 +27359.656587528138,16,32,98 +27458.798542947367,5,37,99 +27559.28914978139,11,42,104 +27659.951240137583,22,34,119 +27760.36201502483,18,36,96 +27860.458753389437,19,28,76 +27960.908388276872,24,34,75 +28061.19499151892,26,34,46 +28161.109053125205,29,33,39 +28261.618333140552,22,26,41 +28360.903107651895,19,25,38 +28462.36381407543,16,13,28 +28561.769476748654,14,18,31 +28662.559554811796,11,13,39 +28761.51843362575,9,17,33 +28863.21974793743,4,21,31 +28963.146670984108,7,48,18 +29063.71535342858,17,67,19 +29163.890677228923,32,76,24 +29263.813201550194,34,65,28 +29364.60087336799,29,75,18 +29464.328317415955,34,74,19 +29565.019418996853,21,73,11 +29665.39613976109,27,59,3 +29765.601351954585,41,67,2 +29865.5207982654,39,63,1 +29966.39543995261,68,51,0 +30066.37898004625,94,45,1 +30166.8292056778,138,46,0 +30266.63801384113,201,41,0 +30366.961014780925,264,42,0 +30467.176545827955,359,36,0 +30567.186939573527,500,24,0 +30667.188414478227,545,27,0 +30767.496836265953,618,23,0 +30867.568422955184,645,19,0 +30967.57324710226,688,21,0 +31067.730006305956,768,28,0 +31167.753597242227,787,21,1 +31267.883614707513,826,15,0 +31367.90152130927,805,16,0 +31467.72968504187,805,25,0 +31567.967999288576,833,19,8 +31667.997214402305,759,19,19 +31767.97658271964,695,12,18 +31868.113033612826,656,11,16 +31968.070447936916,621,10,18 +32068.1393847244,544,13,19 +32168.164778316775,434,10,25 +32268.174370722612,428,8,30 +32368.09861727296,388,1,26 +32468.013597869558,340,1,41 +32568.187503436246,276,1,42 +32668.148533756837,265,0,73 +32768.217375301836,268,0,98 +32868.19917388746,232,0,120 +32968.838940812486,175,0,114 +33068.908127322386,150,0,121 +33169.19508017688,130,0,194 +33269.332817617105,130,0,246 +33369.38464066873,90,0,289 +33469.361370683626,104,0,384 +33569.34114436292,105,0,435 +33669.51385032953,94,0,464 +33769.528459983616,71,0,519 +33869.729928967274,69,0,622 +33969.77444132697,57,0,618 +34069.79740661193,46,0,609 +34169.86817093377,48,0,636 +34269.9679238556,32,0,645 +34369.89871048942,20,0,703 +34469.97490834967,18,0,639 +34570.038155997216,21,0,614 +34670.1030832296,18,0,700 +34770.066042451836,18,0,684 +34870.165017440246,17,0,671 +34970.24367293371,19,0,652 +35070.342900927644,19,0,653 +35170.31500724812,17,0,674 +35270.49707534653,13,0,685 +35370.66004862262,10,0,684 +35470.6481525108,19,3,683 +35570.47228579141,17,5,632 +35670.89152296186,5,16,544 +35771.17223356475,2,16,481 +35871.26704400036,2,24,505 +35971.230483654974,1,33,479 +36071.29100904177,1,55,421 +36171.45848888005,0,87,358 +36271.54654581023,1,90,346 +36371.57484449789,1,152,333 +36471.845714441195,0,170,296 +36572.18262086913,0,183,289 +36672.15790584913,0,212,275 +36772.157023231826,0,236,237 +36872.25159817118,0,292,240 +36972.27972272099,0,355,232 +37072.087893853706,0,377,226 +37172.33807535092,0,475,179 +37272.43850303034,0,533,173 +37372.56388985371,0,643,168 +37472.58001455527,0,689,140 +37572.68468113788,0,763,126 +37672.85500634077,0,857,102 +37772.902554347995,0,925,103 +37872.89673061782,0,896,87 +37972.896095110664,0,964,71 +38072.97873189999,0,922,65 +38173.02329280787,0,937,45 +38273.02681920163,0,989,51 +38372.83265744082,0,967,57 +38473.05308383648,0,966,48 +38572.998838657564,0,995,39 +38673.054752034885,0,1039,43 +38772.952151749625,0,1032,43 +38873.17100578963,0,1044,44 +38973.24972687144,0,1094,23 +39073.159363137034,9,987,28 +39173.236839834666,13,916,26 +39273.46002459392,21,840,25 +39373.42479476658,22,759,20 +39473.510445979875,18,620,13 +39573.49293760747,28,530,8 +39673.810588659886,29,513,12 +39773.84083535642,33,547,5 +39873.854793709295,37,464,3 +39974.0568476996,60,425,0 +40074.185498902894,45,402,0 +40174.1660989814,68,344,0 +40274.34792766874,84,289,0 +40374.5359765659,111,241,1 +40474.515374968636,143,231,1 +40574.46378591579,172,222,0 +40674.62414961122,220,207,0 +40774.91213220646,316,213,0 +40874.9128975766,439,190,0 +40974.95052764285,577,177,0 +41074.96574910084,622,146,0 +41175.014343418,637,127,0 +41275.03131651584,704,113,0 +41375.02812158011,716,96,0 +41475.174052592796,762,82,0 +41575.19652740498,826,90,0 +41675.11352076779,829,78,0 +41775.3278208018,872,82,0 +41875.37007670215,930,75,0 +41975.41708090427,964,62,0 +42075.444383723676,1042,57,0 +42175.39272936143,1100,65,0 +42275.47055227507,1141,53,0 +42375.468494753506,1099,48,0 +42475.48713623248,1103,36,0 +42575.531136145815,1099,46,0 +42675.53126459388,1096,32,0 +42775.53008063621,1145,15,0 +42875.579549323185,1043,7,0 +42975.57015364767,1125,1,2 +43075.61629458461,1046,0,64 +43175.65998147353,916,0,123 +43275.6563619109,897,0,191 +43375.74858817659,746,0,240 +43475.68199647167,708,0,276 +43575.78477686963,604,0,332 +43675.73742231557,573,0,401 +43775.8920075484,491,0,431 +43875.90066655083,415,0,502 +43975.82873190759,406,0,525 +44075.91763886026,393,0,627 +44176.00693739209,377,0,633 +44275.97064797488,319,0,673 +44376.073155611004,307,0,633 +44476.04154977589,265,0,658 +44576.047347880056,220,0,714 +44676.132095432724,179,0,716 +44776.20789381131,131,0,765 +44876.19555469188,125,0,786 +44976.20015939138,97,0,764 +45076.272705500916,79,0,803 +45176.26171815432,94,0,796 +45276.53725406935,81,0,818 +45376.509485508905,81,0,789 +45476.372465011395,63,0,777 +45576.59000922864,49,0,795 +45676.71553818004,37,8,870 +45776.75864321816,35,10,789 +45876.90939163348,33,7,715 +45976.967702147296,36,9,651 +46077.022713192826,23,10,598 +46176.988421913804,27,9,558 +46277.0725469175,26,8,493 +46377.15581230283,27,8,413 +46476.978287003796,25,8,355 +46577.29883052063,22,10,350 +46677.53062184545,5,6,309 +46777.37458462024,2,4,247 +46877.62611349149,1,5,224 +46977.62576695994,0,12,207 +47077.637509892294,0,30,228 +47178.158454311284,1,72,195 +47278.022304739905,1,94,186 +47378.24490501133,1,124,172 +47478.341346462774,0,145,178 +47578.453660343024,1,168,134 +47678.31957296403,0,189,126 +47778.571073470186,0,250,107 +47878.56425717938,0,301,93 +47978.84040220937,0,378,83 +48079.17439270704,0,460,61 +48179.14136325079,2,511,42 +48279.27426726966,7,495,49 +48379.293294201336,3,463,35 +48479.32420534836,8,416,42 +48579.29720514008,4,366,24 +48679.57954441958,9,344,28 +48779.59130230192,15,313,26 +48879.6715022994,18,290,11 +48979.85894147189,20,271,5 +49079.811644628535,26,267,3 +49179.86657913903,21,231,3 +49279.65399161342,50,194,0 +49380.02832106967,120,192,0 +49480.15593184564,167,203,0 +49579.82815302672,223,177,0 +49680.154042609,343,166,0 +49780.35421455383,429,142,0 +49880.35424331603,468,104,6 +49980.50936069484,487,95,9 +50080.510463392064,451,81,5 +50180.5386875397,452,69,8 +50280.5267616311,409,63,6 +50380.672222931054,365,51,7 +50480.43799271522,390,41,12 +50580.46316921008,313,43,11 +50680.82312212925,284,49,14 +50780.85254811854,253,41,15 +50880.932331318065,247,31,26 +50980.27115631493,248,29,13 +51081.33652011187,211,42,6 +51181.240300852995,223,41,1 +51281.257525194356,244,37,1 +51381.19813329679,278,29,1 +51481.422105421094,282,18,0 +51581.737079775485,293,14,1 +51681.81288244137,292,13,0 +51781.760078450105,298,17,1 +51881.87784883866,268,19,0 +51981.933199601954,349,17,0 +52082.13902929159,384,13,0 +52182.199439005446,446,2,0 +52282.24773787813,500,3,8 +52382.29680754707,468,0,39 +52482.32997048557,487,0,134 +52582.30556548886,474,0,167 +52682.424418378105,412,0,225 +52782.37374743871,357,0,319 +52882.47266693399,327,0,395 +52982.53016736079,294,0,464 +53082.57219448218,257,0,501 +53182.70772495185,223,0,532 +53282.63481702207,216,0,558 +53382.75446460995,232,0,567 +53482.803786390985,184,0,616 +53582.79837698153,172,0,638 +53682.80007738721,166,0,647 +53782.9840622171,152,0,705 +53882.95661714303,132,4,698 +53983.076258181565,174,8,620 +54083.175803111495,168,6,523 +54183.22872001067,140,12,457 +54283.710055922566,109,10,444 +54383.49126534866,105,7,422 +54483.881798650145,116,10,367 +54584.08390524762,108,14,321 +54684.07978216943,68,9,301 +54784.26093771734,70,10,288 +54884.16298904742,71,15,281 +54984.32318212749,64,13,210 +55084.646275954336,41,13,200 +55184.65464105604,37,20,192 +55284.575981514565,34,15,219 +55384.990049261425,40,26,203 +55485.06332469333,34,21,179 +55585.126196832796,33,22,139 +55685.42850805933,25,31,157 +55785.24418520562,33,21,156 +55885.5843047766,28,12,149 +55985.65941162739,19,9,145 +56085.20721691792,16,8,100 +56186.18190950562,10,7,113 +56286.41391953437,11,6,128 +56386.94789533891,11,3,120 +56486.860743071185,11,1,130 +56587.418731703794,11,0,147 +56687.31536691248,12,1,168 +56787.76656870909,13,0,185 +56887.61815066278,12,1,211 +56988.278288957525,6,8,210 +57088.31431485473,8,12,203 +57187.903545145185,7,13,186 +57288.67638687372,7,25,185 +57388.951504311546,5,21,157 +57488.96318793667,10,24,155 +57589.04660396707,3,30,169 +57689.17759830952,1,45,141 +57789.22817600563,1,55,142 +57889.444366407224,0,77,111 +57989.85041104072,0,106,115 +58089.99777564001,0,137,85 +58190.01727628042,0,195,74 +58290.22614458613,0,270,76 +58390.676182585994,0,356,74 +58490.90001547276,7,388,52 +58591.01283755387,4,419,63 +58691.135002033625,1,389,50 +58791.145110486636,0,421,53 +58891.01150609755,0,439,51 +58990.83852539622,4,533,46 +59091.254282535396,7,508,43 +59191.46104745853,3,504,50 +59291.58635905287,7,565,38 +59391.60782369305,7,491,39 +59491.82418449659,8,433,44 +59591.87885097491,5,396,42 +59692.089834105755,11,375,29 +59791.87644287786,17,366,30 +59892.404990175244,20,357,27 +59992.403831135285,15,351,15 +60092.39768372318,12,337,18 +60192.53732609703,19,313,20 +60292.72962294882,27,278,13 +60392.989978749116,28,263,19 +60492.989630715456,33,218,25 +60592.7263499386,38,197,21 +60693.213358524146,54,170,9 +60793.159285556256,50,142,5 +60893.30107192781,38,132,2 +60994.341147480205,44,144,0 +61094.91928439626,93,140,0 +61194.94548145197,155,120,0 +61294.956622585065,222,108,0 +61395.11385433507,273,110,0 +61494.96050602904,352,112,0 +61595.5310218978,384,94,0 +61695.48464854882,415,102,0 +61795.57392811677,456,90,0 +61895.47983258193,528,100,0 +61995.67643340064,632,89,0 +62095.711607210294,698,62,0 +62195.735477271126,759,48,0 +62295.83787723843,755,42,0 +62395.867023717896,919,32,0 +62495.86263806162,960,22,5 +62595.8723737297,951,19,10 +62695.92840242974,883,11,8 +62795.89331549765,822,10,18 +62896.02128549805,721,10,21 +62996.0265795647,649,11,20 +63096.03032267688,579,7,40 +63195.99518813253,552,1,44 +63296.10825538188,518,0,71 +63395.81648251823,458,1,92 +63496.3843147478,429,0,140 +63596.29154438921,375,1,134 +63696.44066311408,355,1,137 +63796.47156376697,342,0,162 +63896.72989927413,326,0,194 +63996.66187026119,294,0,242 +64096.944292734566,273,0,290 +64196.9835266383,290,0,395 +64296.97144799121,277,0,391 +64397.06516575655,270,0,366 +64497.127632869786,238,0,419 +64597.15001798481,206,0,495 +64697.17642591753,182,0,595 +64797.200423001916,164,3,648 +64897.120888155776,162,3,636 +64997.32626613069,117,8,628 +65097.30722296733,109,7,577 +65197.32502047289,111,7,503 +65297.31649430921,118,13,471 +65397.35848656337,104,11,439 +65497.464568765514,96,13,454 +65597.4519348394,84,4,367 +65697.67985494848,52,7,318 +65797.72124560633,34,4,287 +65898.13657922448,43,1,287 +65998.47612844195,25,0,275 +66098.08374337431,22,0,267 +66198.47590217383,15,0,309 +66298.7377109199,16,4,299 +66398.75809451201,11,10,303 +66498.72334265048,9,6,308 +66598.96975370022,9,10,274 +66699.36286993048,7,13,263 +66799.38867993947,6,19,232 +66899.58455990984,9,24,247 +66999.70007509606,10,19,197 +67099.39524614188,10,14,181 +67199.98889757357,10,8,180 +67300.15176740178,8,6,177 +67400.03306436358,9,12,167 +67500.1806072963,7,25,152 +67600.47926455986,5,22,122 +67700.45961016376,2,33,105 +67801.04983181355,0,36,102 +67901.28623336207,0,74,93 +68001.90659763617,0,93,107 +68102.02636082216,1,117,94 +68202.07774438453,1,149,83 +68301.89258853643,1,164,99 +68402.18901028184,0,158,86 +68501.8412264954,0,188,72 +68602.36448542499,0,249,52 +68702.29115077609,0,309,53 +68802.55575941417,0,443,65 +68902.74966508165,0,489,57 +69002.6524050068,0,540,41 +69102.74678317284,0,582,48 +69202.96647390889,0,592,47 +69302.85293680556,0,625,40 +69402.96978773472,0,674,40 +69503.12820373672,0,739,29 +69603.15541809393,4,779,14 +69703.16301578625,10,778,11 +69803.17430369536,9,671,14 +69903.2613652501,3,668,13 +70003.25841404256,1,627,13 +70103.43314455243,0,559,12 +70203.30253574478,0,502,13 +70303.55911284738,6,490,9 +70403.59524434003,16,421,14 +70503.76244994138,22,393,6 +70603.71612958751,30,339,11 +70703.78804607246,34,270,7 +70803.88784190372,47,265,9 +70903.9106962088,54,264,9 +71003.62606394643,49,241,13 +71104.82000913615,54,215,14 +71204.72311505368,53,210,9 +71304.97962079158,82,182,13 +71405.27249310179,72,200,9 +71505.30423621488,67,159,4 +71605.55027632492,91,147,0 +71705.4782077441,133,153,0 +71805.55546112364,242,130,0 +71905.65609144978,296,133,0 +72005.59532645429,399,115,0 +72105.55060995795,518,109,0 +72205.63787276656,553,90,0 +72305.80640585657,613,91,0 +72405.84787516852,692,64,0 +72505.84967617595,790,54,0 +72605.8482072258,815,53,0 +72705.82060981948,867,49,0 +72805.91279451242,865,52,0 +72905.92902757225,828,40,0 +73005.89526038276,890,38,0 +73106.00381380515,986,27,0 +73205.99711340977,1067,23,0 +73305.99540933105,991,25,5 +73406.03760180037,949,33,5 +73505.87863719928,827,28,1 +73606.08840631101,833,25,0 +73706.14664442772,772,29,0 +73806.19933952882,803,26,10 +73906.13595028293,764,29,8 +74006.2946032621,642,23,8 +74106.33023116546,561,18,10 +74206.15835610432,525,26,15 +74306.39519959445,519,28,23 +74406.43883199374,458,24,16 +74506.43518330838,392,24,11 +74606.65734244151,378,23,7 +74706.2039118052,307,19,7 +74806.86935568127,337,19,9 +74906.84394647408,324,19,10 +75007.06695554106,308,23,10 +75107.06150640869,284,15,12 +75206.96795901856,236,14,25 +75307.78090538707,215,11,15 +75408.09346313404,200,14,14 +75508.13000043346,156,11,25 +75608.78882093409,151,8,31 +75708.96101266811,140,10,23 +75809.00979900936,114,11,27 +75908.92968896852,119,16,31 +76008.55497499541,99,27,18 +76109.56693712724,96,18,30 +76209.82583186663,80,20,36 +76309.75377013157,61,14,22 +76410.1453768141,79,8,23 +76510.03537247989,65,7,26 +76610.96363255633,64,8,14 +76710.61425661572,69,4,21 +76810.83658474783,61,5,31 +76911.26356822933,63,2,42 +77011.8210596954,50,5,44 +77111.51556628614,41,4,51 +77212.51989364951,32,5,62 +77312.80758209426,18,6,74 +77412.5050668241,15,2,95 +77513.13967360399,19,2,104 +77612.45447184521,17,1,121 +77713.86699776394,19,0,122 +77814.34680186318,18,0,172 +77914.43887709791,16,0,191 +78014.4743481833,18,0,244 +78114.38903074227,23,0,327 +78214.63978554538,23,0,375 +78314.68119324412,25,0,420 +78414.6602591375,21,0,478 +78514.94226263084,20,0,418 +78615.02995665568,21,0,475 +78715.02840392849,17,0,497 +78815.12055260211,12,4,540 +78915.07612746765,5,17,545 +79015.1321108846,1,11,553 +79115.27797204738,0,24,491 +79215.27553401749,0,40,420 +79315.48515679842,0,94,385 +79415.62347402253,0,167,295 +79515.59792917052,0,237,257 +79615.78715704946,0,306,290 +79715.85726122675,0,410,253 +79815.88931303694,0,532,246 +79916.00120900353,0,656,194 +80015.99035064143,0,712,201 +80116.01445176269,0,773,156 +80216.0816953415,0,769,131 +80316.12314208863,0,798,135 +80416.16997070963,0,793,120 +80516.13805713052,0,881,117 +80616.26910313788,0,874,121 +80716.27795228899,0,834,115 +80816.27489059065,0,850,116 +80916.29557082002,0,873,100 +81016.28473277869,0,918,117 +81116.39606517646,0,904,104 +81216.34544273939,0,907,92 +81316.41807699358,0,916,80 +81416.41750233306,0,877,69 +81516.39234132023,0,908,74 +81616.54528265247,0,822,64 +81716.61773485588,0,807,61 +81816.41526521507,0,771,57 +81916.67754731954,0,796,66 +82016.71152816349,0,838,69 +82116.75141785863,0,981,55 +82216.80802564441,2,944,48 +82316.83341411156,6,947,45 +82416.95642959689,12,909,38 +82517.0702278602,16,844,31 +82617.08436605305,18,745,31 +82717.0490826536,15,625,27 +82817.23549896885,21,587,20 +82917.49820944773,29,504,19 +83017.67605432222,22,429,15 +83117.86068137111,23,359,13 +83217.95457107744,27,324,11 +83318.05613617065,41,305,12 +83418.1142919284,38,295,8 +83518.36160991112,35,279,5 +83618.35529041376,40,270,0 +83718.45610365778,110,232,0 +83818.5317516379,220,217,0 +83918.98578977553,284,194,0 +84019.2016201548,394,164,0 +84119.32885929808,446,150,0 +84219.35257436802,592,152,0 +84319.43176187773,663,144,0 +84419.43559080559,711,120,0 +84519.46533177218,712,96,0 +84619.68925680415,690,66,0 +84719.68103852487,740,54,0 +84819.59613284511,746,46,5 +84919.67494336671,766,44,11 +85019.75602554268,768,46,7 +85119.79912416471,664,45,8 +85219.8040932813,633,43,10 +85320.03876908924,617,27,8 +85420.05984979247,621,24,11 +85520.08324940146,548,20,9 +85620.36314211923,480,20,10 +85720.54159769621,426,15,4 +85820.585263794,402,12,3 +85920.99154968237,396,7,10 +86021.09591265483,342,8,6 +86121.0824375159,290,4,19 +86221.18316414606,281,8,32 +86321.22326010255,231,10,38 +86421.5422463905,204,5,51 +86521.63518510113,178,7,48 +86621.80919648398,158,10,53 +86721.87487472004,148,11,57 +86822.08272818748,116,13,57 +86922.30273230183,114,8,42 +87022.5339271133,102,14,48 +87122.96718301288,87,17,43 +87223.27509430048,83,16,43 +87323.48843359452,54,13,35 +87423.59641881639,43,8,34 +87523.65543758041,38,19,29 +87624.63072180038,18,20,21 +87724.10678194097,10,27,17 +87825.12792588276,7,18,17 +87925.34194636527,2,28,15 +88025.3215713608,1,37,22 +88125.53092739418,0,69,25 +88226.08586047859,0,126,22 +88326.42094795793,5,131,8 +88426.34539304313,11,129,2 +88526.47611328126,12,147,0 +88626.60624811308,44,138,0 +88726.88652127588,79,152,0 +88826.99287850539,181,132,0 +88926.74579364176,286,100,0 +89027.12898548257,395,76,0 +89127.2262570268,496,79,0 +89227.39224496929,613,62,0 +89327.5764532606,707,39,0 +89427.5828154209,766,29,3 +89527.65901095723,832,44,4 +89627.75420484837,804,39,6 +89727.79545237485,730,29,14 +89827.86471334014,731,27,13 +89927.84907691223,684,22,16 +90027.91947316933,577,32,19 +90128.07608809034,503,31,15 +90228.17872389781,445,31,14 +90328.21188550263,403,36,16 +90428.1291023666,378,21,14 +90528.2985934436,307,24,19 +90628.52793876242,283,24,21 +90728.91555456909,293,20,18 +90829.31922011991,260,25,18 +90929.11229508687,240,12,22 +91029.42919604381,221,11,21 +91129.6651150286,200,9,23 +91229.9798606634,169,4,23 +91330.07382391793,142,8,29 +91430.06053899572,129,15,26 +91530.442349184,145,21,36 +91629.77142923551,137,20,25 +91730.75410881138,130,26,30 +91830.54474896495,101,22,29 +91931.27653025475,90,26,38 +92031.24941923474,66,20,33 +92131.80582702516,59,21,36 +92231.84918469883,51,17,33 +92332.7171869947,69,9,30 +92433.01205161064,68,2,19 +92533.05145093836,48,2,18 +92633.27518756292,45,1,38 +92733.63400322679,38,0,72 +92833.56838312956,27,0,149 +92934.11172254264,20,0,218 +93034.24468658156,17,0,272 +93134.27884595437,21,0,312 +93234.46018986708,18,0,341 +93334.46960294049,15,0,352 +93434.38034752884,18,8,393 +93534.6413955782,26,5,415 +93634.58677713489,14,4,368 +93735.18614384836,7,0,348 +93834.8101994181,15,0,306 +93935.33320656912,11,0,323 +94035.49055851092,13,0,381 +94135.57470451835,16,0,402 +94235.63744368734,8,0,438 +94335.79260647867,11,0,509 +94435.91803114804,12,3,507 +94535.87476736112,6,8,518 +94636.04037402314,4,11,462 +94736.19324433502,2,22,441 +94836.0399011328,1,21,420 +94936.1774754013,0,61,348 +95036.30989765112,0,131,323 +95136.36388024177,0,212,332 +95236.5029078477,0,306,282 +95336.59523099817,0,411,233 +95436.66969556722,0,409,220 +95536.62713394579,0,413,168 +95636.69242826941,0,487,172 +95736.71897928047,0,541,166 +95836.8964542962,0,570,138 +95936.95153883634,0,626,151 +96036.92003403466,0,606,140 +96137.0642105573,0,650,124 +96237.05418360743,0,626,102 +96337.14829687006,0,766,76 +96437.16443472721,0,768,73 +96537.19038789897,0,778,69 +96637.4896810076,0,769,53 +96737.62614815135,0,768,36 +96837.65228685043,0,848,38 +96937.6631880946,0,918,36 +97037.75098867327,0,933,32 +97137.77855310103,0,984,36 +97237.70631498922,0,945,25 +97337.92680618768,0,913,18 +97437.9802874181,6,920,13 +97538.061325625,2,844,14 +97638.09287457938,0,843,24 +97738.09362194444,10,765,13 +97838.10762253772,13,696,14 +97938.11650486609,15,615,8 +98038.29062990371,16,628,6 +98138.17986806354,7,538,7 +98238.16353181467,7,474,10 +98338.39708899318,15,422,11 +98438.54009905795,20,399,14 +98538.65424840078,15,348,7 +98638.31097327484,25,273,7 +98738.67973370303,25,227,4 +98838.71480995565,30,179,2 +98938.6417284288,33,146,2 +99038.91866334192,35,121,1 +99138.93995162165,76,97,0 +99239.53012677889,159,70,0 +99339.16676383071,264,59,0 +99440.02962579156,348,49,0 +99540.29471426392,423,46,0 +99640.38453125526,476,37,0 +99740.38438157868,516,34,0 +99840.87804343985,589,32,0 +99940.8490129389,655,22,0 +99999.95161541106,704,17,0 +99999.99999999952,704,17,0 \ No newline at end of file diff --git a/ClassicGEC/Examples/Results/repressilator_similar.csv b/ClassicGEC/Examples/Results/repressilator_similar.csv new file mode 100644 index 0000000..391973d --- /dev/null +++ b/ClassicGEC/Examples/Results/repressilator_similar.csv @@ -0,0 +1,1002 @@ +Time,A,B,C +0,0,0,0 +103.91123546487174,26,23,0 +205.27497329774786,83,43,3 +305.4403636186551,129,52,10 +405.5268628679468,125,40,8 +505.946195422491,132,31,13 +606.1653517484071,116,16,8 +706.5593799409236,109,11,16 +806.4436884368034,111,12,11 +906.1706275152397,92,11,11 +1007.1289118149933,79,20,10 +1107.2566430564082,74,22,11 +1206.4317642205658,76,16,18 +1307.559537432179,52,12,19 +1407.992867688328,43,17,14 +1508.050058060913,38,24,8 +1607.7964023715658,52,19,14 +1707.735753118315,64,12,13 +1808.3985220644756,49,14,8 +1908.0812603885245,45,18,14 +2008.7077319008217,39,14,29 +2108.3821871561618,42,12,53 +2209.159427401333,32,5,47 +2309.084014973059,34,0,57 +2409.4064188862876,38,0,85 +2509.560600107608,35,0,110 +2609.8409607601884,34,3,109 +2709.7534041431445,31,1,97 +2810.016420291013,30,0,102 +2909.8411650178823,23,0,149 +3009.7826933059728,17,3,156 +3110.385260909921,22,8,135 +3210.2566329071733,20,10,146 +3310.2905471651557,13,9,152 +3410.257324609446,18,8,148 +3510.522491851695,25,10,134 +3610.8754703240456,21,8,137 +3711.178626275728,19,8,144 +3811.351965713598,15,13,118 +3911.512709104262,15,9,129 +4011.655886303876,17,13,112 +4112.017063229273,21,13,131 +4212.185567312904,10,15,87 +4312.787773183292,4,11,82 +4412.510211118717,1,23,87 +4512.6399449719165,0,26,91 +4612.90562623805,7,48,89 +4712.893276352519,6,45,87 +4813.994037593715,20,39,71 +4914.298293926317,24,36,48 +5014.867524983751,14,31,39 +5115.0970043221,20,32,38 +5215.096900113966,16,26,45 +5315.8238502744,13,19,46 +5415.9141792701985,13,19,48 +5515.996093450112,19,13,34 +5615.889371782633,22,22,48 +5716.6930976976655,31,32,46 +5817.299424400423,26,26,44 +5917.602687348175,26,30,40 +6017.897213233401,27,24,31 +6118.343633961529,14,41,35 +6218.58218845076,10,22,38 +6319.489906066127,7,27,38 +6419.341722859131,9,24,23 +6519.721253937668,8,28,29 +6620.157646757462,7,20,24 +6719.556658659775,4,32,27 +6820.246584850718,4,40,31 +6920.226938637144,4,47,36 +7020.482598935067,8,53,39 +7120.738540561613,17,36,41 +7220.937148243938,15,30,41 +7321.446071885893,13,24,41 +7421.204848497338,9,24,47 +7521.95382036663,11,28,30 +7622.976194370749,6,26,30 +7722.956166408864,3,16,28 +7823.042922278822,2,35,19 +7923.723193037357,2,51,13 +8023.638861277981,1,81,21 +8124.291964932402,0,121,18 +8224.639569604662,1,143,11 +8324.640640532465,0,129,10 +8424.490921795785,0,163,9 +8525.315060572482,5,159,6 +8625.438291000866,10,152,7 +8725.21900582938,13,139,3 +8826.069282293938,18,94,0 +8926.01949152394,34,97,0 +9027.084532898596,76,77,0 +9127.185705131458,187,52,0 +9227.272866283478,285,50,0 +9327.406823981708,375,50,0 +9427.510507791581,411,43,0 +9527.538969122767,449,31,5 +9627.539302339568,446,25,11 +9727.81379729904,386,17,11 +9828.140971235385,355,18,12 +9928.135098035435,306,17,13 +10028.356868304918,234,18,14 +10128.358710352713,239,13,22 +10228.418869615496,193,11,25 +10328.392807901959,170,8,24 +10428.536274821197,174,7,23 +10528.236734572074,129,7,28 +10628.387357829095,133,7,23 +10729.044458745173,124,7,26 +10828.909235495561,127,14,26 +10929.048393145002,109,6,36 +11029.256624782392,96,1,26 +11129.392279610382,77,0,48 +11230.085596320767,59,0,82 +11330.15276825258,62,0,105 +11430.303760616926,57,0,128 +11530.733560048353,53,0,138 +11631.015987975406,59,0,116 +11731.67178184373,34,0,111 +11832.05227692824,32,0,170 +11932.150680373605,26,0,240 +12032.28667173352,20,0,348 +12132.306507137087,14,0,475 +12232.398418664714,25,0,554 +12332.592035410167,20,0,634 +12432.5784455772,25,0,701 +12532.682239826037,30,0,737 +12632.711393061561,20,0,753 +12732.760596598911,21,2,700 +12832.821933468987,23,3,645 +12932.830371730473,23,2,611 +13033.017497161605,13,1,527 +13133.113787652184,13,11,472 +13233.052816138372,13,12,444 +13333.072809871357,7,22,408 +13433.207008951174,13,20,392 +13533.166189885675,7,15,351 +13633.191950223507,2,19,337 +13733.303665981759,1,29,338 +13833.386553456483,1,36,256 +13933.80347804562,0,45,261 +14033.965198565886,0,94,207 +14133.72936319437,0,138,189 +14234.14102054902,0,195,153 +14334.279913273806,0,245,143 +14434.423174287867,0,309,139 +14534.455951520646,0,353,110 +14634.405491380227,0,415,95 +14734.70546879825,0,504,82 +14834.687538407878,0,601,81 +14934.912022906952,0,655,62 +15034.975483864913,0,652,75 +15134.96292908238,0,716,72 +15235.101516376919,0,714,54 +15335.111859795328,0,752,48 +15435.1460890678,0,736,41 +15535.137332789269,0,861,37 +15635.316658645464,0,891,37 +15735.433420921963,0,893,35 +15835.368044922017,7,905,36 +15935.480969758435,8,900,32 +16035.50802815676,13,802,31 +16135.520694937855,9,763,30 +16235.552844509919,9,649,21 +16335.562753507887,9,630,17 +16435.669314282564,12,541,21 +16535.729268573454,16,536,16 +16635.73919028712,19,476,20 +16735.856394314203,23,428,23 +16835.61159428425,8,369,11 +16936.04527151302,16,355,12 +17035.914238601952,18,286,12 +17136.17209543873,27,312,11 +17236.36093366946,37,288,11 +17336.60586127413,42,259,17 +17436.809133746916,47,262,27 +17536.691290159386,50,238,16 +17636.87631752254,40,242,6 +17736.876818246248,36,215,7 +17837.040453945217,34,202,11 +17937.076678728336,33,168,7 +18037.380765659105,45,166,5 +18137.43253371791,44,153,6 +18237.443453547046,61,141,7 +18337.59563942835,59,132,9 +18437.63351359136,47,114,3 +18537.54143312436,41,83,12 +18637.708478411518,44,77,7 +18737.730608253114,37,57,11 +18837.28499776187,41,51,16 +18937.0796459162,45,56,17 +19038.098468481407,52,59,20 +19137.952118044956,39,46,21 +19237.49217238702,44,64,16 +19338.679967065727,35,67,13 +19439.5937613055,27,58,11 +19540.38589979148,26,42,7 +19640.22227467349,31,39,9 +19740.636068785345,47,43,8 +19840.64755259374,58,31,11 +19940.602574679233,66,33,11 +20040.72443050798,61,24,10 +20141.54570340322,77,24,17 +20241.675801315694,74,22,9 +20341.45711991326,78,29,7 +20442.057158850952,72,33,8 +20542.220369929648,79,34,7 +20642.124129837717,90,24,9 +20742.4981792959,81,30,26 +20842.7035344396,73,21,30 +20943.52399751663,90,21,44 +21042.921901197024,86,16,54 +21143.7717927901,72,19,52 +21243.819920549566,75,19,66 +21344.71316684686,85,19,59 +21444.81851140769,51,21,65 +21545.425825738123,49,17,56 +21645.937304563195,55,15,52 +21746.388608476114,55,14,48 +21846.478330926915,55,16,43 +21946.210657959313,53,18,40 +22046.594048411356,54,18,39 +22146.80175151657,33,15,32 +22247.388164776607,33,6,34 +22347.37687360637,39,3,55 +22447.942423679455,51,3,43 +22547.947820132606,42,4,64 +22647.320624242453,34,8,75 +22747.691628808283,36,9,58 +22848.162196675094,35,11,62 +22948.2412206233,42,2,73 +23049.988464978313,55,1,60 +23150.032757896617,52,2,64 +23250.407636832835,43,4,100 +23350.566073149275,42,10,121 +23450.31518966283,46,6,106 +23550.881262742467,43,4,117 +23651.048716060563,47,1,137 +23751.066470654656,44,5,140 +23851.227964019385,30,14,101 +23951.98289031135,20,23,79 +24051.819523368285,29,30,66 +24152.07904163031,20,34,58 +24253.07117685162,13,33,57 +24353.518774583797,9,38,63 +24454.562808877457,5,43,56 +24554.507029968823,4,26,57 +24655.132847447352,2,22,42 +24756.190245509817,2,28,38 +24856.198951864,1,37,43 +24956.127444847276,2,51,40 +25056.757839690512,1,66,35 +25156.828506014623,0,70,37 +25257.241080138363,0,146,29 +25357.662994967097,0,233,15 +25457.6992014166,0,298,14 +25557.96734281583,6,354,10 +25657.972387948455,8,322,11 +25758.09419340209,9,294,9 +25858.18222301933,9,265,10 +25957.816100510663,11,234,8 +26058.23825876695,29,218,15 +26158.27487764547,36,171,16 +26258.203359595547,38,136,18 +26358.521379623853,38,142,26 +26458.55394856564,30,126,23 +26557.844107120072,35,132,26 +26658.7475957175,32,136,21 +26758.987716471183,34,123,21 +26858.750286566024,20,116,26 +26959.04068549308,32,118,27 +27058.81857653427,30,106,21 +27158.70399400282,30,118,17 +27259.62797418525,26,112,14 +27359.656587528138,32,98,16 +27458.798542947367,37,99,5 +27559.28914978139,42,104,11 +27659.951240137583,34,119,22 +27760.36201502483,36,96,18 +27860.458753389437,28,76,19 +27960.908388276872,34,75,24 +28061.19499151892,34,46,26 +28161.109053125205,33,39,29 +28261.618333140552,26,41,22 +28360.903107651895,25,38,19 +28462.36381407543,13,28,16 +28561.769476748654,18,31,14 +28662.559554811796,13,39,11 +28761.51843362575,17,33,9 +28863.21974793743,21,31,4 +28963.146670984108,48,18,7 +29063.71535342858,67,19,17 +29163.890677228923,76,24,32 +29263.813201550194,65,28,34 +29364.60087336799,75,18,29 +29464.328317415955,74,19,34 +29565.019418996853,73,11,21 +29665.39613976109,59,3,27 +29765.601351954585,67,2,41 +29865.5207982654,63,1,39 +29966.39543995261,51,0,68 +30066.37898004625,45,1,94 +30166.8292056778,46,0,138 +30266.63801384113,41,0,201 +30366.961014780925,42,0,264 +30467.176545827955,36,0,359 +30567.186939573527,24,0,500 +30667.188414478227,27,0,545 +30767.496836265953,23,0,618 +30867.568422955184,19,0,645 +30967.57324710226,21,0,688 +31067.730006305956,28,0,768 +31167.753597242227,21,1,787 +31267.883614707513,15,0,826 +31367.90152130927,16,0,805 +31467.72968504187,25,0,805 +31567.967999288576,19,8,833 +31667.997214402305,19,19,759 +31767.97658271964,12,18,695 +31868.113033612826,11,16,656 +31968.070447936916,10,18,621 +32068.1393847244,13,19,544 +32168.164778316775,10,25,434 +32268.174370722612,8,30,428 +32368.09861727296,1,26,388 +32468.013597869558,1,41,340 +32568.187503436246,1,42,276 +32668.148533756837,0,73,265 +32768.217375301836,0,98,268 +32868.19917388746,0,120,232 +32968.838940812486,0,114,175 +33068.908127322386,0,121,150 +33169.19508017688,0,194,130 +33269.332817617105,0,246,130 +33369.38464066873,0,289,90 +33469.361370683626,0,384,104 +33569.34114436292,0,435,105 +33669.51385032953,0,464,94 +33769.528459983616,0,519,71 +33869.729928967274,0,622,69 +33969.77444132697,0,618,57 +34069.79740661193,0,609,46 +34169.86817093377,0,636,48 +34269.9679238556,0,645,32 +34369.89871048942,0,703,20 +34469.97490834967,0,639,18 +34570.038155997216,0,614,21 +34670.1030832296,0,700,18 +34770.066042451836,0,684,18 +34870.165017440246,0,671,17 +34970.24367293371,0,652,19 +35070.342900927644,0,653,19 +35170.31500724812,0,674,17 +35270.49707534653,0,685,13 +35370.66004862262,0,684,10 +35470.6481525108,3,683,19 +35570.47228579141,5,632,17 +35670.89152296186,16,544,5 +35771.17223356475,16,481,2 +35871.26704400036,24,505,2 +35971.230483654974,33,479,1 +36071.29100904177,55,421,1 +36171.45848888005,87,358,0 +36271.54654581023,90,346,1 +36371.57484449789,152,333,1 +36471.845714441195,170,296,0 +36572.18262086913,183,289,0 +36672.15790584913,212,275,0 +36772.157023231826,236,237,0 +36872.25159817118,292,240,0 +36972.27972272099,355,232,0 +37072.087893853706,377,226,0 +37172.33807535092,475,179,0 +37272.43850303034,533,173,0 +37372.56388985371,643,168,0 +37472.58001455527,689,140,0 +37572.68468113788,763,126,0 +37672.85500634077,857,102,0 +37772.902554347995,925,103,0 +37872.89673061782,896,87,0 +37972.896095110664,964,71,0 +38072.97873189999,922,65,0 +38173.02329280787,937,45,0 +38273.02681920163,989,51,0 +38372.83265744082,967,57,0 +38473.05308383648,966,48,0 +38572.998838657564,995,39,0 +38673.054752034885,1039,43,0 +38772.952151749625,1032,43,0 +38873.17100578963,1044,44,0 +38973.24972687144,1094,23,0 +39073.159363137034,987,28,9 +39173.236839834666,916,26,13 +39273.46002459392,840,25,21 +39373.42479476658,759,20,22 +39473.510445979875,620,13,18 +39573.49293760747,530,8,28 +39673.810588659886,513,12,29 +39773.84083535642,547,5,33 +39873.854793709295,464,3,37 +39974.0568476996,425,0,60 +40074.185498902894,402,0,45 +40174.1660989814,344,0,68 +40274.34792766874,289,0,84 +40374.5359765659,241,1,111 +40474.515374968636,231,1,143 +40574.46378591579,222,0,172 +40674.62414961122,207,0,220 +40774.91213220646,213,0,316 +40874.9128975766,190,0,439 +40974.95052764285,177,0,577 +41074.96574910084,146,0,622 +41175.014343418,127,0,637 +41275.03131651584,113,0,704 +41375.02812158011,96,0,716 +41475.174052592796,82,0,762 +41575.19652740498,90,0,826 +41675.11352076779,78,0,829 +41775.3278208018,82,0,872 +41875.37007670215,75,0,930 +41975.41708090427,62,0,964 +42075.444383723676,57,0,1042 +42175.39272936143,65,0,1100 +42275.47055227507,53,0,1141 +42375.468494753506,48,0,1099 +42475.48713623248,36,0,1103 +42575.531136145815,46,0,1099 +42675.53126459388,32,0,1096 +42775.53008063621,15,0,1145 +42875.579549323185,7,0,1043 +42975.57015364767,1,2,1125 +43075.61629458461,0,64,1046 +43175.65998147353,0,123,916 +43275.6563619109,0,191,897 +43375.74858817659,0,240,746 +43475.68199647167,0,276,708 +43575.78477686963,0,332,604 +43675.73742231557,0,401,573 +43775.8920075484,0,431,491 +43875.90066655083,0,502,415 +43975.82873190759,0,525,406 +44075.91763886026,0,627,393 +44176.00693739209,0,633,377 +44275.97064797488,0,673,319 +44376.073155611004,0,633,307 +44476.04154977589,0,658,265 +44576.047347880056,0,714,220 +44676.132095432724,0,716,179 +44776.20789381131,0,765,131 +44876.19555469188,0,786,125 +44976.20015939138,0,764,97 +45076.272705500916,0,803,79 +45176.26171815432,0,796,94 +45276.53725406935,0,818,81 +45376.509485508905,0,789,81 +45476.372465011395,0,777,63 +45576.59000922864,0,795,49 +45676.71553818004,8,870,37 +45776.75864321816,10,789,35 +45876.90939163348,7,715,33 +45976.967702147296,9,651,36 +46077.022713192826,10,598,23 +46176.988421913804,9,558,27 +46277.0725469175,8,493,26 +46377.15581230283,8,413,27 +46476.978287003796,8,355,25 +46577.29883052063,10,350,22 +46677.53062184545,6,309,5 +46777.37458462024,4,247,2 +46877.62611349149,5,224,1 +46977.62576695994,12,207,0 +47077.637509892294,30,228,0 +47178.158454311284,72,195,1 +47278.022304739905,94,186,1 +47378.24490501133,124,172,1 +47478.341346462774,145,178,0 +47578.453660343024,168,134,1 +47678.31957296403,189,126,0 +47778.571073470186,250,107,0 +47878.56425717938,301,93,0 +47978.84040220937,378,83,0 +48079.17439270704,460,61,0 +48179.14136325079,511,42,2 +48279.27426726966,495,49,7 +48379.293294201336,463,35,3 +48479.32420534836,416,42,8 +48579.29720514008,366,24,4 +48679.57954441958,344,28,9 +48779.59130230192,313,26,15 +48879.6715022994,290,11,18 +48979.85894147189,271,5,20 +49079.811644628535,267,3,26 +49179.86657913903,231,3,21 +49279.65399161342,194,0,50 +49380.02832106967,192,0,120 +49480.15593184564,203,0,167 +49579.82815302672,177,0,223 +49680.154042609,166,0,343 +49780.35421455383,142,0,429 +49880.35424331603,104,6,468 +49980.50936069484,95,9,487 +50080.510463392064,81,5,451 +50180.5386875397,69,8,452 +50280.5267616311,63,6,409 +50380.672222931054,51,7,365 +50480.43799271522,41,12,390 +50580.46316921008,43,11,313 +50680.82312212925,49,14,284 +50780.85254811854,41,15,253 +50880.932331318065,31,26,247 +50980.27115631493,29,13,248 +51081.33652011187,42,6,211 +51181.240300852995,41,1,223 +51281.257525194356,37,1,244 +51381.19813329679,29,1,278 +51481.422105421094,18,0,282 +51581.737079775485,14,1,293 +51681.81288244137,13,0,292 +51781.760078450105,17,1,298 +51881.87784883866,19,0,268 +51981.933199601954,17,0,349 +52082.13902929159,13,0,384 +52182.199439005446,2,0,446 +52282.24773787813,3,8,500 +52382.29680754707,0,39,468 +52482.32997048557,0,134,487 +52582.30556548886,0,167,474 +52682.424418378105,0,225,412 +52782.37374743871,0,319,357 +52882.47266693399,0,395,327 +52982.53016736079,0,464,294 +53082.57219448218,0,501,257 +53182.70772495185,0,532,223 +53282.63481702207,0,558,216 +53382.75446460995,0,567,232 +53482.803786390985,0,616,184 +53582.79837698153,0,638,172 +53682.80007738721,0,647,166 +53782.9840622171,0,705,152 +53882.95661714303,4,698,132 +53983.076258181565,8,620,174 +54083.175803111495,6,523,168 +54183.22872001067,12,457,140 +54283.710055922566,10,444,109 +54383.49126534866,7,422,105 +54483.881798650145,10,367,116 +54584.08390524762,14,321,108 +54684.07978216943,9,301,68 +54784.26093771734,10,288,70 +54884.16298904742,15,281,71 +54984.32318212749,13,210,64 +55084.646275954336,13,200,41 +55184.65464105604,20,192,37 +55284.575981514565,15,219,34 +55384.990049261425,26,203,40 +55485.06332469333,21,179,34 +55585.126196832796,22,139,33 +55685.42850805933,31,157,25 +55785.24418520562,21,156,33 +55885.5843047766,12,149,28 +55985.65941162739,9,145,19 +56085.20721691792,8,100,16 +56186.18190950562,7,113,10 +56286.41391953437,6,128,11 +56386.94789533891,3,120,11 +56486.860743071185,1,130,11 +56587.418731703794,0,147,11 +56687.31536691248,1,168,12 +56787.76656870909,0,185,13 +56887.61815066278,1,211,12 +56988.278288957525,8,210,6 +57088.31431485473,12,203,8 +57187.903545145185,13,186,7 +57288.67638687372,25,185,7 +57388.951504311546,21,157,5 +57488.96318793667,24,155,10 +57589.04660396707,30,169,3 +57689.17759830952,45,141,1 +57789.22817600563,55,142,1 +57889.444366407224,77,111,0 +57989.85041104072,106,115,0 +58089.99777564001,137,85,0 +58190.01727628042,195,74,0 +58290.22614458613,270,76,0 +58390.676182585994,356,74,0 +58490.90001547276,388,52,7 +58591.01283755387,419,63,4 +58691.135002033625,389,50,1 +58791.145110486636,421,53,0 +58891.01150609755,439,51,0 +58990.83852539622,533,46,4 +59091.254282535396,508,43,7 +59191.46104745853,504,50,3 +59291.58635905287,565,38,7 +59391.60782369305,491,39,7 +59491.82418449659,433,44,8 +59591.87885097491,396,42,5 +59692.089834105755,375,29,11 +59791.87644287786,366,30,17 +59892.404990175244,357,27,20 +59992.403831135285,351,15,15 +60092.39768372318,337,18,12 +60192.53732609703,313,20,19 +60292.72962294882,278,13,27 +60392.989978749116,263,19,28 +60492.989630715456,218,25,33 +60592.7263499386,197,21,38 +60693.213358524146,170,9,54 +60793.159285556256,142,5,50 +60893.30107192781,132,2,38 +60994.341147480205,144,0,44 +61094.91928439626,140,0,93 +61194.94548145197,120,0,155 +61294.956622585065,108,0,222 +61395.11385433507,110,0,273 +61494.96050602904,112,0,352 +61595.5310218978,94,0,384 +61695.48464854882,102,0,415 +61795.57392811677,90,0,456 +61895.47983258193,100,0,528 +61995.67643340064,89,0,632 +62095.711607210294,62,0,698 +62195.735477271126,48,0,759 +62295.83787723843,42,0,755 +62395.867023717896,32,0,919 +62495.86263806162,22,5,960 +62595.8723737297,19,10,951 +62695.92840242974,11,8,883 +62795.89331549765,10,18,822 +62896.02128549805,10,21,721 +62996.0265795647,11,20,649 +63096.03032267688,7,40,579 +63195.99518813253,1,44,552 +63296.10825538188,0,71,518 +63395.81648251823,1,92,458 +63496.3843147478,0,140,429 +63596.29154438921,1,134,375 +63696.44066311408,1,137,355 +63796.47156376697,0,162,342 +63896.72989927413,0,194,326 +63996.66187026119,0,242,294 +64096.944292734566,0,290,273 +64196.9835266383,0,395,290 +64296.97144799121,0,391,277 +64397.06516575655,0,366,270 +64497.127632869786,0,419,238 +64597.15001798481,0,495,206 +64697.17642591753,0,595,182 +64797.200423001916,3,648,164 +64897.120888155776,3,636,162 +64997.32626613069,8,628,117 +65097.30722296733,7,577,109 +65197.32502047289,7,503,111 +65297.31649430921,13,471,118 +65397.35848656337,11,439,104 +65497.464568765514,13,454,96 +65597.4519348394,4,367,84 +65697.67985494848,7,318,52 +65797.72124560633,4,287,34 +65898.13657922448,1,287,43 +65998.47612844195,0,275,25 +66098.08374337431,0,267,22 +66198.47590217383,0,309,15 +66298.7377109199,4,299,16 +66398.75809451201,10,303,11 +66498.72334265048,6,308,9 +66598.96975370022,10,274,9 +66699.36286993048,13,263,7 +66799.38867993947,19,232,6 +66899.58455990984,24,247,9 +66999.70007509606,19,197,10 +67099.39524614188,14,181,10 +67199.98889757357,8,180,10 +67300.15176740178,6,177,8 +67400.03306436358,12,167,9 +67500.1806072963,25,152,7 +67600.47926455986,22,122,5 +67700.45961016376,33,105,2 +67801.04983181355,36,102,0 +67901.28623336207,74,93,0 +68001.90659763617,93,107,0 +68102.02636082216,117,94,1 +68202.07774438453,149,83,1 +68301.89258853643,164,99,1 +68402.18901028184,158,86,0 +68501.8412264954,188,72,0 +68602.36448542499,249,52,0 +68702.29115077609,309,53,0 +68802.55575941417,443,65,0 +68902.74966508165,489,57,0 +69002.6524050068,540,41,0 +69102.74678317284,582,48,0 +69202.96647390889,592,47,0 +69302.85293680556,625,40,0 +69402.96978773472,674,40,0 +69503.12820373672,739,29,0 +69603.15541809393,779,14,4 +69703.16301578625,778,11,10 +69803.17430369536,671,14,9 +69903.2613652501,668,13,3 +70003.25841404256,627,13,1 +70103.43314455243,559,12,0 +70203.30253574478,502,13,0 +70303.55911284738,490,9,6 +70403.59524434003,421,14,16 +70503.76244994138,393,6,22 +70603.71612958751,339,11,30 +70703.78804607246,270,7,34 +70803.88784190372,265,9,47 +70903.9106962088,264,9,54 +71003.62606394643,241,13,49 +71104.82000913615,215,14,54 +71204.72311505368,210,9,53 +71304.97962079158,182,13,82 +71405.27249310179,200,9,72 +71505.30423621488,159,4,67 +71605.55027632492,147,0,91 +71705.4782077441,153,0,133 +71805.55546112364,130,0,242 +71905.65609144978,133,0,296 +72005.59532645429,115,0,399 +72105.55060995795,109,0,518 +72205.63787276656,90,0,553 +72305.80640585657,91,0,613 +72405.84787516852,64,0,692 +72505.84967617595,54,0,790 +72605.8482072258,53,0,815 +72705.82060981948,49,0,867 +72805.91279451242,52,0,865 +72905.92902757225,40,0,828 +73005.89526038276,38,0,890 +73106.00381380515,27,0,986 +73205.99711340977,23,0,1067 +73305.99540933105,25,5,991 +73406.03760180037,33,5,949 +73505.87863719928,28,1,827 +73606.08840631101,25,0,833 +73706.14664442772,29,0,772 +73806.19933952882,26,10,803 +73906.13595028293,29,8,764 +74006.2946032621,23,8,642 +74106.33023116546,18,10,561 +74206.15835610432,26,15,525 +74306.39519959445,28,23,519 +74406.43883199374,24,16,458 +74506.43518330838,24,11,392 +74606.65734244151,23,7,378 +74706.2039118052,19,7,307 +74806.86935568127,19,9,337 +74906.84394647408,19,10,324 +75007.06695554106,23,10,308 +75107.06150640869,15,12,284 +75206.96795901856,14,25,236 +75307.78090538707,11,15,215 +75408.09346313404,14,14,200 +75508.13000043346,11,25,156 +75608.78882093409,8,31,151 +75708.96101266811,10,23,140 +75809.00979900936,11,27,114 +75908.92968896852,16,31,119 +76008.55497499541,27,18,99 +76109.56693712724,18,30,96 +76209.82583186663,20,36,80 +76309.75377013157,14,22,61 +76410.1453768141,8,23,79 +76510.03537247989,7,26,65 +76610.96363255633,8,14,64 +76710.61425661572,4,21,69 +76810.83658474783,5,31,61 +76911.26356822933,2,42,63 +77011.8210596954,5,44,50 +77111.51556628614,4,51,41 +77212.51989364951,5,62,32 +77312.80758209426,6,74,18 +77412.5050668241,2,95,15 +77513.13967360399,2,104,19 +77612.45447184521,1,121,17 +77713.86699776394,0,122,19 +77814.34680186318,0,172,18 +77914.43887709791,0,191,16 +78014.4743481833,0,244,18 +78114.38903074227,0,327,23 +78214.63978554538,0,375,23 +78314.68119324412,0,420,25 +78414.6602591375,0,478,21 +78514.94226263084,0,418,20 +78615.02995665568,0,475,21 +78715.02840392849,0,497,17 +78815.12055260211,4,540,12 +78915.07612746765,17,545,5 +79015.1321108846,11,553,1 +79115.27797204738,24,491,0 +79215.27553401749,40,420,0 +79315.48515679842,94,385,0 +79415.62347402253,167,295,0 +79515.59792917052,237,257,0 +79615.78715704946,306,290,0 +79715.85726122675,410,253,0 +79815.88931303694,532,246,0 +79916.00120900353,656,194,0 +80015.99035064143,712,201,0 +80116.01445176269,773,156,0 +80216.0816953415,769,131,0 +80316.12314208863,798,135,0 +80416.16997070963,793,120,0 +80516.13805713052,881,117,0 +80616.26910313788,874,121,0 +80716.27795228899,834,115,0 +80816.27489059065,850,116,0 +80916.29557082002,873,100,0 +81016.28473277869,918,117,0 +81116.39606517646,904,104,0 +81216.34544273939,907,92,0 +81316.41807699358,916,80,0 +81416.41750233306,877,69,0 +81516.39234132023,908,74,0 +81616.54528265247,822,64,0 +81716.61773485588,807,61,0 +81816.41526521507,771,57,0 +81916.67754731954,796,66,0 +82016.71152816349,838,69,0 +82116.75141785863,981,55,0 +82216.80802564441,944,48,2 +82316.83341411156,947,45,6 +82416.95642959689,909,38,12 +82517.0702278602,844,31,16 +82617.08436605305,745,31,18 +82717.0490826536,625,27,15 +82817.23549896885,587,20,21 +82917.49820944773,504,19,29 +83017.67605432222,429,15,22 +83117.86068137111,359,13,23 +83217.95457107744,324,11,27 +83318.05613617065,305,12,41 +83418.1142919284,295,8,38 +83518.36160991112,279,5,35 +83618.35529041376,270,0,40 +83718.45610365778,232,0,110 +83818.5317516379,217,0,220 +83918.98578977553,194,0,284 +84019.2016201548,164,0,394 +84119.32885929808,150,0,446 +84219.35257436802,152,0,592 +84319.43176187773,144,0,663 +84419.43559080559,120,0,711 +84519.46533177218,96,0,712 +84619.68925680415,66,0,690 +84719.68103852487,54,0,740 +84819.59613284511,46,5,746 +84919.67494336671,44,11,766 +85019.75602554268,46,7,768 +85119.79912416471,45,8,664 +85219.8040932813,43,10,633 +85320.03876908924,27,8,617 +85420.05984979247,24,11,621 +85520.08324940146,20,9,548 +85620.36314211923,20,10,480 +85720.54159769621,15,4,426 +85820.585263794,12,3,402 +85920.99154968237,7,10,396 +86021.09591265483,8,6,342 +86121.0824375159,4,19,290 +86221.18316414606,8,32,281 +86321.22326010255,10,38,231 +86421.5422463905,5,51,204 +86521.63518510113,7,48,178 +86621.80919648398,10,53,158 +86721.87487472004,11,57,148 +86822.08272818748,13,57,116 +86922.30273230183,8,42,114 +87022.5339271133,14,48,102 +87122.96718301288,17,43,87 +87223.27509430048,16,43,83 +87323.48843359452,13,35,54 +87423.59641881639,8,34,43 +87523.65543758041,19,29,38 +87624.63072180038,20,21,18 +87724.10678194097,27,17,10 +87825.12792588276,18,17,7 +87925.34194636527,28,15,2 +88025.3215713608,37,22,1 +88125.53092739418,69,25,0 +88226.08586047859,126,22,0 +88326.42094795793,131,8,5 +88426.34539304313,129,2,11 +88526.47611328126,147,0,12 +88626.60624811308,138,0,44 +88726.88652127588,152,0,79 +88826.99287850539,132,0,181 +88926.74579364176,100,0,286 +89027.12898548257,76,0,395 +89127.2262570268,79,0,496 +89227.39224496929,62,0,613 +89327.5764532606,39,0,707 +89427.5828154209,29,3,766 +89527.65901095723,44,4,832 +89627.75420484837,39,6,804 +89727.79545237485,29,14,730 +89827.86471334014,27,13,731 +89927.84907691223,22,16,684 +90027.91947316933,32,19,577 +90128.07608809034,31,15,503 +90228.17872389781,31,14,445 +90328.21188550263,36,16,403 +90428.1291023666,21,14,378 +90528.2985934436,24,19,307 +90628.52793876242,24,21,283 +90728.91555456909,20,18,293 +90829.31922011991,25,18,260 +90929.11229508687,12,22,240 +91029.42919604381,11,21,221 +91129.6651150286,9,23,200 +91229.9798606634,4,23,169 +91330.07382391793,8,29,142 +91430.06053899572,15,26,129 +91530.442349184,21,36,145 +91629.77142923551,20,25,137 +91730.75410881138,26,30,130 +91830.54474896495,22,29,101 +91931.27653025475,26,38,90 +92031.24941923474,20,33,66 +92131.80582702516,21,36,59 +92231.84918469883,17,33,51 +92332.7171869947,9,30,69 +92433.01205161064,2,19,68 +92533.05145093836,2,18,48 +92633.27518756292,1,38,45 +92733.63400322679,0,72,38 +92833.56838312956,0,149,27 +92934.11172254264,0,218,20 +93034.24468658156,0,272,17 +93134.27884595437,0,312,21 +93234.46018986708,0,341,18 +93334.46960294049,0,352,15 +93434.38034752884,8,393,18 +93534.6413955782,5,415,26 +93634.58677713489,4,368,14 +93735.18614384836,0,348,7 +93834.8101994181,0,306,15 +93935.33320656912,0,323,11 +94035.49055851092,0,381,13 +94135.57470451835,0,402,16 +94235.63744368734,0,438,8 +94335.79260647867,0,509,11 +94435.91803114804,3,507,12 +94535.87476736112,8,518,6 +94636.04037402314,11,462,4 +94736.19324433502,22,441,2 +94836.0399011328,21,420,1 +94936.1774754013,61,348,0 +95036.30989765112,131,323,0 +95136.36388024177,212,332,0 +95236.5029078477,306,282,0 +95336.59523099817,411,233,0 +95436.66969556722,409,220,0 +95536.62713394579,413,168,0 +95636.69242826941,487,172,0 +95736.71897928047,541,166,0 +95836.8964542962,570,138,0 +95936.95153883634,626,151,0 +96036.92003403466,606,140,0 +96137.0642105573,650,124,0 +96237.05418360743,626,102,0 +96337.14829687006,766,76,0 +96437.16443472721,768,73,0 +96537.19038789897,778,69,0 +96637.4896810076,769,53,0 +96737.62614815135,768,36,0 +96837.65228685043,848,38,0 +96937.6631880946,918,36,0 +97037.75098867327,933,32,0 +97137.77855310103,984,36,0 +97237.70631498922,945,25,0 +97337.92680618768,913,18,0 +97437.9802874181,920,13,6 +97538.061325625,844,14,2 +97638.09287457938,843,24,0 +97738.09362194444,765,13,10 +97838.10762253772,696,14,13 +97938.11650486609,615,8,15 +98038.29062990371,628,6,16 +98138.17986806354,538,7,7 +98238.16353181467,474,10,7 +98338.39708899318,422,11,15 +98438.54009905795,399,14,20 +98538.65424840078,348,7,15 +98638.31097327484,273,7,25 +98738.67973370303,227,4,25 +98838.71480995565,179,2,30 +98938.6417284288,146,2,33 +99038.91866334192,121,1,35 +99138.93995162165,97,0,76 +99239.53012677889,70,0,159 +99339.16676383071,59,0,264 +99440.02962579156,49,0,348 +99540.29471426392,46,0,423 +99640.38453125526,37,0,476 +99740.38438157868,34,0,516 +99840.87804343985,32,0,589 +99940.8490129389,22,0,655 +99999.95161541106,17,0,704 +99999.99999999952,17,0,704 \ No newline at end of file diff --git a/ClassicGEC/ParserTests.playlist b/ClassicGEC/ParserTests.playlist new file mode 100644 index 0000000..b48a059 --- /dev/null +++ b/ClassicGEC/ParserTests.playlist @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ClassicGEC/SBOLJsonToXml/gec.xml b/ClassicGEC/SBOLJsonToXml/gec.xml new file mode 100644 index 0000000..5900c23 --- /dev/null +++ b/ClassicGEC/SBOLJsonToXml/gec.xml @@ -0,0 +1,329 @@ + + + + + production_md + 1 + TetR_Production + + + + c0040_FC + 1 + tetR_FC + + + + + + + + + c0040p_FC + 1 + tetR_protein_FC + + + + + + + + + production + 1 + tetR_production_interaction + + + + + c0040_Part + 1 + tetR_P + + + + + + + + c0040p_Part + 1 + tetRProt_P + + + + + + + + + + inhibition_md + 1 + pTet_Inhibition + + + + c0040c_FC + 1 + tetR_complex_FC + + + + + + + + + r0040_FC + 1 + pTet_FC + + + + + + + + + inhibition + 1 + pTet_inhibition_interaction + + + + + c0040c_Part + 1 + tetRCmplx_P + + + + + + + + r0040_Part + 1 + pTet_P + + + + + + + + + + r0040 + 1 + pTet + + + + + + + b0034 + 1 + rbs + + + + + + + c0040 + 1 + tetR + + + + + + + b0015 + 1 + term + + + + + + + c0040p + 1 + tetR_protein + + + + + tu007 + 1 + tu1 + + + + + + r0040_component + 1 + pTet_component + + + + + + + + b0034_component + 1 + rbs_component + + + + + + + + c0040_component + 1 + tetR_component + + + + + + + + b0015_component + 1 + term_component + + + + + + + + annotation1 + 1 + annotation1 + + + + r0040_range + 1 + range + 1 + 14 + + + + + + + + + + annotation2 + 1 + annotation2 + + + + b0034_range + 1 + range + 15 + 30 + + + + + + + + + + annotation3 + 1 + annotation3 + + + + c0040_range + 1 + range + 31 + 54 + + + + + + + + + + annotation4 + 1 + annotation4 + + + + b0015_range + 1 + range + 55 + 68 + + + + + + + + + + + b0015_sequence + 1 + term_sequence + aaatttttttttgc + + + + + b0034_sequence + 1 + rbs_sequence + aaaaaatttttggggg + + + + + c0040_sequence + 1 + tetR_sequence + aatttaaatttatatatatattaa + + + + + r0040_sequence + 1 + pTet_sequence + aattccggggaaaa + + + + + tu007_sequence + 1 + tu1_sequence + aattccggggaaaaaaaaaatttttgggggaatttaaatttatatatatattaaaaatttttttttgc + + + \ No newline at end of file diff --git a/ClassicGEC/SBOLJsonToXml/json2xml.js b/ClassicGEC/SBOLJsonToXml/json2xml.js new file mode 100644 index 0000000..296a75d --- /dev/null +++ b/ClassicGEC/SBOLJsonToXml/json2xml.js @@ -0,0 +1,319 @@ +var fs = require('fs'); +var SBOLDocument = require('sboljs'); + +var sboljsonFilepath = 'sbol.json' +var resultSBOL = 'gec.xml'; +var sbol = new SBOLDocument(); + +var sbolJson = JSON.parse(fs.readFileSync(sboljsonFilepath) + ''); + +var seqMap = {}; +var compMap = {}; +var funCompMap = {}; +convertJsonToXml(sbolJson) + +//console.log(seqMap); +//console.log(compMap); +//console.log(funCompMap); +//console.log(sbol); + +//Write the SBOL document to an XML file. +fs.writeFile(resultSBOL, sbol.serializeXML(), function (err) { + if (err) { + return console.log(err); + } + + console.log("GEC SBOL XML file created!"); +}); + + +function convertJsonToXml(jsbol){ + jsbol.sequences.forEach(function(element) { + addSequence(element); + }, this); + jsbol.componentDefinitions.forEach(function(element) { + addComponentDefinition(element); + }, this); + jsbol.moduleDefinitions.forEach(function(element) { + addModuleDefinition(element); + }, this); +} + +function addSequence(jelem){ + var elem = sbol.sequence(); + //Start adding basic information like identity + elem.name = jelem.name; + elem.version = jelem.version; + elem.displayId = jelem.displayId; + elem.persistentIdentity = encodeURI(jelem.persistentIdentity); + elem.uri = elem.persistentIdentity + '/' + elem.version; + if(jelem.description.length !== 0){ + elem.description = jelem.description; + } + jelem.annotations.forEach(function (ann){ + if(ann.Type === "uri"){ + elem.addUriAnnotation(ann.name,ann.value); + } + else if(ann.Type === "string"){ + elem.addStringAnnotation(ann.name,ann.value); + } + },this); + //End basic information + elem.elements = jelem.elements; + elem.encoding = jelem.encoding; + + let uriVal = jelem.uri + seqMap[uriVal] = elem; + +} + +function addComponentDefinition(jelem){ + + var elem = sbol.componentDefinition(); + //Start adding basic information like identity + elem.name = jelem.name; + elem.version = jelem.version; + elem.displayId = jelem.displayId; + elem.persistentIdentity = encodeURI(jelem.persistentIdentity); + elem.uri = elem.persistentIdentity + '/' + elem.version; + if(jelem.description.length !== 0){ + elem.description = jelem.description; + } + jelem.annotations.forEach(function (ann){ + if(ann.Type === "uri"){ + elem.addUriAnnotation(ann.name,ann.value); + } + else if(ann.Type === "string"){ + elem.addStringAnnotation(ann.name,ann.value); + } + },this); + //End basic information + + jelem.sequences.forEach(function (sequri){ + elem.addSequence(seqMap[sequri]); + },this); + + jelem.components.forEach(function(comp){ + elem.addComponent(addComponent(comp)); + },this); + jelem.sequenceAnnotations.forEach(function(sa){ + elem.addSequenceAnnotation(addSequenceAnnotation(sa)); + },this); + + jelem.types.forEach(function(t){ + elem.addType(t); + },this); + + jelem.roles.forEach(function(r){ + elem.addRole(r); + },this); + return elem; +} + +function addSequenceAnnotation(jelem){ + var elem = sbol.sequenceAnnotation(); + //Start adding basic information like identity + elem.name = jelem.name; + elem.version = jelem.version; + elem.displayId = jelem.displayId; + elem.persistentIdentity = encodeURI(jelem.persistentIdentity); + elem.uri = elem.persistentIdentity + '/' + elem.version; + if(jelem.description.length !== 0){ + elem.description = jelem.description; + } + jelem.annotations.forEach(function (ann){ + if(ann.Type === "uri"){ + elem.addUriAnnotation(ann.name,ann.value); + } + else if(ann.Type === "string"){ + elem.addStringAnnotation(ann.name,ann.value); + } + },this); + //End basic information + + elem.component = compMap[jelem.Component]; + jelem.locations.forEach(function(loc){ + elem.addLocation(addLocation(loc)); + },this); + return elem; +} + +function addLocation(jloc){ + var suff = "$" + jloc.$; + if(jloc[suff].gecDU === "range"){ + var jelem = jloc[suff]; + var elem = sbol.range(); + //Start adding basic information like identity + elem.name = jelem.name; + elem.version = jelem.version; + elem.displayId = jelem.displayId; + elem.persistentIdentity = encodeURI(jelem.persistentIdentity); + elem.uri = elem.persistentIdentity + '/' + elem.version; + if(jelem.description.length !== 0){ + elem.description = jelem.description; + } + jelem.annotations.forEach(function (ann){ + if(ann.Type === "uri"){ + elem.addUriAnnotation(ann.name,ann.value); + } + else if(ann.Type === "string"){ + elem.addStringAnnotation(ann.name,ann.value); + } + },this); + //End basic information + elem.start = jelem.startIndex; + elem.end = jelem.endIndex; + elem.orientation = jelem.orientation; + return elem; + } + +} + +function addComponent(jelem){ + var elem = sbol.component(); + //Start adding basic information like identity + elem.name = jelem.name; + elem.version = jelem.version; + elem.displayId = jelem.displayId; + elem.persistentIdentity = encodeURI(jelem.persistentIdentity); + elem.uri = elem.persistentIdentity + '/' + elem.version; + if(jelem.description.length !== 0){ + elem.description = jelem.description; + } + jelem.annotations.forEach(function (ann){ + if(ann.Type === "uri"){ + elem.addUriAnnotation(ann.name,ann.value); + } + else if(ann.Type === "string"){ + elem.addStringAnnotation(ann.name,ann.value); + } + },this); + //End basic information + elem.access = jelem.access; + elem.definition = jelem.definition; + let uriVal = jelem.uri + compMap[uriVal] = elem; + return elem; +} + + +function addModuleDefinition(jelem){ + var elem = sbol.moduleDefinition(); + //Start adding basic information like identity + elem.name = jelem.name; + elem.version = jelem.version; + elem.displayId = jelem.displayId; + elem.persistentIdentity = encodeURI(jelem.persistentIdentity); + elem.uri = elem.persistentIdentity + '/' + elem.version; + if(jelem.description.length !== 0){ + elem.description = jelem.description; + } + jelem.annotations.forEach(function (ann){ + if(ann.Type === "uri"){ + elem.addUriAnnotation(ann.name,ann.value); + } + else if(ann.Type === "string"){ + elem.addStringAnnotation(ann.name,ann.value); + } + },this); + //End basic information + + jelem.functionalComponents.forEach(function (fc){ + elem.addFunctionalComponent(addFunctionalComponent(fc)); + },this); + jelem.interactions.forEach(function (inter){ + elem.addInteraction(addInteraction(inter)); + },this); + return elem; +} + + +function addFunctionalComponent(jelem){ + var elem = sbol.functionalComponent(); + //Start adding basic information like identity + elem.name = jelem.name; + elem.version = jelem.version; + elem.displayId = jelem.displayId; + elem.persistentIdentity = encodeURI(jelem.persistentIdentity); + elem.uri = elem.persistentIdentity + '/' + elem.version; + if(jelem.description.length !== 0){ + elem.description = jelem.description; + } + jelem.annotations.forEach(function (ann){ + if(ann.Type === "uri"){ + elem.addUriAnnotation(ann.name,ann.value); + } + else if(ann.Type === "string"){ + elem.addStringAnnotation(ann.name,ann.value); + } + },this); + //End basic information + elem.access = jelem.access; + elem.direction = jelem.direction; + elem.definition = jelem.definition; + let uriVal = jelem.uri + funCompMap[uriVal] = elem; + return elem; +} + + +function addParticipation(jelem){ + var elem = sbol.participation(); + //Start adding basic information like identity + elem.name = jelem.name; + elem.version = jelem.version; + elem.displayId = jelem.displayId; + elem.persistentIdentity = encodeURI(jelem.persistentIdentity); + elem.uri = elem.persistentIdentity + '/' + elem.version; + if(jelem.description.length !== 0){ + elem.description = jelem.description; + } + + jelem.annotations.forEach(function (ann){ + if(ann.Type === "uri"){ + elem.addUriAnnotation(ann.name,ann.value); + } + else if(ann.Type === "string"){ + elem.addStringAnnotation(ann.name,ann.value); + } + },this); + + //End basic information + jelem.roles.forEach(function(r) { + elem.addRole(r); + },this); + + elem.participant = funCompMap[jelem.participant]; + return elem; +} + +function addInteraction(jelem){ + var elem = sbol.interaction(); + //Start adding basic information like identity + elem.name = jelem.name; + elem.version = jelem.version; + elem.displayId = jelem.displayId; + elem.persistentIdentity = encodeURI(jelem.persistentIdentity); + elem.uri = elem.persistentIdentity + '/' + elem.version; + if(jelem.description.length !== 0){ + elem.description = jelem.description; + } + jelem.annotations.forEach(function (ann){ + if(ann.Type === "uri"){ + elem.addUriAnnotation(ann.name,ann.value); + } + else if(ann.Type === "string"){ + elem.addStringAnnotation(ann.name,ann.value); + } + },this); + //End basic information + + jelem.types.forEach(function(t){ + elem.addType(t); + },this); + + jelem.participations.forEach(function(part){ + elem.addParticipation(addParticipation(part)); + },this); + return elem; +} \ No newline at end of file diff --git a/ClassicGEC/SBOLJsonToXml/package.json b/ClassicGEC/SBOLJsonToXml/package.json new file mode 100644 index 0000000..a0074ee --- /dev/null +++ b/ClassicGEC/SBOLJsonToXml/package.json @@ -0,0 +1,18 @@ +{ + "name": "json2xml", + "version": "1.0.0", + "description": "JS library to convert JSON SBOL representation to XML", + "main": "json2xml.js", + "scripts": { + "test": "make test" + }, + "keywords": [ + "sbol" + ], + "author": "Prashant Vaidyanathan ", + "license": "ISC", + "dependencies": { + "fs": "0.0.1-security", + "sboljs": "1.11.0" + } +} diff --git a/ClassicGEC/SBOLJsonToXml/sbol.json b/ClassicGEC/SBOLJsonToXml/sbol.json new file mode 100644 index 0000000..a8ecb08 --- /dev/null +++ b/ClassicGEC/SBOLJsonToXml/sbol.json @@ -0,0 +1,479 @@ +{ + "componentDefinitions": [ + { + "uri": "http://www.microsoft.com/gec/db/r0040/1", + "name": "r0040", + "persistentIdentity": "http://www.microsoft.com/gec/db/r0040", + "displayId": "r0040", + "version": "1", + "description": "", + "annotations": [], + "components": [], + "sequenceAnnotations": [], + "sequences": [], + "types": [ "http://www.biopax.org/release/biopax-level3.owl#DnaRegion" ], + "roles": [ "http://identifiers.org/so/SO:0000167" ] + }, + { + "uri": "http://www.microsoft.com/gec/db/b0034/1", + "name": "b0034", + "persistentIdentity": "http://www.microsoft.com/gec/db/b0034", + "displayId": "b0034", + "version": "1", + "description": "", + "annotations": [], + "components": [], + "sequenceAnnotations": [], + "sequences": [], + "types": [ "http://www.biopax.org/release/biopax-level3.owl#DnaRegion" ], + "roles": [ "http://identifiers.org/so/SO:0000139" ] + }, + { + "uri": "http://www.microsoft.com/gec/db/c0040/1", + "name": "c0040", + "persistentIdentity": "http://www.microsoft.com/gec/db/c0040", + "displayId": "c0040", + "version": "1", + "description": "", + "annotations": [], + "components": [], + "sequenceAnnotations": [], + "sequences": [], + "types": [ "http://www.biopax.org/release/biopax-level3.owl#DnaRegion" ], + "roles": [ "http://identifiers.org/so/SO:0000316" ] + }, + { + "uri": "http://www.microsoft.com/gec/db/b0015/1", + "name": "b0015", + "persistentIdentity": "http://www.microsoft.com/gec/db/b0015", + "displayId": "b0015", + "version": "1", + "description": "", + "annotations": [], + "components": [], + "sequenceAnnotations": [], + "sequences": [], + "types": [ "http://www.biopax.org/release/biopax-level3.owl#DnaRegion" ], + "roles": [ "http://identifiers.org/so/SO:0000141" ] + }, + { + "uri": "http://www.microsoft.com/gec/db/tetR/1", + "name": "tetR", + "persistentIdentity": "http://www.microsoft.com/gec/db/tetR", + "displayId": "tetR", + "version": "1", + "description": "", + "annotations": [], + "components": [], + "sequenceAnnotations": [], + "sequences": [], + "types": [ "http://www.biopax.org/release/biopax-level3.owl#Protein" ], + "roles": [] + }, + { + "uri": "http://www.microsoft.com/gec/db/tu0/1", + "name": "tu0", + "persistentIdentity": "http://www.microsoft.com/gec/db/tu0", + "displayId": "tu0", + "version": "1", + "description": "", + "annotations": [], + "components": [ + { + "uri": "http://www.microsoft.com/gec/db/r0040_component/1", + "name": "r0040_component", + "persistentIdentity": "http://www.microsoft.com/gec/db/r0040_component", + "displayId": "r0040_component", + "version": "1", + "description": "", + "annotations": [], + "access": "http://sbols.org/v2#private", + "definition": "http://www.microsoft.com/gec/db/r0040/1" + }, + { + "uri": "http://www.microsoft.com/gec/db/b0034_component/1", + "name": "b0034_component", + "persistentIdentity": "http://www.microsoft.com/gec/db/b0034_component", + "displayId": "b0034_component", + "version": "1", + "description": "", + "annotations": [], + "access": "http://sbols.org/v2#private", + "definition": "http://www.microsoft.com/gec/db/b0034/1" + }, + { + "uri": "http://www.microsoft.com/gec/db/c0040_component/1", + "name": "c0040_component", + "persistentIdentity": "http://www.microsoft.com/gec/db/c0040_component", + "displayId": "c0040_component", + "version": "1", + "description": "", + "annotations": [], + "access": "http://sbols.org/v2#private", + "definition": "http://www.microsoft.com/gec/db/c0040/1" + }, + { + "uri": "http://www.microsoft.com/gec/db/b0015_component/1", + "name": "b0015_component", + "persistentIdentity": "http://www.microsoft.com/gec/db/b0015_component", + "displayId": "b0015_component", + "version": "1", + "description": "", + "annotations": [], + "access": "http://sbols.org/v2#private", + "definition": "http://www.microsoft.com/gec/db/b0015/1" + } + ], + "sequenceAnnotations": [ + { + "uri": "http://www.microsoft.com/gec/db/annotation1/1", + "name": "annotation1", + "persistentIdentity": "http://www.microsoft.com/gec/db/annotation1", + "displayId": "annotation1", + "version": "1", + "description": "", + "annotations": [], + "component": "http://www.microsoft.com/gec/db/r0040_component/1", + "locations": [ + { + "Case": "Range", + "Fields": [ + { + "gecDU": "range", + "uri": "http://www.microsoft.com/gec/db/annotation1/range/r0040_range/1", + "name": "range", + "persistentIdentity": "http://www.microsoft.com/gec/db/annotation1/range/r0040_range", + "displayId": "r0040_range", + "version": "1", + "description": "", + "annotations": [], + "startIndex": 1, + "endIndex": 1, + "orientation": "http://sbols.org/v2#inline" + } + ] + } + ] + }, + { + "uri": "http://www.microsoft.com/gec/db/annotation2/1", + "name": "annotation2", + "persistentIdentity": "http://www.microsoft.com/gec/db/annotation2", + "displayId": "annotation2", + "version": "1", + "description": "", + "annotations": [], + "component": "http://www.microsoft.com/gec/db/b0034_component/1", + "locations": [ + { + "Case": "Range", + "Fields": [ + { + "gecDU": "range", + "uri": "http://www.microsoft.com/gec/db/annotation2/range/b0034_range/1", + "name": "range", + "persistentIdentity": "http://www.microsoft.com/gec/db/annotation2/range/b0034_range", + "displayId": "b0034_range", + "version": "1", + "description": "", + "annotations": [], + "startIndex": 2, + "endIndex": 2, + "orientation": "http://sbols.org/v2#inline" + } + ] + } + ] + }, + { + "uri": "http://www.microsoft.com/gec/db/annotation3/1", + "name": "annotation3", + "persistentIdentity": "http://www.microsoft.com/gec/db/annotation3", + "displayId": "annotation3", + "version": "1", + "description": "", + "annotations": [], + "component": "http://www.microsoft.com/gec/db/c0040_component/1", + "locations": [ + { + "Case": "Range", + "Fields": [ + { + "gecDU": "range", + "uri": "http://www.microsoft.com/gec/db/annotation3/range/c0040_range/1", + "name": "range", + "persistentIdentity": "http://www.microsoft.com/gec/db/annotation3/range/c0040_range", + "displayId": "c0040_range", + "version": "1", + "description": "", + "annotations": [], + "startIndex": 3, + "endIndex": 3, + "orientation": "http://sbols.org/v2#inline" + } + ] + } + ] + }, + { + "uri": "http://www.microsoft.com/gec/db/annotation4/1", + "name": "annotation4", + "persistentIdentity": "http://www.microsoft.com/gec/db/annotation4", + "displayId": "annotation4", + "version": "1", + "description": "", + "annotations": [], + "component": "http://www.microsoft.com/gec/db/b0015_component/1", + "locations": [ + { + "Case": "Range", + "Fields": [ + { + "gecDU": "range", + "uri": "http://www.microsoft.com/gec/db/annotation4/range/b0015_range/1", + "name": "range", + "persistentIdentity": "http://www.microsoft.com/gec/db/annotation4/range/b0015_range", + "displayId": "b0015_range", + "version": "1", + "description": "", + "annotations": [], + "startIndex": 4, + "endIndex": 4, + "orientation": "http://sbols.org/v2#inline" + } + ] + } + ] + } + ], + "sequences": [ "http://www.microsoft.com/gec/db/tu0_sequence/1" ], + "types": [ "http://www.biopax.org/release/biopax-level3.owl#DnaRegion" ], + "roles": [ "http://identifiers.org/so/SO:0000280" ] + }, + { + "uri": "http://www.microsoft.com/gec/db/device/1", + "name": "device", + "persistentIdentity": "http://www.microsoft.com/gec/db/device", + "displayId": "device", + "version": "1", + "description": "", + "annotations": [], + "components": [ + { + "uri": "http://www.microsoft.com/gec/db/tu0_component/1", + "name": "tu0_component", + "persistentIdentity": "http://www.microsoft.com/gec/db/tu0_component", + "displayId": "tu0_component", + "version": "1", + "description": "", + "annotations": [], + "access": "http://sbols.org/v2#private", + "definition": "http://www.microsoft.com/gec/db/tu0/1" + } + ], + "sequenceAnnotations": [ + { + "uri": "http://www.microsoft.com/gec/db/annotation1/1", + "name": "annotation1", + "persistentIdentity": "http://www.microsoft.com/gec/db/annotation1", + "displayId": "annotation1", + "version": "1", + "description": "", + "annotations": [], + "component": "http://www.microsoft.com/gec/db/tu0_component/1", + "locations": [ + { + "Case": "Range", + "Fields": [ + { + "gecDU": "range", + "uri": "http://www.microsoft.com/gec/db/annotation1/range/tu0_range/1", + "name": "range", + "persistentIdentity": "http://www.microsoft.com/gec/db/annotation1/range/tu0_range", + "displayId": "tu0_range", + "version": "1", + "description": "", + "annotations": [], + "startIndex": 1, + "endIndex": 1, + "orientation": "http://sbols.org/v2#inline" + } + ] + } + ] + } + ], + "sequences": [ "http://www.microsoft.com/gec/db/device_sequence/1" ], + "types": [ "http://www.biopax.org/release/biopax-level3.owl#DnaRegion" ], + "roles": [ "http://identifiers.org/so/SO:0000280" ] + } + ], + "moduleDefinitions": [ + { + "uri": "http://www.microsoft.com/gec/db/c0040_tetR_production_md/1", + "name": "c0040_tetR_production_md", + "persistentIdentity": "http://www.microsoft.com/gec/db/c0040_tetR_production_md", + "displayId": "c0040_tetR_production_md", + "version": "1", + "description": "", + "annotations": [], + "functionalComponents": [ + { + "uri": "http://www.microsoft.com/gec/db/c0040_tetR_production_md/c0040_FC/1", + "name": "c0040_FC", + "persistentIdentity": "http://www.microsoft.com/gec/db/c0040_tetR_production_md/c0040_FC", + "displayId": "c0040_FC", + "version": "1", + "description": "", + "annotations": [], + "access": "http://sbols.org/v2#private", + "direction": "http://sbols.org/v2#inout", + "definition": "http://www.microsoft.com/gec/db/c0040/1" + }, + { + "uri": "http://www.microsoft.com/gec/db/c0040_tetR_production_md/tetR_protein_FC/1", + "name": "tetR_protein_FC", + "persistentIdentity": "http://www.microsoft.com/gec/db/c0040_tetR_production_md/tetR_protein_FC", + "displayId": "tetR_protein_FC", + "version": "1", + "description": "", + "annotations": [], + "access": "http://sbols.org/v2#private", + "direction": "http://sbols.org/v2#inout", + "definition": "http://www.microsoft.com/gec/db/tetR/1" + } + ], + "interactions": [ + { + "uri": "http://www.microsoft.com/gec/db/c0040_tetR_production_md/c0040_tetR_production_interaction/1", + "name": "c0040_tetR_production_interaction", + "persistentIdentity": "http://www.microsoft.com/gec/db/c0040_tetR_production_md/c0040_tetR_production_interaction", + "displayId": "c0040_tetR_production_interaction", + "version": "1", + "description": "", + "annotations": [], + "types": [ "http://identifiers.org/biomodels.sbo/SBO:0000589" ], + "participations": [ + { + "uri": "http://www.microsoft.com/gec/db/c0040_tetR_production_md/c0040_tetR_production_interaction/c0040_participation/1", + "name": "c0040_participation", + "persistentIdentity": "http://www.microsoft.com/gec/db/c0040_tetR_production_md/c0040_tetR_production_interaction/c0040_participation", + "displayId": "c0040_participation", + "version": "1", + "description": "", + "annotations": [], + "roles": [ "http://identifiers.org/biomodels.sbo/SBO:0000645" ], + "participant": "http://www.microsoft.com/gec/db/c0040_tetR_production_md/c0040_FC/1" + }, + { + "uri": "http://www.microsoft.com/gec/db/c0040_tetR_production_md/c0040_tetR_production_interaction/tetRp_participation/1", + "name": "tetRp_participation", + "persistentIdentity": "http://www.microsoft.com/gec/db/c0040_tetR_production_md/c0040_tetR_production_interaction/tetRp_participation", + "displayId": "tetRp_participation", + "version": "1", + "description": "", + "annotations": [], + "roles": [ "http://identifiers.org/biomodels.sbo/SBO:0000011" ], + "participant": "http://www.microsoft.com/gec/db/c0040_tetR_production_md/tetR_protein_FC/1" + } + ] + } + ] + }, + { + "uri": "http://www.microsoft.com/gec/db/tetR_r0040_inhibition_md/1", + "name": "tetR_r0040_inhibition_md", + "persistentIdentity": "http://www.microsoft.com/gec/db/tetR_r0040_inhibition_md", + "displayId": "tetR_r0040_inhibition_md", + "version": "1", + "description": "", + "annotations": [], + "functionalComponents": [ + { + "uri": "http://www.microsoft.com/gec/db/tetR_r0040_inhibition_md/tetR_complex_FC/1", + "name": "tetR_complex_FC", + "persistentIdentity": "http://www.microsoft.com/gec/db/tetR_r0040_inhibition_md/tetR_complex_FC", + "displayId": "tetR_complex_FC", + "version": "1", + "description": "", + "annotations": [], + "access": "http://sbols.org/v2#private", + "direction": "http://sbols.org/v2#inout", + "definition": "http://www.microsoft.com/gec/db/tetR/1" + }, + { + "uri": "http://www.microsoft.com/gec/db/tetR_r0040_inhibition_md/r0040_FC/1", + "name": "r0040_FC", + "persistentIdentity": "http://www.microsoft.com/gec/db/tetR_r0040_inhibition_md/r0040_FC", + "displayId": "r0040_FC", + "version": "1", + "description": "", + "annotations": [], + "access": "http://sbols.org/v2#private", + "direction": "http://sbols.org/v2#inout", + "definition": "http://www.microsoft.com/gec/db/r0040/1" + } + ], + "interactions": [ + { + "uri": "http://www.microsoft.com/gec/db/tetR_r0040_inhibition_md/tetR_r0040_inhibition_interaction/1", + "name": "tetR_r0040_inhibition_interaction", + "persistentIdentity": "http://www.microsoft.com/gec/db/tetR_r0040_inhibition_md/tetR_r0040_inhibition_interaction", + "displayId": "tetR_r0040_inhibition_interaction", + "version": "1", + "description": "", + "annotations": [], + "types": [ "http://identifiers.org/biomodels.sbo/SBO:0000169" ], + "participations": [ + { + "uri": "http://www.microsoft.com/gec/db/tetR_r0040_inhibition_md/tetR_r0040_inhibition_interaction/tetRc_participation/1", + "name": "tetRc_participation", + "persistentIdentity": "http://www.microsoft.com/gec/db/tetR_r0040_inhibition_md/tetR_r0040_inhibition_interaction/tetRc_participation", + "displayId": "tetRc_participation", + "version": "1", + "description": "", + "annotations": [], + "roles": [ "http://identifiers.org/biomodels.sbo/SBO:0000020" ], + "participant": "http://www.microsoft.com/gec/db/tetR_r0040_inhibition_md/tetR_complex_FC/1" + }, + { + "uri": "http://www.microsoft.com/gec/db/tetR_r0040_inhibition_md/tetR_r0040_inhibition_interaction/c0040_participation/1", + "name": "c0040_participation", + "persistentIdentity": "http://www.microsoft.com/gec/db/tetR_r0040_inhibition_md/tetR_r0040_inhibition_interaction/c0040_participation", + "displayId": "c0040_participation", + "version": "1", + "description": "", + "annotations": [], + "roles": [ "http://identifiers.org/biomodels.sbo/SBO:0000642" ], + "participant": "http://www.microsoft.com/gec/db/tetR_r0040_inhibition_md/r0040_FC/1" + } + ] + } + ] + } + ], + "sequences": [ + { + "uri": "http://www.microsoft.com/gec/db/device_sequence/1", + "name": "device_sequence", + "persistentIdentity": "http://www.microsoft.com/gec/db/device_sequence", + "displayId": "device_sequence", + "version": "1", + "description": "", + "annotations": [], + "elements": "", + "encoding": "http://www.chem.qmul.ac.uk/iubmb/misc/naseq.html" + }, + { + "uri": "http://www.microsoft.com/gec/db/tu0_sequence/1", + "name": "tu0_sequence", + "persistentIdentity": "http://www.microsoft.com/gec/db/tu0_sequence", + "displayId": "tu0_sequence", + "version": "1", + "description": "", + "annotations": [], + "elements": "", + "encoding": "http://www.chem.qmul.ac.uk/iubmb/misc/naseq.html" + } + ] +} \ No newline at end of file diff --git a/ClassicGEC/notepadpp.xml b/ClassicGEC/notepadpp.xml new file mode 100644 index 0000000..206e722 --- /dev/null +++ b/ClassicGEC/notepadpp.xml @@ -0,0 +1,64 @@ + + + + + + + + 00// 01 02 03(* 04*) + + + + + + + + [ ] ( ) ; , < > { } * ^ | + - + + + + + + + + + + + directive sweeps simulator deterministic simulation sample time event fit parameters init spec module rate inference data spatial system plot_settings rates units device + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FSBOLWrapper/FSBOLWrapper.sln b/FSBOLWrapper/FSBOLWrapper.sln new file mode 100644 index 0000000..f890906 --- /dev/null +++ b/FSBOLWrapper/FSBOLWrapper.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28307.271 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSBOLWrapper", "FSBOLWrapper\FSBOLWrapper.fsproj", "{BB7BF226-0DD2-412E-8597-C4431A49E44A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {BB7BF226-0DD2-412E-8597-C4431A49E44A}.Debug|x64.ActiveCfg = Debug|Any CPU + {BB7BF226-0DD2-412E-8597-C4431A49E44A}.Debug|x64.Build.0 = Debug|Any CPU + {BB7BF226-0DD2-412E-8597-C4431A49E44A}.Release|x64.ActiveCfg = Release|Any CPU + {BB7BF226-0DD2-412E-8597-C4431A49E44A}.Release|x64.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {73A3DC6C-8793-40C0-A28F-1905C0951B40} + EndGlobalSection +EndGlobal diff --git a/FSBOLWrapper/FSBOLWrapper/AssemblyInfo.fs b/FSBOLWrapper/FSBOLWrapper/AssemblyInfo.fs new file mode 100644 index 0000000..53aedbb --- /dev/null +++ b/FSBOLWrapper/FSBOLWrapper/AssemblyInfo.fs @@ -0,0 +1,41 @@ +namespace FSBOL.AssemblyInfo + +open System.Reflection +open System.Runtime.CompilerServices +open System.Runtime.InteropServices + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[] +[] +[] +[] +[] +[] +[] +[] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [] +[] +[] + +do + () \ No newline at end of file diff --git a/FSBOLWrapper/FSBOLWrapper/Circuit.test.fs b/FSBOLWrapper/FSBOLWrapper/Circuit.test.fs new file mode 100644 index 0000000..933d9ae --- /dev/null +++ b/FSBOLWrapper/FSBOLWrapper/Circuit.test.fs @@ -0,0 +1,151 @@ +module Microsoft.Research.FSBOL.CircuitTest + +open Microsoft.Research.FSBOL.Component +open Microsoft.Research.FSBOL.ComponentDefinition +open Microsoft.Research.FSBOL.Sequence +open Microsoft.Research.FSBOL.Terms +open Microsoft.Research.FSBOL.Range +open Microsoft.Research.FSBOL.SequenceAnnotation +open Microsoft.Research.FSBOL.FunctionalComponent +open Microsoft.Research.FSBOL.Interaction +open Microsoft.Research.FSBOL.ModuleDefinition +open Microsoft.Research.FSBOL.Participation + +open Microsoft.Research.FSBOL.SBOLDocument + +open Microsoft.Research.FSBOL.XmlSerializer +open Microsoft.Research.FSBOL.JsonSerializer + +open Xunit +open FsUnit.Xunit +open System.Diagnostics +open System.Xml +open System.IO +open System.Text + + +[] +let ``CreateCircuit``() = + let urlPrefix = "http://www.microsoft.com/gec" + let version = "1" + + let pTetSequence = "aattccggggaaaa" + let rbsSequence = "aaaaaatttttggggg" + let tetRSequence = "aatttaaatttatatatatattaa" + let termSequence = "aaatttttttttgc" + + let pTetSeq = new Sequence("pTet_sequence",urlPrefix,"r0040_sequence",version,pTetSequence,Terms.dnasequence) + let rbsSeq = new Sequence("rbs_sequence",urlPrefix,"b0034_sequence",version,rbsSequence,Terms.dnasequence) + let tetRSeq = new Sequence("tetR_sequence",urlPrefix,"c0040_sequence",version,tetRSequence,Terms.dnasequence) + let termSeq = new Sequence("term_sequence",urlPrefix,"b0015_sequence",version,termSequence,Terms.dnasequence) + + let pTetCD = new ComponentDefinition("pTet",urlPrefix,"r0040",version,[Terms.dnaRegion],[Terms.promoter],[pTetSeq],[],[]) + let rbsCD = new ComponentDefinition("rbs",urlPrefix,"b0034",version,[Terms.dnaRegion],[Terms.rbs],[rbsSeq],[],[]) + let tetRCD = new ComponentDefinition("tetR",urlPrefix,"c0040",version,[Terms.dnaRegion],[Terms.cds],[tetRSeq],[],[]) + let termCD = new ComponentDefinition("term",urlPrefix,"b0015",version,[Terms.dnaRegion],[Terms.terminator],[termSeq],[],[]) + + let protCD = new ComponentDefinition("tetR_protein",urlPrefix,"c0040p",version,[Terms.protein],[],[],[],[]) + + + let tuName = "tu1" + + let tuPrefix = urlPrefix + "/" + tuName + + let pTetComp = new Component("pTet",tuPrefix,"r0040",version, Terms.privateAccess, pTetCD.uri) + let rbsComp = new Component("rbs",tuPrefix,"b0034",version, Terms.privateAccess, rbsCD.uri) + let tetRComp = new Component("tetR",tuPrefix,"c0040",version, Terms.privateAccess, tetRCD.uri) + let termComp = new Component("term",tuPrefix,"b0015",version, Terms.privateAccess, termCD.uri) + + + //Range then Sequence Annotation + let pTetRange = new Range("range",tuPrefix + "annotation1/range", "r0040_range",version,1,pTetSequence.Length,Terms.inlineOrientation) + let rbsRange = new Range("range",tuPrefix + "annotation2/range", "b0034_range",version,pTetRange.endIndex+1, pTetRange.endIndex + rbsSequence.Length ,Terms.inlineOrientation) + let tetRRange = new Range("range",tuPrefix + "annotation3/range", "c0040_range",version,rbsRange.endIndex+1, rbsRange.endIndex + tetRSequence.Length ,Terms.inlineOrientation) + let termRange = new Range("range", tuPrefix + "annotation4/range", "b0015_range",version, tetRRange.endIndex+1,tetRRange.endIndex + termSequence.Length,Terms.inlineOrientation) + + let pTetsa = new SequenceAnnotation("annotation1",tuPrefix,"annotation1",version,pTetComp,[Location.Range(pTetRange)]) + pTetsa.description <- "prom" + let rbssa = new SequenceAnnotation("annotation2",tuPrefix,"annotation2",version,rbsComp,[Location.Range(rbsRange)]) + rbssa.description <- "rbs" + let tetRsa = new SequenceAnnotation("annotation3",tuPrefix,"annotation3",version,tetRComp,[Location.Range(tetRRange)]) + tetRsa.description <- "pcr" + let termsa = new SequenceAnnotation("annotation4",tuPrefix,"annotation4",version,termComp,[Location.Range(termRange)]) + termsa.description <- "ter" + + let tetRFC = new FunctionalComponent("tetR_FC",urlPrefix,"c0040_FC",version,Terms.privateAccess,Terms.fcInOut,tetRCD.uri) + let tetRProtFC = new FunctionalComponent("tetR_protein_FC",urlPrefix,"c0040p_FC",version,Terms.privateAccess,Terms.fcInOut,protCD.uri) + let tetRCmplxFC = new FunctionalComponent("tetR_complex_FC",urlPrefix,"c0040c_FC",version,Terms.privateAccess,Terms.fcInOut,protCD.uri) + let pTetFC = new FunctionalComponent("pTet_FC",urlPrefix,"r0040_FC",version,Terms.privateAccess,Terms.fcInOut,pTetCD.uri) + + let tetRPart = new Participation("tetR_P",urlPrefix,"c0040_Part",version,[Terms.template],tetRFC) + let tetRProtPart = new Participation("tetRProt_P",urlPrefix,"c0040p_Part",version,[Terms.product],tetRProtFC) + + let tetRCmplxPart = new Participation("tetRCmplx_P",urlPrefix,"c0040c_Part",version,[Terms.inhibitor],tetRCmplxFC) + let pTetPart = new Participation("pTet_P",urlPrefix,"r0040_Part",version,[Terms.inhibited],pTetFC) + + let interactionProd = new Interaction("tetR_production_interaction",urlPrefix,"production",version,[Terms.production],[tetRPart;tetRProtPart]) + let interactionInh = new Interaction("pTet_inhibition_interaction",urlPrefix,"inhibition",version,[Terms.inhibition],[tetRCmplxPart;pTetPart]) + + let mdProd = new ModuleDefinition("TetR_Production",urlPrefix,"production_md",version,[tetRFC;tetRProtFC],[interactionProd]) + let mdIntr = new ModuleDefinition("pTet_Inhibition",urlPrefix,"inhibition_md",version,[tetRCmplxFC;pTetFC],[interactionInh]) + + + let tuSeq = new Sequence(tuName + "_sequence",urlPrefix,"tu007_sequence",version, pTetSequence + rbsSequence + tetRSequence + termSequence ,Terms.dnasequence) + + //let tuCD = new ComponentDefinition(tuName,urlPrefix,"tu007",version,[Terms.dnaRegion],[Terms.engineeredRegion], tuSeq,[pTetComp;rbsComp;tetRComp;termComp],[pTetsa;rbssa;tetRsa;termsa]) + let tuCD = ComponentDefinition.createHigherFunction(tuName,urlPrefix,"tu007",version,[Terms.dnaRegion],[Terms.engineeredRegion],[pTetCD;rbsCD;tetRCD;termCD]) + + let xdoc = new XmlDocument(); + let rootXml = xdoc.CreateElement(QualifiedName.rdfQN,Terms.rdfns) + xdoc.AppendChild(rootXml) |> ignore + xdoc.DocumentElement.SetAttribute(QualifiedName.sbolQN,Terms.sbolns) + xdoc.DocumentElement.SetAttribute(QualifiedName.dctermsQN,Terms.dctermsns) + xdoc.DocumentElement.SetAttribute(QualifiedName.provQN,Terms.provns) + + + rootXml.AppendChild(XmlSerializer.serializeComponentDefinition xdoc pTetCD) |> ignore + rootXml.AppendChild(XmlSerializer.serializeComponentDefinition xdoc rbsCD) |> ignore + rootXml.AppendChild(XmlSerializer.serializeComponentDefinition xdoc tetRCD) |> ignore + rootXml.AppendChild(XmlSerializer.serializeComponentDefinition xdoc termCD) |> ignore + rootXml.AppendChild(XmlSerializer.serializeComponentDefinition xdoc protCD) |> ignore + rootXml.AppendChild(XmlSerializer.serializeSequence xdoc pTetSeq) |> ignore + rootXml.AppendChild(XmlSerializer.serializeSequence xdoc rbsSeq) |> ignore + rootXml.AppendChild(XmlSerializer.serializeSequence xdoc tetRSeq) |> ignore + rootXml.AppendChild(XmlSerializer.serializeSequence xdoc termSeq) |> ignore + rootXml.AppendChild(XmlSerializer.serializeComponentDefinition xdoc tuCD) |> ignore + rootXml.AppendChild(XmlSerializer.serializeSequence xdoc tuSeq) |> ignore + rootXml.AppendChild(XmlSerializer.serializeModuleDefinition xdoc mdProd) |> ignore + rootXml.AppendChild(XmlSerializer.serializeModuleDefinition xdoc mdIntr) |> ignore + + let sw = new StringWriter() + let xwSettings = new XmlWriterSettings() + xwSettings.Indent <- true + xwSettings.Encoding <- Encoding.UTF8 + let xw = XmlWriter.Create(sw,xwSettings) + xdoc.WriteTo(xw) + xw.Close() + + let doc = new SBOLDocument([TopLevel.ComponentDefinition(pTetCD);TopLevel.ComponentDefinition(rbsCD);TopLevel.ComponentDefinition(tetRCD);TopLevel.ComponentDefinition(termCD);TopLevel.ComponentDefinition(protCD);TopLevel.ComponentDefinition(tuCD);TopLevel.ModuleDefinition(mdProd);TopLevel.ModuleDefinition(mdIntr)]) + + Debug.WriteLine(sbolXmlString doc) + + let docback = SBOLDocumentFromXML (XmlSerializer.serializeSBOLDocument doc) + + let jsonSbol = JsonSerializer.serializeSBOLDocument doc + + let fwsw = new StreamWriter("circuit.xml",false) + let fwxwSettings = new XmlWriterSettings() + fwxwSettings.Indent <- true + fwxwSettings.Encoding <- Encoding.UTF8 + let fwxw = XmlWriter.Create(fwsw,fwxwSettings) + (XmlSerializer.serializeSBOLDocument doc).WriteTo(fwxw) + fwxw.Close() + + + + + //Debug.WriteLine(sw.ToString()) + + Debug.WriteLine("Success") + + diff --git a/FSBOLWrapper/FSBOLWrapper/FSBOLWrapper.fsproj b/FSBOLWrapper/FSBOLWrapper/FSBOLWrapper.fsproj new file mode 100644 index 0000000..b061493 --- /dev/null +++ b/FSBOLWrapper/FSBOLWrapper/FSBOLWrapper.fsproj @@ -0,0 +1,16 @@ + + + + netstandard2.0 + x64 + true + + + + + + + + + + \ No newline at end of file diff --git a/FSBOLWrapper/FSBOLWrapper/FromXML.test.fs b/FSBOLWrapper/FSBOLWrapper/FromXML.test.fs new file mode 100644 index 0000000..7c62998 --- /dev/null +++ b/FSBOLWrapper/FSBOLWrapper/FromXML.test.fs @@ -0,0 +1,25 @@ +module Microsoft.Research.FSBOL.FromXMLTest + +open Microsoft.Research.FSBOL.Sequence + + +open Xunit +open FsUnit.Xunit +open System +open System.Diagnostics +open System.Xml +open System.IO +open System.Text + +[] +let ``fromSequenceXML``() = + let uriPrefix = "www.microsoft.com/gec" + let version = "1" + let name = "pTet" + let seq = "atcgga" + let encoding = Terms.dnasequence + let displayId = name; + let s:Sequence = new Sequence(name,uriPrefix,displayId,version, seq,encoding) + + Debug.WriteLine("End of test") + diff --git a/FSBOLWrapper/FSBOLWrapper/GECHelper.fs b/FSBOLWrapper/FSBOLWrapper/GECHelper.fs new file mode 100644 index 0000000..b4a0aa3 --- /dev/null +++ b/FSBOLWrapper/FSBOLWrapper/GECHelper.fs @@ -0,0 +1,96 @@ +[] +module Microsoft.Research.FSBOLWrapper.GECHelper + + +open FSBOL.ComponentDefinition +open FSBOL.SequenceAnnotation +open FSBOL.Component +open FSBOL.Range +open FSBOL.Sequence +open FSBOL.ComponentInstance +open FSBOL.Location + +let createComponent = + let innerFn (cd:ComponentDefinition)= + let uri = Helper.append_url cd.uri "component" + let name = Helper.append_name cd.name "component" + let displayId = Helper.append_name cd.displayId "component" + let persistentid = Helper.append_url_option cd.persistentIdentity "component" + Component(uri,name,displayId,cd.version,persistentid,cd.uri,Access.Private,[],cd.roles,[]) + innerFn + +let createSequenceAnnotations (components:Component list) = + [0..(components.Length-1)] + |> List.map (fun i -> + let c = components.Item(i) + let uri = Helper.append_url c.uri ("sa" + i.ToString()) + let name = Helper.append_name c.name ("sa" + i.ToString()) + let displayId = Helper.append_name c.displayId ("sa" + i.ToString()) + let persistentid = Helper.append_url_option c.persistentIdentity ("sa" + i.ToString()) + + let uri_range = Helper.append_url uri ("range") + let name_range = Helper.append_name name ("range") + let displayId_range = Helper.append_name displayId ("range") + let persistentid_range = Helper.append_url_option persistentid ("range") + let r = Range(uri_range,name_range,displayId_range,c.version,persistentid_range,Orientation.Inline,(i+1),(i+1)) + + SequenceAnnotation(uri,name,displayId,c.version,persistentid,Some(c),[r],c.roles) + ) + +let createHigherFunction (name:string) (persistentId:string) (version:string) (cdlist:ComponentDefinition list) = + let uri = persistentId + "/" + version + "/" + + let components = cdlist |> List.map (fun x -> createComponent x) + //let createComponentForUrlPrefix = ComponentDefinition.createComponent urlPrefix + //let componentList = components |> List.map createComponentForUrlPrefix + //let rangeList = ComponentDefinition.createRanges urlPrefix components + //let indexList = [1 .. components.Length] + + //let forSA = List.zip3 indexList componentList rangeList + //let sequenceAnnotationForUrlPrefix = ComponentDefinition.createSequenceAnnotationFromSingleRange urlPrefix + //let sequenceAnnotations = forSA |> List.map sequenceAnnotationForUrlPrefix + //let seq = Sequence(name+"_sequence",urlPrefix,displayId+"_sequence",version,ComponentDefinition.getConcatenatedSequence(components),Terms.dnasequence) + + let sequenceAnnotations = createSequenceAnnotations components + ComponentDefinition(uri,Some(name),Some(name),Some(version),Some(persistentId),[],[ComponentDefinitionType.DNA],[FSBOL.Role.Role.EngineeredGene],[],components,sequenceAnnotations,[]) + + +(*let createRanges (urlPrefix:string) (cdList:ComponentDefinition list)= + let mutable index = 1; + let mutable start:int = 1; + let ranges:System.Collections.Generic.List = new System.Collections.Generic.List() + for (cd:ComponentDefinition) in cdList do + if List.isEmpty cd.sequences then + ranges.Add(Range("range",urlPrefix + "/annotation" + index.ToString() + "/range",cd.displayId+"_range",cd.version,start,start,Terms.inlineOrientation)) + start <- start+1 + index <- index+1 + else + for (seq:Sequence) in cd.sequences do + match seq.elements with + | "" -> + ranges.Add(Range("range",urlPrefix + "/annotation" + index.ToString() + "/range",cd.displayId+"_range",cd.version,start,start,Terms.inlineOrientation)) + start <- start + 1 + index <- index+1 + | _ -> + ranges.Add(Range("range",urlPrefix + "/annotation" + index.ToString() + "/range",cd.displayId+"_range",cd.version,start,start + seq.elements.Length-1,Terms.inlineOrientation)) + start <- start + seq.elements.Length + index <- index+1 + + + + let rangeList = ranges.ToArray() |> Array.toList + rangeList + + +let getConcatenatedSequence (cdList:ComponentDefinition list) = + let rec concatSeq (cdListL:ComponentDefinition list) = + match cdListL with + | [] -> "" + | cd :: remaining -> + let concaternatedSequence = cd.sequences |> List.fold (fun acc (seq:Sequence) -> (acc + seq.elements) ) "" + concaternatedSequence + concatSeq(remaining) + + concatSeq cdList + + +*) \ No newline at end of file diff --git a/FSBOLWrapper/FSBOLWrapper/Sequence.test.fs b/FSBOLWrapper/FSBOLWrapper/Sequence.test.fs new file mode 100644 index 0000000..911a9f1 --- /dev/null +++ b/FSBOLWrapper/FSBOLWrapper/Sequence.test.fs @@ -0,0 +1,24 @@ +module Microsoft.Research.FSBOL.SequenceTest + +open Microsoft.Research.FSBOL.Sequence +open Microsoft.Research.FSBOL.Terms + +open Xunit +open FsUnit.Xunit +open System +open System.Diagnostics + + +[] +let ``RunTest``() = + let uriPrefix = "www.microsoft.com/gec/" + let version = "1" + let name = "pTet" + let seq = "atcgga" + let encoding = Terms.dnasequence + let displayId = name; + let s:Sequence = new Sequence(name,uriPrefix,displayId,version, seq,encoding) + s.description <- "This is a test Sequence" + + Debug.WriteLine("Wrote it") + diff --git a/FSBOLWrapper/FSBOLWrapper/app.config b/FSBOLWrapper/FSBOLWrapper/app.config new file mode 100644 index 0000000..2bc077c --- /dev/null +++ b/FSBOLWrapper/FSBOLWrapper/app.config @@ -0,0 +1,13 @@ + + + + + + + + + True + + + + \ No newline at end of file diff --git a/FSBOLWrapper/FSBOLWrapper/helper.fs b/FSBOLWrapper/FSBOLWrapper/helper.fs new file mode 100644 index 0000000..2af3f72 --- /dev/null +++ b/FSBOLWrapper/FSBOLWrapper/helper.fs @@ -0,0 +1,32 @@ +[] +module Microsoft.Research.FSBOLWrapper.Helper + +open FSBOL.Annotation + + +let append_url (uri:string) (term:string) = + match uri.EndsWith "/" with + | true -> uri + term + "/" + | false -> uri + "/" + term + "/" + +let append_id (uri:string) (version:string option) (term:string) = + () + +let append_name (str:string option) (term:string) = + match str with + | Some(s) -> Some(s+"_"+term) + | None -> None + +let append_url_option (uri:string option) (term:string) = + match uri with + | Some(u) -> Some(append_url u term) + | None -> None + +let create_string_annotation (key:QName) (value:string) = + Annotation(key,Literal(String(value))) + +let create_double_annotation (key:QName) (value:double) = + Annotation(key,Literal(Double(value))) + +let create_uri_annotation (key:QName) (uri:string) = + Annotation(key,Uri(uri)) \ No newline at end of file diff --git a/FSBOLWrapper/FSBOLWrapper/paket.references b/FSBOLWrapper/FSBOLWrapper/paket.references new file mode 100644 index 0000000..56f47de --- /dev/null +++ b/FSBOLWrapper/FSBOLWrapper/paket.references @@ -0,0 +1,10 @@ +group NETSTANDARD + +#FsCheck +#FsUnit.xUnit +#xunit.core +#xunit.runner.console +#xunit.runner.visualstudio +FSharp.Collections.ParallelSeq +FSharp.Core +FSBOL diff --git a/FSBOLWrapper/FSBOLWrapperJS.sln b/FSBOLWrapper/FSBOLWrapperJS.sln new file mode 100644 index 0000000..73a7318 --- /dev/null +++ b/FSBOLWrapper/FSBOLWrapperJS.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26730.3 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSBOLWrapperJS", "FSBOLWrapperJS\FSBOLWrapperJS.fsproj", "{BEA2FCED-63E6-404B-8A4E-33B03D05B49C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {BEA2FCED-63E6-404B-8A4E-33B03D05B49C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BEA2FCED-63E6-404B-8A4E-33B03D05B49C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BEA2FCED-63E6-404B-8A4E-33B03D05B49C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BEA2FCED-63E6-404B-8A4E-33B03D05B49C}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {3F5697BD-E3C9-4606-91C2-FF348F6D0DB6} + EndGlobalSection +EndGlobal diff --git a/FSBOLWrapper/FSBOLWrapperJS/FSBOLWrapperJS.fsproj b/FSBOLWrapper/FSBOLWrapperJS/FSBOLWrapperJS.fsproj new file mode 100644 index 0000000..aa65bf4 --- /dev/null +++ b/FSBOLWrapper/FSBOLWrapperJS/FSBOLWrapperJS.fsproj @@ -0,0 +1,24 @@ + + + + netstandard2.0 + true + + + TRACE;JavaScript + + + TRACE;JavaScript + + + + + + + + + ..\..\Lib\Oslo-FSharp.websharper\Oslo.FSharp.WebSharper.dll + + + + \ No newline at end of file diff --git a/FSBOLWrapper/FSBOLWrapperJS/paket.references b/FSBOLWrapper/FSBOLWrapperJS/paket.references new file mode 100644 index 0000000..074a29b --- /dev/null +++ b/FSBOLWrapper/FSBOLWrapperJS/paket.references @@ -0,0 +1,4 @@ +group NETSTANDARD + FSharp.Core + WebSharper.FSharp + FSBOLJS \ No newline at end of file