Search in sources :

Example 26 with TimeBounds

use of cbit.vcell.solver.TimeBounds in project vcell by virtualcell.

the class ComsolModelBuilder method getVCCModel.

public static VCCModel getVCCModel(SimulationJob vcellSimJob) throws ExpressionException {
    MathDescription vcellMathDesc = vcellSimJob.getSimulation().getMathDescription();
    Geometry vcellGeometry = vcellMathDesc.getGeometry();
    GeometrySpec vcellGeometrySpec = vcellGeometry.getGeometrySpec();
    int vcellDim = vcellGeometrySpec.getDimension();
    VCCModel model = new VCCModel("Model", vcellDim);
    model.modelpath = "D:\\Developer\\eclipse\\workspace_refactor\\comsol_java\\src";
    model.comments = "Untitled\n\n";
    VCCModelNode comp1 = new VCCModelNode("comp1");
    model.modelnodes.add(comp1);
    // if (vcellDim != 2){
    // throw new RuntimeException("expecting 2D simulation");
    // }
    // 
    // assume initial geometry is circle centered at 0.5, 0.5 of radius 0.3
    // 
    // String comsolOutsideDomainName = "dif1";
    // String comsolInsideDomainName = "c1";
    VCCGeomSequence geom1 = new VCCGeomSequence("geom1", vcellDim);
    model.geometrysequences.add(geom1);
    VCCMeshSequence mesh1 = new VCCMeshSequence("mesh1", geom1);
    model.meshes.add(mesh1);
    VCCStudy std1 = new VCCStudy("std1");
    model.study = std1;
    TimeBounds timeBounds = vcellSimJob.getSimulation().getSolverTaskDescription().getTimeBounds();
    TimeStep timeStep = vcellSimJob.getSimulation().getSolverTaskDescription().getTimeStep();
    String beginTime = Double.toString(timeBounds.getStartingTime());
    String endTime = Double.toString(timeBounds.getEndingTime());
    String step = Double.toString(timeStep.getDefaultTimeStep());
    VCCStudyFeature time = new VCCTransientStudyFeature("time", beginTime, step, endTime);
    std1.features.add(time);
    if (vcellGeometrySpec.getImage() != null) {
        throw new RuntimeException("image-based geometries not yet supported by VCell's COMSOL model builder");
    }
    if (vcellGeometrySpec.getNumSubVolumes() == 0) {
        throw new RuntimeException("no subvolumes defined in geometry");
    }
    if (vcellGeometrySpec.getNumAnalyticOrCSGSubVolumes() != vcellGeometrySpec.getNumSubVolumes()) {
        throw new RuntimeException("only analytic and CSG subvolumes currently supported by VCell's COMSOL model builder");
    }
    // 
    // add geometry for all subvolumes
    // 
    HashMap<String, VCCGeomFeature> subvolumeNameFeatureMap = new HashMap<String, VCCGeomFeature>();
    SubVolume[] subVolumes = vcellGeometrySpec.getSubVolumes();
    for (int i = 0; i < subVolumes.length; i++) {
        SubVolume subvolume = subVolumes[i];
        if (subvolume instanceof CSGObject) {
            CSGObject vcellCSGObject = (CSGObject) subvolume;
            CSGNode vcellCSGNode = vcellCSGObject.getRoot();
            ArrayList<VCCGeomFeature> geomFeatureList = new ArrayList<VCCGeomFeature>();
            VCCGeomFeature feature = csgVisitor(vcellCSGNode, geomFeatureList, subvolume.getName());
            geom1.geomfeatures.addAll(geomFeatureList);
            if (i == 0) {
                // first subvolume (on top in ordinals) doesn't need any differencing
                subvolumeNameFeatureMap.put(subvolume.getName(), feature);
            } else {
                // have to subtract union of prior subvolumes
                ArrayList<VCCGeomFeature> priorFeatures = new ArrayList<VCCGeomFeature>();
                for (int j = 0; j < i; j++) {
                    CSGObject priorCSGObject = (CSGObject) subVolumes[j];
                    CSGNode priorCSGNode = priorCSGObject.getRoot();
                    geomFeatureList.clear();
                    VCCGeomFeature priorFeature = csgVisitor(priorCSGNode, geomFeatureList, subvolume.getName());
                    priorFeatures.add(priorFeature);
                    geom1.geomfeatures.addAll(geomFeatureList);
                }
                VCCDifference diff = new VCCDifference("diff" + subvolume.getName(), Keep.off);
                diff.input.add(feature);
                diff.input2.addAll(priorFeatures);
                geom1.geomfeatures.add(diff);
                subvolumeNameFeatureMap.put(subvolume.getName(), diff);
            }
        } else {
            throw new RuntimeException("only CSG subvolumes currently supported by VCell's COMSOL model builder");
        }
    }
    // 
    // add geometry for all surfaceClasses
    // 
    HashMap<String, VCCGeomFeature> surfaceclassNameFeatureMap = new HashMap<String, VCCGeomFeature>();
    SurfaceClass[] surfaceClasses = vcellGeometry.getGeometrySurfaceDescription().getSurfaceClasses();
    for (int i = 0; i < surfaceClasses.length; i++) {
        SurfaceClass surfaceClass = surfaceClasses[i];
        Set<SubVolume> adjacentSubvolumes = surfaceClass.getAdjacentSubvolumes();
        if (adjacentSubvolumes.size() != 2) {
            throw new RuntimeException("expecting two adjacent subvolumes for surface " + surfaceClass.getName() + " in COMSOL model builder");
        }
        // find adjacent Geometry Features (for subvolumes)
        Iterator<SubVolume> svIter = adjacentSubvolumes.iterator();
        SubVolume subvolume0 = svIter.next();
        SubVolume subvolume1 = svIter.next();
        ArrayList<VCCGeomFeature> adjacentFeatures = new ArrayList<VCCGeomFeature>();
        adjacentFeatures.add(subvolumeNameFeatureMap.get(subvolume0.getName()));
        adjacentFeatures.add(subvolumeNameFeatureMap.get(subvolume1.getName()));
        String name = "inter_" + subvolume0.getName() + "_" + subvolume1.getName();
        // surfaces are dimension N-1
        int entitydim = vcellDim - 1;
        VCCIntersectionSelection intersect_subvolumes = new VCCIntersectionSelection(name, entitydim);
        intersect_subvolumes.input.addAll(adjacentFeatures);
        geom1.geomfeatures.add(intersect_subvolumes);
        surfaceclassNameFeatureMap.put(surfaceClass.getName(), intersect_subvolumes);
    }
    SimulationSymbolTable symbolTable = new SimulationSymbolTable(vcellSimJob.getSimulation(), vcellSimJob.getJobIndex());
    // 
    for (SubDomain subDomain : Collections.list(vcellMathDesc.getSubDomains())) {
        for (Equation equ : subDomain.getEquationCollection()) {
            if (equ instanceof PdeEquation || equ instanceof OdeEquation) {
                VCCGeomFeature geomFeature = null;
                final int dim;
                if (subDomain instanceof CompartmentSubDomain) {
                    geomFeature = subvolumeNameFeatureMap.get(subDomain.getName());
                    dim = vcellDim;
                } else if (subDomain instanceof MembraneSubDomain) {
                    geomFeature = surfaceclassNameFeatureMap.get(subDomain.getName());
                    dim = vcellDim - 1;
                } else {
                    throw new RuntimeException("subdomains of type '" + subDomain.getClass().getSimpleName() + "' not yet supported in COMSOL model builder");
                }
                if (geomFeature == null) {
                    throw new RuntimeException("cannot find COMSOL geometry feature named " + subDomain.getName() + " in COMSOL model builder");
                }
                VCCConvectionDiffusionEquation cdeq = new VCCConvectionDiffusionEquation("cdeq_" + equ.getVariable().getName(), geom1, geomFeature, dim);
                cdeq.fieldName = equ.getVariable().getName();
                cdeq.initial = MathUtilities.substituteModelParameters(equ.getInitialExpression(), symbolTable).flatten().infix();
                cdeq.sourceTerm_f = MathUtilities.substituteModelParameters(equ.getRateExpression(), symbolTable).flatten().infix();
                if (equ instanceof PdeEquation) {
                    PdeEquation pde = (PdeEquation) equ;
                    cdeq.diffTerm_c = MathUtilities.substituteModelParameters(pde.getDiffusionExpression(), symbolTable).flatten().infix();
                    if (subDomain instanceof CompartmentSubDomain) {
                        CompartmentSubDomain compartmentSubdomain = (CompartmentSubDomain) subDomain;
                        ArrayList<String> be = new ArrayList<String>();
                        if (pde.getVelocityX() != null) {
                            be.add(MathUtilities.substituteModelParameters(pde.getVelocityX(), symbolTable).flatten().infix());
                        } else {
                            be.add("0");
                        }
                        if (vcellDim >= 2) {
                            if (pde.getVelocityY() != null) {
                                be.add(MathUtilities.substituteModelParameters(pde.getVelocityY(), symbolTable).flatten().infix());
                            } else {
                                be.add("0");
                            }
                        }
                        if (vcellDim == 3) {
                            if (pde.getVelocityY() != null) {
                                be.add(MathUtilities.substituteModelParameters(pde.getVelocityZ(), symbolTable).flatten().infix());
                            } else {
                                be.add("0");
                            }
                        }
                        cdeq.advection_be = be.toArray(new String[vcellDim]);
                        // 
                        // look for membrane boundary conditions for this variable
                        // 
                        MembraneSubDomain[] membraneSubdomains = vcellMathDesc.getMembraneSubDomains(compartmentSubdomain);
                        for (MembraneSubDomain membraneSubdomain : membraneSubdomains) {
                            JumpCondition jumpCondition = membraneSubdomain.getJumpCondition((VolVariable) pde.getVariable());
                            if (jumpCondition != null) {
                                Expression fluxExpr = null;
                                if (membraneSubdomain.getInsideCompartment() == compartmentSubdomain) {
                                    fluxExpr = jumpCondition.getInFluxExpression();
                                } else if (membraneSubdomain.getOutsideCompartment() == compartmentSubdomain) {
                                    fluxExpr = jumpCondition.getOutFluxExpression();
                                }
                                String name = equ.getVariable().getName() + "_flux_" + membraneSubdomain.getName();
                                VCCGeomFeature selection = surfaceclassNameFeatureMap.get(membraneSubdomain.getName());
                                VCCFluxBoundary fluxBoundary = new VCCFluxBoundary(name, selection, vcellDim - 1);
                                fluxBoundary.flux_g = MathUtilities.substituteModelParameters(fluxExpr, symbolTable).flatten().infix();
                                cdeq.features.add(fluxBoundary);
                            }
                        }
                    }
                }
                model.physics.add(cdeq);
            }
        }
    }
    // 
    return model;
}
Also used : JumpCondition(cbit.vcell.math.JumpCondition) MembraneSubDomain(cbit.vcell.math.MembraneSubDomain) MathDescription(cbit.vcell.math.MathDescription) HashMap(java.util.HashMap) SurfaceClass(cbit.vcell.geometry.SurfaceClass) VCCConvectionDiffusionEquation(org.vcell.solver.comsol.model.VCCConvectionDiffusionEquation) CSGNode(cbit.vcell.geometry.CSGNode) ArrayList(java.util.ArrayList) VCCFluxBoundary(org.vcell.solver.comsol.model.VCCPhysicsFeature.VCCFluxBoundary) GeometrySpec(cbit.vcell.geometry.GeometrySpec) CompartmentSubDomain(cbit.vcell.math.CompartmentSubDomain) SubDomain(cbit.vcell.math.SubDomain) MembraneSubDomain(cbit.vcell.math.MembraneSubDomain) PdeEquation(cbit.vcell.math.PdeEquation) TimeBounds(cbit.vcell.solver.TimeBounds) TimeStep(cbit.vcell.solver.TimeStep) SubVolume(cbit.vcell.geometry.SubVolume) VCCStudyFeature(org.vcell.solver.comsol.model.VCCStudyFeature) CSGObject(cbit.vcell.geometry.CSGObject) VCCGeomFeature(org.vcell.solver.comsol.model.VCCGeomFeature) VCCDifference(org.vcell.solver.comsol.model.VCCGeomFeature.VCCDifference) VCCGeomSequence(org.vcell.solver.comsol.model.VCCGeomSequence) VCCIntersectionSelection(org.vcell.solver.comsol.model.VCCGeomFeature.VCCIntersectionSelection) SimulationSymbolTable(cbit.vcell.solver.SimulationSymbolTable) VCCConvectionDiffusionEquation(org.vcell.solver.comsol.model.VCCConvectionDiffusionEquation) OdeEquation(cbit.vcell.math.OdeEquation) PdeEquation(cbit.vcell.math.PdeEquation) Equation(cbit.vcell.math.Equation) VCCModelNode(org.vcell.solver.comsol.model.VCCModelNode) VCCTransientStudyFeature(org.vcell.solver.comsol.model.VCCTransientStudyFeature) VCCMeshSequence(org.vcell.solver.comsol.model.VCCMeshSequence) Geometry(cbit.vcell.geometry.Geometry) VCCStudy(org.vcell.solver.comsol.model.VCCStudy) OdeEquation(cbit.vcell.math.OdeEquation) Expression(cbit.vcell.parser.Expression) CompartmentSubDomain(cbit.vcell.math.CompartmentSubDomain) VCCModel(org.vcell.solver.comsol.model.VCCModel)

