Search in sources :

Example 6 with SubVolume

use of cbit.vcell.geometry.SubVolume in project vcell by virtualcell.

the class ClientRequestManager method createMathModel.

/**
 * Insert the method's description here.
 * Creation date: (5/24/2004 12:22:11 PM)
 * @param windowID java.lang.String
 */
private MathModel createMathModel(String name, Geometry geometry) {
    MathModel mathModel = new MathModel(null);
    MathDescription mathDesc = mathModel.getMathDescription();
    try {
        mathDesc.setGeometry(geometry);
        if (geometry.getDimension() == 0) {
            mathDesc.addSubDomain(new CompartmentSubDomain("Compartment", CompartmentSubDomain.NON_SPATIAL_PRIORITY));
        } else {
            try {
                if (geometry.getDimension() > 0 && geometry.getGeometrySurfaceDescription().getGeometricRegions() == null) {
                    geometry.getGeometrySurfaceDescription().updateAll();
                }
            } catch (ImageException e) {
                e.printStackTrace(System.out);
                throw new RuntimeException("Geometric surface generation error: \n" + e.getMessage());
            } catch (GeometryException e) {
                e.printStackTrace(System.out);
                throw new RuntimeException("Geometric surface generation error: \n" + e.getMessage());
            }
            SubVolume[] subVolumes = geometry.getGeometrySpec().getSubVolumes();
            for (int i = 0; i < subVolumes.length; i++) {
                mathDesc.addSubDomain(new CompartmentSubDomain(subVolumes[i].getName(), subVolumes[i].getHandle()));
            }
            // 
            // add only those MembraneSubDomains corresponding to surfaces that acutally exist in geometry.
            // 
            GeometricRegion[] regions = geometry.getGeometrySurfaceDescription().getGeometricRegions();
            for (int i = 0; i < regions.length; i++) {
                if (regions[i] instanceof SurfaceGeometricRegion) {
                    SurfaceGeometricRegion surfaceRegion = (SurfaceGeometricRegion) regions[i];
                    SubVolume subVolume1 = ((VolumeGeometricRegion) surfaceRegion.getAdjacentGeometricRegions()[0]).getSubVolume();
                    SubVolume subVolume2 = ((VolumeGeometricRegion) surfaceRegion.getAdjacentGeometricRegions()[1]).getSubVolume();
                    CompartmentSubDomain compartment1 = mathDesc.getCompartmentSubDomain(subVolume1.getName());
                    CompartmentSubDomain compartment2 = mathDesc.getCompartmentSubDomain(subVolume2.getName());
                    MembraneSubDomain membraneSubDomain = mathDesc.getMembraneSubDomain(compartment1, compartment2);
                    if (membraneSubDomain == null) {
                        SurfaceClass surfaceClass = geometry.getGeometrySurfaceDescription().getSurfaceClass(subVolume1, subVolume2);
                        membraneSubDomain = new MembraneSubDomain(compartment1, compartment2, surfaceClass.getName());
                        mathDesc.addSubDomain(membraneSubDomain);
                    }
                }
            }
        }
        mathDesc.isValid();
        mathModel.setName(name);
    } catch (Exception e) {
        e.printStackTrace(System.out);
    }
    return mathModel;
}
Also used : MathModel(cbit.vcell.mathmodel.MathModel) MembraneSubDomain(cbit.vcell.math.MembraneSubDomain) ImageException(cbit.image.ImageException) SetMathDescription(cbit.vcell.client.task.SetMathDescription) MathDescription(cbit.vcell.math.MathDescription) SurfaceClass(cbit.vcell.geometry.SurfaceClass) GeometryException(cbit.vcell.geometry.GeometryException) VolumeGeometricRegion(cbit.vcell.geometry.surface.VolumeGeometricRegion) ProgrammingException(org.vcell.util.ProgrammingException) GeometryException(cbit.vcell.geometry.GeometryException) IOException(java.io.IOException) DataAccessException(org.vcell.util.DataAccessException) PropertyVetoException(java.beans.PropertyVetoException) ImageException(cbit.image.ImageException) UtilCancelException(org.vcell.util.UtilCancelException) DataFormatException(java.util.zip.DataFormatException) UserCancelException(org.vcell.util.UserCancelException) SurfaceGeometricRegion(cbit.vcell.geometry.surface.SurfaceGeometricRegion) VolumeGeometricRegion(cbit.vcell.geometry.surface.VolumeGeometricRegion) GeometricRegion(cbit.vcell.geometry.surface.GeometricRegion) CompartmentSubDomain(cbit.vcell.math.CompartmentSubDomain) SubVolume(cbit.vcell.geometry.SubVolume) AnalyticSubVolume(cbit.vcell.geometry.AnalyticSubVolume) SurfaceGeometricRegion(cbit.vcell.geometry.surface.SurfaceGeometricRegion)

Example 7 with SubVolume

use of cbit.vcell.geometry.SubVolume in project vcell by virtualcell.

the class MathModel_SBMLExporter method addGeometry.

