// 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); }
private void button1_Click(object sender, EventArgs e) { abrirPaciente(textBox1.Text); plan = paciente.Courses.First().PlanSetups.First(); VMS.TPS.Common.Model.API.Image imagen = plan.StructureSet.Image; var isoc = imagen.DicomToUser(imagen.Origin, plan); Beam campo = plan.Beams.First(); //VVector iso = campo.IsocenterPosition.; foreach (Structure estructura in plan.StructureSet.Structures) { for (int z = 0; z < 120; z++) { var contorno = estructura.GetContoursOnImagePlane(35); /*if (contorno.Count()>0) * { * MessageBox.Show(z.ToString() + estructura.Id); * }*/ } } Dose dose = plan.Dose; IEnumerable <Isodose> isodosis = dose.Isodoses; foreach (Isodose iso in isodosis) { var mesh = iso.MeshGeometry; } //plan = paciente.Courses.First().PlanSetups.Where(p => p.Id == "Plan2 #").FirstOrDefault(); Imagen(paciente, plan); }
public void Run( User user, Patient patient, VMS.TPS.Common.Model.API.Image image, StructureSet structureSet, PlanSetup planSetup, IEnumerable <PlanSetup> planSetupsInScope, IEnumerable <PlanSum> planSumsInScope, Window window) { // Your main code now goes here //PlanSetup planSetup = context.PlanSetup; // If there's no selected plan with calculated dose throw an exception if (planSetup == null || planSetup.Dose == null) { throw new ApplicationException("Please open a calculated plan before using this script."); } // Retrieve StructureSet structureSet = planSetup.StructureSet; if (structureSet == null) { throw new ApplicationException("The selected plan does not reference a StructureSet."); } // For this example we will retrieve first available structure of PTV type /*Structure target = null; * foreach (var structure in structureSet.Structures) * { * if (structure.DicomType == "PTV") * { * target = structure; * break; * } * * } * if (target == null) * throw new ApplicationException("The selected plan does not have a PTV."); * * // Retrieve DVH data * DVHData dvhData = planSetup.GetDVHCumulativeData(target, * DoseValuePresentation.Relative, * VolumePresentation.Relative, 0.1); * * if (dvhData == null) * throw new ApplicationException("DVH data does not exist. Script execution cancelled."); */ // Add existing WPF control to the script window. var mainControl = new Example_DVH.MainControl(); window.Content = mainControl; window.Width = mainControl.Width; window.Height = mainControl.Height; foreach (Structure s in structureSet.Structures) { CheckBox cb = new CheckBox(); cb.Content = s.Id; cb.Checked += mainControl.Cb_Checked; mainControl.structures_sp.Children.Add(cb); } mainControl.ps = planSetup; window.Title = "Plan : " + planSetup.Id;// + ", Structure : " + target.Id; // Draw DVH //mainControl.DrawDVH(dvhData); }
public void Execute(ScriptContext context /*, System.Windows.Window window*/) { //************************** // Please check the parameters. //************************** String path_to_OutputFolder = @"C:\Users\Administrator\Desktop"; double scaling_factor = 1.0; //************************** Patient patient = context.Patient; if (patient == null) { throw new ApplicationException("Please open a plan or a plan sum before running the script."); } PlanSetup planSetup = context.PlanSetup; PlanSum psum = context.PlanSumsInScope.FirstOrDefault(); if (planSetup == null && psum == null) { throw new ApplicationException("Please open a plan or a plan sum before running the script."); } SelectedPlanningItem = planSetup != null ? (PlanningItem)planSetup : (PlanningItem)psum; SelectedStructureSet = planSetup != null ? planSetup.StructureSet : psum.PlanSetups.First().StructureSet; // Retrieve StructureSet //StructureSet structureSet = planSetup.StructureSet; if (SelectedStructureSet == null) { throw new ApplicationException("The selected plan does not reference a StructureSet."); } // Retrieve image VMS.TPS.Common.Model.API.Image image = SelectedStructureSet.Image; //------------------------------------- // Plan //------------------------------------- var beams = planSetup.Beams; foreach (var beam in beams) { if (!beam.IsSetupField) { String fileName = path_to_OutputFolder + @"\" + patient.FirstName + patient.LastName + @"_" + patient.Id + @"_" + planSetup.Id + @".txt"; StreamWriter writer = new StreamWriter(fileName, false); String machine = beam.TreatmentUnit.Id; //MLC Plan Type int MLCPlanType = (int)beam.MLCPlanType; //MLCPlanType // 1 MLC plan type: DoseDynamic( The gantry does not rotate. ) // 2 MLC plan type: ArcDynamic // 3 MLC plan type: VMAT int Count = beam.ControlPoints.Count; // Exporting number of control points writer.WriteLine(Count); var JawPositions = beam.ControlPoints.ElementAt(0).JawPositions; if (MLCPlanType == 1 || MLCPlanType == 2 || MLCPlanType == 3) { double MUw = 0.0; double gantryAngle = 0.0; double collimatorAngle = 0.0; double patientSupportAngle = 0.0; foreach (var controlPoints in beam.ControlPoints) { // Exporting number of control points MUw = controlPoints.MetersetWeight; writer.WriteLine(MUw.ToString("0.0000000")); gantryAngle = controlPoints.GantryAngle; collimatorAngle = controlPoints.CollimatorAngle; patientSupportAngle = controlPoints.PatientSupportAngle; //MLC ----- var LeafPositions = controlPoints.LeafPositions; for (int i = 0; i < 60; i++) { double mlc_a = LeafPositions[0, i]; mlc_a = mlc_a * scaling_factor; double mlc_b = LeafPositions[1, i]; mlc_b = mlc_b * scaling_factor; String mlc_positions = mlc_a.ToString("0.00000") + @", " + mlc_b.ToString("0.00000") + @", 1"; // Exporting number of control points writer.WriteLine(mlc_positions); } //MLC ----- end } } writer.Close(); } } }
/*public Course abrirCurso(AriaEntities.Patient paciente, string nombreCurso) * { * //return paciente.Courses.Where(c => c.Id == nombreCurso).FirstOrDefault(); * } * * //public AriaEntities.PlanSetup abrirPlan(Course curso, string nombrePlan) * { * // return curso.PlanSetups.Where(p => p.Id == nombrePlan).FirstOrDefault(); * }*/ public void Imagen(Patient paciente, PlanSetup plan) { foreach (Beam campo in plan.Beams) { MessageBox.Show("Se inicia campo " + campo.Id); try { VMS.TPS.Common.Model.API.Image imagen = campo.ReferenceImage; //Series serie = imagen.Series; /*Frame frame = imagen.Frames[0]; * foreach (GraphicAnnotation ga in frame.GraphicAnnotations) * { * if (ga.GraphicAnnotationType == GraphicAnnotationType.Graticule) * { * * } * }*/ //int x = imagen.XSize; //int y = imagen.YSize; //int[,] matrizXY = new int[x, y]; //double[,] matrizXY2 = new double[x, y]; //imagen.GetVoxels(0, matrizXY); //MessageBox.Show("Se obtuvo la matriz"); //Bitmap bitmapXY = new Bitmap(x, y); /*Bitmap bitmapXY2 = new Bitmap(x, y); * * for (int i = 0; i < x; i++) * { * for (int j = 0; j < y; j++) * { * matrizXY2[i, j] = imagen.VoxelToDisplayValue(matrizXY[i, j]); * int valor = Convert.ToInt32(matrizXY[i, j] / imagen.Window * 255); * bitmapXY.SetPixel(i, j, Color.FromArgb(valor, valor, valor)); * int valorDV = Convert.ToInt32(imagen.VoxelToDisplayValue(matrizXY[i, j]) * 255); * bitmapXY2.SetPixel(i, j, Color.FromArgb(valor, valor, valor)); * } * } * * bitmapXY.Save("drr_" + campo.Id + ".jpg", ImageFormat.Jpeg); * bitmapXY2.Save("drr2_" + campo.Id + ".jpg", ImageFormat.Jpeg); * MessageBox.Show("se guardó la imagen"); * MessageBox.Show("Window" + imagen.Window.ToString()); * MessageBox.Show("Level" + imagen.Level.ToString()); * * System.IO.StreamWriter streamWriter = new System.IO.StreamWriter("drr_" + campo.Id + ".txt"); * string output = ""; * for (int i = 0; i < matrizXY.GetUpperBound(0); i++) * { * for (int j = 0; j < matrizXY.GetUpperBound(1); j++) * { * output += matrizXY[i, j].ToString() + "\t"; * } * streamWriter.WriteLine(output); * output = ""; * } * streamWriter.Close(); * * System.IO.StreamWriter streamWriter2 = new System.IO.StreamWriter("drr2_" + campo.Id + ".txt"); * string output2 = ""; * for (int i = 0; i < matrizXY2.GetUpperBound(0); i++) * { * for (int j = 0; j < matrizXY2.GetUpperBound(1); j++) * { * output2 += matrizXY2[i, j].ToString() + "\t"; * } * streamWriter2.WriteLine(output2); * output2 = ""; * } * streamWriter2.Close();*/ } catch (Exception e) { MessageBox.Show("No se pudo abrir la imagen"); throw; } } }
static string CheckForBlips(StructureSet ss) { //See https://stackoverflow.com/questions/39853481/is-point-inside-polygon int numBlips = 0; string blipsInfo = ""; VMS.TPS.Common.Model.API.Image vi = ss.Image; foreach (Structure s in ss.Structures.Where(s => s.Id.StartsWithArray(new string[2] { "CTV", "GTV" }))) { if (s.Id.Contains("z")) { continue; } //loop through each image slice for (int i = 0; i < vi.ZSize; i++) { VVector[][] www_lower = null; VVector[][] www_upper = null; if (i != 0) { www_lower = s.GetContoursOnImagePlane(i - 1); } if (i != (vi.ZSize - 1)) { www_upper = s.GetContoursOnImagePlane(i + 1); } VVector[][] www = s.GetContoursOnImagePlane(i); VVector[] centrepoints = new VVector[www.GetLength(0)]; double[] _areas = new double[www.GetLength(0)]; //if only ONE structure contoured on slice, look for blips if (www.GetLength(0) == 1) { continue; } for (int k = 0; k < www.GetLength(0); k++) // iterate over slice contours { double minX = www[k][0].x; double maxX = www[k][0].x; double minY = www[k][0].y; double maxY = www[k][0].y; double sliceZ = www[k][0].z; for (int j = 0; j < www[k].Length; j++) // iterate over vertices { if (www[k][j].x > maxX) { maxX = www[k][j].x; } if (www[k][j].x < minX) { minX = www[k][j].x; } if (www[k][j].y > maxY) { maxY = www[k][j].y; } if (www[k][j].y < minY) { minY = www[k][j].y; } } _areas[k] = (maxX - minX) * (maxY - minY); centrepoints[k].x = (maxX + minX) / 2.0; centrepoints[k].y = (maxY + minY) / 2.0; centrepoints[k].z = sliceZ; //If crudely calculated area of contour is too small, call it a blip } //end k loop for (int m = 0; m < www.GetLength(0); m++) // iterate over slice contours { if (_areas[m] > 10) { continue; } bool found_enclosing = false; for (int n = 0; n < www.GetLength(0); n++) { if (n == m) { continue; } if (IsInPolygon(toPointList(www[n]), toPoint(centrepoints[m]))) { found_enclosing = true; } } // Check if blip is enclosed by adjacent slice contours for (int u = 0; u < www_upper.GetLength(0); u++) { if (IsInPolygon(toPointList(www_upper[u]), toPoint(centrepoints[m]))) { found_enclosing = true; } } for (int u = 0; u < www_lower.GetLength(0); u++) { if (IsInPolygon(toPointList(www_lower[u]), toPoint(centrepoints[m]))) { found_enclosing = true; } } if (!found_enclosing) { VVector blipLocationUser = vi.DicomToUser(centrepoints[m], null); //VVector blipLocationUser2 = vi.DicomToUser(www[n][0], null); string blipX = Math.Round(blipLocationUser.x / 10.0, 2).ToString(); string blipY = Math.Round(blipLocationUser.y / 10.0, 2).ToString(); string blipZ = Math.Round(blipLocationUser.z / 10.0, 2).ToString(); //MessageBox.Show($"{blipY} {Math.Round(blipLocationUser2.y / 10.0, 2).ToString()}"); blipsInfo += $"Potential blip or hole (area: {_areas[m].ToString("F1")}) in structure {s.Id} located near: X = {blipX} cm, Y = {blipY} cm, Z = {blipZ} cm. "; numBlips += 1; } } } } //set blipsMessage string to 'OK' if no blips if (numBlips == 0) { return(""); } else { return(blipsInfo); } }
public void Execute(ScriptContext context) { VMS.TPS.Common.Model.API.Image imagen = context.Image; PlanSetup plan = context.PlanSetup; foreach (Isodose isodosis in plan.Dose.Isodoses) { var mesh = isodosis.MeshGeometry; var posiciones = mesh.Positions; } //imagen. /*VMS.TPS.Common.Model.API.Image imagen = context.PlanSetup.Beams.First().ReferenceImage; * int x = imagen.XSize; * int y = imagen.YSize; * int z = imagen.ZSize; * MessageBox.Show("Tamaño: (" + x.ToString() + ", " + y.ToString() + ", " + z.ToString() + ")"); * int[,] matrizXY = new int[x, y]; * int[,] matrizXZ = new int[x, y]; * int[,] matrizYZ = new int[y, z]; * try * { * imagen.GetVoxels(0, matrizXY); * MessageBox.Show("Se pudo XY"); * } * catch (Exception) * { * * MessageBox.Show("El tamaño XY no es correcto"); * } * * try * { * imagen.GetVoxels(0, matrizXZ); * MessageBox.Show("Se pudo XZ"); * } * catch (Exception) * { * * MessageBox.Show("El tamaño XZ no es correcto"); * } * * try * { * imagen.GetVoxels(0, matrizYZ); * MessageBox.Show("Se pudo YZ"); * } * catch (Exception) * { * * MessageBox.Show("El tamaño YZ no es correcto"); * } * * * Bitmap bitmapXY = new Bitmap(x, y); * Bitmap bitmapXZ = new Bitmap(x, z); * Bitmap bitmapYZ = new Bitmap(y, z); * * for (int i = 0; i < x; i++) * { * for (int j = 0; j < y; j++) * { * * bitmapXY.SetPixel(i, j, Color.FromArgb(matrizXY[i, j], matrizXY[i, j], matrizXY[i, j])); * } * } * bitmapXY.Save("test.jpg", ImageFormat.Jpeg);*/ }