Search in sources :

Example 6 with Pair

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

the class MolecularTypePropertiesPanel method showPopupMenu.

private void showPopupMenu(MouseEvent e, PointLocationInShapeContext locationContext) {
    if (popupFromShapeMenu == null) {
        popupFromShapeMenu = new JPopupMenu();
    }
    if (popupFromShapeMenu.isShowing()) {
        return;
    }
    final Object deepestShape = locationContext.getDeepestShape();
    final Object selectedObject;
    if (deepestShape == null) {
        selectedObject = null;
        // when cursor is outside there's nothing to do  ???
        System.out.println("outside");
        return;
    } else if (deepestShape instanceof ComponentStateLargeShape) {
        System.out.println("inside state");
        if (((ComponentStateLargeShape) deepestShape).isHighlighted()) {
            selectedObject = ((ComponentStateLargeShape) deepestShape).getComponentStateDefinition();
        } else {
            // right click only works on highlighted entity, if it's not highlighted we simply return
            return;
        }
    } else if (deepestShape instanceof MolecularComponentLargeShape) {
        System.out.println("inside component");
        if (((MolecularComponentLargeShape) deepestShape).isHighlighted()) {
            selectedObject = ((MolecularComponentLargeShape) deepestShape).getMolecularComponent();
        } else {
            return;
        }
    } else if (deepestShape instanceof MolecularTypeLargeShape) {
        System.out.println("inside molecule");
        if (((MolecularTypeLargeShape) deepestShape).isHighlighted()) {
            selectedObject = ((MolecularTypeLargeShape) deepestShape).getMolecularType();
        } else {
            return;
        }
    } else if (deepestShape instanceof SpeciesPatternLargeShape) {
        // this cannot happen, here just for symmetry
        System.out.println("inside species pattern");
        if (((SpeciesPatternLargeShape) deepestShape).isHighlighted()) {
            selectedObject = ((SpeciesPatternLargeShape) deepestShape).getSpeciesPattern();
        } else {
            return;
        }
    } else {
        selectedObject = null;
        System.out.println("inside something else?");
        return;
    }
    System.out.println(selectedObject);
    boolean bDelete = false;
    boolean bAdd = false;
    popupFromShapeMenu.removeAll();
    Point mousePoint = e.getPoint();
    if (selectedObject instanceof MolecularType) {
        // rename, add
        if (selectedObject != molecularType) {
            throw new RuntimeException("The selected object from shape different from the current object");
        }
        JMenuItem renamMenuItem = new JMenuItem("Rename");
        popupFromShapeMenu.add(renamMenuItem);
        JMenuItem addMenuItem = new JMenuItem("Add " + MolecularComponent.typeName);
        // Icon icon = new MolecularTypeSmallShape(1, 4, mt, gc, mt);
        // menuItem.setIcon(icon);
        popupFromShapeMenu.add(new JSeparator());
        popupFromShapeMenu.add(addMenuItem);
        addMenuItem.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                MolecularComponent molecularComponent = molecularType.createMolecularComponent();
                molecularType.addMolecularComponent(molecularComponent);
                bioModel.getModel().getRbmModelContainer().adjustSpeciesContextPatterns(molecularType, molecularComponent);
                bioModel.getModel().getRbmModelContainer().adjustObservablesPatterns(molecularType, molecularComponent);
                bioModel.getModel().getRbmModelContainer().adjustRulesPatterns(molecularType, molecularComponent);
            // editInPlace((LargeShape)deepestShape);
            }
        });
        renamMenuItem.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                editInPlace((LargeShape) deepestShape);
            }
        });
    } else if (selectedObject instanceof MolecularComponent) {
        // move left / right / separator / rename, delete, separator, add
        String moveRightMenuText = "Move <b>" + "right" + "</b>";
        moveRightMenuText = "<html>" + moveRightMenuText + "</html>";
        JMenuItem moveRightMenuItem = new JMenuItem(moveRightMenuText);
        Icon icon = VCellIcons.moveRightIcon;
        moveRightMenuItem.setIcon(icon);
        moveRightMenuItem.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                MolecularComponent from = (MolecularComponent) selectedObject;
                List<MolecularComponent> mcList = molecularType.getComponentList();
                int fromIndex = mcList.indexOf(from);
                if (mcList.size() == fromIndex + 1) {
                    // already the last element
                    return;
                }
                int toIndex = fromIndex + 1;
                MolecularComponent to = mcList.remove(toIndex);
                mcList.add(fromIndex, to);
                molecularTypeTreeModel.populateTree();
                molecularType.firePropertyChange("entityChange", null, "bbb");
            }
        });
        popupFromShapeMenu.add(moveRightMenuItem);
        String moveLeftMenuText = "Move <b>" + "left" + "</b>";
        moveLeftMenuText = "<html>" + moveLeftMenuText + "</html>";
        JMenuItem moveLeftMenuItem = new JMenuItem(moveLeftMenuText);
        icon = VCellIcons.moveLeftIcon;
        moveLeftMenuItem.setIcon(icon);
        moveLeftMenuItem.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                MolecularComponent from = (MolecularComponent) selectedObject;
                List<MolecularComponent> mcList = molecularType.getComponentList();
                int fromIndex = mcList.indexOf(from);
                if (fromIndex == 0) {
                    // already the first element
                    return;
                }
                int toIndex = fromIndex - 1;
                MolecularComponent to = mcList.remove(toIndex);
                mcList.add(fromIndex, to);
                molecularTypeTreeModel.populateTree();
                molecularType.firePropertyChange("entityChange", null, "bbb");
            }
        });
        popupFromShapeMenu.add(moveLeftMenuItem);
        popupFromShapeMenu.add(new JSeparator());
        JMenuItem renamMenuItem = new JMenuItem("Rename");
        popupFromShapeMenu.add(renamMenuItem);
        JMenuItem addMenuItem = new JMenuItem("Add " + ComponentStateDefinition.typeName);
        JMenuItem deleteMenuItem = new JMenuItem("Delete ");
        popupFromShapeMenu.add(deleteMenuItem);
        popupFromShapeMenu.add(new JSeparator());
        popupFromShapeMenu.add(addMenuItem);
        deleteMenuItem.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                MolecularComponent mc = (MolecularComponent) selectedObject;
                // detailed verifications will be done there, to see if they are being used in reactions, species, observables
                if (!mc.getComponentStateDefinitions().isEmpty()) {
                    String[] options = { "OK" };
                    String errMsg = mc.getDisplayType() + " '<b>" + mc.getDisplayName() + "</b>' cannot be deleted because it contains explicit States.";
                    errMsg += "<br>Please delete each individual State first.";
                    errMsg += "<br><br>Detailed usage information will be provided at that time to help you decide.";
                    errMsg = "<html>" + errMsg + "</html>";
                    JOptionPane.showOptionDialog(shapePanel, errMsg, "Delete " + mc.getDisplayType(), JOptionPane.NO_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]);
                    return;
                }
                // we find and display component usage information to help the user decide
                Map<String, Pair<Displayable, SpeciesPattern>> usedHere = new LinkedHashMap<String, Pair<Displayable, SpeciesPattern>>();
                bioModel.getModel().getRbmModelContainer().findComponentUsage(molecularType, mc, usedHere);
                if (!usedHere.isEmpty()) {
                    String errMsg = mc.dependenciesToHtml(usedHere);
                    errMsg += "<br><br>Delete anyway?";
                    errMsg = "<html>" + errMsg + "</html>";
                    int dialogButton = JOptionPane.YES_NO_OPTION;
                    int returnCode = JOptionPane.showConfirmDialog(shapePanel, errMsg, "Delete " + mc.getDisplayType(), dialogButton);
                    if (returnCode == JOptionPane.YES_OPTION) {
                        // keep this code in sync with MolecularTypeTableModel.setValueAt
                        if (bioModel.getModel().getRbmModelContainer().delete(molecularType, mc) == true) {
                            molecularType.removeMolecularComponent(mc);
                        }
                    }
                } else {
                    if (bioModel.getModel().getRbmModelContainer().delete(molecularType, mc) == true) {
                        molecularType.removeMolecularComponent(mc);
                    }
                }
            }
        });
        addMenuItem.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                MolecularComponent mc = (MolecularComponent) selectedObject;
                ComponentStateDefinition componentStateDefinition = mc.createComponentStateDefinition();
                mc.addComponentStateDefinition(componentStateDefinition);
                bioModel.getModel().getRbmModelContainer().adjustObservablesPatterns(molecularType, mc, componentStateDefinition);
                bioModel.getModel().getRbmModelContainer().adjustRulesPatterns(molecularType, mc, componentStateDefinition);
                bioModel.getModel().getRbmModelContainer().adjustSpeciesPatterns(molecularType, mc, componentStateDefinition);
            // editInPlace((LargeShape)deepestShape);
            }
        });
        renamMenuItem.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                editInPlace((LargeShape) deepestShape);
            }
        });
    } else if (selectedObject instanceof ComponentStateDefinition) {
        // rename, delete
        JMenuItem renamMenuItem = new JMenuItem("Rename");
        popupFromShapeMenu.add(renamMenuItem);
        JMenuItem deleteMenuItem = new JMenuItem("Delete");
        popupFromShapeMenu.add(deleteMenuItem);
        deleteMenuItem.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                ComponentStateDefinition csd = (ComponentStateDefinition) selectedObject;
                // must exist, we're deleting one of its states
                MolecularComponent mc = locationContext.mcs.getMolecularComponent();
                Map<String, Pair<Displayable, SpeciesPattern>> usedHere = new LinkedHashMap<String, Pair<Displayable, SpeciesPattern>>();
                bioModel.getModel().getRbmModelContainer().findStateUsage(molecularType, mc, csd, usedHere);
                if (!usedHere.isEmpty()) {
                    String errMsg = csd.dependenciesToHtml(usedHere);
                    errMsg += "<br><br>Delete anyway?";
                    errMsg = "<html>" + errMsg + "</html>";
                    int dialogButton = JOptionPane.YES_NO_OPTION;
                    int returnCode = JOptionPane.showConfirmDialog(shapePanel, errMsg, "Delete " + ComponentStateDefinition.typeName, dialogButton);
                    if (returnCode == JOptionPane.YES_OPTION) {
                        // keep this code in sync with MolecularTypeTableModel.setValueAt
                        if (bioModel.getModel().getRbmModelContainer().delete(molecularType, mc, csd) == true) {
                            mc.deleteComponentStateDefinition(csd);
                        }
                    }
                } else {
                    if (bioModel.getModel().getRbmModelContainer().delete(molecularType, mc, csd) == true) {
                        mc.deleteComponentStateDefinition(csd);
                    }
                }
            }
        });
        renamMenuItem.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                editInPlace((LargeShape) deepestShape);
            }
        });
    }
    popupFromShapeMenu.show(e.getComponent(), mousePoint.x, mousePoint.y);
}
Also used : ActionEvent(java.awt.event.ActionEvent) SpeciesPatternLargeShape(cbit.vcell.graph.SpeciesPatternLargeShape) JSeparator(javax.swing.JSeparator) SpeciesPattern(org.vcell.model.rbm.SpeciesPattern) LinkedHashMap(java.util.LinkedHashMap) ComponentStateDefinition(org.vcell.model.rbm.ComponentStateDefinition) MolecularTypeLargeShape(cbit.vcell.graph.MolecularTypeLargeShape) MolecularComponent(org.vcell.model.rbm.MolecularComponent) JMenuItem(javax.swing.JMenuItem) MolecularComponentLargeShape(cbit.vcell.graph.MolecularComponentLargeShape) Pair(org.vcell.util.Pair) Displayable(org.vcell.util.Displayable) Point(java.awt.Point) JPopupMenu(javax.swing.JPopupMenu) Point(java.awt.Point) MolecularType(org.vcell.model.rbm.MolecularType) ActionListener(java.awt.event.ActionListener) ComponentStateLargeShape(cbit.vcell.graph.MolecularComponentLargeShape.ComponentStateLargeShape) MolecularTypeLargeShape(cbit.vcell.graph.MolecularTypeLargeShape) SpeciesPatternLargeShape(cbit.vcell.graph.SpeciesPatternLargeShape) ComponentStateLargeShape(cbit.vcell.graph.MolecularComponentLargeShape.ComponentStateLargeShape) LargeShape(cbit.vcell.graph.LargeShape) MolecularComponentLargeShape(cbit.vcell.graph.MolecularComponentLargeShape) RelationshipObject(org.vcell.relationship.RelationshipObject) BioPaxObject(org.vcell.pathway.BioPaxObject) Icon(javax.swing.Icon) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) ActionMap(javax.swing.ActionMap) InputMap(javax.swing.InputMap)

