Skip to content

Update on merging VMAT into dev#377

Open
wahln wants to merge 137 commits intodevfrom
dev_VMAT_merge
Open

Update on merging VMAT into dev#377
wahln wants to merge 137 commits intodevfrom
dev_VMAT_merge

Conversation

@wahln
Copy link
Copy Markdown
Contributor

@wahln wahln commented Sep 20, 2019

Dear @markbangert @eric11210 ,

this is my updated attempt at merging dev_VMAT with dev especially concerning the new optimization interface, but also dose calculation.

What I did here, is merge dev_VMAT into a copy of the current dev branch. I think that this is better than what I did before (#376 ), because know you have a better acces to the changed files within this pull request (and see the changes i did within the merge commit).
Also @markangert should be able to close (#308 ).

It seems like it runs smoothly now with the old settings, i.e. fluence Opt & DAO opt without preconditioning. It doesn't work with VMAT yet (dose calculation works, but fluence optimization is weird and DAO/VMAT doesn't work)
But anyways, I hope you now have a better basis to continue with the merge.

Some comments:

  • integration worked quite well with VMAT Optimization Problem deriving from DAO. Yet I am not clear on how to do something similar with the daoVec2Aperture stuff. I am not familiar enough with the implementation, at the moment the changes are in the OptimizationProblemDAO class within the respective functions.
  • for me siochi leaf sequencing with fails with the matRad.m script, but only when sequencing is turned on and DAO (& of course VMAT) is turned of. Yet I like the idea of putting the number of leves into pln, so I changed all sequencers to have the pln struct in their call.
  • With preconditioning enabled, DAO gives worse results than directly after sequencing.
  • I don't like that the fluence optimization now needs the stf only because the tiny part of VMAT code. Can this be handled differently?
  • Should we just write a matRad_VMAToptimization that itself calls fluence optimization and dao?
  • Merging was at some points weird (git associated some wierd code parts with each other esp in generateStf and dosecalc). I hope I didn't mess something up there.

Let me know if you have questions. I will let you know if I forgot something in the list.

P.S.: Does someone of you have a very light test script for the VMAT?

New: Siochi leaf sequencing with more fluid number of kept apertures.
Still respect constraints of min/max gantry angle spacing.
Changed the first gantry angle from 0 to non-zero.  This makes things
much easier.
Figured out problem with DAO: the leaf speed was defined as the
difference between positions, not absolute difference.  Then speed was
constrained to be between 0 and 6 cm/s, which forced unidirectional
motion, increasing the objective function.

Temporary fix: allow negative values.  Eventually, change definition of
function so that it considers the absolute difference.  Will also have
to change the Jacobian.
Fixed leaf speed constraints and Jacobian.  Siochi sequencing ready to
be pilled to dev.
# Conflicts:
#	optimization/matRad_constFuncWrapper.m
#	optimization/matRad_jacobFuncWrapper.m
Testing Revert
This reverts commit 3fe0406.
Weight to MU changed from 1 to 100.
pln.bioOptimization put into options structure
This reverts commit 79e5632.
Added leaf speed constraints back in
Changed leaf speed from mm/s -> cm/s, greatly reducing treatment time.

Added function helping to test planning capabilities.

Fixed bug in Dij sampling, when no voxels are outside of the core.
Shifted time variable to be the time over the optimized beam's arc,
rather than the time between optimized beam angles.  This makes more
sense when calculating e.g. dose rate.  Also, this will make more sense
when doing dynamic fluence calculation.
Minor tweaks and bugfixes.
Split the daoVec2ApertureInfo into 3 functions so that we didn't have to
keep running if statements on VMAT, dynamic vs. static fluence
calculation, etc.
Added option for dynamic fluence optimization for VMAT DAO, including
support for interpolated apertures.
Support for Jacobian scaling
Added support for 4D dose calculation, including deformed CT cubes and
deformation vectors.
This reverts commit de9682f.
@wahln
Copy link
Copy Markdown
Contributor Author

wahln commented Jan 8, 2026

Working on this again, we are getting close to matRad 4 with VMAT.
I have a few questions:

  • matRad_doseRecalc and matRad_recalcApertureInfo - are these functions exclusively used to recalculate an optimized VMAT plan on a finer angle spacing? So basically interpolation between angles and then full forward dose recalculation? Or is there any other use as well?
  • I do not fully understand the "recalc" parameter in matRad_doseRecalc.
  • About the preconditioning / your wrong derivative checks - to me, the optimization seems to run fine. Did you try derivative checks of IPOPT? What leads you to believe there is an error in the preconditioner?

@eric11210
Copy link
Copy Markdown
Contributor

  1. Regarding matRad_doseRecalc and matRad_recalcApertureInfo. Yes, the purpose is to recalculate the dose using a finer angular resolution, or also possibly using the dynamic aperture method (if static was used during optimization).
  2. I think the recalc structure is there to separate the initial optimization result from the recalculated result. Initially, the recalc structure inherits much of the initial results, but are gradually overwritten as the recalculation proceeds.
  3. I did do derivative checks of IPOPT. From memory, and looking at the checklist, everything worked fine except for the Jacobians on the dosimetric constraints.
  • To elaborate on the derivative checks, I compared the code output of the various gradient and Jacobian functions, to a manual calculation of the gradient and Jacobian using a finite difference method (applying a small perturbation to elements in the optimization vector).
  • Most combinations yielded acceptable results when doing this testing. The exception was the Jacobian for dosimetric constraints.
  • Have you tried running optimization with dosimetric constraints? I didn't tend to use those in my own work.

I can elaborate more on those responses if you need more!

wahln and others added 3 commits January 22, 2026 15:39
# Conflicts:
#	submodules/MOcov
#	submodules/MOxUnit
# Conflicts:
#	matRad/sequencing/matRad_engelLeafSequencing.m
#	matRad/sequencing/matRad_siochiLeafSequencing.m
#	matRad/sequencing/matRad_xiaLeafSequencing.m
@wahln
Copy link
Copy Markdown
Contributor Author

wahln commented Mar 4, 2026

Did some work again on this, particularly on the side of the sequencers. I tried to put it in a way that we do not need to request variables from different pln.prop* structs, but store sensible variables in the sequencing structure itself.

The sequencing algorithms now have a slightly different signature that is more consistent with our current dev branch, and properties about the sequencing (if it should enable VMAT / dynamic delivery, be compatible with continuous apertures, and so on) is now stored in the sequencing struct directl and passt as parameters to the functions.

Particularly the machine constraints and the above mentioned parameters need to be stored there. While doing this I also think more broadly that direct-aperture-optimization related manipulations should not be performed in the sequencers, but in the DAOoptimization initialization itself - for example, preconditioning with matRad_preconditionFactors is currently performed during sequencing, but I don't see a particular reason why this should be the case there. This would then also remove the arwkard handling of a preconditioning switch during sequencing.

This work aligns with #891, which I will merge into dev first and then transition the newly parametrized implementation there.

Afterwards I will tackle optimization.

@eric11210
Copy link
Copy Markdown
Contributor

These changes make sense to me.

@wahln
Copy link
Copy Markdown
Contributor Author

wahln commented Mar 20, 2026

Status Update:

  1. Merged the recent dev (and an extension to the phantom builder for better testing).

  2. I managed to get rid of matRad_VMATGantryAngles and integrate it directly in matRad_StfGeneratorPhotonVMAT

  3. I made the fundamental interface for setting up the stf compatible with standard IMRT. Basically, instead of using startingAngle and finishingAngle, we obtain them from gantryAngles and couchAngles. Reasons for this:

    • I can just feed a standard IMRT pln to VMAT and it will generat an Arc (gantry angles then function as anchor points to be passed during the arc)
    • a new property "arcIndex", which defaults to 1, allows future setup of multiple arcs
    • I could, in principle, allow couch rotations similarly at the anchor points set by gantry angle, allowing non-coplanar arcs.

While some of this is just not fully relevant for the current implementation, it makes it more flexible for future edits.

The VMAT example has been adapted accordingly.

@github-actions
Copy link
Copy Markdown

Code Coverage

Package Line Rate Health
coverage Package 1 49%
Summary 49% (11212 / 23047)

@github-actions
Copy link
Copy Markdown

This PR was automatically marked as stale it has been open 30 days with no activity. Please review/update/merge this PR.

@github-actions github-actions Bot added stale Automatic label for stale issues and removed stale Automatic label for stale issues labels Apr 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants