Exemplo n.º 1
0
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
                                        JsonSerializer serializer)
        {
            // Load the JSON for the Result into a JObject
            var jo     = JObject.Load(reader);
            var unitJO = (JValue)jo[nameof(DoseProfile.Unit)];
            var unit   = serializer.Deserialize <DoseUnit>(unitJO.CreateReader());

            // Load the JSON for the Result into a JObject
            var ja = JArray.Load(jo["Points"].CreateReader());

            var points = ja
                         .Select(j => serializer.Deserialize <ProfilePoint>(((JObject)j).CreateReader()))
                         .ToList();

            var first  = points[0];
            var second = points[1];

            var values = points.Select(p => p.Value).ToList();

            // Construct the Result object using the non-default constructor
            var dp = new DoseProfile(first.Position, second.Position - first.Position, values.ToArray(), unit);

            // Return the result
            return(dp);
        }
Exemplo n.º 2
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));
        }
Exemplo n.º 3
0
        public void SerializeDeserializeDoseProfile()
        {
            var v1 = new VVector(1, 2, 3);
            var v2 = new VVector(4, 5, 6);

            var dp         = new DoseProfile(v1, v2, new double[] { 0.1, 0.2 }, DoseValue.DoseUnit.Percent);
            var serialized = FacadeSerializer.Serialize(dp);

            var deserialized = FacadeSerializer.Deserialize <DoseProfile>(serialized);

            Assert.AreEqual(deserialized.Count, 2);
            Assert.AreEqual(dp[0], deserialized[0]);
            Assert.AreEqual(dp[1], deserialized[1]);
            Assert.AreEqual(dp.Unit, deserialized.Unit);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Calculate a total volume for the loaded patient plan on given percent level of prescitoion dose
        /// and display the result in message box.
        /// </summary>
        /// <param name="curPlan"> the current loaded patient plan</param>
        /// <param name="percentVal"> the percent level of prescition dose</param>
        /// <returns></returns>
        public double CalculateVolAtPercentPresDose(PlanSetup curPlan, double percentVal)
        {
            double totalVol = 0.0;
            int    totalNum = 0;

            // get total prescribed dose, only consider on single plan for this excercise
            var presDose = curPlan.TotalDose.Dose;

            curPlan.DoseValuePresentation = DoseValuePresentation.Absolute;
            var curPlanDose = curPlan.Dose;

            int xDoseCount = curPlanDose.XSize;

            // allocated buffer for dose array in x direction
            double[] xDoseVals = new double[xDoseCount];

            var percentDose = presDose * percentVal / 100;

            // search through 3D dose matrix
            for (double z = 0.0; z < curPlanDose.ZSize * curPlanDose.ZRes; z += curPlanDose.ZRes)
            {
                for (double y = 0.0; y < curPlanDose.YSize * curPlanDose.YRes; y += curPlanDose.YRes)
                {
                    // get first and last point to extract dose profile with given z and y
                    VVector start = curPlanDose.Origin + curPlanDose.YDirection * y + curPlanDose.ZDirection * z;
                    VVector stop  = start + curPlanDose.XDirection * curPlanDose.XRes * (curPlanDose.XSize - 1);

                    DoseProfile profile = null;
                    profile = curPlanDose.GetDoseProfile(start, stop, xDoseVals);

                    // compare doses in x direction
                    foreach (var profilePoint in profile)
                    {
                        if (profilePoint.Value >= percentDose)
                        {
                            totalNum++;
                        }
                    }
                }
            }

            // calculate total Volume in cm
            totalVol = curPlanDose.XRes * curPlanDose.YRes * curPlanDose.ZRes * totalNum / 1000.0;

            return(Math.Round(totalVol, 2));
        }
        private double Get_Gamma(DoseProfile dp, Tuple <double, double> tdd, double v1, double v2, ProfilePoint pp, string axisDir, double norm_factor)
        {
            //throw new NotImplementedException();
            List <double> gamma_values = new List <double>();
            double        dd           = 0.02 * norm_factor; //2%
            double        dta          = 2;                  //2mm
            int           loc          = dp.ToList().IndexOf(pp);
            //search backward 10* the dta
            int start = loc - 10 * dta < 0 ? 0 : loc - Convert.ToInt16(10 * dta);
            int end   = loc + 10 * dta > dp.Count() ? dp.Count() : loc + Convert.ToInt16(10 * dta);

            for (double i = start; i < end - 1; i += 0.1)
            {
                int r0 = (int)Math.Floor(i);
                int r1 = (int)Math.Ceiling(i);
                //find the position in the doseprofile.
                double x0 = axisDir == "X" ? dp[r0].Position.x : dp[r0].Position.y + 200;
                double x1 = axisDir == "X" ? dp[r1].Position.x : dp[r1].Position.y + 200;
                //find the value in the dose profeil.
                double y0  = dp[r0].Value;
                double y1  = dp[r1].Value;
                double dos = 0;
                double pos = 0;
                if (r0 == r1)
                {
                    //cannot linearly interpolate between the same number
                    pos = x0;
                    dos = y0;
                }
                else
                {
                    pos = x0 + (i - r0) * (x1 - x0) / (r1 - r0);
                    dos = y0 + (i - r0) * (y1 - y0) / (r1 - r0);
                }
                double gamma = Math.Sqrt(Math.Pow((pos - tdd.Item1) / dta, 2) + Math.Pow((dos / norm_factor * 100 - tdd.Item2) / dd, 2));
                gamma_values.Add(gamma);
            }
            //return the minumum gamma value.
            return(gamma_values.Min());
        }
Exemplo n.º 6
0
 private void CalculateDoseProfiles()
 {
     if (SelectedPlan != null)
     {
         planSetup = course.PlanSetups.FirstOrDefault(x => x.Id == SelectedPlan);
         double[]           depths   = new double[] { 15, 50, 100, 200, 300 };//mm
         List <DoseProfile> profiles = new List <DoseProfile>();
         foreach (Beam b in planSetup.Beams)
         {
             foreach (double d in depths)
             {
                 double      x1    = b.ControlPoints.First().JawPositions.X1;
                 double      x2    = b.ControlPoints.First().JawPositions.X2;
                 VVector     start = new VVector(x1 - 50, d - 200, 0);
                 VVector     end   = new VVector(x2 + 50, d - 200, 0);
                 DoseProfile prof  = b.Dose.GetDoseProfile(
                     start, end, new double[Convert.ToInt16(end.x - start.x + 1)]);
                 DoseProfileData += $"Profile - d {d}mm - FS {(x2 - x1) / 10}cm\n";
                 profiles.Add(prof);
             }
         }
         _eventAggregator.GetEvent <UpdatePlotEvent>().Publish(profiles);
     }
 }
Exemplo n.º 7
0
        public void Execute(ScriptContext context /*, System.Windows.Window window, ScriptEnvironment environment*/)
        {
            // TODO : Add here the code that is called when the script is launched from Eclipse.
            //get access to the plan.
            PlanSetup ps = context.PlanSetup;
            Dose      d  = ps.Dose;
            //create a vector where the dose profile will start.
            VVector start = new VVector();

            start.x = -100; //mm
            start.y = -100; //location from the dicom origin.
            start.z = 0;
            VVector end = new VVector();

            end.x = 100;
            end.y = start.y;
            end.z = start.z;
            //size of the doseprofile.
            double[]    size = new double[201];
            DoseProfile dp   = d.GetDoseProfile(start,
                                                end,
                                                size);

            //write this doseprofile to a csv file.
            string filename = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) +
                              "\\profile.csv";

            using (StreamWriter sw = new StreamWriter(filename))
            {
                sw.WriteLine("Position,Dose");
                foreach (ProfilePoint pp in dp)
                {
                    sw.WriteLine(String.Format("{0},{1}", pp.Position.x, pp.Value));
                }
            }
        }
