Calculating volume of specified dose level

Oct 18, 2014 at 10:31 PM
Hello Everyone,

I'm trying to determine the volume of a specific isodose level. Ultimately I will take that volume and do comparisions with structure volume (SBRT constraints: high dose spill, conformality calcs). Currently I tried two ways to calculate the volume of 105% dose in a test plan.
  1. Iterate through dose matrix voxels for a given dose plane and compare voxel's dose value to see if greater then my comparison dose e.g. 105%. Do this for all dose planes and to determine volume = #counts * XResYResZRes. This was based off of the post https://variandeveloper.codeplex.com/wikipage?title=Code%20Sample%20-%20Iterate%20through%203D%20Image&referringTitle=Eclipse%20Scripting%20Tips%20and%20Tricks
  2. Create a Dose Profile for a given dose origin + Y + Z Start and X End. Iterate through dose profile to find doseProfile[i].Value > Dose To Compare. Volume calculated as # countsXResYRes*ZRes. This was based off of the post https://variandeveloper.codeplex.com/wikipage?title=Code%20Sample%20-%20Dose%20Voxel%20Data&referringTitle=Eclipse%20Scripting%20Tips%20and%20Tricks.
Both methods calculate within ~1cc of each other for a prostate test plan that is calculating the volume of 105%.

1st method 2.5mm calc grid gives 40.17cc volume for 105% dose
1st method 1mm calc grid gives 38.9cc volume for 105% dose

2nd method 2.5mm calc grid gives 39.08cc volume for 105% dose
2nd method 1mm calc grid gives 38.63cc volume for 105% dose

I was wondering which of these methods was more accurate?

The part I'm a little confused about is when I manually calculate these values for comparison by converting an isodose level to structure in Eclipse I get the following:

Convert 105% to structure on 2.5mm calc grid: 38.16cc volume for 105% dose
Convert 105% to structure on 1mm calc grid: 29.99cc volume for 105% dose

An 8cc difference for the same plan depending on if a 2.5mm calc grid or 1mm calc grid is used seems large. How is the convert isodose to structure doing the conversion?

Which of the 3 methods, voxel search, dose profile, manual isodose to structure conversion is the true volume?

Thanks,
Kurt

Voxel Search Method:
Dose planDose = planItem.Dose;
            int count = 0;


            int[,] dosePlaneVoxels = new int[planDose.XSize, planDose.YSize];

            for ( int z = 0; z < planDose.ZSize; z++ )
            {
                planDose.GetVoxels( z, dosePlaneVoxels ); 
                for ( int y = 0; y < planDose.YSize; y++ )
                {
                    for ( int x = 0; x < planDose.XSize; x++ )
                    {
                        DoseValue voxelDose = 
                                 planDose.VoxelToDoseValue( dosePlaneVoxels[x, y] );
                        if (  voxelDose.Dose >= doseToCompare.Dose )
                        {
                            count++;
                        } // End if voxelDose >= _doseToCompare
                    } // End for to cycle through x dimension
                } // End for to cycle through y dimension
            } // End for loop to cycle through z dose planes

            volumeDoseTotal = ( count * planDose.XRes * planDose.YRes * planDose.ZRes );
Dose Profile Method
            Dose planDose = planItem.Dose;
            int count = 0;


            int xcountDose = planDose.XSize;
            double[] doseArrayDose = new double[xcountDose];

            // Cycle through dose grid in z and y direction
            for ( double z = 0; z < planDose.ZSize * planDose.ZRes; z += planDose.ZRes )
            {
                for ( double y = 0; y < planDose.YSize * planDose.YRes; y += planDose.YRes )
                {
                    // counts of dose values along x for given y and z
                    VVector start = planDose.Origin + planDose.YDirection * y + 
                                              planDose.ZDirection * z;
                    VVector end = start + planDose.XDirection * planDose.XRes * 
                                             planDose.XSize;

                    DoseProfile doseProfile = null;

                    // Search for dose in x direction
                    for ( int i = 0; i < doseArrayDose.Count(); i++ )
                    {

                        if ( doseProfile == null )
                        {
                            doseProfile = planDose.GetDoseProfile( start, end, 
                                                   doseArrayDose );
                        }

                        double planDoseValue = doseProfile[i].Value;
                        if (planDoseValue > doseToCompare.Dose )
                        {
                            count++;
                        }
                    }
                    doseProfile = null;
                }
            }


            volumeDoseTotal = ( count * planDose.XRes * planDose.YRes * planDose.ZRes ); 
