Search in sources :

Example 1 with AlgorithmParameter

use of org.jlibsedml.AlgorithmParameter in project vcell by virtualcell.

the class SEDMLExporter method translateBioModelToSedML.

private void translateBioModelToSedML(String savePath, String sBaseFileName, boolean bForceVCML, boolean bHasDataOnly, boolean bFromOmex) {
    // true if invoked for omex export, false if for sedml
    sbmlFilePathStrAbsoluteList.clear();
    // models
    try {
        SimulationContext[] simContexts = vcBioModel.getSimulationContexts();
        cbit.vcell.model.Model vcModel = vcBioModel.getModel();
        // "urn:sedml:language:sbml";
        String sbmlLanguageURN = SUPPORTED_LANGUAGE.SBML_GENERIC.getURN();
        // "urn:sedml:language:vcml";
        String vcmlLanguageURN = SUPPORTED_LANGUAGE.VCELL_GENERIC.getURN();
        String bioModelName = vcBioModel.getName();
        String bioModelID = TokenMangler.mangleToSName(bioModelName);
        // String usrHomeDirPath = ResourceUtil.getUserHomeDir().getAbsolutePath();
        // to get Xpath string for variables.
        SBMLSupport sbmlSupport = new SBMLSupport();
        // for model count, task subcount
        int simContextCnt = 0;
        boolean bSpeciesAddedAsDataGens = false;
        String sedmlNotesStr = "";
        for (SimulationContext simContext : simContexts) {
            // Export the application itself to SBML, with default overrides
            String sbmlString = null;
            int level = 3;
            int version = 1;
            boolean isSpatial = simContext.getGeometry().getDimension() > 0 ? true : false;
            // local to global translation map
            Map<Pair<String, String>, String> l2gMap = null;
            boolean sbmlExportFailed = false;
            if (!bForceVCML) {
                // we try to save to SBML
                try {
                    // to compute and set the sizes of the remaining structures.
                    if (!simContext.getGeometryContext().isAllSizeSpecifiedPositive()) {
                        Structure structure = simContext.getModel().getStructure(0);
                        double structureSize = 1.0;
                        StructureMapping structMapping = simContext.getGeometryContext().getStructureMapping(structure);
                        StructureSizeSolver.updateAbsoluteStructureSizes(simContext, structure, structureSize, structMapping.getSizeParameter().getUnitDefinition());
                    // StructureMapping structureMapping = simContext.getGeometryContext().getStructureMappings()[0];
                    // StructureSizeSolver.updateAbsoluteStructureSizes(simContext, structureMapping.getStructure(), 1.0, structureMapping.getSizeParameter().getUnitDefinition());
                    }
                    SBMLExporter sbmlExporter = new SBMLExporter(vcBioModel, level, version, isSpatial);
                    sbmlExporter.setSelectedSimContext(simContext);
                    // no sim job
                    sbmlExporter.setSelectedSimulationJob(null);
                    sbmlString = sbmlExporter.getSBMLString();
                    l2gMap = sbmlExporter.getLocalToGlobalTranslationMap();
                } catch (Exception e) {
                    sbmlExportFailed = true;
                }
            } else {
                // we want to force VCML, we act as if saving to SBML failed
                sbmlExportFailed = true;
            }
            // marked as failed, even if exporting to sbml didn't throw any exception
            if (simContext.getGeometry().getDimension() > 0 && simContext.getApplicationType() == Application.NETWORK_STOCHASTIC) {
                sbmlExportFailed = true;
            } else if (simContext.getApplicationType() == Application.RULE_BASED_STOCHASTIC) {
                sbmlExportFailed = true;
            }
            String simContextName = simContext.getName();
            String filePathStrAbsolute = null;
            String filePathStrRelative = null;
            String urn = null;
            String simContextId = null;
            if (sbmlExportFailed) {
                // filePathStrAbsolute = Paths.get(savePath, bioModelName + ".vcml").toString();
                filePathStrAbsolute = Paths.get(savePath, sBaseFileName + ".vcml").toString();
                // filePathStrRelative = bioModelName + ".vcml";
                filePathStrRelative = sBaseFileName + ".vcml";
                if (!bFromOmex) {
                    // the vcml file is managed elsewhere when called for omex
                    String vcmlString = XmlHelper.bioModelToXML(vcBioModel);
                    XmlUtil.writeXMLStringToFile(vcmlString, filePathStrAbsolute, true);
                    sbmlFilePathStrAbsoluteList.add(filePathStrRelative);
                }
                urn = vcmlLanguageURN;
                sedmlModel.addModel(new Model(bioModelID, bioModelName, urn, filePathStrRelative));
            } else {
                // filePathStrAbsolute = Paths.get(savePath, bioModelName + "_" + TokenMangler.mangleToSName(simContextName) + ".xml").toString();
                filePathStrAbsolute = Paths.get(savePath, sBaseFileName + "_" + TokenMangler.mangleToSName(simContextName) + ".xml").toString();
                // filePathStrRelative = bioModelName + "_" +  TokenMangler.mangleToSName(simContextName) + ".xml";
                filePathStrRelative = sBaseFileName + "_" + TokenMangler.mangleToSName(simContextName) + ".xml";
                XmlUtil.writeXMLStringToFile(sbmlString, filePathStrAbsolute, true);
                urn = sbmlLanguageURN;
                sbmlFilePathStrAbsoluteList.add(filePathStrRelative);
                simContextId = TokenMangler.mangleToSName(simContextName);
                sedmlModel.addModel(new Model(simContextId, simContextName, urn, filePathStrRelative));
            }
            MathMapping mathMapping = simContext.createNewMathMapping();
            MathSymbolMapping mathSymbolMapping = mathMapping.getMathSymbolMapping();
            // -------
            // create sedml objects (simulation, task, datagenerators, report, plot) for each simulation in simcontext
            // -------
            int simCount = 0;
            String taskRef = null;
            int overrideCount = 0;
            for (Simulation vcSimulation : simContext.getSimulations()) {
                if (bHasDataOnly) {
                    // skip simulations not present in hash
                    if (!simsToExport.contains(vcSimulation))
                        continue;
                }
                // 1 -------> check compatibility
                // if simContext is non-spatial stochastic, check if sim is histogram; if so, skip it, it can't be encoded in sedml 1.x
                SolverTaskDescription simTaskDesc = vcSimulation.getSolverTaskDescription();
                if (simContext.getGeometry().getDimension() == 0 && simContext.isStoch()) {
                    long numOfTrials = simTaskDesc.getStochOpt().getNumOfTrials();
                    if (numOfTrials > 1) {
                        String msg = "\n\t" + simContextName + " ( " + vcSimulation.getName() + " ) : export of non-spatial stochastic simulation with histogram option to SEDML not supported at this time.";
                        sedmlNotesStr += msg;
                        continue;
                    }
                }
                // 2 ------->
                // create Algorithm and sedmlSimulation (UniformtimeCourse)
                SolverDescription vcSolverDesc = simTaskDesc.getSolverDescription();
                String kiSAOIdStr = vcSolverDesc.getKisao();
                Algorithm sedmlAlgorithm = new Algorithm(kiSAOIdStr);
                TimeBounds vcSimTimeBounds = simTaskDesc.getTimeBounds();
                double startingTime = vcSimTimeBounds.getStartingTime();
                String simName = vcSimulation.getName();
                UniformTimeCourse utcSim = new UniformTimeCourse(TokenMangler.mangleToSName(simName), simName, startingTime, startingTime, vcSimTimeBounds.getEndingTime(), (int) simTaskDesc.getExpectedNumTimePoints(), sedmlAlgorithm);
                // --------- deal with error tolerance
                boolean enableAbsoluteErrorTolerance;
                boolean enableRelativeErrorTolerance;
                if (vcSolverDesc.isSemiImplicitPdeSolver() || vcSolverDesc.isChomboSolver()) {
                    enableAbsoluteErrorTolerance = false;
                    enableRelativeErrorTolerance = true;
                } else if (vcSolverDesc.hasErrorTolerance()) {
                    enableAbsoluteErrorTolerance = true;
                    enableRelativeErrorTolerance = true;
                } else {
                    enableAbsoluteErrorTolerance = false;
                    enableRelativeErrorTolerance = false;
                }
                if (enableAbsoluteErrorTolerance) {
                    ErrorTolerance et = simTaskDesc.getErrorTolerance();
                    String kisaoStr = ErrorTolerance.ErrorToleranceDescription.Absolute.getKisao();
                    AlgorithmParameter sedmlAlgorithmParameter = new AlgorithmParameter(kisaoStr, et.getAbsoluteErrorTolerance() + "");
                    sedmlAlgorithm.addAlgorithmParameter(sedmlAlgorithmParameter);
                }
                if (enableRelativeErrorTolerance) {
                    ErrorTolerance et = simTaskDesc.getErrorTolerance();
                    String kisaoStr = ErrorTolerance.ErrorToleranceDescription.Relative.getKisao();
                    AlgorithmParameter sedmlAlgorithmParameter = new AlgorithmParameter(kisaoStr, et.getRelativeErrorTolerance() + "");
                    sedmlAlgorithm.addAlgorithmParameter(sedmlAlgorithmParameter);
                }
                // ---------- deal with time step (code adapted from TimeSpecPanel.refresh()
                boolean enableDefaultTimeStep;
                boolean enableMinTimeStep;
                boolean enableMaxTimeStep;
                if (vcSolverDesc.compareEqual(SolverDescription.StochGibson)) {
                    // stochastic time
                    enableDefaultTimeStep = false;
                    enableMinTimeStep = false;
                    enableMaxTimeStep = false;
                } else if (vcSolverDesc.compareEqual(SolverDescription.NFSim)) {
                    enableDefaultTimeStep = false;
                    enableMinTimeStep = false;
                    enableMaxTimeStep = false;
                } else {
                    // fixed time step solvers and non spatial stochastic solvers only show default time step.
                    if (!vcSolverDesc.hasVariableTimestep() || vcSolverDesc.isNonSpatialStochasticSolver()) {
                        enableDefaultTimeStep = true;
                        enableMinTimeStep = false;
                        enableMaxTimeStep = false;
                    } else {
                        // variable time step solvers shows min and max, but sundials solvers don't show min
                        enableDefaultTimeStep = false;
                        enableMinTimeStep = true;
                        enableMaxTimeStep = true;
                        if (vcSolverDesc.hasSundialsTimeStepping()) {
                            enableMinTimeStep = false;
                        }
                    }
                }
                TimeStep ts = simTaskDesc.getTimeStep();
                if (enableDefaultTimeStep) {
                    String kisaoStr = TimeStep.TimeStepDescription.Default.getKisao();
                    AlgorithmParameter sedmlAlgorithmParameter = new AlgorithmParameter(kisaoStr, ts.getDefaultTimeStep() + "");
                    sedmlAlgorithm.addAlgorithmParameter(sedmlAlgorithmParameter);
                }
                if (enableMinTimeStep) {
                    String kisaoStr = TimeStep.TimeStepDescription.Minimum.getKisao();
                    AlgorithmParameter sedmlAlgorithmParameter = new AlgorithmParameter(kisaoStr, ts.getMinimumTimeStep() + "");
                    sedmlAlgorithm.addAlgorithmParameter(sedmlAlgorithmParameter);
                }
                if (enableMaxTimeStep) {
                    String kisaoStr = TimeStep.TimeStepDescription.Maximum.getKisao();
                    AlgorithmParameter sedmlAlgorithmParameter = new AlgorithmParameter(kisaoStr, ts.getMaximumTimeStep() + "");
                    sedmlAlgorithm.addAlgorithmParameter(sedmlAlgorithmParameter);
                }
                if (simTaskDesc.getSimulation().getMathDescription().isNonSpatialStoch()) {
                    // ------- deal with seed
                    NonspatialStochSimOptions nssso = simTaskDesc.getStochOpt();
                    if (nssso.isUseCustomSeed()) {
                        // 488
                        String kisaoStr = SolverDescription.AlgorithmParameterDescription.Seed.getKisao();
                        AlgorithmParameter sedmlAlgorithmParameter = new AlgorithmParameter(kisaoStr, nssso.getCustomSeed() + "");
                        sedmlAlgorithm.addAlgorithmParameter(sedmlAlgorithmParameter);
                    }
                } else {
                    // (... isRuleBased(), isSpatial(), isMovingMembrane(), isSpatialHybrid() ...
                    ;
                }
                if (// -------- deal with hybrid solvers (non-spatial)
                vcSolverDesc == SolverDescription.HybridEuler || vcSolverDesc == SolverDescription.HybridMilAdaptive || vcSolverDesc == SolverDescription.HybridMilstein) {
                    NonspatialStochHybridOptions nssho = simTaskDesc.getStochHybridOpt();
                    String kisaoStr = SolverDescription.AlgorithmParameterDescription.Epsilon.getKisao();
                    AlgorithmParameter sedmlAlgorithmParameter = new AlgorithmParameter(kisaoStr, nssho.getEpsilon() + "");
                    sedmlAlgorithm.addAlgorithmParameter(sedmlAlgorithmParameter);
                    kisaoStr = SolverDescription.AlgorithmParameterDescription.Lambda.getKisao();
                    sedmlAlgorithmParameter = new AlgorithmParameter(kisaoStr, nssho.getLambda() + "");
                    sedmlAlgorithm.addAlgorithmParameter(sedmlAlgorithmParameter);
                    kisaoStr = SolverDescription.AlgorithmParameterDescription.MSRTolerance.getKisao();
                    sedmlAlgorithmParameter = new AlgorithmParameter(kisaoStr, nssho.getMSRTolerance() + "");
                    sedmlAlgorithm.addAlgorithmParameter(sedmlAlgorithmParameter);
                }
                if (vcSolverDesc == SolverDescription.HybridMilAdaptive) {
                    // --------- one more param for hybrid-adaptive
                    NonspatialStochHybridOptions nssho = simTaskDesc.getStochHybridOpt();
                    String kisaoStr = SolverDescription.AlgorithmParameterDescription.SDETolerance.getKisao();
                    AlgorithmParameter sedmlAlgorithmParameter = new AlgorithmParameter(kisaoStr, nssho.getSDETolerance() + "");
                    sedmlAlgorithm.addAlgorithmParameter(sedmlAlgorithmParameter);
                }
                // TODO: consider adding notes for the algorithm parameters, to provide human-readable description of kisao terms
                // sedmlAlgorithm.addNote(createNotesElement(algorithmNotesStr));
                // TODO: even better, AlgorithmParameter in sed-ml should also have a human readable "name" field
                // add a note to utcSim to indicate actual solver name
                String simNotesStr = "Actual Solver Name : '" + vcSolverDesc.getDisplayLabel() + "'.";
                utcSim.addNote(createNotesElement(simNotesStr));
                sedmlModel.addSimulation(utcSim);
                // 3 ------->
                // create Tasks
                MathOverrides mathOverrides = vcSimulation.getMathOverrides();
                if ((sbmlExportFailed == false) && mathOverrides != null && mathOverrides.hasOverrides()) {
                    String[] overridenConstantNames = mathOverrides.getOverridenConstantNames();
                    String[] scannedConstantsNames = mathOverrides.getScannedConstantNames();
                    HashMap<String, String> scannedParamHash = new HashMap<String, String>();
                    HashMap<String, String> unscannedParamHash = new HashMap<String, String>();
                    for (String name : scannedConstantsNames) {
                        scannedParamHash.put(name, name);
                    }
                    for (String name : overridenConstantNames) {
                        if (!scannedParamHash.containsKey(name)) {
                            unscannedParamHash.put(name, name);
                        }
                    }
                    if (!unscannedParamHash.isEmpty() && scannedParamHash.isEmpty()) {
                        // only parameters with simple overrides (numeric/expression) no scans
                        // create new model with change for each parameter that has override; add simple task
                        String overriddenSimContextId = simContextId + "_" + overrideCount;
                        String overriddenSimContextName = simContextName + " modified";
                        Model sedModel = new Model(overriddenSimContextId, overriddenSimContextName, sbmlLanguageURN, simContextId);
                        overrideCount++;
                        for (String unscannedParamName : unscannedParamHash.values()) {
                            SymbolTableEntry ste = getSymbolTableEntryForModelEntity(mathSymbolMapping, unscannedParamName);
                            Expression unscannedParamExpr = mathOverrides.getActualExpression(unscannedParamName, 0);
                            if (unscannedParamExpr.isNumeric()) {
                                // if expression is numeric, add ChangeAttribute to model created above
                                XPathTarget targetXpath = getTargetAttributeXPath(ste, l2gMap);
                                ChangeAttribute changeAttribute = new ChangeAttribute(targetXpath, unscannedParamExpr.infix());
                                sedModel.addChange(changeAttribute);
                            } else {
                                // non-numeric expression : add 'computeChange' to modified model
                                ASTNode math = Libsedml.parseFormulaString(unscannedParamExpr.infix());
                                XPathTarget targetXpath = getTargetXPath(ste, l2gMap);
                                ComputeChange computeChange = new ComputeChange(targetXpath, math);
                                String[] exprSymbols = unscannedParamExpr.getSymbols();
                                // }
                                for (String symbol : exprSymbols) {
                                    String symbolName = TokenMangler.mangleToSName(symbol);
                                    SymbolTableEntry ste1 = vcModel.getEntry(symbol);
                                    if (ste != null) {
                                        if (ste1 instanceof SpeciesContext || ste1 instanceof Structure || ste1 instanceof ModelParameter) {
                                            XPathTarget ste1_XPath = getTargetXPath(ste1, l2gMap);
                                            org.jlibsedml.Variable sedmlVar = new org.jlibsedml.Variable(symbolName, symbolName, taskRef, ste1_XPath.getTargetAsString());
                                            computeChange.addVariable(sedmlVar);
                                        } else {
                                            double doubleValue = 0.0;
                                            if (ste1 instanceof ReservedSymbol) {
                                                doubleValue = getReservedSymbolValue(ste1);
                                            }
                                            Parameter sedmlParameter = new Parameter(symbolName, symbolName, doubleValue);
                                            computeChange.addParameter(sedmlParameter);
                                        }
                                    } else {
                                        throw new RuntimeException("Symbol '" + symbol + "' used in expression for '" + unscannedParamName + "' not found in model.");
                                    }
                                }
                                sedModel.addChange(computeChange);
                            }
                        }
                        sedmlModel.addModel(sedModel);
                        String taskId = "tsk_" + simContextCnt + "_" + simCount;
                        Task sedmlTask = new Task(taskId, vcSimulation.getName(), sedModel.getId(), utcSim.getId());
                        sedmlModel.addTask(sedmlTask);
                        // to be used later to add dataGenerators : one set of DGs per model (simContext).
                        taskRef = taskId;
                    } else if (!scannedParamHash.isEmpty() && unscannedParamHash.isEmpty()) {
                        // only parameters with scans : only add 1 Task and 1 RepeatedTask
                        String taskId = "tsk_" + simContextCnt + "_" + simCount;
                        Task sedmlTask = new Task(taskId, vcSimulation.getName(), simContextId, utcSim.getId());
                        sedmlModel.addTask(sedmlTask);
                        String repeatedTaskId = "repTsk_" + simContextCnt + "_" + simCount;
                        // TODO: temporary solution - we use as range here the first range
                        String scn = scannedConstantsNames[0];
                        String rId = "range_" + simContextCnt + "_" + simCount + "_" + scn;
                        RepeatedTask rt = new RepeatedTask(repeatedTaskId, repeatedTaskId, true, rId);
                        // to be used later to add dataGenerators - in our case it has to be the repeated task
                        taskRef = repeatedTaskId;
                        SubTask subTask = new SubTask("0", taskId);
                        rt.addSubtask(subTask);
                        for (String scannedConstName : scannedConstantsNames) {
                            ConstantArraySpec constantArraySpec = mathOverrides.getConstantArraySpec(scannedConstName);
                            String rangeId = "range_" + simContextCnt + "_" + simCount + "_" + scannedConstName;
                            // list of Ranges, if sim is parameter scan.
                            if (constantArraySpec != null) {
                                Range r = null;
                                // System.out.println("     " + constantArraySpec.toString());
                                if (constantArraySpec.getType() == ConstantArraySpec.TYPE_INTERVAL) {
                                    // ------ Uniform Range
                                    r = new UniformRange(rangeId, constantArraySpec.getMinValue(), constantArraySpec.getMaxValue(), constantArraySpec.getNumValues());
                                    rt.addRange(r);
                                } else {
                                    // ----- Vector Range
                                    cbit.vcell.math.Constant[] cs = constantArraySpec.getConstants();
                                    ArrayList<Double> values = new ArrayList<Double>();
                                    for (int i = 0; i < cs.length; i++) {
                                        String value = cs[i].getExpression().infix();
                                        values.add(Double.parseDouble(value));
                                    }
                                    r = new VectorRange(rangeId, values);
                                    rt.addRange(r);
                                }
                                // list of Changes
                                SymbolTableEntry ste = getSymbolTableEntryForModelEntity(mathSymbolMapping, scannedConstName);
                                XPathTarget target = getTargetXPath(ste, l2gMap);
                                // ASTNode math1 = new ASTCi(r.getId());		// was scannedConstName
                                ASTNode math1 = Libsedml.parseFormulaString(r.getId());
                                SetValue setValue = new SetValue(target, r.getId(), simContextId);
                                setValue.setMath(math1);
                                rt.addChange(setValue);
                            } else {
                                throw new RuntimeException("No scan ranges found for scanned parameter : '" + scannedConstName + "'.");
                            }
                        }
                        sedmlModel.addTask(rt);
                    } else {
                        // both scanned and simple parameters : create new model with change for each simple override; add RepeatedTask
                        // create new model with change for each unscanned parameter that has override
                        String overriddenSimContextId = simContextId + "_" + overrideCount;
                        String overriddenSimContextName = simContextName + " modified";
                        Model sedModel = new Model(overriddenSimContextId, overriddenSimContextName, sbmlLanguageURN, simContextId);
                        overrideCount++;
                        String taskId = "tsk_" + simContextCnt + "_" + simCount;
                        Task sedmlTask = new Task(taskId, vcSimulation.getName(), overriddenSimContextId, utcSim.getId());
                        sedmlModel.addTask(sedmlTask);
                        // scanned parameters
                        String repeatedTaskId = "repTsk_" + simContextCnt + "_" + simCount;
                        // TODO: temporary solution - we use as range here the first range
                        String scn = scannedConstantsNames[0];
                        String rId = "range_" + simContextCnt + "_" + simCount + "_" + scn;
                        RepeatedTask rt = new RepeatedTask(repeatedTaskId, repeatedTaskId, true, rId);
                        // to be used later to add dataGenerators - in our case it has to be the repeated task
                        taskRef = repeatedTaskId;
                        SubTask subTask = new SubTask("0", taskId);
                        rt.addSubtask(subTask);
                        for (String scannedConstName : scannedConstantsNames) {
                            ConstantArraySpec constantArraySpec = mathOverrides.getConstantArraySpec(scannedConstName);
                            String rangeId = "range_" + simContextCnt + "_" + simCount + "_" + scannedConstName;
                            // list of Ranges, if sim is parameter scan.
                            if (constantArraySpec != null) {
                                Range r = null;
                                // System.out.println("     " + constantArraySpec.toString());
                                if (constantArraySpec.getType() == ConstantArraySpec.TYPE_INTERVAL) {
                                    // ------ Uniform Range
                                    r = new UniformRange(rangeId, constantArraySpec.getMinValue(), constantArraySpec.getMaxValue(), constantArraySpec.getNumValues());
                                    rt.addRange(r);
                                } else {
                                    // ----- Vector Range
                                    cbit.vcell.math.Constant[] cs = constantArraySpec.getConstants();
                                    ArrayList<Double> values = new ArrayList<Double>();
                                    for (int i = 0; i < cs.length; i++) {
                                        String value = cs[i].getExpression().infix() + ", ";
                                        values.add(Double.parseDouble(value));
                                    }
                                    r = new VectorRange(rangeId, values);
                                    rt.addRange(r);
                                }
                                // use scannedParamHash to store rangeId for that param, since it might be needed if unscanned param has a scanned param in expr.
                                if (scannedParamHash.get(scannedConstName).equals(scannedConstName)) {
                                    // the hash was originally populated as <scannedParamName, scannedParamName>. Replace 'value' with rangeId for scannedParam
                                    scannedParamHash.put(scannedConstName, r.getId());
                                }
                                // create setValue for scannedConstName
                                SymbolTableEntry ste2 = getSymbolTableEntryForModelEntity(mathSymbolMapping, scannedConstName);
                                XPathTarget target1 = getTargetXPath(ste2, l2gMap);
                                ASTNode math1 = new ASTCi(scannedConstName);
                                SetValue setValue1 = new SetValue(target1, r.getId(), sedModel.getId());
                                setValue1.setMath(math1);
                                rt.addChange(setValue1);
                            } else {
                                throw new RuntimeException("No scan ranges found for scanned parameter : '" + scannedConstName + "'.");
                            }
                        }
                        // for unscanned parameter overrides
                        for (String unscannedParamName : unscannedParamHash.values()) {
                            SymbolTableEntry ste = getSymbolTableEntryForModelEntity(mathSymbolMapping, unscannedParamName);
                            Expression unscannedParamExpr = mathOverrides.getActualExpression(unscannedParamName, 0);
                            if (unscannedParamExpr.isNumeric()) {
                                // if expression is numeric, add ChangeAttribute to model created above
                                XPathTarget targetXpath = getTargetAttributeXPath(ste, l2gMap);
                                ChangeAttribute changeAttribute = new ChangeAttribute(targetXpath, unscannedParamExpr.infix());
                                sedModel.addChange(changeAttribute);
                            } else {
                                // check for any scanned parameter in unscanned parameter expression
                                ASTNode math = Libsedml.parseFormulaString(unscannedParamExpr.infix());
                                String[] exprSymbols = unscannedParamExpr.getSymbols();
                                boolean bHasScannedParameter = false;
                                String scannedParamNameInUnscannedParamExp = null;
                                for (String symbol : exprSymbols) {
                                    if (scannedParamHash.get(symbol) != null) {
                                        bHasScannedParameter = true;
                                        scannedParamNameInUnscannedParamExp = new String(symbol);
                                        // @TODO check for multiple scannedParameters in expression.
                                        break;
                                    }
                                }
                                // (scanned parameter in expr) ? (add setValue for unscanned param in repeatedTask) : (add computeChange to modifiedModel)
                                if (bHasScannedParameter && scannedParamNameInUnscannedParamExp != null) {
                                    // create setValue for unscannedParamName (which contains a scanned param in its expression)
                                    SymbolTableEntry entry = getSymbolTableEntryForModelEntity(mathSymbolMapping, unscannedParamName);
                                    XPathTarget target = getTargetXPath(entry, l2gMap);
                                    String rangeId = scannedParamHash.get(scannedParamNameInUnscannedParamExp);
                                    // @TODO: we have no range??
                                    SetValue setValue = new SetValue(target, rangeId, sedModel.getId());
                                    setValue.setMath(math);
                                    rt.addChange(setValue);
                                } else {
                                    // non-numeric expression : add 'computeChange' to modified model
                                    XPathTarget targetXpath = getTargetXPath(ste, l2gMap);
                                    ComputeChange computeChange = new ComputeChange(targetXpath, math);
                                    for (String symbol : exprSymbols) {
                                        String symbolName = TokenMangler.mangleToSName(symbol);
                                        SymbolTableEntry ste1 = vcModel.getEntry(symbol);
                                        // ste1 could be a math parameter, hence the above could return null
                                        if (ste1 == null) {
                                            ste1 = simContext.getMathDescription().getEntry(symbol);
                                        }
                                        if (ste1 != null) {
                                            if (ste1 instanceof SpeciesContext || ste1 instanceof Structure || ste1 instanceof ModelParameter) {
                                                XPathTarget ste1_XPath = getTargetXPath(ste1, l2gMap);
                                                org.jlibsedml.Variable sedmlVar = new org.jlibsedml.Variable(symbolName, symbolName, taskRef, ste1_XPath.getTargetAsString());
                                                computeChange.addVariable(sedmlVar);
                                            } else {
                                                double doubleValue = 0.0;
                                                if (ste1 instanceof ReservedSymbol) {
                                                    doubleValue = getReservedSymbolValue(ste1);
                                                } else if (ste instanceof Function) {
                                                    try {
                                                        doubleValue = ste.getExpression().evaluateConstant();
                                                    } catch (Exception e) {
                                                        e.printStackTrace(System.out);
                                                        throw new RuntimeException("Unable to evaluate function '" + ste.getName() + "' used in '" + unscannedParamName + "' expression : ", e);
                                                    }
                                                } else {
                                                    doubleValue = ste.getConstantValue();
                                                }
                                                // TODO: shouldn't be s1_init_uM which is a math symbol, should be s0 (so use the ste-something from above)
                                                // TODO: revert to Variable, not Parameter
                                                Parameter sedmlParameter = new Parameter(symbolName, symbolName, doubleValue);
                                                computeChange.addParameter(sedmlParameter);
                                            }
                                        } else {
                                            throw new RuntimeException("Symbol '" + symbol + "' used in expression for '" + unscannedParamName + "' not found in model.");
                                        }
                                    }
                                    sedModel.addChange(computeChange);
                                }
                            }
                        }
                        sedmlModel.addModel(sedModel);
                        sedmlModel.addTask(rt);
                    }
                } else {
                    // no math overrides, add basic task.
                    String taskId = "tsk_" + simContextCnt + "_" + simCount;
                    // temporary workaround
                    // TODO better fix
                    simContextId = sbmlExportFailed ? bioModelID : simContextId;
                    Task sedmlTask = new Task(taskId, vcSimulation.getName(), simContextId, utcSim.getId());
                    sedmlModel.addTask(sedmlTask);
                    // to be used later to add dataGenerators : one set of DGs per model (simContext).
                    taskRef = taskId;
                }
                // 4 ------->
                // Create DataGenerators
                List<DataGenerator> dataGeneratorsOfSim = new ArrayList<DataGenerator>();
                // add one DataGenerator for 'time'
                String timeDataGenPrefix = DATAGENERATOR_TIME_NAME + "_" + taskRef;
                DataGenerator timeDataGen = sedmlModel.getDataGeneratorWithId(timeDataGenPrefix);
                org.jlibsedml.Variable timeVar = new org.jlibsedml.Variable(DATAGENERATOR_TIME_SYMBOL + "_" + taskRef, DATAGENERATOR_TIME_SYMBOL, taskRef, VariableSymbol.TIME);
                ASTNode math = Libsedml.parseFormulaString(DATAGENERATOR_TIME_SYMBOL + "_" + taskRef);
                timeDataGen = new DataGenerator(timeDataGenPrefix, timeDataGenPrefix, math);
                timeDataGen.addVariable(timeVar);
                sedmlModel.addDataGenerator(timeDataGen);
                dataGeneratorsOfSim.add(timeDataGen);
                // add dataGenerators for species
                // get species list from SBML model.
                // Map<String, String> name2IdMap = new LinkedHashMap<> ();
                String dataGenIdPrefix = "dataGen_" + taskRef;
                if (sbmlExportFailed) {
                    // we try vcml export
                    for (SpeciesContext sc : vcModel.getSpeciesContexts()) {
                        String varName = sc.getName();
                        String varId = varName + "_" + taskRef;
                        // name2IdMap.put(varName, varId);
                        ASTNode varMath = Libsedml.parseFormulaString(varId);
                        String dataGenId = dataGenIdPrefix + "_" + TokenMangler.mangleToSName(varName);
                        DataGenerator dataGen = new DataGenerator(dataGenId, dataGenId, varMath);
                        org.jlibsedml.Variable variable = new org.jlibsedml.Variable(varId, varName, taskRef, XmlHelper.getXPathForSpecies(varName));
                        dataGen.addVariable(variable);
                        sedmlModel.addDataGenerator(dataGen);
                        dataGeneratorsOfSim.add(dataGen);
                    }
                } else {
                    String[] varNamesList = SimSpec.fromSBML(sbmlString).getVarsList();
                    for (String varName : varNamesList) {
                        String varId = varName + "_" + taskRef;
                        // name2IdMap.put(varName, varId);
                        org.jlibsedml.Variable sedmlVar = new org.jlibsedml.Variable(varId, varName, taskRef, sbmlSupport.getXPathForSpecies(varName));
                        ASTNode varMath = Libsedml.parseFormulaString(varId);
                        // "dataGen_" + varCount; - old code
                        String dataGenId = dataGenIdPrefix + "_" + TokenMangler.mangleToSName(varName);
                        DataGenerator dataGen = new DataGenerator(dataGenId, dataGenId, varMath);
                        dataGen.addVariable(sedmlVar);
                        sedmlModel.addDataGenerator(dataGen);
                        dataGeneratorsOfSim.add(dataGen);
                    }
                }
                // add DataGenerators for output functions here
                ArrayList<AnnotatedFunction> outputFunctions = simContext.getOutputFunctionContext().getOutputFunctionsList();
                for (AnnotatedFunction annotatedFunction : outputFunctions) {
                    // Expression originalFunctionExpression = annotatedFunction.getExpression();
                    // Expression modifiedFunctionExpr = new Expression(annotatedFunction.getExpression());
                    // System.out.println("Before: " + originalFunctionExpression);
                    // String[] symbols = modifiedFunctionExpr.getSymbols();
                    // for(String symbol : symbols) {
                    // String id = name2IdMap.get(symbol);
                    // if(id == null) {
                    // System.err.println("Could not find id for " + symbol);
                    // } else {
                    // modifiedFunctionExpr.substituteInPlace(new Expression(symbol), new Expression(id));
                    // }
                    // }
                    // System.out.println("After:  " + modifiedFunctionExpr);
                    // ASTNode funcMath = Libsedml.parseFormulaString(modifiedFunctionExpr.infix());
                    // "dataGen_" + varCount; - old code
                    String dataGenId = dataGenIdPrefix + "_" + TokenMangler.mangleToSName(annotatedFunction.getName());
                    String varId = TokenMangler.mangleToSName(annotatedFunction.getName()) + taskRef;
                    if (sbmlExportFailed) {
                        // VCML
                        Expression exp = new Expression(varId);
                        ASTNode funcMath = Libsedml.parseFormulaString(exp.infix());
                        DataGenerator dataGen = new DataGenerator(dataGenId, dataGenId, funcMath);
                        org.jlibsedml.Variable sedmlVar = new org.jlibsedml.Variable(varId, annotatedFunction.getName(), taskRef, XmlHelper.getXPathForOutputFunction(simContextName, annotatedFunction.getName()));
                        dataGen.addVariable(sedmlVar);
                        sedmlModel.addDataGenerator(dataGen);
                        dataGeneratorsOfSim.add(dataGen);
                    } else {
                    // SBML
                    }
                // String[] functionSymbols = originalFunctionExpression.getSymbols();
                // for (String symbol : functionSymbols) {
                // String symbolName = TokenMangler.mangleToSName(symbol);
                // // try to get symbol from model, if null, try simContext.mathDesc
                // SymbolTableEntry ste = vcModel.getEntry(symbol);
                // if (ste == null) {
                // ste = simContext.getMathDescription().getEntry(symbol);
                // }
                // if (ste instanceof SpeciesContext || ste instanceof Structure || ste instanceof ModelParameter) {
                // XPathTarget targetXPath = getTargetXPath(ste, l2gMap);
                // if(sbmlExportFailed) {		// VCML
                // if(ste instanceof SpeciesContext) {
                // //											String varId = symbolName + "_" + taskRef;
                // //											org.jlibsedml.Variable sedmlVar = new org.jlibsedml.Variable(varId, symbolName, taskRef, XmlHelper.getXPathForSpecies(symbolName));
                // //											dataGen.addVariable(sedmlVar);
                // } else {
                // System.err.println("Not a species");
                // }
                // } else {					// SBML
                // //										String varId = symbolName + "_" + taskRef;
                // //										org.jlibsedml.Variable sedmlVar = new org.jlibsedml.Variable(varId, symbolName, taskRef, targetXPath.getTargetAsString());
                // //										dataGen.addVariable(sedmlVar);
                // }
                // } else {
                // double value = 0.0;
                // if (ste instanceof Function) {
                // try {
                // value = ste.getExpression().evaluateConstant();
                // } catch (Exception e) {
                // e.printStackTrace(System.out);
                // throw new RuntimeException("Unable to evaluate function '" + ste.getName() + "' for output function '" + annotatedFunction.getName() + "'.", e);
                // }
                // } else {
                // value = ste.getConstantValue();
                // }
                // Parameter sedmlParameter = new Parameter(symbolName, symbolName, value);
                // dataGen.addParameter(sedmlParameter);
                // }
                // }
                }
                // ignoring output for spatial deterministic (spatial stochastic is not exported to SEDML) and non-spatial stochastic applications with histogram
                if (!(simContext.getGeometry().getDimension() > 0)) {
                    String plot2dId = "plot2d_" + TokenMangler.mangleToSName(vcSimulation.getName());
                    String reportId = "report_" + TokenMangler.mangleToSName(vcSimulation.getName());
                    // String reportId = "__plot__" + plot2dId;
                    String plotName = simContextName + "_" + simName + "_plot";
                    Plot2D sedmlPlot2d = new Plot2D(plot2dId, plotName);
                    Report sedmlReport = new Report(reportId, plotName);
                    sedmlPlot2d.addNote(createNotesElement("Plot of all variables and output functions from application '" + simContext.getName() + "' ; simulation '" + vcSimulation.getName() + "' in VCell model"));
                    sedmlReport.addNote(createNotesElement("Report of all variables and output functions from application '" + simContext.getName() + "' ; simulation '" + vcSimulation.getName() + "' in VCell model"));
                    DataGenerator dgtime = sedmlModel.getDataGeneratorWithId(DATAGENERATOR_TIME_NAME + "_" + taskRef);
                    String xDataRef = dgtime.getId();
                    String xDatasetXId = "__data_set__" + plot2dId + dgtime.getId();
                    // id, name, label, data generator reference
                    DataSet dataSet = new DataSet(xDatasetXId, DATAGENERATOR_TIME_NAME, xDataRef, xDataRef);
                    sedmlReport.addDataSet(dataSet);
                    // add a curve for each dataGenerator in SEDML model
                    int curveCnt = 0;
                    // String id, String name, ASTNode math
                    for (DataGenerator dg : dataGeneratorsOfSim) {
                        // no curve for time, since time is xDateReference
                        if (dg.getId().equals(xDataRef)) {
                            continue;
                        }
                        String curveId = "curve_" + plot2dId + "_" + dg.getName();
                        String datasetYId = "__data_set__" + plot2dId + dg.getName();
                        Curve curve = new Curve(curveId, dg.getName(), false, false, xDataRef, dg.getId());
                        sedmlPlot2d.addCurve(curve);
                        // // id, name, label, dataRef
                        // // dataset id    <- unique id
                        // // dataset name  <- data generator name
                        // // dataset label <- dataset id
                        DataSet yDataSet = new DataSet(datasetYId, dg.getName(), dg.getId(), dg.getId());
                        sedmlReport.addDataSet(yDataSet);
                        curveCnt++;
                    }
                    sedmlModel.addOutput(sedmlPlot2d);
                    sedmlModel.addOutput(sedmlReport);
                } else {
                    // spatial deterministic
                    if (simContext.getApplicationType().equals(Application.NETWORK_DETERMINISTIC)) {
                        // we ignore spatial stochastic (Smoldyn)
                        if (bForceVCML) {
                            String reportId = "_report_" + TokenMangler.mangleToSName(vcSimulation.getName());
                            Report sedmlReport = new Report(reportId, simContext.getName() + "plots");
                            String xDataRef = sedmlModel.getDataGeneratorWithId(DATAGENERATOR_TIME_NAME + "_" + taskRef).getId();
                            String xDatasetXId = "datasetX_" + DATAGENERATOR_TIME_NAME + "_" + timeDataGen.getId();
                            DataSet dataSetTime = new DataSet(xDatasetXId, xDataRef, xDatasetXId, xDataRef);
                            sedmlReport.addDataSet(dataSetTime);
                            int surfaceCnt = 0;
                            for (DataGenerator dg : dataGeneratorsOfSim) {
                                if (dg.getId().equals(xDataRef)) {
                                    continue;
                                }
                                // String datasetYId = "datasetY_" + surfaceCnt;
                                String datasetYId = "__data_set__" + surfaceCnt + "_" + dg.getName();
                                DataSet yDataSet = new DataSet(datasetYId, dg.getName(), datasetYId, dg.getId());
                                sedmlReport.addDataSet(yDataSet);
                                surfaceCnt++;
                            }
                            sedmlModel.addOutput(sedmlReport);
                        } else {
                            // spatial deterministic SBML
                            // TODO: add surfaces to the plots
                            String plot3dId = "plot3d_" + TokenMangler.mangleToSName(vcSimulation.getName());
                            String reportId = "report_" + TokenMangler.mangleToSName(vcSimulation.getName());
                            String plotName = simContext.getName() + "plots";
                            Plot3D sedmlPlot3d = new Plot3D(plot3dId, plotName);
                            Report sedmlReport = new Report(reportId, plotName);
                            sedmlPlot3d.addNote(createNotesElement("Plot of all variables and output functions from application '" + simContext.getName() + "' ; simulation '" + vcSimulation.getName() + "' in VCell model"));
                            sedmlReport.addNote(createNotesElement("Report of all variables and output functions from application '" + simContext.getName() + "' ; simulation '" + vcSimulation.getName() + "' in VCell model"));
                            DataGenerator dgtime = sedmlModel.getDataGeneratorWithId(DATAGENERATOR_TIME_NAME + "_" + taskRef);
                            String xDataRef = dgtime.getId();
                            String xDatasetXId = "__data_set__" + plot3dId + dgtime.getId();
                            // id, name, label, data generator reference
                            DataSet dataSet = new DataSet(xDatasetXId, DATAGENERATOR_TIME_NAME, xDataRef, xDataRef);
                            sedmlReport.addDataSet(dataSet);
                            // add a curve for each dataGenerator in SEDML model
                            int curveCnt = 0;
                            // String id, String name, ASTNode math
                            for (DataGenerator dg : dataGeneratorsOfSim) {
                                // no curve for time, since time is xDateReference
                                if (dg.getId().equals(xDataRef)) {
                                    continue;
                                }
                                String curveId = "curve_" + plot3dId + "_" + dg.getName();
                                String datasetYId = "__data_set__" + plot3dId + dg.getName();
                                DataSet yDataSet = new DataSet(datasetYId, dg.getName(), dg.getId(), dg.getId());
                                sedmlReport.addDataSet(yDataSet);
                                curveCnt++;
                            }
                            sedmlModel.addOutput(sedmlReport);
                        }
                    }
                }
                simCount++;
            }
            // end - for 'sims'
            simContextCnt++;
        }
        // if sedmlNotesStr is not null, there were some applications that could not be exported to SEDML (eg., spatial stochastic). Create a notes element and add it to sedml Model.
        if (sedmlNotesStr.length() > 0) {
            sedmlNotesStr = "\n\tThe following applications in the VCell model were not exported to VCell : " + sedmlNotesStr;
            sedmlModel.addNote(createNotesElement(sedmlNotesStr));
        }
        if (sedmlModel.getModels() != null && sedmlModel.getModels().size() > 1) {
            System.out.println("Number of models in the sedml is " + sedmlModel.getModels().size());
        }
    } catch (Exception e) {
        e.printStackTrace(System.out);
        throw new RuntimeException("Error adding model to SEDML document : " + e.getMessage());
    }
}
Also used : Task(org.jlibsedml.Task) SubTask(org.jlibsedml.SubTask) RepeatedTask(org.jlibsedml.RepeatedTask) LinkedHashMap(java.util.LinkedHashMap) HashMap(java.util.HashMap) DataSet(org.jlibsedml.DataSet) NonspatialStochSimOptions(cbit.vcell.solver.NonspatialStochSimOptions) ArrayList(java.util.ArrayList) SpeciesContext(cbit.vcell.model.SpeciesContext) ConstantArraySpec(cbit.vcell.solver.ConstantArraySpec) ChangeAttribute(org.jlibsedml.ChangeAttribute) ComputeChange(org.jlibsedml.ComputeChange) ErrorTolerance(cbit.vcell.solver.ErrorTolerance) SolverTaskDescription(cbit.vcell.solver.SolverTaskDescription) Plot3D(org.jlibsedml.Plot3D) SubTask(org.jlibsedml.SubTask) AnnotatedFunction(cbit.vcell.solver.AnnotatedFunction) Curve(org.jlibsedml.Curve) SBMLExporter(org.vcell.sbml.vcell.SBMLExporter) VectorRange(org.jlibsedml.VectorRange) UniformRange(org.jlibsedml.UniformRange) Range(org.jlibsedml.Range) Algorithm(org.jlibsedml.Algorithm) MathOverrides(cbit.vcell.solver.MathOverrides) ModelParameter(cbit.vcell.model.Model.ModelParameter) DataGenerator(org.jlibsedml.DataGenerator) MathMapping(cbit.vcell.mapping.MathMapping) UniformTimeCourse(org.jlibsedml.UniformTimeCourse) Plot2D(org.jlibsedml.Plot2D) AlgorithmParameter(org.jlibsedml.AlgorithmParameter) VectorRange(org.jlibsedml.VectorRange) SolverDescription(cbit.vcell.solver.SolverDescription) ReservedSymbol(cbit.vcell.model.Model.ReservedSymbol) StructureMapping(cbit.vcell.mapping.StructureMapping) TimeBounds(cbit.vcell.solver.TimeBounds) TimeStep(cbit.vcell.solver.TimeStep) AnnotatedFunction(cbit.vcell.solver.AnnotatedFunction) Function(cbit.vcell.math.Function) SymbolTableEntry(cbit.vcell.parser.SymbolTableEntry) ASTCi(org.jmathml.ASTCi) RepeatedTask(org.jlibsedml.RepeatedTask) ASTNode(org.jmathml.ASTNode) Structure(cbit.vcell.model.Structure) Pair(org.vcell.util.Pair) Report(org.jlibsedml.Report) SimulationContext(cbit.vcell.mapping.SimulationContext) MathSymbolMapping(cbit.vcell.mapping.MathSymbolMapping) SbmlException(org.vcell.sbml.SbmlException) TransformerException(javax.xml.transform.TransformerException) XmlParseException(cbit.vcell.xml.XmlParseException) IOException(java.io.IOException) ExpressionException(cbit.vcell.parser.ExpressionException) ParserConfigurationException(javax.xml.parsers.ParserConfigurationException) SBMLSupport(org.jlibsedml.modelsupport.SBMLSupport) Simulation(cbit.vcell.solver.Simulation) Expression(cbit.vcell.parser.Expression) UniformRange(org.jlibsedml.UniformRange) BioModel(cbit.vcell.biomodel.BioModel) Model(org.jlibsedml.Model) StructureMappingParameter(cbit.vcell.mapping.StructureMapping.StructureMappingParameter) KineticsParameter(cbit.vcell.model.Kinetics.KineticsParameter) ModelParameter(cbit.vcell.model.Model.ModelParameter) SpeciesContextSpecParameter(cbit.vcell.mapping.SpeciesContextSpec.SpeciesContextSpecParameter) ProxyParameter(cbit.vcell.model.ProxyParameter) AlgorithmParameter(org.jlibsedml.AlgorithmParameter) Parameter(org.jlibsedml.Parameter) NonspatialStochHybridOptions(cbit.vcell.solver.NonspatialStochHybridOptions) XPathTarget(org.jlibsedml.XPathTarget) SetValue(org.jlibsedml.SetValue)

