Project 3 Planning + Build Checklist

Pipeline first — validate always

Author

Dr. Anna Rosen

Published

March 3, 2026

This worksheet is a guide for Project 3. You are not required to complete every section today.

The goal is to help you build a working MCRT pipeline without wandering: units \(\to\) grid \(\to\) photon emission \(\to\) ray marching \(\to\) absorption \(\to\) diagnostics \(\to\) validate.

Bring this sheet to the Monday Mar 9 lab for a quick checkoff.

Group info

Names:

Section / group # (if applicable):

Roles (circle): Pipeline lead / Physics checker / Skeptic / Timekeeper


1) What you are building (in 4 sentences)

Write a short description of what this repo does. This becomes the first draft of your README.md overview.


2) Units and constants (before anything else)

Getting units wrong is the #1 failure mode in radiative transfer code. Commit to CGS before writing a single line.

Your unit system

Fill in with CGS values:

  • Length unit: cm (1 pc = ________ cm)
  • Mass unit: g
  • Time unit: s
  • Luminosity unit: erg/s (1 \(L_\odot\) = ________ erg/s)
  • Stellar radius unit: cm (1 \(R_\odot\) = ________ cm)

Constants you will need

Constant Symbol Value (CGS)
Speed of light \(c\)
Planck’s constant \(h\)
Boltzmann constant \(k_B\)
Stefan-Boltzmann constant \(\sigma\)
Solar luminosity \(L_\odot\)
Solar radius \(R_\odot\)
Proton mass \(m_H\)

Dust medium properties

Show your calculation for each:

  • Number density: \(n_H = 1000\) cm\(^{-3}\)
  • Molecular weight: \(\mu = 2.3\)
  • Gas density: \(\rho_\mathrm{gas} = n_H \times \mu \times m_H\) = ________ g/cm\(^3\)
  • Dust-to-gas ratio: \(f_{D/G}\) = ________
  • Dust density: \(\rho_\mathrm{dust} = \rho_\mathrm{gas} \times f_{D/G}\) = ________ g/cm\(^3\)

The most common unit bug

Which density do you use for optical depth calculations — \(\rho_\mathrm{gas}\) or \(\rho_\mathrm{dust}\)?

Answer: ________

What factor are you off by if you use the wrong one? ________


3) Grid contract

Write the data structure specification for your 3D grid. This is a contract — your entire codebase must be consistent.

Grid geometry

  • Box size: \(L\) = ________ pc = ________ cm
  • Number of cells per dimension: \(N_\mathrm{cells}\) = ________ (start small for debugging!)
  • Cell size: \(\Delta x = L / N_\mathrm{cells}\) = ________ cm
  • Domain: \(x \in [-L/2, L/2]\), same for \(y\), \(z\)

Cell indexing

For a position \((x, y, z)\), write the formula for cell indices:

  • \(i_x\) = ________
  • \(i_y\) = ________
  • \(i_z\) = ________

Hand-check your indexing

Position \((-L/2, -L/2, -L/2)\) should map to cell \((0, 0, 0)\).

Position \((0, 0, 0)\) should map to cell \((N/2, N/2, N/2)\).

Position just inside \((+L/2, +L/2, +L/2)\) should map to cell \((N-1, N-1, N-1)\).

Verify these with your formula:

Grid arrays

Array Shape Stores
rho_gas
L_absorbed
n_absorbed

4) Photon packet contract

What is a photon packet?

In one sentence, explain the difference between a photon packet and a physical photon:

Packet attributes

Attribute Type Units Description
\(x, y, z\) float cm
\(\hat{n}_x, \hat{n}_y, \hat{n}_z\) float unitless
\(L_\mathrm{packet}\) float erg/s
\(\kappa\) float cm\(^2\)/g
band str

Packet luminosity

For a single-band simulation with total band luminosity \(L_\mathrm{band}\) and \(N_\mathrm{packets}\) packets:

\(L_\mathrm{packet}\) = ________

Critical: Do all packets carry the same luminosity? ________

Why does this matter for Monte Carlo statistics?


5) Hand trace: one photon through a uniform medium

Compute by hand. If you can’t trace it, you can’t debug it.

Setup

  • Box: \(L = 1\) pc, uniform dust density \(\rho_\mathrm{dust} = 3.84 \times 10^{-23}\) g/cm\(^3\)
  • Grid: \(16^3\) cells (for hand tracing)
  • Constant opacity: \(\kappa_V = 7300\) cm\(^2\)/g
  • Star at origin, packet emitted in the \(+x\) direction: \(\hat{n} = (1, 0, 0)\)

Optical depth to box edge

Distance from origin to \(+x\) boundary: \(d = L/2\) = ________ cm

Optical depth to edge: \(\tau_\mathrm{edge} = \kappa \times \rho_\mathrm{dust} \times d\) = ________

Packet fate decision

Sample \(\tau_\mathrm{sample} = -\ln(\xi)\) where \(\xi \in (0, 1)\).

If \(\xi = 0.5\): \(\tau_\mathrm{sample}\) = ________

Does this packet escape or get absorbed? (Compare \(\tau_\mathrm{sample}\) to \(\tau_\mathrm{edge}\)):