Coordinator
Oct 25, 2014 at 12:46 AM
As is evident from the results, the most unreliable (and / or most grid size dependent) method is the conversion of the isodose to a structure. This is because the method to represent a contour given at one resolution in another resolution makes no attempt to preserve the area (hence the volume of the structure is not preserved).

As to the two other methods, both seem to converge pretty close to the same result at 0mm grid size (about 38.2cc … 38.3cc), the dose profile method converging faster. Maybe it makes sense that the dose profile method, while trilinearly interpolating the dose, gets a slightly more accurate approximation of the location of the boundary of the isodose already at a higher resolution.


Image


The least accurate method is to determine a structure based on iso-dose, because in that method there is a limited control over the grid resolution used.

The voxel search and the dose profile methods will reach to same answer once the grid spacing is reduced enough. Note that the dose profile method is actually using a super-fine resolution in the profile direction.

If you want to calculate the volume accurately using the scripting API but would like to benchmark the results in external beam planning, first determine a structure based on an isodose surface that is somewhat smaller than the desired dose level (say 10 % in low gradient region, maybe up to 50 % in high gradient region) and then calculate the DVH based on that. The absolute volume of the desired dose level can be read from that DVH curve. The trick is to use a structure that is guaranteed to have all the dose voxels with desired dose level but is not too much larger than the actual volume-of-interest (the body is not suitable) so that the DVH sampling coverage stays acceptable.
Marked as answer by rexcardan on 11/25/2014 at 8:02 AM
Coordinator
Oct 25, 2014 at 1:14 AM
Also...

If the profile is created so that the sample points correspond to the voxel grid the results between voxel search and dose profile should be exactly the same.

There seems to be a bug in this line of the sample code in https://variandeveloper.codeplex.com/wikipage?title=Code%20Sample%20-%20Dose%20Voxel%20Data&referringTitle=Eclipse%20Scripting%20Tips%20and%20Tricks
VVector end = start + dose.XDirection * dose.XRes * dose.XSize;
It should use ‘(dose.XSize-1)’ to exactly determine the location of the last voxel. When this is changed the differences disappear.
Marked as answer by rexcardan on 11/25/2014 at 8:02 AM
Oct 28, 2014 at 7:53 AM
Thanks for the thorough explanation.

I went through and updated to dose.XSize-1 and now the voxel search and dose profile search are returning the same volume for a given dose.

The DVH Benchmarking works well, especially as the dose grid size decreases. I create a structure slightly larger then the dose level I wanted to calculate the volume of and used the dVH to determine the volume of the interested dose level. I did this for the 105% dose which I was working on before and also on 10% dose and calculated at 2.5mm, 2mm, 1.5mm, and 1mm dose grid sizes.

Results are as follows:
Image

The 10% has a much smaller dependency on the dose grid size which makes sense. In both the 105% and 10% cases, on the 1mm dose grid all methods (voxel search, dose profile, and DVH benchmark) return nearly the same value. I think it's interesting how the difference between the DVH Benchmark volume and Script Calculated Volumes decreases with grid size but in terms of dose grid size and absolute volume, the calculated volume bounces around. Not sure if this is due to the change in location, when searching along a given direction, of the position of the last dose grid value greater then a specified dose value.

Thanks,
Kurt