Example 2 with AlgorithmParameter

use of org.jlibsedml.AlgorithmParameter in project vcell by virtualcell.

the class XmlHelper method sedmlToBioModel.

public static List<VCDocument> sedmlToBioModel(VCLogger transLogger, ExternalDocInfo externalDocInfo, SedML sedml, List<AbstractTask> tasks, String sedmlFileLocation, boolean exactMatchOnly) throws Exception {
    if (sedml.getModels().isEmpty()) {
        throw new Exception("No models found in SED-ML document");
    }
    try {
        // iterate through all the elements and show them at the console
        List<org.jlibsedml.Model> mmm = sedml.getModels();
        for (Model mm : mmm) {
            System.out.println(mm.toString());
        }
        List<org.jlibsedml.Simulation> sss = sedml.getSimulations();
        for (org.jlibsedml.Simulation ss : sss) {
            System.out.println(ss.toString());
        }
        List<AbstractTask> ttt = sedml.getTasks();
        if (ttt.isEmpty()) {
            throw new Exception("No tasks found in SED-ML document");
        }
        for (AbstractTask tt : ttt) {
            System.out.println(tt.toString());
        }
        List<DataGenerator> ddd = sedml.getDataGenerators();
        for (DataGenerator dd : ddd) {
            System.out.println(dd.toString());
        }
        List<Output> ooo = sedml.getOutputs();
        for (Output oo : ooo) {
            System.out.println(oo.toString());
        }
        if (ooo.isEmpty()) {
            System.err.println("List of outputs cannot be empty!");
        }
        if (tasks == null || tasks.isEmpty()) {
            // no task selection, we'll import all that we find in the SED-ML
            tasks = sedml.getTasks();
        }
        // We need to make a separate BioModel for each SED-ML model
        // We will parse all tasks and create Simulations for each in the BioModel(s) corresponding to the model referenced by the tasks
        List<VCDocument> docs = new ArrayList<VCDocument>();
        // extract bioModel name from sedx (or sedml) file
        String bioModelBaseName = FileUtils.getBaseName(externalDocInfo.getFile().getAbsolutePath());
        String kisaoID = null;
        // this will become the vCell simulation
        org.jlibsedml.Simulation sedmlSimulation = null;
        // the "original" model referred to by the task
        org.jlibsedml.Model sedmlOriginalModel = null;
        // this will be used in the BioModel name
        String sedmlOriginalModelName = null;
        // can be sbml or vcml
        String sedmlOriginalModelLanguage = null;
        ArchiveComponents ac = null;
        if (externalDocInfo.getFile().getPath().toLowerCase().endsWith("sedx") || externalDocInfo.getFile().getPath().toLowerCase().endsWith("omex")) {
            ac = Libsedml.readSEDMLArchive(new FileInputStream(externalDocInfo.getFile().getPath()));
        }
        ModelResolver resolver = new ModelResolver(sedml);
        if (ac != null) {
            resolver.add(new ArchiveModelResolver(ac));
        }
        resolver.add(new FileModelResolver());
        if (sedmlFileLocation != null) {
            File sedmlFile = new File(sedmlFileLocation);
            String sedmlRelativePrefix = sedmlFile.getParent() + File.separator;
            if (sedmlRelativePrefix != null) {
                resolver.add(new RelativeFileModelResolver(sedmlRelativePrefix));
            }
        }
        for (AbstractTask selectedTask : tasks) {
            if (selectedTask instanceof Task) {
                sedmlOriginalModel = sedml.getModelWithId(selectedTask.getModelReference());
                sedmlSimulation = sedml.getSimulation(selectedTask.getSimulationReference());
            } else if (selectedTask instanceof RepeatedTask) {
                System.err.println("RepeatedTask not supported yet, task " + SEDMLUtil.getName(selectedTask) + " is being skipped");
                continue;
            // TODO the below is unfinished code
            // RepeatedTask rt = (RepeatedTask)selectedTask;
            // assert(rt.getSubTasks().size() == 1);
            // SubTask st = rt.getSubTasks().entrySet().iterator().next().getValue();		// first (and only) subtask
            // String taskId = st.getTaskId();
            // AbstractTask t = sedml.getTaskWithId(taskId);
            // sedmlOriginalModel = sedml.getModelWithId(t.getModelReference());			// get model and simulation from subtask
            // sedmlSimulation = sedml.getSimulation(t.getSimulationReference());
            } else {
                throw new RuntimeException("Unexpected task " + selectedTask);
            }
            sedmlOriginalModelName = sedmlOriginalModel.getId();
            sedmlOriginalModelLanguage = sedmlOriginalModel.getLanguage();
            // at this point we assume that the sedml simulation, algorithm and kisaoID are all valid
            Algorithm algorithm = sedmlSimulation.getAlgorithm();
            kisaoID = algorithm.getKisaoID();
            // identify the vCell solvers that would match best the sedml solver kisao id
            // try to find a match in the ontology tree
            SolverDescription solverDescription = SolverUtilities.matchSolverWithKisaoId(kisaoID, exactMatchOnly);
            if (solverDescription != null) {
                System.out.println("Task (id='" + selectedTask.getId() + "') is compatible, solver match found in ontology: '" + kisaoID + "' matched to " + solverDescription);
            } else {
                // give it a try anyway with our deterministic default solver
                solverDescription = SolverDescription.CombinedSundials;
                System.err.println("Task (id='" + selectedTask.getId() + ")' is not compatible, no equivalent solver found in ontology for requested algorithm '" + kisaoID + "'; trying with deterministic default solver " + solverDescription);
            }
            // find out everything else we need about the application we're going to use,
            // some of the info will be needed when we parse the sbml file
            boolean bSpatial = false;
            Application appType = Application.NETWORK_DETERMINISTIC;
            Set<SolverDescription.SolverFeature> sfList = solverDescription.getSupportedFeatures();
            for (SolverDescription.SolverFeature sf : sfList) {
                switch(sf) {
                    case Feature_Rulebased:
                        appType = Application.RULE_BASED_STOCHASTIC;
                        break;
                    case Feature_Stochastic:
                        appType = Application.NETWORK_STOCHASTIC;
                        break;
                    case Feature_Deterministic:
                        appType = Application.NETWORK_DETERMINISTIC;
                        break;
                    case Feature_Spatial:
                        bSpatial = true;
                        break;
                    default:
                        break;
                }
            }
            // we make a biomodel for each task; if there are many simulations, probably
            // only one will match the selected task id, the others are parasites and must not be run
            BioModel bioModel = null;
            boolean justMade = false;
            String newMdl = resolver.getModelString(sedmlOriginalModel);
            String bioModelName = bioModelBaseName + "_" + sedml.getFileName() + "_" + sedmlOriginalModelName;
            // get it if we made it already
            for (VCDocument existingDoc : docs) {
                if (!docs.isEmpty()) {
                    if (existingDoc.getName().equals(bioModelName)) {
                        bioModel = (BioModel) existingDoc;
                        break;
                    }
                }
            }
            // make it if we didn't and mark it as fresh
            if (bioModel == null) {
                if (sedmlOriginalModelLanguage.contentEquals(SUPPORTED_LANGUAGE.VCELL_GENERIC.getURN())) {
                    // vcml
                    XMLSource vcmlSource = new XMLSource(newMdl);
                    bioModel = (BioModel) XmlHelper.XMLToBioModel(vcmlSource);
                    bioModel.setName(bioModelName);
                    docs.add(bioModel);
                    justMade = true;
                    try {
                        bioModel.getVCMetaData().createBioPaxObjects(bioModel);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                } else {
                    // we assume it's sbml, if it's neither import will fail
                    // sbmlSource with all the changes applied
                    XMLSource sbmlSource = new XMLSource(newMdl);
                    bioModel = (BioModel) XmlHelper.importSBML(transLogger, sbmlSource, bSpatial);
                    bioModel.setName(bioModelName);
                    docs.add(bioModel);
                    justMade = true;
                }
            }
            if (sedmlOriginalModelLanguage.contentEquals(SUPPORTED_LANGUAGE.VCELL_GENERIC.getURN())) {
                // we basically ignore the sedml simulation altogether
                for (Simulation sim : bioModel.getSimulations()) {
                    if (sim.getName().equals(selectedTask.getName())) {
                        System.out.println(" --- selected task - name: " + selectedTask.getName() + ", id: " + selectedTask.getId());
                        sim.setImportedTaskID(selectedTask.getId());
                    }
                }
                continue;
            }
            // even if we just created the biomodel from the sbml file we have at least one application with initial conditions and stuff
            // see if there is a suitable application type for the sedml kisao
            // if not, we add one by doing a "copy as" to the right type
            SimulationContext[] existingSimulationContexts = bioModel.getSimulationContexts();
            SimulationContext matchingSimulationContext = null;
            for (SimulationContext simContext : existingSimulationContexts) {
                if (simContext.getApplicationType().equals(appType) && ((simContext.getGeometry().getDimension() > 0) == bSpatial)) {
                    matchingSimulationContext = simContext;
                    break;
                }
            }
            if (matchingSimulationContext == null) {
                if (justMade) {
                    matchingSimulationContext = SimulationContext.copySimulationContext(existingSimulationContexts[0], sedmlOriginalModelName, bSpatial, appType);
                    bioModel.removeSimulationContext(existingSimulationContexts[0]);
                } else {
                    matchingSimulationContext = SimulationContext.copySimulationContext(existingSimulationContexts[0], sedmlOriginalModelName + "_" + existingSimulationContexts.length, bSpatial, appType);
                }
                bioModel.addSimulationContext(matchingSimulationContext);
            }
            // making the new vCell simulation based on the sedml simulation
            matchingSimulationContext.refreshDependencies();
            MathMappingCallback callback = new MathMappingCallbackTaskAdapter(null);
            matchingSimulationContext.refreshMathDescription(callback, NetworkGenerationRequirements.ComputeFullStandardTimeout);
            Simulation newSimulation = new Simulation(matchingSimulationContext.getMathDescription());
            newSimulation.setSimulationOwner(matchingSimulationContext);
            if (selectedTask instanceof Task) {
                String newSimName = selectedTask.getId();
                if (SEDMLUtil.getName(selectedTask) != null) {
                    newSimName += "_" + SEDMLUtil.getName(selectedTask);
                }
                newSimulation.setName(newSimName);
                newSimulation.setImportedTaskID(selectedTask.getId());
            } else {
                newSimulation.setName(SEDMLUtil.getName(sedmlSimulation) + "_" + SEDMLUtil.getName(selectedTask));
            }
            // we identify the type of sedml simulation (uniform time course, etc)
            // and set the vCell simulation parameters accordingly
            SolverTaskDescription simTaskDesc = newSimulation.getSolverTaskDescription();
            if (solverDescription != null) {
                simTaskDesc.setSolverDescription(solverDescription);
            }
            TimeBounds timeBounds = new TimeBounds();
            TimeStep timeStep = new TimeStep();
            double outputTimeStep = 0.1;
            int outputNumberOfPoints = 1;
            if (sedmlSimulation instanceof UniformTimeCourse) {
                // we translate initial time to zero, we provide output for the duration of the simulation
                // because we can't select just an interval the way the SEDML simulation can
                double initialTime = ((UniformTimeCourse) sedmlSimulation).getInitialTime();
                double outputStartTime = ((UniformTimeCourse) sedmlSimulation).getOutputStartTime();
                double outputEndTime = ((UniformTimeCourse) sedmlSimulation).getOutputEndTime();
                outputNumberOfPoints = ((UniformTimeCourse) sedmlSimulation).getNumberOfPoints();
                outputTimeStep = (outputEndTime - outputStartTime) / outputNumberOfPoints;
                timeBounds = new TimeBounds(0, outputEndTime - initialTime);
                ErrorTolerance errorTolerance = new ErrorTolerance();
                // we look for explicit algorithm parameters
                List<AlgorithmParameter> sedmlAlgorithmParameters = algorithm.getListOfAlgorithmParameters();
                for (AlgorithmParameter sedmlAlgorithmParameter : sedmlAlgorithmParameters) {
                    String apKisaoID = sedmlAlgorithmParameter.getKisaoID();
                    String apValue = sedmlAlgorithmParameter.getValue();
                    if (apKisaoID == null || apKisaoID.isEmpty()) {
                        System.err.println("Undefined KisaoID algorithm parameter for algorithm '" + kisaoID + "'");
                    }
                    // TODO: use the proper ontology for the algorithm parameters kisao id
                    if (apKisaoID.contentEquals(ErrorTolerance.ErrorToleranceDescription.Absolute.getKisao())) {
                        double value = Double.parseDouble(apValue);
                        errorTolerance.setAbsoluteErrorTolerance(value);
                    } else if (apKisaoID.contentEquals(ErrorTolerance.ErrorToleranceDescription.Relative.getKisao())) {
                        double value = Double.parseDouble(apValue);
                        errorTolerance.setRelativeErrorTolerance(value);
                    } else if (apKisaoID.contentEquals(TimeStep.TimeStepDescription.Default.getKisao())) {
                        double value = Double.parseDouble(apValue);
                        timeStep.setDefaultTimeStep(value);
                    } else if (apKisaoID.contentEquals(TimeStep.TimeStepDescription.Maximum.getKisao())) {
                        double value = Double.parseDouble(apValue);
                        timeStep.setMaximumTimeStep(value);
                    } else if (apKisaoID.contentEquals(TimeStep.TimeStepDescription.Minimum.getKisao())) {
                        double value = Double.parseDouble(apValue);
                        timeStep.setMinimumTimeStep(value);
                    } else if (apKisaoID.contentEquals(AlgorithmParameterDescription.Seed.getKisao())) {
                        // custom seed
                        if (simTaskDesc.getSimulation().getMathDescription().isNonSpatialStoch()) {
                            NonspatialStochSimOptions nssso = simTaskDesc.getStochOpt();
                            int value = Integer.parseInt(apValue);
                            nssso.setCustomSeed(value);
                        } else {
                            System.err.println("Algorithm parameter '" + AlgorithmParameterDescription.Seed.getDescription() + "' is only supported for nonspatial stochastic simulations");
                        }
                    // some arguments used only for non-spatial hybrid solvers
                    } else if (apKisaoID.contentEquals(AlgorithmParameterDescription.Epsilon.getKisao())) {
                        NonspatialStochHybridOptions nssho = simTaskDesc.getStochHybridOpt();
                        nssho.setEpsilon(Double.parseDouble(apValue));
                    } else if (apKisaoID.contentEquals(AlgorithmParameterDescription.Lambda.getKisao())) {
                        NonspatialStochHybridOptions nssho = simTaskDesc.getStochHybridOpt();
                        nssho.setLambda(Double.parseDouble(apValue));
                    } else if (apKisaoID.contentEquals(AlgorithmParameterDescription.MSRTolerance.getKisao())) {
                        NonspatialStochHybridOptions nssho = simTaskDesc.getStochHybridOpt();
                        nssho.setMSRTolerance(Double.parseDouble(apValue));
                    } else if (apKisaoID.contentEquals(AlgorithmParameterDescription.SDETolerance.getKisao())) {
                        NonspatialStochHybridOptions nssho = simTaskDesc.getStochHybridOpt();
                        nssho.setSDETolerance(Double.parseDouble(apValue));
                    } else {
                        System.err.println("Algorithm parameter with kisao id '" + apKisaoID + "' not supported at this time, skipping.");
                    }
                }
                simTaskDesc.setErrorTolerance(errorTolerance);
            } else if (sedmlSimulation instanceof OneStep) {
                // for anything other than UniformTimeCourse we just ignore
                System.err.println("OneStep Simulation not supported");
                continue;
            } else if (sedmlSimulation instanceof SteadyState) {
                System.err.println("SteadyState Simulation not supported");
                continue;
            }
            OutputTimeSpec outputTimeSpec = new UniformOutputTimeSpec(outputTimeStep);
            simTaskDesc.setTimeBounds(timeBounds);
            simTaskDesc.setTimeStep(timeStep);
            if (simTaskDesc.getSolverDescription().supports(outputTimeSpec)) {
                simTaskDesc.setOutputTimeSpec(outputTimeSpec);
            } else {
                simTaskDesc.setOutputTimeSpec(new DefaultOutputTimeSpec(1, Integer.max(DefaultOutputTimeSpec.DEFAULT_KEEP_AT_MOST, outputNumberOfPoints)));
            }
            newSimulation.setSolverTaskDescription(simTaskDesc);
            newSimulation.setDescription(SEDMLUtil.getName(selectedTask));
            bioModel.addSimulation(newSimulation);
            newSimulation.refreshDependencies();
        }
        return docs;
    } catch (Exception e) {
        e.printStackTrace();
        throw new RuntimeException("Unable to initialize bioModel for the given selection\n" + e.getMessage());
    }
}
Also used : Task(org.jlibsedml.Task) RepeatedTask(org.jlibsedml.RepeatedTask) SimulationTask(cbit.vcell.messaging.server.SimulationTask) AbstractTask(org.jlibsedml.AbstractTask) SubTask(org.jlibsedml.SubTask) ArrayList(java.util.ArrayList) ArchiveModelResolver(org.jlibsedml.execution.ArchiveModelResolver) FileModelResolver(org.jlibsedml.execution.FileModelResolver) RelativeFileModelResolver(org.vcell.sedml.RelativeFileModelResolver) ModelResolver(org.jlibsedml.execution.ModelResolver) SteadyState(org.jlibsedml.SteadyState) VCDocument(org.vcell.util.document.VCDocument) MathMappingCallback(cbit.vcell.mapping.SimulationContext.MathMappingCallback) Algorithm(org.jlibsedml.Algorithm) FileInputStream(java.io.FileInputStream) ArchiveModelResolver(org.jlibsedml.execution.ArchiveModelResolver) DataGenerator(org.jlibsedml.DataGenerator) UniformTimeCourse(org.jlibsedml.UniformTimeCourse) AlgorithmParameter(org.jlibsedml.AlgorithmParameter) File(java.io.File) Application(cbit.vcell.mapping.SimulationContext.Application) AbstractTask(org.jlibsedml.AbstractTask) RelativeFileModelResolver(org.vcell.sedml.RelativeFileModelResolver) OneStep(org.jlibsedml.OneStep) ArchiveComponents(org.jlibsedml.ArchiveComponents) RepeatedTask(org.jlibsedml.RepeatedTask) Output(org.jlibsedml.Output) MathMappingCallbackTaskAdapter(cbit.vcell.mapping.MathMappingCallbackTaskAdapter) FileModelResolver(org.jlibsedml.execution.FileModelResolver) RelativeFileModelResolver(org.vcell.sedml.RelativeFileModelResolver) SimulationContext(cbit.vcell.mapping.SimulationContext) XMLStreamException(javax.xml.stream.XMLStreamException) SbmlException(org.vcell.sbml.SbmlException) SBMLException(org.sbml.jsbml.SBMLException) IOException(java.io.IOException) ExpressionException(cbit.vcell.parser.ExpressionException) Model(org.jlibsedml.Model) BioModel(cbit.vcell.biomodel.BioModel) MathModel(cbit.vcell.mathmodel.MathModel) BioModel(cbit.vcell.biomodel.BioModel) Model(org.jlibsedml.Model)

Aggregations

BioModel (cbit.vcell.biomodel.BioModel)2 SimulationContext (cbit.vcell.mapping.SimulationContext)2 ExpressionException (cbit.vcell.parser.ExpressionException)2 IOException (java.io.IOException)2 ArrayList (java.util.ArrayList)2 Algorithm (org.jlibsedml.Algorithm)2 AlgorithmParameter (org.jlibsedml.AlgorithmParameter)2 DataGenerator (org.jlibsedml.DataGenerator)2 Model (org.jlibsedml.Model)2 RepeatedTask (org.jlibsedml.RepeatedTask)2 SubTask (org.jlibsedml.SubTask)2 Task (org.jlibsedml.Task)2 UniformTimeCourse (org.jlibsedml.UniformTimeCourse)2 SbmlException (org.vcell.sbml.SbmlException)2 MathMapping (cbit.vcell.mapping.MathMapping)1 MathMappingCallbackTaskAdapter (cbit.vcell.mapping.MathMappingCallbackTaskAdapter)1 MathSymbolMapping (cbit.vcell.mapping.MathSymbolMapping)1 Application (cbit.vcell.mapping.SimulationContext.Application)1 MathMappingCallback (cbit.vcell.mapping.SimulationContext.MathMappingCallback)1 SpeciesContextSpecParameter (cbit.vcell.mapping.SpeciesContextSpec.SpeciesContextSpecParameter)1