Search in sources :

Example 6 with RationalNumber

use of ucar.units_vcell.RationalNumber in project vcell by virtualcell.

the class VCUnitEvaluator method getUnitDefinition.

private VCUnitDefinition getUnitDefinition(SimpleNode node, UnitsHashMap unitsHashMap) throws ExpressionException, VCUnitException {
    // temp variable
    VCUnitDefinition unit = null;
    if (node == null) {
        return null;
    }
    if (node instanceof ASTAndNode || node instanceof ASTOrNode || node instanceof ASTNotNode) {
        for (int i = 0; i < node.jjtGetNumChildren(); i++) {
            SimpleNode child = (SimpleNode) node.jjtGetChild(i);
            VCUnitDefinition childUnit = getUnitDefinition(child, unitsHashMap);
            if (!childUnit.isEquivalent(unitSystem.getInstance_DIMENSIONLESS())) {
                throw new VCUnitException("argument to boolean expression '" + child.infixString(SimpleNode.LANGUAGE_DEFAULT) + "' must be dimensionless");
            }
        }
        return unitSystem.getInstance_DIMENSIONLESS();
    } else if (node instanceof ASTRelationalNode) {
        ArrayList<VCUnitDefinition> units = new ArrayList<VCUnitDefinition>();
        for (int i = 0; i < node.jjtGetNumChildren(); i++) {
            units.add(getUnitDefinition((SimpleNode) node.jjtGetChild(i), unitsHashMap));
        }
        // looking for imcompatabilities
        computeUnit(node, (VCUnitDefinition[]) units.toArray(new VCUnitDefinition[units.size()]), true);
        return unitSystem.getInstance_DIMENSIONLESS();
    } else if (node instanceof ASTAddNode || node instanceof ASTMinusTermNode) {
        ArrayList<VCUnitDefinition> units = new ArrayList<VCUnitDefinition>();
        for (int i = 0; i < node.jjtGetNumChildren(); i++) {
            units.add(getUnitDefinition((SimpleNode) node.jjtGetChild(i), unitsHashMap));
        }
        return computeUnit(node, (VCUnitDefinition[]) units.toArray(new VCUnitDefinition[units.size()]), true);
    } else if (node instanceof ASTMultNode) {
        if (node.jjtGetNumChildren() == 1) {
            return getUnitDefinition((SimpleNode) node.jjtGetChild(0), unitsHashMap);
        }
        VCUnitDefinition accumUnit = null;
        for (int i = 0; i < node.jjtGetNumChildren(); i++) {
            SimpleNode child = (SimpleNode) node.jjtGetChild(i);
            unit = getUnitDefinition(child, unitsHashMap);
            if (unit.isTBD()) {
                return unit;
            }
            if (accumUnit == null) {
                accumUnit = unit;
            } else {
                accumUnit = accumUnit.multiplyBy(unit);
            }
        }
        return accumUnit;
    } else if (node instanceof ASTInvertTermNode) {
        SimpleNode child = (SimpleNode) node.jjtGetChild(0);
        unit = getUnitDefinition(child, unitsHashMap);
        if (unit.isTBD()) {
            return unit;
        } else {
            return unit.getInverse();
        }
    } else if (node instanceof DerivativeNode) {
        unit = getUnitDefinition((SimpleNode) node.jjtGetChild(1), unitsHashMap);
        return getUnitDefinition((SimpleNode) node.jjtGetChild(0), unitsHashMap).divideBy(unit);
    } else if (node instanceof ASTLaplacianNode) {
        return unitSystem.getInstance_TBD();
    // unit = unitSystem.Instance(ModelUnitSystem.UNITSYMBOL_um);
    // return getUnitDefinition((SimpleNode)node.jjtGetChild(0),unitsHashMap).divideBy(unit).divideBy(unit);
    } else if (node instanceof ASTFloatNode) {
        // return TBD instead of dimensionless.
        return unitSystem.getInstance_TBD();
    } else if (node instanceof ASTFuncNode) {
        String functionName = ((ASTFuncNode) node).getName();
        if (functionName.equalsIgnoreCase("pow")) {
            SimpleNode child0 = (SimpleNode) node.jjtGetChild(0);
            SimpleNode child1 = (SimpleNode) node.jjtGetChild(1);
            VCUnitDefinition unit0 = getUnitDefinition(child0, unitsHashMap);
            VCUnitDefinition unit1 = getUnitDefinition(child1, unitsHashMap);
            if (!unit1.isEquivalent(unitSystem.getInstance_DIMENSIONLESS()) && !unit1.isTBD()) {
                throw new VCUnitException("exponent of '" + node.infixString(SimpleNode.LANGUAGE_DEFAULT) + "' has units of " + unit0);
            }
            if (unit0.isEquivalent(unitSystem.getInstance_DIMENSIONLESS()) || unit0.isTBD()) {
                return unit0;
            }
            try {
                double d = ((SimpleNode) node.jjtGetChild(1)).evaluateConstant();
                RationalNumber rn = RationalNumber.getApproximateFraction(d);
                return unit0.raiseTo(rn);
            } catch (ExpressionException e) {
                // ????? don't know the unit now
                return unitSystem.getInstance_TBD();
            }
        } else if (functionName.equalsIgnoreCase("exp")) {
            SimpleNode child0 = (SimpleNode) node.jjtGetChild(0);
            VCUnitDefinition unit0 = getUnitDefinition(child0, unitsHashMap);
            if (!unit0.isEquivalent(unitSystem.getInstance_DIMENSIONLESS()) && !unit0.isTBD()) {
                throw new VCUnitException("exponent of exp() '" + node.infixString(SimpleNode.LANGUAGE_DEFAULT) + "' has units of " + unit0);
            }
            return unitSystem.getInstance_DIMENSIONLESS();
        } else if (functionName.equalsIgnoreCase("sqrt")) {
            SimpleNode child0 = (SimpleNode) node.jjtGetChild(0);
            VCUnitDefinition unit0 = getUnitDefinition(child0, unitsHashMap);
            if (unit0.isEquivalent(unitSystem.getInstance_DIMENSIONLESS()) || unit0.isTBD()) {
                return unit0;
            }
            RationalNumber rn = new RationalNumber(1, 2);
            return unit0.raiseTo(rn);
        } else if (functionName.equalsIgnoreCase("abs") || functionName.equalsIgnoreCase("min") || functionName.equalsIgnoreCase("max")) {
            return getUnitDefinition((SimpleNode) node.jjtGetChild(0), unitsHashMap);
        } else if (((ASTFuncNode) node).getFunction() == FunctionType.USERDEFINED) {
            ASTFuncNode funcNode = (ASTFuncNode) node;
            SymbolTableFunctionEntry stfe = funcNode.getSymbolTableFunctionEntry();
            if (stfe != null) {
                if (stfe.getUnitDefinition() != null) {
                    return stfe.getUnitDefinition();
                }
            }
            return unitSystem.getInstance_TBD();
        } else {
            return unitSystem.getInstance_DIMENSIONLESS();
        }
    } else if (node instanceof ASTPowerNode) {
        SimpleNode child0 = (SimpleNode) node.jjtGetChild(0);
        SimpleNode child1 = (SimpleNode) node.jjtGetChild(1);
        VCUnitDefinition unit0 = getUnitDefinition(child0, unitsHashMap);
        VCUnitDefinition unit1 = getUnitDefinition(child1, unitsHashMap);
        if (!unit1.isEquivalent(unitSystem.getInstance_DIMENSIONLESS()) && !unit1.isTBD()) {
            throw new VCUnitException("exponent of '" + node.infixString(SimpleNode.LANGUAGE_DEFAULT) + "' has units of " + unit0);
        }
        if (unit0.isEquivalent(unitSystem.getInstance_DIMENSIONLESS())) {
            return unitSystem.getInstance_DIMENSIONLESS();
        }
        boolean bConstantExponent = false;
        double exponentValue = 1;
        try {
            exponentValue = child1.evaluateConstant();
            bConstantExponent = true;
        } catch (ExpressionException e) {
            bConstantExponent = false;
        }
        if (bConstantExponent) {
            // 
            if (unit0.isTBD()) {
                return unitSystem.getInstance_TBD();
            } else {
                RationalNumber rn = RationalNumber.getApproximateFraction(exponentValue);
                return unit0.raiseTo(rn);
            }
        } else {
            return unitSystem.getInstance_TBD();
        }
    } else if (node instanceof ASTIdNode) {
        SymbolTableEntry ste = ((ASTIdNode) node).symbolTableEntry;
        unit = unitsHashMap.get(ste);
        if (unit == null) {
            unit = ste.getUnitDefinition();
            if (unit == null) {
                throw new ExpressionException("No unit found for expression node: " + node.toString());
            } else {
                unitsHashMap.put(ste, unit);
            }
        }
        return unit;
    } else {
        throw new ExpressionException("node type " + node.getClass().toString() + " not supported yet");
    }
}
Also used : ArrayList(java.util.ArrayList) VCUnitException(cbit.vcell.units.VCUnitException) RationalNumber(ucar.units_vcell.RationalNumber) VCUnitDefinition(cbit.vcell.units.VCUnitDefinition)

