Fiber Bundle Configuration for Multi-Fiber Instruments

Overview

PyReduce supports multi-fiber instruments where each spectral order contains multiple physical fibers. The fibers section in config.yaml defines how these fibers are organized into groups and which traces to use for each reduction step.

Terminology

  • Trace: Polynomial describing one fiber’s path across detector

  • Fiber: Physical fiber in bundle (numbered 1-N within each order/group)

  • Group: Named collection of fibers with semantic meaning (e.g., “A”, “cal”, “B”). Use groups when fibers have distinct roles - science targets, calibration sources, sky fibers, etc.

  • Bundle: Numbered groups of identical fibers (e.g., “bundle_1”, “bundle_2”, …). Use bundles for repeating patterns like IFU spaxels where each bundle has the same structure.

  • Spectral Order: Wavelength range; multi-order instruments have same fiber pattern repeated across orders

  • fiber_idx: Index of a fiber within its group/order (1-indexed). Used for per-fiber wavelength calibration.

In short: groups are for named, semantically distinct fiber sets; bundles are for numbered, structurally identical fiber sets.

Each Trace object has:

  • m: Spectral order number (physical diffraction order)

  • group: Group/bundle identifier (“A”, “B”, “cal”, or bundle index)

  • fiber_idx: Fiber index within the group (1-indexed), or None if merged

Configuration

Named Groups (single-order instruments)

For instruments with explicitly defined fiber groups:

fibers:
  groups:
    A:
      range: [1, 36]      # Fibers 1-35 (1-based, half-open interval)
      merge: average      # Average all fiber traces into one
    cal:
      range: [37, 40]     # Fibers 37-39
      merge: average
    B:
      range: [40, 76]     # Fibers 40-75
      merge: average

  use:
    science: [A, B]       # Science extraction uses A and B groups
    wavecal: [cal]        # Wavelength calibration uses cal fiber
    norm_flat: all        # Flat normalization uses all individual fibers

Bundle Pattern (MOSAIC-style)

For instruments with repeating fiber bundles:

fibers:
  bundles:
    size: 7               # 7 fibers per bundle
    count: 90             # 90 bundles total (optional validation)
    merge: center         # Select middle fiber from each bundle

  use:
    curvature: groups     # Use all 90 bundle centers
    science: groups

Handling Missing/Broken Fibers

When some fibers are broken or missing, the trace count won’t be divisible by bundle size. Use bundle_centers_file to assign traces to bundles by proximity rather than fixed division:

fibers:
  bundles:
    size: 7
    bundle_centers_file: bundle_centers.yaml  # y-position of each bundle center
    merge: center

  use:
    curvature: groups
    science: groups

The bundle_centers.yaml file maps bundle IDs to y-positions at detector center:

# bundle_centers.yaml
1: 3975.0
2: 3932.4
3: 3889.8
# ... etc for all 90 bundles

Each detected trace is assigned to its nearest bundle center. When merging:

  • merge: center with all fibers present: picks middle index (e.g., fiber 4 of 7)

  • merge: center with missing fibers: picks trace closest to bundle_center

  • merge: average: averages all present fibers (no extrapolation for missing)

This approach handles arbitrary patterns of missing fibers without requiring the trace count to be divisible by bundle size.

Per-Order Grouping (echelle multi-fiber)

For echelle instruments where fiber groups repeat across spectral orders (e.g., ANDES_YJH with 75 fibers per order across 18 orders):

fibers:
  fibers_per_order: 75              # Enables per-order organization
  order_centers_file: order_centers.yaml  # Or inline with order_centers:

  groups:
    A:
      range: [1, 36]
      merge: average
    cal:
      range: [37, 40]
      merge: average
    B:
      range: [40, 76]
      merge: average

  use:
    science: [A, B]
    wavecal: [cal]
    norm_flat: all

Setting fibers_per_order enables per-order organization (no separate per_order: true needed).

The order_centers.yaml file maps spectral order numbers to y-positions at detector center:

# order_centers.yaml
90: 3868.1
91: 3609.0
92: 3356.4
# ... etc

Or inline for instruments with few orders:

fibers:
  fibers_per_order: 3
  order_centers:
    1: 150.5
    2: 320.3
    3: 490.1

