Beispiel #1
0
        public double[] GetDoseForStructure(Structure structure)
        {
            var doseList = new List <double>();

            for (double z = _zStart; z < _zEnd; z += DoseSamplingDistanceInMm)
            {
                for (double y = _yStart; y < _yEnd; y += DoseSamplingDistanceInMm)
                {
                    VVector start = new VVector(_xStart, y, z);
                    VVector stop  = new VVector(_xEnd, y, z);

                    BitArray bitArray       = new BitArray(_dose.XSize);
                    var      segmentProfile = structure.GetSegmentProfile(start, stop, bitArray);

                    double[] doseArray   = new double[_dose.XSize];
                    var      doseProfile = _dose.GetDoseProfile(start, stop, doseArray);

                    for (int i = 0; i < segmentProfile.Count; i++)
                    {
                        if (segmentProfile[i].Value)
                        {
                            doseList.Add(doseProfile[i].Value);
                        }
                    }
                }
            }

            return(doseList.ToArray());
        }
        private void CalcDepths()
        {
            Field = _beam.Id;

            if (_beam.MLCPlanType == MLCPlanType.VMAT || _beam.MLCPlanType == MLCPlanType.ArcDynamic)
            {
                double totalDistFromTarget = 0;
                foreach (ControlPoint controlPoint in _beam.ControlPoints)
                {
                    //vector from source to reference point for calculating physical depth of point
                    VVector ToRefPoint = _point.RefPointLocation - _beam.GetSourceLocation(controlPoint.GantryAngle);

                    totalDistFromTarget += ToRefPoint.Length;
                }

                Depth = Math.Round((totalDistFromTarget / _beam.ControlPoints.Count() - _point.SSD) / 10.0, 1);
            }
            else
            {
                //vector from source to reference point for calculating physical depth of point
                VVector ToRefPoint = _point.RefPointLocation - _beam.GetSourceLocation(_beam.ControlPoints.First().GantryAngle);

                Depth = Math.Round((ToRefPoint.Length - _point.SSD) / 10.0, 1);
            }

            EffectiveDepth = Math.Round(_point.EffectiveDepth / 10.0, 1);
        }
Beispiel #3
0
 private void SurfaceView_MouseWheel(object sender, MouseWheelEventArgs e)
 {
     if (viewMode == 1)
     {
         if (e.Delta > 0)
         {
             transform.Y += 10;
         }
         else
         {
             transform.Y -= 10;
         }
         camera.Transform = new TranslateTransform3D(0, transform.Y, 0);
     }
     if (viewMode == 2)
     {
         var q = quaternion;
         q.Invert();
         double  val = e.Delta > 0 ? -1 : 1;
         Point3D p   = (new RotateTransform3D(new QuaternionRotation3D(q))).Transform(new Point3D(0, val, 0));
         var     s   = ss.Structures.ElementAt(selected_roi);
         VVector vv  = new VVector(-(p.X + transform.X), -(p.Y + transform.Y), -(p.Z + transform.Z));
         if (s.IsPointInsideSegment(vv))
         {
             transform = new Vector3D(p.X + transform.X, p.Y + transform.Y, p.Z + transform.Z);
             Transform3DGroup transform3DGroup = new Transform3DGroup();
             transform3DGroup.Children.Add(new TranslateTransform3D(transform));
             transform3DGroup.Children.Add(new RotateTransform3D(new QuaternionRotation3D(quaternion)));
             model.Transform = transform3DGroup;
             pre_transform   = transform;
         }
     }
 }
        /// <summary>
        /// This splits a structure into two. It creates a margin around the target,
        /// so that it approximately crosses the mass center of the structure, and then
        /// uses boolean operators to create two new structures. Note: due to the nature
        /// of the segment model in Eclipse, the new structures do not always perfectly cover
        /// the whole volume of the original structure.
        /// </summary>
        /// <param name="s"></param>
        /// <param name="ss"></param>
        /// <returns></returns>
        bool SplitStructure(StructureSet ss, Structure target, Structure roi)
        {
            if (ss.CanAddStructure(roi.DicomType, roi.Id + "_spl1"))
            {
                Structure newStr1 = ss.AddStructure(roi.DicomType, roi.Id + "_spl1");
                Structure newStr2 = ss.AddStructure(roi.DicomType, roi.Id + "_spl2");

                VVector targetCenter = target.CenterPoint;
                VVector roiCenter    = roi.CenterPoint;
                double  dist         = (targetCenter - roiCenter).Length;

                //figure out distance from target center to target surface
                System.Collections.BitArray buffer = new System.Collections.BitArray(100);
                SegmentProfile profile             = target.GetSegmentProfile(targetCenter, roiCenter, buffer);
                double         distToTargetSurface = 0;
                foreach (SegmentProfilePoint point in profile)
                {
                    if (point.Value == false)
                    {
                        //first point outside structure
                        distToTargetSurface = (point.Position - targetCenter).Length;
                        break;
                    }
                }
                //SegmentVolume seg = target.Margin(dist - distToTargetSurface);
                SegmentVolume seg = target.LargeMargin(dist - distToTargetSurface);
                newStr1.SegmentVolume = seg.And(roi);
                newStr2.SegmentVolume = roi.Sub(newStr1);
                return(true);
            }
            return(false);
        }
