This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Firebird is a web-based event display framework for particle physics experiments, specifically designed for the Electron-Ion Collider (EIC). It visualizes detector geometries, particle trajectories, and physics processes using modern web technologies. Firebird serves research, debugging/QC, and educational purposes.
Live deployment: https://seeeic.org (Firebird Event Display application) Documentation: https://eic.github.io/firebird/ (VitePress documentation site)
This is a monorepo containing three interdependent components:
- firebird-ng/ - Angular 20 frontend (TypeScript, Three.js, RxJS)
- pyrobird/ - Python Flask backend (file server, ROOT conversion)
- dd4hep-plugin/ - C++ Geant4/DD4Hep plugin (trajectory extraction during simulation)
The documentation source lives in:
- docs/ - VitePress documentation site (deployed to GitHub Pages)
- firebird-ng/src/assets/doc - Documentation embedded in the Angular application
cd firebird-ng
# Development server with hot reload
ng serve # http://localhost:4200
# Testing
npm test # Interactive tests (Karma)
npm run test:headless # CI mode (headless Chrome)
ng test --include='**/my-component.spec.ts' # Run single test file
# Building
npm run build # Production build
npm run build:ghpages # GitHub Pages deployment
npm run build:watch # Watch mode for development
# Generate components (Angular CLI)
ng generate component component-name
ng generate service service-namecd pyrobird
# Development installation with all optional features
python -m pip install --editable .[dev,batch,xrootd]
# Start development server
pyrobird serve # Serves files from CWD
pyrobird serve --work-path=/path/to/data # Restrict to specific directory
gunicorn --bind 0.0.0.0:5454 pyrobird.server:flask_app --log-level debug
# Testing (requires dev dependencies)
pytest ./tests/unit_tests # Run unit tests
pytest ./tests/integration_tests # Run integration tests
pytest -x --pdb # Stop on first error, debug
pytest ./tests/unit_tests/test_cli.py # Run single test file
pytest ./tests/unit_tests/test_cli.py::test_name # Run specific test
# CLI utilities
pyrobird convert input.root output.json # Convert ROOT to Firebird DEX
pyrobird merge file1.json file2.json -o out.json # Merge DEX files
pyrobird geo geometry.root # Extract geometrycd dd4hep-plugin
mkdir build && cd build
cmake ..
make && make install # Installs to ./prefix/lib
# Make library discoverable
cd ..
export LD_LIBRARY_PATH="$(pwd)/prefix/lib:$LD_LIBRARY_PATH"
# Run simulation with plugin
ddsim --steeringFile=firebird_steering.py \
--compactFile=detector.xml \
-N=100 \
--outputFile=sim.edm4hep.root \
--inputFiles=input.hepmc# Root level orchestration
python build.py all # Build frontend and copy to pyrobird
python build.py --dry-run all # Test build without changes
# build all with changing version (source files will be changed)
python build.py all --version=v2025.12.1Firebird is made so that running frontend alone is sufficient for most use cases. Backend serves for:
- some file conversions (e.g. working with xrootd, editing events, etc.)
- serving firebird locally for users
- using pip install for deployment
The Angular application uses a service-oriented architecture with clear separation of concerns:
-
three.service.ts (3700+ lines) - Central Three.js orchestration
- Scene setup (cameras, lights, rendering loop)
- Raycasting for object selection
- BVH (Bounding Volume Hierarchy) acceleration for performance
- Clipping planes and measurement tools
- Frame callbacks for animations
-
event-display.service.ts - High-level event visualization
- Data loading (geometry, events, ROOT files)
- Time animation and event cycling
- Painter orchestration
- Animation manager integration
-
geometry.service.ts - Detector geometry management
- Load and process ROOT geometry files
- Geometry optimization and post-processing
-
data-model.service.ts - Event data management
- Load Firebird DEX format events
- Load EDM4eic ROOT files
- Event registry and navigation
The event group factory pattern enables extensibility:
EventGroup- Abstract base class for all event componentsBoxHitGroup- Tracker hits (3D boxes with energy/time)PointTrajectoryGroup- Particle trajectories (polylines)- Component registry with
registerComponentFactory()for custom types
To add a new component type:
- Extend
EventGroupand implementtoDexObject() - Create a factory implementing
EventGroupFactory - Register the factory at initialization
Painters render event data to Three.js objects using time-aware rendering:
data-model-painter.ts- Main orchestrator (filters by time range)trajectory.painter.ts- Particle tracks with smooth splinesbox-hit.painter.ts- Individual tracker hitsstep-track.painter.ts- Geant4 step-by-step trajectories
The system uses Angular signals for reactive time updates that automatically propagate through the painter hierarchy.
Flask server with three main API endpoints:
GET /api/v1/download- Secure file downloads with access controlGET /api/v1/convert/edm4eic/<event>- Convert EDM4eic events to JSONGET /assets/config.jsonc- Serve dynamic configuration
Security model (restrictive by default):
--work-pathrestricts downloads to specific directory (default: CWD)--allow-any-filedisables path restrictions (DANGEROUS in production)--disable-filesdisables all downloads- Path traversal prevention built-in
Three Geant4 actions for trajectory extraction:
-
FirebirdTrajectoryWriterEventAction (PRIMARY USE CASE)
- Saves trajectories at end of event (same as Geant4 event display)
- Extensive filtering: momentum, vertex position, step cuts, particle type
- Configured via Python steering files
-
FirebirdTrajectoryWriterSteppingAction (CUSTOMIZATION)
- Captures data step-by-step as simulation runs
- Users modify C++ code for custom physics data extraction
- Access to detailed internal Geant4 information
-
TextDumpingSteppingAction (SIMPLE TEXT OUTPUT)
- Easy-to-parse text format for custom analysis
- Example for plugin extension
Standardized JSON format for event data interoperability:
{
"type": "firebird-dex-json",
"version": "0.04",
"origin": {
"source": "filename.root",
"by": "Pyrobird"
},
"events": [
{
"id": "event_0",
"groups": [
{
"name": "BarrelHits",
"type": "BoxTrackerHit",
"hits": [{"pos": [x,y,z], "dim": [dx,dy,dz], "t": [t,dt], "ed": [e,de]}]
},
{
"name": "CentralTracks",
"type": "TrackerLinePointTrajectory",
"lines": [{"points": [[x,y,z,t,dx,dy,dz,dt], ...], "params": [...]}]
}
]
}
]
}Key types:
BoxTrackerHit- 3D box hits with energy/time informationTrackerLinePointTrajectory- Polyline trajectories with metadata- Extensible via factory pattern for custom component types
Component factories enable DEX deserialization without modifying core code. Register new types with registerComponentFactory() in appropriate initialization code (typically in the component's own file or a central registry).
The painter system filters data by time range using Angular signals:
EventTimesignal propagates through painter hierarchy- Components show/hide based on time range
- Tween.js enables smooth animations
three-mesh-bvh provides fast raycasting for object selection:
- Lazy BVH computation on demand
- Frustum culling for performance
- Critical for large detector geometries
Angular services are singletons managing global state:
- Scene management (three.service)
- Event data (data-model.service)
- Configuration (config.service)
- URL parameters (url.service)
Restrictive defaults prevent unauthorized file access:
- Explicit opt-in for dangerous features
- Path traversal prevention
- CORS disabled by default
- Framework: Karma + Jasmine
- CI: GitHub Actions on every push/PR (Node.js 22, headless Chrome)
- Run tests:
npm testornpm run test:headless
- Framework: pytest
- CI: GitHub Actions (Python 3.9-3.12)
- Run tests:
pytest ./tests/unit_tests - Debug:
pytest -x --pdb
- Style: PEP8 required
- Docstrings: NumPy style format
- Type hints: Use throughout
- Exceptions: Use specific exceptions, not generic ones
- Dependencies: Add to
pyproject.tomlwith justification
- Type safety: Strict TypeScript compilation
- Components: Standalone Angular components (Angular 20)
- Reactive programming: RxJS and Angular signals
- Bundle size: 2MB warning, 5MB error limits
- frontend.yaml - Build and test Angular app (CI only, no deployment)
- docs.yaml - Build and deploy VitePress documentation to GitHub Pages
- pyrobird.yaml - Test Python package on multiple Python versions
- integration-tests.yml - Run full integration test suite
The Firebird project uses a split deployment model:
- Firebird Event Display Application - Hosted on https://seeeic.org (separate server)
- VitePress Documentation - Deployed to https://eic.github.io/firebird/ via GitHub Pages
The docs.yaml workflow handles documentation deployment:
- Triggered on push to
mainbranch (whendocs/changes) or manually viaworkflow_dispatch - Builds VitePress documentation from
docs/directory - Deploys to https://eic.github.io/firebird/
To build documentation locally:
cd docs
npm install
npm run build # Build for production
npm run dev # Development server with hot reloadFirebird supports ROOT geometry and event files through pyrobird:
# Extract geometry from ROOT file
pyrobird geo detector.root
# Convert EDM4eic events to DEX format
pyrobird convert simulation.edm4hep.root output.json
# Server can convert events on-the-fly
# GET /api/v1/convert/edm4eic/5?filename=path/to/file.edm4eic.rootfirebird-ng/angular.json- Angular build configuration, bundle size limitsfirebird-ng/package.json- Dependencies, npm scriptsfirebird-ng/tsconfig.json- TypeScript compiler settings (strict mode)pyrobird/pyproject.toml- Python packaging, dependencies, metadatadd4hep-plugin/CMakeLists.txt- C++ build system, DD4Hep/Geant4 integration.github/workflows/- CI/CD pipeline definitionsfirebird-ng/src/assets/config.jsonc- Runtime configuration (geometry, server URLs)
- BVH acceleration - Enable for large geometries (automatic in three.service)
- Bundle size limits - Keep production builds under 2MB (warning at 2MB, error at 5MB)
- Lazy loading - Use Angular route-based code splitting
- Geometry merging - Merge similar geometry for reduced draw calls
- Time-based filtering - Painters only render objects in current time range
- Web Workers - Event loading happens in worker thread (event-loader.worker.ts)
- Create class extending
EventGroupinfirebird-ng/src/app/model/ - Implement
toDexObject()for serialization - Create factory class implementing
EventGroupFactory - Register factory in appropriate initialization code
- Create painter in
firebird-ng/src/app/painters/to render component - Update pyrobird conversion if needed
- Edit steering file (e.g.,
dd4hep-plugin/firebird_steering.py) - Adjust parameters:
MomentumMin,VertexZMin/Max,StepCut,SaveParticles(PDG codes) - Rebuild if modifying C++ code:
cd dd4hep-plugin/build && make && make install
- Add route to
pyrobird/server/__init__.py - Implement handler function
- Add tests in
pyrobird/tests/unit_tests/ - Consider security implications (file access, CORS)
- Update API documentation in README
- Check browser console for Three.js errors
- Use Performance Stats component (toggle in UI)
- Verify DEX format with sample files
- Check painter configuration in scene tree
- Use raycasting component to inspect object properties
- Enable verbose logging:
ng serve --verbose
- Bundle optimization: Angular build enforces size limits. Use
ng build --stats-jsonto analyze. - ROOT file compatibility: pyrobird uses Uproot (pure Python). Some complex ROOT types may require conversion.
- XRootD support: Install with
pip install pyrobird[xrootd]for remote file access. - Docker for DD4Hep: EIC provides
eicweb/eic_xl:nightlywith full HENP stack. - Git LFS: This repository may use Git LFS for large binary files.
- Documentation: User-facing documentation is in
docs/(VitePress site) and also infirebird-ng/src/assets/doc/(embedded in app), including tutorials.