Example 27 with TimeBounds

use of cbit.vcell.solver.TimeBounds in project vcell by virtualcell.

the class NFSimSolver method getMathExecutableCommand.

@Override
protected String[] getMathExecutableCommand() {
    String executableName = null;
    try {
        executableName = SolverUtilities.getExes(SolverDescription.NFSim)[0].getAbsolutePath();
    } catch (IOException e) {
        throw new RuntimeException("failed to get executable for solver " + SolverDescription.NFSim.getDisplayLabel() + ": " + e.getMessage(), e);
    }
    String inputFilename = getInputFilename();
    String outputFilename = getOutputFilename();
    String speciesOutputFilename = getSpeciesOutputFilename();
    NFsimSimulationOptions nfsso = simTask.getSimulation().getSolverTaskDescription().getNFSimSimulationOptions();
    ArrayList<String> adv = new ArrayList<String>();
    boolean observableComputationOff = nfsso.getObservableComputationOff();
    if (observableComputationOff == true) {
        // false is by default, no need to specify
        adv.add("-notf");
    }
    Integer moleculeDistance = nfsso.getMoleculeDistance();
    if (moleculeDistance != null) {
        adv.add("-utl");
        adv.add(moleculeDistance + "");
    }
    boolean aggregateBookkeeping = nfsso.getAggregateBookkeeping();
    if (aggregateBookkeeping == true || simTask.getSimulation().getMathDescription().hasSpeciesObservable()) {
        // false is by default, no need to specify
        adv.add("-cb");
    }
    Integer maxMoleculesPerType = nfsso.getMaxMoleculesPerType();
    if (maxMoleculesPerType != null) {
        adv.add("-gml");
        adv.add(maxMoleculesPerType + "");
    }
    Integer equilibrateTime = nfsso.getEquilibrateTime();
    if (equilibrateTime != null) {
        adv.add("-eq");
        adv.add(equilibrateTime + "");
    }
    boolean preventIntraBonds = nfsso.getPreventIntraBonds();
    if (preventIntraBonds == true) {
        // false is by default, no need to specify
        adv.add("-bscb");
    }
    TimeBounds tb = getSimulationJob().getSimulation().getSolverTaskDescription().getTimeBounds();
    double dtime = tb.getEndingTime() - tb.getStartingTime();
    String timeSpecOption1 = "-oSteps";
    String timeSpecOption2 = "10";
    OutputTimeSpec outputTimeSpec = getSimulationJob().getSimulation().getSolverTaskDescription().getOutputTimeSpec();
    if (outputTimeSpec instanceof DefaultOutputTimeSpec) {
        DefaultOutputTimeSpec dots = (DefaultOutputTimeSpec) outputTimeSpec;
        int steps = dots.getKeepAtMost();
        timeSpecOption1 = "-oSteps";
        timeSpecOption2 = Integer.toString(steps);
    } else if (outputTimeSpec instanceof UniformOutputTimeSpec) {
        UniformOutputTimeSpec dots = (UniformOutputTimeSpec) outputTimeSpec;
        double steps = dtime / dots.getOutputTimeStep();
        timeSpecOption1 = "-oSteps";
        int stepsi = (int) Math.round(steps);
        timeSpecOption2 = Integer.toString(stepsi);
    } else {
        throw new RuntimeException("Unsupported output time spec class");
    }
    String[] baseCommands = { "-xml", inputFilename, "-o", outputFilename, "-sim", Double.toString(dtime), "-ss", speciesOutputFilename };
    ArrayList<String> cmds = new ArrayList<String>();
    cmds.add(executableName);
    Integer seed = nfsso.getRandomSeed();
    if (seed != null) {
        cmds.add("-seed");
        cmds.add(seed.toString());
    } else {
        long randomSeed = System.currentTimeMillis();
        randomSeed = randomSeed + simTask.getSimulationJob().getJobIndex();
        // multiply with a large prime number to spread numbers that are too close and in sequence
        randomSeed = randomSeed * 89611;
        Integer rs = (int) randomSeed;
        String str = rs.toString();
        if (str.startsWith("-")) {
            // NFSim wants a positive integer, for anything else is initializing with 0
            str = str.substring(1);
        }
        cmds.add("-seed");
        cmds.add(str);
    // PrintWriter writer;
    // try {
    // writer = new PrintWriter("c:\\TEMP\\aaa\\" + randomSeed + ".txt", "UTF-8");
    // writer.println(str);
    // writer.close();
    // } catch (FileNotFoundException | UnsupportedEncodingException e) {
    // // Auto-generated catch block
    // e.printStackTrace();
    // }
    }
    cmds.add("-vcell");
    cmds.addAll(new ArrayList<String>(Arrays.asList(baseCommands)));
    cmds.add(timeSpecOption1);
    cmds.add(timeSpecOption2);
    cmds.addAll(adv);
    if (bMessaging) {
        cmds.add("-v");
    }
    return cmds.toArray(new String[cmds.size()]);
}
Also used : NFsimSimulationOptions(cbit.vcell.solver.NFsimSimulationOptions) UniformOutputTimeSpec(cbit.vcell.solver.UniformOutputTimeSpec) ArrayList(java.util.ArrayList) IOException(java.io.IOException) TimeBounds(cbit.vcell.solver.TimeBounds) DefaultOutputTimeSpec(cbit.vcell.solver.DefaultOutputTimeSpec) UniformOutputTimeSpec(cbit.vcell.solver.UniformOutputTimeSpec) OutputTimeSpec(cbit.vcell.solver.OutputTimeSpec) DefaultOutputTimeSpec(cbit.vcell.solver.DefaultOutputTimeSpec)