Beispiel #5
0
        private void ChangeStructure(object sender, EventArgs e)
        {
            // Get selected structure
            Structure viewStructure = SelectedStructureSet.Structures.FirstOrDefault(
                s => s.Id == structureNames[structureList.SelectedIndex]);
            MeshGeometry3D viewContour = viewStructure.MeshGeometry;
            Color          viewColor   = viewStructure.Color;
            // Use body contour as mesh
            GeometryModel3D viewGeometryModel = ((myViewport3D.Children[0] as ModelVisual3D).Content as Model3DGroup).Children[1] as GeometryModel3D;

            viewGeometryModel.Geometry = viewContour;
            // Define material (e.g. brush) and apply to the mesh geometries.
            DiffuseMaterial viewMaterial = new DiffuseMaterial(new SolidColorBrush(viewColor));

            viewGeometryModel.Material     = viewMaterial;
            viewGeometryModel.BackMaterial = viewMaterial;
            // Reset camera to point at new structure
            PerspectiveCamera newPCamera = myViewport3D.Camera as PerspectiveCamera;

            cameraRadius = 800.0;
            cameraTheta  = 90.0 * (Math.PI / 180.0);
            cameraPhi    = 0.0 * (Math.PI / 180.0);
            cv           = viewStructure.CenterPoint;
            double cameraX = cv.x + cameraRadius * Math.Sin(cameraTheta) * Math.Cos(cameraPhi - Math.PI / 2.0);
            double cameraY = cv.y + cameraRadius * Math.Sin(cameraTheta) * Math.Sin(cameraPhi - Math.PI / 2.0);
            double cameraZ = cv.z + (cameraRadius * Math.Cos(cameraTheta));

            newPCamera.Position      = new Point3D(cameraX, cameraY, cameraZ);
            newPCamera.LookDirection = new Vector3D(cv.x - cameraX, cv.y - cameraY, cv.z - cameraZ);
            myViewport3D.Camera      = newPCamera;
        }
Beispiel #6
0
        //
        // Cut profile with calculation volume. Could actaully be easier to simply prune out NaN's which is assiugned to points outside of the dose.
        //
        // Math.Abs(direction.x) > 1e-4 is a crude check for profile running parallel to axis (and thus beigbn outside of the calculation volume)
        //
        public static void cutWithCalculationVolume(VoiBox calculationVolume, ref VVector point, VVector direction)
        {
            var xDiff = Math.Max(point.x - calculationVolume.xmax, 0.0);

            xDiff = (xDiff == 0) ? Math.Min(point.x - calculationVolume.xmin, 0) : xDiff;

            if (xDiff != 0 && Math.Abs(direction.x) > 1e-4)
            {
                var l = xDiff / direction.x;
                point.x -= xDiff;
                point.y -= l * direction.y;
                point.z -= l * direction.z;
            }

            var yDiff = Math.Max(point.y - calculationVolume.ymax, 0.0);

            yDiff = (yDiff == 0) ? Math.Min(point.y - calculationVolume.ymin, 0) : yDiff;
            if (yDiff != 0 && Math.Abs(direction.y) > 1e-4)
            {
                var l = yDiff / direction.y;
                point.x -= l * direction.x;
                point.y -= yDiff;
                point.z -= l * direction.z;
            }
            var zDiff = Math.Max(point.z - calculationVolume.zmax, 0.0);

            zDiff = (zDiff == 0) ? Math.Min(point.z - calculationVolume.zmin, 0) : zDiff;
            if (zDiff != 0 && Math.Abs(direction.z) > 1e-4)
            {
                var l = zDiff / direction.z;
                point.x -= l * direction.x;
                point.y -= l * direction.y;
                point.z -= zDiff;
            }
        }
