Search in sources :

Example 81 with VCUnitDefinition

use of cbit.vcell.units.VCUnitDefinition in project vcell by virtualcell.

the class ElectricalStimulus method parameterVCMLSet.

/**
 * This method was created by a SmartGuide.
 * @param tokens java.util.StringTokenizer
 * @exception java.lang.Exception The exception description.
 */
public final void parameterVCMLSet(CommentStringTokenizer tokens) throws ExpressionException, PropertyVetoException {
    if (tokens == null) {
        return;
    }
    Vector<LocalParameter> esParametersV = new Vector<LocalParameter>();
    if (!tokens.nextToken().equalsIgnoreCase(VCMODL.ElectricalStimulus) || !tokens.nextToken().equalsIgnoreCase(GENERAL_PROTOCOL) || !tokens.nextToken().equalsIgnoreCase(VCMODL.BeginBlock)) {
        throw new RuntimeException(ElectricalStimulus.class.getName() + ".parameterVCMLRead, unexpected token ");
    }
    String token = null;
    ModelUnitSystem modelUnitSystem = simulationContext.getModel().getUnitSystem();
    while (tokens.hasMoreTokens()) {
        token = tokens.nextToken();
        if (token.equalsIgnoreCase(VCMODL.EndBlock)) {
            break;
        }
        if (token.equalsIgnoreCase(VCMODL.Parameter)) {
            String roleName = tokens.nextToken();
            ElectricalStimulusParameterType parameterType = null;
            for (ElectricalStimulusParameterType role : ElectricalStimulusParameterType.values()) {
                if (roleName.equals(role.databaseRoleTag)) {
                    parameterType = role;
                    break;
                }
            }
            if (parameterType == null) {
                throw new RuntimeException(ElectricalStimulus.class.getName() + ".parameterVCMLRead, unexpected token for roleName " + roleName);
            }
            String parameterName = tokens.nextToken();
            Expression exp = MathFunctionDefinitions.fixFunctionSyntax(tokens);
            String unitsString = tokens.nextToken();
            VCUnitDefinition unitDef = modelUnitSystem.getInstance_TBD();
            if (unitsString.startsWith("[")) {
                while (!unitsString.endsWith("]")) {
                    String tempToken = tokens.nextToken();
                    unitsString = unitsString + " " + tempToken;
                }
                // 
                // now string starts with '[' and ends with ']'
                // 
                unitDef = modelUnitSystem.getInstance(unitsString.substring(1, unitsString.length() - 1));
            } else {
                tokens.pushToken(unitsString);
            }
            LocalParameter esp = parameterContext.new LocalParameter(parameterName, exp, parameterType, unitDef, parameterType.databaseRoleTag);
            esParametersV.add(esp);
        } else {
            throw new RuntimeException(ElectricalStimulus.class.getName() + ".parameterVCMLRead, unexpected token for paramter tag " + token);
        }
    }
    if (esParametersV.size() > 0) {
        LocalParameter[] espArr = new LocalParameter[esParametersV.size()];
        esParametersV.copyInto(espArr);
        parameterContext.setLocalParameters(espArr);
    } else {
        parameterContext.setLocalParameters(null);
    }
}
Also used : LocalParameter(cbit.vcell.mapping.ParameterContext.LocalParameter) VCUnitDefinition(cbit.vcell.units.VCUnitDefinition) Expression(cbit.vcell.parser.Expression) Vector(java.util.Vector) ModelUnitSystem(cbit.vcell.model.ModelUnitSystem)

Example 82 with VCUnitDefinition

use of cbit.vcell.units.VCUnitDefinition in project vcell by virtualcell.

the class MembraneStructureAnalyzer method refreshResolvedFluxes.

/**
 * This method was created in VisualAge.
 */
