# ParamML README

## Overview

You are working with **OpenBrIM's Parametric Engine (ParamML)**, a powerful XML-based parametric modeling system for bridge engineering and infrastructure projects. This system enables the creation of intelligent, data-driven bridge components through parametric expressions, inheritance, and lazy evaluation.

## What is ParamML?

ParamML (Parametric Markup Language) is an XML-based language that defines:

* **Parametric Objects**: Hierarchical objects with parameters and expressions
* **Library Components**: Reusable templates for bridge elements (girders, columns, decks, etc.)
* **3D Geometry**: Points, Lines, Surfaces, and Volumes
* **FEA Models**: Finite Element Analysis meshes and boundary conditions
* **Code Checks**: Design verification and compliance calculations
* **Reports**: Automated documentation and analysis results

## File Structure

When you download a branch, you'll receive:

### 1. Branch XML Files (Main Objects)

* `ObjectName.xml` - The library objects you're working on
* These are the objects that were modified or developed in this branch

### 2. Dependency XML Files (Referenced Objects)

* `__dep__ObjectName.xml` - Library objects that are referenced by your main objects
* Prefixed with `__dep__` to distinguish them from your working files
* These are automatically downloaded based on the `subobjtypes` (object type references) in your main objects
* **Example**: If your girder object uses a `StandardSection` object, `__dep__StandardSection.xml` will be downloaded

### 3. AI Documentation Files (.md)

These are guides to help you understand and work with the ParamML system:

**Core Guides (Read These First):**

* `AI-Parametric-Engine-Guide.md` - **ESSENTIAL - Read FIRST**
  * Explains Objects, Parameters, Expressions, Lazy Evaluation
  * Covers Repeat loops, Guards, Library Objects, Export objects
  * Distance-based parameter resolution
  * Performance optimization patterns
* `AI-ParamML-Functions-Reference.md` - **Function library reference**
  * Mathematical, geometric, and alignment functions
  * Array operations (map, filter, reduce)
  * String manipulation and utility functions

**Task-Specific Guides (Read When Needed):**

* `AI-FEA-Guide.md` - Finite Element Analysis
  * FENode, FELine, FESurf element types
  * Boundary conditions, loads, analysis cases
  * Mesh generation and node merging
* `AI-3D-Visualization-Guide.md` - 3D Geometry
  * Point, Line, Surface, Volume primitives
  * Texture mapping and materials
  * Parametric shapes and extrusions
* `AI-Bridge-Alignment-Guide.md` - Bridge Alignments
  * Horizontal and vertical alignment functions
  * Superelevation and cross-slope
  * Station-based positioning

## Key Concepts (Quick Reference)

### 1. XML Object Structure

```xml
<O N="ObjectName" T="ObjectType">
  <P N="ParameterName" V="Expression" Role="Input" UT="Length"/>
  <!-- Child objects -->
</O>
```

### 2. Parameter Roles

* `Role="Input"` - User-editable, automatically exported (accessible to other objects)
* `Role="Private"` - Internal calculations, not exported
* No role - Private by default

### 3. Export Objects

To export computed parameters, place them inside `<O T="Export">` containers. Parameters inside Export objects are automatically accessible to other objects.

**Important Dependency Rule:** If an exported parameter depends on other parameters, those dependencies must also be exported OR have `Role="Input"`.

**Naming Export Objects:** Export objects can have names (e.g., `<O N="MyExport" T="Export">`). This is useful when extending objects, as named Export groups can be overridden with `Override="1"`.

```xml
<!-- ❌ WRONG - param3 depends on non-exported parameters -->
<O T="Group">
  <P N="param1" V="12"/>
  <P N="param2" V="13"/>
</O>
<O T="Export">
  <P N="param3" V="param1+param2"/>  <!-- ERROR: param1, param2 not accessible -->
</O>

<!-- ✅ CORRECT - Option 1: Put dependencies in Export (with name for override) -->
<O N="Calculations" T="Export">
  <P N="param1" V="12"/>
  <P N="param2" V="13"/>
  <P N="param3" V="param1+param2"/>
</O>

<!-- ✅ CORRECT - Option 2: Use Role="Input" for dependencies -->
<O T="Group">
  <P N="param1" V="12" Role="Input"/>
  <P N="param2" V="13" Role="Input"/>
</O>
<O T="Export">
  <P N="param3" V="param1+param2"/>
</O>

<!-- Override Export in extended object -->
<O N="DerivedObject" T="Project" Extends="BaseObject">
  <O N="Calculations" T="Export" Override="1">
    <P N="param1" V="100"/>  <!-- Override values -->
    <P N="param3" V="param1*param2"/>  <!-- Override formula -->
  </O>
</O>
```

