/// <summary> /// Provides the transformation from IEC coordinates to patient DICOM coordinates. Useful for rendering /// structures. /// </summary> /// <param name="orient"></param> /// <returns>4x4 transformation matrix</returns> public static Matrix3D IECToDICOM(PatientOrientation orient) { var tx = DICOM2IEC(orient); tx.Invert(); return(tx); }
/// <summary> /// Initializes a new instance of <see cref="MammographyImageSpatialTransform"/> with the specified image plane details. /// </summary> public MammographyImageSpatialTransform(IGraphic ownerGraphic, int rows, int columns, double pixelSpacingX, double pixelSpacingY, double pixelAspectRatioX, double pixelAspectRatioY, PatientOrientation patientOrientation, string laterality) : base(ownerGraphic, rows, columns, pixelSpacingX, pixelSpacingY, pixelAspectRatioX, pixelAspectRatioY) { // image coordinates are defined with X and Y being equivalent to the screen axes (right and down) and with Z = X cross Y (into the screen) Vector3D imagePosterior, imageHead, imageLeft; // patient orientation vectors in image space GetPatientOrientationVectors(patientOrientation, out imageHead, out imageLeft, out imagePosterior); // no adjustments if the posterior direction is not represented in the image if ((_imagePosterior = imagePosterior) != null) { Vector3D normativePosterior, normativeHead, normativeLeft; // normative patient orientation vectors in image space GetNormativeOrientationVectors(laterality, out normativeHead, out normativeLeft, out normativePosterior); // only do any adjustments if laterality implies a normative orientation for the posterior direction if (normativePosterior != null) { // check if the order of the patient vectors are flipped according to the normative vectors // we know we need to flip if the direction vector cross products have different signs if (imageHead != null) FlipX = _coreFlipX = Math.Sign(imagePosterior.Cross(imageHead).Z) != Math.Sign(normativePosterior.Cross(normativeHead).Z); else if (imageLeft != null) FlipX = _coreFlipX = Math.Sign(imagePosterior.Cross(imageLeft).Z) != Math.Sign(normativePosterior.Cross(normativeLeft).Z); // with flip normalized, just rotate to align the current posterior direction with the normative posterior var currentPosterior = GetCurrentPosteriorVector(_imagePosterior, SourceWidth, AdjustedSourceHeight, 0, 1, 1, _coreFlipX, false); var posteriorAngle = Math.Atan2(currentPosterior.Y, currentPosterior.X); var normativeAngle = Math.Atan2(normativePosterior.Y, normativePosterior.X); // compute required rotation, rounded to multiples of 90 degrees (PI/2 radians) RotationXY = _coreRotation = 90*((int) Math.Round((normativeAngle - posteriorAngle)*2/Math.PI)); } } }
public PatientOrientationHelper(SpatialTransform imageTransform, PatientOrientation patientOrientation) { Platform.CheckForNullReference(imageTransform, "imageTransform"); Platform.CheckForNullReference(patientOrientation, "patientOrientation"); _imageTransform = imageTransform; _patientOrientation = patientOrientation; AngleTolerance = 1; }
public PatientOrientationHelper(ISpatialTransform imageTransform, PatientOrientation patientOrientation) { Platform.CheckForNullReference(imageTransform, "imageTransform"); Platform.CheckForNullReference(patientOrientation, "patientOrientation"); _imageTransform = imageTransform; _patientOrientation = patientOrientation; AngleTolerance = 1; }
/// <summary> /// Provides the transformation from patient DICOM coordinates to IEC coordinates, adjusted for the isocenter position. /// Useful for rendering structures. /// </summary> /// <param name="orient">patient orienation</param> /// /// <param name="iso">isocenter position</param> /// <returns>4x4 transformation matrix</returns> public static Matrix3D DICOM2IEC_IsoAdjusted(PatientOrientation orient, VVector iso) { var basic = DICOM2IEC(orient); var offset = Matrix3D.Identity; offset.OffsetX = -iso.x; offset.OffsetY = -iso.y; offset.OffsetZ = -iso.z; return(Matrix3D.Multiply(offset, basic)); }
public StructureSet AddEmptyPhantom(string imageId, PatientOrientation orientation, int xSizePixel, int ySizePixel, double widthMM, double heightMM, int nrOfPlanes, double planeSepMM) { var local = this; var retVal = X.Instance.CurrentContext.GetValue(sc => { return(new StructureSet(local._client.AddEmptyPhantom(imageId, orientation, xSizePixel, ySizePixel, widthMM, heightMM, nrOfPlanes, planeSepMM))); }); return(retVal); }
public FieldNameChecker(string fieldName, double gantry, double couch, PatientOrientation patientOrientation = PatientOrientation.HeadFirstSupine) { this.FieldName = fieldName; this.GantryAngle = gantry; this.CouchAngle = couch; this.PatientPosition = patientOrientation; fieldNameDecoder(fieldName); if (IsLegitName) { this.Orientation = new FieldOrientation(Name); IsAngleMatch = GantryAngleMatch(this.Orientation, this.GantryAngle, this.CouchAngle, this.PatientPosition); } }
/// <summary> /// Called by GetAnnotationText (and also by Unit Test code). Making this function internal simply makes it easier /// to write unit tests for this class (don't have to implement a fake PresentationImage). /// </summary> /// <param name="imageTransform">the image transform</param> /// <param name="patientOrientation">the image orientation patient (direction cosines)</param> /// <returns></returns> internal string GetAnnotationTextInternal(SpatialTransform imageTransform, PatientOrientation patientOrientation) { SizeF[] imageEdgeVectors = new SizeF[4]; for (int i = 0; i < 4; ++i) { imageEdgeVectors[i] = imageTransform.ConvertToDestination(_edgeVectors[i]); } //find out which source image edge got transformed to coincide with this viewport edge. ImageEdge transformedEdge = GetTransformedEdge(imageEdgeVectors); //get the marker for the appropriate (source) image edge. return(GetMarker(transformedEdge, patientOrientation)); }
/// <summary> /// Constructor for BeamGeometry /// </summary> /// <param name="gantryAngle"> Gantry angle in degree </param> /// <param name="collimatorAngle"> Collimator angle in degree </param> /// <param name="couchAngle"> Couch angle in radian </param> /// <param name="isocenter"> Isocenter coordinate in the planning coordinate system in mm </param> /// <para name="patientOrientation"> Enum for patient orientation </para> public BeamGeometry(double gantryAngle, double collimatorAngle, double couchAngle, double[] isocenter, PatientOrientation patientOrientation = PatientOrientation.NoOrientation) { this.GantryAngle = gantryAngle; this.CollimatorAngle = collimatorAngle; this.CouchAngle = couchAngle; for (int i = 0; i < 3; i++) { this.Isocenter[i] = isocenter[i]; } CoordinateTransform3D.SourceCoordinateInPlanningCoordinate( SourcePosition, isocenter, gantryAngle, collimatorAngle, couchAngle, SourceToAxisDistance); }
/// <summary> /// Determines the (untransformed) marker for a particular image edge. /// </summary> /// <param name="imageEdge">the edge (image coordinates)</param> /// <param name="patientOrientation">the patient orientation construct of the image</param> /// <returns>a string representation of the direction (a 'marker')</returns> private string GetMarker(ImageEdge imageEdge, PatientOrientation patientOrientation) { bool negativeDirection = (imageEdge == ImageEdge.Left || imageEdge == ImageEdge.Top); bool rowValues = (imageEdge == ImageEdge.Left || imageEdge == ImageEdge.Right); var direction = (rowValues ? patientOrientation.Row : patientOrientation.Column) ?? PatientDirection.Empty; if (negativeDirection) { direction = direction.OpposingDirection; } string markerText = ""; markerText += GetMarkerText(direction.Primary); markerText += GetMarkerText(direction.Secondary); return(markerText); }
public string GetMatchingStoredLayoutId(IDicomAttributeProvider dicomAttributeProvider) { if (dicomAttributeProvider == null) { return(null); } var filterCandidates = new List <KeyValuePair <string, string> > { new KeyValuePair <string, string>("Modality", dicomAttributeProvider[DicomTags.Modality].GetString(0, string.Empty)) }; // these are hard-coded as the only filter candidates for now, until more general use cases are identified. var patientOrientation = PatientOrientation.FromString(dicomAttributeProvider[DicomTags.PatientOrientation].ToString()); if (patientOrientation != null && !patientOrientation.IsEmpty) { filterCandidates.Add(new KeyValuePair <string, string>("PatientOrientation_Row", patientOrientation.PrimaryRow)); filterCandidates.Add(new KeyValuePair <string, string>("PatientOrientation_Col", patientOrientation.PrimaryColumn)); } return(GetMatchingStoredLayoutId(filterCandidates)); }
private bool GantryAngleMatch(FieldOrientation fieldOrientation, double gantry, double couch, PatientOrientation patientOrientation) { bool checkLR = false; bool checkAP = false; bool checkSI = false; switch (patientOrientation) { case PatientOrientation.HeadFirstSupine: { //check some special case switch (fieldOrientation.FieldName) { case "VERTEX": if ((couch == 90.00 && gantry == 270.00) || (couch == 270.00 & gantry == 90.00)) { checkLR = checkAP = checkSI = true; } break; case "ANT": if (gantry == 0.00 && couch == 0.00) { checkLR = checkAP = checkSI = true; } break; case "POST": if (gantry == 180.00 && couch == 0.00) { checkLR = checkAP = checkSI = true; } break; case "LT LAT": if (gantry == 90.00 && couch == 0.00) { checkLR = checkAP = checkSI = true; } break; case "RT LAT": if (gantry == 270.00 && couch == 0.00) { checkLR = checkAP = checkSI = true; } break; default: //check Left Right if (gantry > 0.00 && gantry < 180.00 && (couch != 90.00 || couch != 270.00)) { checkLR = fieldOrientation.LeftRight == FieldOrientation.LeftorRight.Left; } else if (gantry > 180.00 && gantry < 359.99) { checkLR = fieldOrientation.LeftRight == FieldOrientation.LeftorRight.Right; } else { checkLR = fieldOrientation.LeftRight == FieldOrientation.LeftorRight.NA; } //check Antieror Postieror if ((gantry > 270.00 && gantry < 359.99) || (gantry >= 0.00 && gantry < 90.00)) { checkAP = fieldOrientation.AntPost == FieldOrientation.AntorPost.Anterior; } else if (gantry > 90.00 && gantry < 270.00) { checkAP = fieldOrientation.AntPost == FieldOrientation.AntorPost.Posterior; } else { checkAP = fieldOrientation.AntPost == FieldOrientation.AntorPost.NA; } //check Superior and Inferior if ((gantry > 0.00 && gantry < 180.00 && couch > 270.00 && couch < 359.99) || (gantry > 180.00 && gantry < 359.99 && couch > 0.00 && couch < 90.00)) { checkSI = fieldOrientation.SupInf == FieldOrientation.SuporInf.Superior; } else if ((gantry > 0.00 && gantry < 180.00 && couch > 0.00 && couch < 90.00) || (gantry > 180.00 && gantry < 359.99 && couch > 270.00 && couch < 359.99)) { checkSI = fieldOrientation.SupInf == FieldOrientation.SuporInf.Inferior; } else { checkSI = fieldOrientation.SupInf == FieldOrientation.SuporInf.NA; } break; } break; } case PatientOrientation.HeadFirstProne: break; case PatientOrientation.FeetFirstSupine: break; case PatientOrientation.FeetFirstProne: break; } if (!checkLR) { Warning += System.Environment.NewLine + "Left Right mismatch"; } if (!checkAP) { Warning += System.Environment.NewLine + "Anterior Posterior mismatch"; } if (!checkSI) { Warning += System.Environment.NewLine + "Superior Inferior mismatch"; } return(checkLR && checkAP && checkSI); }
/// <summary> /// Provides the transformation from patient DICOM coordinates to IEC coordinates. Useful for rendering /// structures. /// </summary> /// <param name="orient"></param> /// <returns>4x4 transformation matrix</returns> public static Matrix3D DICOM2IEC(PatientOrientation orient) { switch (orient) { case PatientOrientation.HeadFirstSupine: return(new Matrix3D( 1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1)); case PatientOrientation.HeadFirstProne: return(new Matrix3D( -1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1)); case PatientOrientation.FeetFirstSupine: return(new Matrix3D( -1, 0, 0, 0, 0, 0, -1, 0, 0, -1, 0, 0, 0, 0, 0, 1)); case PatientOrientation.FeetFirstProne: return(new Matrix3D( 1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1)); case PatientOrientation.HeadFirstDecubitusLeft: return(new Matrix3D( 0, 0, -1, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1)); case PatientOrientation.HeadFirstDecubitusRight: return(new Matrix3D( 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1)); case PatientOrientation.FeetFirstDecubitusLeft: return(new Matrix3D( 0, 0, -1, 0, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 1)); case PatientOrientation.FeetFirstDecubitusRight: return(new Matrix3D( 0, 0, 1, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 1)); default: throw new Exception("Don't have transform for this orientation!"); } }
/// <summary> /// Determines the (untransformed) marker for a particular image edge. /// </summary> /// <param name="imageEdge">the edge (image coordinates)</param> /// <param name="patientOrientation">the patient orientation construct of the image</param> /// <returns>a string representation of the direction (a 'marker')</returns> private string GetMarker(ImageEdge imageEdge, PatientOrientation patientOrientation) { bool negativeDirection = (imageEdge == ImageEdge.Left || imageEdge == ImageEdge.Top); bool rowValues = (imageEdge == ImageEdge.Left || imageEdge == ImageEdge.Right); var direction = (rowValues ? patientOrientation.Row : patientOrientation.Column) ?? PatientDirection.Empty; if (negativeDirection) direction = direction.OpposingDirection; string markerText = ""; markerText += GetMarkerText(direction.Primary); markerText += GetMarkerText(direction.Secondary); return markerText; }
/// <summary> /// Called by GetAnnotationText (and also by Unit Test code). Making this function internal simply makes it easier /// to write unit tests for this class (don't have to implement a fake PresentationImage). /// </summary> /// <param name="imageTransform">the image transform</param> /// <param name="patientOrientation">the image orientation patient (direction cosines)</param> /// <returns></returns> internal string GetAnnotationTextInternal(SpatialTransform imageTransform, PatientOrientation patientOrientation) { SizeF[] imageEdgeVectors = new SizeF[4]; for (int i = 0; i < 4; ++i) imageEdgeVectors[i] = imageTransform.ConvertToDestination(_edgeVectors[i]); //find out which source image edge got transformed to coincide with this viewport edge. ImageEdge transformedEdge = GetTransformedEdge(imageEdgeVectors); //get the marker for the appropriate (source) image edge. return GetMarker(transformedEdge, patientOrientation); }
private static void GetPatientOrientationVectors(PatientOrientation patientOrientation, out Vector3D headVector, out Vector3D leftVector, out Vector3D posteriorVector) { headVector = leftVector = posteriorVector = null; if (patientOrientation == null) { return; } if (!string.IsNullOrEmpty(patientOrientation.Row)) { switch (char.ToUpperInvariant(patientOrientation.Row.Code[0])) { case _orientationLeft: leftVector = new Vector3D(+1, 0, 0); break; case _orientationRight: leftVector = new Vector3D(-1, 0, 0); break; case _orientationPosterior: posteriorVector = new Vector3D(+1, 0, 0); break; case _orientationAnterior: posteriorVector = new Vector3D(-1, 0, 0); break; case _orientationHead: headVector = new Vector3D(+1, 0, 0); break; case _orientationFoot: headVector = new Vector3D(-1, 0, 0); break; } } if (!string.IsNullOrEmpty(patientOrientation.Column)) { switch (char.ToUpperInvariant(patientOrientation.Column.Code[0])) { case _orientationLeft: leftVector = new Vector3D(0, +1, 0); break; case _orientationRight: leftVector = new Vector3D(0, -1, 0); break; case _orientationPosterior: posteriorVector = new Vector3D(0, +1, 0); break; case _orientationAnterior: posteriorVector = new Vector3D(0, -1, 0); break; case _orientationHead: headVector = new Vector3D(0, +1, 0); break; case _orientationFoot: headVector = new Vector3D(0, -1, 0); break; } } }
private static void GetPatientOrientationVectors(PatientOrientation patientOrientation, out Vector3D headVector, out Vector3D leftVector, out Vector3D posteriorVector) { headVector = leftVector = posteriorVector = null; if (patientOrientation == null) return; if (!string.IsNullOrEmpty(patientOrientation.Row)) { switch (char.ToUpperInvariant(patientOrientation.Row.Code[0])) { case _orientationLeft: leftVector = new Vector3D(+1, 0, 0); break; case _orientationRight: leftVector = new Vector3D(-1, 0, 0); break; case _orientationPosterior: posteriorVector = new Vector3D(+1, 0, 0); break; case _orientationAnterior: posteriorVector = new Vector3D(-1, 0, 0); break; case _orientationHead: headVector = new Vector3D(+1, 0, 0); break; case _orientationFoot: headVector = new Vector3D(-1, 0, 0); break; } } if (!string.IsNullOrEmpty(patientOrientation.Column)) { switch (char.ToUpperInvariant(patientOrientation.Column.Code[0])) { case _orientationLeft: leftVector = new Vector3D(0, +1, 0); break; case _orientationRight: leftVector = new Vector3D(0, -1, 0); break; case _orientationPosterior: posteriorVector = new Vector3D(0, +1, 0); break; case _orientationAnterior: posteriorVector = new Vector3D(0, -1, 0); break; case _orientationHead: headVector = new Vector3D(0, +1, 0); break; case _orientationFoot: headVector = new Vector3D(0, -1, 0); break; } } }
protected override void RunTest(PlanSetup plan) { DisplayName = "Patient Shifts"; TestExplanation = "Displays shifts from Marker Structure or User Origin"; Result = ""; ResultDetails = ""; DisplayColor = ResultColorChoices.Pass; PatientOrientation orientation = plan.TreatmentOrientation; // get location of user origin and plan isocenter VVector tattoos = plan.StructureSet.Image.UserOrigin; VVector isocenter = plan.Beams.First().IsocenterPosition; // calculated shift distance from user origin VVector shift = isocenter - tattoos; string shiftFrom = "User Origin"; // these sites set iso at sim and import in a "MARKER" structure that shifts will be based off (also they don't use gold markers, so there's no need to worry about those "MARKER" structures) if (Department == Department.MPH || Department == Department.FLT || Department == Department.LAP || Department == Department.OWO || Department == Department.DET || Department == Department.FAR) { // loop through each patient marker and see if it's closer to the iso than the user origin and if it is use that for the calculated shift foreach (Structure point in plan.StructureSet.Structures.Where(x => x.DicomType == "MARKER")) { if (Math.Round((isocenter - point.CenterPoint).Length, 2) <= Math.Round(shift.Length, 2)) { shift = isocenter - point.CenterPoint; shiftFrom = point.Id; } } } //round it off to prevent very small numbers from appearing and convert to cm for shifts shift.x = Math.Round(shift.x / 10, 1); shift.y = Math.Round(shift.y / 10, 1); shift.z = Math.Round(shift.z / 10, 1); if (shift.Length == 0) { ResultDetails = $"No shifts from {shiftFrom}"; } else { // Set shift verbiage based on department string pat, sup, inf, ant, post; if (Department == Department.NOR) { pat = "Table"; sup = "out"; inf = "in"; ant = "down"; post = "up"; } else { pat = "Patient"; sup = "superior"; inf = "inferior"; ant = "anterior"; post = "posterior"; } //x-axis if (shift.x > 0) { ResultDetails += $"{pat} left: {shift.x:0.0} cm\n"; } else if (shift.x < 0) { ResultDetails += $"{pat} right: {-shift.x:0.0} cm\n"; } //z-axis if (shift.z > 0) { ResultDetails += $"{pat} {sup}: {shift.z:0.0} cm\n"; } else if (shift.z < 0) { ResultDetails += $"{pat} {inf}: {-shift.z:0.0} cm\n"; } //y-axis if (shift.y > 0) { ResultDetails += $"{pat} {post}: {shift.y:0.0} cm\n"; } else if (shift.y < 0) { ResultDetails += $"{pat} {ant}: {-shift.y:0.0} cm\n"; } //remove negatives ResultDetails.Replace("-", string.Empty); ResultDetails = $"Shifts from {shiftFrom}\n" + ResultDetails; } ResultDetails = ResultDetails.TrimEnd('\n'); }
/// <summary> /// Initializes a new instance of <see cref="MammographyImageSpatialTransform"/> with the specified image plane details. /// </summary> public MammographyImageSpatialTransform(IGraphic ownerGraphic, int rows, int columns, double pixelSpacingX, double pixelSpacingY, double pixelAspectRatioX, double pixelAspectRatioY, PatientOrientation patientOrientation, string laterality) : base(ownerGraphic, rows, columns, pixelSpacingX, pixelSpacingY, pixelAspectRatioX, pixelAspectRatioY) { // image coordinates are defined with X and Y being equivalent to the screen axes (right and down) and with Z = X cross Y (into the screen) Vector3D imagePosterior, imageHead, imageLeft; // patient orientation vectors in image space GetPatientOrientationVectors(patientOrientation, out imageHead, out imageLeft, out imagePosterior); // save the posterior vector _imagePosterior = imagePosterior; if (imagePosterior != null) { Vector3D normativePosterior, normativeHead, normativeLeft; // normative patient orientation vectors in image space GetNormativeOrientationVectors(laterality, out normativeHead, out normativeLeft, out normativePosterior); // only do any adjustments if laterality implies a normative orientation for the posterior direction if (normativePosterior != null) { // check if the order of the patient vectors are flipped according to the normative vectors // we know we need to flip if the direction vector cross products have different signs if (imageHead != null) { FlipX = Math.Sign(imagePosterior.Cross(imageHead).Z) != Math.Sign(normativePosterior.Cross(normativeHead).Z); } else if (imageLeft != null) { FlipX = Math.Sign(imagePosterior.Cross(imageLeft).Z) != Math.Sign(normativePosterior.Cross(normativeLeft).Z); } // with flip normalized, just rotate to align the current posterior direction with the normative posterior var currentPosterior = ScreenPosterior; var posteriorAngle = Math.Atan2(currentPosterior.Y, currentPosterior.X); var normativeAngle = Math.Atan2(normativePosterior.Y, normativePosterior.X); // compute required rotation, rounded to multiples of 90 degrees (PI/2 radians) RotationXY = 90 * ((int)Math.Round((normativeAngle - posteriorAngle) * 2 / Math.PI)); } } }
//Check Image (Orientation, CT thickness, or missing CT, total number, etc.) List <PlanCheckResult> CheckImage(IonPlanSetup plan) { List <PlanCheckResult> planCheckResults = new List <PlanCheckResult>(); Image image = plan.StructureSet.Image; //Orientation PatientOrientation patientOrientation = image.ImagingOrientation; if (patientOrientation == PatientOrientation.HeadFirstSupine) { PlanCheckResult planCheckResult = new PlanCheckResult(); planCheckResult.Item = "Patient Orientation"; planCheckResult.Expected = PatientOrientation.HeadFirstSupine.ToString(); planCheckResult.CurrentPlan = patientOrientation.ToString(); planCheckResult.Pass = PlanCheckResult.CheckResult.Pass; planCheckResult.Comments = ""; planCheckResults.Add(planCheckResult); } else { PlanCheckResult planCheckResult = new PlanCheckResult(); planCheckResult.Item = "Patient Orientation"; planCheckResult.Expected = ""; planCheckResult.CurrentPlan = patientOrientation.ToString(); planCheckResult.Pass = PlanCheckResult.CheckResult.Warning; planCheckResult.Comments = "Patient is NOT HeadFirstSupine, please double check patient orientation."; planCheckResults.Add(planCheckResult); } //CT thickness double CTThickness = image.ZRes; double defaultCTThickness = 2.5; if (CTThickness - defaultCTThickness < 1e-7) { PlanCheckResult planCheckResult = new PlanCheckResult(); planCheckResult.Item = "CT Thickness (mm)"; planCheckResult.Expected = "2.5"; planCheckResult.CurrentPlan = CTThickness.ToString(); planCheckResult.Pass = PlanCheckResult.CheckResult.Pass; planCheckResult.Comments = ""; planCheckResults.Add(planCheckResult); } else { PlanCheckResult planCheckResult = new PlanCheckResult(); planCheckResult.Item = "CT Thickness (mm)"; planCheckResult.Expected = "2.5"; planCheckResult.CurrentPlan = CTThickness.ToString("0.00"); planCheckResult.Pass = PlanCheckResult.CheckResult.Warning; planCheckResult.Comments = "CT thickness is not same as default. Please check."; planCheckResults.Add(planCheckResult); } //CT total slices < 300 double CTSlices = image.ZSize; double maxSlice = 300; if (CTSlices <= maxSlice) { PlanCheckResult planCheckResult = new PlanCheckResult(); planCheckResult.Item = "CT Slices"; planCheckResult.Expected = "<300"; planCheckResult.CurrentPlan = CTSlices.ToString(); planCheckResult.Pass = PlanCheckResult.CheckResult.Pass; planCheckResult.Comments = ""; planCheckResults.Add(planCheckResult); } else { PlanCheckResult planCheckResult = new PlanCheckResult(); planCheckResult.Item = "CT Slices"; planCheckResult.Expected = "<300"; planCheckResult.CurrentPlan = CTSlices.ToString(); planCheckResult.Pass = PlanCheckResult.CheckResult.Warning; planCheckResult.Comments = "CT slice is more than 300"; planCheckResults.Add(planCheckResult); } return(planCheckResults); }