use of cbit.vcell.parser.SymbolTableEntry in project vcell by virtualcell.
the class AbstractMathMapping method getDefaultGeometryClass.
protected GeometryClass getDefaultGeometryClass(Expression expr) throws ExpressionException, MappingException {
GeometryClass geometryClass = null;
if (simContext.getGeometry().getDimension() == 0) {
return null;
}
String[] symbols = expr.getSymbols();
// if expr has no symbols, model param cannot be localized to a domain (its a const).
if (symbols == null) {
return null;
} else {
Expression modelParamExpr = substituteGlobalParameters(expr);
symbols = modelParamExpr.getSymbols();
for (int k = 0; symbols != null && k < symbols.length; k++) {
Structure symbolStructure = null;
SymbolTableEntry ste = modelParamExpr.getSymbolBinding(symbols[k]);
if (ste instanceof SpeciesContext) {
symbolStructure = ((SpeciesContext) ste).getStructure();
} else if (ste instanceof StructureSize) {
symbolStructure = ((StructureSize) ste).getStructure();
} else if (ste instanceof MembraneVoltage) {
symbolStructure = ((MembraneVoltage) ste).getMembrane();
}
if (symbolStructure != null) {
StructureMapping sm = simContext.getGeometryContext().getStructureMapping(symbolStructure);
GeometryClass symbolGeomClass = sm.getGeometryClass();
if (geometryClass == null) {
geometryClass = symbolGeomClass;
} else {
if (geometryClass != symbolGeomClass) {
if (geometryClass instanceof SurfaceClass) {
if (symbolGeomClass instanceof SurfaceClass) {
throw new MappingException("The expression '" + expr.infix() + "' references variables in surface domain '" + geometryClass.getName() + "' & surface domain '" + symbolGeomClass.getName() + "' that cannot be evaluated.");
} else if (symbolGeomClass instanceof SubVolume) {
// geomClass : surfaceClass; symbolGeomClass : subVol
if (!((SurfaceClass) geometryClass).isAdjacentTo((SubVolume) symbolGeomClass)) {
throw new MappingException("The expression '" + expr.infix() + "' references variables in surface domain '" + geometryClass.getName() + "' & volume domain '" + symbolGeomClass.getName() + "' that cannot be evaluated.");
}
} else {
throw new MappingException("unexpected geometry class : " + symbolGeomClass.getClass());
}
} else if (geometryClass instanceof SubVolume) {
// geometryClass is a SubVolume
if (symbolGeomClass instanceof SubVolume) {
// check if adjacent; if so, choose separating membrane.
SurfaceClass surfaceClass = simContext.getGeometry().getGeometrySurfaceDescription().getSurfaceClass((SubVolume) symbolGeomClass, (SubVolume) geometryClass);
if (surfaceClass != null) {
geometryClass = surfaceClass;
} else {
throw new MappingException("The expression '" + expr.infix() + "' references variables in volume domain '" + geometryClass.getName() + "' & volume domain '" + symbolGeomClass.getName() + "' that cannot be evaluated.");
}
} else {
// geomClass : subVol; symbolGeomClass = surfaceClass
SurfaceClass surfaceSymbolGeomClass = (SurfaceClass) symbolGeomClass;
if (!surfaceSymbolGeomClass.isAdjacentTo((SubVolume) geometryClass)) {
throw new MappingException("The expression '" + expr.infix() + "' references variables in surface domain '" + surfaceSymbolGeomClass.getName() + "' & volume domain '" + geometryClass.getName() + "' that cannot be evaluated.");
} else {
geometryClass = symbolGeomClass;
}
}
} else {
throw new MappingException("unexpected geometry class : " + geometryClass.getClass());
}
}
}
}
}
}
return geometryClass;
}
use of cbit.vcell.parser.SymbolTableEntry in project vcell by virtualcell.
the class BioEvent method gatherIssues.
public void gatherIssues(IssueContext issueContext, List<Issue> issueList) {
// check all event assignment symbols
if (eventAssignmentList != null) {
for (EventAssignment ea : eventAssignmentList) {
// the target of the event assignment
SymbolTableEntry ste = simulationContext.getEntry(ea.getTarget().getName());
// SymbolTableEntry ste = parameterContext.getEntry(ea.getTarget().getName());
if (ste == null) {
String msg = "Missing Parameter '" + ea.getTarget().getName() + "' used in BioEvent '" + name + "'.";
String tip = "Remove the Action containing the missing parameter from the BioEvent '" + name + "'.";
issueList.add(new Issue(this, issueContext, IssueCategory.Identifiers, msg, tip, Issue.Severity.ERROR));
// found one issue on this event assignment, we show it and go to next
break;
}
// the expression of the event assignment
Expression exp = ea.assignmentExpression;
String[] symbols = exp.getSymbols();
if (symbols != null) {
boolean found = false;
for (String symbol : symbols) {
ste = simulationContext.getEntry(symbol);
if (ste == null) {
String msg = "Missing Symbol '" + symbol + "' in Assignment Expression for BioEvent '" + name + "'.";
String tip = "Remove the Action containing the missing Symbol from the Assignment Expression of the BioEvent '" + name + "'.";
issueList.add(new Issue(this, issueContext, IssueCategory.Identifiers, msg, tip, Issue.Severity.ERROR));
found = true;
break;
}
}
if (found == true) {
// found one issue on this event assignment, we show it and go to next
break;
}
}
}
} else {
String msg = "No Action assigned to BioEvent '" + name + "'.";
String tip = "Please assign an Action to the BioEvent '" + name + "'.";
issueList.add(new Issue(this, issueContext, IssueCategory.Identifiers, msg, tip, Issue.Severity.WARNING));
}
// check all trigger condition symbols
for (LocalParameter lp : getEventParameters()) {
if (lp.getExpression() != null && lp.getExpression().getSymbols() != null) {
String[] symbols = lp.getExpression().getSymbols();
boolean found = false;
for (String symbol : symbols) {
SymbolTableEntry ste = simulationContext.getEntry(symbol);
if (ste == null) {
String msg = "Missing Symbol '" + symbol + "' in the Trigger Condition for BioEvent '" + name + "'.";
String tip = "Remove the Action containing the missing Symbol from the Trigger Condition of the BioEvent '" + name + "'.";
issueList.add(new Issue(this, issueContext, IssueCategory.Identifiers, msg, tip, Issue.Severity.ERROR));
found = true;
break;
}
}
if (found == true) {
// found one issue with a parameter on this trigger condition, we show it and stop
break;
}
}
}
}
use of cbit.vcell.parser.SymbolTableEntry in project vcell by virtualcell.
the class BioEvent method generateTriggerExpression.
public Expression generateTriggerExpression() throws ExpressionException {
SymbolTableEntry timeSymbolTableEntry = getSimulationContext().getModel().getTIME();
Expression tExp = new Expression(timeSymbolTableEntry, getNameScope());
switch(triggerType) {
case GeneralTrigger:
{
return new Expression(getParameter(BioEventParameterType.GeneralTriggerFunction), getNameScope());
}
case ListOfTimes:
{
ArrayList<LocalParameter> timeParams = new ArrayList<LocalParameter>();
for (LocalParameter p : parameterContext.getLocalParameters()) {
if (p.getRole() == BioEventParameterType.TimeListItem) {
timeParams.add(p);
}
}
if (timeParams.size() == 0) {
throw new RuntimeException("no times found for BioEvent " + getName());
}
//
if (timeParams.size() == 1) {
Expression timeParamExp = new Expression(timeParams.get(0), getNameScope());
return Expression.relational(">=", tExp, timeParamExp);
}
//
// if more than one, flatten time expressions to get list of doubles for event triggers.
// these numbers are sorted to find the minimum distance between adjacent times.
// epsilon is 1/2 of this inter-trigger time interval (to insert a falling edge between events)
//
ArrayList<Double> timeValues = new ArrayList<Double>();
for (LocalParameter p : timeParams) {
timeValues.add(MathUtilities.substituteModelParameters(p.getExpression(), getScopedSymbolTable()).flatten().evaluateConstant());
}
Collections.sort(timeValues);
double epsilon = Double.MAX_VALUE;
for (int i = 0; i < timeValues.size() - 1; i++) {
double absdiff = Math.abs(timeValues.get(i) - timeValues.get(i + 1));
epsilon = Math.min(epsilon, absdiff);
}
epsilon /= 2.0;
//
// construct (((t >= t0) && (t <= t0+epsilon)) || ((t >= t1) && (t <= t1+epsilon)) || ((t >= t2) && (t <= t2+epsilon)))
//
ArrayList<Expression> timeClauses = new ArrayList<Expression>();
for (LocalParameter timeParam : timeParams) {
Expression timeParamExp = new Expression(timeParam, getNameScope());
Expression timeParamExpPlusEpsilon = Expression.add(timeParamExp, new Expression(epsilon));
timeClauses.add(Expression.and(Expression.relational(">=", tExp, timeParamExp), Expression.relational("<=", tExp, timeParamExpPlusEpsilon)));
}
if (timeClauses.size() == 1) {
return timeClauses.get(0);
} else {
// put all individual time clauses together
return Expression.or(timeClauses.toArray(new Expression[timeClauses.size()]));
}
}
case LinearRangeTimes:
case LogRangeTimes:
{
//
// if more than one, flatten time expressions to get list of doubles for event triggers.
// these numbers are sorted to find the minimum distance between adjacent times.
// epsilon is 1/2 of this inter-trigger time interval (to insert a falling edge between events)
//
LocalParameter firstTimeParam = getParameter(BioEventParameterType.RangeMinTime);
LocalParameter lastTimeParam = getParameter(BioEventParameterType.RangeMaxTime);
LocalParameter numTimesParam = getParameter(BioEventParameterType.RangeNumTimes);
double firstTime = MathUtilities.substituteModelParameters(firstTimeParam.getExpression(), getScopedSymbolTable()).flatten().evaluateConstant();
double lastTime = MathUtilities.substituteModelParameters(lastTimeParam.getExpression(), getScopedSymbolTable()).flatten().evaluateConstant();
double numTimes = MathUtilities.substituteModelParameters(numTimesParam.getExpression(), getScopedSymbolTable()).flatten().evaluateConstant();
Expression first = new Expression(firstTimeParam, getNameScope());
Expression last = new Expression(lastTimeParam, getNameScope());
Expression num = new Expression(numTimesParam, getNameScope());
ArrayList<Expression> timeExps = new ArrayList<Expression>();
ArrayList<Double> timeValues = new ArrayList<Double>();
timeValues.add(firstTime);
timeExps.add(first);
if (getTriggerType() == TriggerType.LinearRangeTimes) {
double delta = (lastTime - firstTime) / (numTimes - 1);
Expression deltaExp = Expression.div(Expression.add(last, Expression.negate(first)), Expression.add(num, new Expression(-1)));
for (int i = 1; i < numTimes; i++) {
timeValues.add(firstTime + delta * i);
Expression eventTime = Expression.add(first, Expression.mult(deltaExp, new Expression(i)));
timeExps.add(eventTime);
}
} else if (getTriggerType() == TriggerType.LogRangeTimes) {
double ratio = lastTime / firstTime;
Expression ratioExp = Expression.div(last, first);
double n_minus_1 = numTimes - 1;
Expression n_minus_1_exp = Expression.add(num, new Expression(-1));
for (int i = 1; i < numTimes; i++) {
timeValues.add(firstTime * Math.pow(ratio, i / n_minus_1));
timeExps.add(Expression.mult(first, Expression.power(ratioExp, Expression.div(new Expression(i), n_minus_1_exp))));
}
}
double epsilon = Double.MAX_VALUE;
for (int i = 0; i < timeValues.size() - 1; i++) {
double absdiff = Math.abs(timeValues.get(i) - timeValues.get(i + 1));
epsilon = Math.min(epsilon, absdiff);
}
epsilon /= 2.0;
//
// construct (((t >= t0) && (t <= t0+epsilon)) || ((t >= t1) && (t <= t1+epsilon)) || ((t >= t2) && (t <= t2+epsilon)))
//
ArrayList<Expression> timeClauses = new ArrayList<Expression>();
for (Expression timeExp : timeExps) {
Expression timeExpPlusEpsilon = Expression.add(timeExp, new Expression(epsilon));
timeClauses.add(Expression.and(Expression.relational(">=", tExp, timeExp), Expression.relational("<=", tExp, timeExpPlusEpsilon)));
}
if (timeClauses.size() == 1) {
return timeClauses.get(0);
} else {
// put all individual time clauses together
return Expression.or(timeClauses.toArray(new Expression[timeClauses.size()]));
}
}
case ObservableAboveThreshold:
{
Expression highTrigger = Expression.relational(">=", new Expression(getParameter(BioEventParameterType.Observable), getNameScope()), new Expression(getParameter(BioEventParameterType.Threshold), getNameScope()));
return highTrigger;
}
case ObservableBelowThreshold:
{
Expression lowTrigger = Expression.relational("<=", new Expression(getParameter(BioEventParameterType.Observable), getNameScope()), new Expression(getParameter(BioEventParameterType.Threshold), getNameScope()));
return lowTrigger;
}
case SingleTriggerTime:
{
SymbolTableEntry time = getSimulationContext().getModel().getTIME();
return Expression.relational(">=", new Expression(time, getNameScope()), new Expression(getParameter(BioEventParameterType.SingleTriggerTime), getNameScope()));
}
default:
{
throw new RuntimeException("unexpected triggerType " + getTriggerType());
}
}
}
use of cbit.vcell.parser.SymbolTableEntry in project vcell by virtualcell.
the class Kinetics method setParameterValue.
/**
* This method was created by a SmartGuide.
* @param expressionString java.lang.String
* @exception java.lang.Exception The exception description.
*/
public void setParameterValue(KineticsParameter parm, Expression exp) throws ExpressionException, PropertyVetoException {
Parameter p = getKineticsParameter(parm.getName());
if (p != parm) {
throw new RuntimeException("parameter " + parm.getName() + " not found");
}
Expression oldExpression = parm.getExpression();
boolean bBound = false;
try {
KineticsParameter[] newKineticsParameters = (KineticsParameter[]) fieldKineticsParameters.clone();
// KineticsProxyParameter newProxyParameters[] = (KineticsProxyParameter[])fieldProxyParameters.clone();
String[] symbols = exp.getSymbols();
ModelUnitSystem modelUnitSystem = getReactionStep().getModel().getUnitSystem();
for (int i = 0; symbols != null && i < symbols.length; i++) {
SymbolTableEntry ste = reactionStep.getEntry(symbols[i]);
if (ste == null) {
newKineticsParameters = (KineticsParameter[]) BeanUtils.addElement(newKineticsParameters, new KineticsParameter(symbols[i], new Expression(0.0), ROLE_UserDefined, modelUnitSystem.getInstance_TBD()));
}
}
parm.setExpression(exp);
setKineticsParameters(newKineticsParameters);
// setProxyParameters(newProxyParameters);
exp.bindExpression(reactionStep);
bBound = true;
} finally {
try {
if (!bBound) {
parm.setExpression(oldExpression);
}
cleanupParameters();
} catch (ModelException e) {
e.printStackTrace(System.out);
throw new RuntimeException(e.getMessage());
} catch (PropertyVetoException e) {
e.printStackTrace(System.out);
throw new RuntimeException(e.getMessage());
}
}
}
use of cbit.vcell.parser.SymbolTableEntry in project vcell by virtualcell.
the class MassActionSolver method substituteParameters.
public static Expression substituteParameters(Expression exp, boolean substituteConst) throws ExpressionException {
Expression result = new Expression(exp);
boolean bSubstituted = true;
while (bSubstituted) {
bSubstituted = false;
String[] symbols = result.getSymbols();
for (int k = 0; symbols != null && k < symbols.length; k++) {
SymbolTableEntry ste = result.getSymbolBinding(symbols[k]);
if (ste instanceof ProxyParameter) {
ProxyParameter pp = (ProxyParameter) ste;
result.substituteInPlace(new Expression(pp, pp.getNameScope()), new Expression(pp.getTarget(), pp.getTarget().getNameScope()));
bSubstituted = true;
} else if (ste instanceof Parameter) {
Parameter kp = (Parameter) ste;
try {
Expression expKP = kp.getExpression();
if (!expKP.flatten().isNumeric() || substituteConst) {
result.substituteInPlace(new Expression(symbols[k]), new Expression(kp.getExpression()));
bSubstituted = true;
}
} catch (ExpressionException e1) {
e1.printStackTrace();
throw new ExpressionException(e1.getMessage());
}
} else if (substituteConst && ste instanceof Model.ReservedSymbol) {
Model.ReservedSymbol rs = (Model.ReservedSymbol) ste;
try {
if (rs.getExpression() != null) {
result.substituteInPlace(new Expression(symbols[k]), new Expression(rs.getExpression()));
bSubstituted = true;
}
} catch (ExpressionException e1) {
e1.printStackTrace();
throw new ExpressionException(e1.getMessage());
}
}
}
}
return result;
}
Aggregations