private static void addGeometry(Model sbmlModel, MathModel vcMathModel) {
    SpatialModelPlugin mplugin = (SpatialModelPlugin) sbmlModel.getPlugin(SBMLUtils.SBML_SPATIAL_NS_PREFIX);
    // Creates a geometry object via SpatialModelPlugin object.
    org.sbml.jsbml.ext.spatial.Geometry sbmlGeometry = mplugin.getGeometry();
    sbmlGeometry.setCoordinateSystem(GeometryKind.cartesian);
    Geometry vcGeometry = vcMathModel.getGeometry();
    // 
    // list of CoordinateComponents : 1 if geometry is 1-d, 2 if geometry is 2-d, 3 if geometry is 3-d
    // 
    int dimension = vcGeometry.getDimension();
    Extent vcExtent = vcGeometry.getExtent();
    Origin vcOrigin = vcGeometry.getOrigin();
    // add x coordinate component
    CoordinateComponent coordCompX = sbmlGeometry.createCoordinateComponent();
    coordCompX.setSpatialId("CoordCompX");
    coordCompX.setType(CoordinateKind.cartesianX);
    Boundary minX = coordCompX.getBoundaryMaximum();
    minX.setSpatialId("Xmin");
    minX.setValue(vcOrigin.getX());
    Boundary maxX = coordCompX.getBoundaryMaximum();
    maxX.setSpatialId("Xmax");
    maxX.setValue(vcOrigin.getX() + (vcExtent.getX()));
    Parameter parameterX = sbmlModel.createParameter();
    // note for exporting BioModels rather than MathModels, get ReservedSymbol from Model with Role of ReservedSymbolRole.X
    parameterX.setId(ReservedVariable.X.getName());
    SpatialSymbolReference coordXSpatialRef = new SpatialSymbolReference();
    coordXSpatialRef.setSpatialRef(coordCompX.getSpatialId());
    SpatialParameterPlugin parameterXSpatialPlugin = (SpatialParameterPlugin) parameterX.getPlugin(SBMLUtils.SBML_SPATIAL_NS_PREFIX);
    parameterXSpatialPlugin.setParamType(coordXSpatialRef);
    // add y coordinate component
    if (dimension == 2 || dimension == 3) {
        CoordinateComponent coordCompY = sbmlGeometry.createCoordinateComponent();
        coordCompY.setSpatialId("CoordCompY");
        coordCompY.setType(CoordinateKind.cartesianY);
        Boundary minY = coordCompY.getBoundaryMinimum();
        minY.setId("Ymin");
        minY.setValue(vcOrigin.getY());
        Boundary maxY = coordCompY.getBoundaryMaximum();
        maxY.setId("Ymax");
        maxY.setValue(vcOrigin.getY() + (vcExtent.getY()));
        Parameter parameterY = sbmlModel.createParameter();
        // note for exporting BioModels rather than MathModels, get ReservedSymbol from Model with Role of ReservedSymbolRole.Y
        parameterY.setId(ReservedVariable.Y.getName());
        SpatialSymbolReference coordYSpatialRef = new SpatialSymbolReference();
        coordYSpatialRef.setSpatialRef(coordCompY.getSpatialId());
        SpatialParameterPlugin parameterYSpatialPlugin = (SpatialParameterPlugin) parameterY.getPlugin(SBMLUtils.SBML_SPATIAL_NS_PREFIX);
        parameterYSpatialPlugin.setParamType(coordYSpatialRef);
    }
    // add z coordinate component
    if (dimension == 3) {
        CoordinateComponent coordCompZ = sbmlGeometry.createCoordinateComponent();
        coordCompZ.setSpatialId("CoordCompZ");
        coordCompZ.setType(CoordinateKind.cartesianZ);
        Boundary minZ = coordCompZ.getBoundaryMinimum();
        minZ.setId("Zmin");
        minZ.setValue(vcOrigin.getZ());
        Boundary maxZ = coordCompZ.getBoundaryMaximum();
        maxZ.setId("Zmax");
        maxZ.setValue(vcOrigin.getZ() + (vcExtent.getZ()));
        Parameter parameterZ = sbmlModel.createParameter();
        // note for exporting BioModels rather than MathModels, get ReservedSymbol from Model with Role of ReservedSymbolRole.Y
        parameterZ.setId(ReservedVariable.Z.getName());
        SpatialSymbolReference coordZSpatialRef = new SpatialSymbolReference();
        coordZSpatialRef.setSpatialRef(coordCompZ.getSpatialId());
        SpatialParameterPlugin parameterZSpatialPlugin = (SpatialParameterPlugin) parameterZ.getPlugin(SBMLUtils.SBML_SPATIAL_NS_PREFIX);
        parameterZSpatialPlugin.setParamType(coordZSpatialRef);
    }
    // 
    // list of domain types : subvolumes and surface classes from VC
    // Also create compartments - one compartment for each geometryClass. set id and spatialDimension based on type of geometryClass.
    // 
    boolean bAnalyticGeom = false;
    boolean bImageGeom = false;
    GeometryClass[] vcGeomClasses = vcGeometry.getGeometryClasses();
    int numVCGeomClasses = vcGeomClasses.length;
    for (int i = 0; i < numVCGeomClasses; i++) {
        DomainType domainType = sbmlGeometry.createDomainType();
        domainType.setId(vcGeomClasses[i].getName());
        if (vcGeomClasses[i] instanceof SubVolume) {
            if (((SubVolume) vcGeomClasses[i]) instanceof AnalyticSubVolume) {
                bAnalyticGeom = true;
            } else if (((SubVolume) vcGeomClasses[i]) instanceof ImageSubVolume) {
                bImageGeom = true;
            }
            domainType.setSpatialDimensions(3);
        } else if (vcGeomClasses[i] instanceof SurfaceClass) {
            domainType.setSpatialDimensions(2);
        }
    }
    // 
    // list of domains, adjacent domains : from VC geometricRegions
    // 
    GeometrySurfaceDescription vcGSD = vcGeometry.getGeometrySurfaceDescription();
    if (vcGSD.getRegionImage() == null) {
        try {
            vcGSD.updateAll();
        } catch (Exception e) {
            e.printStackTrace(System.out);
            throw new RuntimeException("Unable to generate region images for geometry");
        }
    }
    GeometricRegion[] vcGeometricRegions = vcGSD.getGeometricRegions();
    ISize sampleSize = vcGSD.getVolumeSampleSize();
    int numX = sampleSize.getX();
    int numY = sampleSize.getY();
    int numZ = sampleSize.getZ();
    double ox = vcOrigin.getX();
    double oy = vcOrigin.getY();
    double oz = vcOrigin.getZ();
    RegionInfo[] regionInfos = vcGSD.getRegionImage().getRegionInfos();
    Compartment compartment = null;
    for (int i = 0; i < vcGeometricRegions.length; i++) {
        // domains
        Domain domain = sbmlGeometry.createDomain();
        domain.setId(vcGeometricRegions[i].getName());
        compartment = sbmlModel.createCompartment();
        compartment.setId("compartment" + i);
        if (vcGeometricRegions[i] instanceof VolumeGeometricRegion) {
            domain.setDomainType(((VolumeGeometricRegion) vcGeometricRegions[i]).getSubVolume().getName());
            // domain.setImplicit(false);
            compartment.setSpatialDimensions(3);
            InteriorPoint interiorPt = domain.createInteriorPoint();
            int regionID = ((VolumeGeometricRegion) vcGeometricRegions[i]).getRegionID();
            boolean bFound = false;
            int regInfoIndx = 0;
            for (int j = 0; j < regionInfos.length; j++) {
                regInfoIndx = j;
                if (regionInfos[j].getRegionIndex() == regionID) {
                    int volIndx = 0;
                    for (int z = 0; z < numZ && !bFound; z++) {
                        for (int y = 0; y < numY && !bFound; y++) {
                            for (int x = 0; x < numX && !bFound; x++) {
                                if (regionInfos[j].isIndexInRegion(volIndx)) {
                                    bFound = true;
                                    double unit_z = (numZ > 1) ? ((double) z) / (numZ - 1) : 0.5;
                                    double coordZ = oz + vcExtent.getZ() * unit_z;
                                    double unit_y = (numY > 1) ? ((double) y) / (numY - 1) : 0.5;
                                    double coordY = oy + vcExtent.getY() * unit_y;
                                    double unit_x = (numX > 1) ? ((double) x) / (numX - 1) : 0.5;
                                    double coordX = ox + vcExtent.getX() * unit_x;
                                    interiorPt.setCoord1(coordX);
                                    interiorPt.setCoord2(coordY);
                                    interiorPt.setCoord3(coordZ);
                                }
                                volIndx++;
                            }
                        // end - for x
                        }
                    // end - for y
                    }
                // end - for z
                }
            // end if
            }
            // end for regionInfos
            if (!bFound) {
                throw new RuntimeException("Unable to find interior point for region '" + regionInfos[regInfoIndx].toString());
            }
        } else if (vcGeometricRegions[i] instanceof SurfaceGeometricRegion) {
            SurfaceGeometricRegion vcSurfaceGeomReg = (SurfaceGeometricRegion) vcGeometricRegions[i];
            GeometricRegion geomRegion0 = vcSurfaceGeomReg.getAdjacentGeometricRegions()[0];
            GeometricRegion geomRegion1 = vcSurfaceGeomReg.getAdjacentGeometricRegions()[1];
            SurfaceClass surfaceClass = vcGSD.getSurfaceClass(((VolumeGeometricRegion) geomRegion0).getSubVolume(), ((VolumeGeometricRegion) geomRegion1).getSubVolume());
            domain.setDomainType(surfaceClass.getName());
            // domain.setImplicit(true);
            compartment.setSpatialDimensions(2);
            // adjacent domains : 2 adjacent domain objects for each surfaceClass in VC.
            // adjacent domain 1
            AdjacentDomains adjDomain = sbmlGeometry.createAdjacentDomain();
            adjDomain.setId(TokenMangler.mangleToSName(vcSurfaceGeomReg.getName() + "_" + geomRegion0.getName()));
            adjDomain.setDomain1(vcSurfaceGeomReg.getName());
            adjDomain.setDomain2(geomRegion0.getName());
            // adjacent domain 2
            adjDomain = sbmlGeometry.createAdjacentDomain();
            adjDomain.setId(TokenMangler.mangleToSName(vcSurfaceGeomReg.getName() + "_" + geomRegion1.getName()));
            adjDomain.setDomain1(vcSurfaceGeomReg.getName());
            adjDomain.setDomain2(geomRegion1.getName());
        }
        // 
        // Mathmodel does not have structureMapping, hence creating compartmentMapping while creating domains.
        // @TODO : how to assign unitSize for compartmentMapping?
        // 
        SpatialCompartmentPlugin cplugin = (SpatialCompartmentPlugin) compartment.getPlugin(SBMLUtils.SBML_SPATIAL_NS_PREFIX);
        CompartmentMapping compMapping = cplugin.getCompartmentMapping();
        String compMappingId = TokenMangler.mangleToSName(domain.getDomainType() + "_" + compartment.getId());
        compMapping.setId(compMappingId);
        compMapping.setDomainType(TokenMangler.mangleToSName(domain.getDomainType()));
    // try {
    // compMapping.setUnitSize(1.0);
    // } catch (ExpressionException e) {
    // e.printStackTrace(System.out);
    // throw new RuntimeException("Unable to create compartment mapping for structureMapping '" + compMapping.getId() +"' : " + e.getMessage());
    // }
    }
    AnalyticGeometry sbmlAnalyticGeom = null;
    SampledFieldGeometry sbmlSFGeom = null;
    // both image and analytic subvolumes?? == not handled in SBML at this time.
    if (bAnalyticGeom && !bImageGeom) {
        sbmlAnalyticGeom = sbmlGeometry.createAnalyticGeometry();
        sbmlAnalyticGeom.setId(TokenMangler.mangleToSName(vcGeometry.getName()));
    } else if (bImageGeom && !bAnalyticGeom) {
        // assuming image based geometry if not analytic geometry
        sbmlSFGeom = sbmlGeometry.createSampledFieldGeometry();
        sbmlSFGeom.setId(TokenMangler.mangleToSName(vcGeometry.getName()));
    } else if (bAnalyticGeom && bImageGeom) {
        throw new RuntimeException("Export to SBML of a combination of Image-based and Analytic geometries is not supported yet.");
    } else if (!bAnalyticGeom && !bImageGeom) {
        throw new RuntimeException("Unknown geometry type.");
    }
    // 
    for (int i = 0; i < vcGeomClasses.length; i++) {
        if (vcGeomClasses[i] instanceof AnalyticSubVolume) {
            // add analytiVols to sbmlAnalyticGeometry
            if (sbmlAnalyticGeom != null) {
                AnalyticVolume analyticVol = sbmlAnalyticGeom.createAnalyticVolume();
                analyticVol.setId(vcGeomClasses[i].getName());
                analyticVol.setDomainType(vcGeomClasses[i].getName());
                analyticVol.setFunctionType(FunctionKind.layered);
                analyticVol.setOrdinal(i);
                Expression expr = ((AnalyticSubVolume) vcGeomClasses[i]).getExpression();
                try {
                    String mathMLStr = ExpressionMathMLPrinter.getMathML(expr, true);
                    ASTNode mathMLNode = ASTNode.readMathMLFromString(mathMLStr);
                    analyticVol.setMath(mathMLNode);
                } catch (Exception e) {
                    e.printStackTrace(System.out);
                    throw new RuntimeException("Error converting VC subvolume expression to mathML" + e.getMessage());
                }
            } else {
                throw new RuntimeException("SBML AnalyticGeometry is null.");
            }
        } else if (vcGeomClasses[i] instanceof ImageSubVolume) {
            // add sampledVols to sbmlSFGeometry
            if (sbmlSFGeom != null) {
                SampledVolume sampledVol = sbmlSFGeom.createSampledVolume();
                sampledVol.setId(vcGeomClasses[i].getName());
                sampledVol.setDomainType(vcGeomClasses[i].getName());
                sampledVol.setSampledValue(((ImageSubVolume) vcGeomClasses[i]).getPixelValue());
            } else {
                throw new RuntimeException("SBML SampledFieldGeometry is null.");
            }
        }
    }
    if (sbmlSFGeom != null) {
        // add sampledField to sampledFieldGeometry
        SampledField sampledField = sbmlGeometry.createSampledField();
        VCImage vcImage = vcGeometry.getGeometrySpec().getImage();
        sampledField.setId(vcImage.getName());
        sampledField.setNumSamples1(vcImage.getNumX());
        if (vcImage.getNumY() > 1) {
            sampledField.setNumSamples2(vcImage.getNumY());
        }
        if (vcImage.getNumZ() > 1) {
            sampledField.setNumSamples3(vcImage.getNumZ());
        }
        sampledField.setInterpolationType(InterpolationKind.nearestneighbor);
        sampledField.setDataType(DataKind.UINT8);
        // add image from vcGeometrySpec to sampledField.
        try {
            StringBuffer sb = new StringBuffer();
            byte[] imagePixelsBytes = vcImage.getPixelsCompressed();
            for (int i = 0; i < imagePixelsBytes.length; i++) {
                int uint8_sample = ((int) imagePixelsBytes[i]) & 0xff;
                sb.append(uint8_sample + " ");
            }
            sampledField.setSamplesLength(vcImage.getNumXYZ());
            sampledField.setSamples(sb.toString().trim());
        } catch (ImageException e) {
            e.printStackTrace(System.out);
            throw new RuntimeException("Unable to export image from VCell to SBML : " + e.getMessage());
        }
    }
}
Also used : Origin(org.vcell.util.Origin) CompartmentMapping(org.sbml.jsbml.ext.spatial.CompartmentMapping) Compartment(org.sbml.jsbml.Compartment) SpatialParameterPlugin(org.sbml.jsbml.ext.spatial.SpatialParameterPlugin) AnalyticGeometry(org.sbml.jsbml.ext.spatial.AnalyticGeometry) Boundary(org.sbml.jsbml.ext.spatial.Boundary) DomainType(org.sbml.jsbml.ext.spatial.DomainType) SampledVolume(org.sbml.jsbml.ext.spatial.SampledVolume) SubVolume(cbit.vcell.geometry.SubVolume) ImageSubVolume(cbit.vcell.geometry.ImageSubVolume) AnalyticSubVolume(cbit.vcell.geometry.AnalyticSubVolume) SpatialCompartmentPlugin(org.sbml.jsbml.ext.spatial.SpatialCompartmentPlugin) CoordinateComponent(org.sbml.jsbml.ext.spatial.CoordinateComponent) VolumeGeometricRegion(cbit.vcell.geometry.surface.VolumeGeometricRegion) VolumeGeometricRegion(cbit.vcell.geometry.surface.VolumeGeometricRegion) SurfaceGeometricRegion(cbit.vcell.geometry.surface.SurfaceGeometricRegion) GeometricRegion(cbit.vcell.geometry.surface.GeometricRegion) SpatialSymbolReference(org.sbml.jsbml.ext.spatial.SpatialSymbolReference) AnalyticVolume(org.sbml.jsbml.ext.spatial.AnalyticVolume) InteriorPoint(org.sbml.jsbml.ext.spatial.InteriorPoint) SampledField(org.sbml.jsbml.ext.spatial.SampledField) Domain(org.sbml.jsbml.ext.spatial.Domain) AnalyticSubVolume(cbit.vcell.geometry.AnalyticSubVolume) GeometryClass(cbit.vcell.geometry.GeometryClass) ImageException(cbit.image.ImageException) GeometrySurfaceDescription(cbit.vcell.geometry.surface.GeometrySurfaceDescription) Extent(org.vcell.util.Extent) SurfaceClass(cbit.vcell.geometry.SurfaceClass) ISize(org.vcell.util.ISize) RegionInfo(cbit.vcell.geometry.RegionImage.RegionInfo) VCImage(cbit.image.VCImage) ASTNode(org.sbml.jsbml.ASTNode) ImageSubVolume(cbit.vcell.geometry.ImageSubVolume) SurfaceGeometricRegion(cbit.vcell.geometry.surface.SurfaceGeometricRegion) SampledFieldGeometry(org.sbml.jsbml.ext.spatial.SampledFieldGeometry) SpatialModelPlugin(org.sbml.jsbml.ext.spatial.SpatialModelPlugin) InteriorPoint(org.sbml.jsbml.ext.spatial.InteriorPoint) XMLStreamException(javax.xml.stream.XMLStreamException) ImageException(cbit.image.ImageException) SBMLException(org.sbml.jsbml.SBMLException) AdjacentDomains(org.sbml.jsbml.ext.spatial.AdjacentDomains) Geometry(cbit.vcell.geometry.Geometry) AnalyticGeometry(org.sbml.jsbml.ext.spatial.AnalyticGeometry) SampledFieldGeometry(org.sbml.jsbml.ext.spatial.SampledFieldGeometry) Expression(cbit.vcell.parser.Expression) Parameter(org.sbml.jsbml.Parameter)

Example 8 with SubVolume

use of cbit.vcell.geometry.SubVolume in project vcell by virtualcell.

the class XmlReader method getGeometry.

/**
 * This method returns a Geometry object from a XML representation.
 * Creation date: (4/26/2001 12:12:18 PM)
 * @return cbit.vcell.geometry.Geometry
 * @param param org.jdom.Element
 * @exception cbit.vcell.xml.XmlParseException The exception description.
 */
public Geometry getGeometry(Element param) throws XmlParseException {
    // Get the Extent object
    Extent newextent = getExtent(param.getChild(XMLTags.ExtentTag, vcNamespace));
    // Get VCimage information
    VCImage newimage = null;
    if (param.getChild(XMLTags.ImageTag, vcNamespace) != null) {
        try {
            newimage = getVCImage(param.getChild(XMLTags.ImageTag, vcNamespace), newextent);
        } catch (Throwable e) {
            e.printStackTrace();
            throw new XmlParseException(e);
        }
    }
    // Get attributes
    String name = unMangle(param.getAttributeValue(XMLTags.NameAttrTag));
    int newdimension = Integer.parseInt(param.getAttributeValue(XMLTags.DimensionAttrTag));
    // Get Version
    Version version = getVersion(param.getChild(XMLTags.VersionTag, vcNamespace));
    // Try to construct the geometry upon four different cases
    Geometry newgeometry = null;
    if (version != null && newimage != null) {
        newgeometry = new Geometry(version, newimage);
    } else if (version != null) {
        newgeometry = new Geometry(version, newdimension);
    } else if (newimage != null) {
        newgeometry = new Geometry(name, newimage);
    } else {
        newgeometry = new Geometry(name, newdimension);
    }
    // set attributes
    try {
        if (!newgeometry.getName().equalsIgnoreCase(name)) {
            newgeometry.setName(name);
        }
        // String annotation = param.getAttributeValue(XMLTags.AnnotationAttrTag);
        // if (annotation!=null) {
        // newgeometry.setDescription( unMangle(annotation) );
        // }
        // Add annotation
        String annotation = param.getChildText(XMLTags.AnnotationTag, vcNamespace);
        if (annotation != null && annotation.length() > 0) {
            newgeometry.setDescription(unMangle(annotation));
        }
    } catch (java.beans.PropertyVetoException e) {
        e.printStackTrace();
        throw new XmlParseException("A PropertyVetoException occurred when setting the name " + name + " to a Geometry object!", e);
    }
    // Add the Extent
    try {
        newgeometry.getGeometrySpec().setExtent(newextent);
    } catch (java.beans.PropertyVetoException e) {
        e.printStackTrace();
        throw new XmlParseException("A PropertyVetoException occurred while trying to set the Extent for the Geometry " + name, e);
    }
    // Add the Origin
    newgeometry.getGeometrySpec().setOrigin(getOrigin(param.getChild(XMLTags.OriginTag, vcNamespace)));
    // Add the SubVolumes
    List<Element> children = param.getChildren(XMLTags.SubVolumeTag, vcNamespace);
    SubVolume[] newsubvolumes = new SubVolume[children.size()];
    int subvolumeCounter = 0;
    for (Element child : children) {
        newsubvolumes[subvolumeCounter] = getSubVolume(child);
        subvolumeCounter++;
    }
    try {
        newgeometry.getGeometrySpec().setSubVolumes(newsubvolumes);
    } catch (java.beans.PropertyVetoException e) {
        e.printStackTrace();
        throw new XmlParseException("A PropertyVetoException was generated when ading the subvolumes to the Geometry " + name, e);
    }
    if (newgeometry.getDimension() > 0) {
        // Add SurfaceClasses
        List<Element> surfaceClassChildren = param.getChildren(XMLTags.SurfaceClassTag, vcNamespace);
        SurfaceClass[] newSurfaceClassArr = new SurfaceClass[surfaceClassChildren.size()];
        int surfClassCounter = 0;
        for (Element surfClassChild : surfaceClassChildren) {
            newSurfaceClassArr[surfClassCounter] = getSurfaceClass(surfClassChild, newgeometry);
            surfClassCounter++;
        }
        try {
            newgeometry.getGeometrySurfaceDescription().setSurfaceClasses(newSurfaceClassArr);
        } catch (java.beans.PropertyVetoException e) {
            e.printStackTrace();
            throw new XmlParseException("A PropertyVetoException was generated when ading the subvolumes to the Geometry " + name, e);
        }
    }
    // read Filaments (if any)
    Iterator<Element> iterator = param.getChildren(XMLTags.FilamentTag, vcNamespace).iterator();
    while (iterator.hasNext()) {
        Element tempElement = iterator.next();
        String filname = unMangle(tempElement.getAttributeValue(XMLTags.NameAttrTag));
        Iterator<Element> curveiterator = tempElement.getChildren().iterator();
        while (curveiterator.hasNext()) {
            ControlPointCurve curve = getControlPointCurve(curveiterator.next());
            newgeometry.getGeometrySpec().getFilamentGroup().addCurve(filname, curve);
        }
    }
    // read Surface description (if any)
    Element sd = param.getChild(XMLTags.SurfaceDescriptionTag, vcNamespace);
    if (sd != null) {
        GeometrySurfaceDescription dummy = getGeometrySurfaceDescription(sd, newgeometry);
    }
    try {
        newgeometry.precomputeAll(new GeometryThumbnailImageFactoryAWT(), false, false);
    } catch (GeometryException e) {
        e.printStackTrace(System.out);
    } catch (ImageException e) {
        e.printStackTrace(System.out);
    } catch (ExpressionException e) {
        e.printStackTrace(System.out);
    }
    return newgeometry;
}
Also used : ImageException(cbit.image.ImageException) GeometrySurfaceDescription(cbit.vcell.geometry.surface.GeometrySurfaceDescription) Extent(org.vcell.util.Extent) SurfaceClass(cbit.vcell.geometry.SurfaceClass) GeometryException(cbit.vcell.geometry.GeometryException) Element(org.jdom.Element) VCImage(cbit.image.VCImage) ControlPointCurve(cbit.vcell.geometry.ControlPointCurve) ExpressionException(cbit.vcell.parser.ExpressionException) Geometry(cbit.vcell.geometry.Geometry) PropertyVetoException(java.beans.PropertyVetoException) GeometryThumbnailImageFactoryAWT(cbit.vcell.geometry.GeometryThumbnailImageFactoryAWT) Version(org.vcell.util.document.Version) RedistributionVersion(cbit.vcell.solvers.mb.MovingBoundarySolverOptions.RedistributionVersion) SimulationVersion(org.vcell.util.document.SimulationVersion) VCellSoftwareVersion(org.vcell.util.document.VCellSoftwareVersion) SubVolume(cbit.vcell.geometry.SubVolume) CompartmentSubVolume(cbit.vcell.geometry.CompartmentSubVolume) AnalyticSubVolume(cbit.vcell.geometry.AnalyticSubVolume) ImageSubVolume(cbit.vcell.geometry.ImageSubVolume)

