コード例 #1
0
ファイル: TRE.cs プロジェクト: zhafr/Varian-Code-Samples
            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;
            }
コード例 #2
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);
        }
コード例 #3
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);
        }
コード例 #4
0
        public static bool[] ProfileStructureMask(VVector start, VVector end, Structure structure, double res = 1.0)
        {
            int numberOfIntervals = ProfileNumberOfIntervals(start, end, res);
            int numberOfPoints    = numberOfIntervals + 1;

            VVector pointVVector;

            bool[] structureMask = new bool[numberOfPoints];

            double distance = VVector.Distance(start, end);

            for (int i = 0; i < numberOfPoints; i++)
            {
                pointVVector     = start + ((i * res) / distance) * (end - start);
                structureMask[i] = structure.IsPointInsideSegment(pointVVector);
            }

            return(structureMask);
        }
コード例 #5
0
ファイル: GetProfile.cs プロジェクト: EuroMediTech/GetProfile
        private DoseProfile CalculateProfile(
            Double x_start, Double y_start, Double z_start, Double x_stop, Double y_stop, Double z_stop, Double step, Dose dose
            )
        {
            // 始点と終点を定義
            var start = new VVector(x_start, y_start, z_start);
            var stop  = new VVector(x_stop, y_stop, z_stop);

            // 始点・終点間距離を定義
            var distance = VVector.Distance(start, stop);

            if (distance == 0)
            {
                throw new ApplicationException("Distance between two points is 0.");
            }

            // 距離をステップサイズで割ってサンプリング点数を決定(切り捨て)
            Double point = Math.Floor(distance / step);

            if (point < 1.0)
            {
                throw new ApplicationException("Step size is largar than distance between two points.");
            }

            // 始点から終点へ向かう長さ1のベクトルを得る
            var dir = stop - start;

            dir.ScaleToUnitLength();

            // stepサイズに合うように終点位置を調整
            var stop_new = start + dir * point * step;

            // DoseProfile用の配列を準備
            double[] profile = new double[(int)(point + 1)];
            // DoseProfileを取得
            var doseProfile = dose.GetDoseProfile(start, stop_new, profile);

            return(doseProfile);
        }
コード例 #6
0
ファイル: TRE.cs プロジェクト: zhafr/Varian-Code-Samples
        public string GenerateReport(ScriptContext context, MIRSRegistration mirsReg,
                                     IEnumerable <VVector> sourcePoints,
                                     IEnumerable <VVector> registeredPoints,
                                     IEnumerable <VVector> transformedPoints,
                                     RegStats stats)
        {
            // userid {0}, report time {1}, patient {2}, source dataset {3}, registered dataset {4}.
            string htmlStartFmt = @"
                <HTML>
                  <BODY text=""black"" bgColor=""white"">
                    <H2>Registration Report</H2>
                    Created by {0} on {1}
                    <br/><br/>
                    <table>
                      <tr><td>Patient:</td><td>{2}</td></tr>
                      <tr><td>Source Dataset:</td><td>{3}</td></tr>
                      <tr><td>Registered Dataset:</td><td>{4}</td></tr>
                    </table>";
            string htmlEnd      = "</BODY></HTML>";

            // reg id {0}, reg type {1}, min {2}, max{3}, mean {4}
            string htmlRegHeaderFmt = @"
                <H3>Registration:     {0} (type: {1})</H3>
                <H4>Error Statistics:</H4>
                <table>
                  <tr><td>Min:</td><td>{2:0.0}</td><td>mm</td></tr>
                  <tr><td>Max:</td><td>{3:0.0}</td><td>mm</td></tr>
                  <tr><td>Mean:</td><td>{4:0.0}</td><td>mm</td></tr>
                </table>
                <table border=""1"">
                  <tr>
                    <th>point #</th>
                    <th>Source Match Point</th>
                    <th>Registered Match Point</th>
                    <th>Derived Match Point</th>
                    <th>Distance (mm)</th>
                  </tr>";
            string htmlRegFooter    = "</table>";

            // point # {0}, source match point {1}, registered match point {2}, derived match point {3}, distance {4}
            string htmlPointRowFmt = @"
                <tr>
                <td>{0}</td>
                <td>{1:0.0}</td>
                <td>{2:0.0}</td>
                <td>{3:0.0}</td>
                <td>{4:0.0}</td>
                </tr>";

            // point.x {0}, point.y {1}, point.z {2}
            string htmlFirstIndividualPointFmt = @"
                <table>
                    <tr><td>x: {0:0.0}</td></tr>
                    <tr><td>y: {1:0.0}</td></tr>
                    <tr><td>z: {2:0.0}</td></tr>
                </table>";

            string htmlIndividualPointFmt = @"
                <table>
                    <tr><td>{0:0.0}</td></tr>
                    <tr><td>{1:0.0}</td></tr>
                    <tr><td>{2:0.0}</td></tr>
                </table>";

            string temp     = System.Environment.GetEnvironmentVariable("TEMP");
            string htmlPath = string.Format("{0}\\reg_report.html", temp);

            // open file "%temp%\points.html"
            using (System.IO.TextWriter writer = new System.IO.StreamWriter(htmlPath))
            {
                // build the HTML header and write that
                // userid {0}, report time {1}, patient {2}, source dataset {3}, registered dataset {4}.
                writer.Write(string.Format(htmlStartFmt, context.CurrentUser.Name, DateTime.Now,
                                           context.Patient.Id, mirsReg.SourceImage.Id, mirsReg.RegisteredImage.Id));

                // write the reg header
                writer.Write(string.Format(htmlRegHeaderFmt, mirsReg.Id, mirsReg.ToString(), stats.min, stats.max, stats.mean));

                // list points for the registration
                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);
                    string  oneRow     =
                        string.Format(htmlPointRowFmt, i + 1,
                                      string.Format(htmlFirstIndividualPointFmt, source.x, source.y, source.z),
                                      string.Format(htmlIndividualPointFmt, registered.x, registered.y, registered.z),
                                      string.Format(htmlIndividualPointFmt, derived.x, derived.y, derived.z),
                                      distance.ToString(".0"));
                    writer.Write(oneRow);
                }
                // write the registration footer.
                writer.Write(htmlRegFooter);
                // end the HTML document
                writer.Write(htmlEnd);
            }
            return(htmlPath);
        }
