Search in sources :

Example 1 with Pair

use of org.vcell.util.Pair in project vcell by virtualcell.

the class SpeciesCompartmentalizer method addTransformation.

/**
 * Adds a rule for re-assigning species to different compartments based on
 * specie name
 * @param str array of three strings is expected
 * first is regex name pattern; if specie name matches this pattern the specie will be
 * moved to the specified compartment;
 * second is compartment id
 * third is id of the enclosing compartment, shall be "" for one
 * outmost compartment
 */
public void addTransformation(String[] parameters, String comment) {
    if (compartmentNamePattern == null) {
        compartmentNamePattern = new ArrayList<Pair<Pattern, String>>();
        compIds = new HashMap<String, String>();
        compDimensionMap = new HashMap<String, Integer>();
    }
    super.storeTransformationInfo(parameters, comment);
    String pattern = parameters[0];
    String dim = parameters[1];
    String compartment = parameters[2];
    String enclosed = parameters[3];
    Pattern p = Pattern.compile(pattern);
    compartmentNamePattern.add(new Pair<Pattern, String>(p, compartment));
    String enclStored = compIds.get(compartment);
    if (null == compartment || compartment.length() == 0)
        throw new SbmlTransformException("empty compartment name");
    // store the compartment - spDim values in hash
    compDimensionMap.put(compartment, Integer.valueOf(dim));
    if (// compartment is not defined or
    null == enclStored || // defined again inside same enclosure
    enclStored.equals(enclosed)) {
        compIds.put(compartment, enclosed);
    } else {
        StringBuffer buff = new StringBuffer();
        buff.append("compartment \"" + compartment + "\" defined twice: ");
        if (enclStored.length() == 0)
            buff.append("top level");
        else
            buff.append("inside \"" + enclStored + "\"");
        buff.append(" and ");
        if (enclosed.length() == 0)
            buff.append("top level");
        else
            buff.append("inside \"" + enclosed + "\"");
        throw new SbmlTransformException(buff.toString());
    }
}
Also used : Pattern(java.util.regex.Pattern) Pair(org.vcell.util.Pair)

Example 2 with Pair

use of org.vcell.util.Pair in project vcell by virtualcell.

the class SEDMLExporter method translateBioModelToSedML.