private void refreshResolvedFluxes() throws Exception {
    // System.out.println("MembraneStructureAnalyzer.refreshResolvedFluxes()");
    ModelUnitSystem unitSystem = mathMapping.getSimulationContext().getModel().getUnitSystem();
    GeometryContext geoContext = mathMapping.getSimulationContext().getGeometryContext();
    Vector<ResolvedFlux> resolvedFluxList = new Vector<ResolvedFlux>();
    // 
    // for each reaction, get all fluxReactions associated with this membrane
    // 
    Vector<FluxReaction> fluxList = new Vector<FluxReaction>();
    ReactionSpec[] reactionSpecs = mathMapping.getSimulationContext().getReactionContext().getReactionSpecs();
    for (int j = 0; j < reactionSpecs.length; j++) {
        if (reactionSpecs[j].isExcluded()) {
            continue;
        }
        ReactionStep rs = reactionSpecs[j].getReactionStep();
        if (rs.getStructure() != null && geoContext.getStructureMapping(rs.getStructure()).getGeometryClass() == surfaceClass) {
            if (rs instanceof FluxReaction) {
                fluxList.addElement((FluxReaction) rs);
            }
        }
    }
    // 
    for (int i = 0; i < fluxList.size(); i++) {
        FluxReaction fr = fluxList.elementAt(i);
        ReactionParticipant[] reactionParticipants = fr.getReactionParticipants();
        for (int j = 0; j < reactionParticipants.length; j++) {
            if (!(reactionParticipants[j] instanceof Reactant) && !(reactionParticipants[j] instanceof Product)) {
                continue;
            }
            ResolvedFlux rf = null;
            SpeciesContext speciesContext = reactionParticipants[j].getSpeciesContext();
            for (int k = 0; k < resolvedFluxList.size(); k++) {
                ResolvedFlux rf_tmp = resolvedFluxList.elementAt(k);
                if (rf_tmp.getSpeciesContext() == reactionParticipants[j].getSpeciesContext()) {
                    rf = rf_tmp;
                }
            }
            // 
            // if speciesContext is not "fixed" and is mapped to a volume, add flux to ResolvedFlux
            // 
            StructureMapping structureMapping = mathMapping.getSimulationContext().getGeometryContext().getStructureMapping(reactionParticipants[j].getStructure());
            if (structureMapping.getGeometryClass() == surfaceClass) {
                // flux within surface
                continue;
            }
            if (structureMapping.getGeometryClass() instanceof SubVolume && surfaceClass.isAdjacentTo((SubVolume) structureMapping.getGeometryClass())) {
                SpeciesContextSpec speciesContextSpec = mathMapping.getSimulationContext().getReactionContext().getSpeciesContextSpec(speciesContext);
                if (!speciesContextSpec.isConstant()) {
                    if (rf == null) {
                        VCUnitDefinition speciesFluxUnit = speciesContext.getUnitDefinition().multiplyBy(unitSystem.getLengthUnit()).divideBy(unitSystem.getTimeUnit());
                        rf = new ResolvedFlux(speciesContext, speciesFluxUnit);
                        resolvedFluxList.addElement(rf);
                    }
                    FeatureMapping featureMapping = (FeatureMapping) structureMapping;
                    Expression insideFluxCorrection = Expression.invert(new Expression(featureMapping.getVolumePerUnitVolumeParameter(), mathMapping.getNameScope()));
                    // 
                    if (fr.getKinetics() instanceof DistributedKinetics) {
                        KineticsParameter reactionRateParameter = ((DistributedKinetics) fr.getKinetics()).getReactionRateParameter();
                        Expression correctedReactionRate = Expression.mult(new Expression(reactionRateParameter, mathMapping.getNameScope()), insideFluxCorrection);
                        if (reactionParticipants[j] instanceof Product) {
                            if (rf.getFluxExpression().isZero()) {
                                rf.setFluxExpression(correctedReactionRate.flatten());
                            } else {
                                rf.setFluxExpression(Expression.add(rf.getFluxExpression(), correctedReactionRate.flatten()));
                            }
                        } else if (reactionParticipants[j] instanceof Reactant) {
                            if (rf.getFluxExpression().isZero()) {
                                rf.setFluxExpression(Expression.negate(correctedReactionRate).flatten());
                            } else {
                                rf.setFluxExpression(Expression.add(rf.getFluxExpression(), Expression.negate(correctedReactionRate).flatten()));
                            }
                        } else {
                            throw new RuntimeException("expected either FluxReactant or FluxProduct");
                        }
                    } else if (fr.getKinetics() instanceof LumpedKinetics) {
                        throw new RuntimeException("Lumped Kinetics for fluxes not yet supported");
                    } else {
                        throw new RuntimeException("unexpected Kinetic type in MembraneStructureAnalyzer.refreshResolvedFluxes()");
                    }
                    rf.getFluxExpression().bindExpression(mathMapping);
                }
            }
        }
    }
    // 
    for (int i = 0; i < reactionSpecs.length; i++) {
        if (reactionSpecs[i].isExcluded()) {
            continue;
        }
        ReactionStep rs = reactionSpecs[i].getReactionStep();
        if (rs.getStructure() != null && geoContext.getStructureMapping(rs.getStructure()).getGeometryClass() == surfaceClass) {
            if (rs instanceof SimpleReaction) {
                SimpleReaction sr = (SimpleReaction) rs;
                ReactionParticipant[] rp_Array = sr.getReactionParticipants();
                for (int k = 0; k < rp_Array.length; k++) {
                    if (rp_Array[k] instanceof Reactant || rp_Array[k] instanceof Product) {
                        SpeciesContextSpec rpSCS = mathMapping.getSimulationContext().getReactionContext().getSpeciesContextSpec(rp_Array[k].getSpeciesContext());
                        StructureMapping rpSM = mathMapping.getSimulationContext().getGeometryContext().getStructureMapping(rp_Array[k].getStructure());
                        if (rpSM.getGeometryClass() instanceof SubVolume && !rpSCS.isConstant()) {
                            // 
                            // get ResolvedFlux for this species
                            // 
                            ResolvedFlux rf = null;
                            for (int j = 0; j < resolvedFluxList.size(); j++) {
                                ResolvedFlux rf_tmp = (ResolvedFlux) resolvedFluxList.elementAt(j);
                                if (rf_tmp.getSpeciesContext() == rp_Array[k].getSpeciesContext()) {
                                    rf = rf_tmp;
                                }
                            }
                            if (rf == null) {
                                VCUnitDefinition speciesFluxUnit = rp_Array[k].getSpeciesContext().getUnitDefinition().multiplyBy(unitSystem.getLengthUnit()).divideBy(unitSystem.getTimeUnit());
                                rf = new ResolvedFlux(rp_Array[k].getSpeciesContext(), speciesFluxUnit);
                                resolvedFluxList.addElement(rf);
                            }
                            if (rpSM.getGeometryClass() instanceof SubVolume && surfaceClass.isAdjacentTo((SubVolume) rpSM.getGeometryClass())) {
                                // 
                                // for binding on inside or outside, add to ResolvedFlux.flux
                                // 
                                Expression fluxRateExpression = getCorrectedRateExpression(sr, rp_Array[k], RateType.ResolvedFluxRate).renameBoundSymbols(mathMapping.getNameScope());
                                if (rf.getFluxExpression().isZero()) {
                                    rf.setFluxExpression(fluxRateExpression);
                                } else {
                                    rf.setFluxExpression(Expression.add(rf.getFluxExpression(), fluxRateExpression));
                                }
                                rf.getFluxExpression().bindExpression(mathMapping);
                            } else {
                                String structureName = ((rs.getStructure() != null) ? (rs.getStructure().getName()) : ("<null>"));
                                throw new Exception("In Application '" + mathMapping.getSimulationContext().getName() + "', SpeciesContext '" + rp_Array[k].getSpeciesContext().getName() + "' is not mapped adjacent to structure '" + structureName + "' but reacts there");
                            }
                        }
                    }
                }
            }
        }
    }
    // 
    if (resolvedFluxList.size() > 0) {
        resolvedFluxes = new ResolvedFlux[resolvedFluxList.size()];
        resolvedFluxList.copyInto(resolvedFluxes);
    } else {
        resolvedFluxes = null;
    }
}
Also used : LumpedKinetics(cbit.vcell.model.LumpedKinetics) Product(cbit.vcell.model.Product) FluxReaction(cbit.vcell.model.FluxReaction) SpeciesContext(cbit.vcell.model.SpeciesContext) Reactant(cbit.vcell.model.Reactant) KineticsParameter(cbit.vcell.model.Kinetics.KineticsParameter) SubVolume(cbit.vcell.geometry.SubVolume) Vector(java.util.Vector) ModelUnitSystem(cbit.vcell.model.ModelUnitSystem) DistributedKinetics(cbit.vcell.model.DistributedKinetics) SimpleReaction(cbit.vcell.model.SimpleReaction) VCUnitDefinition(cbit.vcell.units.VCUnitDefinition) Expression(cbit.vcell.parser.Expression) ReactionStep(cbit.vcell.model.ReactionStep) ReactionParticipant(cbit.vcell.model.ReactionParticipant)