Example 28 with TimeBounds

use of cbit.vcell.solver.TimeBounds in project vcell by virtualcell.

the class Generate2DSimBioModelOp method generateBioModel.

public BioModel generateBioModel(Extent extent, ROI cellROI_2D, double[] timeStamps, Integer indexFirstPostbleach, double primaryDiffusionRate, double primaryFraction, double bleachMonitorRate, Double secondaryDiffusionRate, double secondaryFraction, Double bindingSiteConcentration, double bindingOnRate, double bindingOffRate, String extracellularName, String cytosolName, User owner, KeyValue simKey) throws PropertyVetoException, ExpressionException, ModelException, GeometryException, ImageException, MappingException, MathException, MatrixException {
    if (owner == null) {
        throw new IllegalArgumentException("Owner is not defined");
    }
    double df = primaryDiffusionRate;
    double ff = primaryFraction;
    double bwmRate = bleachMonitorRate;
    double dc = 0.0;
    double fc = 0.0;
    if (secondaryDiffusionRate != null) {
        dc = secondaryDiffusionRate;
        fc = secondaryFraction;
    }
    double bs = 0.0;
    double onRate = 0.0;
    double offRate = 0.0;
    if (bindingSiteConcentration != null) {
        bs = bindingSiteConcentration;
        onRate = bindingOnRate;
        offRate = bindingOffRate;
    }
    // immobile fraction
    double fimm = 1 - ff - fc;
    if (fimm < epsilon && fimm > (0 - epsilon)) {
        fimm = 0;
    }
    if (fimm < (1 + epsilon) && fimm > (1 - epsilon)) {
        fimm = 1;
    }
    int startingIndexForRecovery = indexFirstPostbleach;
    TimeBounds timeBounds = new TimeBounds(0.0, timeStamps[timeStamps.length - 1] - timeStamps[startingIndexForRecovery]);
    double timeStepVal = timeStamps[startingIndexForRecovery + 1] - timeStamps[startingIndexForRecovery];
    ROI cellROI = cellROI_2D;
    int numX = cellROI.getISize().getX();
    int numY = cellROI.getISize().getY();
    int numZ = cellROI.getISize().getZ();
    short[] shortPixels = cellROI.getRoiImages()[0].getPixels();
    byte[] bytePixels = new byte[numX * numY * numZ];
    final byte EXTRACELLULAR_PIXVAL = 0;
    final byte CYTOSOL_PIXVAL = 1;
    for (int i = 0; i < bytePixels.length; i++) {
        if (shortPixels[i] != 0) {
            bytePixels[i] = CYTOSOL_PIXVAL;
        }
    }
    VCImage maskImage;
    try {
        maskImage = new VCImageUncompressed(null, bytePixels, extent, numX, numY, numZ);
    } catch (ImageException e) {
        e.printStackTrace();
        throw new RuntimeException("failed to create mask image for geometry");
    }
    Geometry geometry = new Geometry("geometry", maskImage);
    if (geometry.getGeometrySpec().getNumSubVolumes() != 2) {
        throw new IllegalArgumentException("Cell ROI has no ExtraCellular.");
    }
    String EXTRACELLULAR_NAME = extracellularName;
    String CYTOSOL_NAME = cytosolName;
    int subVolume0PixVal = ((ImageSubVolume) geometry.getGeometrySpec().getSubVolume(0)).getPixelValue();
    geometry.getGeometrySpec().getSubVolume(0).setName((subVolume0PixVal == EXTRACELLULAR_PIXVAL ? EXTRACELLULAR_NAME : CYTOSOL_NAME));
    int subVolume1PixVal = ((ImageSubVolume) geometry.getGeometrySpec().getSubVolume(1)).getPixelValue();
    geometry.getGeometrySpec().getSubVolume(1).setName((subVolume1PixVal == CYTOSOL_PIXVAL ? CYTOSOL_NAME : EXTRACELLULAR_NAME));
    geometry.getGeometrySurfaceDescription().updateAll();
    BioModel bioModel = new BioModel(null);
    bioModel.setName("unnamed");
    Model model = new Model("model");
    bioModel.setModel(model);
    model.addFeature(EXTRACELLULAR_NAME);
    Feature extracellular = (Feature) model.getStructure(EXTRACELLULAR_NAME);
    model.addFeature(CYTOSOL_NAME);
    Feature cytosol = (Feature) model.getStructure(CYTOSOL_NAME);
    // Membrane mem = model.addMembrane(EXTRACELLULAR_CYTOSOL_MEM_NAME);
    // model.getStructureTopology().setInsideFeature(mem, cytosol);
    // model.getStructureTopology().setOutsideFeature(mem, extracellular);
    String roiDataName = ROI_EXTDATA_NAME;
    final int SPECIES_COUNT = 4;
    final int FREE_SPECIES_INDEX = 0;
    final int BS_SPECIES_INDEX = 1;
    final int COMPLEX_SPECIES_INDEX = 2;
    final int IMMOBILE_SPECIES_INDEX = 3;
    Expression[] diffusionConstants = null;
    Species[] species = null;
    SpeciesContext[] speciesContexts = null;
    Expression[] initialConditions = null;
    diffusionConstants = new Expression[SPECIES_COUNT];
    species = new Species[SPECIES_COUNT];
    speciesContexts = new SpeciesContext[SPECIES_COUNT];
    initialConditions = new Expression[SPECIES_COUNT];
    // total initial condition
    FieldFunctionArguments postBleach_first = new FieldFunctionArguments(roiDataName, "postbleach_first", new Expression(0), VariableType.VOLUME);
    FieldFunctionArguments prebleach_avg = new FieldFunctionArguments(roiDataName, "prebleach_avg", new Expression(0), VariableType.VOLUME);
    Expression expPostBleach_first = new Expression(postBleach_first.infix());
    Expression expPreBleach_avg = new Expression(prebleach_avg.infix());
    Expression totalIniCondition = Expression.div(expPostBleach_first, expPreBleach_avg);
    // Free Species
    diffusionConstants[FREE_SPECIES_INDEX] = new Expression(df);
    species[FREE_SPECIES_INDEX] = new Species(SPECIES_NAME_PREFIX_MOBILE, "Mobile bleachable species");
    speciesContexts[FREE_SPECIES_INDEX] = new SpeciesContext(null, species[FREE_SPECIES_INDEX].getCommonName(), species[FREE_SPECIES_INDEX], cytosol);
    initialConditions[FREE_SPECIES_INDEX] = Expression.mult(new Expression(ff), totalIniCondition);
    // Immobile Species (No diffusion)
    // Set very small diffusion rate on immobile to force evaluation as state variable (instead of FieldData function)
    // If left as a function errors occur because functions involving FieldData require a database connection
    final String IMMOBILE_DIFFUSION_KLUDGE = "1e-14";
    diffusionConstants[IMMOBILE_SPECIES_INDEX] = new Expression(IMMOBILE_DIFFUSION_KLUDGE);
    species[IMMOBILE_SPECIES_INDEX] = new Species(SPECIES_NAME_PREFIX_IMMOBILE, "Immobile bleachable species");
    speciesContexts[IMMOBILE_SPECIES_INDEX] = new SpeciesContext(null, species[IMMOBILE_SPECIES_INDEX].getCommonName(), species[IMMOBILE_SPECIES_INDEX], cytosol);
    initialConditions[IMMOBILE_SPECIES_INDEX] = Expression.mult(new Expression(fimm), totalIniCondition);
    // BS Species
    diffusionConstants[BS_SPECIES_INDEX] = new Expression(IMMOBILE_DIFFUSION_KLUDGE);
    species[BS_SPECIES_INDEX] = new Species(SPECIES_NAME_PREFIX_BINDING_SITE, "Binding Site species");
    speciesContexts[BS_SPECIES_INDEX] = new SpeciesContext(null, species[BS_SPECIES_INDEX].getCommonName(), species[BS_SPECIES_INDEX], cytosol);
    initialConditions[BS_SPECIES_INDEX] = Expression.mult(new Expression(bs), totalIniCondition);
    // Complex species
    diffusionConstants[COMPLEX_SPECIES_INDEX] = new Expression(dc);
    species[COMPLEX_SPECIES_INDEX] = new Species(SPECIES_NAME_PREFIX_SLOW_MOBILE, "Slower mobile bleachable species");
    speciesContexts[COMPLEX_SPECIES_INDEX] = new SpeciesContext(null, species[COMPLEX_SPECIES_INDEX].getCommonName(), species[COMPLEX_SPECIES_INDEX], cytosol);
    initialConditions[COMPLEX_SPECIES_INDEX] = Expression.mult(new Expression(fc), totalIniCondition);
    // add reactions to species if there is bleachWhileMonitoring rate.
    for (int i = 0; i < initialConditions.length; i++) {
        model.addSpecies(species[i]);
        model.addSpeciesContext(speciesContexts[i]);
        // reaction with BMW rate, which should not be applied to binding site
        if (!(species[i].getCommonName().equals(SPECIES_NAME_PREFIX_BINDING_SITE))) {
            SimpleReaction simpleReaction = new SimpleReaction(model, cytosol, speciesContexts[i].getName() + "_bleach", true);
            model.addReactionStep(simpleReaction);
            simpleReaction.addReactant(speciesContexts[i], 1);
            MassActionKinetics massActionKinetics = new MassActionKinetics(simpleReaction);
            simpleReaction.setKinetics(massActionKinetics);
            KineticsParameter kforward = massActionKinetics.getForwardRateParameter();
            simpleReaction.getKinetics().setParameterValue(kforward, new Expression(new Double(bwmRate)));
        }
    }
    // add the binding reaction: F + BS <-> C
    SimpleReaction simpleReaction2 = new SimpleReaction(model, cytosol, "reac_binding", true);
    model.addReactionStep(simpleReaction2);
    simpleReaction2.addReactant(speciesContexts[FREE_SPECIES_INDEX], 1);
    simpleReaction2.addReactant(speciesContexts[BS_SPECIES_INDEX], 1);
    simpleReaction2.addProduct(speciesContexts[COMPLEX_SPECIES_INDEX], 1);
    MassActionKinetics massActionKinetics = new MassActionKinetics(simpleReaction2);
    simpleReaction2.setKinetics(massActionKinetics);
    KineticsParameter kforward = massActionKinetics.getForwardRateParameter();
    KineticsParameter kreverse = massActionKinetics.getReverseRateParameter();
    simpleReaction2.getKinetics().setParameterValue(kforward, new Expression(new Double(onRate)));
    simpleReaction2.getKinetics().setParameterValue(kreverse, new Expression(new Double(offRate)));
    // create simulation context
    SimulationContext simContext = new SimulationContext(bioModel.getModel(), geometry);
    bioModel.addSimulationContext(simContext);
    FeatureMapping cytosolFeatureMapping = (FeatureMapping) simContext.getGeometryContext().getStructureMapping(cytosol);
    FeatureMapping extracellularFeatureMapping = (FeatureMapping) simContext.getGeometryContext().getStructureMapping(extracellular);
    SubVolume cytSubVolume = geometry.getGeometrySpec().getSubVolume(CYTOSOL_NAME);
    SubVolume exSubVolume = geometry.getGeometrySpec().getSubVolume(EXTRACELLULAR_NAME);
    SurfaceClass pmSurfaceClass = geometry.getGeometrySurfaceDescription().getSurfaceClass(exSubVolume, cytSubVolume);
    cytosolFeatureMapping.setGeometryClass(cytSubVolume);
    extracellularFeatureMapping.setGeometryClass(exSubVolume);
    cytosolFeatureMapping.getUnitSizeParameter().setExpression(new Expression(1.0));
    extracellularFeatureMapping.getUnitSizeParameter().setExpression(new Expression(1.0));
    for (int i = 0; i < speciesContexts.length; i++) {
        SpeciesContextSpec scs = simContext.getReactionContext().getSpeciesContextSpec(speciesContexts[i]);
        scs.getInitialConditionParameter().setExpression(initialConditions[i]);
        scs.getDiffusionParameter().setExpression(diffusionConstants[i]);
    }
    MathMapping mathMapping = simContext.createNewMathMapping();
    MathDescription mathDesc = mathMapping.getMathDescription();
    // Add total fluorescence as function of mobile(optional: and slower mobile) and immobile fractions
    mathDesc.addVariable(new Function(SPECIES_NAME_PREFIX_COMBINED, new Expression(species[FREE_SPECIES_INDEX].getCommonName() + "+" + species[COMPLEX_SPECIES_INDEX].getCommonName() + "+" + species[IMMOBILE_SPECIES_INDEX].getCommonName()), null));
    simContext.setMathDescription(mathDesc);
    SimulationVersion simVersion = new SimulationVersion(simKey, "sim1", owner, new GroupAccessNone(), new KeyValue("0"), new BigDecimal(0), new Date(), VersionFlag.Current, "", null);
    Simulation newSimulation = new Simulation(simVersion, mathDesc);
    simContext.addSimulation(newSimulation);
    newSimulation.getSolverTaskDescription().setTimeBounds(timeBounds);
    newSimulation.getMeshSpecification().setSamplingSize(cellROI.getISize());
    // newSimulation.getSolverTaskDescription().setTimeStep(timeStep); // Sundials doesn't need time step
    newSimulation.getSolverTaskDescription().setSolverDescription(SolverDescription.SundialsPDE);
    // use exp time step as output time spec
    newSimulation.getSolverTaskDescription().setOutputTimeSpec(new UniformOutputTimeSpec(timeStepVal));
    return bioModel;
}
Also used : ImageException(cbit.image.ImageException) KeyValue(org.vcell.util.document.KeyValue) SurfaceClass(cbit.vcell.geometry.SurfaceClass) MathDescription(cbit.vcell.math.MathDescription) VCImage(cbit.image.VCImage) SpeciesContext(cbit.vcell.model.SpeciesContext) SpeciesContextSpec(cbit.vcell.mapping.SpeciesContextSpec) Feature(cbit.vcell.model.Feature) TimeBounds(cbit.vcell.solver.TimeBounds) Function(cbit.vcell.math.Function) GroupAccessNone(org.vcell.util.document.GroupAccessNone) SimulationVersion(org.vcell.util.document.SimulationVersion) KineticsParameter(cbit.vcell.model.Kinetics.KineticsParameter) FeatureMapping(cbit.vcell.mapping.FeatureMapping) SubVolume(cbit.vcell.geometry.SubVolume) ImageSubVolume(cbit.vcell.geometry.ImageSubVolume) Species(cbit.vcell.model.Species) ImageSubVolume(cbit.vcell.geometry.ImageSubVolume) SimpleReaction(cbit.vcell.model.SimpleReaction) UniformOutputTimeSpec(cbit.vcell.solver.UniformOutputTimeSpec) FieldFunctionArguments(cbit.vcell.field.FieldFunctionArguments) VCImageUncompressed(cbit.image.VCImageUncompressed) SimulationContext(cbit.vcell.mapping.SimulationContext) ROI(cbit.vcell.VirtualMicroscopy.ROI) BigDecimal(java.math.BigDecimal) Date(java.util.Date) Geometry(cbit.vcell.geometry.Geometry) Simulation(cbit.vcell.solver.Simulation) Expression(cbit.vcell.parser.Expression) BioModel(cbit.vcell.biomodel.BioModel) BioModel(cbit.vcell.biomodel.BioModel) Model(cbit.vcell.model.Model) MathMapping(cbit.vcell.mapping.MathMapping) MassActionKinetics(cbit.vcell.model.MassActionKinetics)

