# FrameCPP Minimal Frame Utilities

**Utilities for generating minimal test frames across all frame specification versions (v3-v9)**

This guide documents the `framecpp_sample` and `framel_sample` utilities used for creating minimal frame files with precise control over frame contents. These tools are essential for testing, debugging, and validating frame I/O operations.

---

## Table of Contents

- [Overview](#overview)
- [framecpp_sample - FrameCPP Utility](#framecpp_sample---framecpp-utility)
- [framel_sample - FrameL Utility](#framel_sample---framel-utility)
- [Common Usage Patterns](#common-usage-patterns)
- [Testing Workflow](#testing-workflow)
- [Version-Specific Behaviors](#version-specific-behaviors)
- [Troubleshooting](#troubleshooting)

---

## Overview

### What are Minimal Frames?

**Minimal frames** contain only the frame structure you want to test, plus the required frame markers (FrameH, FrEndOfFrame, FrEndOfFile). This isolation approach enables:

- **Targeted testing** - Validate one object type at a time
- **Debugging** - Identify version-specific issues quickly
- **Performance analysis** - Measure I/O overhead per structure
- **Specification compliance** - Verify exact conformance to frame spec

### Available Utilities

| Utility | Library | Versions | Purpose |
|---------|---------|----------|---------|
| `framecpp_sample` | FrameCPP | v3-v9 | Primary testing tool, all versions |
| `framel_sample` | FrameL | v3-v8 | Cross-library validation (optional) |

---

## framecpp_sample - FrameCPP Utility

### Quick Start

```bash
# Generate empty frame (just FrameH)
framecpp_sample --version 6 --enable-empty

# Generate frame with detector metadata
framecpp_sample --version 6 --enable-detector

# Generate frame with ADC data
framecpp_sample --version 6 --enable-fr-adc

# Generate frame with multiple objects
framecpp_sample --version 6 --enable-detector --enable-fr-adc --enable-fr-proc-data
```

### Command-Line Options

#### Basic Options

```
--help, -h
    Print help message with all available options

--version <version>
    Frame specification version (3, 4, 5, 6, 7, 8, or 9)
    Default: 8

--description <string>
    Custom description for filename
    Default: "ilwd_test_frame"
    Output: Z-<description>-<gps_time>-<duration>.gwf

--start-time <gps_seconds>
    GPS start time in seconds
    Default: 600000000 (1999-01-14)

--duration <seconds>
    Frame duration in seconds
    Default: 1

--disable-toc
    Disable Table of Contents (FrTOC) generation
    Creates frame without TOC structure (slower random access)
```

#### Minimal Frame Mode (--enable-* flags)

When any `--enable-*` flag is used, framecpp_sample enters **minimal frame mode**:
- Creates empty frame via `createEmptyFrame()`
- Adds only the requested structures
- Automatically sets `minimal_frame_mode = true`

```
--enable-empty
    Generate truly empty frame (just FrameH, no data objects)
    Useful for: TOC validation, baseline I/O testing

--enable-detector
    Add FrDetector structure (detector metadata)
    Versions: v3-v9

--with-detector-name <string>
    Set custom detector name (requires --enable-detector)
    Default: "TestDetector"
    Example: --with-detector-name "LIGO_Hanford"

--enable-history
    Add FrHistory structure (processing history)
    Versions: v3-v9

--with-history-msg <string>
    Set custom history message (requires --enable-history)
    Default: "Created by framecpp_sample"
    Example: --with-history-msg "Test frame for debugging"

--enable-fr-adc
    Add FrAdcData structure (ADC channel data)
    Versions: v3-v9
    ⭐ Most critical for data analysis workflows

--enable-fr-proc-data
    Add FrProcData structure (processed/calibrated data)
    Versions: v3-v9

--enable-fr-sim-data
    Add FrSimData structure (simulated data)
    Versions: v3-v9

--enable-fr-ser-data
    Add FrSerData structure (serial data streams)
    Versions: v3-v9

--enable-fr-event
    Add FrEvent structure (event/trigger data)
    Versions: v3-v9
    Note: Called FrTrigData in v3-v4

--enable-fr-msg
    Add FrMsg structure (message log)
    Versions: v3-v9

--enable-fr-sim-event
    Add FrSimEvent structure (simulated events)
    Versions: v4-v9 (introduced in v4)

--enable-fr-summary
    Add FrSummary structure (summary/trend data)
    Versions: v3-v9

--enable-fr-stat-data
    Add FrStatData structure (static detector data)
    Versions: v3-v8 (deprecated in v9)

--enable-fr-table
    Add FrTable structure (tabular data with FrVect columns)
    Versions: v4-v9 (introduced in v4)

--enable-fr-rawdata
    Add FrRawData container (multi-object raw data container)
    Versions: v3-v9
    Contains: FrAdcData + FrSerData
```

#### Legacy Mode

```
--test-frame-mode
    Generate full test frame with all structures
    Default mode when NO --enable-* flags specified
    Use: Backward compatibility testing
```

### Output Filenames

Filename format: `Z-<description>[-notoc]-<gps_time>-<duration>.gwf`

Examples:
```bash
# Default description
framecpp_sample --version 6 --enable-detector
# → Z-test_detector_v6-600000000-1.gwf

# Custom description
framecpp_sample --version 6 --description my_test --enable-fr-adc
# → Z-my_test-600000000-1.gwf

# With --disable-toc
framecpp_sample --version 6 --enable-detector --disable-toc
# → Z-test_detector_v6_notoc-600000000-1.gwf
```

### Usage Examples

#### Example 1: Testing ADC Data Across All Versions

```bash
# Generate v3-v9 test frames
for ver in 3 4 5 6 7 8 9; do
    framecpp_sample --version $ver --enable-fr-adc \
                    --description test_adc_v${ver}
done

# Validate with framecpp_dump_toc
for file in Z-test_adc_*.gwf; do
    echo "=== $file ==="
    framecpp_dump_toc $file | grep nADC
done
```

#### Example 2: Custom Detector Configuration

```bash
# LIGO Hanford detector
framecpp_sample --version 8 \
                --enable-detector \
                --with-detector-name "LIGO_Hanford" \
                --description hanford_detector

# LIGO Livingston detector
framecpp_sample --version 8 \
                --enable-detector \
                --with-detector-name "LIGO_Livingston" \
                --description livingston_detector
```

#### Example 3: Multi-Object Frame for Integration Testing

```bash
# Complex frame with detector, ADC, and processed data
framecpp_sample --version 9 \
                --enable-detector \
                --enable-fr-adc \
                --enable-fr-proc-data \
                --description integration_test

# Verify contents
framecpp_dump_toc Z-integration_test-600000000-1.gwf
```

#### Example 4: TOC Validation Testing

```bash
# Generate frame with TOC (default)
framecpp_sample --version 7 --enable-fr-sim-data \
                --description test_with_toc

# Generate frame without TOC
framecpp_sample --version 7 --enable-fr-sim-data \
                --disable-toc \
                --description test_no_toc

# Compare file sizes (TOC adds overhead)
ls -lh Z-test_*_toc*.gwf
```

#### Example 5: Empty Frame Baseline

```bash
# Smallest possible frame (just FrameH)
framecpp_sample --version 6 --enable-empty \
                --description baseline

# Measure baseline I/O overhead
time framecpp_dump_toc Z-baseline-600000000-1.gwf
```

---

## framel_sample - FrameL Utility

### Purpose

Cross-library validation tool that generates frames using the **FrameL library** for comparison with FrameCPP output. Enables bidirectional compatibility testing.

### Availability

- **Compile-time conditional**: Only built if `FRAMEL_FOUND`
- **Version support**: v3-v8 only (FrameL doesn't support v9)
- **Object support**: Subset of FrameCPP objects (see table below)

### Supported Objects

| Object | FrameCPP | FrameL | Versions |
|--------|----------|--------|----------|
| FrDetector | ✅ | ✅ | v3-v8 |
| FrHistory | ✅ | ✅ | v3-v8 |
| FrAdcData | ✅ | ✅ | v3-v8 |
| FrProcData | ✅ | ✅ | v3-v8 |
| FrSimData | ✅ | ✅ | v3-v8 |
| FrSerData | ✅ | ✅ | v3-v8 |
| FrStatData | ✅ | ✅ | v3-v8 |
| FrRawData | ✅ | ✅ | v3-v8 |
| FrEvent | ✅ | ❌ | v3-v9 |
| FrMsg | ✅ | ❌ | v3-v9 |
| FrSimEvent | ✅ | ❌ | v4-v9 |
| FrSummary | ✅ | ❌ | v3-v9 |
| FrTable | ✅ | ❌ | v4-v9 |

### Usage

```bash
# Same command-line interface as framecpp_sample
framel_sample --version 6 --enable-fr-adc

# Uses different GPS time (1000000000 vs 600000000)
# Output: Z-test_framel_fr-adc_v6l-1000000000-1.gwf
#                               ↑ 'l' suffix for FrameL
```

### Cross-Library Validation Workflow

```bash
# 1. Generate with FrameCPP
framecpp_sample --version 6 --enable-fr-proc-data \
                --start-time 1000000000 \
                --description test_framecpp

# 2. Generate with FrameL
framel_sample --version 6 --enable-fr-proc-data \
              --description test_framel

# 3. Compare outputs
framecpp_dump_toc Z-test_framecpp-1000000000-1.gwf
framecpp_dump_toc Z-test_framel-1000000000-1.gwf

# 4. Cross-read test (FrameCPP reads FrameL file)
framecpp_query Z-test_framel-1000000000-1.gwf --channels

# 5. Optional: FrCheck validation (if available)
FrCheck -i Z-test_framecpp-1000000000-1.gwf
FrCheck -i Z-test_framel-1000000000-1.gwf
```

---

## Common Usage Patterns

### 1. Version Compatibility Testing

```bash
#!/bin/bash
# Test FrAdcData across all versions

for ver in 3 4 5 6 7 8 9; do
    echo "Testing version $ver..."

    # Generate frame
    framecpp_sample --version $ver \
                    --enable-fr-adc \
                    --description adc_v${ver}

    # Validate structure
    framecpp_dump_toc Z-adc_v${ver}-600000000-1.gwf > v${ver}_toc.txt

    # Optional: FrCheck validation (v6-v8)
    if [ $ver -ge 6 ] && [ $ver -le 8 ]; then
        FrCheck -i Z-adc_v${ver}-600000000-1.gwf
    fi
done

# Compare TOC outputs
diff v3_toc.txt v4_toc.txt
```

### 2. Debugging Frame Read Failures

```bash
# Start with simplest possible frame
framecpp_sample --version 6 --enable-empty

# Add complexity incrementally
framecpp_sample --version 6 --enable-detector
framecpp_sample --version 6 --enable-detector --enable-fr-adc
framecpp_sample --version 6 --enable-detector --enable-fr-adc --enable-fr-proc-data

# Identify which structure causes the failure
```

### 3. Performance Benchmarking

```bash
#!/bin/bash
# Measure I/O performance by object type

structures=("empty" "detector" "fr-adc" "fr-proc-data" "fr-sim-data")

for struct in "${structures[@]}"; do
    # Generate frame
    framecpp_sample --version 8 --enable-${struct} \
                    --description perf_${struct}

    # Benchmark read performance (10 iterations)
    echo "=== $struct ==="
    for i in {1..10}; do
        /usr/bin/time -f "%E elapsed" \
            framecpp_dump_toc Z-perf_${struct}-600000000-1.gwf > /dev/null
    done
done
```

### 4. Automated Test Suite Integration

```cmake
# CMake example from test/CMakeLists.txt

# Generate test frame
add_custom_command(
  OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/test_frame_v6.gwf
  COMMAND $<TARGET_FILE:framecpp_sample>
    --version 6
    --enable-fr-adc
    --description test_frame_v6
  DEPENDS framecpp_sample
  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)

# Validate with CMake test
add_test(
  NAME test_adc_v6
  COMMAND ${CMAKE_COMMAND}
    -DVERSION=6
    -DTEST_TYPE=adc
    -DFRAMECPP_SAMPLE_EXE=$<TARGET_FILE:framecpp_sample>
    -DFRAMECPP_DUMP_TOC_EXE=$<TARGET_FILE:framecpp_dump_toc>
    -DWORK_DIR=${CMAKE_CURRENT_BINARY_DIR}
    -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/verify_toc.cmake
)
```

---

## Testing Workflow

### Test-Driven Development Cycle

```
1. Generate Test Frame
   ↓
   framecpp_sample --version 6 --enable-fr-adc

2. Read and Validate
   ↓
   framecpp_query <file> --channels

3. Cross-Validate (optional)
   ↓
   FrCheck -i <file>

4. Compare with FrameL (optional)
   ↓
   framel_sample --version 6 --enable-fr-adc
   Compare outputs

5. Iterate on Failures
   ↓
   Simplify: --enable-empty → --enable-detector → ...
```

### CMake Test Integration

The test suite uses these utilities via `test/cmake/verify_toc.cmake`:

```bash
# Run all TOC validation tests
ctest -R test_toc

# Run specific version
ctest -R test_toc_.*_v6

# Run specific test type
ctest -R test_toc_detector

# Verbose output
ctest -R test_toc_detector_v6 --verbose
```

---

## Version-Specific Behaviors

### Frame Specification Evolution

| Version | Key Changes | Testing Impact |
|---------|-------------|----------------|
| **v3** | Original spec | Baseline for compatibility |
| **v4** | Added: FrTable, FrSimEvent, dataQuality field | Test with --enable-fr-table |
| **v5** | FrTrigData → FrEvent (rename), amplitudeEvent added | Check field name in TOC |
| **v6** | Added: armLength to FrDetector | --with-detector-name tests |
| **v7** | Added: FrVect representation field | FrVect metadata tests |
| **v8** | Added: nTotalEvent field in FrTOC | TOC validation critical |
| **v9** | Removed: FrStatData (deprecated), added fileBaseName | --enable-fr-stat-data fails |

### Version-Specific Field Names

**FrEvent Field Evolution:**
```bash
# v3-v4: nTrig, nameTrig, GTimeSEvent
framecpp_dump_toc Z-test_v4.gwf | grep nTrig

# v5+: nEventType, nameEvent, GTimeSEvent
framecpp_dump_toc Z-test_v5.gwf | grep nEventType
```

**FrStatData Deprecation:**
```bash
# v3-v8: FrStatData supported
framecpp_sample --version 8 --enable-fr-stat-data  # ✅ Works

# v9: FrStatData removed
framecpp_sample --version 9 --enable-fr-stat-data  # ❌ Error (expected)
```

### TOC Generation Differences

```bash
# v3: No TOC support
framecpp_sample --version 3 --enable-fr-adc
# → TOC still generated by FrameCPP for convenience

# v4+: Full TOC support
framecpp_sample --version 4 --enable-fr-adc
# → Native TOC generation

# Disable TOC (all versions)
framecpp_sample --version 6 --enable-fr-adc --disable-toc
# → File has no FrTOC structure (slower random access)
```

---

## Troubleshooting

### Common Issues

#### Issue: "unrecognised option '--enable-xyz'"

**Cause:** Option not supported for this object type or version

**Solution:**
```bash
# Check supported options
framecpp_sample --help

# Verify version compatibility
# FrTable: v4+ only
framecpp_sample --version 3 --enable-fr-table  # ❌ Fails
framecpp_sample --version 4 --enable-fr-table  # ✅ Works

# FrStatData: v3-v8 only
framecpp_sample --version 9 --enable-fr-stat-data  # ❌ Fails
framecpp_sample --version 8 --enable-fr-stat-data  # ✅ Works
```

#### Issue: "No table of contents (TOC) present in this file"

**Cause:** Frame generated with `--disable-toc`

**Solution:**
```bash
# Regenerate with TOC enabled (default)
framecpp_sample --version 6 --enable-fr-adc

# Or verify TOC is disabled intentionally
framecpp_sample --version 6 --enable-fr-adc --disable-toc
# → Expected behavior for --disable-toc tests
```

#### Issue: TOC counts don't match expectations

**Cause:** Test frame mode vs minimal frame mode confusion

**Solution:**
```bash
# ❌ Wrong: No flags → defaults to full test frame
framecpp_sample --version 6
# → Generates frame with ALL structures

# ✅ Correct: Use --enable-empty for truly empty frame
framecpp_sample --version 6 --enable-empty
# → Generates frame with ONLY FrameH
```

#### Issue: FrameL compatibility errors

**Cause:** Using unsupported objects or v9

**Solution:**
```bash
# ❌ FrameL doesn't support v9
framel_sample --version 9 --enable-fr-adc

# ✅ Use v3-v8 for FrameL
framel_sample --version 8 --enable-fr-adc

# ❌ FrameL doesn't support FrEvent
framel_sample --version 6 --enable-fr-event

# ✅ Use FrameCPP for unsupported objects
framecpp_sample --version 6 --enable-fr-event
```

### Debugging Tips

1. **Start simple**: Use `--enable-empty` baseline
2. **Add incrementally**: Enable one structure at a time
3. **Check TOC**: Use `framecpp_dump_toc` to verify contents
4. **Cross-validate**: Use `FrCheck` for v6-v8 (if available)
5. **Compare versions**: Generate same structure across v3-v9
6. **Read logs**: Look for debug messages in test output

### Getting Help

```bash
# Command-line help
framecpp_sample --help
framel_sample --help

# Test suite documentation
cat test/MINIMAL_FRAME_TEST_PLAN.md

# CMake test list
ctest -N | grep test_

# Validation script details
cat test/cmake/verify_toc.cmake
```

---

## Summary

### Key Takeaways

✅ **Use framecpp_sample for**:
- All versions (v3-v9)
- All object types
- Primary testing and debugging

✅ **Use framel_sample for**:
- Cross-library validation (v3-v8)
- FrameL compatibility testing
- Subset of objects (detector, adc, proc, sim, ser, stat, rawdata)

✅ **Use --enable-* flags for**:
- Minimal frames (one object at a time)
- Targeted testing
- TOC validation

✅ **Use --disable-toc for**:
- Testing frames without TOC
- Performance comparison (TOC overhead)

✅ **Best Practices**:
- Always specify `--version` explicitly
- Use `--description` for meaningful filenames
- Start with `--enable-empty` for debugging
- Validate with `framecpp_dump_toc`
- Cross-check with `FrCheck` when available

---

**For detailed implementation information, see:**
- `src/Utilities/FrSampleCommon.hh` - Shared configuration
- `src/Utilities/FrSample.cc` - FrameCPP implementation
- `test/framel_sample.cc` - FrameL implementation
- `test/cmake/verify_toc.cmake` - Validation script
- `test/MINIMAL_FRAME_TEST_PLAN.md` - Comprehensive test plan