If \(\xi = 0.01\): \(\tau_\mathrm{sample}\) = ________

Does this packet escape or get absorbed?

Expected escape fraction

For the full box (uniform medium, star at center, packets going in all directions):

  • Face-normal upper bound: \(f_\mathrm{esc}^\mathrm{max} = e^{-\kappa \rho L/2}\) = ________
  • Corner lower bound: \(f_\mathrm{esc}^\mathrm{min} = e^{-\kappa \rho L\sqrt{3}/2}\) = ________

Your MC result should fall between these two values. Is the escape fraction closer to 0% or 100%? Does that make physical sense for a dense molecular cloud?


6) Ray marching plan

This is the hardest part of the implementation. Plan it carefully.

The algorithm (pseudocode)

Fill in the ray marching logic for propagating a packet through cells:

1. Sample interaction depth: tau_sample = ...
2. Set tau_accumulated = 0
3. While packet is inside box:
   a. Get current cell indices: ix, iy, iz = ...
   b. Get local dust density: rho_dust = ...
   c. Calculate distance to next cell boundary: d_next = ...
   d. Calculate optical depth through this cell segment: d_tau = ...
   e. If tau_accumulated + d_tau >= tau_sample:
      -> Packet is ...
      -> Action: ...
   f. Otherwise:
      -> tau_accumulated += d_tau
      -> Move packet to ...
      -> Update cell indices
4. If packet exits box:
   -> Packet has ...
   -> Action: ...

Distance to next cell boundary

This is where most bugs hide. For a packet at position \((x, y, z)\) moving in direction \((\hat{n}_x, \hat{n}_y, \hat{n}_z)\):

For the \(x\)-dimension, the next cell boundary is at:

  • If \(\hat{n}_x > 0\): \(x_\mathrm{boundary}\) = ________ and \(d_x = (x_\mathrm{boundary} - x) / \hat{n}_x\)
  • If \(\hat{n}_x < 0\): \(x_\mathrm{boundary}\) = ________ and \(d_x = (x_\mathrm{boundary} - x) / \hat{n}_x\)
  • If \(\hat{n}_x = 0\): \(d_x\) = ________ (why?)

The distance to the next boundary in any dimension is: \(d_\mathrm{next} = \min(d_x, d_y, d_z)\)

Three bugs to avoid

For each, write one sentence explaining the bug and how to prevent it:

  1. Division by zero (direction component = 0):

  2. Negative distance (\(d_\mathrm{next} \leq 0\)):

  3. Off-by-one at cell boundaries (packet exactly on a face):


7) Energy bookkeeping plan

The conservation law

For every simulation, the following must hold:

\(L_\mathrm{in}\) = ________ + ________

How you will track it

Counter What it accumulates When it updates
L_input Before simulation
L_absorbed When a packet is ________
L_escaped When a packet ________

Conservation test

\(\left| L_\mathrm{in} - (L_\mathrm{abs} + L_\mathrm{esc}) \right| / L_\mathrm{in} <\) ________

If this fails, what should you check? (List 2 things):


8) Phase 1A test case: what to expect

Initial conditions

Parameter Value
Star mass 20 \(M_\odot\)
Star position \((0, 0, 0)\)
\(\kappa_V\) (constant) 7300 cm\(^2\)/g
Grid resolution \(16^3\) (debugging)
\(N_\mathrm{packets}\) 1000 (debugging)

What correct output looks like

Describe what you expect for the escape fraction (2-3 sentences). Is it high or low? Why?

What obviously wrong output looks like

List three things that would indicate a bug:


9) Validation plan

Write three checks you will run before moving to Phase 1B.

  1. Anchor check (\(f_\mathrm{esc}\) matches \(e^{-\tau}\) within Monte Carlo error):

  2. Trend check (escape fraction decreases when you increase \(\kappa\)):

  3. Diagnostic check (energy conservation within tolerance):


10) Repo structure

Write a 1-line responsibility for each file you plan to have:

  • project3_analysis.py:
  • src/constants.py:
  • src/star.py:
  • src/zams.py:
  • src/utils.py:
  • src/dust.py:
  • src/grid.py:
  • src/photon.py:
  • src/transport.py:
  • src/detectors.py:
  • src/mcrt_viz.py:
  • tests/test_validation.py:

11) Phases 1B–2 roadmap (lightweight)

You do not need to plan these in detail yet. Write one sentence for each.

Phase 1B: Multiple stars (V-band only)

What changes from Phase 1A? (one sentence — hint: not the transport code):

How do you select which star emits each packet? (one sentence):

Phase 2: Multiple bands (B, V, K)

What changes from Phase 1B? (one sentence — hint: not the transport code):

What is a Planck mean opacity? (one sentence):

Why does a hot star have a different \(\langle\kappa\rangle_V\) than a cool star? (one sentence):


12) Figures plan

List the required figures from the project spec. For each, note which module produces it.

Figure Description Module/function
Opacity validation
Convergence analysis
SED comparison
Absorption map (B)
Absorption map (V)
Absorption map (K)

For each figure, write one “what would look obviously wrong?” note:


Instructor checkoff (Mon Mar 9)

Checkboxes:

(Optional today, required by Check-in 1 on Wed Mar 11):