**For more details:** See `AI-Export.md`

### 4. Library Objects (Templates)

```xml
<O N="MyLibraryObject" T="Project" Tags="@library" ObjLabel="Display Name">
  <!-- Input parameters - automatically exported -->
  <P N="Width" V="24" Role="Input"/>
  <P N="Height" V="12" Role="Input"/>

  <!-- Export computed results -->
  <O N="Results" T="Export">
    <P N="Area" V="Width*Height"/>  <!-- Can access Input parameters -->
  </O>
</O>

<!-- Use the template -->
<O N="Instance1" T="MyLibraryObject">
  <P N="Width" V="30"/>  <!-- Override -->
</O>
```

### 5. Extending Objects

Use `Extends` attribute to inherit from other objects. For multiple inheritance, use array syntax.

```xml
<!-- Single inheritance -->
<O N="DerivedObject" T="Project" Extends="BaseObject">
  <P N="Width" V="50"/>  <!-- Override parent parameter -->
</O>

<!-- Multiple inheritance -->
<O N="CombinedObject" T="Project" Extends="[BaseObject1,BaseObject2]">
  <!-- Inherits from both objects -->
</O>
```

### 6. Object References

* `@ObjectName|ObjectType` - Reference by name and type
* `ObjectName.ParameterName` - Access object parameters
* `RepeatName[i].ParameterName` - Array access in Repeat loops
* `RepeatName[i-1].ParameterName` - Access previous iteration

### 7. Coordinate Format

**ALWAYS use inline X-Y-Z attributes (no spaces in expressions):**

```xml
<!-- ✅ CORRECT -->
<O T="Point" N="Pt" X="i*10" Y="0" Z="0" />
<O T="FENode" N="NODE" X="j*120" Y="i*120" Z="0">
  <P N="Tz" V="1"/>
</O>

<!-- ❌ WRONG (nested P elements, spaces in math) -->
<O T="Point" N="Pt">
  <P N="X" V="i * 10"/>
  <P N="Y" V="0"/>
  <P N="Z" V="0"/>
</O>
```

### 8. Repeat Loops

```xml
<O T="Repeat" N="Points" S="0" E="10" I="1" CTRL="i" i="0">
  <O T="Point" N="Pt" X="i*12" Y="0" Z="0" />
</O>

<!-- Access previous element -->
<O T="Repeat" N="Segments" S="0" E="5" I="1" CTRL="i" i="0">
  <O T="Segment" N="Seg">
    <P N="StartX" V="i > 0 ? Segments[i-1].EndX : 0"/>
  </O>
</O>
```

### 9. Performance Rules

* **Use Repeat ONLY for creating objects** (Points, Lines, FENodes, etc.)
* **Use map() for data transformations** - 100x faster than Repeat
* **Use filter() for selecting subsets**
* **Use reduce() for aggregations**

```xml
<!-- ✅ CORRECT -->
<P N="Results" V="map(InputList, x => x * 2)"/>

<!-- ❌ WRONG (creates unnecessary objects) -->
<O T="Repeat" N="Loop" S="0" E="99">
  <P N="Result" V="InputList[i] * 2"/>
</O>
```

## Working with This Code

### Step 1: Read Documentation Guides

**Before starting any task**, read the relevant AI guides:

1. **Always read first**: `AI-Parametric-Engine-Guide.md` (core foundation)
2. If working with FEA: `AI-FEA-Guide.md`
3. If using functions: `AI-ParamML-Functions-Reference.md`
4. If working with 3D geometry: `AI-3D-Visualization-Guide.md`
5. If working with alignments: `AI-Bridge-Alignment-Guide.md`

### Step 2: Understand the Object Type

* **Library Objects**: `T="Project"` with Tags - reusable templates
* **Geometry**: Point, Line, Surface, Volume
* **FEA**: FENode, FELine, FESurf, FEGroup
* **Structural**: Girder, Column, Deck, Bearing
* **Analysis**: AnalysisCase, LoadCase, LoadCombination