private void translateBioModelToSedML(String savePath) {
    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();
        String bioModelName = TokenMangler.mangleToSName(vcBioModel.getName());
        // String usrHomeDirPath = ResourceUtil.getUserHomeDir().getAbsolutePath();
        // to get Xpath string for variables.
        SBMLSupport sbmlSupport = new SBMLSupport();
        // for model count, task subcount
        int simContextCnt = 0;
        // for dtaGenerator count.
        int varCount = 0;
        boolean bSpeciesAddedAsDataGens = false;
        String sedmlNotesStr = "";
        for (SimulationContext simContext : simContexts) {
            String simContextName = simContext.getName();
            // export all applications that are not spatial stochastic
            if (!(simContext.getGeometry().getDimension() > 0 && simContext.isStoch())) {
                // 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());
                }
                // Export the application itself to SBML, with default overrides
                String sbmlString = null;
                int level = 2;
                int version = 4;
                boolean isSpatial = simContext.getGeometry().getDimension() > 0 ? true : false;
                SimulationJob simJob = null;
                // if (simContext.getGeometry().getDimension() > 0) {
                // sbmlString = XmlHelper.exportSBML(vcBioModel, 2, 4, 0, true, simContext, null);
                // } else {
                // sbmlString = XmlHelper.exportSBML(vcBioModel, 2, 4, 0, false, simContext, null);
                // }
                // 
                // TODO: we need to salvage from the SBMLExporter info about the fate of local parameters
                // some of them may stay as locals, some others may become globals
                // Any of these, if used in a repeated task or change or whatever, needs to be used in a consistent way,
                // that is, if a param becomes a global in SBML, we need to refer at it in SEDML as the same global
                // 
                // We'll use:
                // Map<Pair <String reaction, String param>, String global>		- if local converted to global
                // Set<Pair <String reaction, String param>>	(if needed?)	- if local stays local
                // 
                // local to global translation map
                Map<Pair<String, String>, String> l2gMap = null;
                if (vcBioModel instanceof BioModel) {
                    try {
                        // check if model to be exported to SBML has units compatible with SBML default units (default units in SBML can be assumed only until SBML Level2)
                        ModelUnitSystem forcedModelUnitSystem = simContext.getModel().getUnitSystem();
                        if (level < 3 && !ModelUnitSystem.isCompatibleWithDefaultSBMLLevel2Units(forcedModelUnitSystem)) {
                            forcedModelUnitSystem = ModelUnitSystem.createDefaultSBMLLevel2Units();
                        }
                        // create new Biomodel with new (SBML compatible)  unit system
                        BioModel modifiedBiomodel = ModelUnitConverter.createBioModelWithNewUnitSystem(simContext.getBioModel(), forcedModelUnitSystem);
                        // extract the simContext from new Biomodel. Apply overrides to *this* modified simContext
                        SimulationContext simContextFromModifiedBioModel = modifiedBiomodel.getSimulationContext(simContext.getName());
                        SBMLExporter sbmlExporter = new SBMLExporter(modifiedBiomodel, level, version, isSpatial);
                        sbmlExporter.setSelectedSimContext(simContextFromModifiedBioModel);
                        // no sim job
                        sbmlExporter.setSelectedSimulationJob(null);
                        sbmlString = sbmlExporter.getSBMLFile();
                        l2gMap = sbmlExporter.getLocalToGlobalTranslationMap();
                    } catch (ExpressionException | SbmlException e) {
                        e.printStackTrace(System.out);
                        throw new XmlParseException(e);
                    }
                } else {
                    throw new RuntimeException("unsupported Document Type " + vcBioModel.getClass().getName() + " for SBML export");
                }
                String sbmlFilePathStrAbsolute = savePath + FileUtils.WINDOWS_SEPARATOR + bioModelName + "_" + simContextName + ".xml";
                String sbmlFilePathStrRelative = bioModelName + "_" + simContextName + ".xml";
                XmlUtil.writeXMLStringToFile(sbmlString, sbmlFilePathStrAbsolute, true);
                sbmlFilePathStrAbsoluteList.add(sbmlFilePathStrRelative);
                String simContextId = TokenMangler.mangleToSName(simContextName);
                sedmlModel.addModel(new Model(simContextId, simContextName, sbmlLanguageURN, sbmlFilePathStrRelative));
                // required for mathOverrides, if any
                MathMapping mathMapping = simContext.createNewMathMapping();
                MathSymbolMapping mathSymbolMapping = mathMapping.getMathSymbolMapping();
                // create sedml simulation objects and tasks (mapping each sim with current simContext)
                int simCount = 0;
                String taskRef = null;
                int overrideCount = 0;
                for (Simulation vcSimulation : simContext.getSimulations()) {
                    List<DataGenerator> dataGeneratorsOfSim = new ArrayList<DataGenerator>();
                    // if simContext is non-spatial stochastic, check if sim is histogram
                    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;
                        }
                    }
                    // create Algorithm and sedmlSimulation (UniformtimeCourse)
                    SolverDescription vcSolverDesc = simTaskDesc.getSolverDescription();
                    // String kiSAOIdStr = getKiSAOIdFromSimulation(vcSolverDesc);	// old way of doing it, going directly to the web site
                    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);
                    // if solver is not CVODE, add a note to utcSim to indicate actual solver name
                    if (!vcSolverDesc.equals(SolverDescription.CVODE)) {
                        String simNotesStr = "Actual Solver Name : '" + vcSolverDesc.getDisplayLabel() + "'.";
                        utcSim.addNote(createNotesElement(simNotesStr));
                    }
                    sedmlModel.addSimulation(utcSim);
                    // add SEDML tasks (map simulation to model:simContext)
                    // repeated tasks
                    MathOverrides mathOverrides = vcSimulation.getMathOverrides();
                    if (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, taskId, 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, taskId, 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, taskId, 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;
                        Task sedmlTask = new Task(taskId, taskId, simContextId, utcSim.getId());
                        sedmlModel.addTask(sedmlTask);
                        // to be used later to add dataGenerators : one set of DGs per model (simContext).
                        taskRef = taskId;
                    }
                    // add one dataGenerator for 'time' for entire SEDML model.
                    // (using the id of the first task in model for 'taskRef' field of var since
                    String timeDataGenPrefix = DATAGENERATOR_TIME_NAME + "_" + taskRef;
                    DataGenerator timeDataGen = sedmlModel.getDataGeneratorWithId(timeDataGenPrefix);
                    if (timeDataGen == null) {
                        // org.jlibsedml.Variable timeVar = new org.jlibsedml.Variable(DATAGENERATOR_TIME_SYMBOL, DATAGENERATOR_TIME_SYMBOL, sedmlModel.getTasks().get(0).getId(), VariableSymbol.TIME);
                        org.jlibsedml.Variable timeVar = new org.jlibsedml.Variable(DATAGENERATOR_TIME_SYMBOL, DATAGENERATOR_TIME_SYMBOL, taskRef, VariableSymbol.TIME);
                        ASTNode math = Libsedml.parseFormulaString(DATAGENERATOR_TIME_SYMBOL);
                        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.
                    String dataGenIdPrefix = "dataGen_" + taskRef;
                    String[] varNamesList = SimSpec.fromSBML(sbmlString).getVarsList();
                    for (String varName : varNamesList) {
                        org.jlibsedml.Variable sedmlVar = new org.jlibsedml.Variable(varName, varName, taskRef, sbmlSupport.getXPathForSpecies(varName));
                        ASTNode varMath = Libsedml.parseFormulaString(varName);
                        // "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);
                        varCount++;
                    }
                    // add DataGenerators for output functions here
                    ArrayList<AnnotatedFunction> outputFunctions = simContext.getOutputFunctionContext().getOutputFunctionsList();
                    for (AnnotatedFunction annotatedFunction : outputFunctions) {
                        Expression functionExpr = annotatedFunction.getExpression();
                        ASTNode funcMath = Libsedml.parseFormulaString(functionExpr.infix());
                        // "dataGen_" + varCount; - old code
                        String dataGenId = dataGenIdPrefix + "_" + TokenMangler.mangleToSName(annotatedFunction.getName());
                        DataGenerator dataGen = new DataGenerator(dataGenId, dataGenId, funcMath);
                        String[] functionSymbols = functionExpr.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);
                                org.jlibsedml.Variable sedmlVar = new org.jlibsedml.Variable(symbolName, 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);
                            }
                        }
                        sedmlModel.addDataGenerator(dataGen);
                        dataGeneratorsOfSim.add(dataGen);
                        varCount++;
                    }
                    simCount++;
                    // ignoring output for spatial deterministic (spatial stochastic is not exported to SEDML) and non-spatial stochastic applications with histogram
                    if (!(simContext.getGeometry().getDimension() > 0)) {
                        // ignore Output (Plot2d)  for non-spatial stochastic simulation with histogram.
                        boolean bSimHasHistogram = false;
                        if (simContext.isStoch()) {
                            long numOfTrials = simTaskDesc.getStochOpt().getNumOfTrials();
                            if (numOfTrials > 1) {
                                // not histogram {
                                bSimHasHistogram = true;
                            }
                        }
                        if (!bSimHasHistogram) {
                            String plot2dId = "plot2d_" + TokenMangler.mangleToSName(vcSimulation.getName());
                            Plot2D sedmlPlot2d = new Plot2D(plot2dId, simContext.getName() + "plots");
                            sedmlPlot2d.addNote(createNotesElement("Plot of all variables and output functions from application '" + simContext.getName() + "' ; simulation '" + vcSimulation.getName() + "' in VCell model"));
                            List<DataGenerator> dataGenerators = sedmlModel.getDataGenerators();
                            String xDataRef = sedmlModel.getDataGeneratorWithId(DATAGENERATOR_TIME_NAME + "_" + taskRef).getId();
                            // add a curve for each dataGenerator in SEDML model
                            int curveCnt = 0;
                            for (DataGenerator dataGenerator : dataGeneratorsOfSim) {
                                // no curve for time, since time is xDateReference
                                if (dataGenerator.getId().equals(xDataRef)) {
                                    continue;
                                }
                                String curveId = "curve_" + curveCnt++;
                                Curve curve = new Curve(curveId, curveId, false, false, xDataRef, dataGenerator.getId());
                                sedmlPlot2d.addCurve(curve);
                            }
                            sedmlModel.addOutput(sedmlPlot2d);
                        }
                    }
                }
            // end - for 'sims'
            } else {
                // end if (!(simContext.getGeometry().getDimension() > 0 && simContext.isStoch()))
                String msg = "\n\t" + simContextName + " : export of spatial stochastic (Smoldyn solver) applications to SEDML not supported at this time.";
                sedmlNotesStr += msg;
            }
            // end : if-else simContext is not spatial stochastic
            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));
        }
        // error check : if there are no non-spatial deterministic applications (=> no models in SEDML document), complain.
        if (sedmlModel.getModels().isEmpty()) {
            throw new RuntimeException("No applications in biomodel to export to Sedml.");
        }
    } 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) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) SpeciesContext(cbit.vcell.model.SpeciesContext) ConstantArraySpec(cbit.vcell.solver.ConstantArraySpec) ExpressionException(cbit.vcell.parser.ExpressionException) ChangeAttribute(org.jlibsedml.ChangeAttribute) ComputeChange(org.jlibsedml.ComputeChange) SolverTaskDescription(cbit.vcell.solver.SolverTaskDescription) SubTask(org.jlibsedml.SubTask) AnnotatedFunction(cbit.vcell.solver.AnnotatedFunction) Curve(org.jlibsedml.Curve) SBMLExporter(org.vcell.sbml.vcell.SBMLExporter) XmlParseException(cbit.vcell.xml.XmlParseException) 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) SbmlException(org.vcell.sbml.SbmlException) 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) 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) SimulationJob(cbit.vcell.solver.SimulationJob) Pair(org.vcell.util.Pair) ModelUnitSystem(cbit.vcell.model.ModelUnitSystem) 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) BioModel(cbit.vcell.biomodel.BioModel) 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) Parameter(org.jlibsedml.Parameter) XPathTarget(org.jlibsedml.XPathTarget) SetValue(org.jlibsedml.SetValue)

Example 3 with Pair

use of org.vcell.util.Pair in project vcell by virtualcell.

the class SEDMLExporter method getTargetXPath.

private XPathTarget getTargetXPath(SymbolTableEntry ste, Map<Pair<String, String>, String> l2gMap) {
    // to get Xpath string for variables.
    SBMLSupport sbmlSupport = new SBMLSupport();
    XPathTarget targetXpath = null;
    if (ste instanceof SpeciesContext || ste instanceof SpeciesContextSpecParameter) {
        String name = ste.getName();
        if (ste instanceof SpeciesContextSpecParameter) {
            name = ((SpeciesContextSpecParameter) ste).getSpeciesContext().getName();
        }
        targetXpath = new XPathTarget(sbmlSupport.getXPathForSpecies(name));
    } else if (ste instanceof ModelParameter) {
        targetXpath = new XPathTarget(sbmlSupport.getXPathForGlobalParameter(ste.getName()));
    } else if (ste instanceof Structure || ste instanceof Structure.StructureSize || (ste instanceof StructureMappingParameter && ((StructureMappingParameter) ste).getRole() == StructureMapping.ROLE_Size)) {
        String compartmentId = ste.getName();
        // can change compartment size or spatial dimension, but in vcell, we cannot change compartment dimension.
        String compartmentAttr = "";
        if (ste instanceof Structure.StructureSize) {
            compartmentId = ((StructureSize) ste).getStructure().getName();
            compartmentAttr = ((StructureSize) ste).getName();
        }
        if (ste instanceof StructureMappingParameter) {
            StructureMappingParameter smp = (StructureMappingParameter) ste;
            compartmentId = smp.getStructure().getName();
            if (smp.getRole() == StructureMapping.ROLE_Size) {
                compartmentAttr = smp.getName();
            }
        }
        if (compartmentAttr.length() < 1) {
            targetXpath = new XPathTarget(sbmlSupport.getXPathForCompartment(compartmentId));
        } else if (compartmentAttr.equalsIgnoreCase("size")) {
            targetXpath = new XPathTarget(sbmlSupport.getXPathForCompartment(compartmentId, CompartmentAttribute.size));
        } else {
            throw new RuntimeException("Unknown compartment attribute '" + compartmentAttr + "'; cannot get xpath target for compartment '" + compartmentId + "'.");
        }
    } else if (ste instanceof KineticsParameter) {
        KineticsParameter kp = (KineticsParameter) ste;
        String reactionID = kp.getKinetics().getReactionStep().getName();
        String parameterID = kp.getName();
        Pair<String, String> key = new Pair(reactionID, parameterID);
        String value = l2gMap.get(key);
        if (value == null) {
            targetXpath = new XPathTarget(sbmlSupport.getXPathForKineticLawParameter(reactionID, parameterID));
        } else {
            targetXpath = new XPathTarget(sbmlSupport.getXPathForGlobalParameter(value, ParameterAttribute.value));
        }
    } else {
        System.err.println("Entity should be SpeciesContext, Structure, ModelParameter : " + ste.getClass());
        throw new RuntimeException("Unknown entity in SBML model");
    }
    return targetXpath;
}
Also used : ModelParameter(cbit.vcell.model.Model.ModelParameter) KineticsParameter(cbit.vcell.model.Kinetics.KineticsParameter) SpeciesContext(cbit.vcell.model.SpeciesContext) StructureMappingParameter(cbit.vcell.mapping.StructureMapping.StructureMappingParameter) XPathTarget(org.jlibsedml.XPathTarget) Structure(cbit.vcell.model.Structure) StructureSize(cbit.vcell.model.Structure.StructureSize) SBMLSupport(org.jlibsedml.modelsupport.SBMLSupport) SpeciesContextSpecParameter(cbit.vcell.mapping.SpeciesContextSpec.SpeciesContextSpecParameter) Pair(org.vcell.util.Pair)