Example 9 with SubVolume

use of cbit.vcell.geometry.SubVolume in project vcell by virtualcell.

the class StochMathMapping method refreshMathDescription.

/**
 * set up a math description based on current simulationContext.
 */
@Override
protected void refreshMathDescription() throws MappingException, MatrixException, MathException, ExpressionException, ModelException {
    // use local variable instead of using getter all the time.
    SimulationContext simContext = getSimulationContext();
    GeometryClass geometryClass = simContext.getGeometry().getGeometrySpec().getSubVolumes()[0];
    Domain domain = new Domain(geometryClass);
    // local structure mapping list
    StructureMapping[] structureMappings = simContext.getGeometryContext().getStructureMappings();
    // We have to check if all the reactions are able to tranform to stochastic jump processes before generating the math.
    String stochChkMsg = simContext.getModel().isValidForStochApp();
    if (!(stochChkMsg.equals(""))) {
        throw new ModelException("Problem updating math description: " + simContext.getName() + "\n" + stochChkMsg);
    }
    simContext.checkValidity();
    // 
    if (simContext.getGeometry().getDimension() > 0) {
        throw new MappingException("nonspatial stochastic math mapping requires 0-dimensional geometry");
    }
    // 
    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 = simContext.getBioEvents();
    if (bioEvents != null && bioEvents.length > 0) {
        throw new MappingException("events not yet supported for particle-based models");
    }
    // 
    // verify that all structures are mapped to subvolumes and all subvolumes are mapped to a structure
    // 
    Structure[] structures = simContext.getGeometryContext().getModel().getStructures();
    for (int i = 0; i < structures.length; i++) {
        StructureMapping sm = simContext.getGeometryContext().getStructureMapping(structures[i]);
        if (sm == null || (sm instanceof FeatureMapping && ((FeatureMapping) sm).getGeometryClass() == null)) {
            throw new MappingException("model structure '" + structures[i].getName() + "' not mapped to a geometry subVolume");
        }
        if (sm != null && (sm instanceof MembraneMapping) && ((MembraneMapping) sm).getVolumeFractionParameter() != null) {
            Expression volFractExp = ((MembraneMapping) sm).getVolumeFractionParameter().getExpression();
            try {
                if (volFractExp != null) {
                    double volFract = volFractExp.evaluateConstant();
                    if (volFract >= 1.0) {
                        throw new MappingException("model structure '" + (getSimulationContext().getModel().getStructureTopology().getInsideFeature(((MembraneMapping) sm).getMembrane()).getName() + "' has volume fraction >= 1.0"));
                    }
                }
            } catch (ExpressionException e) {
                e.printStackTrace(System.out);
            }
        }
    }
    SubVolume[] subVolumes = simContext.getGeometryContext().getGeometry().getGeometrySpec().getSubVolumes();
    for (int i = 0; i < subVolumes.length; i++) {
        Structure[] mappedStructures = simContext.getGeometryContext().getStructuresFromGeometryClass(subVolumes[i]);
        if (mappedStructures == null || mappedStructures.length == 0) {
            throw new MappingException("geometry subVolume '" + subVolumes[i].getName() + "' not mapped from a model structure");
        }
    }
    // 
    // gather only those reactionSteps that are not "excluded"
    // 
    ReactionSpec[] reactionSpecs = simContext.getReactionContext().getReactionSpecs();
    Vector<ReactionStep> rsList = new Vector<ReactionStep>();
    for (int i = 0; i < reactionSpecs.length; i++) {
        if (!reactionSpecs[i].isExcluded()) {
            rsList.add(reactionSpecs[i].getReactionStep());
        }
    }
    // 
    for (ReactionStep reactionStep : rsList) {
        Kinetics.UnresolvedParameter[] unresolvedParameters = reactionStep.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("In Application '" + simContext.getName() + "', " + reactionStep.getDisplayType() + " '" + reactionStep.getName() + "' contains unresolved identifier(s): " + buffer);
        }
    }
    // 
    // create new MathDescription (based on simContext's previous MathDescription if possible)
    // 
    MathDescription oldMathDesc = simContext.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(simContext.getName() + "_generated");
    }
    // 
    // temporarily place all variables in a hashtable (before binding) and discarding duplicates
    // 
    VariableHash varHash = new VariableHash();
    // 
    // conversion factors
    // 
    Model model = simContext.getModel();
    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.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(simContext.getTemperatureKelvin()), model.getTEMPERATURE().getUnitDefinition(), null)));
    Enumeration<SpeciesContextMapping> enum1 = getSpeciesContextMappings();
    while (enum1.hasMoreElements()) {
        SpeciesContextMapping scm = enum1.nextElement();
        if (scm.getVariable() instanceof StochVolVariable) {
            varHash.addVariable(scm.getVariable());
        }
    }
    // deals with model parameters
    ModelParameter[] modelParameters = simContext.getModel().getModelParameters();
    for (int j = 0; j < modelParameters.length; j++) {
        Expression expr = getSubstitutedExpr(modelParameters[j].getExpression(), true, false);
        expr = getIdentifierSubstitutions(expr, modelParameters[j].getUnitDefinition(), geometryClass);
        varHash.addVariable(newFunctionOrConstant(getMathSymbol(modelParameters[j], geometryClass), expr, geometryClass));
    }
    // added July 2009, ElectricalStimulusParameter electric mapping tab
    ElectricalStimulus[] elecStimulus = simContext.getElectricalStimuli();
    if (elecStimulus.length > 0) {
        throw new MappingException("Modles with electrophysiology are not supported for stochastic applications.");
    }
    for (int j = 0; j < structureMappings.length; j++) {
        if (structureMappings[j] instanceof MembraneMapping) {
            MembraneMapping memMapping = (MembraneMapping) structureMappings[j];
            Parameter initialVoltageParm = memMapping.getInitialVoltageParameter();
            try {
                Expression exp = initialVoltageParm.getExpression();
                exp.evaluateConstant();
                varHash.addVariable(newFunctionOrConstant(getMathSymbol(memMapping.getMembrane().getMembraneVoltage(), memMapping.getGeometryClass()), getIdentifierSubstitutions(memMapping.getInitialVoltageParameter().getExpression(), memMapping.getInitialVoltageParameter().getUnitDefinition(), memMapping.getGeometryClass()), memMapping.getGeometryClass()));
            } catch (ExpressionException e) {
                e.printStackTrace(System.out);
                throw new MappingException("Membrane initial voltage: " + initialVoltageParm.getName() + " cannot be evaluated as constant.");
            }
        }
    }
    // 
    for (ReactionStep rs : rsList) {
        if (rs.getKinetics() instanceof LumpedKinetics) {
            throw new RuntimeException("Lumped Kinetics not yet supported for Stochastic Math Generation");
        }
        Kinetics.KineticsParameter[] parameters = rs.getKinetics().getKineticsParameters();
        for (KineticsParameter parameter : parameters) {
            // 
            if ((parameter.getRole() == Kinetics.ROLE_CurrentDensity) && (parameter.getExpression() == null || parameter.getExpression().isZero())) {
                continue;
            }
            // 
            // don't add rate, we'll do it later when creating the jump processes
            // 
            // if (parameter.getRole() == Kinetics.ROLE_ReactionRate) {
            // continue;
            // }
            // 
            // don't add mass action reverse parameter if irreversible
            // 
            // if (!rs.isReversible() && parameters[i].getRole() == Kinetics.ROLE_KReverse){
            // continue;
            // }
            Expression expr = getSubstitutedExpr(parameter.getExpression(), true, false);
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(parameter, geometryClass), getIdentifierSubstitutions(expr, parameter.getUnitDefinition(), geometryClass), geometryClass));
        }
    }
    // the parameter "Size" is already put into mathsymbolmapping in refreshSpeciesContextMapping()
    for (int i = 0; i < structureMappings.length; i++) {
        StructureMapping sm = structureMappings[i];
        StructureMapping.StructureMappingParameter parm = sm.getParameterFromRole(StructureMapping.ROLE_Size);
        if (parm.getExpression() != null) {
            try {
                double value = parm.getExpression().evaluateConstant();
                varHash.addVariable(new Constant(getMathSymbol(parm, sm.getGeometryClass()), new Expression(value)));
            } catch (ExpressionException e) {
                // varHash.addVariable(new Function(getMathSymbol0(parm,sm),getIdentifierSubstitutions(parm.getExpression(),parm.getUnitDefinition(),sm)));
                e.printStackTrace(System.out);
                throw new MappingException("Size of structure:" + sm.getNameScope().getName() + " cannot be evaluated as constant.");
            }
        }
    }
    SpeciesContextSpec[] speciesContextSpecs = getSimulationContext().getReactionContext().getSpeciesContextSpecs();
    addInitialConditions(domain, speciesContextSpecs, varHash);
    // 
    // 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());
        }
    }
    // 
    if (simContext.getGeometryContext().getGeometry() != null) {
        try {
            mathDesc.setGeometry(simContext.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 in Application " + simContext.getName());
    }
    // 
    // create subDomains
    // 
    SubVolume subVolume = simContext.getGeometry().getGeometrySpec().getSubVolumes()[0];
    SubDomain subDomain = new CompartmentSubDomain(subVolume.getName(), 0);
    mathDesc.addSubDomain(subDomain);
    // 
    // functions: species which is not a variable, but has dependency expression
    // 
    enum1 = getSpeciesContextMappings();
    while (enum1.hasMoreElements()) {
        SpeciesContextMapping scm = (SpeciesContextMapping) enum1.nextElement();
        if (scm.getVariable() == null && scm.getDependencyExpression() != null) {
            StructureMapping sm = simContext.getGeometryContext().getStructureMapping(scm.getSpeciesContext().getStructure());
            Expression exp = scm.getDependencyExpression();
            exp.bindExpression(this);
            SpeciesCountParameter spCountParam = getSpeciesCountParameter(scm.getSpeciesContext());
            varHash.addVariable(new Function(getMathSymbol(spCountParam, sm.getGeometryClass()), getIdentifierSubstitutions(exp, spCountParam.getUnitDefinition(), sm.getGeometryClass()), domain));
        }
    }
    addJumpProcesses(varHash, geometryClass, subDomain);
    // 
    for (int i = 0; i < fieldMathMappingParameters.length; i++) {
        if (fieldMathMappingParameters[i] instanceof UnitFactorParameter) {
            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());
    // 
    // set up variable initial conditions in subDomain
    // 
    SpeciesContextSpec[] scSpecs = simContext.getReactionContext().getSpeciesContextSpecs();
    for (int i = 0; i < speciesContextSpecs.length; i++) {
        // get stochastic variable by name
        SpeciesCountParameter spCountParam = getSpeciesCountParameter(speciesContextSpecs[i].getSpeciesContext());
        StructureMapping sm = simContext.getGeometryContext().getStructureMapping(speciesContextSpecs[i].getSpeciesContext().getStructure());
        String varName = getMathSymbol(spCountParam, sm.getGeometryClass());
        StochVolVariable var = (StochVolVariable) mathDesc.getVariable(varName);
        // stochastic use initial number of particles
        SpeciesContextSpec.SpeciesContextSpecParameter initParm = scSpecs[i].getInitialCountParameter();
        // stochastic variables initial expression.
        if (initParm != null) {
            VarIniCondition varIni = null;
            if (!scSpecs[i].isConstant() && getSimulationContext().isRandomizeInitCondition()) {
                varIni = new VarIniPoissonExpectedCount(var, new Expression(getMathSymbol(initParm, sm.getGeometryClass())));
            } else {
                varIni = new VarIniCount(var, new Expression(getMathSymbol(initParm, sm.getGeometryClass())));
            }
            subDomain.addVarIniCondition(varIni);
        }
    }
    // 
    for (int i = 0; i < fieldMathMappingParameters.length; i++) {
        if (fieldMathMappingParameters[i] instanceof UnitFactorParameter) {
            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 (fieldMathMappingParameters[i] instanceof ObservableCountParameter) {
            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()) {
        System.out.println(mathDesc.getVCML_database());
        throw new MappingException("generated an invalid mathDescription: " + mathDesc.getWarning());
    }
}
Also used : VarIniCondition(cbit.vcell.math.VarIniCondition) LumpedKinetics(cbit.vcell.model.LumpedKinetics) MathDescription(cbit.vcell.math.MathDescription) ExpressionException(cbit.vcell.parser.ExpressionException) PropertyVetoException(java.beans.PropertyVetoException) CompartmentSubDomain(cbit.vcell.math.CompartmentSubDomain) SubDomain(cbit.vcell.math.SubDomain) KineticsParameter(cbit.vcell.model.Kinetics.KineticsParameter) SubVolume(cbit.vcell.geometry.SubVolume) Vector(java.util.Vector) ModelException(cbit.vcell.model.ModelException) ModelParameter(cbit.vcell.model.Model.ModelParameter) CompartmentSubDomain(cbit.vcell.math.CompartmentSubDomain) ReactionStep(cbit.vcell.model.ReactionStep) CompartmentSubDomain(cbit.vcell.math.CompartmentSubDomain) SubDomain(cbit.vcell.math.SubDomain) Domain(cbit.vcell.math.Variable.Domain) GeometryClass(cbit.vcell.geometry.GeometryClass) StochVolVariable(cbit.vcell.math.StochVolVariable) Variable(cbit.vcell.math.Variable) VariableHash(cbit.vcell.math.VariableHash) Constant(cbit.vcell.math.Constant) VarIniPoissonExpectedCount(cbit.vcell.math.VarIniPoissonExpectedCount) Function(cbit.vcell.math.Function) Structure(cbit.vcell.model.Structure) StochVolVariable(cbit.vcell.math.StochVolVariable) VarIniCount(cbit.vcell.math.VarIniCount) Expression(cbit.vcell.parser.Expression) Model(cbit.vcell.model.Model) Parameter(cbit.vcell.model.Parameter) KineticsParameter(cbit.vcell.model.Kinetics.KineticsParameter) ModelParameter(cbit.vcell.model.Model.ModelParameter)

Example 10 with SubVolume

use of cbit.vcell.geometry.SubVolume in project vcell by virtualcell.

the class MathMapping_4_8 method refreshMathDescription.

/**
 * This method was created in VisualAge.
 */
private void refreshMathDescription() throws MappingException, MatrixException, MathException, ExpressionException, ModelException {
    // All sizes must be set for new ODE models and ratios must be set for old ones.
    simContext.checkValidity();
    // 
    // temporarily place all variables in a hashtable (before binding) and discarding duplicates (check for equality)
    // 
    VariableHash varHash = new VariableHash();
    StructureMapping[] structureMappings = simContext.getGeometryContext().getStructureMappings();
    Model model = simContext.getModel();
    StructureTopology structTopology = model.getStructureTopology();
    // 
    // verify that all structures are mapped to subvolumes and all subvolumes are mapped to a structure
    // 
    Structure[] structures = simContext.getGeometryContext().getModel().getStructures();
    for (int i = 0; i < structures.length; i++) {
        StructureMapping sm = simContext.getGeometryContext().getStructureMapping(structures[i]);
        if (sm == null || (sm instanceof FeatureMapping && getSubVolume((FeatureMapping) sm) == null)) {
            throw new MappingException("model structure '" + structures[i].getName() + "' not mapped to a geometry subdomain");
        }
        if (sm != null && (sm instanceof MembraneMapping) && ((MembraneMapping) sm).getVolumeFractionParameter() != null) {
            Expression volFractExp = ((MembraneMapping) sm).getVolumeFractionParameter().getExpression();
            if (volFractExp != null) {
                try {
                    double volFract = volFractExp.evaluateConstant();
                    if (volFract >= 1.0) {
                        throw new MappingException("model structure '" + structTopology.getInsideFeature(((MembraneMapping) sm).getMembrane()).getName() + "' has volume fraction >= 1.0");
                    }
                } catch (ExpressionException e) {
                }
            }
        }
    }
    SubVolume[] subVolumes = simContext.getGeometryContext().getGeometry().getGeometrySpec().getSubVolumes();
    for (int i = 0; i < subVolumes.length; i++) {
        if (getStructures(subVolumes[i]) == null || getStructures(subVolumes[i]).length == 0) {
            throw new MappingException("geometry subdomain '" + subVolumes[i].getName() + "' not mapped from a model structure");
        }
    }
    // deals with model parameters
    Hashtable<VolVariable, EventAssignmentInitParameter> eventVolVarHash = new Hashtable<VolVariable, EventAssignmentInitParameter>();
    ModelParameter[] modelParameters = model.getModelParameters();
    if (simContext.getGeometry().getDimension() == 0) {
        // 
        // global parameters from model (that presently are constants)
        // 
        BioEvent[] bioEvents = simContext.getBioEvents();
        ArrayList<SymbolTableEntry> eventAssignTargets = new ArrayList<SymbolTableEntry>();
        if (bioEvents != null && bioEvents.length > 0) {
            for (BioEvent be : bioEvents) {
                for (EventAssignment ea : be.getEventAssignments()) {
                    if (!eventAssignTargets.contains(ea.getTarget())) {
                        eventAssignTargets.add(ea.getTarget());
                    }
                }
            }
        }
        for (int j = 0; j < modelParameters.length; j++) {
            Expression modelParamExpr = getIdentifierSubstitutions(modelParameters[j].getExpression(), modelParameters[j].getUnitDefinition(), null);
            if (eventAssignTargets.contains(modelParameters[j])) {
                EventAssignmentInitParameter eap = null;
                try {
                    eap = addEventAssignmentInitParameter(modelParameters[j].getName(), modelParameters[j].getExpression(), PARAMETER_ROLE_EVENTASSIGN_INITCONDN, modelParameters[j].getUnitDefinition());
                } catch (PropertyVetoException e) {
                    e.printStackTrace(System.out);
                    throw new MappingException(e.getMessage());
                }
                // varHash.addVariable(newFunctionOrConstant(getMathSymbol(eap, null), modelParamExpr));
                VolVariable volVar = new VolVariable(modelParameters[j].getName(), nullDomain);
                varHash.addVariable(volVar);
                eventVolVarHash.put(volVar, eap);
            } else {
                varHash.addVariable(newFunctionOrConstant(getMathSymbol(modelParameters[j], null), modelParamExpr));
            }
        }
    } else {
        // 
        for (int pass = 0; pass < 2; pass++) {
            for (int j = 0; j < modelParameters.length; j++) {
                Hashtable<String, Expression> structMappingVariantsHash = new Hashtable<String, Expression>();
                for (int k = 0; k < structureMappings.length; k++) {
                    String paramVariantName = null;
                    Expression paramVariantExpr = null;
                    if (modelParameters[j].getExpression().getSymbols() == null) {
                        paramVariantName = modelParameters[j].getName();
                        paramVariantExpr = getIdentifierSubstitutions(modelParameters[j].getExpression(), modelParameters[j].getUnitDefinition(), null);
                    } else {
                        paramVariantName = modelParameters[j].getName() + "_" + TokenMangler.fixTokenStrict(structureMappings[k].getStructure().getName());
                        // if the expression has symbols that do not belong in that structureMapping, do not create the variant.
                        Expression exp1 = modelParameters[j].getExpression();
                        Expression flattenedModelParamExpr = substituteGlobalParameters(exp1);
                        String[] symbols = flattenedModelParamExpr.getSymbols();
                        boolean bValid = true;
                        Structure sm_struct = structureMappings[k].getStructure();
                        if (symbols != null) {
                            for (int ii = 0; ii < symbols.length; ii++) {
                                SpeciesContext sc = model.getSpeciesContext(symbols[ii]);
                                if (sc != null) {
                                    // symbol[ii] is a speciesContext, check its structure with structureMapping[k].structure. If they are the same or
                                    // if it is the adjacent membrane(s), allow variant expression to be created. Else, continue.
                                    Structure sp_struct = sc.getStructure();
                                    if (sp_struct.compareEqual(sm_struct)) {
                                        bValid = bValid && true;
                                    } else {
                                        // if the 2 structures are not the same, are they adjacent? then 'bValid' is true, else false.
                                        if ((sm_struct instanceof Feature) && (sp_struct instanceof Membrane)) {
                                            Feature sm_feature = (Feature) sm_struct;
                                            Membrane sp_mem = (Membrane) sp_struct;
                                            if (sp_mem.compareEqual(structTopology.getParentStructure(sm_feature)) || (structTopology.getInsideFeature(sp_mem).compareEqual(sm_feature) || structTopology.getOutsideFeature(sp_mem).compareEqual(sm_feature))) {
                                                bValid = bValid && true;
                                            } else {
                                                bValid = bValid && false;
                                                break;
                                            }
                                        } else if ((sm_struct instanceof Membrane) && (sp_struct instanceof Feature)) {
                                            Feature sp_feature = (Feature) sp_struct;
                                            Membrane sm_mem = (Membrane) sm_struct;
                                            if (sm_mem.compareEqual(structTopology.getParentStructure(sp_feature)) || (structTopology.getInsideFeature(sm_mem).compareEqual(sp_feature) || structTopology.getOutsideFeature(sm_mem).compareEqual(sp_feature))) {
                                                bValid = bValid && true;
                                            } else {
                                                bValid = bValid && false;
                                                break;
                                            }
                                        } else {
                                            bValid = bValid && false;
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                        if (bValid) {
                            if (pass == 0) {
                                paramVariantExpr = new Expression("VCELL_TEMPORARY_EXPRESSION_PLACEHOLDER");
                            } else {
                                paramVariantExpr = getIdentifierSubstitutions(modelParameters[j].getExpression(), modelParameters[j].getUnitDefinition(), structureMappings[k]);
                            }
                        }
                    }
                    if (paramVariantExpr != null) {
                        structMappingVariantsHash.put(paramVariantName, paramVariantExpr);
                    }
                }
                globalParamVariantsHash.put(modelParameters[j], structMappingVariantsHash);
            }
        }
        // 
        for (int j = 0; j < modelParameters.length; j++) {
            if (modelParameters[j].getExpression().getSymbols() == null) {
                varHash.addVariable(newFunctionOrConstant(getMathSymbol(modelParameters[j], null), getIdentifierSubstitutions(modelParameters[j].getExpression(), modelParameters[j].getUnitDefinition(), null)));
            } else {
                Hashtable<String, Expression> smVariantsHash = globalParamVariantsHash.get(modelParameters[j]);
                for (int k = 0; k < structureMappings.length; k++) {
                    String variantName = modelParameters[j].getName() + "_" + TokenMangler.fixTokenStrict(structureMappings[k].getStructure().getName());
                    Expression variantExpr = smVariantsHash.get(variantName);
                    if (variantExpr != null) {
                        varHash.addVariable(newFunctionOrConstant(variantName, variantExpr));
                    }
                }
            }
        }
    }
    // 
    // gather only those reactionSteps that are not "excluded"
    // 
    ReactionSpec[] reactionSpecs = simContext.getReactionContext().getReactionSpecs();
    Vector<ReactionStep> rsList = new Vector<ReactionStep>();
    for (int i = 0; i < reactionSpecs.length; i++) {
        if (reactionSpecs[i].isExcluded() == false) {
            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);
        }
    }
    // 
    // create new MathDescription (based on simContext's previous MathDescription if possible)
    // 
    MathDescription oldMathDesc = simContext.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(simContext.getName() + "_generated");
    }
    // 
    // volume variables
    // 
    Enumeration<SpeciesContextMapping> enum1 = getSpeciesContextMappings();
    while (enum1.hasMoreElements()) {
        SpeciesContextMapping scm = enum1.nextElement();
        if (scm.getVariable() instanceof VolVariable) {
            if (!(mathDesc.getVariable(scm.getVariable().getName()) instanceof VolVariable)) {
                varHash.addVariable(scm.getVariable());
            }
        }
    }
    // 
    // membrane variables
    // 
    enum1 = getSpeciesContextMappings();
    while (enum1.hasMoreElements()) {
        SpeciesContextMapping scm = (SpeciesContextMapping) enum1.nextElement();
        if (scm.getVariable() instanceof MemVariable) {
            varHash.addVariable(scm.getVariable());
        }
    }
    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(simContext.getTemperatureKelvin()), model.getTEMPERATURE().getUnitDefinition(), null)));
    // 
    // only calculate potential if at least one MembraneMapping has CalculateVoltage == true
    // 
    boolean bCalculatePotential = false;
    for (int i = 0; i < structureMappings.length; i++) {
        if (structureMappings[i] instanceof MembraneMapping) {
            if (((MembraneMapping) structureMappings[i]).getCalculateVoltage()) {
                bCalculatePotential = true;
            }
        }
    }
    // (simContext.getGeometry().getDimension() == 0);
    potentialMapping = new PotentialMapping(simContext, this);
    potentialMapping.computeMath();
    if (bCalculatePotential) {
        // 
        // copy functions for currents and constants for capacitances
        // 
        ElectricalDevice[] devices = potentialMapping.getElectricalDevices();
        for (int j = 0; j < devices.length; j++) {
            if (devices[j] instanceof MembraneElectricalDevice) {
                MembraneElectricalDevice membraneElectricalDevice = (MembraneElectricalDevice) devices[j];
                MembraneMapping memMapping = membraneElectricalDevice.getMembraneMapping();
                Parameter specificCapacitanceParm = memMapping.getParameterFromRole(MembraneMapping.ROLE_SpecificCapacitance);
                varHash.addVariable(new Constant(getMathSymbol(specificCapacitanceParm, memMapping), getIdentifierSubstitutions(specificCapacitanceParm.getExpression(), specificCapacitanceParm.getUnitDefinition(), memMapping)));
                ElectricalDevice.ElectricalDeviceParameter transmembraneCurrentParm = membraneElectricalDevice.getParameterFromRole(ElectricalDevice.ROLE_TransmembraneCurrent);
                ElectricalDevice.ElectricalDeviceParameter totalCurrentParm = membraneElectricalDevice.getParameterFromRole(ElectricalDevice.ROLE_TotalCurrent);
                ElectricalDevice.ElectricalDeviceParameter capacitanceParm = membraneElectricalDevice.getParameterFromRole(ElectricalDevice.ROLE_Capacitance);
                if (totalCurrentParm != null && /* totalCurrentDensityParm.getExpression()!=null && */
                memMapping.getCalculateVoltage()) {
                    Expression totalCurrentDensityExp = (totalCurrentParm.getExpression() != null) ? (totalCurrentParm.getExpression()) : (new Expression(0.0));
                    varHash.addVariable(newFunctionOrConstant(getMathSymbol(totalCurrentParm, membraneElectricalDevice.getMembraneMapping()), getIdentifierSubstitutions(totalCurrentDensityExp, totalCurrentParm.getUnitDefinition(), membraneElectricalDevice.getMembraneMapping())));
                }
                if (transmembraneCurrentParm != null && transmembraneCurrentParm.getExpression() != null && memMapping.getCalculateVoltage()) {
                    varHash.addVariable(newFunctionOrConstant(getMathSymbol(transmembraneCurrentParm, membraneElectricalDevice.getMembraneMapping()), getIdentifierSubstitutions(transmembraneCurrentParm.getExpression(), transmembraneCurrentParm.getUnitDefinition(), membraneElectricalDevice.getMembraneMapping())));
                }
                if (capacitanceParm != null && capacitanceParm.getExpression() != null && memMapping.getCalculateVoltage()) {
                    StructureMappingParameter sizeParameter = membraneElectricalDevice.getMembraneMapping().getSizeParameter();
                    if (simContext.getGeometry().getDimension() == 0 && (sizeParameter.getExpression() == null || sizeParameter.getExpression().isZero())) {
                        varHash.addVariable(newFunctionOrConstant(getMathSymbol(capacitanceParm, membraneElectricalDevice.getMembraneMapping()), getIdentifierSubstitutions(Expression.mult(memMapping.getNullSizeParameterValue(), specificCapacitanceParm.getExpression()), capacitanceParm.getUnitDefinition(), membraneElectricalDevice.getMembraneMapping())));
                    } else {
                        varHash.addVariable(newFunctionOrConstant(getMathSymbol(capacitanceParm, membraneElectricalDevice.getMembraneMapping()), getIdentifierSubstitutions(capacitanceParm.getExpression(), capacitanceParm.getUnitDefinition(), membraneElectricalDevice.getMembraneMapping())));
                    }
                }
                // 
                if (membraneElectricalDevice.getDependentVoltageExpression() == null) {
                    // is Voltage Independent?
                    StructureMapping.StructureMappingParameter initialVoltageParm = memMapping.getInitialVoltageParameter();
                    varHash.addVariable(newFunctionOrConstant(getMathSymbol(initialVoltageParm, memMapping), getIdentifierSubstitutions(initialVoltageParm.getExpression(), initialVoltageParm.getUnitDefinition(), memMapping)));
                } else // 
                // membrane forced potential
                // 
                {
                    varHash.addVariable(newFunctionOrConstant(getMathSymbol(memMapping.getMembrane().getMembraneVoltage(), memMapping), getIdentifierSubstitutions(membraneElectricalDevice.getDependentVoltageExpression(), memMapping.getMembrane().getMembraneVoltage().getUnitDefinition(), memMapping)));
                }
            } else if (devices[j] instanceof CurrentClampElectricalDevice) {
                CurrentClampElectricalDevice currentClampDevice = (CurrentClampElectricalDevice) devices[j];
                // total current = current source (no capacitance)
                Parameter totalCurrentParm = currentClampDevice.getParameterFromRole(CurrentClampElectricalDevice.ROLE_TotalCurrent);
                Parameter currentParm = currentClampDevice.getParameterFromRole(CurrentClampElectricalDevice.ROLE_TransmembraneCurrent);
                // Parameter dependentVoltage = currentClampDevice.getCurrentClampStimulus().getVoltageParameter();
                varHash.addVariable(newFunctionOrConstant(getMathSymbol(totalCurrentParm, null), getIdentifierSubstitutions(totalCurrentParm.getExpression(), totalCurrentParm.getUnitDefinition(), null)));
                varHash.addVariable(newFunctionOrConstant(getMathSymbol(currentParm, null), getIdentifierSubstitutions(currentParm.getExpression(), currentParm.getUnitDefinition(), null)));
                // varHash.addVariable(newFunctionOrConstant(getMathSymbol(dependentVoltage,null),getIdentifierSubstitutions(currentClampDevice.getDependentVoltageExpression(),dependentVoltage.getUnitDefinition(),null)));
                // 
                // add user-defined parameters
                // 
                ElectricalDevice.ElectricalDeviceParameter[] parameters = currentClampDevice.getParameters();
                for (int k = 0; k < parameters.length; k++) {
                    if (parameters[k].getExpression() != null) {
                        // guards against voltage parameters that are "variable".
                        varHash.addVariable(newFunctionOrConstant(getMathSymbol(parameters[k], null), getIdentifierSubstitutions(parameters[k].getExpression(), parameters[k].getUnitDefinition(), null)));
                    }
                }
            } else if (devices[j] instanceof VoltageClampElectricalDevice) {
                VoltageClampElectricalDevice voltageClampDevice = (VoltageClampElectricalDevice) devices[j];
                // total current = current source (no capacitance)
                Parameter totalCurrent = voltageClampDevice.getParameterFromRole(VoltageClampElectricalDevice.ROLE_TotalCurrent);
                Parameter totalCurrentParm = voltageClampDevice.getParameterFromRole(VoltageClampElectricalDevice.ROLE_TotalCurrent);
                Parameter voltageParm = voltageClampDevice.getParameterFromRole(VoltageClampElectricalDevice.ROLE_Voltage);
                varHash.addVariable(newFunctionOrConstant(getMathSymbol(totalCurrent, null), getIdentifierSubstitutions(totalCurrent.getExpression(), totalCurrent.getUnitDefinition(), null)));
                varHash.addVariable(newFunctionOrConstant(getMathSymbol(totalCurrentParm, null), getIdentifierSubstitutions(totalCurrentParm.getExpression(), totalCurrentParm.getUnitDefinition(), null)));
                varHash.addVariable(newFunctionOrConstant(getMathSymbol(voltageParm, null), getIdentifierSubstitutions(voltageParm.getExpression(), voltageParm.getUnitDefinition(), null)));
                // 
                // add user-defined parameters
                // 
                ElectricalDevice.ElectricalDeviceParameter[] parameters = voltageClampDevice.getParameters();
                for (int k = 0; k < parameters.length; k++) {
                    if (parameters[k].getRole() == ElectricalDevice.ROLE_UserDefined) {
                        varHash.addVariable(newFunctionOrConstant(getMathSymbol(parameters[k], null), getIdentifierSubstitutions(parameters[k].getExpression(), parameters[k].getUnitDefinition(), null)));
                    }
                }
            }
        }
    } else {
        // 
        for (int j = 0; j < structureMappings.length; j++) {
            if (structureMappings[j] instanceof MembraneMapping) {
                MembraneMapping memMapping = (MembraneMapping) structureMappings[j];
                varHash.addVariable(newFunctionOrConstant(getMathSymbol(memMapping.getMembrane().getMembraneVoltage(), memMapping), getIdentifierSubstitutions(memMapping.getInitialVoltageParameter().getExpression(), memMapping.getInitialVoltageParameter().getUnitDefinition(), memMapping)));
            }
        }
    }
    // 
    for (int j = 0; j < structureMappings.length; j++) {
        if (structureMappings[j] instanceof MembraneMapping) {
            MembraneMapping membraneMapping = (MembraneMapping) structureMappings[j];
            Membrane.MembraneVoltage membraneVoltage = membraneMapping.getMembrane().getMembraneVoltage();
            ElectricalDevice[] membraneDevices = potentialMapping.getElectricalDevices(membraneMapping.getMembrane());
            // ElectricalDevice membraneDevice = null;
            for (int i = 0; i < membraneDevices.length; i++) {
                if (membraneDevices[i].hasCapacitance() && membraneDevices[i].getDependentVoltageExpression() == null) {
                    if (membraneMapping.getCalculateVoltage() && bCalculatePotential) {
                        if (getResolved(membraneMapping)) {
                            // 
                            if (mathDesc.getVariable(Membrane.MEMBRANE_VOLTAGE_REGION_NAME) == null) {
                                // varHash.addVariable(new MembraneRegionVariable(MembraneVoltage.MEMBRANE_VOLTAGE_REGION_NAME));
                                varHash.addVariable(new MembraneRegionVariable(getMathSymbol(membraneVoltage, membraneMapping), nullDomain));
                            }
                        } else {
                            // 
                            // spatially unresolved membrane, and must solve for potential ... make VolVariable for this compartment
                            // 
                            varHash.addVariable(new VolVariable(getMathSymbol(membraneVoltage, membraneMapping), nullDomain));
                        }
                        Parameter initialVoltageParm = membraneMapping.getInitialVoltageParameter();
                        Variable initVoltageFunction = newFunctionOrConstant(getMathSymbol(initialVoltageParm, membraneMapping), getIdentifierSubstitutions(initialVoltageParm.getExpression(), initialVoltageParm.getUnitDefinition(), membraneMapping));
                        varHash.addVariable(initVoltageFunction);
                    } else {
                        // 
                        // don't calculate voltage, still may need it though
                        // 
                        Parameter initialVoltageParm = membraneMapping.getInitialVoltageParameter();
                        Variable voltageFunction = newFunctionOrConstant(getMathSymbol(membraneMapping.getMembrane().getMembraneVoltage(), membraneMapping), getIdentifierSubstitutions(initialVoltageParm.getExpression(), initialVoltageParm.getUnitDefinition(), membraneMapping));
                        varHash.addVariable(voltageFunction);
                    }
                }
            }
        }
    }
    // 
    for (int j = 0; j < reactionSteps.length; j++) {
        ReactionStep rs = reactionSteps[j];
        if (simContext.getReactionContext().getReactionSpec(rs).isExcluded()) {
            continue;
        }
        Kinetics.KineticsParameter[] parameters = rs.getKinetics().getKineticsParameters();
        StructureMapping sm = simContext.getGeometryContext().getStructureMapping(rs.getStructure());
        if (parameters != null) {
            for (int i = 0; i < parameters.length; i++) {
                if (((parameters[i].getRole() == Kinetics.ROLE_CurrentDensity) || (parameters[i].getRole() == Kinetics.ROLE_LumpedCurrent)) && (parameters[i].getExpression() == null || parameters[i].getExpression().isZero())) {
                    continue;
                }
                varHash.addVariable(newFunctionOrConstant(getMathSymbol(parameters[i], sm), getIdentifierSubstitutions(parameters[i].getExpression(), parameters[i].getUnitDefinition(), sm)));
            }
        }
    }
    // 
    // initial constants (either function or constant)
    // 
    SpeciesContextSpec[] speciesContextSpecs = simContext.getReactionContext().getSpeciesContextSpecs();
    for (int i = 0; i < speciesContextSpecs.length; i++) {
        SpeciesContextSpecParameter initParm = speciesContextSpecs[i].getParameterFromRole(SpeciesContextSpec.ROLE_InitialConcentration);
        if (initParm != null) {
            Expression initExpr = new Expression(initParm.getExpression());
            StructureMapping sm = simContext.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 = simContext.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), getIdentifierSubstitutions(initExpr, initParm.getUnitDefinition(), sm)));
        }
    }
    // 
    for (int i = 0; i < speciesContextSpecs.length; i++) {
        SpeciesContextMapping scm = getSpeciesContextMapping(speciesContextSpecs[i].getSpeciesContext());
        SpeciesContextSpec.SpeciesContextSpecParameter diffParm = speciesContextSpecs[i].getParameterFromRole(SpeciesContextSpec.ROLE_DiffusionRate);
        if (diffParm != null && (scm.isPDERequired())) {
            StructureMapping sm = simContext.getGeometryContext().getStructureMapping(speciesContextSpecs[i].getSpeciesContext().getStructure());
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(diffParm, sm), getIdentifierSubstitutions(diffParm.getExpression(), diffParm.getUnitDefinition(), sm)));
        }
    }
    // 
    for (int i = 0; i < speciesContextSpecs.length; i++) {
        SpeciesContextSpec.SpeciesContextSpecParameter bc_xm = speciesContextSpecs[i].getParameterFromRole(SpeciesContextSpec.ROLE_BoundaryValueXm);
        StructureMapping sm = simContext.getGeometryContext().getStructureMapping(speciesContextSpecs[i].getSpeciesContext().getStructure());
        if (bc_xm != null && (bc_xm.getExpression() != null)) {
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(bc_xm, sm), getIdentifierSubstitutions(bc_xm.getExpression(), bc_xm.getUnitDefinition(), sm)));
        }
        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), getIdentifierSubstitutions(bc_xp.getExpression(), bc_xp.getUnitDefinition(), sm)));
        }
        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), getIdentifierSubstitutions(bc_ym.getExpression(), bc_ym.getUnitDefinition(), sm)));
        }
        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), getIdentifierSubstitutions(bc_yp.getExpression(), bc_yp.getUnitDefinition(), sm)));
        }
        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), getIdentifierSubstitutions(bc_zm.getExpression(), bc_zm.getUnitDefinition(), sm)));
        }
        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), getIdentifierSubstitutions(bc_zp.getExpression(), bc_zp.getUnitDefinition(), sm)));
        }
    }
    // 
    for (int i = 0; i < speciesContextSpecs.length; i++) {
        SpeciesContextSpec.SpeciesContextSpecParameter advection_velX = speciesContextSpecs[i].getParameterFromRole(SpeciesContextSpec.ROLE_VelocityX);
        StructureMapping sm = simContext.getGeometryContext().getStructureMapping(speciesContextSpecs[i].getSpeciesContext().getStructure());
        if (advection_velX != null && (advection_velX.getExpression() != null)) {
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(advection_velX, sm), getIdentifierSubstitutions(advection_velX.getExpression(), advection_velX.getUnitDefinition(), sm)));
        }
        SpeciesContextSpec.SpeciesContextSpecParameter advection_velY = speciesContextSpecs[i].getParameterFromRole(SpeciesContextSpec.ROLE_VelocityY);
        if (advection_velY != null && (advection_velY.getExpression() != null)) {
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(advection_velY, sm), getIdentifierSubstitutions(advection_velY.getExpression(), advection_velY.getUnitDefinition(), sm)));
        }
        SpeciesContextSpec.SpeciesContextSpecParameter advection_velZ = speciesContextSpecs[i].getParameterFromRole(SpeciesContextSpec.ROLE_VelocityZ);
        if (advection_velZ != null && (advection_velZ.getExpression() != null)) {
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(advection_velZ, sm), getIdentifierSubstitutions(advection_velZ.getExpression(), advection_velZ.getUnitDefinition(), sm)));
        }
    }
    // 
    // 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(model.getN_PMOLE().getName(), getIdentifierSubstitutions(model.getN_PMOLE().getExpression(), model.getN_PMOLE().getUnitDefinition(), null)));
    varHash.addVariable(new Constant(model.getKMILLIVOLTS().getName(), getIdentifierSubstitutions(model.getKMILLIVOLTS().getExpression(), model.getKMILLIVOLTS().getUnitDefinition(), null)));
    varHash.addVariable(new Constant(model.getK_GHK().getName(), getIdentifierSubstitutions(model.getK_GHK().getExpression(), model.getK_GHK().getUnitDefinition(), null)));
    // 
    // geometric functions
    // 
    ModelUnitSystem modelUnitSystem = simContext.getModel().getUnitSystem();
    VCUnitDefinition lengthInverseUnit = modelUnitSystem.getLengthUnit().getInverse();
    for (int i = 0; i < structureMappings.length; i++) {
        StructureMapping sm = structureMappings[i];
        Parameter parm = sm.getParameterFromRole(StructureMapping.ROLE_VolumeFraction);
        if (parm != null && parm.getExpression() != null && sm.getGeometryClass() instanceof SubVolume) {
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(parm, sm), getIdentifierSubstitutions(parm.getExpression(), parm.getUnitDefinition(), sm)));
        }
        parm = sm.getParameterFromRole(StructureMapping.ROLE_SurfaceToVolumeRatio);
        if (parm != null && parm.getExpression() != null && sm.getGeometryClass() instanceof SubVolume) {
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(parm, sm), getIdentifierSubstitutions(parm.getExpression(), parm.getUnitDefinition(), sm)));
        }
        if (sm instanceof MembraneMapping && !getResolved(sm)) {
            MembraneMapping mm = (MembraneMapping) sm;
            parm = ((MembraneMapping) sm).getVolumeFractionParameter();
            if (parm.getExpression() == null) {
                throw new MappingException("volume fraction not specified for feature '" + structTopology.getInsideFeature(mm.getMembrane()).getName() + "', please refer to Structure Mapping in Application '" + simContext.getName() + "'");
            }
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(parm, sm), getIdentifierSubstitutions(parm.getExpression(), modelUnitSystem.getInstance_DIMENSIONLESS(), sm)));
            parm = mm.getSurfaceToVolumeParameter();
            if (parm.getExpression() == null) {
                throw new MappingException("surface to volume ratio not specified for membrane '" + mm.getMembrane().getName() + "', please refer to Structure Mapping in Application '" + simContext.getName() + "'");
            }
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(parm, sm), getIdentifierSubstitutions(parm.getExpression(), lengthInverseUnit, sm)));
        }
        StructureMappingParameter sizeParm = sm.getSizeParameter();
        if (sizeParm != null) {
            if (simContext.getGeometry().getDimension() == 0) {
                if (sizeParm.getExpression() != null) {
                    try {
                        double value = sizeParm.getExpression().evaluateConstant();
                        varHash.addVariable(new Constant(getMathSymbol(sizeParm, sm), new Expression(value)));
                    } catch (ExpressionException e) {
                        // varHash.addVariable(new Function(getMathSymbol(parm,sm),getIdentifierSubstitutions(parm.getExpression(),parm.getUnitDefinition(),sm)));
                        e.printStackTrace(System.out);
                        throw new MappingException("Size of structure:" + sm.getNameScope().getName() + " cannot be evaluated as constant.");
                    }
                }
            } else {
                String compartmentName = null;
                VCUnitDefinition sizeUnit = sm.getSizeParameter().getUnitDefinition();
                String sizeFunctionName = null;
                if (sm instanceof MembraneMapping) {
                    MembraneMapping mm = (MembraneMapping) sm;
                    if (getResolved(mm)) {
                        FeatureMapping fm_inside = (FeatureMapping) simContext.getGeometryContext().getStructureMapping(structTopology.getInsideFeature(mm.getMembrane()));
                        FeatureMapping fm_outside = (FeatureMapping) simContext.getGeometryContext().getStructureMapping(structTopology.getOutsideFeature(mm.getMembrane()));
                        compartmentName = getSubVolume(fm_inside).getName() + "_" + getSubVolume(fm_outside).getName();
                        sizeFunctionName = MathFunctionDefinitions.Function_regionArea_current.getFunctionName();
                    } else {
                        FeatureMapping fm_inside = (FeatureMapping) simContext.getGeometryContext().getStructureMapping(structTopology.getInsideFeature(mm.getMembrane()));
                        FeatureMapping fm_outside = (FeatureMapping) simContext.getGeometryContext().getStructureMapping(structTopology.getOutsideFeature(mm.getMembrane()));
                        if (getSubVolume(fm_inside) == getSubVolume(fm_outside)) {
                            compartmentName = getSubVolume(fm_inside).getName();
                            sizeFunctionName = MathFunctionDefinitions.Function_regionVolume_current.getFunctionName();
                        } else {
                            throw new RuntimeException("unexpected structure mapping for membrane '" + mm.getMembrane().getName() + "'");
                        }
                    }
                } else if (sm instanceof FeatureMapping) {
                    FeatureMapping fm = (FeatureMapping) sm;
                    compartmentName = getSubVolume(fm).getName();
                    sizeFunctionName = MathFunctionDefinitions.Function_regionVolume_current.getFunctionName();
                } else {
                    throw new RuntimeException("structure mapping " + sm.getClass().getName() + " not yet supported");
                }
                Expression totalVolumeCorrection = sm.getStructureSizeCorrection(simContext, this);
                Expression sizeFunctionExpression = Expression.function(sizeFunctionName, new Expression[] { new Expression("'" + compartmentName + "'") });
                sizeFunctionExpression.bindExpression(mathDesc);
                varHash.addVariable(newFunctionOrConstant(getMathSymbol(sizeParm, sm), getIdentifierSubstitutions(Expression.mult(totalVolumeCorrection, sizeFunctionExpression), sizeUnit, sm)));
                parm = sm.getParameterFromRole(StructureMapping.ROLE_AreaPerUnitArea);
                if (parm != null && parm.getExpression() != null && sm.getGeometryClass() instanceof SurfaceClass) {
                    varHash.addVariable(newFunctionOrConstant(getMathSymbol(parm, sm), getIdentifierSubstitutions(parm.getExpression(), parm.getUnitDefinition(), sm)));
                }
                parm = sm.getParameterFromRole(StructureMapping.ROLE_AreaPerUnitVolume);
                if (parm != null && parm.getExpression() != null && sm.getGeometryClass() instanceof SubVolume) {
                    varHash.addVariable(newFunctionOrConstant(getMathSymbol(parm, sm), getIdentifierSubstitutions(parm.getExpression(), parm.getUnitDefinition(), sm)));
                }
                parm = sm.getParameterFromRole(StructureMapping.ROLE_VolumePerUnitArea);
                if (parm != null && parm.getExpression() != null && sm.getGeometryClass() instanceof SurfaceClass) {
                    varHash.addVariable(newFunctionOrConstant(getMathSymbol(parm, sm), getIdentifierSubstitutions(parm.getExpression(), parm.getUnitDefinition(), sm)));
                }
                parm = sm.getParameterFromRole(StructureMapping.ROLE_VolumePerUnitVolume);
                if (parm != null && parm.getExpression() != null && sm.getGeometryClass() instanceof SubVolume) {
                    varHash.addVariable(newFunctionOrConstant(getMathSymbol(parm, sm), getIdentifierSubstitutions(parm.getExpression(), parm.getUnitDefinition(), sm)));
                }
            }
        }
    }
    // 
    for (int i = 0; i < fieldMathMappingParameters.length; i++) {
        varHash.addVariable(newFunctionOrConstant(getMathSymbol(fieldMathMappingParameters[i], null), getIdentifierSubstitutions(fieldMathMappingParameters[i].getExpression(), fieldMathMappingParameters[i].getUnitDefinition(), null)));
    }
    // 
    // functions
    // 
    enum1 = getSpeciesContextMappings();
    while (enum1.hasMoreElements()) {
        SpeciesContextMapping scm = (SpeciesContextMapping) enum1.nextElement();
        if (scm.getVariable() == null && scm.getDependencyExpression() != null) {
            StructureMapping sm = simContext.getGeometryContext().getStructureMapping(scm.getSpeciesContext().getStructure());
            varHash.addVariable(newFunctionOrConstant(getMathSymbol(scm.getSpeciesContext(), sm), getIdentifierSubstitutions(scm.getDependencyExpression(), scm.getSpeciesContext().getUnitDefinition(), sm)));
        }
    }
    // 
    // set Variables to MathDescription all at once with the order resolved by "VariableHash"
    // 
    mathDesc.setAllVariables(varHash.getAlphabeticallyOrderedVariables());
    // 
    if (simContext.getGeometryContext().getGeometry() != null) {
        try {
            mathDesc.setGeometry(simContext.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");
    }
    // 
    // volume subdomains
    // 
    subVolumes = simContext.getGeometryContext().getGeometry().getGeometrySpec().getSubVolumes();
    VCUnitDefinition timeUnit = modelUnitSystem.getTimeUnit();
    for (int j = 0; j < subVolumes.length; j++) {
        SubVolume subVolume = (SubVolume) subVolumes[j];
        // 
        // get priority of subDomain
        // 
        int priority;
        Feature spatialFeature = getResolvedFeature(subVolume);
        if (spatialFeature == null) {
            if (simContext.getGeometryContext().getGeometry().getDimension() > 0) {
                throw new MappingException("no compartment (in Physiology) is mapped to subdomain '" + subVolume.getName() + "' (in Geometry)");
            } else {
                priority = CompartmentSubDomain.NON_SPATIAL_PRIORITY;
            }
        } else {
            // now does not have to match spatial feature, *BUT* needs to be unique
            priority = j;
        }
        // 
        // create subDomain
        // 
        CompartmentSubDomain subDomain = new CompartmentSubDomain(subVolume.getName(), priority);
        mathDesc.addSubDomain(subDomain);
        // 
        if (spatialFeature != null) {
            FeatureMapping fm = (FeatureMapping) simContext.getGeometryContext().getStructureMapping(spatialFeature);
            subDomain.setBoundaryConditionXm(fm.getBoundaryConditionTypeXm());
            subDomain.setBoundaryConditionXp(fm.getBoundaryConditionTypeXp());
            if (simContext.getGeometry().getDimension() > 1) {
                subDomain.setBoundaryConditionYm(fm.getBoundaryConditionTypeYm());
                subDomain.setBoundaryConditionYp(fm.getBoundaryConditionTypeYp());
            }
            if (simContext.getGeometry().getDimension() > 2) {
                subDomain.setBoundaryConditionZm(fm.getBoundaryConditionTypeZm());
                subDomain.setBoundaryConditionZp(fm.getBoundaryConditionTypeZp());
            }
        }
        // 
        // create equations
        // 
        VolumeStructureAnalyzer structureAnalyzer = getVolumeStructureAnalyzer(subVolume);
        Enumeration<SpeciesContextMapping> enumSCM = getSpeciesContextMappings();
        while (enumSCM.hasMoreElements()) {
            SpeciesContextMapping scm = enumSCM.nextElement();
            // 
            if (scm.getVariable() instanceof VolVariable && scm.getDependencyExpression() == null) {
                SpeciesContext sc = scm.getSpeciesContext();
                StructureMapping sm = simContext.getGeometryContext().getStructureMapping(sc.getStructure());
                SpeciesContextSpec scs = simContext.getReactionContext().getSpeciesContextSpec(sc);
                VolVariable variable = (VolVariable) scm.getVariable();
                Equation equation = null;
                if ((scm.isPDERequired()) && sm instanceof FeatureMapping) {
                    // 
                    if (getSubVolume((FeatureMapping) sm) == subVolume) {
                        // 
                        // species context belongs to this subDomain
                        // 
                        Expression initial = new Expression(getMathSymbol(scs.getParameterFromRole(SpeciesContextSpec.ROLE_InitialConcentration), sm));
                        Expression rate = getIdentifierSubstitutions(scm.getRate(), scm.getSpeciesContext().getUnitDefinition().divideBy(timeUnit), simContext.getGeometryContext().getStructureMapping(sc.getStructure()));
                        Expression diffusion = new Expression(getMathSymbol(scs.getDiffusionParameter(), sm));
                        equation = new PdeEquation(variable, initial, rate, diffusion);
                        ((PdeEquation) equation).setBoundaryXm((scs.getBoundaryXmParameter().getExpression() == null) ? (null) : new Expression(getMathSymbol(scs.getBoundaryXmParameter(), sm)));
                        ((PdeEquation) equation).setBoundaryXp((scs.getBoundaryXpParameter().getExpression() == null) ? (null) : new Expression(getMathSymbol(scs.getBoundaryXpParameter(), sm)));
                        ((PdeEquation) equation).setBoundaryYm((scs.getBoundaryYmParameter().getExpression() == null) ? (null) : new Expression(getMathSymbol(scs.getBoundaryYmParameter(), sm)));
                        ((PdeEquation) equation).setBoundaryYp((scs.getBoundaryYpParameter().getExpression() == null) ? (null) : new Expression(getMathSymbol(scs.getBoundaryYpParameter(), sm)));
                        ((PdeEquation) equation).setBoundaryZm((scs.getBoundaryZmParameter().getExpression() == null) ? (null) : new Expression(getMathSymbol(scs.getBoundaryZmParameter(), sm)));
                        ((PdeEquation) equation).setBoundaryZp((scs.getBoundaryZpParameter().getExpression() == null) ? (null) : new Expression(getMathSymbol(scs.getBoundaryZpParameter(), sm)));
                        ((PdeEquation) equation).setVelocityX((scs.getVelocityXParameter().getExpression() == null) ? (null) : new Expression(getMathSymbol(scs.getVelocityXParameter(), sm)));
                        ((PdeEquation) equation).setVelocityY((scs.getVelocityYParameter().getExpression() == null) ? (null) : new Expression(getMathSymbol(scs.getVelocityYParameter(), sm)));
                        ((PdeEquation) equation).setVelocityZ((scs.getVelocityZParameter().getExpression() == null) ? (null) : new Expression(getMathSymbol(scs.getVelocityZParameter(), sm)));
                        subDomain.replaceEquation(equation);
                    } else {
                        Expression initial = new Expression(0.0);
                        Expression rate = new Expression(0.0);
                        Expression diffusion = new Expression(getMathSymbol(scs.getDiffusionParameter(), sm));
                        equation = new PdeEquation(variable, initial, rate, diffusion);
                        if (subDomain.getEquation(variable) == null) {
                            subDomain.addEquation(equation);
                        }
                    }
                } else {
                    // 
                    // ODE
                    // 
                    SubVolume mappedSubVolume = null;
                    if (sm instanceof FeatureMapping) {
                        mappedSubVolume = getSubVolume((FeatureMapping) sm);
                    } else if (sm instanceof MembraneMapping) {
                        // membrane is mapped to that of the inside feature
                        FeatureMapping featureMapping = (FeatureMapping) simContext.getGeometryContext().getStructureMapping(structTopology.getInsideFeature((Membrane) sm.getStructure()));
                        mappedSubVolume = getSubVolume(featureMapping);
                    }
                    if (mappedSubVolume == subVolume) {
                        // 
                        // species context belongs to this subDomain
                        // 
                        Expression initial = new Expression(getMathSymbol(scs.getParameterFromRole(SpeciesContextSpec.ROLE_InitialConcentration), null));
                        Expression rate = (scm.getRate() == null) ? new Expression(0.0) : getIdentifierSubstitutions(scm.getRate(), scm.getSpeciesContext().getUnitDefinition().divideBy(timeUnit), simContext.getGeometryContext().getStructureMapping(sc.getStructure()));
                        equation = new OdeEquation(variable, initial, rate);
                        subDomain.replaceEquation(equation);
                    } else {
                        Expression initial = new Expression(0.0);
                        Expression rate = new Expression(0.0);
                        equation = new OdeEquation(variable, initial, rate);
                        if (subDomain.getEquation(variable) == null) {
                            subDomain.addEquation(equation);
                        }
                    }
                }
            }
        }
        // 
        // create fast system (if neccessary)
        // 
        SpeciesContextMapping[] fastSpeciesContextMappings = structureAnalyzer.getFastSpeciesContextMappings();
        VCUnitDefinition subDomainUnit = modelUnitSystem.getVolumeConcentrationUnit();
        if (fastSpeciesContextMappings != null) {
            FastSystem fastSystem = new FastSystem(mathDesc);
            for (int i = 0; i < fastSpeciesContextMappings.length; i++) {
                SpeciesContextMapping scm = fastSpeciesContextMappings[i];
                if (scm.getFastInvariant() == null) {
                    // 
                    // independant-fast variable, create a fastRate object
                    // 
                    Expression rate = getIdentifierSubstitutions(scm.getFastRate(), scm.getSpeciesContext().getUnitDefinition().divideBy(timeUnit), simContext.getGeometryContext().getStructureMapping(getResolvedFeature(subVolume)));
                    FastRate fastRate = new FastRate(rate);
                    fastSystem.addFastRate(fastRate);
                } else {
                    // 
                    // dependant-fast variable, create a fastInvariant object
                    // 
                    Expression rate = getIdentifierSubstitutions(scm.getFastInvariant(), subDomainUnit, simContext.getGeometryContext().getStructureMapping(getResolvedFeature(subVolume)));
                    FastInvariant fastInvariant = new FastInvariant(rate);
                    fastSystem.addFastInvariant(fastInvariant);
                }
            }
            subDomain.setFastSystem(fastSystem);
            // constructor calls the 'refresh' method which constructs depemdency matrix, dependent/independent vars and pseudoconstants, etc.
            FastSystemAnalyzer fs_analyzer = new FastSystemAnalyzer(fastSystem, mathDesc);
        }
        // 
        // create ode's for voltages to be calculated on unresolved membranes mapped to this subVolume
        // 
        Structure[] localStructures = getStructures(subVolume);
        for (int sIndex = 0; sIndex < localStructures.length; sIndex++) {
            if (localStructures[sIndex] instanceof Membrane) {
                Membrane membrane = (Membrane) localStructures[sIndex];
                MembraneMapping membraneMapping = (MembraneMapping) simContext.getGeometryContext().getStructureMapping(membrane);
                if (!getResolved(membraneMapping) && membraneMapping.getCalculateVoltage()) {
                    MembraneElectricalDevice capacitiveDevice = potentialMapping.getCapacitiveDevice(membrane);
                    if (capacitiveDevice.getDependentVoltageExpression() == null) {
                        VolVariable vVar = (VolVariable) mathDesc.getVariable(getMathSymbol(capacitiveDevice.getVoltageSymbol(), membraneMapping));
                        Expression initExp = new Expression(getMathSymbol(capacitiveDevice.getMembraneMapping().getInitialVoltageParameter(), membraneMapping));
                        subDomain.addEquation(new OdeEquation(vVar, initExp, getIdentifierSubstitutions(potentialMapping.getOdeRHS(capacitiveDevice, this), membrane.getMembraneVoltage().getUnitDefinition().divideBy(timeUnit), membraneMapping)));
                    } else {
                    // 
                    // 
                    // 
                    }
                }
            }
        }
    }
    // 
    for (int k = 0; k < subVolumes.length; k++) {
        SubVolume subVolume = (SubVolume) subVolumes[k];
        // 
        // if there is a spatially resolved membrane surrounding this subVolume, then create a membraneSubDomain
        // 
        structures = getStructures(subVolume);
        Membrane membrane = null;
        if (structures != null) {
            for (int j = 0; j < structures.length; j++) {
                if (structures[j] instanceof Membrane && getResolved(simContext.getGeometryContext().getStructureMapping(structures[j]))) {
                    membrane = (Membrane) structures[j];
                }
            }
        }
        if (membrane == null) {
            continue;
        }
        SubVolume outerSubVolume = getSubVolume(((FeatureMapping) simContext.getGeometryContext().getStructureMapping(structTopology.getOutsideFeature(membrane))));
        SubVolume innerSubVolume = getSubVolume(((FeatureMapping) simContext.getGeometryContext().getStructureMapping(structTopology.getInsideFeature(membrane))));
        if (innerSubVolume != subVolume) {
            throw new MappingException("membrane " + membrane.getName() + " improperly mapped to inner subVolume " + innerSubVolume.getName());
        }
        // 
        // get priority of subDomain
        // 
        // Feature spatialFeature = simContext.getGeometryContext().getResolvedFeature(subVolume);
        // int priority = spatialFeature.getPriority();
        // 
        // create subDomain
        // 
        CompartmentSubDomain outerCompartment = mathDesc.getCompartmentSubDomain(outerSubVolume.getName());
        CompartmentSubDomain innerCompartment = mathDesc.getCompartmentSubDomain(innerSubVolume.getName());
        SurfaceClass surfaceClass = simContext.getGeometry().getGeometrySurfaceDescription().getSurfaceClass(innerSubVolume, outerSubVolume);
        MembraneSubDomain memSubDomain = new MembraneSubDomain(innerCompartment, outerCompartment, surfaceClass.getName());
        mathDesc.addSubDomain(memSubDomain);
        // 
        // create equations for membrane-bound molecular species
        // 
        MembraneStructureAnalyzer membraneStructureAnalyzer = getMembraneStructureAnalyzer(membrane);
        Enumeration<SpeciesContextMapping> enumSCM = getSpeciesContextMappings();
        while (enumSCM.hasMoreElements()) {
            SpeciesContextMapping scm = enumSCM.nextElement();
            SpeciesContext sc = scm.getSpeciesContext();
            SpeciesContextSpec scs = simContext.getReactionContext().getSpeciesContextSpec(sc);
            // 
            if ((scm.getVariable() instanceof MemVariable) && scm.getDependencyExpression() == null) {
                // 
                // independant variable, create an equation object
                // 
                Equation equation = null;
                MemVariable variable = (MemVariable) scm.getVariable();
                MembraneMapping mm = (MembraneMapping) simContext.getGeometryContext().getStructureMapping(sc.getStructure());
                if (scm.isPDERequired()) {
                    // 
                    if (mm.getMembrane() == membrane) {
                        // 
                        // species context belongs to this subDomain
                        // 
                        Expression initial = new Expression(getMathSymbol(scs.getParameterFromRole(SpeciesContextSpec.ROLE_InitialConcentration), mm));
                        Expression rate = getIdentifierSubstitutions(scm.getRate(), scm.getSpeciesContext().getUnitDefinition().divideBy(timeUnit), simContext.getGeometryContext().getStructureMapping(sc.getStructure()));
                        Expression diffusion = new Expression(getMathSymbol(scs.getDiffusionParameter(), mm));
                        equation = new PdeEquation(variable, initial, rate, diffusion);
                        ((PdeEquation) equation).setBoundaryXm((scs.getBoundaryXmParameter().getExpression() == null) ? (null) : new Expression(getMathSymbol(scs.getBoundaryXmParameter(), mm)));
                        ((PdeEquation) equation).setBoundaryXp((scs.getBoundaryXpParameter().getExpression() == null) ? (null) : new Expression(getMathSymbol(scs.getBoundaryXpParameter(), mm)));
                        ((PdeEquation) equation).setBoundaryYm((scs.getBoundaryYmParameter().getExpression() == null) ? (null) : new Expression(getMathSymbol(scs.getBoundaryYmParameter(), mm)));
                        ((PdeEquation) equation).setBoundaryYp((scs.getBoundaryYpParameter().getExpression() == null) ? (null) : new Expression(getMathSymbol(scs.getBoundaryYpParameter(), mm)));
                        ((PdeEquation) equation).setBoundaryZm((scs.getBoundaryZmParameter().getExpression() == null) ? (null) : new Expression(getMathSymbol(scs.getBoundaryZmParameter(), mm)));
                        ((PdeEquation) equation).setBoundaryZp((scs.getBoundaryZpParameter().getExpression() == null) ? (null) : new Expression(getMathSymbol(scs.getBoundaryZpParameter(), mm)));
                        memSubDomain.replaceEquation(equation);
                    } else {
                        Expression initial = new Expression(0.0);
                        Expression rate = new Expression(0.0);
                        Expression diffusion = new Expression(getMathSymbol(scs.getDiffusionParameter(), mm));
                        equation = new PdeEquation(variable, initial, rate, diffusion);
                        if (memSubDomain.getEquation(variable) == null) {
                            memSubDomain.addEquation(equation);
                        }
                    }
                } else {
                    // 
                    if (mm.getMembrane() == membrane) {
                        // 
                        // species context belongs to this subDomain
                        // 
                        Expression initial = new Expression(getMathSymbol(scs.getParameterFromRole(SpeciesContextSpec.ROLE_InitialConcentration), null));
                        Expression rate = getIdentifierSubstitutions(scm.getRate(), scm.getSpeciesContext().getUnitDefinition().divideBy(timeUnit), simContext.getGeometryContext().getStructureMapping(sc.getStructure()));
                        equation = new OdeEquation(variable, initial, rate);
                        memSubDomain.replaceEquation(equation);
                    } else {
                        Expression initial = new Expression(0.0);
                        Expression rate = new Expression(0.0);
                        equation = new OdeEquation(variable, initial, rate);
                        if (memSubDomain.getEquation(variable) == null) {
                            memSubDomain.addEquation(equation);
                        }
                    }
                }
            }
        }
        // 
        // create dummy jump conditions for all volume variables that diffuse and/or advect
        // 
        Enumeration<SpeciesContextMapping> enum_scm = getSpeciesContextMappings();
        while (enum_scm.hasMoreElements()) {
            SpeciesContextMapping scm = enum_scm.nextElement();
            if (scm.isPDERequired()) {
                // Species species = scm.getSpeciesContext().getSpecies();
                Variable var = scm.getVariable();
                if (var instanceof VolVariable && (scm.isPDERequired())) {
                    JumpCondition jc = memSubDomain.getJumpCondition((VolVariable) var);
                    if (jc == null) {
                        // System.out.println("MathMapping.refreshMathDescription(), adding jump condition for diffusing variable "+var.getName()+" on membrane "+membraneStructureAnalyzer.getMembrane().getName());
                        jc = new JumpCondition((VolVariable) var);
                        memSubDomain.addJumpCondition(jc);
                    }
                }
            }
        }
        // 
        // create jump conditions for any volume variables that bind to membrane or have explicitly defined fluxes
        // 
        ResolvedFlux[] resolvedFluxes = membraneStructureAnalyzer.getResolvedFluxes();
        if (resolvedFluxes != null) {
            for (int i = 0; i < resolvedFluxes.length; i++) {
                Species species = resolvedFluxes[i].getSpecies();
                SpeciesContext sc = simContext.getReactionContext().getModel().getSpeciesContext(species, structTopology.getInsideFeature(membraneStructureAnalyzer.getMembrane()));
                if (sc == null) {
                    sc = simContext.getReactionContext().getModel().getSpeciesContext(species, structTopology.getOutsideFeature(membraneStructureAnalyzer.getMembrane()));
                }
                SpeciesContextMapping scm = getSpeciesContextMapping(sc);
                // if (scm.getVariable() instanceof VolVariable && scm.isDiffusing()){
                if (scm.getVariable() instanceof VolVariable && ((MembraneStructureAnalyzer.bNoFluxIfFixed || (scm.isPDERequired())))) {
                    if (MembraneStructureAnalyzer.bNoFluxIfFixed && !scm.isPDERequired()) {
                        MembraneStructureAnalyzer.bNoFluxIfFixedExercised = true;
                    }
                    JumpCondition jc = memSubDomain.getJumpCondition((VolVariable) scm.getVariable());
                    if (jc == null) {
                        jc = new JumpCondition((VolVariable) scm.getVariable());
                        memSubDomain.addJumpCondition(jc);
                    }
                    Expression inFlux = getIdentifierSubstitutions(resolvedFluxes[i].inFluxExpression, resolvedFluxes[i].getUnitDefinition(), simContext.getGeometryContext().getStructureMapping(membraneStructureAnalyzer.getMembrane()));
                    jc.setInFlux(inFlux);
                    Expression outFlux = getIdentifierSubstitutions(resolvedFluxes[i].outFluxExpression, resolvedFluxes[i].getUnitDefinition(), simContext.getGeometryContext().getStructureMapping(membraneStructureAnalyzer.getMembrane()));
                    jc.setOutFlux(outFlux);
                } else {
                    throw new MappingException("APPLICATION  " + simContext.getName() + " : " + scm.getSpeciesContext().getName() + " has spatially resolved flux at membrane " + membrane.getName() + ", but doesn't diffuse in compartment " + scm.getSpeciesContext().getStructure().getName());
                }
            }
        }
        // 
        // create fast system (if neccessary)
        // 
        SpeciesContextMapping[] fastSpeciesContextMappings = membraneStructureAnalyzer.getFastSpeciesContextMappings();
        if (fastSpeciesContextMappings != null) {
            FastSystem fastSystem = new FastSystem(mathDesc);
            for (int i = 0; i < fastSpeciesContextMappings.length; i++) {
                SpeciesContextMapping scm = fastSpeciesContextMappings[i];
                if (scm.getFastInvariant() == null) {
                    // 
                    // independant-fast variable, create a fastRate object
                    // 
                    VCUnitDefinition rateUnit = scm.getSpeciesContext().getUnitDefinition().divideBy(timeUnit);
                    MembraneMapping membraneMapping = (MembraneMapping) simContext.getGeometryContext().getStructureMapping(membraneStructureAnalyzer.getMembrane());
                    FastRate fastRate = new FastRate(getIdentifierSubstitutions(scm.getFastRate(), rateUnit, membraneMapping));
                    fastSystem.addFastRate(fastRate);
                } else {
                    // 
                    // dependant-fast variable, create a fastInvariant object
                    // 
                    VCUnitDefinition invariantUnit = scm.getSpeciesContext().getUnitDefinition();
                    MembraneMapping membraneMapping = (MembraneMapping) simContext.getGeometryContext().getStructureMapping(membraneStructureAnalyzer.getMembrane());
                    FastInvariant fastInvariant = new FastInvariant(getIdentifierSubstitutions(scm.getFastInvariant(), invariantUnit, membraneMapping));
                    fastSystem.addFastInvariant(fastInvariant);
                }
            }
            memSubDomain.setFastSystem(fastSystem);
            // constructor calls the 'refresh' method which constructs depemdency matrix, dependent/independent vars and pseudoconstants, etc.
            FastSystemAnalyzer fs_analyzer = new FastSystemAnalyzer(fastSystem, mathDesc);
        }
        // 
        // create Membrane-region equations for potential of this resolved membrane
        // 
        MembraneMapping membraneMapping = (MembraneMapping) simContext.getGeometryContext().getStructureMapping(membrane);
        if (membraneMapping.getCalculateVoltage()) {
            ElectricalDevice[] membraneDevices = potentialMapping.getElectricalDevices(membrane);
            int numCapacitiveDevices = 0;
            MembraneElectricalDevice capacitiveDevice = null;
            for (int i = 0; i < membraneDevices.length; i++) {
                if (membraneDevices[i] instanceof MembraneElectricalDevice) {
                    numCapacitiveDevices++;
                    capacitiveDevice = (MembraneElectricalDevice) membraneDevices[i];
                }
            }
            if (numCapacitiveDevices != 1) {
                throw new MappingException("expecting 1 capacitive electrical device on graph edge for membrane " + membrane.getName() + ", found '" + numCapacitiveDevices + "'");
            }
            if (mathDesc.getVariable(getMathSymbol(capacitiveDevice.getVoltageSymbol(), membraneMapping)) instanceof MembraneRegionVariable) {
                MembraneRegionVariable vVar = (MembraneRegionVariable) mathDesc.getVariable(getMathSymbol(capacitiveDevice.getVoltageSymbol(), membraneMapping));
                Parameter initialVoltageParm = capacitiveDevice.getMembraneMapping().getInitialVoltageParameter();
                Expression initExp = getIdentifierSubstitutions(initialVoltageParm.getExpression(), initialVoltageParm.getUnitDefinition(), capacitiveDevice.getMembraneMapping());
                MembraneRegionEquation vEquation = new MembraneRegionEquation(vVar, initExp);
                vEquation.setMembraneRateExpression(getIdentifierSubstitutions(potentialMapping.getOdeRHS(capacitiveDevice, this), membrane.getMembraneVoltage().getUnitDefinition().divideBy(timeUnit), capacitiveDevice.getMembraneMapping()));
                memSubDomain.addEquation(vEquation);
            }
        }
    }
    // create equations for event assign targets that are model params/strutureSize, etc.
    Set<VolVariable> hashKeySet = eventVolVarHash.keySet();
    Iterator<VolVariable> volVarsIter = hashKeySet.iterator();
    // working under teh assumption that we are dealing with non-spatial math, hence only one compartment domain!
    SubDomain subDomain = mathDesc.getSubDomains().nextElement();
    while (volVarsIter.hasNext()) {
        VolVariable volVar = volVarsIter.next();
        EventAssignmentInitParameter eap = eventVolVarHash.get(volVar);
        Expression rateExpr = new Expression(0.0);
        Equation equation = new OdeEquation(volVar, new Expression(getMathSymbol(eap, null)), rateExpr);
        subDomain.addEquation(equation);
    }
    // events - add events to math desc and odes for event assignments that have parameters as target variables
    BioEvent[] bioevents = simContext.getBioEvents();
    if (bioevents != null && bioevents.length > 0) {
        for (BioEvent be : bioevents) {
            // transform the bioEvent trigger/delay to math Event
            Expression mathTriggerExpr = getIdentifierSubstitutions(be.generateTriggerExpression(), modelUnitSystem.getInstance_DIMENSIONLESS(), null);
            Delay mathDelay = null;
            if (be.getParameter(BioEventParameterType.TriggerDelay) != null) {
                boolean bUseValsFromTriggerTime = be.getUseValuesFromTriggerTime();
                Expression mathDelayExpr = getIdentifierSubstitutions(be.getParameter(BioEventParameterType.TriggerDelay).getExpression(), timeUnit, null);
                mathDelay = new Delay(bUseValsFromTriggerTime, mathDelayExpr);
            }
            // now deal with (bio)event Assignment translation to math EventAssignment
            ArrayList<EventAssignment> eventAssignments = be.getEventAssignments();
            ArrayList<Event.EventAssignment> mathEventAssignmentsList = new ArrayList<Event.EventAssignment>();
            for (EventAssignment ea : eventAssignments) {
                SymbolTableEntry ste = simContext.getEntry(ea.getTarget().getName());
                VCUnitDefinition eventAssignVarUnit = ste.getUnitDefinition();
                Variable variable = varHash.getVariable(ste.getName());
                Event.EventAssignment mathEA = new Event.EventAssignment(variable, getIdentifierSubstitutions(ea.getAssignmentExpression(), eventAssignVarUnit, null));
                mathEventAssignmentsList.add(mathEA);
            }
            // use the translated trigger, delay and event assignments to create (math) event
            Event mathEvent = new Event(be.getName(), mathTriggerExpr, mathDelay, mathEventAssignmentsList);
            mathDesc.addEvent(mathEvent);
        }
    }
    if (!mathDesc.isValid()) {
        throw new MappingException("generated an invalid mathDescription: " + mathDesc.getWarning());
    }
// System.out.println("]]]]]]]]]]]]]]]]]]]]]] VCML string begin ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]");
// System.out.println(mathDesc.getVCML());
// System.out.println("]]]]]]]]]]]]]]]]]]]]]] VCML string end ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]");
}
Also used : MembraneMapping(cbit.vcell.mapping.MembraneMapping) MembraneSubDomain(cbit.vcell.math.MembraneSubDomain) ArrayList(java.util.ArrayList) SpeciesContext(cbit.vcell.model.SpeciesContext) StructureMappingParameter(cbit.vcell.mapping.StructureMapping.StructureMappingParameter) Feature(cbit.vcell.model.Feature) MemVariable(cbit.vcell.math.MemVariable) KineticsParameter(cbit.vcell.model.Kinetics.KineticsParameter) SubVolume(cbit.vcell.geometry.SubVolume) Vector(java.util.Vector) SpeciesContextSpecParameter(cbit.vcell.mapping.SpeciesContextSpec.SpeciesContextSpecParameter) StructureTopology(cbit.vcell.model.Model.StructureTopology) ReactionSpec(cbit.vcell.mapping.ReactionSpec) FastInvariant(cbit.vcell.math.FastInvariant) PropertyVetoException(java.beans.PropertyVetoException) VCUnitDefinition(cbit.vcell.units.VCUnitDefinition) FastSystem(cbit.vcell.math.FastSystem) CompartmentSubDomain(cbit.vcell.math.CompartmentSubDomain) ReactionStep(cbit.vcell.model.ReactionStep) MembraneRegionEquation(cbit.vcell.math.MembraneRegionEquation) SurfaceClass(cbit.vcell.geometry.SurfaceClass) VariableHash(cbit.vcell.math.VariableHash) StructureMapping(cbit.vcell.mapping.StructureMapping) FeatureMapping(cbit.vcell.mapping.FeatureMapping) Structure(cbit.vcell.model.Structure) ModelUnitSystem(cbit.vcell.model.ModelUnitSystem) Hashtable(java.util.Hashtable) StructureMappingParameter(cbit.vcell.mapping.StructureMapping.StructureMappingParameter) Expression(cbit.vcell.parser.Expression) Model(cbit.vcell.model.Model) ProxyParameter(cbit.vcell.model.ProxyParameter) StructureMappingParameter(cbit.vcell.mapping.StructureMapping.StructureMappingParameter) Parameter(cbit.vcell.model.Parameter) KineticsParameter(cbit.vcell.model.Kinetics.KineticsParameter) SpeciesContextSpecProxyParameter(cbit.vcell.mapping.SpeciesContextSpec.SpeciesContextSpecProxyParameter) LocalParameter(cbit.vcell.mapping.ParameterContext.LocalParameter) ModelParameter(cbit.vcell.model.Model.ModelParameter) SpeciesContextSpecParameter(cbit.vcell.mapping.SpeciesContextSpec.SpeciesContextSpecParameter) BioEvent(cbit.vcell.mapping.BioEvent) Event(cbit.vcell.math.Event) BioEvent(cbit.vcell.mapping.BioEvent) MembraneRegionVariable(cbit.vcell.math.MembraneRegionVariable) MathDescription(cbit.vcell.math.MathDescription) SpeciesContextMapping(cbit.vcell.mapping.SpeciesContextMapping) SpeciesContextSpec(cbit.vcell.mapping.SpeciesContextSpec) ExpressionException(cbit.vcell.parser.ExpressionException) Delay(cbit.vcell.math.Event.Delay) MappingException(cbit.vcell.mapping.MappingException) PropertyVetoException(java.beans.PropertyVetoException) PdeEquation(cbit.vcell.math.PdeEquation) CompartmentSubDomain(cbit.vcell.math.CompartmentSubDomain) SubDomain(cbit.vcell.math.SubDomain) MembraneSubDomain(cbit.vcell.math.MembraneSubDomain) Species(cbit.vcell.model.Species) SpeciesContextSpecParameter(cbit.vcell.mapping.SpeciesContextSpec.SpeciesContextSpecParameter) EventAssignment(cbit.vcell.mapping.BioEvent.EventAssignment) VolVariable(cbit.vcell.math.VolVariable) ModelParameter(cbit.vcell.model.Model.ModelParameter) OdeEquation(cbit.vcell.math.OdeEquation) JumpCondition(cbit.vcell.math.JumpCondition) MembraneRegionVariable(cbit.vcell.math.MembraneRegionVariable) VolVariable(cbit.vcell.math.VolVariable) MemVariable(cbit.vcell.math.MemVariable) Variable(cbit.vcell.math.Variable) SpeciesContextSpecProxyParameter(cbit.vcell.mapping.SpeciesContextSpec.SpeciesContextSpecProxyParameter) Constant(cbit.vcell.math.Constant) SymbolTableEntry(cbit.vcell.parser.SymbolTableEntry) Membrane(cbit.vcell.model.Membrane) EventAssignment(cbit.vcell.mapping.BioEvent.EventAssignment) OdeEquation(cbit.vcell.math.OdeEquation) MembraneRegionEquation(cbit.vcell.math.MembraneRegionEquation) PdeEquation(cbit.vcell.math.PdeEquation) Equation(cbit.vcell.math.Equation) FastRate(cbit.vcell.math.FastRate)

Aggregations

SubVolume (cbit.vcell.geometry.SubVolume)84 SurfaceClass (cbit.vcell.geometry.SurfaceClass)42 Expression (cbit.vcell.parser.Expression)33 AnalyticSubVolume (cbit.vcell.geometry.AnalyticSubVolume)26 ImageSubVolume (cbit.vcell.geometry.ImageSubVolume)22 GeometryClass (cbit.vcell.geometry.GeometryClass)21 ArrayList (java.util.ArrayList)21 Geometry (cbit.vcell.geometry.Geometry)20 MathDescription (cbit.vcell.math.MathDescription)17 SpeciesContext (cbit.vcell.model.SpeciesContext)17 PropertyVetoException (java.beans.PropertyVetoException)17 CompartmentSubDomain (cbit.vcell.math.CompartmentSubDomain)16 CompartmentSubVolume (cbit.vcell.geometry.CompartmentSubVolume)15 Model (cbit.vcell.model.Model)15 ImageException (cbit.image.ImageException)14 VCImage (cbit.image.VCImage)14 Feature (cbit.vcell.model.Feature)14 Structure (cbit.vcell.model.Structure)14 MembraneSubDomain (cbit.vcell.math.MembraneSubDomain)13 ExpressionException (cbit.vcell.parser.ExpressionException)13