Example 7 with Pair

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

the class MolecularTypeTableModel method checkInputValue.

@Override
public String checkInputValue(String inputValue, int row, int columnIndex) {
    String errMsg = null;
    final Column col = Column.values()[columnIndex];
    MolecularType selectedMolecularType = getValueAt(row);
    switch(col) {
        case name:
            {
                if (!inputValue.equals(TokenMangler.fixTokenStrict(inputValue))) {
                    errMsg = "'" + inputValue + "' not legal identifier, try '" + TokenMangler.fixTokenStrict(inputValue) + "'.";
                    errMsg += VCellErrorMessages.PressEscToUndo;
                    errMsg = "<html>" + errMsg + "</html>";
                    return errMsg;
                }
                inputValue = TokenMangler.fixTokenStrict(inputValue);
                MolecularType mt = getModel().getRbmModelContainer().getMolecularType(inputValue);
                if (mt != null && mt != selectedMolecularType) {
                    errMsg = mt.getDisplayType() + " '" + inputValue + "' already exists!";
                    errMsg += VCellErrorMessages.PressEscToUndo;
                    errMsg = "<html>" + errMsg + "</html>";
                    return errMsg;
                }
                break;
            }
        case bngl_pattern:
            {
                try {
                    inputValue = inputValue.trim();
                    if (inputValue.length() > 0) {
                        MolecularType mt = RbmUtils.parseMolecularType(inputValue);
                        MolecularType mt1 = getModel().getRbmModelContainer().getMolecularType(mt.getName());
                        if (mt1 != null && getRowIndex(mt1) != row) {
                            // molecular type with this name exists already on another row
                            errMsg = mt.getDisplayType() + " '" + mt.getDisplayName() + "' already exists!";
                            errMsg += VCellErrorMessages.PressEscToUndo;
                            errMsg = "<html>" + errMsg + "</html>";
                            return errMsg;
                        }
                        // need to check if any Component we try to delete is not already in use elsewhere
                        for (MolecularComponent selectedMolecularComponent : selectedMolecularType.getComponentList()) {
                            if (mt.getMolecularComponent(selectedMolecularComponent.getName()) == null) {
                                // the user tries to delete this mc
                                Map<String, Pair<Displayable, SpeciesPattern>> usedHere = new LinkedHashMap<String, Pair<Displayable, SpeciesPattern>>();
                                bioModel.getModel().getRbmModelContainer().findComponentUsage(selectedMolecularType, selectedMolecularComponent, usedHere);
                                if (!usedHere.isEmpty()) {
                                    errMsg = selectedMolecularComponent.dependenciesToHtml(usedHere);
                                    errMsg += "<br><br>Deleting and Renaming a Component can be done in the Object Properties tree below.";
                                    errMsg += VCellErrorMessages.PressEscToUndo;
                                    errMsg = "<html>" + errMsg + "</html>";
                                    return errMsg;
                                }
                            }
                        }
                        // need to check if any State we try to delete is not already in use elsewhere
                        for (MolecularComponent selectedMolecularComponent : selectedMolecularType.getComponentList()) {
                            for (ComponentStateDefinition selectedComponentStateDefinition : selectedMolecularComponent.getComponentStateDefinitions()) {
                                MolecularComponent mc = mt.getMolecularComponent(selectedMolecularComponent.getName());
                                if (mc.getComponentStateDefinition(selectedComponentStateDefinition.getName()) == null) {
                                    // new list is missing a state which was present in the original
                                    if (!getModel().getRbmModelContainer().isDeleteAllowed(selectedMolecularType, selectedMolecularComponent, selectedComponentStateDefinition)) {
                                        errMsg = "State '" + selectedComponentStateDefinition + "' cannot be deleted because it's already being used.";
                                        errMsg += "<br>Deleting and Renaming a State can be done in the Object Properties tree below.";
                                        errMsg += VCellErrorMessages.PressEscToUndo;
                                        errMsg = "<html>" + errMsg + "</html>";
                                        return errMsg;
                                    }
                                }
                            }
                        }
                    }
                } catch (Exception ex) {
                    errMsg = ex.getMessage();
                    errMsg += VCellErrorMessages.PressEscToUndo;
                    errMsg = "<html>" + errMsg + "</html>";
                    return errMsg;
                }
                break;
            }
    }
    return null;
}
Also used : MolecularType(org.vcell.model.rbm.MolecularType) Displayable(org.vcell.util.Displayable) MolecularComponent(org.vcell.model.rbm.MolecularComponent) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) SpeciesPattern(org.vcell.model.rbm.SpeciesPattern) Pair(org.vcell.util.Pair) ComponentStateDefinition(org.vcell.model.rbm.ComponentStateDefinition)

Example 8 with Pair

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

the class ParticleMathMapping method refreshMathDescription.

/**
 * This method was created in VisualAge.
 */