Example 4 with Pair

use of org.vcell.util.Pair in project vcell by virtualcell.

the class SBMLExporter method addReactions.

/**
 * addReactions comment.
 * @throws SbmlException
 * @throws XMLStreamException
 */
protected void addReactions() throws SbmlException, XMLStreamException {
    // Check if any reaction has electrical mapping
    boolean bCalculatePotential = false;
    StructureMapping[] structureMappings = getSelectedSimContext().getGeometryContext().getStructureMappings();
    for (int i = 0; i < structureMappings.length; i++) {
        if (structureMappings[i] instanceof MembraneMapping) {
            if (((MembraneMapping) structureMappings[i]).getCalculateVoltage()) {
                bCalculatePotential = true;
            }
        }
    }
    // If it does, VCell doesn't export it to SBML (no representation).
    if (bCalculatePotential) {
        throw new RuntimeException("This VCell model has Electrical mapping; cannot be exported to SBML at this time");
    }
    l2gMap.clear();
    ReactionSpec[] vcReactionSpecs = getSelectedSimContext().getReactionContext().getReactionSpecs();
    for (int i = 0; i < vcReactionSpecs.length; i++) {
        if (vcReactionSpecs[i].isExcluded()) {
            continue;
        }
        ReactionStep vcReactionStep = vcReactionSpecs[i].getReactionStep();
        // Create sbml reaction
        String rxnName = vcReactionStep.getName();
        org.sbml.jsbml.Reaction sbmlReaction = sbmlModel.createReaction();
        sbmlReaction.setId(org.vcell.util.TokenMangler.mangleToSName(rxnName));
        sbmlReaction.setName(rxnName);
        // If the reactionStep is a flux reaction, add the details to the annotation (structure, carrier valence, flux carrier, fluxOption, etc.)
        // If reactionStep is a simple reaction, add annotation to indicate the structure of reaction.
        // Useful when roundtripping ...
        Element sbmlImportRelatedElement = null;
        // try {
        // sbmlImportRelatedElement = getAnnotationElement(vcReactionStep);
        // } catch (XmlParseException e1) {
        // e1.printStackTrace(System.out);
        // //			throw new RuntimeException("Error ");
        // }
        // Get annotation (RDF and non-RDF) for reactionStep from SBMLAnnotationUtils
        sbmlAnnotationUtil.writeAnnotation(vcReactionStep, sbmlReaction, sbmlImportRelatedElement);
        // Now set notes,
        sbmlAnnotationUtil.writeNotes(vcReactionStep, sbmlReaction);
        // Get reaction kineticLaw
        Kinetics vcRxnKinetics = vcReactionStep.getKinetics();
        org.sbml.jsbml.KineticLaw sbmlKLaw = sbmlReaction.createKineticLaw();
        try {
            // Convert expression from kinetics rate parameter into MathML and use libSBMl utilities to convert it to formula
            // (instead of directly using rate parameter's expression infix) to maintain integrity of formula :
            // for example logical and inequalities are not handled gracefully by libSBMl if expression.infix is used.
            final Expression localRateExpr;
            final Expression lumpedRateExpr;
            if (vcRxnKinetics instanceof DistributedKinetics) {
                localRateExpr = ((DistributedKinetics) vcRxnKinetics).getReactionRateParameter().getExpression();
                lumpedRateExpr = null;
            } else if (vcRxnKinetics instanceof LumpedKinetics) {
                localRateExpr = null;
                lumpedRateExpr = ((LumpedKinetics) vcRxnKinetics).getLumpedReactionRateParameter().getExpression();
            } else {
                throw new RuntimeException("unexpected Rate Law '" + vcRxnKinetics.getClass().getSimpleName() + "', not distributed or lumped type");
            }
            // if (vcRxnKinetics instanceof DistributedKinetics)
            // Expression correctedRateExpr = kineticsAdapter.getExpression();
            // Add parameters, if any, to the kineticLaw
            Kinetics.KineticsParameter[] vcKineticsParams = vcRxnKinetics.getKineticsParameters();
            // In the first pass thro' the kinetic params, store the non-numeric param names and expressions in arrays
            String[] kinParamNames = new String[vcKineticsParams.length];
            Expression[] kinParamExprs = new Expression[vcKineticsParams.length];
            for (int j = 0; j < vcKineticsParams.length; j++) {
                if (true) {
                    // Since local reaction parameters cannot be defined by a rule, such parameters (with rules) are exported as global parameters.
                    if ((vcKineticsParams[j].getRole() == Kinetics.ROLE_CurrentDensity && (!vcKineticsParams[j].getExpression().isZero())) || (vcKineticsParams[j].getRole() == Kinetics.ROLE_LumpedCurrent && (!vcKineticsParams[j].getExpression().isZero()))) {
                        throw new RuntimeException("Electric current not handled by SBML export; failed to export reaction \"" + vcReactionStep.getName() + "\" at this time");
                    }
                    if (!vcKineticsParams[j].getExpression().isNumeric()) {
                        // NON_NUMERIC KINETIC PARAM
                        // Create new name for kinetic parameter and store it in kinParamNames, store corresponding exprs in kinParamExprs
                        // Will be used later to add this param as global.
                        String newParamName = TokenMangler.mangleToSName(vcKineticsParams[j].getName() + "_" + vcReactionStep.getName());
                        kinParamNames[j] = newParamName;
                        kinParamExprs[j] = new Expression(vcKineticsParams[j].getExpression());
                    }
                }
            }
            // If so, these need to be added as global param (else the SBML doc will not be valid)
            for (int j = 0; j < vcKineticsParams.length; j++) {
                final KineticsParameter vcKParam = vcKineticsParams[j];
                if ((vcKParam.getRole() != Kinetics.ROLE_ReactionRate) && (vcKParam.getRole() != Kinetics.ROLE_LumpedReactionRate)) {
                    // if expression of kinetic param evaluates to a double, the parameter value is set
                    if ((vcKParam.getRole() == Kinetics.ROLE_CurrentDensity && (!vcKParam.getExpression().isZero())) || (vcKParam.getRole() == Kinetics.ROLE_LumpedCurrent && (!vcKParam.getExpression().isZero()))) {
                        throw new RuntimeException("Electric current not handled by SBML export; failed to export reaction \"" + vcReactionStep.getName() + "\" at this time");
                    }
                    if (vcKParam.getExpression().isNumeric()) {
                        // NUMERIC KINETIC PARAM
                        // check if it is used in other parameters that have expressions,
                        boolean bAddedParam = false;
                        String origParamName = vcKParam.getName();
                        String newParamName = TokenMangler.mangleToSName(origParamName + "_" + vcReactionStep.getName());
                        VCUnitDefinition vcUnit = vcKParam.getUnitDefinition();
                        for (int k = 0; k < vcKineticsParams.length; k++) {
                            if (kinParamExprs[k] != null) {
                                // The param could be in the expression for any other param
                                if (kinParamExprs[k].hasSymbol(origParamName)) {
                                    // mangle its name to avoid conflict with other globals
                                    if (globalParamNamesHash.get(newParamName) == null) {
                                        globalParamNamesHash.put(newParamName, newParamName);
                                        org.sbml.jsbml.Parameter sbmlKinParam = sbmlModel.createParameter();
                                        sbmlKinParam.setId(newParamName);
                                        sbmlKinParam.setValue(vcKParam.getConstantValue());
                                        final boolean constValue = vcKParam.isConstant();
                                        sbmlKinParam.setConstant(true);
                                        // Set SBML units for sbmlParam using VC units from vcParam
                                        if (!vcUnit.isTBD()) {
                                            UnitDefinition unitDefn = getOrCreateSBMLUnit(vcUnit);
                                            sbmlKinParam.setUnits(unitDefn);
                                        }
                                        Pair<String, String> origParam = new Pair<String, String>(rxnName, origParamName);
                                        l2gMap.put(origParam, newParamName);
                                        bAddedParam = true;
                                    } else {
                                    // need to get another name for param and need to change all its refereces in the other kinParam euqations.
                                    }
                                    // update the expression to contain new name, since the globalparam has new name
                                    kinParamExprs[k].substituteInPlace(new Expression(origParamName), new Expression(newParamName));
                                }
                            }
                        }
                        // If the param hasn't been added yet, it is definitely a local param. add it to kineticLaw now.
                        if (!bAddedParam) {
                            org.sbml.jsbml.LocalParameter sbmlKinParam = sbmlKLaw.createLocalParameter();
                            sbmlKinParam.setId(origParamName);
                            sbmlKinParam.setValue(vcKParam.getConstantValue());
                            System.out.println("tis constant " + sbmlKinParam.isExplicitlySetConstant());
                            // Set SBML units for sbmlParam using VC units from vcParam
                            if (!vcUnit.isTBD()) {
                                UnitDefinition unitDefn = getOrCreateSBMLUnit(vcUnit);
                                sbmlKinParam.setUnits(unitDefn);
                            }
                        } else {
                            // hence change its occurance in rate expression if it contains that param name
                            if (localRateExpr != null && localRateExpr.hasSymbol(origParamName)) {
                                localRateExpr.substituteInPlace(new Expression(origParamName), new Expression(newParamName));
                            }
                            if (lumpedRateExpr != null && lumpedRateExpr.hasSymbol(origParamName)) {
                                lumpedRateExpr.substituteInPlace(new Expression(origParamName), new Expression(newParamName));
                            }
                        }
                    }
                }
            }
            // (using the kinParamNames and kinParamExprs above) to ensure uniqueness in the global parameter names.
            for (int j = 0; j < vcKineticsParams.length; j++) {
                if (((vcKineticsParams[j].getRole() != Kinetics.ROLE_ReactionRate) && (vcKineticsParams[j].getRole() != Kinetics.ROLE_LumpedReactionRate)) && !(vcKineticsParams[j].getExpression().isNumeric())) {
                    String oldName = vcKineticsParams[j].getName();
                    String newName = kinParamNames[j];
                    // change the name of this parameter in the rate expression
                    if (localRateExpr != null && localRateExpr.hasSymbol(oldName)) {
                        localRateExpr.substituteInPlace(new Expression(oldName), new Expression(newName));
                    }
                    if (lumpedRateExpr != null && lumpedRateExpr.hasSymbol(oldName)) {
                        lumpedRateExpr.substituteInPlace(new Expression(oldName), new Expression(newName));
                    }
                    // Change the occurence of this param in other param expressions
                    for (int k = 0; k < vcKineticsParams.length; k++) {
                        if (((vcKineticsParams[k].getRole() != Kinetics.ROLE_ReactionRate) && (vcKineticsParams[j].getRole() != Kinetics.ROLE_LumpedReactionRate)) && !(vcKineticsParams[k].getExpression().isNumeric())) {
                            if (k != j && vcKineticsParams[k].getExpression().hasSymbol(oldName)) {
                                // for all params except the current param represented by index j (whose name was changed)
                                kinParamExprs[k].substituteInPlace(new Expression(oldName), new Expression(newName));
                            }
                            if (k == j && vcKineticsParams[k].getExpression().hasSymbol(oldName)) {
                                throw new RuntimeException("A parameter cannot refer to itself in its expression");
                            }
                        }
                    }
                // end for - k
                }
            }
            // In the fifth pass thro' the kinetic params, the non-numeric params are added to the global params of the model
            for (int j = 0; j < vcKineticsParams.length; j++) {
                if (((vcKineticsParams[j].getRole() != Kinetics.ROLE_ReactionRate) && (vcKineticsParams[j].getRole() != Kinetics.ROLE_LumpedReactionRate)) && !(vcKineticsParams[j].getExpression().isNumeric())) {
                    // Now, add this param to the globalParamNamesHash and add a global parameter to the sbmlModel
                    String paramName = kinParamNames[j];
                    if (globalParamNamesHash.get(paramName) == null) {
                        globalParamNamesHash.put(paramName, paramName);
                    } else {
                    // need to get another name for param and need to change all its refereces in the other kinParam euqations.
                    }
                    Pair<String, String> origParam = new Pair<String, String>(rxnName, paramName);
                    // keeps its name but becomes a global (?)
                    l2gMap.put(origParam, paramName);
                    ASTNode paramFormulaNode = getFormulaFromExpression(kinParamExprs[j]);
                    AssignmentRule sbmlParamAssignmentRule = sbmlModel.createAssignmentRule();
                    sbmlParamAssignmentRule.setVariable(paramName);
                    sbmlParamAssignmentRule.setMath(paramFormulaNode);
                    org.sbml.jsbml.Parameter sbmlKinParam = sbmlModel.createParameter();
                    sbmlKinParam.setId(paramName);
                    if (!vcKineticsParams[j].getUnitDefinition().isTBD()) {
                        sbmlKinParam.setUnits(getOrCreateSBMLUnit(vcKineticsParams[j].getUnitDefinition()));
                    }
                    // Since the parameter is being specified by a Rule, its 'constant' field shoud be set to 'false' (default - true).
                    sbmlKinParam.setConstant(false);
                }
            }
            // end for (j) - fifth pass
            // After making all necessary adjustments to the rate expression, now set the sbmlKLaw.
            final ASTNode exprFormulaNode;
            if (lumpedRateExpr != null) {
                exprFormulaNode = getFormulaFromExpression(lumpedRateExpr);
            } else {
                if (bSpatial) {
                    exprFormulaNode = getFormulaFromExpression(localRateExpr);
                } else {
                    exprFormulaNode = getFormulaFromExpression(Expression.mult(localRateExpr, new Expression(vcReactionStep.getStructure().getName())));
                }
            }
            sbmlKLaw.setMath(exprFormulaNode);
        } catch (cbit.vcell.parser.ExpressionException e) {
            e.printStackTrace(System.out);
            throw new RuntimeException("Error getting value of parameter : " + e.getMessage());
        }
        // Add kineticLaw to sbmlReaction - not needed now, since we use sbmlRxn.createKLaw() ??
        // sbmlReaction.setKineticLaw(sbmlKLaw);
        // Add reactants, products, modifiers
        // Simple reactions have catalysts, fluxes have 'flux'
        cbit.vcell.model.ReactionParticipant[] rxnParticipants = vcReactionStep.getReactionParticipants();
        for (ReactionParticipant rxnParticpant : rxnParticipants) {
            SimpleSpeciesReference ssr = null;
            SpeciesReference sr = null;
            if (rxnParticpant instanceof cbit.vcell.model.Reactant) {
                ssr = sr = sbmlReaction.createReactant();
            } else if (rxnParticpant instanceof cbit.vcell.model.Product) {
                ssr = sr = sbmlReaction.createProduct();
            }
            if (rxnParticpant instanceof cbit.vcell.model.Catalyst) {
                ssr = sbmlReaction.createModifier();
            }
            if (ssr != null) {
                ssr.setSpecies(rxnParticpant.getSpeciesContext().getName());
            }
            if (sr != null) {
                sr.setStoichiometry(Double.parseDouble(Integer.toString(rxnParticpant.getStoichiometry())));
                String modelUniqueName = vcReactionStep.getName() + '_' + rxnParticpant.getName();
                sr.setId(TokenMangler.mangleToSName(modelUniqueName));
                // SBML-REVIEW
                sr.setConstant(true);
                // int rcode = sr.appendNotes("<
                try {
                    SBMLHelper.addNote(sr, "VCELL guess: how do we know if reaction is constant?");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        sbmlReaction.setFast(vcReactionSpecs[i].isFast());
        // this attribute is mandatory for L3, optional for L2. So explicitly setting value.
        sbmlReaction.setReversible(true);
        if (bSpatial) {
            // set compartment for reaction if spatial
            sbmlReaction.setCompartment(vcReactionStep.getStructure().getName());
            // CORE  HAS ALT MATH true
            // set the "isLocal" attribute = true (in 'spatial' namespace) for each species
            SpatialReactionPlugin srplugin = (SpatialReactionPlugin) sbmlReaction.getPlugin(SBMLUtils.SBML_SPATIAL_NS_PREFIX);
            srplugin.setIsLocal(vcRxnKinetics instanceof DistributedKinetics);
        }
    }
}
Also used : MembraneMapping(cbit.vcell.mapping.MembraneMapping) LumpedKinetics(cbit.vcell.model.LumpedKinetics) Element(org.jdom.Element) StructureMapping(cbit.vcell.mapping.StructureMapping) SimpleSpeciesReference(org.sbml.jsbml.SimpleSpeciesReference) KineticsParameter(cbit.vcell.model.Kinetics.KineticsParameter) SpeciesReference(org.sbml.jsbml.SpeciesReference) SimpleSpeciesReference(org.sbml.jsbml.SimpleSpeciesReference) ASTNode(org.sbml.jsbml.ASTNode) VCUnitDefinition(cbit.vcell.units.VCUnitDefinition) UnitDefinition(org.sbml.jsbml.UnitDefinition) Pair(org.vcell.util.Pair) DistributedKinetics(cbit.vcell.model.DistributedKinetics) SpatialReactionPlugin(org.sbml.jsbml.ext.spatial.SpatialReactionPlugin) ReactionSpec(cbit.vcell.mapping.ReactionSpec) AssignmentRule(org.sbml.jsbml.AssignmentRule) ExpressionException(cbit.vcell.parser.ExpressionException) InteriorPoint(org.sbml.jsbml.ext.spatial.InteriorPoint) XMLStreamException(javax.xml.stream.XMLStreamException) SbmlException(org.vcell.sbml.SbmlException) ImageException(cbit.image.ImageException) SBMLException(org.sbml.jsbml.SBMLException) ExpressionException(cbit.vcell.parser.ExpressionException) VCUnitDefinition(cbit.vcell.units.VCUnitDefinition) Expression(cbit.vcell.parser.Expression) ReactionStep(cbit.vcell.model.ReactionStep) Kinetics(cbit.vcell.model.Kinetics) DistributedKinetics(cbit.vcell.model.DistributedKinetics) LumpedKinetics(cbit.vcell.model.LumpedKinetics) ReactionParticipant(cbit.vcell.model.ReactionParticipant)

Example 5 with Pair

use of org.vcell.util.Pair in project vcell by virtualcell.

the class DiffEquMathMapping method computeBoundaryConditionSource.

// determine membrane inside and outside subvolume
public static Pair<SubVolume, SubVolume> computeBoundaryConditionSource(Model model, SimulationContext simContext, SurfaceClass surfaceClass) {
    SubVolume outerSubVolume = null;
    SubVolume innerSubVolume = null;
    Structure[] mappedStructures = simContext.getGeometryContext().getStructuresFromGeometryClass(surfaceClass);
    // inside and outside correspond to structure hierarchy when present
    for (Structure s : mappedStructures) {
        if (s instanceof Membrane) {
            Membrane m = (Membrane) s;
            Feature infeature = model.getStructureTopology().getInsideFeature(m);
            if (infeature != null) {
                FeatureMapping insm = (FeatureMapping) simContext.getGeometryContext().getStructureMapping(infeature);
                if (insm.getGeometryClass() instanceof SubVolume) {
                    innerSubVolume = (SubVolume) insm.getGeometryClass();
                }
            }
            Feature outfeature = model.getStructureTopology().getOutsideFeature(m);
            if (outfeature != null) {
                FeatureMapping outsm = (FeatureMapping) simContext.getGeometryContext().getStructureMapping(outfeature);
                if (outsm.getGeometryClass() instanceof SubVolume) {
                    outerSubVolume = (SubVolume) outsm.getGeometryClass();
                }
            }
        }
    }
    // make the choice deterministic
    if (innerSubVolume == null || outerSubVolume == null || innerSubVolume == outerSubVolume) {
        Set<SubVolume> sv = surfaceClass.getAdjacentSubvolumes();
        Iterator<SubVolume> iterator = sv.iterator();
        innerSubVolume = iterator.next();
        outerSubVolume = iterator.next();
        if (innerSubVolume.getName().compareTo(outerSubVolume.getName()) > 0) {
            SubVolume temp = innerSubVolume;
            innerSubVolume = outerSubVolume;
            outerSubVolume = temp;
        }
    }
    Pair<SubVolume, SubVolume> ret = new Pair<>(innerSubVolume, outerSubVolume);
    return ret;
}
Also used : SubVolume(cbit.vcell.geometry.SubVolume) Membrane(cbit.vcell.model.Membrane) Structure(cbit.vcell.model.Structure) Feature(cbit.vcell.model.Feature) Pair(org.vcell.util.Pair)

Aggregations

Pair (org.vcell.util.Pair)17 SpeciesContext (cbit.vcell.model.SpeciesContext)8 Expression (cbit.vcell.parser.Expression)7 LinkedHashMap (java.util.LinkedHashMap)7 Map (java.util.Map)7 ExpressionException (cbit.vcell.parser.ExpressionException)6 KineticsParameter (cbit.vcell.model.Kinetics.KineticsParameter)5 Structure (cbit.vcell.model.Structure)5 ArrayList (java.util.ArrayList)5 SpeciesContextSpecParameter (cbit.vcell.mapping.SpeciesContextSpec.SpeciesContextSpecParameter)4 StructureMappingParameter (cbit.vcell.mapping.StructureMapping.StructureMappingParameter)4 ModelParameter (cbit.vcell.model.Model.ModelParameter)4 ReactionRule (cbit.vcell.model.ReactionRule)4 PropertyVetoException (java.beans.PropertyVetoException)4 SpeciesPattern (org.vcell.model.rbm.SpeciesPattern)4 Model (cbit.vcell.model.Model)3 ModelException (cbit.vcell.model.ModelException)3 ReactionStep (cbit.vcell.model.ReactionStep)3 IOException (java.io.IOException)3 XPathTarget (org.jlibsedml.XPathTarget)3