- Calculation Scope & Variables
- MathJS Syntax
- Multiline MathJS Syntax
- Python Syntax
- Variable Referencing
- Display Types
- Complete Examples
Calculation Scope:
- All statements within a single calculation share the same variable scope
- Variables defined in one statement can be referenced by other statements in the same calculation
- The
calculationIddetermines the scope boundary - Variables are evaluated in the order they appear
Statement Structure:
title: The display name for the statement (appears in UI sidebar)formula: The actual mathematical expression or codeengine: The calculation engine (mathjs,multiline_mathjs, orpython)
Variable Names:
- Use clear, descriptive names (e.g.,
beam_length,total_load) - Can contain letters, numbers, and underscores
- Should be snake_case for consistency
- The
titlefield is the statement identifier, not necessarily the variable name
Formula Pattern: variable_name = value units
Rules:
- Variable name MUST be included in the formula
- Use
=to assign value to variable - Units are optional but recommended
- Each statement creates ONE variable
Examples:
// Basic assignment with units
beam_length = 10 m
width = 300 mm
height = 500 mm
load = 5 kN
// Assignment without units
count = 42
factor = 1.5
name = "Steel Beam"
// Calculated assignments (referencing other variables)
area = width * height
moment = load * beam_length
stress = moment / (width * height^2 / 6)Supported Operations:
// Unit arithmetic
pressure = 1 kPa
area = 1 m^2
force = pressure * area // Returns: 1 kN
// Unit conversion using 'to'
length_m = 3 m + 200 cm // Returns: 5 m
length_ft = length_m to ft // Converts to feet
// Invalid operations are prevented
invalid = 10 m + 5 kg // ERROR: Cannot add incompatible unitsCommon Units:
- Length:
m,mm,cm,km,ft,in - Force:
N,kN,MN,lbf,kip - Pressure:
Pa,kPa,MPa,GPa,psi,ksi - Area:
m^2,mm^2,ft^2,in^2 - Volume:
m^3,L,gal,ft^3
// Built-in Math.js functions
sqrt_value = sqrt(16)
abs_value = abs(-10)
max_value = max(5, 10, 3)
min_value = min(5, 10, 3)
rounded = round(3.7)
// Trigonometric (angles in radians)
sin_val = sin(pi/2)
cos_val = cos(0)
tan_val = tan(pi/4)
// With units
result = sqrt(25 m^2) // Returns: 5 m- Multiple related variables in one statement
- Intermediate calculations
- Complex multi-step formulas
Formula Pattern: Multiple lines separated by \n
Examples:
// Multiple assignments in one statement
width = 300 mm
height = 500 mm
area = width * height
// Intermediate calculations
E = 200 GPa
nu = 0.3
G = E / (2 * (1 + nu))
K = E / (3 * (1 - 2*nu))
// Section properties
b = 400 mm
h = 600 mm
A = b * h
I = b * h^3 / 12
W = I / (h/2)Rules:
- Each line creates a new variable
- Variables from earlier lines can be used in later lines
- All variables created in the block are available to other statements
- Use
\n(actual newline character) to separate lines in API calls
Formula Pattern: Python code with imports and calculations
Key Requirements:
- Include
userIdin thedatafield when creating python statements via API - Variables defined in global scope are available to other statements
- Use
print()for output display
Examples:
# Basic calculation
import math
total = sum(range(10))
average = total / 10
result = math.sqrt(average)
print(f'Result: {result}')
# Using NumPy
import numpy as np
array = np.array([1, 2, 3, 4, 5])
mean_value = np.mean(array)
std_value = np.std(array)
print(f'Mean: {mean_value}, Std: {std_value}')
# Reading workspace files
data = ct.open('data.csv', mode='rb').read()
print(f'File size: {len(data)} bytes')CalcTree provides 26+ pre-installed Python libraries:
Core Scientific: numpy, scipy, pandas, matplotlib, seaborn, SymPy, Scikit-learn
Engineering/Structural: anaStruct, OpenSeesPy+OpsVis, PyNite, pyFrame3DD, pycba, sectionproperties, StructPy, pyCalculiX, eurocodepy
Specialized: Groundhog (geotechnical), GemPy (geological), REDi (resilience), energy-py-linear
Utilities: handcalcs, ezdxf, SimPy, pysal, joypy, topojson
Standard: math, all Python 3 standard library
CalcTree-specific: ct.open() for workspace files, ct.quantity() for units
Variables defined in mathjs statements within the same calculation scope can be referenced in Python.
CRITICAL: MathJS variables with units are automatically ct.quantity() objects:
# MathJS defines:
# beam_length = 10 m
# load = 5 kN
# Python code - variables automatically have units:
moment = beam_length * load # Returns: 50 kN*m (unit math automatic)
# Convert units
moment_Nm = moment.to("N*m") # Returns: 50000 N*m
# Extract numeric value
value = moment_Nm.magnitude # Returns: 50000.0
print(f'Moment: {moment}')
print(f'Moment in N*m: {moment_Nm}')Do NOT wrap MathJS variables with ct.quantity() - they already have units attached automatically.
See PYTHON_GUIDE.md for complete unit handling documentation.
All statements in a calculation can reference variables from other statements:
Example Calculation Structure:
// Statement 1: Input parameters (mathjs)
title: "beam_length"
formula: "beam_length = 10 m"
// Statement 2: More inputs (mathjs)
title: "load"
formula: "load = 5 kN"
// Statement 3: Calculated result (mathjs) - references Statement 1 & 2
title: "moment"
formula: "moment = load * beam_length" // Uses load and beam_length
// Statement 4: Section properties (multiline_mathjs)
title: "Section"
formula: "width = 300 mm\nheight = 500 mm\nI = width * height^3 / 12"
// Statement 5: Stress calculation (mathjs) - references Statement 3 & 4
title: "stress"
formula: "stress = moment / (I / (height/2))" // Uses moment, I, and heightVariables flow through the calculation in order:
- Input variables (no dependencies)
- Intermediate calculations (depend on inputs)
- Final results (depend on intermediates)
Best Practice: Organize statements logically from inputs → calculations → outputs
- Simple variable with assigned value
- Syntax:
variable_name = value units - Use for: Input parameters, calculated results
- User selects from predefined options
- Can populate from CSV data
- Returns selected value to calculation scope
- Display data in table format
- Can reference individual cells
- Useful for schedules and structured data
- Multiple choice selection
- Similar to dropdown but different UI
- Visual indicator (red/yellow/green)
- Based on conditional logic
- Use for: Pass/fail criteria, safety factors
Note: Display types are configured in the UI. Via API, use Assignment type (standard formula syntax).
from nanoid import generate
import requests
import time
# ... (setup code)
# Create interrelated calculation
execute_query("""
mutation CreateCalc($workspaceId: ID!, $calculationId: ID!, $withStatements: [CreateStatementInput!]!, $data: JSON) {
createOrUpdateCalculation(
workspaceId: $workspaceId
calculationId: $calculationId
withStatements: $withStatements
data: $data
) {
calculationId
revisionId
}
}
""", {
"workspaceId": WORKSPACE_ID,
"calculationId": page_id,
"withStatements": [
{
"statementId": generate(),
"title": "Geometry",
"engine": "multiline_mathjs",
"formula": "L = 10 m\nb = 300 mm\nh = 500 mm"
},
{
"statementId": generate(),
"title": "Loading",
"engine": "multiline_mathjs",
"formula": "q = 10 kN/m\nP = 50 kN"
},
{
"statementId": generate(),
"title": "Section Properties",
"engine": "multiline_mathjs",
"formula": "A = b * h\nI = b * h^3 / 12\nW = I / (h/2)"
},
{
"statementId": generate(),
"title": "max_moment",
"engine": "mathjs",
"formula": "max_moment = q * L^2 / 8 + P * L / 4"
},
{
"statementId": generate(),
"title": "max_stress",
"engine": "mathjs",
"formula": "max_stress = max_moment / W"
},
{
"statementId": generate(),
"title": "Analysis",
"engine": "python",
"formula": "import math\nprint(f'Max Stress: {max_stress}')\nif max_stress < 250e6: # Pa\n print('PASS: Stress within limits')\nelse:\n print('FAIL: Stress exceeds limits')"
}
],
"data": {
"pageId": page_id,
"id": generate(),
"cursor": "0",
"timestamp": int(time.time() * 1000)
}
})// Statement 1: Material constants
E = 200 GPa
nu = 0.3
rho = 7850 kg/m^3
// Statement 2: Derived properties (references Statement 1)
G = E / (2 * (1 + nu))
K = E / (3 * (1 - 2*nu))
// Statement 3: Geometry
L = 5 m
A = 0.01 m^2
// Statement 4: Mass calculation (references Statements 1 and 3)
mass = rho * A * L
// Statement 5: Stiffness (references Statements 1, 2, and 3)
axial_stiffness = E * A / L
shear_stiffness = G * A / L# MathJS: Input
beam_length = 10 m
load = 5 kN
# Multiline MathJS: Section
width = 300 mm
height = 500 mm
I = width * height^3 / 12
# MathJS: Calculate moment
moment = load * beam_length
# Python: Analysis and reporting
import numpy as np
print(f'Beam Length: {beam_length}')
print(f'Applied Load: {load}')
print(f'Bending Moment: {moment}')
stress_array = np.linspace(0, moment, 10)
print(f'Max stress in array: {max(stress_array)}')- Use
createOrUpdateCalculationwith all statements inwithStatementsarray - Set
calculationId = pageIdto link calculation to page - Use correct syntax for each engine type:
- mathjs:
variable_name = value units - multiline_mathjs: Multiple lines with
\n - python: Standard Python code
- mathjs:
- Reference variables by name across statements in same calculation
- Order matters: Define variables before using them
- Include units for physical quantities (mathjs handles unit math)
- For python: Include
userIdindatafield when creating via API
- Query authorization may fail for calculations with python statements, but statements ARE created successfully
- Always verify page URL in browser to confirm statements appear
- Use
revisionId: "ffffffff"for operations even though API returnsnull - All IDs use nanoid format (21 characters)