Aggregations

RationalNumber (ucar.units_vcell.RationalNumber)6 VCUnitDefinition (cbit.vcell.units.VCUnitDefinition)5 ArrayList (java.util.ArrayList)4 GeometryClass (cbit.vcell.geometry.GeometryClass)2 SpeciesContextSpecParameter (cbit.vcell.mapping.SpeciesContextSpec.SpeciesContextSpecParameter)2 SpeciesContextSpecProxyParameter (cbit.vcell.mapping.SpeciesContextSpec.SpeciesContextSpecProxyParameter)2 StructureMappingParameter (cbit.vcell.mapping.StructureMapping.StructureMappingParameter)2 Action (cbit.vcell.math.Action)2 CompartmentSubDomain (cbit.vcell.math.CompartmentSubDomain)2 Constant (cbit.vcell.math.Constant)2 InteractionRadius (cbit.vcell.math.InteractionRadius)2 JumpProcessRateDefinition (cbit.vcell.math.JumpProcessRateDefinition)2 MacroscopicRateConstant (cbit.vcell.math.MacroscopicRateConstant)2 MathDescription (cbit.vcell.math.MathDescription)2 MembraneParticleVariable (cbit.vcell.math.MembraneParticleVariable)2 MembraneSubDomain (cbit.vcell.math.MembraneSubDomain)2 ParticleJumpProcess (cbit.vcell.math.ParticleJumpProcess)2 ParticleProperties (cbit.vcell.math.ParticleProperties)2 ParticleVariable (cbit.vcell.math.ParticleVariable)2 SubDomain (cbit.vcell.math.SubDomain)2