### Step 3: Follow XML Formatting Standards

* Use inline X-Y-Z attributes for coordinates
* No spaces around operators in expressions (e.g., `i*12` not `i * 12`)
* Self-closing tags when no children: `<O T="Point" .../>`
* Comments for clarity: `<!-- Description -->`

### Step 4: Parameter Best Practices

* Use `Role="Input"` for user-editable values (automatically exported)
* Place computed results inside `<O T="Export">` containers
* Include `UT` (UnitType) for engineering values
* Add `D` (Description) for documentation
* Ensure exported parameters only depend on other exported params or `Role="Input"` params

### Step 5: Test Expressions

* All expressions use JavaScript syntax
* Lazy evaluation - computed only when needed
* Ternary operators: `condition ? trueValue : falseValue`
* Math functions: `sin()`, `cos()`, `sqrt()`, `abs()`, etc.
* Array functions: `map()`, `filter()`, `reduce()`, `sum()`, `max()`, `min()`

## Common Patterns

### Creating Library Components

```xml
<O N="StandardGirder" T="Project"
   Tags="@library,structural,girder"
   ObjLabel="Standard Steel Girder"
   Category="Structural Components:Girders">

  <!-- Inputs - automatically exported -->
  <P N="Span" V="120" Role="Input" UT="Length"/>
  <P N="Depth" V="72" Role="Input" UT="Length"/>

  <!-- Internal calculations (private, not exported) -->
  <P N="SectionModulus" V="Depth^3/6"/>

  <!-- Export results - can access Role="Input" parameters -->
  <O T="Export">
    <P N="Weight" V="Span*Depth*0.49" UT="Force"/>

    <!-- Export geometry -->
    <O T="Line" N="Geometry">
      <O T="Point" X="0" Y="0" Z="0"/>
      <O T="Point" X="Span" Y="0" Z="0"/>
    </O>
  </O>
</O>
```

### FEA Mesh Generation

```xml
<!-- Node grid -->
<O T="Repeat" N="NodeRows" S="0" E="3" I="1" CTRL="i" i="0">
  <O T="Repeat" N="NodeCols" S="0" E="3" I="1" CTRL="j" j="0">
    <O T="FENode" N="NODE" X="j*120" Y="i*120" Z="0">
      <P N="Tz" V="(i==0 || i==3) ? 1 : 0"/>  <!-- Pin edges -->
    </O>
  </O>
</O>

<!-- Elements -->
<O T="Repeat" N="ElemRows" S="0" E="2" I="1" CTRL="i" i="0">
  <O T="Repeat" N="ElemCols" S="0" E="2" I="1" CTRL="j" j="0">
    <O T="FESurfMITC4" N="SHELL">
      <P N="Node1" V="@NODE_{i}_{j}|FENode"/>
      <P N="Node2" V="@NODE_{i}_{j+1}|FENode"/>
      <P N="Node3" V="@NODE_{i+1}_{j+1}|FENode"/>
      <P N="Node4" V="@NODE_{i+1}_{j}|FENode"/>
    </O>
  </O>
</O>
```

### Alignment-Based Positioning

```xml
<O T="Point" N="BridgePoint"
   X="alignHX(Centerline, Station, Offset)"
   Y="alignHY(Centerline, Station, Offset)"
   Z="alignV(Centerline, Station)+alignT(Centerline, Station, Offset)">
  <P N="Station" V="100" Role="Input"/>
  <P N="Offset" V="10" Role="Input"/>
</O>
```

### Referencing Objects Pattern (Bidirectional References)

Use this pattern to create automatic two-way references between parent and child objects.

**Use Cases:**

* Girder → Cross Frames (bracings)
* Pier Column → Foundation
* Deck → Barrier

```xml
<!-- PARENT: Girder -->
<O N="OBPBase_Girder" T="Project">
    <O N="Referencing Objects" T="Group">
        <P N="bracings" V="[]" D="Cross Frames" Role="Input" Category="Referencing Objects" />
        <O T="ParamInfo" Param="bracings" Required="0" ReadOnly="1" />
    </O>
</O>

<!-- CHILD: CrossFrame -->
<O N="OBPBase_CrossFrame" T="Project">
    <O N="General" T="Group">
        <P N="Girders" V="[]" T="OBPBase_Girder" D="Girders" Role="Input" />
        <O T="ParamInfo" Param="Girders" Min="2" Max="2" Required="1" RefParam="@bracings"/>
    </O>
</O>
```

**Key Points:**

* Parent has `ReadOnly="1"` list in "Referencing Objects" group
* Child uses `RefParam="@bracings"` to register itself with parent
* System automatically adds/removes child from parent's list
* Other objects can navigate through references (e.g., Deck takes girder list, then accesses `girder.bracings` to reach cross frame data)

## File Types

* `.md` - Markdown documentation (AI guides)
* `.xml` - XML data files (library objects, type definitions)
* `.ts` - TypeScript source code (ParamML engine implementation)

## Common Tasks

### Adding New Library Objects

1. Read: `AI-Parametric-Engine-Guide.md` (Library Objects section)
2. Define `T="Project"` with proper Tags and Category
3. Add `Role="Input"` parameters for user configuration (automatically exported)
4. Add internal calculations (no role - private by default)
5. Create `<O T="Export">` for computed results that need to be accessible externally
6. Ensure exported params only depend on other exported params or `Role="Input"` params

### Creating FEA Models

1. Read: `AI-FEA-Guide.md`
2. Create nodes with `T="FENode"` (use X, Y, Z attributes)
3. Create elements (FELine, FESurf, FEVolume)
4. Define boundary conditions (Tx, Ty, Tz, Rx, Ry, Rz)
5. Create analysis cases and load combinations
6. Reference nodes using `@NodeName|FENode`

### Working with 3D Geometry

1. Read: `AI-3D-Visualization-Guide.md`
2. Use Point, Line, Surface, Volume types
3. Define coordinates with inline X, Y, Z attributes
4. Use Repeat for parametric arrays
5. Apply materials and textures as needed

## Code Review Checklist

When reviewing ParamML code, systematically check for these common issues:

### 1. Parameter Name Validation

**Check:** All parameter overrides use correct names from parent object

```xml
<!-- ❌ BAD: Typo in parameter name -->
<O N="MyGirder" Extends="StandardGirder">
  <P N="Lenght" V="120"/>  <!-- Typo: should be "Length" -->
</O>

<!-- ✅ GOOD: Correct parameter names -->
<O N="MyGirder" Extends="StandardGirder">
  <P N="Length" V="120"/>
</O>
```

**How to Check:**

1. Open `__dep__ParentObjectName.xml` file
2. List all `Role="Input"` parameters
3. Verify each override matches an actual parameter name
4. Flag typos or non-existent parameter names

### 2. Complete Parameter Overrides (Extends)

**Check:** All parameters affecting referenced child objects are overridden

```xml
<!-- ❌ BAD: Using StiffenerGroup but not setting NumStiffeners -->
<O N="MyGirder" Extends="StandardGirder">
  <P N="Length" V="120"/>
  <!-- Missing: NumStiffeners -->
</O>
<P N="Count" V="MyGirder.StiffenerGroup.Count"/>  <!-- BUG! -->

<!-- ✅ GOOD: Set all parameters affecting groups you use -->
<O N="MyGirder" Extends="StandardGirder">
  <P N="Length" V="120"/>
  <P N="NumStiffeners" V="5"/>
</O>
<P N="Count" V="MyGirder.StiffenerGroup.Count"/>
```

**How to Check:**

1. Find all references to child objects: `ObjectName.ChildGroup.Property`
2. Open `__dep__` file, trace which input parameters affect those child objects
3. Verify ALL those parameters are either:
   * Overridden with appropriate values
   * Left as default AND defaults make sense for this use case

### 3. Coordinate Format Standards

**Check:** All coordinates use inline X-Y-Z attributes, no spaces in math

```xml
<!-- ❌ BAD -->
<O T="Point" N="Pt">
  <P N="X" V="i * 10"/>
</O>

<!-- ✅ GOOD -->
<O T="Point" N="Pt" X="i*10" Y="0" Z="0" />
```

### 4. Performance: Repeat vs map() and StaticParams

**Check:** Using Repeat only for objects, map() for data transformations

```xml
<!-- ❌ BAD: Using Repeat for calculations -->
<O T="Repeat" N="Loop" S="0" E="99">
  <P N="Result" V="InputList[i] * 2"/>
</O>

<!-- ✅ GOOD: Using map() -->
<P N="Results" V="map(InputList, x => x * 2)"/>
```

