Source code for cerr.imrtp.dosecalc.montecarlo

"""montecarlo
~~~~~~~~~~

Placeholders for the Monte-Carlo dose engines of CERR's
``IMRTP/recompDose`` toolbox (DPM and VMC++).

The Matlab originals
(https://github.com/cerr/CERR/tree/master/IMRTP/recompDose) drive compiled
MC executables and a measurement-based photon source model:

    beam2MCdose.m / beam2MCdose_with_QIB.m
        Build the fluence (leaf sequences, MLC transmission `leak`, wedges,
        tongue-and-groove, horn/softening corrections, source model) for
        one beam of an RTPLAN and run the selected solver.
    calcDoseByBeamMeterset.m
        Read per-beam MC dose from disk and combine using the plan
        metersets (DPM path of ``call_doseRecal.m``).

Porting these requires the DPM / VMC++ binaries, their phase-space /
spectrum inputs (e.g. ``6MV10x10MDA.spectrum``) and the accelerator-head
source model, none of which ship with pyCERR.  The functions below define
the intended Python interfaces and raise ``NotImplementedError`` with
pointers to the Matlab references; the parameter set mirrors
``call_doseRecal.m`` so existing workflows translate directly.

This file is part of pyCERR and is distributed under the terms of the
Lesser GNU Public License (same terms as CERR).
"""

from __future__ import annotations

from dataclasses import dataclass

_RECOMP_URL = 'https://github.com/cerr/CERR/tree/master/IMRTP/recompDose'

#: solver codes used by call_doseRecal.m
MC_SOLVER_DPM = 1
MC_SOLVER_VMC = 2
MC_SOLVER_QIB = 3


[docs] @dataclass class MCRecompParams: """Inputs of ``beam2MCdose.m`` (defaults from ``call_doseRecal.m``).""" leak: float = 0.032 # MLC leakage/transmission spectrum_File: str = '6MV10x10MDA.spectrum' nhist: float = 1e5 # histories per cm^2 (1M ~ 2% sigma) batch: int = 101 # unique id per calculation OutputError: int = 0 PBMaxWidth: float = 10.0 gradsense: float = 25.0 MCsolver: int = MC_SOLVER_DPM # 1: DPM, 2: VMC++ saveIM: int = 0 sourceModel: int = 0 # 1 to use the source model doseToWater: int = 0 fillWater: int = 0 useWedge: int = 0 inputPB: int = 0 inputIM: int = 1 Softening: int = 1 UseFlatFilter: int = 1 MLC: int = 0 TongueGroove: int = 0 interactiveMode: int = 0 LS_flag: int = 0 K: int = 1 scatterThreshold: float = 11.2 # DPM default (QIB uses 0.1)
[docs] def beam2MCdose(im, planC, whichBeam: int, params: MCRecompParams = None, statusCallback=None): """PLACEHOLDER -- Monte-Carlo dose for one beam (DPM or VMC++). Intended port of ``beam2MCdose.m`` / ``beam2MCdose_with_QIB.m`` from the CERR ``recompDose`` toolbox: build the beam fluence map (including MLC leaf sequences, transmission, wedge and source model) and run the selected Monte-Carlo solver, returning the per-beam IM dosimetry and beamlet weights. """ params = params or MCRecompParams() solver = 'DPM' if params.MCsolver == MC_SOLVER_DPM else 'VMC++' raise NotImplementedError( 'The %s Monte-Carlo engine has not been ported to pyCERR. See the ' 'Matlab reference implementation in %s (beam2MCdose.m). Implement ' 'this function (or register a custom engine with ' 'cerr.imrtp.registerEngine) to enable Monte-Carlo recomputation.' % (solver, _RECOMP_URL))
[docs] def calcDoseByBeamMeterset(planC, nhist: float, batch: int): """PLACEHOLDER -- combine per-beam DPM doses using plan metersets. Intended port of ``calcDoseByBeamMeterset.m`` (DPM path of ``call_doseRecal.m``): reads the per-beam MC dose files written by the DPM solver and sums them weighted by the beam metersets. """ raise NotImplementedError( 'DPM dose summation has not been ported to pyCERR. See ' 'calcDoseByBeamMeterset.m in %s.' % _RECOMP_URL)
[docs] def dpmEngine(im, planC, statusCallback=None): """PLACEHOLDER engine entry ('DPM') for the cerr.imrtp registry.""" raise NotImplementedError( "The 'DPM' Monte-Carlo engine is a placeholder. Port beam2MCdose.m " 'from %s or register your own engine via ' "cerr.imrtp.registerEngine('DPM', fn). The 'QIB' engine is " 'available now.' % _RECOMP_URL)
[docs] def vmcEngine(im, planC, statusCallback=None): """PLACEHOLDER engine entry ('VMC++') for the cerr.imrtp registry.""" raise NotImplementedError( "The 'VMC++' Monte-Carlo engine is a placeholder. Port " 'generateVMCInfluence.m / beam2MCdose.m from %s or register your ' "own engine via cerr.imrtp.registerEngine('VMC++', fn). The 'QIB' " 'engine is available now.' % _RECOMP_URL)