private void refreshMathDescription() throws MappingException, MatrixException, MathException, ExpressionException, ModelException {
    getSimulationContext().checkValidity();
    if (getSimulationContext().getGeometry().getDimension() == 0) {
        throw new MappingException("particle math mapping requires spatial geometry - dimension >= 1");
    }
    StructureMapping[] structureMappings = getSimulationContext().getGeometryContext().getStructureMappings();
    for (int i = 0; i < structureMappings.length; i++) {
        if (structureMappings[i] instanceof MembraneMapping) {
            if (((MembraneMapping) structureMappings[i]).getCalculateVoltage()) {
                throw new MappingException("electric potential not yet supported for particle models");
            }
        }
    }
    // 
    // fail if any events
    // 
    BioEvent[] bioEvents = getSimulationContext().getBioEvents();
    if (bioEvents != null && bioEvents.length > 0) {
        throw new MappingException("events not yet supported for particle-based models");
    }
    // 
    // gather only those reactionSteps that are not "excluded"
    // 
    ReactionSpec[] reactionSpecs = getSimulationContext().getReactionContext().getReactionSpecs();
    Vector<ReactionStep> rsList = new Vector<ReactionStep>();
    for (int i = 0; i < reactionSpecs.length; i++) {
        if (reactionSpecs[i].isExcluded() == false) {
            if (reactionSpecs[i].isFast()) {
                throw new MappingException("fast reactions not supported for particle models");
            }
            rsList.add(reactionSpecs[i].getReactionStep());
        }
    }
    ReactionStep[] reactionSteps = new ReactionStep[rsList.size()];
    rsList.copyInto(reactionSteps);
    // 
    for (int i = 0; i < reactionSteps.length; i++) {
        Kinetics.UnresolvedParameter[] unresolvedParameters = reactionSteps[i].getKinetics().getUnresolvedParameters();
        if (unresolvedParameters != null && unresolvedParameters.length > 0) {
            StringBuffer buffer = new StringBuffer();
            for (int j = 0; j < unresolvedParameters.length; j++) {
                if (j > 0) {
                    buffer.append(", ");
                }
                buffer.append(unresolvedParameters[j].getName());
            }
            throw new MappingException(reactionSteps[i].getDisplayType() + " '" + reactionSteps[i].getName() + "' contains unresolved identifier(s): " + buffer);
        }
    }
    // 
    // temporarily place all variables in a hashtable (before binding) and discarding duplicates (check for equality)
    // 
    VariableHash varHash = new VariableHash();
    // //
    // // verify that all structures are mapped to geometry classes and all geometry classes are mapped to a structure
    // //
    // Structure structures[] = getSimulationContext().getGeometryContext().getModel().getStructures();
    // for (int i = 0; i < structures.length; i++){
    // StructureMapping sm = getSimulationContext().getGeometryContext().getStructureMapping(structures[i]);
    // if (sm==null || (sm.getGeometryClass() == null)){
    // throw new MappingException("model structure '"+structures[i].getName()+"' not mapped to a geometry subdomain");
    // }
    // if (sm.getUnitSizeParameter()!=null){
    // Expression unitSizeExp = sm.getUnitSizeParameter().getExpression();
    // if(unitSizeExp != null)
    // {
    // try {
    // double unitSize = unitSizeExp.evaluateConstant();
    // if (unitSize != 1.0){
    // throw new MappingException("model structure '"+sm.getStructure().getName()+"' unit size = "+unitSize+" != 1.0 ... partial volume or surface mapping not yet supported for particles");
    // }
    // }catch (ExpressionException e){
    // e.printStackTrace(System.out);
    // throw new MappingException("couldn't evaluate unit size for model structure '"+sm.getStructure().getName()+"' : "+e.getMessage());
    // }
    // }
    // }
    // }
    // {
    // GeometryClass[] geometryClass = getSimulationContext().getGeometryContext().getGeometry().getGeometryClasses();
    // for (int i = 0; i < geometryClass.length; i++){
    // Structure[] mappedStructures = getSimulationContext().getGeometryContext().getStructuresFromGeometryClass(geometryClass[i]);
    // if (mappedStructures==null || mappedStructures.length==0){
    // throw new MappingException("geometryClass '"+geometryClass[i].getName()+"' not mapped from a model structure");
    // }
    // }
    // }
    // deals with model parameters
    Model model = getSimulationContext().getModel();
    ModelUnitSystem modelUnitSystem = model.getUnitSystem();
    ModelParameter[] modelParameters = model.getModelParameters();
    // populate in globalParameterVariants hashtable
    for (int j = 0; j < modelParameters.length; j++) {
        Expression modelParamExpr = modelParameters[j].getExpression();
        GeometryClass geometryClass = getDefaultGeometryClass(modelParamExpr);
        modelParamExpr = getIdentifierSubstitutions(modelParamExpr, modelParameters[j].getUnitDefinition(), geometryClass);
        varHash.addVariable(newFunctionOrConstant(getMathSymbol(modelParameters[j], geometryClass), modelParamExpr, geometryClass));
    }
    // 
    // create new MathDescription (based on simContext's previous MathDescription if possible)
    // 
    MathDescription oldMathDesc = getSimulationContext().getMathDescription();
    mathDesc = null;
    if (oldMathDesc != null) {
        if (oldMathDesc.getVersion() != null) {
            mathDesc = new MathDescription(oldMathDesc.getVersion());
        } else {
            mathDesc = new MathDescription(oldMathDesc.getName());
        }
    } else {
        mathDesc = new MathDescription(getSimulationContext().getName() + "_generated");
    }
    // 
    // volume particle variables
    // 
    Enumeration<SpeciesContextMapping> enum1 = getSpeciesContextMappings();
    while (enum1.hasMoreElements()) {
        SpeciesContextMapping scm = enum1.nextElement();
        if (scm.getVariable() instanceof ParticleVariable) {
            if (!(mathDesc.getVariable(scm.getVariable().getName()) instanceof ParticleVariable)) {
                varHash.addVariable(scm.getVariable());
            }
        }
    }
    varHash.addVariable(new Constant(getMathSymbol(model.getPI_CONSTANT(), null), getIdentifierSubstitutions(model.getPI_CONSTANT().getExpression(), model.getPI_CONSTANT().getUnitDefinition(), null)));
    varHash.addVariable(new Constant(getMathSymbol(model.getFARADAY_CONSTANT(), null), getIdentifierSubstitutions(model.getFARADAY_CONSTANT().getExpression(), model.getFARADAY_CONSTANT().getUnitDefinition(), null)));
    varHash.addVariable(new Constant(getMathSymbol(model.getFARADAY_CONSTANT_NMOLE(), null), getIdentifierSubstitutions(model.getFARADAY_CONSTANT_NMOLE().getExpression(), model.getFARADAY_CONSTANT_NMOLE().getUnitDefinition(), null)));
    varHash.addVariable(new Constant(getMathSymbol(model.getGAS_CONSTANT(), null), getIdentifierSubstitutions(model.getGAS_CONSTANT().getExpression(), model.getGAS_CONSTANT().getUnitDefinition(), null)));
    varHash.addVariable(new Constant(getMathSymbol(model.getTEMPERATURE(), null), getIdentifierSubstitutions(new Expression(getSimulationContext().getTemperatureKelvin()), model.getTEMPERATURE().getUnitDefinition(), null)));
    // 
    for (int j = 0; j < structureMappings.length; j++) {
        if (structureMappings[j] instanceof MembraneMapping) {
            MembraneMapping membraneMapping = (MembraneMapping) structureMappings[j];
            GeometryClass geometryClass = membraneMapping.getGeometryClass();
            // 
            // don't calculate voltage, still may need it though
            // 
            Parameter initialVoltageParm = membraneMapping.getInitialVoltageParameter();
            Variable voltageFunction = newFunctionOrConstant(getMathSymbol(membraneMapping.getMembrane().getMembraneVoltage(), geometryClass), getIdentifierSubstitutions(initialVoltageParm.getExpression(), initialVoltageParm.getUnitDefinition(), geometryClass), geometryClass);
            varHash.addVariable(voltageFunction);
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(membraneMapping.getMembrane().getMembraneVoltage(), membraneMapping.getGeometryClass()), getIdentifierSubstitutions(membraneMapping.getInitialVoltageParameter().getExpression(), membraneMapping.getInitialVoltageParameter().getUnitDefinition(), membraneMapping.getGeometryClass()), membraneMapping.getGeometryClass()));
        }
    }
    // 
    for (int j = 0; j < reactionSteps.length; j++) {
        ReactionStep rs = reactionSteps[j];
        if (getSimulationContext().getReactionContext().getReactionSpec(rs).isExcluded()) {
            continue;
        }
        Kinetics.KineticsParameter[] parameters = rs.getKinetics().getKineticsParameters();
        GeometryClass geometryClass = null;
        if (rs.getStructure() != null) {
            geometryClass = getSimulationContext().getGeometryContext().getStructureMapping(rs.getStructure()).getGeometryClass();
        }
        if (parameters != null) {
            for (int i = 0; i < parameters.length; i++) {
                // Reaction rate, currentDensity, LumpedCurrent and null parameters are not going to displayed in the particle math description.
                if (((parameters[i].getRole() == Kinetics.ROLE_CurrentDensity) || (parameters[i].getRole() == Kinetics.ROLE_LumpedCurrent) || (parameters[i].getRole() == Kinetics.ROLE_ReactionRate)) || (parameters[i].getExpression() == null)) {
                    continue;
                }
                varHash.addVariable(newFunctionOrConstant(getMathSymbol(parameters[i], geometryClass), getIdentifierSubstitutions(parameters[i].getExpression(), parameters[i].getUnitDefinition(), geometryClass), geometryClass));
            }
        }
    }
    // 
    // initial constants (either function or constant)
    // 
    SpeciesContextSpec[] speciesContextSpecs = getSimulationContext().getReactionContext().getSpeciesContextSpecs();
    for (int i = 0; i < speciesContextSpecs.length; i++) {
        SpeciesContextSpecParameter initParm = null;
        Expression initExpr = null;
        if (getSimulationContext().isUsingConcentration()) {
            initParm = speciesContextSpecs[i].getParameterFromRole(SpeciesContextSpec.ROLE_InitialConcentration);
            initExpr = new Expression(initParm.getExpression());
        // if (speciesContextSpecs[i].getSpeciesContext().getStructure() instanceof Feature) {
        // initExpr = Expression.div(initExpr, new Expression(model.getKMOLE, getNameScope())).flatten();
        // }
        } else {
            initParm = speciesContextSpecs[i].getParameterFromRole(SpeciesContextSpec.ROLE_InitialCount);
            initExpr = new Expression(initParm.getExpression());
        }
        if (initExpr != null) {
            StructureMapping sm = getSimulationContext().getGeometryContext().getStructureMapping(speciesContextSpecs[i].getSpeciesContext().getStructure());
            String[] symbols = initExpr.getSymbols();
            // Check if 'initExpr' has other speciesContexts in its expression, need to replace it with 'spContext_init'
            for (int j = 0; symbols != null && j < symbols.length; j++) {
                // if symbol is a speciesContext, replacing it with a reference to initial condition for that speciesContext.
                SpeciesContext spC = null;
                SymbolTableEntry ste = initExpr.getSymbolBinding(symbols[j]);
                if (ste instanceof SpeciesContextSpecProxyParameter) {
                    SpeciesContextSpecProxyParameter spspp = (SpeciesContextSpecProxyParameter) ste;
                    if (spspp.getTarget() instanceof SpeciesContext) {
                        spC = (SpeciesContext) spspp.getTarget();
                        SpeciesContextSpec spcspec = getSimulationContext().getReactionContext().getSpeciesContextSpec(spC);
                        SpeciesContextSpecParameter spCInitParm = spcspec.getParameterFromRole(SpeciesContextSpec.ROLE_InitialConcentration);
                        // if initConc param expression is null, try initCount
                        if (spCInitParm.getExpression() == null) {
                            spCInitParm = spcspec.getParameterFromRole(SpeciesContextSpec.ROLE_InitialCount);
                        }
                        // need to get init condn expression, but can't get it from getMathSymbol() (mapping between bio and math), hence get it as below.
                        Expression scsInitExpr = new Expression(spCInitParm, getNameScope());
                        // scsInitExpr.bindExpression(this);
                        initExpr.substituteInPlace(new Expression(spC.getName()), scsInitExpr);
                    }
                }
            }
            // now create the appropriate function for the current speciesContextSpec.
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(initParm, sm.getGeometryClass()), getIdentifierSubstitutions(initExpr, initParm.getUnitDefinition(), sm.getGeometryClass()), sm.getGeometryClass()));
        }
    }
    // 
    for (int i = 0; i < speciesContextSpecs.length; i++) {
        SpeciesContextSpec.SpeciesContextSpecParameter diffParm = speciesContextSpecs[i].getParameterFromRole(SpeciesContextSpec.ROLE_DiffusionRate);
        if (diffParm != null) {
            StructureMapping sm = getSimulationContext().getGeometryContext().getStructureMapping(speciesContextSpecs[i].getSpeciesContext().getStructure());
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(diffParm, sm.getGeometryClass()), getIdentifierSubstitutions(diffParm.getExpression(), diffParm.getUnitDefinition(), sm.getGeometryClass()), sm.getGeometryClass()));
        }
    }
    // 
    for (int i = 0; i < speciesContextSpecs.length; i++) {
        SpeciesContextSpec.SpeciesContextSpecParameter bc_xm = speciesContextSpecs[i].getParameterFromRole(SpeciesContextSpec.ROLE_BoundaryValueXm);
        StructureMapping sm = getSimulationContext().getGeometryContext().getStructureMapping(speciesContextSpecs[i].getSpeciesContext().getStructure());
        if (bc_xm != null && (bc_xm.getExpression() != null)) {
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(bc_xm, sm.getGeometryClass()), getIdentifierSubstitutions(bc_xm.getExpression(), bc_xm.getUnitDefinition(), sm.getGeometryClass()), sm.getGeometryClass()));
        }
        SpeciesContextSpec.SpeciesContextSpecParameter bc_xp = speciesContextSpecs[i].getParameterFromRole(SpeciesContextSpec.ROLE_BoundaryValueXp);
        if (bc_xp != null && (bc_xp.getExpression() != null)) {
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(bc_xp, sm.getGeometryClass()), getIdentifierSubstitutions(bc_xp.getExpression(), bc_xp.getUnitDefinition(), sm.getGeometryClass()), sm.getGeometryClass()));
        }
        SpeciesContextSpec.SpeciesContextSpecParameter bc_ym = speciesContextSpecs[i].getParameterFromRole(SpeciesContextSpec.ROLE_BoundaryValueYm);
        if (bc_ym != null && (bc_ym.getExpression() != null)) {
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(bc_ym, sm.getGeometryClass()), getIdentifierSubstitutions(bc_ym.getExpression(), bc_ym.getUnitDefinition(), sm.getGeometryClass()), sm.getGeometryClass()));
        }
        SpeciesContextSpec.SpeciesContextSpecParameter bc_yp = speciesContextSpecs[i].getParameterFromRole(SpeciesContextSpec.ROLE_BoundaryValueYp);
        if (bc_yp != null && (bc_yp.getExpression() != null)) {
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(bc_yp, sm.getGeometryClass()), getIdentifierSubstitutions(bc_yp.getExpression(), bc_yp.getUnitDefinition(), sm.getGeometryClass()), sm.getGeometryClass()));
        }
        SpeciesContextSpec.SpeciesContextSpecParameter bc_zm = speciesContextSpecs[i].getParameterFromRole(SpeciesContextSpec.ROLE_BoundaryValueZm);
        if (bc_zm != null && (bc_zm.getExpression() != null)) {
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(bc_zm, sm.getGeometryClass()), getIdentifierSubstitutions(bc_zm.getExpression(), bc_zm.getUnitDefinition(), sm.getGeometryClass()), sm.getGeometryClass()));
        }
        SpeciesContextSpec.SpeciesContextSpecParameter bc_zp = speciesContextSpecs[i].getParameterFromRole(SpeciesContextSpec.ROLE_BoundaryValueZp);
        if (bc_zp != null && (bc_zp.getExpression() != null)) {
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(bc_zp, sm.getGeometryClass()), getIdentifierSubstitutions(bc_zp.getExpression(), bc_zp.getUnitDefinition(), sm.getGeometryClass()), sm.getGeometryClass()));
        }
    }
    // 
    for (int i = 0; i < speciesContextSpecs.length; i++) {
        SpeciesContextSpec.SpeciesContextSpecParameter advection_velX = speciesContextSpecs[i].getParameterFromRole(SpeciesContextSpec.ROLE_VelocityX);
        StructureMapping sm = getSimulationContext().getGeometryContext().getStructureMapping(speciesContextSpecs[i].getSpeciesContext().getStructure());
        GeometryClass geometryClass = sm.getGeometryClass();
        if (advection_velX != null && (advection_velX.getExpression() != null)) {
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(advection_velX, geometryClass), getIdentifierSubstitutions(advection_velX.getExpression(), advection_velX.getUnitDefinition(), geometryClass), geometryClass));
        }
        SpeciesContextSpec.SpeciesContextSpecParameter advection_velY = speciesContextSpecs[i].getParameterFromRole(SpeciesContextSpec.ROLE_VelocityY);
        if (advection_velY != null && (advection_velY.getExpression() != null)) {
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(advection_velY, geometryClass), getIdentifierSubstitutions(advection_velY.getExpression(), advection_velY.getUnitDefinition(), geometryClass), geometryClass));
        }
        SpeciesContextSpec.SpeciesContextSpecParameter advection_velZ = speciesContextSpecs[i].getParameterFromRole(SpeciesContextSpec.ROLE_VelocityZ);
        if (advection_velZ != null && (advection_velZ.getExpression() != null)) {
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(advection_velZ, geometryClass), getIdentifierSubstitutions(advection_velZ.getExpression(), advection_velZ.getUnitDefinition(), geometryClass), geometryClass));
        }
    }
    // 
    // constant species (either function or constant)
    // 
    enum1 = getSpeciesContextMappings();
    while (enum1.hasMoreElements()) {
        SpeciesContextMapping scm = (SpeciesContextMapping) enum1.nextElement();
        if (scm.getVariable() instanceof Constant) {
            varHash.addVariable(scm.getVariable());
        }
    }
    // 
    // conversion factors
    // 
    varHash.addVariable(new Constant(getMathSymbol(model.getKMOLE(), null), getIdentifierSubstitutions(model.getKMOLE().getExpression(), model.getKMOLE().getUnitDefinition(), null)));
    varHash.addVariable(new Constant(getMathSymbol(model.getN_PMOLE(), null), getIdentifierSubstitutions(model.getN_PMOLE().getExpression(), model.getN_PMOLE().getUnitDefinition(), null)));
    varHash.addVariable(new Constant(getMathSymbol(model.getKMILLIVOLTS(), null), getIdentifierSubstitutions(model.getKMILLIVOLTS().getExpression(), model.getKMILLIVOLTS().getUnitDefinition(), null)));
    varHash.addVariable(new Constant(getMathSymbol(model.getK_GHK(), null), getIdentifierSubstitutions(model.getK_GHK().getExpression(), model.getK_GHK().getUnitDefinition(), null)));
    // 
    for (int i = 0; i < structureMappings.length; i++) {
        StructureMapping sm = structureMappings[i];
        if (getSimulationContext().getGeometry().getDimension() == 0) {
            StructureMappingParameter sizeParm = sm.getSizeParameter();
            if (sizeParm != null && sizeParm.getExpression() != null) {
                varHash.addVariable(newFunctionOrConstant(getMathSymbol(sizeParm, sm.getGeometryClass()), getIdentifierSubstitutions(sizeParm.getExpression(), sizeParm.getUnitDefinition(), sm.getGeometryClass()), sm.getGeometryClass()));
            } else {
                if (sm instanceof MembraneMapping) {
                    MembraneMapping mm = (MembraneMapping) sm;
                    StructureMappingParameter volFrac = mm.getVolumeFractionParameter();
                    if (volFrac != null && volFrac.getExpression() != null) {
                        varHash.addVariable(newFunctionOrConstant(getMathSymbol(volFrac, sm.getGeometryClass()), getIdentifierSubstitutions(volFrac.getExpression(), volFrac.getUnitDefinition(), sm.getGeometryClass()), sm.getGeometryClass()));
                    }
                    StructureMappingParameter surfToVol = mm.getSurfaceToVolumeParameter();
                    if (surfToVol != null && surfToVol.getExpression() != null) {
                        varHash.addVariable(newFunctionOrConstant(getMathSymbol(surfToVol, sm.getGeometryClass()), getIdentifierSubstitutions(surfToVol.getExpression(), surfToVol.getUnitDefinition(), sm.getGeometryClass()), sm.getGeometryClass()));
                    }
                }
            }
        } else {
            Parameter parm = sm.getParameterFromRole(StructureMapping.ROLE_AreaPerUnitArea);
            if (parm != null && parm.getExpression() != null && sm.getGeometryClass() instanceof SurfaceClass) {
                varHash.addVariable(newFunctionOrConstant(getMathSymbol(parm, sm.getGeometryClass()), getIdentifierSubstitutions(parm.getExpression(), parm.getUnitDefinition(), sm.getGeometryClass()), sm.getGeometryClass()));
            }
            parm = sm.getParameterFromRole(StructureMapping.ROLE_AreaPerUnitVolume);
            if (parm != null && parm.getExpression() != null && sm.getGeometryClass() instanceof SubVolume) {
                varHash.addVariable(newFunctionOrConstant(getMathSymbol(parm, sm.getGeometryClass()), getIdentifierSubstitutions(parm.getExpression(), parm.getUnitDefinition(), sm.getGeometryClass()), sm.getGeometryClass()));
            }
            parm = sm.getParameterFromRole(StructureMapping.ROLE_VolumePerUnitArea);
            if (parm != null && parm.getExpression() != null && sm.getGeometryClass() instanceof SurfaceClass) {
                varHash.addVariable(newFunctionOrConstant(getMathSymbol(parm, sm.getGeometryClass()), getIdentifierSubstitutions(parm.getExpression(), parm.getUnitDefinition(), sm.getGeometryClass()), sm.getGeometryClass()));
            }
            parm = sm.getParameterFromRole(StructureMapping.ROLE_VolumePerUnitVolume);
            if (parm != null && parm.getExpression() != null && sm.getGeometryClass() instanceof SubVolume) {
                varHash.addVariable(newFunctionOrConstant(getMathSymbol(parm, sm.getGeometryClass()), getIdentifierSubstitutions(parm.getExpression(), parm.getUnitDefinition(), sm.getGeometryClass()), sm.getGeometryClass()));
            }
        }
    }
    // 
    // functions
    // 
    enum1 = getSpeciesContextMappings();
    while (enum1.hasMoreElements()) {
        SpeciesContextMapping scm = (SpeciesContextMapping) enum1.nextElement();
        if (scm.getVariable() == null && scm.getDependencyExpression() != null) {
            StructureMapping sm = getSimulationContext().getGeometryContext().getStructureMapping(scm.getSpeciesContext().getStructure());
            Variable dependentVariable = newFunctionOrConstant(getMathSymbol(scm.getSpeciesContext(), sm.getGeometryClass()), getIdentifierSubstitutions(scm.getDependencyExpression(), scm.getSpeciesContext().getUnitDefinition(), sm.getGeometryClass()), sm.getGeometryClass());
            dependentVariable.setDomain(new Domain(sm.getGeometryClass()));
            varHash.addVariable(dependentVariable);
        }
    }
    // 
    for (int i = 0; i < fieldMathMappingParameters.length; i++) {
        if (fieldMathMappingParameters[i] instanceof UnitFactorParameter) {
            GeometryClass geometryClass = fieldMathMappingParameters[i].getGeometryClass();
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(fieldMathMappingParameters[i], geometryClass), getIdentifierSubstitutions(fieldMathMappingParameters[i].getExpression(), fieldMathMappingParameters[i].getUnitDefinition(), geometryClass), fieldMathMappingParameters[i].getGeometryClass()));
        }
    }
    // 
    // set Variables to MathDescription all at once with the order resolved by "VariableHash"
    // 
    mathDesc.setAllVariables(varHash.getAlphabeticallyOrderedVariables());
    // 
    if (getSimulationContext().getGeometryContext().getGeometry() != null) {
        try {
            mathDesc.setGeometry(getSimulationContext().getGeometryContext().getGeometry());
        } catch (java.beans.PropertyVetoException e) {
            e.printStackTrace(System.out);
            throw new MappingException("failure setting geometry " + e.getMessage());
        }
    } else {
        throw new MappingException("geometry must be defined");
    }
    // 
    // create subdomains (volume and surfaces)
    // 
    GeometryClass[] geometryClasses = getSimulationContext().getGeometryContext().getGeometry().getGeometryClasses();
    for (int k = 0; k < geometryClasses.length; k++) {
        if (geometryClasses[k] instanceof SubVolume) {
            SubVolume subVolume = (SubVolume) geometryClasses[k];
            // 
            // get priority of subDomain
            // 
            // now does not have to match spatial feature, *BUT* needs to be unique
            int priority = k;
            // 
            // create subDomain
            // 
            CompartmentSubDomain subDomain = new CompartmentSubDomain(subVolume.getName(), priority);
            mathDesc.addSubDomain(subDomain);
            // 
            // assign boundary condition types
            // 
            StructureMapping[] mappedSMs = getSimulationContext().getGeometryContext().getStructureMappings(subVolume);
            FeatureMapping mappedFM = null;
            for (int i = 0; i < mappedSMs.length; i++) {
                if (mappedSMs[i] instanceof FeatureMapping) {
                    if (mappedFM != null) {
                        lg.warn("WARNING:::: MathMapping.refreshMathDescription() ... assigning boundary condition types not unique");
                    }
                    mappedFM = (FeatureMapping) mappedSMs[i];
                }
            }
            if (mappedFM != null) {
                subDomain.setBoundaryConditionXm(mappedFM.getBoundaryConditionTypeXm());
                subDomain.setBoundaryConditionXp(mappedFM.getBoundaryConditionTypeXp());
                if (getSimulationContext().getGeometry().getDimension() > 1) {
                    subDomain.setBoundaryConditionYm(mappedFM.getBoundaryConditionTypeYm());
                    subDomain.setBoundaryConditionYp(mappedFM.getBoundaryConditionTypeYp());
                }
                if (getSimulationContext().getGeometry().getDimension() > 2) {
                    subDomain.setBoundaryConditionZm(mappedFM.getBoundaryConditionTypeZm());
                    subDomain.setBoundaryConditionZp(mappedFM.getBoundaryConditionTypeZp());
                }
            }
        } else if (geometryClasses[k] instanceof SurfaceClass) {
            SurfaceClass surfaceClass = (SurfaceClass) geometryClasses[k];
            // determine membrane inside and outside subvolume
            // this preserves backward compatibility so that membrane subdomain
            // inside and outside correspond to structure hierarchy when present
            Pair<SubVolume, SubVolume> ret = DiffEquMathMapping.computeBoundaryConditionSource(model, simContext, surfaceClass);
            SubVolume innerSubVolume = ret.one;
            SubVolume outerSubVolume = ret.two;
            // 
            // create subDomain
            // 
            CompartmentSubDomain outerCompartment = mathDesc.getCompartmentSubDomain(outerSubVolume.getName());
            CompartmentSubDomain innerCompartment = mathDesc.getCompartmentSubDomain(innerSubVolume.getName());
            MembraneSubDomain memSubDomain = new MembraneSubDomain(innerCompartment, outerCompartment, surfaceClass.getName());
            mathDesc.addSubDomain(memSubDomain);
        }
    }
    // 
    // create Particle Contexts for all Particle Variables
    // 
    Enumeration<SpeciesContextMapping> enumSCM = getSpeciesContextMappings();
    Expression unitFactor = getUnitFactor(modelUnitSystem.getStochasticSubstanceUnit().divideBy(modelUnitSystem.getVolumeSubstanceUnit()));
    while (enumSCM.hasMoreElements()) {
        SpeciesContextMapping scm = enumSCM.nextElement();
        SpeciesContext sc = scm.getSpeciesContext();
        StructureMapping sm = getSimulationContext().getGeometryContext().getStructureMapping(sc.getStructure());
        SpeciesContextSpec scs = getSimulationContext().getReactionContext().getSpeciesContextSpec(sc);
        if (scm.getVariable() instanceof ParticleVariable && scm.getDependencyExpression() == null) {
            ParticleVariable particleVariable = (ParticleVariable) scm.getVariable();
            // 
            // initial distribution of particles
            // 
            ArrayList<ParticleInitialCondition> particleInitialConditions = new ArrayList<ParticleInitialCondition>();
            ParticleInitialCondition pic = null;
            if (getSimulationContext().isUsingConcentration()) {
                Expression initialDistribution = scs.getInitialConcentrationParameter().getExpression() == null ? null : new Expression(getMathSymbol(scs.getInitialConcentrationParameter(), sm.getGeometryClass()));
                if (particleVariable instanceof VolumeParticleVariable) {
                    initialDistribution = Expression.mult(initialDistribution, unitFactor);
                }
                pic = new ParticleInitialConditionConcentration(initialDistribution);
            } else {
                Expression initialCount = scs.getInitialCountParameter().getExpression() == null ? null : new Expression(getMathSymbol(scs.getInitialCountParameter(), sm.getGeometryClass()));
                if (initialCount == null) {
                    throw new MappingException("initialCount not defined for speciesContext " + scs.getSpeciesContext().getName());
                }
                Expression locationX = new Expression("u");
                Expression locationY = new Expression("u");
                Expression locationZ = new Expression("u");
                pic = new ParticleInitialConditionCount(initialCount, locationX, locationY, locationZ);
            }
            particleInitialConditions.add(pic);
            // 
            // diffusion
            // 
            Expression diffusion = new Expression(getMathSymbol(scs.getDiffusionParameter(), sm.getGeometryClass()));
            Expression driftXExp = null;
            if (scs.getVelocityXParameter().getExpression() != null) {
                driftXExp = new Expression(getMathSymbol(scs.getVelocityXParameter(), sm.getGeometryClass()));
            } else {
                SpatialQuantity[] velX_quantities = scs.getVelocityQuantities(QuantityComponent.X);
                if (velX_quantities.length > 0) {
                    int numRegions = simContext.getGeometry().getGeometrySurfaceDescription().getGeometricRegions(sm.getGeometryClass()).length;
                    if (velX_quantities.length == 1 && numRegions == 1) {
                        driftXExp = new Expression(getMathSymbol(velX_quantities[0], sm.getGeometryClass()));
                    } else {
                        throw new MappingException("multiple advection velocities enabled set for multiple volume domains ");
                    }
                }
            }
            Expression driftYExp = null;
            if (scs.getVelocityYParameter().getExpression() != null) {
                driftYExp = new Expression(getMathSymbol(scs.getVelocityYParameter(), sm.getGeometryClass()));
            } else {
                SpatialQuantity[] velY_quantities = scs.getVelocityQuantities(QuantityComponent.Y);
                if (velY_quantities.length > 0) {
                    int numRegions = simContext.getGeometry().getGeometrySurfaceDescription().getGeometricRegions(sm.getGeometryClass()).length;
                    if (velY_quantities.length == 1 && numRegions == 1) {
                        driftYExp = new Expression(getMathSymbol(velY_quantities[0], sm.getGeometryClass()));
                    } else {
                        throw new MappingException("multiple advection velocities enabled set for multiple volume domains ");
                    }
                }
            }
            Expression driftZExp = null;
            if (scs.getVelocityZParameter().getExpression() != null) {
                driftZExp = new Expression(getMathSymbol(scs.getVelocityZParameter(), sm.getGeometryClass()));
            } else {
                SpatialQuantity[] velZ_quantities = scs.getVelocityQuantities(QuantityComponent.Z);
                if (velZ_quantities.length > 0) {
                    int numRegions = simContext.getGeometry().getGeometrySurfaceDescription().getGeometricRegions(sm.getGeometryClass()).length;
                    if (velZ_quantities.length == 1 && numRegions == 1) {
                        driftZExp = new Expression(getMathSymbol(velZ_quantities[0], sm.getGeometryClass()));
                    } else {
                        throw new MappingException("multiple advection velocities enabled set for multiple volume domains ");
                    }
                }
            }
            ParticleProperties particleProperties = new ParticleProperties(particleVariable, diffusion, driftXExp, driftYExp, driftZExp, particleInitialConditions);
            GeometryClass myGC = sm.getGeometryClass();
            if (myGC == null) {
                throw new MappingException("Application '" + getSimulationContext().getName() + "'\nGeometry->StructureMapping->(" + sm.getStructure().getTypeName() + ")'" + sm.getStructure().getName() + "' must be mapped to geometry domain.\n(see 'Problems' tab)");
            }
            SubDomain subDomain = mathDesc.getSubDomain(myGC.getName());
            subDomain.addParticleProperties(particleProperties);
        }
    }
    for (ReactionStep reactionStep : reactionSteps) {
        Kinetics kinetics = reactionStep.getKinetics();
        StructureMapping sm = getSimulationContext().getGeometryContext().getStructureMapping(reactionStep.getStructure());
        GeometryClass reactionStepGeometryClass = sm.getGeometryClass();
        SubDomain subdomain = mathDesc.getSubDomain(reactionStepGeometryClass.getName());
        KineticsParameter reactionRateParameter = null;
        if (kinetics instanceof LumpedKinetics) {
            reactionRateParameter = ((LumpedKinetics) kinetics).getLumpedReactionRateParameter();
        } else {
            reactionRateParameter = ((DistributedKinetics) kinetics).getReactionRateParameter();
        }
        // macroscopic_irreversible/Microscopic_irreversible for bimolecular membrane reactions. They will NOT go through MassAction solver.
        if (kinetics.getKineticsDescription().equals(KineticsDescription.Macroscopic_irreversible) || kinetics.getKineticsDescription().equals(KineticsDescription.Microscopic_irreversible)) {
            Expression radiusExp = getIdentifierSubstitutions(reactionStep.getKinetics().getKineticsParameterFromRole(Kinetics.ROLE_Binding_Radius).getExpression(), modelUnitSystem.getBindingRadiusUnit(), reactionStepGeometryClass);
            if (radiusExp != null) {
                Expression expCopy = new Expression(radiusExp);
                try {
                    MassActionSolver.substituteParameters(expCopy, true).evaluateConstant();
                } catch (ExpressionException e) {
                    throw new MathException(VCellErrorMessages.getMassActionSolverMessage(reactionStep.getName(), "Problem in binding radius of " + reactionStep.getName() + ":  '" + radiusExp.infix() + "', " + e.getMessage()));
                }
            } else {
                throw new MathException(VCellErrorMessages.getMassActionSolverMessage(reactionStep.getName(), "Binding radius of " + reactionStep.getName() + " is null."));
            }
            List<ParticleVariable> reactantParticles = new ArrayList<ParticleVariable>();
            List<ParticleVariable> productParticles = new ArrayList<ParticleVariable>();
            List<Action> forwardActions = new ArrayList<Action>();
            for (ReactionParticipant rp : reactionStep.getReactionParticipants()) {
                SpeciesContext sc = rp.getSpeciesContext();
                SpeciesContextSpec scs = getSimulationContext().getReactionContext().getSpeciesContextSpec(sc);
                GeometryClass scGeometryClass = getSimulationContext().getGeometryContext().getStructureMapping(sc.getStructure()).getGeometryClass();
                String varName = getMathSymbol(sc, scGeometryClass);
                Variable var = mathDesc.getVariable(varName);
                if (var instanceof ParticleVariable) {
                    ParticleVariable particle = (ParticleVariable) var;
                    if (rp instanceof Reactant) {
                        reactantParticles.add(particle);
                        if (!scs.isConstant() && !scs.isForceContinuous()) {
                            for (int i = 0; i < Math.abs(rp.getStoichiometry()); i++) {
                                if (radiusExp != null) {
                                    forwardActions.add(Action.createDestroyAction(particle));
                                }
                            }
                        }
                    } else if (rp instanceof Product) {
                        productParticles.add(particle);
                        if (!scs.isConstant() && !scs.isForceContinuous()) {
                            for (int i = 0; i < Math.abs(rp.getStoichiometry()); i++) {
                                if (radiusExp != null) {
                                    forwardActions.add(Action.createCreateAction(particle));
                                }
                            }
                        }
                    }
                } else {
                    throw new MappingException("particle variable '" + varName + "' not found");
                }
            }
            JumpProcessRateDefinition bindingRadius = new InteractionRadius(radiusExp);
            // get jump process name
            String jpName = TokenMangler.mangleToSName(reactionStep.getName());
            // only for NFSim/Rules for now.
            ProcessSymmetryFactor processSymmetryFactor = null;
            if (forwardActions.size() > 0) {
                ParticleJumpProcess forwardProcess = new ParticleJumpProcess(jpName, reactantParticles, bindingRadius, forwardActions, processSymmetryFactor);
                subdomain.addParticleJumpProcess(forwardProcess);
            }
        } else // other type of reactions
        {
            /* check the reaction rate law to see if we need to decompose a reaction(reversible) into two jump processes.
			   rate constants are important in calculating the probability rate.
			   for Mass Action, we use KForward and KReverse, 
			   for General Kinetics we parse reaction rate J to see if it is in Mass Action form.
			 */
            Expression forwardRate = null;
            Expression reverseRate = null;
            // Using the MassActionFunction to write out the math description
            MassActionSolver.MassActionFunction maFunc = null;
            if (kinetics.getKineticsDescription().equals(KineticsDescription.MassAction) || kinetics.getKineticsDescription().equals(KineticsDescription.General) || kinetics.getKineticsDescription().equals(KineticsDescription.GeneralPermeability)) {
                Expression rateExp = kinetics.getKineticsParameterFromRole(Kinetics.ROLE_ReactionRate).getExpression();
                Parameter forwardRateParameter = null;
                Parameter reverseRateParameter = null;
                if (kinetics.getKineticsDescription().equals(KineticsDescription.MassAction)) {
                    forwardRateParameter = kinetics.getKineticsParameterFromRole(Kinetics.ROLE_KForward);
                    reverseRateParameter = kinetics.getKineticsParameterFromRole(Kinetics.ROLE_KReverse);
                } else if (kinetics.getKineticsDescription().equals(KineticsDescription.GeneralPermeability)) {
                    forwardRateParameter = kinetics.getKineticsParameterFromRole(Kinetics.ROLE_Permeability);
                    reverseRateParameter = kinetics.getKineticsParameterFromRole(Kinetics.ROLE_Permeability);
                }
                maFunc = MassActionSolver.solveMassAction(forwardRateParameter, reverseRateParameter, rateExp, reactionStep);
                if (maFunc.getForwardRate() == null && maFunc.getReverseRate() == null) {
                    throw new MappingException("Cannot generate stochastic math mapping for the reaction:" + reactionStep.getName() + "\nLooking for the rate function according to the form of k1*Reactant1^Stoir1*Reactant2^Stoir2...-k2*Product1^Stoip1*Product2^Stoip2.");
                } else {
                    if (maFunc.getForwardRate() != null) {
                        forwardRate = maFunc.getForwardRate();
                    }
                    if (maFunc.getReverseRate() != null) {
                        reverseRate = maFunc.getReverseRate();
                    }
                }
            }
            if (maFunc != null) {
                // if the reaction has forward rate (Mass action,HMMs), or don't have either forward or reverse rate (some other rate laws--like general)
                // we process it as forward reaction
                List<ParticleVariable> reactantParticles = new ArrayList<ParticleVariable>();
                List<ParticleVariable> productParticles = new ArrayList<ParticleVariable>();
                List<Action> forwardActions = new ArrayList<Action>();
                List<Action> reverseActions = new ArrayList<Action>();
                List<ReactionParticipant> reactants = maFunc.getReactants();
                List<ReactionParticipant> products = maFunc.getProducts();
                for (ReactionParticipant rp : reactants) {
                    SpeciesContext sc = rp.getSpeciesContext();
                    SpeciesContextSpec scs = getSimulationContext().getReactionContext().getSpeciesContextSpec(sc);
                    GeometryClass scGeometryClass = getSimulationContext().getGeometryContext().getStructureMapping(sc.getStructure()).getGeometryClass();
                    String varName = getMathSymbol(sc, scGeometryClass);
                    Variable var = mathDesc.getVariable(varName);
                    if (var instanceof ParticleVariable) {
                        ParticleVariable particle = (ParticleVariable) var;
                        reactantParticles.add(particle);
                        if (!scs.isConstant() && !scs.isForceContinuous()) {
                            for (int i = 0; i < Math.abs(rp.getStoichiometry()); i++) {
                                if (forwardRate != null) {
                                    forwardActions.add(Action.createDestroyAction(particle));
                                }
                                if (reverseRate != null) {
                                    reverseActions.add(Action.createCreateAction(particle));
                                }
                            }
                        }
                    } else {
                        throw new MappingException("particle variable '" + varName + "' not found");
                    }
                }
                for (ReactionParticipant rp : products) {
                    SpeciesContext sc = rp.getSpeciesContext();
                    SpeciesContextSpec scs = getSimulationContext().getReactionContext().getSpeciesContextSpec(sc);
                    GeometryClass scGeometryClass = getSimulationContext().getGeometryContext().getStructureMapping(sc.getStructure()).getGeometryClass();
                    String varName = getMathSymbol(sc, scGeometryClass);
                    Variable var = mathDesc.getVariable(varName);
                    if (var instanceof ParticleVariable) {
                        ParticleVariable particle = (ParticleVariable) var;
                        productParticles.add(particle);
                        if (!scs.isConstant() && !scs.isForceContinuous()) {
                            for (int i = 0; i < Math.abs(rp.getStoichiometry()); i++) {
                                if (forwardRate != null) {
                                    forwardActions.add(Action.createCreateAction(particle));
                                }
                                if (reverseRate != null) {
                                    reverseActions.add(Action.createDestroyAction(particle));
                                }
                            }
                        }
                    } else {
                        throw new MappingException("particle variable '" + varName + "' not found");
                    }
                }
                // 
                // There are two unit conversions required:
                // 
                // 1) convert entire reaction rate from vcell reaction units to Smoldyn units (molecules/lengthunit^dim/timeunit)
                // (where dim is 2 for membrane reactions and 3 for volume reactions)
                // 
                // for forward rates:
                // 2) convert each reactant from Smoldyn units (molecules/lengthunit^dim) to VCell units
                // (where dim is 2 for membrane reactants and 3 for volume reactants)
                // 
                // or
                // 
                // for reverse rates:
                // 2) convert each product from Smoldyn units (molecules/lengthunit^dim) to VCell units
                // (where dim is 2 for membrane products and 3 for volume products)
                // 
                RationalNumber reactionLocationDim = new RationalNumber(reactionStep.getStructure().getDimension());
                VCUnitDefinition timeUnit = modelUnitSystem.getTimeUnit();
                VCUnitDefinition smoldynReactionSizeUnit = modelUnitSystem.getLengthUnit().raiseTo(reactionLocationDim);
                VCUnitDefinition smoldynSubstanceUnit = modelUnitSystem.getStochasticSubstanceUnit();
                VCUnitDefinition smoldynReactionRateUnit = smoldynSubstanceUnit.divideBy(smoldynReactionSizeUnit).divideBy(timeUnit);
                VCUnitDefinition vcellReactionRateUnit = reactionRateParameter.getUnitDefinition();
                VCUnitDefinition reactionUnitFactor = smoldynReactionRateUnit.divideBy(vcellReactionRateUnit);
                if (forwardRate != null) {
                    VCUnitDefinition smoldynReactantsUnit = modelUnitSystem.getInstance_DIMENSIONLESS();
                    // start with factor to translate entire reaction rate.
                    VCUnitDefinition forwardUnitFactor = reactionUnitFactor;
                    // 
                    for (ReactionParticipant reactant : maFunc.getReactants()) {
                        VCUnitDefinition vcellReactantUnit = reactant.getSpeciesContext().getUnitDefinition();
                        boolean bForceContinuous = simContext.getReactionContext().getSpeciesContextSpec(reactant.getSpeciesContext()).isForceContinuous();
                        VCUnitDefinition smoldynReactantUnit = null;
                        if (bForceContinuous) {
                            // reactant is continuous (vcell units)
                            smoldynReactantUnit = reactant.getSpeciesContext().getUnitDefinition();
                        } else {
                            // reactant is a particle (smoldyn units)
                            RationalNumber reactantLocationDim = new RationalNumber(reactant.getStructure().getDimension());
                            VCUnitDefinition smoldynReactantSize = modelUnitSystem.getLengthUnit().raiseTo(reactantLocationDim);
                            smoldynReactantUnit = smoldynSubstanceUnit.divideBy(smoldynReactantSize);
                        }
                        // keep track of units of all reactants
                        smoldynReactantsUnit = smoldynReactantsUnit.multiplyBy(smoldynReactantUnit);
                        RationalNumber reactantStoichiometry = new RationalNumber(reactant.getStoichiometry());
                        VCUnitDefinition reactantUnitFactor = (vcellReactantUnit.divideBy(smoldynReactantUnit)).raiseTo(reactantStoichiometry);
                        // accumulate unit factors for all reactants
                        forwardUnitFactor = forwardUnitFactor.multiplyBy(reactantUnitFactor);
                    }
                    forwardRate = Expression.mult(forwardRate, getUnitFactor(forwardUnitFactor));
                    VCUnitDefinition smoldynExpectedForwardRateUnit = smoldynReactionRateUnit.divideBy(smoldynReactantsUnit);
                    // get probability
                    Expression exp = getIdentifierSubstitutions(forwardRate, smoldynExpectedForwardRateUnit, reactionStepGeometryClass).flatten();
                    JumpProcessRateDefinition partRateDef = new MacroscopicRateConstant(exp);
                    // create particle jump process
                    String jpName = TokenMangler.mangleToSName(reactionStep.getName());
                    // only for NFSim/Rules for now.
                    ProcessSymmetryFactor processSymmetryFactor = null;
                    if (forwardActions.size() > 0) {
                        ParticleJumpProcess forwardProcess = new ParticleJumpProcess(jpName, reactantParticles, partRateDef, forwardActions, processSymmetryFactor);
                        subdomain.addParticleJumpProcess(forwardProcess);
                    }
                }
                // end of forward rate not null
                if (reverseRate != null) {
                    VCUnitDefinition smoldynProductsUnit = modelUnitSystem.getInstance_DIMENSIONLESS();
                    // start with factor to translate entire reaction rate.
                    VCUnitDefinition reverseUnitFactor = reactionUnitFactor;
                    // 
                    for (ReactionParticipant product : maFunc.getProducts()) {
                        VCUnitDefinition vcellProductUnit = product.getSpeciesContext().getUnitDefinition();
                        boolean bForceContinuous = simContext.getReactionContext().getSpeciesContextSpec(product.getSpeciesContext()).isForceContinuous();
                        VCUnitDefinition smoldynProductUnit = null;
                        if (bForceContinuous) {
                            smoldynProductUnit = product.getSpeciesContext().getUnitDefinition();
                        } else {
                            RationalNumber productLocationDim = new RationalNumber(product.getStructure().getDimension());
                            VCUnitDefinition smoldynProductSize = modelUnitSystem.getLengthUnit().raiseTo(productLocationDim);
                            smoldynProductUnit = smoldynSubstanceUnit.divideBy(smoldynProductSize);
                        }
                        // keep track of units of all products
                        smoldynProductsUnit = smoldynProductsUnit.multiplyBy(smoldynProductUnit);
                        RationalNumber productStoichiometry = new RationalNumber(product.getStoichiometry());
                        VCUnitDefinition productUnitFactor = (vcellProductUnit.divideBy(smoldynProductUnit)).raiseTo(productStoichiometry);
                        // accumulate unit factors for all products
                        reverseUnitFactor = reverseUnitFactor.multiplyBy(productUnitFactor);
                    }
                    reverseRate = Expression.mult(reverseRate, getUnitFactor(reverseUnitFactor));
                    VCUnitDefinition smoldynExpectedReverseRateUnit = smoldynReactionRateUnit.divideBy(smoldynProductsUnit);
                    // get probability
                    Expression exp = getIdentifierSubstitutions(reverseRate, smoldynExpectedReverseRateUnit, reactionStepGeometryClass).flatten();
                    JumpProcessRateDefinition partProbRate = new MacroscopicRateConstant(exp);
                    // get jump process name
                    String jpName = TokenMangler.mangleToSName(reactionStep.getName() + "_reverse");
                    // only for NFSim/Rules for now.
                    ProcessSymmetryFactor processSymmetryFactor = null;
                    if (reverseActions.size() > 0) {
                        ParticleJumpProcess reverseProcess = new ParticleJumpProcess(jpName, productParticles, partProbRate, reverseActions, processSymmetryFactor);
                        subdomain.addParticleJumpProcess(reverseProcess);
                    }
                }
            // end of reverse rate not null
            }
        // end of maFunc not null
        }
    // end of reaction step for loop
    }
    // 
    for (int i = 0; i < fieldMathMappingParameters.length; i++) {
        if (fieldMathMappingParameters[i] instanceof UnitFactorParameter) {
            GeometryClass geometryClass = fieldMathMappingParameters[i].getGeometryClass();
            Variable variable = newFunctionOrConstant(getMathSymbol(fieldMathMappingParameters[i], geometryClass), getIdentifierSubstitutions(fieldMathMappingParameters[i].getExpression(), fieldMathMappingParameters[i].getUnitDefinition(), geometryClass), fieldMathMappingParameters[i].getGeometryClass());
            if (mathDesc.getVariable(variable.getName()) == null) {
                mathDesc.addVariable(variable);
            }
        }
    }
    if (!mathDesc.isValid()) {
        lg.warn(mathDesc.getVCML_database());
        throw new MappingException("generated an invalid mathDescription: " + mathDesc.getWarning());
    }
    if (lg.isDebugEnabled()) {
        System.out.println("]]]]]]]]]]]]]]]]]]]]]] VCML string begin ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]");
        System.out.println(mathDesc.getVCML());
        System.out.println("]]]]]]]]]]]]]]]]]]]]]] VCML string end ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]");
    }
}
Also used : MembraneSubDomain(cbit.vcell.math.MembraneSubDomain) LumpedKinetics(cbit.vcell.model.LumpedKinetics) MathDescription(cbit.vcell.math.MathDescription) ArrayList(java.util.ArrayList) Product(cbit.vcell.model.Product) SpeciesContext(cbit.vcell.model.SpeciesContext) StructureMappingParameter(cbit.vcell.mapping.StructureMapping.StructureMappingParameter) Reactant(cbit.vcell.model.Reactant) ExpressionException(cbit.vcell.parser.ExpressionException) CompartmentSubDomain(cbit.vcell.math.CompartmentSubDomain) SubDomain(cbit.vcell.math.SubDomain) MembraneSubDomain(cbit.vcell.math.MembraneSubDomain) KineticsParameter(cbit.vcell.model.Kinetics.KineticsParameter) SubVolume(cbit.vcell.geometry.SubVolume) Vector(java.util.Vector) SpatialQuantity(cbit.vcell.mapping.spatial.SpatialObject.SpatialQuantity) SpeciesContextSpecParameter(cbit.vcell.mapping.SpeciesContextSpec.SpeciesContextSpecParameter) SpeciesContextSpecParameter(cbit.vcell.mapping.SpeciesContextSpec.SpeciesContextSpecParameter) JumpProcessRateDefinition(cbit.vcell.math.JumpProcessRateDefinition) InteractionRadius(cbit.vcell.math.InteractionRadius) ParticleJumpProcess(cbit.vcell.math.ParticleJumpProcess) ModelParameter(cbit.vcell.model.Model.ModelParameter) VCUnitDefinition(cbit.vcell.units.VCUnitDefinition) CompartmentSubDomain(cbit.vcell.math.CompartmentSubDomain) ParticleInitialCondition(cbit.vcell.math.ParticleProperties.ParticleInitialCondition) ReactionStep(cbit.vcell.model.ReactionStep) ParticleProperties(cbit.vcell.math.ParticleProperties) Kinetics(cbit.vcell.model.Kinetics) DistributedKinetics(cbit.vcell.model.DistributedKinetics) LumpedKinetics(cbit.vcell.model.LumpedKinetics) CompartmentSubDomain(cbit.vcell.math.CompartmentSubDomain) SubDomain(cbit.vcell.math.SubDomain) Domain(cbit.vcell.math.Variable.Domain) MembraneSubDomain(cbit.vcell.math.MembraneSubDomain) ReactionParticipant(cbit.vcell.model.ReactionParticipant) GeometryClass(cbit.vcell.geometry.GeometryClass) Action(cbit.vcell.math.Action) VolumeParticleVariable(cbit.vcell.math.VolumeParticleVariable) MembraneParticleVariable(cbit.vcell.math.MembraneParticleVariable) ParticleVariable(cbit.vcell.math.ParticleVariable) Variable(cbit.vcell.math.Variable) SpeciesContextSpecProxyParameter(cbit.vcell.mapping.SpeciesContextSpec.SpeciesContextSpecProxyParameter) SurfaceClass(cbit.vcell.geometry.SurfaceClass) VariableHash(cbit.vcell.math.VariableHash) VolumeParticleVariable(cbit.vcell.math.VolumeParticleVariable) MembraneParticleVariable(cbit.vcell.math.MembraneParticleVariable) ParticleVariable(cbit.vcell.math.ParticleVariable) MacroscopicRateConstant(cbit.vcell.math.MacroscopicRateConstant) Constant(cbit.vcell.math.Constant) SymbolTableEntry(cbit.vcell.parser.SymbolTableEntry) MacroscopicRateConstant(cbit.vcell.math.MacroscopicRateConstant) RationalNumber(ucar.units_vcell.RationalNumber) ModelUnitSystem(cbit.vcell.model.ModelUnitSystem) Pair(org.vcell.util.Pair) ParticleInitialConditionConcentration(cbit.vcell.math.ParticleProperties.ParticleInitialConditionConcentration) ProcessSymmetryFactor(cbit.vcell.math.ParticleJumpProcess.ProcessSymmetryFactor) Expression(cbit.vcell.parser.Expression) VolumeParticleVariable(cbit.vcell.math.VolumeParticleVariable) MathException(cbit.vcell.math.MathException) Model(cbit.vcell.model.Model) StructureMappingParameter(cbit.vcell.mapping.StructureMapping.StructureMappingParameter) Parameter(cbit.vcell.model.Parameter) KineticsParameter(cbit.vcell.model.Kinetics.KineticsParameter) SpeciesContextSpecProxyParameter(cbit.vcell.mapping.SpeciesContextSpec.SpeciesContextSpecProxyParameter) ModelParameter(cbit.vcell.model.Model.ModelParameter) SpeciesContextSpecParameter(cbit.vcell.mapping.SpeciesContextSpec.SpeciesContextSpecParameter) MassActionSolver(cbit.vcell.model.MassActionSolver) ParticleInitialConditionCount(cbit.vcell.math.ParticleProperties.ParticleInitialConditionCount)