**Check:** Using StaticParams for constant parameters in Repeat loops

**IMPORTANT:** StaticParams value must be enclosed in square brackets `[]`.

```xml
<!-- ❌ INEFFICIENT: Re-evaluates Spacing every iteration -->
<O T="Repeat" N="Points" S="0" E="10" CTRL="i">
  <P N="Spacing" V="12"/>
  <O T="Point" X="i*Spacing" Y="0" Z="0"/>
</O>

<!-- ❌ WRONG: Missing square brackets -->
<O T="Repeat" N="Points" S="0" E="10" CTRL="i" StaticParams="Spacing">
  ...
</O>

<!-- ✅ CORRECT: StaticParams with square brackets -->
<O T="Repeat" N="Points" S="0" E="10" CTRL="i" StaticParams="[Spacing]">
  <P N="Spacing" V="12"/>
  <O T="Point" X="i*Spacing" Y="0" Z="0"/>
</O>

<!-- ✅ CORRECT: Multiple static params -->
<O T="Repeat" N="Points" S="0" E="10" CTRL="i" StaticParams="[Spacing,Offset,Material]">
  <P N="Spacing" V="12"/>
  <P N="Offset" V="5"/>
  <O T="Point" X="i*Spacing+Offset" Y="0" Z="0"/>
</O>
```

**How to Check:**

1. Find all Repeat loops
2. Identify parameters that don't depend on loop variable (i, j, etc.)
3. Add those parameter names to StaticParams attribute
4. Format: `StaticParams="[Param1,Param2,Param3]"` (with square brackets!)

### 5. FEA Content Separation

**Check:** FEA-specific code should reference AI-FEA-Guide.md

* FENode, FELine, FESurf, FEGroup → FEA-specific
* Point, Line, Surface, Volume → General geometry

### 6. Input Parameter Renaming - Breaking Changes

**Check:** Renaming `Role="Input"` parameters in **workflow objects** requires backwards compatibility

**Critical Rule:** If a library object appears in a **Workflow** (check `*Workflow*.xml` files), renaming its `Role="Input"` parameters is a **breaking change** for end users.

**Why This Matters:**

* End users have saved projects with parameter values using old names
* Renaming parameters loses user's saved values (silent failure)
* Users must manually re-enter all values - **unacceptable UX**

**Problem Example:**

```xml
<!-- User's project (created 6 months ago): -->
<O N="MyObject" T="SomeWorkflowObject">
  <O N="InputGroup" T="Group">
    <P N="WidthOld" V="25"/>     <!-- User entered 25 -->
    <P N="HeightOld" V="30"/>    <!-- User entered 30 -->
  </O>
</O>

<!-- Developer renames parameters: -->
<!-- OLD: WidthOld, HeightOld -->
<!-- NEW: WidthNew, HeightNew -->

<!-- ❌ RESULT: User updates software version -->
<!-- WidthOld = 25 → LOST (falls back to default) -->
<!-- HeightOld = 30 → LOST (falls back to default) -->
<!-- User's values are silently ignored! -->
```

**Solution:**

If renaming `Role="Input"` parameters in workflow objects, **implement backwards compatibility** to preserve old parameter values. This ensures users don't lose their saved data when updating software versions.

**Best Practice:**

* **Check workflow files** before renaming to see if object is user-facing
* If object is in workflow → Backwards compatibility may be needed to preserve user data
* If object is NOT in workflow → Update dependent objects in same branch
* Document parameter renames in release notes

### 7. DesignRun Object Completeness Check (DR Objects)

**Check:** For DesignRun (DR) objects, verify all Base object's `Role="Input"` parameters are mapped in `T="DesignRun"` group

**What are DR Objects?**

* DR (DesignRun) objects are wrapper objects that execute Base library objects with user-provided inputs
* They map user inputs from the DR object's interface to the Base object's parameters
* Pattern: `*OBPDR_*.xml` files contain DR objects, they reference `*OBPBase_*.xml` files
* File naming: Base object `OBPBase_MyObject.xml` → DR object `OBPDR_MyObject.xml`

**Structure:**