Example 83 with VCUnitDefinition

use of cbit.vcell.units.VCUnitDefinition in project vcell by virtualcell.

the class ParameterContext method resolveUndefinedUnits.

public void resolveUndefinedUnits() {
    // 
    if (!bResolvingUnits) {
        VCUnitSystem unitSystem = unitSystemProvider.getUnitSystem();
        try {
            bResolvingUnits = true;
            boolean bAnyTBDUnits = false;
            for (int i = 0; i < fieldParameters.length; i++) {
                if (fieldParameters[i].getUnitDefinition() == null) {
                    // not ready to resolve units yet
                    return;
                } else if (fieldParameters[i].getUnitDefinition().isTBD()) {
                    bAnyTBDUnits = true;
                }
            }
            // 
            if (bAnyTBDUnits) {
                VCUnitEvaluator unitEvaluator = new VCUnitEvaluator(unitSystem);
                VCUnitDefinition[] vcUnitDefinitions = unitEvaluator.suggestUnitDefinitions(fieldParameters);
                for (int i = 0; i < fieldParameters.length; i++) {
                    if (!fieldParameters[i].getUnitDefinition().isEquivalent(vcUnitDefinitions[i])) {
                        fieldParameters[i].setUnitDefinition(vcUnitDefinitions[i]);
                    }
                }
            // System.out.println("successfully completed Kinetics.resolveUndefinedUnits() for ReactionStep '"+getReactionStep()+"'");
            }
        } catch (ExpressionBindingException e) {
            System.out.println("ParameterContext.resolveUndefinedUnits(): EXCEPTION: " + e.getMessage());
        } catch (Exception e) {
            System.out.println("ParameterContext.resolveUndefinedUnits(): EXCEPTION: " + e.getMessage());
        } finally {
            bResolvingUnits = false;
        }
    }
}
Also used : VCUnitEvaluator(cbit.vcell.parser.VCUnitEvaluator) VCUnitSystem(cbit.vcell.units.VCUnitSystem) VCUnitDefinition(cbit.vcell.units.VCUnitDefinition) ExpressionBindingException(cbit.vcell.parser.ExpressionBindingException) VCUnitException(cbit.vcell.units.VCUnitException) PropertyVetoException(java.beans.PropertyVetoException) ExpressionException(cbit.vcell.parser.ExpressionException) ExpressionBindingException(cbit.vcell.parser.ExpressionBindingException)

Example 84 with VCUnitDefinition

use of cbit.vcell.units.VCUnitDefinition in project vcell by virtualcell.

the class ParticleMathMapping method combineHybrid.