Example 9 with Pair

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

the class RulebasedTransformer method parseBngOutput.

private void parseBngOutput(SimulationContext simContext, Set<ReactionRule> fromReactions, BNGOutput bngOutput) {
    Model model = simContext.getModel();
    Document bngNFSimXMLDocument = bngOutput.getNFSimXMLDocument();
    bngRootElement = bngNFSimXMLDocument.getRootElement();
    Element modelElement = bngRootElement.getChild("model", Namespace.getNamespace("http://www.sbml.org/sbml/level3"));
    Element listOfReactionRulesElement = modelElement.getChild("ListOfReactionRules", Namespace.getNamespace("http://www.sbml.org/sbml/level3"));
    List<Element> reactionRuleChildren = new ArrayList<Element>();
    reactionRuleChildren = listOfReactionRulesElement.getChildren("ReactionRule", Namespace.getNamespace("http://www.sbml.org/sbml/level3"));
    for (Element reactionRuleElement : reactionRuleChildren) {
        ReactionRuleAnalysisReport rar = new ReactionRuleAnalysisReport();
        boolean bForward = true;
        String rule_id_str = reactionRuleElement.getAttributeValue("id");
        ruleElementMap.put(rule_id_str, reactionRuleElement);
        String rule_name_str = reactionRuleElement.getAttributeValue("name");
        String symmetry_factor_str = reactionRuleElement.getAttributeValue("symmetry_factor");
        Double symmetry_factor_double = Double.parseDouble(symmetry_factor_str);
        ReactionRule rr = null;
        if (rule_name_str.startsWith("_reverse_")) {
            bForward = false;
            rule_name_str = rule_name_str.substring("_reverse_".length());
            rr = model.getRbmModelContainer().getReactionRule(rule_name_str);
            RbmKineticLaw rkl = rr.getKineticLaw();
            try {
                if (symmetry_factor_double != 1.0 && fromReactions.contains(rr)) {
                    Expression expression = rkl.getLocalParameterValue(RbmKineticLawParameterType.MassActionReverseRate);
                    expression = Expression.div(expression, new Expression(symmetry_factor_double));
                    rkl.setLocalParameterValue(RbmKineticLawParameterType.MassActionReverseRate, expression);
                }
            } catch (ExpressionException | PropertyVetoException exc) {
                exc.printStackTrace();
                throw new RuntimeException("Unexpected transform exception: " + exc.getMessage());
            }
            rulesReverseMap.put(rr, rar);
        } else {
            rr = model.getRbmModelContainer().getReactionRule(rule_name_str);
            RbmKineticLaw rkl = rr.getKineticLaw();
            try {
                if (symmetry_factor_double != 1.0 && fromReactions.contains(rr)) {
                    Expression expression = rkl.getLocalParameterValue(RbmKineticLawParameterType.MassActionForwardRate);
                    expression = Expression.div(expression, new Expression(symmetry_factor_double));
                    rkl.setLocalParameterValue(RbmKineticLawParameterType.MassActionForwardRate, expression);
                }
            } catch (ExpressionException | PropertyVetoException exc) {
                exc.printStackTrace();
                throw new RuntimeException("Unexpected transform exception: " + exc.getMessage());
            }
            rulesForwardMap.put(rr, rar);
        }
        rar.symmetryFactor = symmetry_factor_double;
        System.out.println("rule id=" + rule_id_str + ", name=" + rule_name_str + ", symmetry factor=" + symmetry_factor_str);
        keyMap.put(rule_id_str, rr);
        Element listOfReactantPatternsElement = reactionRuleElement.getChild("ListOfReactantPatterns", Namespace.getNamespace("http://www.sbml.org/sbml/level3"));
        List<Element> reactantPatternChildren = new ArrayList<Element>();
        reactantPatternChildren = listOfReactantPatternsElement.getChildren("ReactantPattern", Namespace.getNamespace("http://www.sbml.org/sbml/level3"));
        for (int i = 0; i < reactantPatternChildren.size(); i++) {
            Element reactantPatternElement = reactantPatternChildren.get(i);
            String pattern_id_str = reactantPatternElement.getAttributeValue("id");
            ReactionRuleParticipant p = bForward ? rr.getReactantPattern(i) : rr.getProductPattern(i);
            SpeciesPattern sp = p.getSpeciesPattern();
            System.out.println("  reactant id=" + pattern_id_str + ", name=" + sp.toString());
            keyMap.put(pattern_id_str, sp);
            // list of molecules
            extractMolecules(sp, model, reactantPatternElement);
            // list of bonds (not implemented)
            extractBonds(reactantPatternElement);
        }
        Element listOfProductPatternsElement = reactionRuleElement.getChild("ListOfProductPatterns", Namespace.getNamespace("http://www.sbml.org/sbml/level3"));
        List<Element> productPatternChildren = new ArrayList<Element>();
        productPatternChildren = listOfProductPatternsElement.getChildren("ProductPattern", Namespace.getNamespace("http://www.sbml.org/sbml/level3"));
        for (int i = 0; i < productPatternChildren.size(); i++) {
            Element productPatternElement = productPatternChildren.get(i);
            String pattern_id_str = productPatternElement.getAttributeValue("id");
            ReactionRuleParticipant p = bForward ? rr.getProductPattern(i) : rr.getReactantPattern(i);
            SpeciesPattern sp = p.getSpeciesPattern();
            System.out.println("  product  id=" + pattern_id_str + ", name=" + sp.toString());
            keyMap.put(pattern_id_str, sp);
            extractMolecules(sp, model, productPatternElement);
            extractBonds(productPatternElement);
        }
        // extract the Map for this rule
        Element listOfMapElement = reactionRuleElement.getChild("Map", Namespace.getNamespace("http://www.sbml.org/sbml/level3"));
        List<Element> mapChildren = new ArrayList<Element>();
        mapChildren = listOfMapElement.getChildren("MapItem", Namespace.getNamespace("http://www.sbml.org/sbml/level3"));
        for (Element mapElement : mapChildren) {
            String target_id_str = mapElement.getAttributeValue("targetID");
            String source_id_str = mapElement.getAttributeValue("sourceID");
            System.out.println("Map: target=" + target_id_str + " source=" + source_id_str);
            RbmObject target_object = keyMap.get(target_id_str);
            RbmObject source_object = keyMap.get(source_id_str);
            if (target_object == null)
                System.out.println("!!! Missing map target  " + target_id_str);
            if (source_object == null)
                System.out.println("!!! Missing map source " + source_id_str);
            if (source_object != null) {
                // target_object may be null
                System.out.println("      target=" + target_object + " source=" + source_object);
                Pair<RbmObject, RbmObject> mapEntry = new Pair<RbmObject, RbmObject>(target_object, source_object);
                rar.objmappingList.add(mapEntry);
            }
            Pair<String, String> idmapEntry = new Pair<String, String>(target_id_str, source_id_str);
            rar.idmappingList.add(idmapEntry);
        }
        // ListOfOperations
        Element listOfOperationsElement = reactionRuleElement.getChild("ListOfOperations", Namespace.getNamespace("http://www.sbml.org/sbml/level3"));
        List<Element> operationsChildren = new ArrayList<Element>();
        operationsChildren = listOfOperationsElement.getChildren("StateChange", Namespace.getNamespace("http://www.sbml.org/sbml/level3"));
        System.out.println("ListOfOperations");
        for (Element operationsElement : operationsChildren) {
            String finalState_str = operationsElement.getAttributeValue("finalState");
            String site_str = operationsElement.getAttributeValue("site");
            RbmObject site_object = keyMap.get(site_str);
            if (site_object == null)
                System.out.println("!!! Missing map object " + site_str);
            if (site_object != null) {
                System.out.println("   finalState=" + finalState_str + " site=" + site_object);
                StateChangeOperation sco = new StateChangeOperation(finalState_str, site_str, site_object);
                rar.operationsList.add(sco);
            }
        }
        operationsChildren = listOfOperationsElement.getChildren("AddBond", Namespace.getNamespace("http://www.sbml.org/sbml/level3"));
        for (Element operationsElement : operationsChildren) {
            String site1_str = operationsElement.getAttributeValue("site1");
            String site2_str = operationsElement.getAttributeValue("site2");
            RbmObject site1_object = keyMap.get(site1_str);
            RbmObject site2_object = keyMap.get(site2_str);
            if (site1_object == null)
                System.out.println("!!! Missing map object " + site1_str);
            if (site2_object == null)
                System.out.println("!!! Missing map object " + site2_str);
            if (site1_object != null && site2_object != null) {
                System.out.println("   site1=" + site1_object + " site2=" + site2_object);
                AddBondOperation abo = new AddBondOperation(site1_str, site2_str, site1_object, site2_object);
                rar.operationsList.add(abo);
            }
        }
        operationsChildren = listOfOperationsElement.getChildren("DeleteBond", Namespace.getNamespace("http://www.sbml.org/sbml/level3"));
        for (Element operationsElement : operationsChildren) {
            String site1_str = operationsElement.getAttributeValue("site1");
            String site2_str = operationsElement.getAttributeValue("site2");
            RbmObject site1_object = keyMap.get(site1_str);
            RbmObject site2_object = keyMap.get(site2_str);
            if (site1_object == null)
                System.out.println("!!! Missing map object " + site1_str);
            if (site2_object == null)
                System.out.println("!!! Missing map object " + site2_str);
            if (site1_object != null && site2_object != null) {
                System.out.println("   site1=" + site1_object + " site2=" + site2_object);
                DeleteBondOperation dbo = new DeleteBondOperation(site1_str, site2_str, site1_object, site2_object);
                rar.operationsList.add(dbo);
            }
        }
        operationsChildren = listOfOperationsElement.getChildren("Add", Namespace.getNamespace("http://www.sbml.org/sbml/level3"));
        for (Element operationsElement : operationsChildren) {
            String id_str = operationsElement.getAttributeValue("id");
            RbmObject id_object = keyMap.get(id_str);
            if (id_object == null)
                System.out.println("!!! Missing map object " + id_str);
            if (id_object != null) {
                System.out.println("   id=" + id_str);
                AddOperation ao = new AddOperation(id_str, id_object);
                rar.operationsList.add(ao);
            }
        }
        operationsChildren = listOfOperationsElement.getChildren("Delete", Namespace.getNamespace("http://www.sbml.org/sbml/level3"));
        for (Element operationsElement : operationsChildren) {
            String id_str = operationsElement.getAttributeValue("id");
            String delete_molecules_str = operationsElement.getAttributeValue("DeleteMolecules");
            RbmObject id_object = keyMap.get(id_str);
            if (id_object == null)
                System.out.println("!!! Missing map object " + id_str);
            int delete_molecules_int = 0;
            if (delete_molecules_str != null) {
                delete_molecules_int = Integer.parseInt(delete_molecules_str);
            }
            if (id_object != null) {
                System.out.println("   id=" + id_str + ", DeleteMolecules=" + delete_molecules_str);
                DeleteOperation dop = new DeleteOperation(id_str, id_object, delete_molecules_int);
                rar.operationsList.add(dop);
            }
        }
    }
    System.out.println("done parsing xml file");
}
Also used : Element(org.jdom.Element) ArrayList(java.util.ArrayList) Document(org.jdom.Document) ExpressionException(cbit.vcell.parser.ExpressionException) SpeciesPattern(org.vcell.model.rbm.SpeciesPattern) Pair(org.vcell.util.Pair) ReactionRule(cbit.vcell.model.ReactionRule) RbmKineticLaw(cbit.vcell.model.RbmKineticLaw) PropertyVetoException(java.beans.PropertyVetoException) Expression(cbit.vcell.parser.Expression) ReactionRuleParticipant(cbit.vcell.model.ReactionRuleParticipant) RbmObject(org.vcell.model.rbm.RbmObject) Model(cbit.vcell.model.Model)