Multi-Channel Instruments

For instruments with multiple channels (detectors/arms), per-order fields can be lists indexed by channel:

channels: [UVB, VIS, NIR]

fibers:
  fibers_per_order: [75, 75, 60]  # Can vary per channel
  order_centers_file: [uvb_centers.yaml, vis_centers.yaml, nir_centers.yaml]

  groups:  # Same structure across all channels
    A: {range: [1, 36], merge: average}
    B: {range: [40, 76], merge: average}

If fiber arrangements differ fundamentally between channels, use separate instrument configs.

Merge Methods

  • average - Fit polynomial to mean y-positions of all fibers in group

  • center - Select the middle fiber’s trace

  • [i] or [i, j, ...] - Select specific 1-based indices within group

Per-Step Trace Selection

The use section specifies which traces each reduction step receives:

  • all - All individual fiber traces (ignores grouping)

  • groups - All merged group/bundle traces stacked

  • [A, B] - Specific named groups (kept separate in output)

  • per_fiber - Traces grouped by fiber_idx for per-fiber processing

Steps not listed in use default to groups when groups/bundles are defined.

Per-Fiber Wavelength Calibration

For 2D wavelength calibration (dimensionality: "2D"), all traces in a fit must share the same optical path. When multiple fibers exist per order:

fibers:
  use:
    wavecal: [A]        # One 2D fit for group A across all orders
    # OR
    wavecal: [A, B]     # Separate 2D fits for A and B
    # OR
    wavecal: per_fiber  # Separate 2D fit per fiber_idx

With per_fiber, each unique fiber_idx gets its own 2D polynomial fit. This is useful when fibers have slightly different wavelength solutions and you want to calibrate each independently.

Output Format

Tracing saves all traces to a FITS binary table (.traces.fits) with one row per trace:

Column

Type

Description

M

int16

Spectral order number (-1 if N/A)

GROUP

16A

Group/bundle identifier (‘A’, ‘B’, ‘cal’, etc.)

FIBER_IDX

int16

Fiber index within group (1-indexed, -1 if N/A)

POS

float64[deg+1]

Position polynomial coefficients

COL_RANGE

int32[2]

Valid x range [start, end)

HEIGHT

float32

Extraction aperture height in pixels

SLIT

float64[…]

Curvature coefficients (if available)

SLITDELTA

float32[…]

Per-row curvature residuals (if available)

WAVE

float64[…]

Wavelength polynomial (if available)

The GROUP column identifies which group/bundle each trace belongs to. The FIBER_IDX column identifies the fiber within the group (1-indexed). For merged groups, multiple raw fibers become a single trace with the group name and FIBER_IDX = -1.

Automatic Extraction Heights

The heights array stores per-trace extraction heights computed from trace geometry:

  • For middle traces: half the distance between neighboring traces

  • For edge traces: distance to the single neighbor

  • Measured at multiple reference columns; maximum is used

These heights are used automatically when extraction_height is set to null in settings.json. This provides optimal per-trace apertures without manual tuning.

For groups/bundles, heights are derived from fiber spacing within each group (span + fiber diameter).

Example Instruments

ANDES_UBV / ANDES_RIZ (66 fibers per order)

Simulated echelle spectrographs for visible wavelengths:

  • Fibers 1-31: Slit A

  • Fibers 33-35: Calibration

  • Fibers 36-66: Slit B

  • ANDES_UBV: channels U, B, V (selected by BAND header)

  • ANDES_RIZ: channels R, R1, R2, IZ (selected by HDFMODEL header, since R variants all have BAND=R)

ANDES_YJH (75 fibers per order)

Simulated NIR echelle with science fibers A/B, calibration, and IFU:

  • Fibers 1-35: Slit A

  • Fibers 37-39: Calibration

  • Fibers 40-75: Slit B

  • Additional groups: ifu, ring0-4 (subsets of the fiber bundle)

  • Channels Y, J, H (selected by BAND header)

MOSAIC (630 fibers, single order)

ELT multi-object spectrograph with 90 IFU targets:

  • 7 fibers per target bundle

  • Extract center fiber from each bundle for reduction

  • Uses bundles pattern with bundle_centers_file to handle broken fibers