Beispiel #7
0
        public VVector TransformPoint(VVector pt)
        {
            var local  = this;
            var retVal = X.Instance.CurrentContext.GetValue(sc => { return(local._client.TransformPoint(pt)); });

            return(retVal);
        }
        // check each point on the image grid, and store the indices only
        static List <int> GetInterior(VMS.TPS.Common.Model.API.Image dose, VMS.TPS.Common.Model.API.Structure st)
        {
            List <int> result    = new List <int>();
            VVector    p         = new VVector();
            Rect3D     st_bounds = st.MeshGeometry.Bounds;

            for (int z = 0; z < dose.ZSize; ++z)
            {
                for (int y = 0; y < dose.YSize; ++y)
                {
                    for (int x = 0; x < dose.XSize; ++x)
                    {
                        p.x = x * dose.XRes;
                        p.y = y * dose.YRes;
                        p.z = z * dose.ZRes;

                        p = p + dose.Origin;

                        if (st_bounds.Contains(p.x, p.y, p.z) && // trimming
                            st.IsPointInsideSegment(p))    // this is an expensive call
                        {
                            int[,] voxels = new int[dose.XSize, dose.YSize];
                            dose.GetVoxels(z, voxels);
                            result.Add(voxels[x, y]);
                        }
                    }
                }
                GC.Collect(); // do this to avoid time out
                GC.WaitForPendingFinalizers();
            }

            return(result);
        }
Beispiel #9
0
            public void computeStats(IEnumerable <VVector> sourcePoints,
                                     IEnumerable <VVector> registeredPoints,
                                     IEnumerable <VVector> transformedPoints)
            {
                // ensure that all lists have same number of points.
                if (sourcePoints.Count() != registeredPoints.Count() || sourcePoints.Count() != transformedPoints.Count())
                {
                    throw new ApplicationException("source and registered match points don't have the same # of points!");
                }
                // compute statistics
                double sum       = 0;
                int    numPoints = sourcePoints.Count();

                for (int i = 0; i < numPoints; i++)
                {
                    VVector source     = sourcePoints.ElementAt(i);
                    VVector registered = registeredPoints.ElementAt(i);
                    VVector derived    = transformedPoints.ElementAt(i);
                    double  distance   = VVector.Distance(registered, derived);
                    min  = Math.Min(min, distance);
                    max  = Math.Max(max, distance);
                    sum += distance;
                }
                mean = sum / (double)numPoints;
            }
Beispiel #10
0
        public DoseValue GetDoseToPoint(VVector at)
        {
            var local  = this;
            var retVal = X.Instance.CurrentContext.GetValue(sc => { return(local._client.GetDoseToPoint(at)); });

            return(retVal);
        }
Beispiel #11
0
        /// <summary>
        /// Return image profiles through plan isocenter in primary axis direction
        /// </summary>
        /// <param name="plan">TPS.NET.Plan</param>
        /// <param name="profileLengthInmm"> length of the profiles in mm</param>
        /// <returns></returns>
        public static (ImageProfile, ImageProfile, ImageProfile) getImageProfilesThroughIsocenter(PlanSetup plan)
        {
            var image   = plan.StructureSet.Image;
            var dirVecs = new VVector[] {
                plan.StructureSet.Image.XDirection,
                plan.StructureSet.Image.YDirection,
                plan.StructureSet.Image.ZDirection
            };

            var steps = new double[] {
                plan.StructureSet.Image.XRes,
                plan.StructureSet.Image.YRes,
                plan.StructureSet.Image.ZRes
            };


            var planIso = plan.Beams.First().IsocenterPosition;
            var tmpRes  = new ImageProfile[3];

            //
            // Throws if plan does not have 'BODY'
            //
            var body = plan.StructureSet.Structures.Single(st => st.Id == "BODY");

            for (int ind = 0; ind < 3; ind++)
            {
                (var startPoint, var endPoint) = Helpers.GetStructureEntryAndExit(body, dirVecs[ind], planIso, steps[ind]);
                var samples = (int)Math.Ceiling((endPoint - startPoint).Length / steps[ind]);
                tmpRes[ind] = image.GetImageProfile(startPoint, endPoint, new double[samples]);
            }
            return(tmpRes[0], tmpRes[1], tmpRes[2]);
        }