Example 10 with Pair

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

the class RulebasedTransformer method generateNetwork.

private void generateNetwork(SimulationContext simContext, Set<ReactionRule> fromReactions, MathMappingCallback mathMappingCallback) throws ClassNotFoundException, IOException {
    TaskCallbackMessage tcm;
    BNGOutputSpec outputSpec;
    speciesEquivalenceMap.clear();
    kineticsParameterMap.clear();
    NetworkGenerationRequirements networkGenerationRequirements = NetworkGenerationRequirements.ComputeFullStandardTimeout;
    String input = convertToBngl(simContext, true, mathMappingCallback, networkGenerationRequirements);
    // System.out.println(input);		// TODO: uncomment to see the xml string
    for (Map.Entry<FakeSeedSpeciesInitialConditionsParameter, Pair<SpeciesContext, Expression>> entry : speciesEquivalenceMap.entrySet()) {
        FakeSeedSpeciesInitialConditionsParameter key = entry.getKey();
        Pair<SpeciesContext, Expression> value = entry.getValue();
        SpeciesContext sc = value.one;
        Expression initial = value.two;
        System.out.println("key: " + key.fakeParameterName + ",   species: " + sc.getName() + ", initial: " + initial.infix());
    }
    BNGInput bngInput = new BNGInput(input);
    BNGOutput bngOutput = null;
    try {
        // for the writeXML command we don't want to run iteration by iteration - it wouldn't even make sense since we don't flatten anything
        // so we run bionetgen the "old" way
        final BNGExecutorService bngService = BNGExecutorService.getInstanceOld(bngInput, networkGenerationRequirements.timeoutDurationMS);
        bngOutput = bngService.executeBNG();
    } catch (RuntimeException ex) {
        ex.printStackTrace(System.out);
        // rethrow without losing context
        throw ex;
    } catch (Exception ex) {
        ex.printStackTrace(System.out);
        throw new RuntimeException(ex.getMessage());
    }
    simContext.setInsufficientIterations(false);
    simContext.setInsufficientMaxMolecules(false);
    String bngConsoleString = bngOutput.getConsoleOutput();
    tcm = new TaskCallbackMessage(TaskCallbackStatus.DetailBatch, bngConsoleString);
    // simContext.appendToConsole(tcm);
    // String bngNetString = bngOutput.getNetFileContent();
    // outputSpec = BNGOutputFileParser.createBngOutputSpec(bngNetString);
    // //BNGOutputFileParser.printBNGNetOutput(outputSpec);			// prints all output to console
    // 
    // if (mathMappingCallback.isInterrupted()){
    // String msg = "Canceled by user.";
    // //			tcm = new TaskCallbackMessage(TaskCallbackStatus.Error, msg);
    // //			simContext.appendToConsole(tcm);
    // //			simContext.setMd5hash(null);					// clean the cache if the user interrupts
    // throw new UserCancelException(msg);
    // }
    // if(outputSpec.getBNGSpecies().length > SimulationConsolePanel.speciesLimit) {
    // String message = SimulationConsolePanel.getSpeciesLimitExceededMessage(outputSpec);
    // //			tcm = new TaskCallbackMessage(TaskCallbackStatus.Error, message);
    // //			simContext.appendToConsole(tcm);
    // //			simContext.setMd5hash(null);
    // throw new RuntimeException(message);
    // }
    // if(outputSpec.getBNGReactions().length > SimulationConsolePanel.reactionsLimit) {
    // String message = SimulationConsolePanel.getReactionsLimitExceededMessage(outputSpec);
    // //			tcm = new TaskCallbackMessage(TaskCallbackStatus.Error, message);
    // //			simContext.appendToConsole(tcm);
    // //			simContext.setMd5hash(null);
    // throw new RuntimeException(message);
    // }
    // TODO: uncomment here to parse the xml file!!!
    parseBngOutput(simContext, fromReactions, bngOutput);
// 
// Saving the observables, as produced by bionetgen
// in debug configurations add to command line   -Ddebug.user=danv
// 
// String debugUser = PropertyLoader.getProperty("debug.user", "not_defined");
// if (debugUser.equals("danv") || debugUser.equals("mblinov")){
// System.out.println("Saving their observables");
// parseObservablesBngOutput(simContext, bngOutput);
// }
// compareOutputs(simContext);
}
Also used : SpeciesContext(cbit.vcell.model.SpeciesContext) BNGExecutorService(cbit.vcell.server.bionetgen.BNGExecutorService) BNGOutput(cbit.vcell.server.bionetgen.BNGOutput) FakeSeedSpeciesInitialConditionsParameter(org.vcell.model.rbm.FakeSeedSpeciesInitialConditionsParameter) BNGOutputSpec(cbit.vcell.bionetgen.BNGOutputSpec) PropertyVetoException(java.beans.PropertyVetoException) ModelException(cbit.vcell.model.ModelException) IOException(java.io.IOException) ExpressionException(cbit.vcell.parser.ExpressionException) Expression(cbit.vcell.parser.Expression) NetworkGenerationRequirements(cbit.vcell.mapping.SimulationContext.NetworkGenerationRequirements) BNGInput(cbit.vcell.server.bionetgen.BNGInput) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) 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