Exemplo n.º 8
0
        /// <summary>
        /// Return collapsed 1D dose profile
        /// </summary>
        /// <param name="profile"> DoseProfile to collapse</param>
        /// <returns>Array of double[2] of location and doseValue.
        /// Location at profile start is set to 0 with subsequent values set at distance from start.
        /// </returns>
        public static double[][] flattenProfile(DoseProfile profile)
        {
            var start = profile.ElementAt(0).Position;

            return(profile.Select(pp => new double[] { (pp.Position - start).Length, pp.Value }).ToArray());
        }
Exemplo n.º 9
0
        public void Execute(ScriptContext context /*, System.Windows.Window window*/)
        {
            PlanSetup    plan = context.PlanSetup;
            StructureSet ss   = context.StructureSet;

            if (plan == null)
            {
                MessageBox.Show("Load a plan!");
                return;
            }
            if (plan.IsDoseValid == false)
            {
                MessageBox.Show("plan has no dose calculated!");
                return;
            }
            //User places point called "TopLeft" in top left corner where scan will start before running script
            Structure refMarker = (from s in ss.Structures
                                   where
                                   s.Id == "TopLeft"
                                   select s).FirstOrDefault();

            if (refMarker == null)
            {
                MessageBox.Show("No marker point called TopLeft found.");
                return;
            }
            VVector topLeft = refMarker.CenterPoint;

            //User places point called "BottomRight" in bottom right corner where scan will stop before running script
            Structure refMarker2 = (from s in ss.Structures
                                    where
                                    s.Id == "BottomRight"
                                    select s).FirstOrDefault();

            if (refMarker == null)
            {
                MessageBox.Show("No marker point called BottomRight found.");
                return;
            }
            VVector bottomRight = refMarker2.CenterPoint;
            VVector topRight    = new VVector(bottomRight.x, topLeft.y, topLeft.z);
            VVector bottomLeft  = new VVector(topLeft.x, topLeft.y, bottomRight.z);

            int column = 255; // arbitrarily make 255x255 (since that's what Excel can handle)
            int row    = 255;

            double[] buffer = new double[column];

            double xDist    = (VVector.Distance(topLeft, topRight)) / (double)column;
            string filename = string.Format(@"c:\temp\doseplane.csv");

            using (System.IO.StreamWriter sw = new System.IO.StreamWriter(filename, false, Encoding.ASCII))
            {
                sw.Write("Y[cm]...X[cm],");
                for (int i = 0; i < column; i++)
                {
                    sw.Write("{0},", MMtoCM(Math.Round(topLeft.x + (xDist * i), 3)));
                }
                sw.WriteLine("");
                double zDist = (VVector.Distance(topLeft, bottomLeft)) / (double)row;
                for (int j = 0; j < row; j++)
                {
                    // figure out new start and stop points for the row we are scanning, then get the dose profile (scan it)
                    double  newZ        = topLeft.z - (zDist * j);
                    VVector newRowStart = topLeft;
                    VVector newRowEnd   = topRight;
                    newRowStart.z = newZ;
                    newRowEnd.z   = newZ;
                    // scan the row
                    DoseProfile dp = plan.Dose.GetDoseProfile(newRowStart, newRowEnd, buffer);

                    sw.Write("{0},", MMtoCM(Math.Round(newZ, 3)));
                    foreach (var profilePt in dp)
                    {
                        sw.Write("{0},", Math.Round(profilePt.Value, 6));
                    }
                    sw.WriteLine("");
                }

                sw.Flush();
                sw.Close();

                MessageBox.Show(string.Format(@"File written to '{0}'", filename), "Varian Developer");
            }
            // 'Start' generated CSV file to launch Excel window
            System.Diagnostics.Process.Start(filename);
            // Sleep for a few seconds to let Excel to start
            System.Threading.Thread.Sleep(TimeSpan.FromSeconds(2));
        }
        private void OnCompareScan()
        {
            //prevScans_sp.Children.Clear();//we will refill this stackpanel with results later.
            PlanSetup ps = SelectedPlan;

            foreach (DataScan ds in ds_list)
            {
                //find a beam with the same field size as the scan.
                string s_output = "";
                Beam   b_keep   = null;
                foreach (Beam b in ps.Beams)
                {
                    double x1 = b.ControlPoints.First().JawPositions.X1;
                    double x2 = b.ControlPoints.First().JawPositions.X2;
                    double y1 = b.ControlPoints.First().JawPositions.Y1;
                    double y2 = b.ControlPoints.First().JawPositions.Y2;
                    if (Math.Abs(x2 - x1 - ds.FieldX) < 0.1 && Math.Abs(y2 - y1 - ds.FieldY) < 0.1)
                    {
                        b_keep = b;//found a winner!
                        break;
                    }
                }
                if (b_keep == null)
                {
                    s_output = "No Scan";
                }                                            //could not find the similar field.
                else
                {
                    //analyze the field.
                    //start by gettig the dose profile.
                    VVector start = new VVector();
                    start.x = ds.axisDir == "X" ? ds.scan_data.First().Item1 : 0;
                    start.y = ds.axisDir == "X" ? ds.depth - 200 : ds.scan_data.First().Item1 - 200; //-200 because of the conversion from depth to dicom coordinate.
                    start.z = 0;                                                                     //crossline profiles only!
                    VVector end = new VVector();
                    end.x = ds.axisDir == "X" ? ds.scan_data.Last().Item1 : start.x;
                    end.y = ds.axisDir == "X" ? start.y : ds.scan_data.Last().Item1 - 200;
                    end.z = start.z;
                    double[]    size = new double[ds.scanLength];//make data arrays the same size.
                    DoseProfile dp   = b_keep.Dose.GetDoseProfile(start, end, size);
                    //normalization factor (eclipse calcs not normalized)
                    double norm_factor = ds.axisDir == "X" ?                              //if this is a profile
                                         dp.Where(x => x.Position.x >= 0).First().Value : //norm to central axis.
                                         dp.Max(x => x.Value);                            //for PDD normalizeto max dose.
                                                                                          //write the data to the desktop
                    using (StreamWriter sw = new StreamWriter(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) +
                                                              "\\Scan" + ds.FieldX.ToString() + "X" + ds.FieldY.ToString() + "_" + ds.depth.ToString() + ".csv")) {
                        sw.WriteLine("Scan Pos, Scan Dose, Calc Pos, Calc Dose, Gamma");
                        foreach (Tuple <double, double> tdd in ds.scan_data)
                        {
                            //check the profile point to make sure a point exists in the doseprofile.
                            IEnumerable <ProfilePoint> pp_check = ds.axisDir == "X" ?
                                                                  dp.Where(x => x.Position.x >= tdd.Item1) :
                                                                  dp.Where(x => x.Position.y + 200 >= tdd.Item1);
                            ProfilePoint pp;
                            //if there is not profile point, then you cannot do that gamma analysis.
                            if (pp_check.Count() == 0)
                            {
                                break;
                            }
                            else
                            {
                                pp = pp_check.First();
                            }                                                                    //but if there is a profile point, take the first.
                                                                                                 //get calculated position and dose (from eclipse profile)
                            string calc_pos = ds.axisDir == "X" ?
                                              pp.Position.x.ToString() :
                                              Convert.ToString(pp.Position.y + 200);
                            string calcdos = Convert.ToString(pp.Value / norm_factor * 100);
                            double gam     = Get_Gamma(dp, tdd, Convert.ToDouble(calc_pos), Convert.ToDouble(calcdos), pp, ds.axisDir, norm_factor);
                            //write data to csv
                            sw.WriteLine(String.Format("{0},{1},{2},{3},{4}",
                                                       tdd.Item1, tdd.Item2, calc_pos, calcdos, gam));
                        }
                        sw.Flush();
                        s_output = "Success";
                    }
                }
            }
        }