コード例 #7
0
        /// <summary>
        /// checkFieldFunc
        /// </summary>
        /// <param name="plan"></param>
        /// <returns></returns>
        static string CheckFieldFunc(PlanSetup plan)
        {
            //Initializes the variables
            string oText     = "";
            string checkName = "";

            ////////////////////////////////////////////////////////////////////////////////
            // Check Treatment Machine
            //
            checkName = "Check treatment machine";
            bool machineChkFlag = true;

            //TreatmentMachineName (the 1st field)
            string machine = plan.Beams.ElementAt(0).TreatmentUnit.Id;

            foreach (var beam in plan.Beams)
            {
                if (!beam.IsSetupField)
                {
                    if (machine != beam.TreatmentUnit.Id)
                    {
                        //If false
                        //flag -> false
                        machineChkFlag = false;
                        //add the parameters to the string
                        oText += MakeFormatText(false, checkName, beam.Id + ": " + beam.TreatmentUnit.Id + " -> " + machine);
                    }
                }
            }

            // If true
            if (machineChkFlag == true)
            {
                //add OK to the string
                oText += MakeFormatText(true, checkName, "");
            }

            ////////////////////////////////////////////////////////////////////////////////
            // Check isocenter
            // Plan isocenter must be single point
            checkName = "Check single isocenter";
            bool isoChkFlg = true;

            // Get 1st field isocenter position
            VVector isoCNT = plan.Beams.ElementAt(0).IsocenterPosition;

            foreach (var beam in plan.Beams)
            {
                // Compare isocenter position of 1st field with others
                if (VVector.Distance(beam.IsocenterPosition, isoCNT) != 0)
                {
                    isoChkFlg = false;
                }
            }

            if (isoChkFlg == true)
            {
                // If true, add text[O] to the string
                oText += MakeFormatText(true, checkName, "");
            }
            else
            {
                //If false, add the parameters and text[X] to the string
                oText += MakeFormatText(false, checkName, "multiple isocenter");
            }


            ////////////////////////////////////////////////////////////////////////////////
            // Check MU
            checkName = "Check MU";

            double minMU     = 5.0;
            bool   validFlag = true;
            string invalidMU = "";

            foreach (var beam in plan.Beams)
            {
                if (!beam.IsSetupField)
                {
                    if (beam.Meterset.Value < minMU)
                    {
                        validFlag  = false;
                        invalidMU += "(" + beam.Id + ":" + string.Format("{0:f1}", beam.Meterset.Value) + ")";
                    }
                }
            }
            if (validFlag == true)
            {
                // If true, add text[O] to the string
                oText += MakeFormatText(true, checkName, "");
            }
            else
            {
                //If false, add the parameters and text[X] to the string
                oText += MakeFormatText(false, checkName, invalidMU);
            }

            ///////////////////////
            //Check Dose Rate
            checkName = "Check Dose Rate";
            int    defDoserate = 600;
            bool   DRvalidFlag = true;
            string invalidDR   = "";

            foreach (var beam in plan.Beams)
            {
                if (!beam.IsSetupField)
                {
                    if (beam.DoseRate != defDoserate)
                    {
                        DRvalidFlag = false;
                        invalidDR  += "(" + beam.Id + ":" + string.Format("{0}", beam.DoseRate) + ")";
                    }
                }
            }
            if (DRvalidFlag == true)
            {
                // If true, add text[O] to the string
                oText += MakeFormatText(true, checkName, "");
            }
            else
            {
                //If false, add the parameters and text[X] to the string
                oText += MakeFormatText(false, checkName, invalidDR);
            }

            ////////////////////////////////////////////////////////////////////////////////
            // Check Jaw/MLC Position
            checkName = "Check Jaw/MLC position";

            var checkJawMLCText = "\n";

            double distJawMLCX = 0.0; // Jawともっとも開いているMLCとの規定距離(X方向)

            foreach (var beam in plan.Beams)
            {
                bool checkJawMLC = true;

                // MLCあり、かつStaticの場合のみ評価
                if (beam.MLC != null && beam.MLCPlanType == 0)
                {
                    var jawPositions  = beam.ControlPoints.ElementAt(0).JawPositions;
                    var leafPositions = beam.ControlPoints.ElementAt(0).LeafPositions;
                    var leafPairs     = leafPositions.GetLength(1); // Leaf対の数

                    float minX = 200;
                    float maxX = -200;

                    for (int i = 0; i < leafPairs; i++)
                    {
                        if (leafPositions[0, i] != leafPositions[1, i])
                        {
                            minX = (minX > leafPositions[0, i]) ? leafPositions[0, i] : minX;
                            maxX = (maxX < leafPositions[1, i]) ? leafPositions[1, i] : maxX;
                        }
                    }

                    // X Jawの規定位置
                    var jawIdealX1 = minX - distJawMLCX;
                    var jawIdealX2 = maxX + distJawMLCX;


                    // 規定位置と2㎜以上ずれている場合にエラーを出す
                    if (Math.Abs(jawIdealX1 - jawPositions.X1) > 2.0)
                    {
                        checkJawMLCText += string.Format("{0} : X1 jaw should be {1:f1} cm", beam.Id, jawIdealX1 / 10);
                        checkJawMLC      = false;
                    }

                    if (Math.Abs(jawIdealX2 - jawPositions.X2) > 2.0)
                    {
                        checkJawMLCText += string.Format("{0} : X2 jaw should be {1:f1} cm", beam.Id, jawIdealX2 / 10);
                        checkJawMLC      = false;
                    }
                }

                if (checkJawMLC)
                {
                    oText += MakeFormatText(true, checkName + "(" + beam.Id + ")", "");
                }
                else
                {
                    oText += MakeFormatText(false, checkName, checkJawMLCText);
                }
            }


            return(oText);
        }