Beispiel #12
0
        public static int ProfileNumberOfIntervals(VVector start, VVector end, double res = 1.0)
        {
            double distance = VVector.Distance(start, end);
            int    num      = ((int)(distance / res));

            return(num);
        }
Beispiel #13
0
        public static DoseValue CalculateMeanDose(PlanSetup plan, Structure structure)
        {
            Dose dose = plan.Dose;

            if (dose == null)
            {
                return(new DoseValue(Double.NaN, DoseValue.DoseUnit.Unknown));
            }

            plan.DoseValuePresentation = DoseValuePresentation.Absolute;

            double sum   = 0.0;
            int    count = 0;

            double xres = 2.5;
            double yres = 2.5;
            double zres = 2.5;

            int xcount = (int)((dose.XRes * dose.XSize) / xres);

            System.Collections.BitArray segmentStride = new System.Collections.BitArray(xcount);
            double[]           doseArray = new double[xcount];
            DoseValue.DoseUnit doseUnit  = dose.DoseMax3D.Unit;

            for (double z = 0; z < dose.ZSize * dose.ZRes; z += zres)
            {
                for (double y = 0; y < dose.YSize * dose.YRes; y += yres)
                {
                    VVector start = dose.Origin +
                                    dose.YDirection * y +
                                    dose.ZDirection * z;
                    VVector end = start + dose.XDirection * dose.XRes * dose.XSize;

                    SegmentProfile segmentProfile = structure.GetSegmentProfile(start, end, segmentStride);
                    DoseProfile    doseProfile    = null;

                    for (int i = 0; i < segmentProfile.Count; i++)
                    {
                        if (segmentStride[i])
                        {
                            if (doseProfile == null)
                            {
                                doseProfile = dose.GetDoseProfile(start, end, doseArray);
                            }

                            double doseValue = doseProfile[i].Value;
                            if (!Double.IsNaN(doseValue))
                            {
                                sum += doseProfile[i].Value;
                                count++;
                            }
                        }
                    }
                    doseProfile = null;
                }
            }
            double mean = sum / ((double)count);

            return(new DoseValue(mean, doseUnit));
        }
Beispiel #14
0
        /// <summary>
        /// Transforms point in DICOM (HFS patient only) into gantry coordinates (invert GantryToDICOM)
        /// </summary>
        /// <param name="point"> Point to transform</param>
        /// <param name="gantryInDegrees"> Gantry angle b</param>
        /// <param name="patientSupportInDegrees">Patient support angle</param>
        /// <param name="isoCenter"> Isocenter position</param>
        /// <returns></returns>
        public static VVector DICOMToGantry(VVector point, double gantryInDegrees, double patientSupportInDegrees, VVector isoCenter)
        {
            var retval = point - isoCenter;

            retval = new VVector(retval.x, retval.z, -retval.y);
            retval = RotateZ(retval, -patientSupportInDegrees);
            return(RotateY(retval, -gantryInDegrees));
        }
Beispiel #15
0
 public SegShift(VVector mMDisplacement, StructureSet structureSet, Structure structure)
 {
     MMDisplacement   = mMDisplacement;
     Structure        = structure;
     SS               = structureSet;
     OriginalContours = GetContours();
     Contours         = OriginalContours;
 }
Beispiel #16
0
        public static double distanciaMaxima(VVector punto1, VVector punto2)
        {
            double difX = Math.Abs(punto1.x - punto2.x);
            double difY = Math.Abs(punto1.y - punto2.y);
            double difZ = Math.Abs(punto1.z - punto2.z);

            return(Math.Max(difX, Math.Max(difY, difZ)));
        }
Beispiel #17
0
        public static VVector ProfileEndVVector(VVector start, VVector end, double res = 1.0)
        {
            double  distance     = VVector.Distance(start, end);
            int     num          = ProfileNumberOfIntervals(start, end, res);
            VVector truncatedEnd = start + ((num * res) / distance) * (end - start);

            return(truncatedEnd);
        }