Aggregations

TimeBounds (cbit.vcell.solver.TimeBounds)28 Simulation (cbit.vcell.solver.Simulation)16 UniformOutputTimeSpec (cbit.vcell.solver.UniformOutputTimeSpec)15 Expression (cbit.vcell.parser.Expression)10 BioModel (cbit.vcell.biomodel.BioModel)9 SimulationContext (cbit.vcell.mapping.SimulationContext)8 KeyValue (org.vcell.util.document.KeyValue)8 MathMapping (cbit.vcell.mapping.MathMapping)7 MathDescription (cbit.vcell.math.MathDescription)7 TimeStep (cbit.vcell.solver.TimeStep)7 ArrayList (java.util.ArrayList)7 SimulationVersion (org.vcell.util.document.SimulationVersion)7 Model (cbit.vcell.model.Model)6 DefaultOutputTimeSpec (cbit.vcell.solver.DefaultOutputTimeSpec)6 OutputTimeSpec (cbit.vcell.solver.OutputTimeSpec)6 IOException (java.io.IOException)6 Geometry (cbit.vcell.geometry.Geometry)5 SubVolume (cbit.vcell.geometry.SubVolume)5 SpeciesContext (cbit.vcell.model.SpeciesContext)5 SolverTaskDescription (cbit.vcell.solver.SolverTaskDescription)5