-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathFieldViewModel.txt
More file actions
90 lines (85 loc) · 4.26 KB
/
FieldViewModel.txt
File metadata and controls
90 lines (85 loc) · 4.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
public ObservableCollection<FieldModel> Fields { get; set; }
private FieldModel _selectedField;
public FieldModel SelectedField
{
get { return _selectedField; }
set { SetProperty(ref _selectedField, value); }
}
public FieldViewModel(PlanSetup planSetup)
{
Fields = new ObservableCollection<FieldModel>();
GatherFieldInfo(planSetup);
}
private void GatherFieldInfo(PlanSetup planSetup)
{
foreach (var field in planSetup.Beams.Where(x => !x.IsSetupField).OrderBy(x => x.BeamNumber))
{
Fields.Add(new FieldModel
{
FieldId = field.Id,
FieldName = field.Name,
Technique = field.Technique.Id,
Energy = field.EnergyModeDisplayName,
FieldX = (field.ControlPoints.Max(x => x.JawPositions.X2) - field.ControlPoints.Min(x => x.JawPositions.X1)) / 10.0,
FieldY = (field.ControlPoints.Max(x => x.JawPositions.Y2) - field.ControlPoints.Min(x => x.JawPositions.Y1)) / 10.0,
X1 = field.ControlPoints.Min(x => x.JawPositions.X1) / 10.0,
X2 = field.ControlPoints.Max(x => x.JawPositions.X2) / 10.0,
Y1 = field.ControlPoints.Min(x => x.JawPositions.Y1) / 10.0,
Y2 = field.ControlPoints.Max(x => x.JawPositions.Y2) / 10.0,
Machine = field.TreatmentUnit.Id,
Isocenter = GetIsocenter(planSetup,field),
MU = field.Meterset.Value,
MLCPlanType = field.MLCPlanType.ToString(),
SSD = Math.Round(field.SSD/10.0,2),//maybe for arcs average ssd would be the best.
DoseRate = field.DoseRate,
Gantry = GetGantry(planSetup,field),
Collimator = field.CollimatorAngleToUser(field.ControlPoints.First().CollimatorAngle),
CouchAngle = field.PatientSupportAngleToUser(field.ControlPoints.First().PatientSupportAngle),
ToleranceTable = field.ToleranceTableLabel,
DRR = BuildDRRImage(field)
});
}
}
private BitmapSource BuildDRRImage(Beam field)
{
if(field.ReferenceImage == null){ return null;}
var drr = field.ReferenceImage;
int[,] pixels = new int[drr.YSize, drr.XSize];
drr.GetVoxels(0,pixels);//get image pixels out of ESAPI.
int[] flat_pixels = new int[drr.YSize * drr.XSize];
//lay out pixels into single array
for(int i = 0; i < drr.YSize; i++)
{
for(int ii = 0; ii < drr.XSize; ii++)
{
flat_pixels[i + drr.XSize * ii] = pixels[i,ii];
}
}
//translate into byte array
var drr_max = flat_pixels.Max();
var drr_min = flat_pixels.Min();
PixelFormat format = PixelFormats.Gray8;//low res image, but only 1 byte per pixel.
int stride = (drr.XSize * format.BitsPerPixel + 7) / 8;
byte[] image_bytes = new byte[stride * drr.YSize];
for(int i = 0; i < flat_pixels.Length; i++)
{
double value = flat_pixels[i];
image_bytes[i] = Convert.ToByte(255 * ((value - drr_min) / (drr_max - drr_min)));
}
//build the bitmapsource.
return BitmapSource.Create(drr.XSize, drr.YSize, 25.4 / drr.XRes, 25.4 / drr.YRes, format, null, image_bytes, stride);
}
private string GetGantry(PlanSetup plan, Beam field)
{
if (field.Technique.Id.Contains("ARC"))
{
return $"{field.ControlPoints.First().GantryAngle} {field.GantryDirection} {field.ControlPoints.Last().GantryAngle}";
}
return field.ControlPoints.First().GantryAngle.ToString();
}
private string GetIsocenter(PlanSetup plan, Beam field)
{
var uo = plan.StructureSet.Image.UserOrigin;
var iso = field.IsocenterPosition;
return $"({(iso.x - uo.x) / 10.0:F1}, {(iso.y - uo.y) / 10.0:F1}, {(iso.z - uo.z) / 10.0:F1})";
}