Beispiel #18
0
        /// <summary>
        /// Aligns beam isocenter to within the nearest mm.
        /// </summary>
        /// <param name="beam">beam in which isocenter will be set</param>
        /// <param name="str">the structure in which the center will be used</param>
        public static void AlignToStructureCenter(this IonBeam beam, Structure str)
        {
            var beamParams = beam.GetEditableParameters();
            var rounded    = new VVector(Math.Round(str.CenterPoint.x), Math.Round(str.CenterPoint.x), Math.Round(str.CenterPoint.x));

            beamParams.Isocenter = rounded;
            beam.ApplyParameters(beamParams);
        }
        public static Point toPoint(VVector inp)
        {
            Point p = new Point();

            p.X = inp.x;
            p.Y = inp.y;
            return(p);
        }
Beispiel #20
0
        /// <summary>
        /// Aligns beam isocenter to within the nearest mm to structure midpoint (not "weighted" center).
        /// </summary>
        /// <param name="beam">beam in which isocenter will be set</param>
        /// <param name="str">the structure in which the center will be used</param>
        public static void AlignToStructureMidpoint(this IonBeam beam, Structure str)
        {
            var beamParams = beam.GetEditableParameters();
            var midpoint   = str.GetMidpoint();
            var rounded    = new VVector(Math.Round(midpoint.x), Math.Round(midpoint.y), Math.Round(midpoint.z));

            beamParams.Isocenter = rounded;
            beam.ApplyParameters(beamParams);
        }
Beispiel #21
0
        /// <summary>
        /// ESAPI DICOM coordinate system to the user coordinate system.
        /// </summary>
        /// <param name="x">The x coordinate in the DICOM coordinate system.</param>
        /// <param name="y">The y coordinate in the DICOM coordinate system.</param>
        /// <param name="z">The z coordinate in the DICOM coordinate system.</param>
        /// <param name="planSetup">ESAPI PlanSetup, which is necessary to convert from the DICOM to User coordinate system.</param>
        /// <returns>Coordinates in the User coordinate system.</returns>
        public static double[] DicomToUserCoordinates(double x, double y, double z, PlanSetup planSetup)
        {
            var strucureSet = planSetup.StructureSet;
            var imageEsapi  = strucureSet.Image;
            var vectorInDCS = new VVector(x, y, z);
            var vectorInUCS = imageEsapi.DicomToUser(vectorInDCS, planSetup);

            return(new double[] { vectorInUCS.x, vectorInUCS.y, vectorInUCS.z });
        }
Beispiel #22
0
 /// <summary>
 /// cross product between two 3-vectors a and b
 /// </summary>
 /// <param name="a"></param>
 /// <param name="b"></param>
 /// <returns></returns>
 public static VVector CrossProduct(VVector a, VVector b)
 {
     return(new VVector()
     {
         x = a.y * b.z - a.z * b.y,
         y = -a.x * b.z + b.x * a.z,
         z = a.x * b.y - a.y * b.x
     });
 }
Beispiel #23
0
        public static double[]  ImageProfile(Image imageEsapi, VVector start, VVector end, double res = 1.0)
        {
            int numberOfIntervals = ProfileNumberOfIntervals(start, end, res);

            double[] imageProfile = new double[numberOfIntervals + 1];
            imageEsapi.GetImageProfile(start, end, imageProfile);

            return(imageProfile);
        }