private void combineHybrid() throws MappingException, ExpressionException, MatrixException, MathException, ModelException {
    ArrayList<SpeciesContext> continuousSpecies = new ArrayList<SpeciesContext>();
    ArrayList<ParticleVariable> continuousSpeciesParticleVars = new ArrayList<ParticleVariable>();
    ArrayList<SpeciesContext> stochSpecies = new ArrayList<SpeciesContext>();
    // 
    // categorize speciesContexts as continuous and stochastic
    // 
    SpeciesContextSpec[] scsArray = getSimulationContext().getReactionContext().getSpeciesContextSpecs();
    continuousSpecies = new ArrayList<SpeciesContext>();
    stochSpecies = new ArrayList<SpeciesContext>();
    for (SpeciesContextSpec speciesContextSpec : scsArray) {
        if (!getSimulationContext().isStoch() || speciesContextSpec.isForceContinuous()) {
            continuousSpecies.add(speciesContextSpec.getSpeciesContext());
            Variable variable = getMathSymbolMapping().getVariable(speciesContextSpec.getSpeciesContext());
            if (variable instanceof ParticleVariable) {
                continuousSpeciesParticleVars.add((ParticleVariable) variable);
            }
        } else {
            stochSpecies.add(speciesContextSpec.getSpeciesContext());
        }
    }
    if (continuousSpecies.isEmpty()) {
        return;
    }
    // 
    // create continuous mathDescription ... add stochastic variables and processes to the continuous Math and use this.
    // 
    DiffEquMathMapping mathMapping = new DiffEquMathMapping(getSimulationContext(), callback, networkGenerationRequirements);
    mathMapping.refresh(null);
    MathDescription contMathDesc = mathMapping.getMathDescription();
    // 
    // get list of all continuous variables
    // 
    HashMap<String, Variable> allContinuousVars = new HashMap<String, Variable>();
    Enumeration<Variable> enumVar = contMathDesc.getVariables();
    while (enumVar.hasMoreElements()) {
        Variable var = enumVar.nextElement();
        allContinuousVars.put(var.getName(), var);
    }
    // 
    // replace those continuous variables and equations for stochastic speciesContexts
    // with the particleVariables and particleProperties
    // (ParticleJumpProcesses removed later)
    // 
    ModelUnitSystem unitSystem = getSimulationContext().getModel().getUnitSystem();
    for (SpeciesContext stochSpeciesContext : stochSpecies) {
        Variable contVar = mathMapping.getMathSymbolMapping().getVariable(stochSpeciesContext);
        Variable stochVar = getMathSymbolMapping().getVariable(stochSpeciesContext);
        allContinuousVars.put(stochVar.getName(), stochVar);
        // 
        // replace continuous "concentration" VolVariable/MemVariable for this particle with a Function for concentration
        // 
        allContinuousVars.remove(contVar);
        VCUnitDefinition sizeUnit = unitSystem.getLengthUnit().raiseTo(new RationalNumber(stochSpeciesContext.getStructure().getDimension()));
        VCUnitDefinition stochasticDensityUnit = unitSystem.getStochasticSubstanceUnit().divideBy(sizeUnit);
        VCUnitDefinition continuousDensityUnit = unitSystem.getConcentrationUnit(stochSpeciesContext.getStructure());
        if (stochasticDensityUnit.isEquivalent(continuousDensityUnit)) {
            allContinuousVars.put(contVar.getName(), new Function(contVar.getName(), new Expression(stochVar, getNameScope()), contVar.getDomain()));
        } else {
            Expression conversionFactorExp = getUnitFactor(continuousDensityUnit.divideBy(stochasticDensityUnit));
            allContinuousVars.put(contVar.getName(), new Function(contVar.getName(), Expression.mult(new Expression(stochVar, getNameScope()), conversionFactorExp), contVar.getDomain()));
        }
        // 
        // remove continuous equation
        // 
        Enumeration<SubDomain> contSubDomains = contMathDesc.getSubDomains();
        while (contSubDomains.hasMoreElements()) {
            SubDomain contSubDomain = contSubDomains.nextElement();
            contSubDomain.removeEquation(contVar);
            if (contSubDomain instanceof MembraneSubDomain) {
                ((MembraneSubDomain) contSubDomain).removeJumpCondition(contVar);
            }
        }
        // 
        // remove all continuous variables for speciesContextSpec parameters (e.g. initial conditions, diffusion rates, boundary conditions, velocities)
        // 
        SpeciesContextSpec scs = getSimulationContext().getReactionContext().getSpeciesContextSpec(stochSpeciesContext);
        Parameter[] scsParameters = scs.getParameters();
        for (Parameter parameter : scsParameters) {
            Variable continuousScsParmVariable = mathMapping.getMathSymbolMapping().getVariable(parameter);
            allContinuousVars.remove(continuousScsParmVariable);
        }
        // 
        // copy ParticleJumpProcess and ParticleProperties to the continuous math
        // 
        SubDomain contSubDomain = contMathDesc.getSubDomain(contVar.getDomain().getName());
        SubDomain stochSubDomain = mathDesc.getSubDomain(stochVar.getDomain().getName());
        ParticleProperties particleProperties = stochSubDomain.getParticleProperties(stochVar);
        contSubDomain.addParticleProperties(particleProperties);
    }
    // 
    // add all ParticleJumpProcesses to the continuous model
    // 
    Enumeration<SubDomain> enumStochSubdomains = mathDesc.getSubDomains();
    while (enumStochSubdomains.hasMoreElements()) {
        SubDomain stochSubdomain = enumStochSubdomains.nextElement();
        SubDomain contSubdomain = contMathDesc.getSubDomain(stochSubdomain.getName());
        for (ParticleJumpProcess particleJumpProcess : stochSubdomain.getParticleJumpProcesses()) {
            // 
            // modify "selection list" (particleVariables), probability rate, and actions if referenced particleVariable is to be "forced continuous"
            // 
            ParticleVariable[] selectedParticles = particleJumpProcess.getParticleVariables();
            for (ParticleVariable particleVariable : selectedParticles) {
                if (continuousSpeciesParticleVars.contains(particleVariable)) {
                    particleJumpProcess.remove(particleVariable);
                    JumpProcessRateDefinition jumpProcessRateDefinition = particleJumpProcess.getParticleRateDefinition();
                    if (jumpProcessRateDefinition instanceof MacroscopicRateConstant) {
                        MacroscopicRateConstant macroscopicRateConstant = (MacroscopicRateConstant) jumpProcessRateDefinition;
                        macroscopicRateConstant.setExpression(Expression.mult(macroscopicRateConstant.getExpression(), new Expression(particleVariable, null)));
                    } else if (jumpProcessRateDefinition instanceof InteractionRadius) {
                        throw new MappingException("cannot adjust interaction radius for reaction process " + particleJumpProcess.getName() + ", particle " + particleVariable.getName() + " is continuous");
                    } else {
                        throw new MappingException("rate definition type " + jumpProcessRateDefinition.getClass().getSimpleName() + " not yet implemented for hybrid PDE/Particle math generation");
                    }
                }
                Iterator<Action> iterAction = particleJumpProcess.getActions().iterator();
                while (iterAction.hasNext()) {
                    Action action = iterAction.next();
                    if (continuousSpeciesParticleVars.contains(action.getVar())) {
                        iterAction.remove();
                    }
                }
            }
            if (!particleJumpProcess.getActions().isEmpty()) {
                contSubdomain.addParticleJumpProcess(particleJumpProcess);
            }
        }
    }
    // 
    for (MathMappingParameter mathMappingParameter : fieldMathMappingParameters) {
        if (mathMappingParameter instanceof UnitFactorParameter) {
            String name = mathMappingParameter.getName();
            if (!allContinuousVars.containsKey(name)) {
                allContinuousVars.put(name, newFunctionOrConstant(name, mathMappingParameter.getExpression(), null));
            }
        }
    }
    // 
    // add constants and functions from the particle math that aren't already defined in the continuous math
    // 
    Enumeration<Variable> enumVars = mathDesc.getVariables();
    while (enumVars.hasMoreElements()) {
        Variable var = enumVars.nextElement();
        if (var instanceof Constant || var instanceof Function) {
            String name = var.getName();
            if (!allContinuousVars.containsKey(name)) {
                allContinuousVars.put(name, var);
            }
        }
    }
    contMathDesc.setAllVariables(allContinuousVars.values().toArray(new Variable[0]));
    mathDesc = contMathDesc;
    // 
    for (int i = 0; i < fieldMathMappingParameters.length; i++) {
        if (fieldMathMappingParameters[i] instanceof UnitFactorParameter) {
            GeometryClass geometryClass = fieldMathMappingParameters[i].getGeometryClass();
            Variable variable = newFunctionOrConstant(getMathSymbol(fieldMathMappingParameters[i], geometryClass), getIdentifierSubstitutions(fieldMathMappingParameters[i].getExpression(), fieldMathMappingParameters[i].getUnitDefinition(), geometryClass), fieldMathMappingParameters[i].getGeometryClass());
            if (mathDesc.getVariable(variable.getName()) == null) {
                mathDesc.addVariable(variable);
            }
        }
    }
    if (!mathDesc.isValid()) {
        System.out.println(mathDesc.getVCML_database());
        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 : GeometryClass(cbit.vcell.geometry.GeometryClass) MembraneSubDomain(cbit.vcell.math.MembraneSubDomain) Action(cbit.vcell.math.Action) VolumeParticleVariable(cbit.vcell.math.VolumeParticleVariable) MembraneParticleVariable(cbit.vcell.math.MembraneParticleVariable) ParticleVariable(cbit.vcell.math.ParticleVariable) Variable(cbit.vcell.math.Variable) MathDescription(cbit.vcell.math.MathDescription) HashMap(java.util.HashMap) VolumeParticleVariable(cbit.vcell.math.VolumeParticleVariable) MembraneParticleVariable(cbit.vcell.math.MembraneParticleVariable) ParticleVariable(cbit.vcell.math.ParticleVariable) MacroscopicRateConstant(cbit.vcell.math.MacroscopicRateConstant) Constant(cbit.vcell.math.Constant) ArrayList(java.util.ArrayList) SpeciesContext(cbit.vcell.model.SpeciesContext) CompartmentSubDomain(cbit.vcell.math.CompartmentSubDomain) SubDomain(cbit.vcell.math.SubDomain) MembraneSubDomain(cbit.vcell.math.MembraneSubDomain) Function(cbit.vcell.math.Function) MacroscopicRateConstant(cbit.vcell.math.MacroscopicRateConstant) RationalNumber(ucar.units_vcell.RationalNumber) ModelUnitSystem(cbit.vcell.model.ModelUnitSystem) JumpProcessRateDefinition(cbit.vcell.math.JumpProcessRateDefinition) InteractionRadius(cbit.vcell.math.InteractionRadius) ParticleJumpProcess(cbit.vcell.math.ParticleJumpProcess) VCUnitDefinition(cbit.vcell.units.VCUnitDefinition) Expression(cbit.vcell.parser.Expression) StructureMappingParameter(cbit.vcell.mapping.StructureMapping.StructureMappingParameter) Parameter(cbit.vcell.model.Parameter) KineticsParameter(cbit.vcell.model.Kinetics.KineticsParameter) SpeciesContextSpecProxyParameter(cbit.vcell.mapping.SpeciesContextSpec.SpeciesContextSpecProxyParameter) ModelParameter(cbit.vcell.model.Model.ModelParameter) SpeciesContextSpecParameter(cbit.vcell.mapping.SpeciesContextSpec.SpeciesContextSpecParameter) ParticleProperties(cbit.vcell.math.ParticleProperties)

Example 85 with VCUnitDefinition

use of cbit.vcell.units.VCUnitDefinition in project vcell by virtualcell.

the class RulebasedMathMapping method addStrictMassActionParticleJumpProcess.

private void addStrictMassActionParticleJumpProcess(VariableHash varHash, GeometryClass geometryClass, SubDomain subDomain, ReactionRule reactionRule, String jpName, ArrayList<ParticleVariable> reactantParticles, ArrayList<ParticleVariable> productParticles, ArrayList<Action> forwardActions, ArrayList<Action> reverseActions) throws ExpressionException, ExpressionBindingException, PropertyVetoException, MathException, MappingException {
    String reactionRuleName = reactionRule.getName();
    RbmKineticLaw kinetics = reactionRule.getKineticLaw();
    RulebasedTransformation ruleBasedTransformation = ((RulebasedTransformation) getTransformation());
    if (kinetics.getRateLawType() != RbmKineticLaw.RateLawType.MassAction) {
        throw new RuntimeException("expecting mass action kinetics for reaction rule " + reactionRuleName);
    }
    // 
    // construct stochastic forward or reverse rate expression (separately).  Transform from
    // original expression of "concentrationRate" in terms of rateParameter and reactants/products in concentrations
    // to
    // new stochastic expression of "molecularRate" in terms of forwardRateParameter, reactants/products in molecules, structure sizes, and unit conversions.
    // 
    // (1)  concentrationRate = K * [s0] * [s1]    [uM.s-1]  or   [molecules.um-3.s-1]   or   [molecules.um-2.s-1]  (or other)
    // (2)  molecularRate = P * <s0> * <s1>        [molecules.s-1]
    // 
    // in this math description, we are using <s_i> [molecules], but original kinetics were in [s_i] [uM or molecules.um-2].
    // so through a change in variable to get things in terms of <s_i>.  <<<< Here P is the desired stochastic rate coefficient. >>>
    // 
    // (3)  let [s_i] = <s_i>/structsize(s_i)*unitConversionFactor(substanceunit([s_i])/substanceunit(<s_i>))
    // 
    // in addition to the change in variables, we need to transform the entire expression from concentration/time to molecules/time
    // 
    // (4)  let molecularRate = concentrationRate * structSize(reaction) * unitConversionFactor(substanceunit(molecularRate)/substanceunit(concentrationRate))
    // 
    // (5)  in general, concentationRate = K * PRODUCT([s_i])
    // 
    // change of variables into stochastic variables used in MathDescription, substituting (3) into (5)
    // 
    // (6)  concentrationRate = K * PRODUCT(<s_i>/structsize(s_i)*unitConversionFactor(substanceunit([s_i])/substanceunit(<s_i>)))
    // 
    // reordering to separate the sizes, the unit conversions and the <s_i>
    // 
    // (7)  concentrationRate = K * PRODUCT(<s_i>) * PRODUCT(1/structsize(s_i)) * unitConversionFactor(PRODUCT(substanceunit([s_i])/substanceunit(<s_i>)))
    // 
    // combining (4) and (7)
    // 
    // (8) molecularRate = K * PRODUCT(<s_i>) * PRODUCT(1/structsize(s_i)) * unitConversionFactor(PRODUCT(substanceunit([s_i])/substanceunit(<s_i>))) * structSize(reaction) * unitConversionFactor(substanceunit(molecularRate)/substanceunit(concentrationRate))
    // 
    // collecting terms of sizes and unit conversions
    // 
    // (9)  molecularRate = K * PRODUCT(<s_i>) * structSize(reaction) / PRODUCT(structsize(s_i)) * unitConversionFactor(substanceunit(molecularRate)/substanceunit(concentrationRate) * PRODUCT(substanceunit([s_i])/substanceunit(<s_i>)))
    // 
    // (10) molecularRate = K * PRODUCT(<s_i>) * sizeFactor * unitConversionFactor(substanceConversionUnit)
    // 
    // where
    // 
    // (11) sizeFactor = structSize(reaction) / PRODUCT(structsize(s_i))
    // (12) substanceConversionUnit = substanceunit(molecularRate)/substanceunit(concentrationRate) * PRODUCT(substanceunit([s_i])/substanceunit(<s_i>))
    // 
    // The ParticleJumpCondition wants a single new rate stochastic, P from equation (2).  Note that PRODUCT(<s_i>) will be captured separately the the reactantPatterns.
    // comparing (2) and (10) we have found P.
    // 
    // (13) P = K * sizeFactor * unitConversionFactor(substanceConversionUnit)
    // 
    // the framework also needs the proper unit for P
    // 
    // (14) Unit(P) = Unit(K) * Unit(sizeFactor) * substanceConversionUnit
    // 
    // 
    ModelUnitSystem modelUnitSystem = getSimulationContext().getModel().getUnitSystem();
    VCUnitDefinition stochasticSubstanceUnit = modelUnitSystem.getStochasticSubstanceUnit();
    VCUnitDefinition reactionRuleSubstanceUnit = modelUnitSystem.getSubstanceUnit(reactionRule.getStructure());
    int forwardRuleIndex = 0;
    // 
    // get forward rate parameter and make sure it is constant valued.
    // 
    Parameter forward_rateParameter = kinetics.getLocalParameter(RbmKineticLawParameterType.MassActionForwardRate);
    Expression substitutedForwardRate = MathUtilities.substituteModelParameters(forward_rateParameter.getExpression(), reactionRule.getNameScope().getScopedSymbolTable());
    if (!substitutedForwardRate.flatten().isNumeric()) {
        throw new MappingException("forward rate constant for reaction rule " + reactionRule.getName() + " is not constant");
    }
    // 
    // create forward sizeExp and forward unitFactor
    // 
    VCUnitDefinition forward_substanceConversionUnit = stochasticSubstanceUnit.divideBy(reactionRuleSubstanceUnit);
    VCUnitDefinition forward_sizeFactorUnit = reactionRule.getStructure().getStructureSize().getUnitDefinition();
    Expression forward_sizeFactor = new Expression(reactionRule.getStructure().getStructureSize(), getNameScope());
    for (ReactantPattern reactantPattern : reactionRule.getReactantPatterns()) {
        Expression reactantSizeExp = new Expression(reactantPattern.getStructure().getStructureSize(), getNameScope());
        VCUnitDefinition reactantSizeUnit = reactantPattern.getStructure().getStructureSize().getUnitDefinition();
        VCUnitDefinition reactantSubstanceUnit = modelUnitSystem.getSubstanceUnit(reactantPattern.getStructure());
        forward_sizeFactor = Expression.div(forward_sizeFactor, reactantSizeExp);
        forward_sizeFactorUnit = forward_sizeFactorUnit.divideBy(reactantSizeUnit);
        forward_substanceConversionUnit = forward_substanceConversionUnit.multiplyBy(reactantSubstanceUnit).divideBy(stochasticSubstanceUnit);
    }
    // simplify sizeFactor (often has size/size/size)
    try {
        forward_sizeFactor = RationalExpUtils.getRationalExp(forward_sizeFactor).simplifyAsExpression();
        forward_sizeFactor.bindExpression(getSimulationContext().getModel());
    } catch (ParseException e) {
        e.printStackTrace();
    }
    Expression forward_rateExp = Expression.mult(new Expression(forward_rateParameter, getNameScope()), forward_sizeFactor, getUnitFactor(forward_substanceConversionUnit)).flatten();
    VCUnitDefinition forward_rateUnit = forward_rateParameter.getUnitDefinition().multiplyBy(forward_sizeFactorUnit).multiplyBy(forward_substanceConversionUnit);
    ProbabilityParameter forward_probParm = addProbabilityParameter(PARAMETER_PROBABILITYRATE_PREFIX + jpName, forward_rateExp, PARAMETER_ROLE_P, forward_rateUnit, reactionRule);
    // add probability to function or constant
    varHash.addVariable(newFunctionOrConstant(getMathSymbol(forward_probParm, geometryClass), getIdentifierSubstitutions(forward_rateExp, forward_rateUnit, geometryClass), geometryClass));
    // add forward ParticleJumpProcess
    String forward_name = reactionRuleName;
    Expression forward_rate = getIdentifierSubstitutions(new Expression(forward_probParm, getNameScope()), forward_probParm.getUnitDefinition(), geometryClass);
    JumpProcessRateDefinition forward_rateDefinition = new MacroscopicRateConstant(forward_rate);
    ReactionRuleAnalysisReport rrarBiomodelForward = ruleBasedTransformation.getRulesForwardMap().get(reactionRule);
    ProcessSymmetryFactor forwardSymmetryFactor = new ProcessSymmetryFactor(rrarBiomodelForward.getSymmetryFactor());
    ParticleJumpProcess forward_particleJumpProcess = new ParticleJumpProcess(forward_name, reactantParticles, forward_rateDefinition, forwardActions, forwardSymmetryFactor);
    subDomain.addParticleJumpProcess(forward_particleJumpProcess);
    // 
    for (ReactionRule rr : getSimulationContext().getModel().getRbmModelContainer().getReactionRuleList()) {
        if (rr == reactionRule) {
            break;
        }
        forwardRuleIndex++;
        if (rr.isReversible()) {
            forwardRuleIndex++;
        }
    }
    // 
    if (reactionRule.isReversible()) {
        Parameter reverse_rateParameter = kinetics.getLocalParameter(RbmKineticLawParameterType.MassActionReverseRate);
        if (reverse_rateParameter == null || reverse_rateParameter.getExpression() == null) {
            throw new MappingException("reverse rate constant for reaction rule " + reactionRule.getName() + " is missing");
        }
        {
            Expression substitutedReverseRate = MathUtilities.substituteModelParameters(reverse_rateParameter.getExpression(), reactionRule.getNameScope().getScopedSymbolTable());
            if (!substitutedReverseRate.flatten().isNumeric()) {
                throw new MappingException("reverse rate constant for reaction rule " + reactionRule.getName() + " is not constant");
            }
        }
        // 
        // create reverse sizeExp and reverse unitFactor
        // 
        VCUnitDefinition reverse_substanceConversionUnit = stochasticSubstanceUnit.divideBy(reactionRuleSubstanceUnit);
        VCUnitDefinition reverse_sizeFactorUnit = reactionRule.getStructure().getStructureSize().getUnitDefinition();
        Expression reverse_sizeFactor = new Expression(reactionRule.getStructure().getStructureSize(), getNameScope());
        for (ProductPattern productPattern : reactionRule.getProductPatterns()) {
            Expression reactantSizeExp = new Expression(productPattern.getStructure().getStructureSize(), getNameScope());
            VCUnitDefinition reactantSizeUnit = productPattern.getStructure().getStructureSize().getUnitDefinition();
            VCUnitDefinition reactantSubstanceUnit = modelUnitSystem.getSubstanceUnit(productPattern.getStructure());
            reverse_sizeFactor = Expression.div(reverse_sizeFactor, reactantSizeExp);
            reverse_sizeFactorUnit = reverse_sizeFactorUnit.divideBy(reactantSizeUnit);
            reverse_substanceConversionUnit = reverse_substanceConversionUnit.multiplyBy(reactantSubstanceUnit).divideBy(stochasticSubstanceUnit);
        }
        // simplify sizeFactor (often has size/size/size)
        try {
            reverse_sizeFactor = RationalExpUtils.getRationalExp(reverse_sizeFactor).simplifyAsExpression();
            reverse_sizeFactor.bindExpression(getSimulationContext().getModel());
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Expression reverse_rateExp = Expression.mult(new Expression(reverse_rateParameter, getNameScope()), reverse_sizeFactor, getUnitFactor(reverse_substanceConversionUnit)).flatten();
        VCUnitDefinition reverse_rateUnit = reverse_rateParameter.getUnitDefinition().multiplyBy(reverse_sizeFactorUnit).multiplyBy(reverse_substanceConversionUnit);
        // if the reaction has forward rate (Mass action,HMMs), or don't have either forward or reverse rate (some other rate laws--like general)
        // we process it as forward reaction
        // get jump process name
        ProbabilityParameter reverse_probParm = addProbabilityParameter(PARAMETER_PROBABILITYRATE_PREFIX + jpName + "_reverse", reverse_rateExp, PARAMETER_ROLE_P_reverse, reverse_rateUnit, reactionRule);
        // add probability to function or constant
        varHash.addVariable(newFunctionOrConstant(getMathSymbol(reverse_probParm, geometryClass), getIdentifierSubstitutions(reverse_rateExp, reverse_rateUnit, geometryClass), geometryClass));
        // add reverse ParticleJumpProcess
        Expression reverse_rate = getIdentifierSubstitutions(new Expression(reverse_probParm, getNameScope()), reverse_probParm.getUnitDefinition(), geometryClass);
        String reverse_name = reactionRuleName + "_reverse";
        JumpProcessRateDefinition reverse_rateDefinition = new MacroscopicRateConstant(reverse_rate);
        ReactionRuleAnalysisReport rrarBiomodelReverse = ruleBasedTransformation.getRulesReverseMap().get(reactionRule);
        ProcessSymmetryFactor reverseSymmetryFactor = new ProcessSymmetryFactor(rrarBiomodelReverse.getSymmetryFactor());
        ParticleJumpProcess reverse_particleJumpProcess = new ParticleJumpProcess(reverse_name, productParticles, reverse_rateDefinition, reverseActions, reverseSymmetryFactor);
        subDomain.addParticleJumpProcess(reverse_particleJumpProcess);
        // 
        // check reverse direction mapping and operations with RuleAnalysis.
        // 
        int reverseRuleIndex = forwardRuleIndex + 1;
        ReactionRuleAnalysisReport rrar = ruleBasedTransformation.getRulesReverseMap().get(reactionRule);
        jumpProcessMap.put(reverse_particleJumpProcess, rrar);
    }
}
Also used : ReactionRuleAnalysisReport(cbit.vcell.mapping.RulebasedTransformer.ReactionRuleAnalysisReport) JumpProcessRateDefinition(cbit.vcell.math.JumpProcessRateDefinition) ReactionRule(cbit.vcell.model.ReactionRule) ProductPattern(cbit.vcell.model.ProductPattern) ParticleJumpProcess(cbit.vcell.math.ParticleJumpProcess) RbmKineticLaw(cbit.vcell.model.RbmKineticLaw) ProcessSymmetryFactor(cbit.vcell.math.ParticleJumpProcess.ProcessSymmetryFactor) VCUnitDefinition(cbit.vcell.units.VCUnitDefinition) Expression(cbit.vcell.parser.Expression) Parameter(cbit.vcell.model.Parameter) UnresolvedParameter(cbit.vcell.mapping.ParameterContext.UnresolvedParameter) LocalParameter(cbit.vcell.mapping.ParameterContext.LocalParameter) ModelParameter(cbit.vcell.model.Model.ModelParameter) MacroscopicRateConstant(cbit.vcell.math.MacroscopicRateConstant) ParseException(jscl.text.ParseException) RulebasedTransformation(cbit.vcell.mapping.RulebasedTransformer.RulebasedTransformation) ModelUnitSystem(cbit.vcell.model.ModelUnitSystem) ReactantPattern(cbit.vcell.model.ReactantPattern)

Aggregations

VCUnitDefinition (cbit.vcell.units.VCUnitDefinition)113 Expression (cbit.vcell.parser.Expression)73 ModelUnitSystem (cbit.vcell.model.ModelUnitSystem)36 ExpressionException (cbit.vcell.parser.ExpressionException)26 PropertyVetoException (java.beans.PropertyVetoException)24 LocalParameter (cbit.vcell.mapping.ParameterContext.LocalParameter)21 Element (org.jdom.Element)20 KineticsParameter (cbit.vcell.model.Kinetics.KineticsParameter)19 ArrayList (java.util.ArrayList)17 ModelParameter (cbit.vcell.model.Model.ModelParameter)16 Model (cbit.vcell.model.Model)14 Parameter (cbit.vcell.model.Parameter)14 SpeciesContext (cbit.vcell.model.SpeciesContext)13 SymbolTableEntry (cbit.vcell.parser.SymbolTableEntry)13 Membrane (cbit.vcell.model.Membrane)12 Structure (cbit.vcell.model.Structure)12 StructureMapping (cbit.vcell.mapping.StructureMapping)11 MathException (cbit.vcell.math.MathException)10 ReactionStep (cbit.vcell.model.ReactionStep)10 Feature (cbit.vcell.model.Feature)9