Physical depth from field reference point

Mar 6 at 5:44 PM
In our tml reports we have a variable $FieldRefPointDepth that gives the physical depth for our calc points (that have a location.) I've gone through the API and also the XML plan writer and haven't come across this variable. I'm good on beam.SSD, beam.frp.SSD, beam.frp.EffectiveDepth and all that, but need this physical depth.

Our MU calc program needs this variable, I'm trying to speed up the data entry.

I'm guessing the API doesn't grab point depth. Does anyone know how Eclipse calculates/stores this variable? I'm guessing it's using the point's x,y,z, isocenter x,y,z, and gantry angle to determine the distance to the body contour, but I'm far too lazy (busy) to work out the vectors and code this up at the moment. I'd also like to keep things as close to what Eclipse is doing as possible.

Let me know if anyone's come across this or has a solution. Hopefully I'm just missing something here.

Apr 25 at 11:52 PM
Edited Apr 26 at 12:34 AM
I'm afraid there is a not a way to get this through the API directly.

Given that this is the case, you are indeed going to have to do some Vector math; Fortunately the .NET framework includes some good tools for manipulating vectors (such as rotating them around a given axis) so it's not so difficult to (1) get a direction vector for you beam and then (2) step along that vector direction until you encounter the patient's body and/or bolus (using the Structure's IsPointInsideSegment function). More specifically, these are found in the Vector3D, Matrix3D, and Quaternion in the System.Windows.Media.Media3D namespace. To use them, of course, you'll need to convert the VVectors into Vector3Ds.

There is a pretty big gotcha, however, in that the 3D VVector locations returned by all Eclipse API functions (and the one used for lookup using the IsPointInsideSegment function) is not in the "global" Eclipse External Beam Planning coordinate system... it is what would be returned if the patient were in a head-first supine position, so if you simply use the assumption that the central ray of a beam at gantry = 0 is in the +y direction (i.e. (0,1,0) ) before you apply the Matrix rotations (gantry and couch if its a central ray thing) on it that give you the actual direction for that beam's of the central ray that you step along until encountering the patient's body, then it will only work for Head-first supine patients. Correcting for the orientation can be tricky but it is possible.

Once you encounter the body, you can continue to step the vector through the patient at whatever resolution you think is appropriate, check the HU at those locations, and convert it to a relative electron density to determine the equivalent length of that step... Unfortunately the Eclipse API does not expose the HU to relative electron density curve from what I can tell. (I wish it did). You would need to implement one with an interpolation calculation in the code.

If you need more specific guidance on this I can probably help, please feel free to contact me.

-Alan Nelson
Oct 3 at 10:41 PM
Finally got around to working on this and had some nice methods built before I stumbled upon Beam.GetSourceLocation and FieldReferencePoint.SSD. Turns out you can get the physical depth on static beams pretty quickly using:
var b = planSetup.Beams.Where(o => o.IsSetupField == false);  // is not a setup field
var frp = planSetup.Beams.Where(o => o.IsSetupField == false).First().FieldReferencePoints.Where(o => o.RefPointLocation.x.ToString() != "NaN");  // has a location
double pdepth = Math.Round(((frp.RefPointLocation - b.GetSourceLocation(b.ControlPoints.First().GantryAngle)).Length - frp.SSD) / 10, 1);  // depth in cm
Gets the length from reference point to target and subtracts the SSD to the reference point. I'll still work on my methods for weighting VMAT based on MU, but that's much less of a priority atm. Thanks for the guidance Alan, using it in the other methods.