Beispiel #24
0
        private void SurfaceView_MouseMove(object sender, MouseEventArgs e)
        {
            var diff = e.GetPosition(this) - pre_point;
            var size = Math.Min(this.ActualWidth, this.ActualHeight);

            if (right_click)
            {
                double x = 360 * diff.X / size;
                double y = 360 * diff.Y / size;
                var    q = new Quaternion(new Vector3D(0, 0, 1), x);
                q *= new Quaternion(new Vector3D(1, 0, 0), y);
                q *= quaternion;
                Transform3DGroup transform3DGroup = new Transform3DGroup();
                if (viewMode == 1)
                {
                    transform3DGroup.Children.Add(new RotateTransform3D(new QuaternionRotation3D(q)));
                    transform3DGroup.Children.Add(new TranslateTransform3D(transform.X, 0, transform.Z));
                    model.Transform = transform3DGroup;
                }
                if (viewMode == 2)
                {
                    transform3DGroup.Children.Add(new TranslateTransform3D(transform));
                    transform3DGroup.Children.Add(new RotateTransform3D(new QuaternionRotation3D(q)));
                    model.Transform = transform3DGroup;
                }
            }
            if (left_click)
            {
                double           x = diff.X / size * 100;
                double           y = -diff.Y / size * 100;
                Transform3DGroup transform3DGroup = new Transform3DGroup();
                if (viewMode == 1)
                {
                    transform3DGroup.Children.Add(new RotateTransform3D(new QuaternionRotation3D(quaternion)));
                    transform3DGroup.Children.Add(new TranslateTransform3D(x + transform.X, 0, y + transform.Z));
                    model.Transform = transform3DGroup;
                }
                if (viewMode == 2)
                {
                    var q = quaternion;
                    q.Invert();
                    x /= 5;
                    y /= 5;
                    Point3D p  = (new RotateTransform3D(new QuaternionRotation3D(q))).Transform(new Point3D(x, 0, y));
                    var     s  = ss.Structures.ElementAt(selected_roi);
                    VVector vv = new VVector(-(p.X + transform.X), -(p.Y + transform.Y), -(p.Z + transform.Z));
                    if (s.IsPointInsideSegment(vv))
                    {
                        transform3DGroup.Children.Add(new TranslateTransform3D(p.X + transform.X, p.Y + transform.Y, p.Z + transform.Z));
                        transform3DGroup.Children.Add(new RotateTransform3D(new QuaternionRotation3D(quaternion)));
                        model.Transform = transform3DGroup;
                        pre_transform   = new Vector3D(p.X + transform.X, p.Y + transform.Y, p.Z + transform.Z);
                    }
                }
            }
        }
Beispiel #25
0
        public ImageProfile GetImageProfile(VVector start, VVector stop, double[] preallocatedBuffer)
        {
            var local  = this;
            var retVal = X.Instance.CurrentContext.GetValue(sc =>
            {
                return(local._client.GetImageProfile(start, stop, preallocatedBuffer));
            });

            return(retVal);
        }
Beispiel #26
0
        public bool IsPointInsideSegment(VVector point)
        {
            var local  = this;
            var retVal = X.Instance.CurrentContext.GetValue(sc =>
            {
                return(local._client.IsPointInsideSegment(point));
            });

            return(retVal);
        }
Beispiel #27
0
        /// <summary>
        /// Rotate point about Y axis (gantry)
        /// </summary>
        /// <param name="point"></param>
        /// <param name="angleInDeg">Patient support angle</param>
        /// <param name="dir">Positive angle direction default clockwise</param>
        /// <returns>point rotated about y axis</returns>
        public static VVector RotateY(VVector point, double angleInDeg, Direction dir = Direction.CW)
        {
            var angleInRad = angleInDeg * 2 * Math.PI / 360;
            var c          = Math.Cos(angleInRad);
            var s          = ((int)dir) * Math.Sin(angleInRad);
            var x          = point.x * c - point.z * s;
            var z          = point.x * s + point.z * c;

            return(new VVector(x, point.y, z));
        }
Beispiel #28
0
        public VVector DicomToUser(VVector dicom, PlanSetup planSetup)
        {
            var local  = this;
            var retVal = X.Instance.CurrentContext.GetValue(sc =>
            {
                return(local._client.DicomToUser(dicom, planSetup._client));
            });

            return(retVal);
        }
Beispiel #29
0
        public static double BeamPointDose(Beam beam, VVector pointDicom)
        {
            DoseValue dose      = beam.Dose.GetDoseToPoint(pointDicom);
            double    muPerGy   = beam.MetersetPerGy;
            double    mu        = beam.Meterset.Value;
            double    refDose   = mu / muPerGy;
            double    pointDose = refDose * dose.Dose;

            return(pointDose);
        }
Beispiel #30
0
        public VVector UserToDicom(VVector user, PlanSetup planSetup)
        {
            var local  = this;
            var retVal = X.Instance.CurrentContext.GetValue(sc =>
            {
                return(local._client.UserToDicom(user, planSetup._client));
            });

            return(retVal);
        }