```xml
<!-- DR Object Structure -->
<O N="MyDRObject" T="Project">
    <!-- User input parameters (DR interface) -->
    <O N="General" T="Group">
        <P N="userInput1" V="..." Role="Input" Category="General"/>
        <P N="userInput2" V="..." Role="Input" Category="General"/>
    </O>

    <!-- DesignRun group - maps to Base object -->
    <O N="STGLR" T="DesignRun">
        <P N="LibObjTypeName" V="OBPBase_MyObject" T="Text"/>
        <P N="LibObjVersion" V="1"/>

        <!-- Map ALL Base Role="Input" parameters here -->
        <P N="baseInputParam1" V="userInput1"/>
        <P N="baseInputParam2" V="userInput2"/>

        <!-- WARNING: Can also override non-Input parameters -->
        <P N="baseCalculatedParam" V="customValue"/>
    </O>
</O>
```

**Why This Matters:**

* **Missing Input parameters** → Base uses default values instead of user inputs → **Silent failures**
* **Users lose control** over critical design parameters
* **Results may be incorrect** without any warning
* Incomplete mapping is the **#1 cause** of DR object bugs

**⚠️ WARNING: DesignRun Non-Input Parameter Override**

DesignRun has a **dangerous capability** that must be carefully controlled:

**The Problem:**

* DesignRun can override **ANY parameter** in the Base object, not just `Role="Input"` parameters
* When you override a non-Input parameter, **ALL occurrences** of that parameter in the Base object scope are overridden
* This is **NOT recommended** and should be avoided in most cases

**Example - Unintended Override:**

```xml
<!-- Base Object -->
<O N="OBPBase_MyCodeCheck" T="Project">
    <P N="width" V="10" Role="Input"/>
    <P N="height" V="20" Role="Input"/>

    <!-- Internal calculation parameter - NOT an Input -->
    <P N="safety_factor" V="1.5"/>

    <P N="area" V="width * height"/>
    <P N="capacity" V="area * safety_factor"/>
    <P N="check1" V="capacity * safety_factor"/>
    <P N="check2" V="width * safety_factor"/>
</O>

<!-- DR Object - PROBLEMATIC -->
<O N="OBPDR_MyCodeCheck" T="Project">
    <P N="userWidth" V="15" Role="Input"/>
    <P N="userHeight" V="25" Role="Input"/>
    <P N="userFactor" V="2.0" Role="Input"/>

    <O N="Run" T="DesignRun">
        <P N="LibObjTypeName" V="OBPBase_MyCodeCheck" T="Text"/>

        <!-- OK: Map Input parameters -->
        <P N="width" V="userWidth"/>
        <P N="height" V="userHeight"/>

        <!-- ⚠️ PROBLEM: Overriding non-Input parameter -->
        <P N="safety_factor" V="userFactor"/>
        <!-- This overrides safety_factor EVERYWHERE in Base:
             - capacity calculation
             - check1 calculation
             - check2 calculation
             ALL will now use 2.0 instead of 1.5 -->
    </O>
</O>
```

**When This Happens:**

* ❌ **Breaks Base object's internal logic** - calculated parameters no longer use intended values
* ❌ **Creates maintenance nightmare** - changes to Base don't behave as expected
* ❌ **Violates separation of concerns** - DR should only provide input data, not override calculations
* ❌ **Hard to debug** - override affects multiple locations silently

**What To Do Instead:**

**If user needs to control a parameter that's not `Role="Input"`:**

1. **Add `Role="Input"` to that parameter in the Base object**

   ```xml
   <!-- Fix in Base object -->
   <P N="safety_factor" V="1.5" Role="Input"/>
   ```

   * Makes it officially part of the Base object's API
   * Clear to all developers that this parameter is meant to be configurable
   * Proper design pattern
2. **If parameter should remain internal:**
   * Do NOT override it from DR
   * Modify Base object logic if behavior needs to change
   * Keep data override (DR) separate from logic (Base)

**How to Check:**

**Step 1:** Identify the Base object reference

```xml
<O N="STGLR" T="DesignRun">
    <P N="LibObjTypeName" V="OBPBase_MyObject" T="Text"/>
</O>
```

**Step 2:** Extract all `Role="Input"` parameters from Base object

* Open the corresponding Base file (e.g., `OBPBase_MyObject.xml`)
* Find ALL parameters with `Role="Input"` attribute
* Create a list of these parameter names (these MUST be mapped)

**Step 3:** Verify each Base input exists in DesignRun group

* Check the `<O N="..." T="DesignRun">` group in the DR file
* Verify EVERY Base `Role="Input"` parameter has a corresponding `<P N="paramName" .../>` entry
* Parameter names must match EXACTLY (no spaces, correct spelling)

**Step 4:** Check for non-Input parameter overrides

* Identify any parameters in DesignRun that are NOT `Role="Input"` in Base
* These are **problematic overrides** that should be flagged
* Review why these exist and if Base object should be modified instead

**Step 5:** Check for naming errors

* Watch for trailing/leading spaces: `N="param "` vs `N="param"`
* Watch for typos or case sensitivity issues
* Parameter names must match Base object exactly (character-by-character)

**Automated Check (PowerShell):**

```powershell
# Extract Base Role="Input" parameters
$baseLines = Get-Content 'OBPBase_MyObject.xml'
$baseInputs = @()
foreach ($line in $baseLines) {
    if ($line -match 'Role="Input"' -and $line -match '<P\s+N="([^"]+)"') {
        $baseInputs += $matches[1]
    }
}

Write-Host "Base object has $($baseInputs.Count) Role='Input' parameters"

# Extract DR DesignRun parameters
$drLines = Get-Content 'OBPDR_MyObject.xml'
$designRunStart = -1
$designRunEnd = -1

# Find DesignRun group boundaries
for ($i = 0; $i -lt $drLines.Count; $i++) {
    if ($drLines[$i] -match '<O\s+[^>]*T="DesignRun"') {
        $designRunStart = $i
    }
    if ($designRunStart -gt -1 -and $designRunEnd -eq -1 -and $drLines[$i] -match '^\s*</O>\s*$') {
        $designRunEnd = $i
        break
    }
}

# Extract DesignRun parameters
$drParams = @()
for ($i = $designRunStart; $i -le $designRunEnd; $i++) {
    if ($drLines[$i] -match '<P\s+N="([^"]+)"') {
        $drParams += $matches[1]
    }
}

Write-Host "DesignRun group has $($drParams.Count) parameters mapped"

# Find missing Input parameters
$missing = @()
foreach ($param in $baseInputs) {
    if ($drParams -notcontains $param) {
        $missing += $param
    }
}

# Report missing inputs
if ($missing.Count -eq 0) {
    Write-Host "`n✅ All Base Role='Input' parameters are mapped in DesignRun"
} else {
    Write-Host "`n❌ ERROR: Missing $($missing.Count) Role='Input' parameters in DesignRun:"
    foreach ($param in $missing) {
        for ($i = 0; $i -lt $baseLines.Count; $i++) {
            if ($baseLines[$i] -match "N=`"$param`"" -and $baseLines[$i] -match 'Role="Input"') {
                Write-Host "  - $param (Base line $($i + 1))"
                break
            }
        }
    }
}

# Check for non-Input parameter overrides
$drNonInputOverrides = @()
foreach ($param in $drParams) {
    if ($baseInputs -notcontains $param -and $param -ne 'LibObjTypeName' -and $param -ne 'LibObjVersion') {
        $drNonInputOverrides += $param
    }
}

if ($drNonInputOverrides.Count -gt 0) {
    Write-Host "`n⚠️  WARNING: $($drNonInputOverrides.Count) non-Input parameter(s) overridden:"
    $drNonInputOverrides | ForEach-Object { Write-Host "  - $_" }
    Write-Host "`nThese overrides are PROBLEMATIC because:"
    Write-Host "  1. They override internal Base object calculations"
    Write-Host "  2. They affect ALL occurrences of these parameters in Base"
    Write-Host "  3. They violate separation of data (DR) and logic (Base)"
    Write-Host "`nRECOMMENDATION:"
    Write-Host "  - If users need to control these parameters: Add Role='Input' to Base object"
    Write-Host "  - If parameters should remain internal: Remove these overrides from DR"
}
```

**Common Issues:**

1. **Forgotten Input Parameters:** New `Role="Input"` added to Base but not mapped in DR
2. **Spacing Errors:** `N="param "` (with space) vs `N="param"` (correct)
3. **Typos:** Parameter name misspellings
4. **Version Mismatch:** DR references old Base version, missing new parameters
5. **Unintended Non-Input Overrides:** DR overrides calculated parameters (MUST FIX)

**Best Practice:**

* **Always map ALL `Role="Input"` parameters** from Base to DR (mandatory)
* **NEVER override non-Input parameters** in DesignRun
* When adding new `Role="Input"` to Base → immediately add to corresponding DR
* Use automated scripts during code review to verify completeness
* If non-Input override is found → add `Role="Input"` to Base or remove override from DR

***

**Review Process:**

When user says "review the code":

1. ✅ **Validate parameter names** against `__dep__` files
2. ✅ **Check complete overrides** for all referenced child objects
3. ✅ **Verify coordinate format** (inline X-Y-Z, no spaces)
4. ✅ **Check Repeat optimization** (use map() for data, StaticParams for constants)
5. ✅ **Check formatting** (no spaces in math: `i*12` not `i * 12`)
6. ✅ **Check input parameter renames** (if workflow files exist and parameters renamed, warn user about backwards compatibility)
7. ✅ **Check DesignRun completeness** (for DR objects with `T="DesignRun"`: find the Base object via `LibObjTypeName` parameter, verify all Base `Role="Input"` parameters are mapped in DesignRun group, flag any non-Input parameter overrides)

## Important Notes

⚠️ **Always read the AI documentation guides before starting work** (start with AI-Parametric-Engine-Guide.md)

⚠️ **Understand file types:**

* **Main objects** (`ObjectName.xml`) - Your working files
* **Dependencies** (`__dep__ObjectName.xml`) - Referenced library objects
* **Guides** (`.md` files) - Documentation to help you understand the system

⚠️ **FEA-specific content belongs in AI-FEA-Guide.md, not AI-Parametric-Engine-Guide.md**

⚠️ **Use inline X-Y-Z attributes for all coordinate definitions**

⚠️ **No spaces in mathematical expressions** (e.g., `i*12` not `i * 12`)

⚠️ **Use map() for data transformations, Repeat only for objects**

⚠️ **Type name is `Surface` not `Surface3D` in XML** (Surface3D is TypeScript class name)

⚠️ **Parameter Scope and Shared Parameters:**

* Parameters in sibling Groups under the same parent CAN access each other
* When parameters are used by multiple sibling Groups, consider organizing them:
  * **Option 1:** Keep shared parameters in one Group if primary usage is there (sibling access works)
  * **Option 2:** Move to parent level for clearer organization and better documentation
  * Both approaches work technically, but Option 2 is preferred for maintainability

**Example:** Shared parameters between CADD drawings and Section geometry:

```xml
<!-- WORKS: Sibling groups can access each other's parameters -->
<O N="CADDrawing" T="Group">
    <P N="SharedParam" V="10" />
    <O N="Drawing1" T="CADD">
        <!-- Can use SharedParam -->
    </O>
</O>
<O N="SectionGeometries" T="Group">
    <O N="Section1" T="Section">
        <P N="Value" V="SharedParam" />  <!-- ✅ WORKS (sibling group access) -->
    </O>
</O>

<!-- BETTER: Move shared parameters to parent level -->
<O N="SharedParameters" T="Group">
    <P N="SharedParam" V="10" />
</O>
<O N="CADDrawing" T="Group">
    <O N="Drawing1" T="CADD">
        <!-- Can use SharedParam -->
    </O>
</O>
<O N="SectionGeometries" T="Group">
    <O N="Section1" T="Section">
        <P N="Value" V="SharedParam" />  <!-- ✅ CLEARER (parent parameter) -->
    </O>
</O>
```

## Getting Help

When you need clarification:

1. Check the relevant AI guide first (AI-Parametric-Engine-Guide.md, AI-FEA-Guide.md, etc.)
2. Search for similar examples in the guides
3. Check `__dep__` files to understand referenced object structures

## Summary

This is a sophisticated parametric modeling system for bridge engineering. The XML files define intelligent, data-driven components that:

* Automatically calculate results from input parameters
* Generate 3D geometry and FEA meshes
* Perform design checks and code compliance
* Update dynamically when parameters change
* Export computed results for use by other objects
* Reference other library objects (downloaded as `__dep__` files)

**Quick Start:**

1. Read `AI-Parametric-Engine-Guide.md` first
2. Examine your main XML files (`ObjectName.xml`)
3. Check `__dep__` files to understand dependencies
4. Follow formatting standards and best practices
5. Create robust, reusable parametric components

***

**Generated for AI Agents working with OpenBrIM ParamML Code**