コード例 #8
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));
        }
コード例 #9
0
ファイル: IsocenterChecks.cs プロジェクト: bcatt09/PlanCheck
        protected override void RunTest(PlanSetup plan)
        {
            DisplayName     = "Isocenter";
            ResultDetails   = "";
            TestExplanation = "Checks that only a single isocenter exists in the plan\nAlso suggests using G180E if the isocenter is shifted >2cm to patient's right";

            int isocenters = 1;


            VVector firstIso = plan.Beams.FirstOrDefault().IsocenterPosition;

            foreach (Beam field in plan.Beams)
            {
                //check for multiple isocenters
                if (field != plan.Beams.First())
                {
                    //if there's no distance between the two, they are equal
                    if (VVector.Distance(field.IsocenterPosition, firstIso) != 0)
                    {
                        isocenters++;
                    }
                }

                //check if 180E might be necessary
                if (!field.IsSetupField && field.ControlPoints.First().GantryAngle == 180)
                {
                    try
                    {
                        Structure body = (from s in plan.StructureSet.Structures where (s.DicomType == "BODY" || s.DicomType == "EXTERNAL") select s).First();

                        //Looks for the isocenter position to be 20 mm to the left when facing the linac. Positions are in mm
                        if (field.IsocenterPosition.x - body.CenterPoint.x < -20 && (plan.TreatmentOrientation == PatientOrientation.HeadFirstSupine || plan.TreatmentOrientation == PatientOrientation.FeetFirstProne))
                        {
                            Result         = "Warning";
                            ResultDetails += $"Isocenter is shifted to patients right, do you want to use {field.GantryAngleToUser(180)}E?\n";
                            DisplayColor   = ResultColorChoices.Warn;
                        }
                        if (field.IsocenterPosition.x - body.CenterPoint.x > 20 && (plan.TreatmentOrientation == PatientOrientation.HeadFirstProne || plan.TreatmentOrientation == PatientOrientation.FeetFirstSupine))
                        {
                            Result         = "Warning";
                            ResultDetails += $"Isocenter is shifted to patients left, do you want to use {field.GantryAngleToUser(180)}E?\n";
                            DisplayColor   = ResultColorChoices.Warn;
                        }
                    }
                    catch
                    {
                        TestCouldNotComplete("CheckIsocenterPosition - No structure with type \"BODY\" or \"EXTERNAL\" found");
                    }
                }
            }

            if (isocenters > 1)
            {
                Result         = "Warning";
                ResultDetails += $"{isocenters} isocenters detected, please check plan\n";
                DisplayColor   = ResultColorChoices.Warn;
            }

            ResultDetails = ResultDetails.TrimEnd('\n');

            //no problems found
            if (ResultDetails == "")
            {
                Result       = "Pass";
                DisplayColor = ResultColorChoices.Pass;
            }
        }